diff --git a/README.md b/README.md index fd1bd0f4..ce254d3f 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,18 @@ You’ll also need to ensure the following: The website pulls all ebook information from what is contained in `/standardebooks.org/www/ebooks/`. It does not inspect `/standardebooks.org/ebooks/`. Therefore it is possible for one or the other to hold different catalogs if they become out of sync. +# Testing + +This repository includes [PHPStan](https://github.com/phpstan/phpstan) to statically analyze the codebase. + +To run PHPStan, execute: + +```shell +$> /vendor/bin/phpstan analyse -c /config/phpstan/phpstan.neon +``` + +If run successfully, it should output `[OK] No errors`. + # Contributing Before submitting design contributions, please discuss them with the Standard Ebooks lead. While we encourage discussion and contributions, we can’t guarantee that unsoliticed design contributions will be accepted. You can open an issue to discuss potential design contributions with us before you begin. diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..e7651088 --- /dev/null +++ b/composer.json @@ -0,0 +1,9 @@ +{ + "require-dev": { + "phpstan/phpstan": "^0.11.2" + }, + "autoload": { + "psr-4": {"": "lib/"}, + "files": ["lib/Constants.php", "lib/CoreFunctions.php"] + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..8de44248 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1105 @@ +{ + "_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#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "eed5e4de65902f3c2e1429d5b4068d9d", + "packages": [], + "packages-dev": [ + { + "name": "composer/xdebug-handler", + "version": "1.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "d17708133b6c276d6e42ef887a877866b909d892" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/d17708133b6c276d6e42ef887a877866b909d892", + "reference": "d17708133b6c276d6e42ef887a877866b909d892", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.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" + ], + "time": "2019-01-28T20:25:53+00:00" + }, + { + "name": "jean85/pretty-package-versions", + "version": "1.2", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "shasum": "" + }, + "require": { + "ocramius/package-versions": "^1.2.0", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", + "keywords": [ + "composer", + "package", + "release", + "versions" + ], + "time": "2018-06-13T13:22:40+00:00" + }, + { + "name": "nette/bootstrap", + "version": "v2.4.6", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543", + "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543", + "shasum": "" + }, + "require": { + "nette/di": "~2.4.7", + "nette/utils": "~2.4", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "latte/latte": "~2.2", + "nette/application": "~2.3", + "nette/caching": "~2.3", + "nette/database": "~2.3", + "nette/forms": "~2.3", + "nette/http": "~2.4.0", + "nette/mail": "~2.3", + "nette/robot-loader": "^2.4.2 || ^3.0", + "nette/safe-stream": "~2.2", + "nette/security": "~2.3", + "nette/tester": "~2.0", + "tracy/tracy": "^2.4.1" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "time": "2018-05-17T12:52:20+00:00" + }, + { + "name": "nette/di", + "version": "v2.4.15", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "d0561b8f77e8ef2ed6d83328860e16c81a5a8649" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/d0561b8f77e8ef2ed6d83328860e16c81a5a8649", + "reference": "d0561b8f77e8ef2ed6d83328860e16c81a5a8649", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/neon": "^2.3.3 || ~3.0.0", + "nette/php-generator": "^2.6.1 || ^3.0.0", + "nette/utils": "^2.5.0 || ~3.0.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/bootstrap": "<2.4", + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "time": "2019-01-30T13:26:05+00:00" + }, + { + "name": "nette/finder", + "version": "v2.4.2", + "source": { + "type": "git", + "url": "https://github.com/nette/finder.git", + "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/finder/zipball/ee951a656cb8ac622e5dd33474a01fd2470505a0", + "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0", + "shasum": "" + }, + "require": { + "nette/utils": "~2.4", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔍 Nette Finder: find files and directories with an intuitive API.", + "homepage": "https://nette.org", + "keywords": [ + "filesystem", + "glob", + "iterator", + "nette" + ], + "time": "2018-06-28T11:49:23+00:00" + }, + { + "name": "nette/neon", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/cbff32059cbdd8720deccf9e9eace6ee516f02eb", + "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": ">=7.0" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "http://ne-on.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "time": "2019-02-05T21:30:40+00:00" + }, + { + "name": "nette/php-generator", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "9de4e093a130f7a1bd175198799ebc0efbac6924" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/9de4e093a130f7a1bd175198799ebc0efbac6924", + "reference": "9de4e093a130f7a1bd175198799ebc0efbac6924", + "shasum": "" + }, + "require": { + "nette/utils": "^2.4.2 || ~3.0.0", + "php": ">=7.1" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.3 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "time": "2018-11-27T19:00:14+00:00" + }, + { + "name": "nette/robot-loader", + "version": "v3.1.0", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/fc76c70e740b10f091e502b2e393d0be912f38d4", + "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/finder": "^2.3 || ^3.0", + "nette/utils": "^2.4 || ^3.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "time": "2018-08-13T14:19:06+00:00" + }, + { + "name": "nette/utils", + "version": "v2.5.3", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/17b9f76f2abd0c943adfb556e56f2165460b15ce", + "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize() and toAscii()", + "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/loader.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "time": "2018-09-18T10:22:16+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.2.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/5221f49a608808c1e4d436df32884cbc1b821ac0", + "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-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" + ], + "time": "2019-02-16T20:54:15+00:00" + }, + { + "name": "ocramius/package-versions", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.1.0" + }, + "require-dev": { + "composer/composer": "^1.6.3", + "doctrine/coding-standard": "^5.0.1", + "ext-zip": "*", + "infection/infection": "^0.7.1", + "phpunit/phpunit": "^7.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2019-02-21T12:16:21+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.3.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/2cc49f47c69b023eaf05b48e6529389893b13d74", + "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "require-dev": { + "consistence/coding-standard": "^2.0.0", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/phpstan": "^0.10", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^3.3.0", + "symfony/process": "^3.4 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.3-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", + "time": "2019-01-14T12:26:23+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "0.11.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "8e185a74004920419ee97bf9dc62e6a175e8dca5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8e185a74004920419ee97bf9dc62e6a175e8dca5", + "reference": "8e185a74004920419ee97bf9dc62e6a175e8dca5", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.3.0", + "jean85/pretty-package-versions": "^1.0.3", + "nette/bootstrap": "^2.4 || ^3.0", + "nette/di": "^2.4.7 || ^3.0", + "nette/robot-loader": "^3.0.1", + "nette/utils": "^2.4.5 || ^3.0", + "nikic/php-parser": "^4.0.2", + "php": "~7.1", + "phpstan/phpdoc-parser": "^0.3", + "symfony/console": "~3.2 || ~4.0", + "symfony/finder": "~3.2 || ~4.0" + }, + "conflict": { + "symfony/console": "3.4.16 || 4.1.5" + }, + "require-dev": { + "brianium/paratest": "^2.0", + "consistence/coding-standard": "^3.5", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ext-intl": "*", + "ext-mysqli": "*", + "ext-soap": "*", + "ext-zip": "*", + "jakub-onderka/php-parallel-lint": "^1.0", + "localheinz/composer-normalize": "^1.1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-deprecation-rules": "^0.11", + "phpstan/phpstan-php-parser": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2" + }, + "bin": [ + "bin/phpstan" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.11-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": [ + "src/", + "build/PHPStan" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "time": "2019-02-12T14:54:38+00:00" + }, + { + "name": "psr/log", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2018-11-20T15:27:04+00:00" + }, + { + "name": "symfony/console", + "version": "v4.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4", + "reference": "1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "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": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2019-01-25T14:35:16+00:00" + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "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": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2018-12-05T08:06:11+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.2.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "ef71816cbb264988bb57fe6a73f610888b9aa70c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/ef71816cbb264988bb57fe6a73f610888b9aa70c", + "reference": "ef71816cbb264988bb57fe6a73f610888b9aa70c", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "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": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2019-01-16T20:35:37+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "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" + ], + "time": "2018-09-21T13:07:52+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/lib/Constants.php b/lib/Constants.php index 1d87730d..6df0ebf9 100644 --- a/lib/Constants.php +++ b/lib/Constants.php @@ -1,4 +1,6 @@ diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 00000000..11dbeb02 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath.'\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 00000000..f0157a6e --- /dev/null +++ b/vendor/composer/LICENSE @@ -0,0 +1,56 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: Composer +Upstream-Contact: Jordi Boggiano +Source: https://github.com/composer/composer + +Files: * +Copyright: 2016, Nils Adermann + 2016, Jordi Boggiano +License: Expat + +Files: src/Composer/Util/TlsHelper.php +Copyright: 2016, Nils Adermann + 2016, Jordi Boggiano + 2013, Evan Coury +License: Expat and BSD-2-Clause + +License: BSD-2-Clause + 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. + . + 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. + +License: Expat + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is furnished + to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..e9ee7d51 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,103 @@ + $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Bridges\\DITracy\\ContainerPanel' => $vendorDir . '/nette/di/src/Bridges/DITracy/ContainerPanel.php', + 'Nette\\Bridges\\Framework\\TracyBridge' => $vendorDir . '/nette/bootstrap/src/Bridges/Framework/TracyBridge.php', + 'Nette\\Configurator' => $vendorDir . '/nette/bootstrap/src/Bootstrap/Configurator.php', + 'Nette\\DI\\Compiler' => $vendorDir . '/nette/di/src/DI/Compiler.php', + 'Nette\\DI\\CompilerExtension' => $vendorDir . '/nette/di/src/DI/CompilerExtension.php', + 'Nette\\DI\\Config\\Adapters\\IniAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/IniAdapter.php', + 'Nette\\DI\\Config\\Adapters\\NeonAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/NeonAdapter.php', + 'Nette\\DI\\Config\\Adapters\\PhpAdapter' => $vendorDir . '/nette/di/src/DI/Config/Adapters/PhpAdapter.php', + 'Nette\\DI\\Config\\Helpers' => $vendorDir . '/nette/di/src/DI/Config/Helpers.php', + 'Nette\\DI\\Config\\IAdapter' => $vendorDir . '/nette/di/src/DI/Config/IAdapter.php', + 'Nette\\DI\\Config\\Loader' => $vendorDir . '/nette/di/src/DI/Config/Loader.php', + 'Nette\\DI\\Container' => $vendorDir . '/nette/di/src/DI/Container.php', + 'Nette\\DI\\ContainerBuilder' => $vendorDir . '/nette/di/src/DI/ContainerBuilder.php', + 'Nette\\DI\\ContainerLoader' => $vendorDir . '/nette/di/src/DI/ContainerLoader.php', + 'Nette\\DI\\DependencyChecker' => $vendorDir . '/nette/di/src/DI/DependencyChecker.php', + 'Nette\\DI\\Extensions\\ConstantsExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ConstantsExtension.php', + 'Nette\\DI\\Extensions\\DIExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DIExtension.php', + 'Nette\\DI\\Extensions\\DecoratorExtension' => $vendorDir . '/nette/di/src/DI/Extensions/DecoratorExtension.php', + 'Nette\\DI\\Extensions\\ExtensionsExtension' => $vendorDir . '/nette/di/src/DI/Extensions/ExtensionsExtension.php', + 'Nette\\DI\\Extensions\\InjectExtension' => $vendorDir . '/nette/di/src/DI/Extensions/InjectExtension.php', + 'Nette\\DI\\Extensions\\PhpExtension' => $vendorDir . '/nette/di/src/DI/Extensions/PhpExtension.php', + 'Nette\\DI\\Helpers' => $vendorDir . '/nette/di/src/DI/Helpers.php', + 'Nette\\DI\\MissingServiceException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\PhpGenerator' => $vendorDir . '/nette/di/src/DI/PhpGenerator.php', + 'Nette\\DI\\PhpReflection' => $vendorDir . '/nette/di/src/DI/PhpReflection.php', + 'Nette\\DI\\ServiceCreationException' => $vendorDir . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\ServiceDefinition' => $vendorDir . '/nette/di/src/DI/ServiceDefinition.php', + 'Nette\\DI\\Statement' => $vendorDir . '/nette/di/src/DI/Statement.php', + 'Nette\\DeprecatedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\DirectoryNotFoundException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\FileNotFoundException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\IOException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\InvalidArgumentException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\InvalidStateException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Iterators\\CachingIterator' => $vendorDir . '/nette/utils/src/Iterators/CachingIterator.php', + 'Nette\\Iterators\\Mapper' => $vendorDir . '/nette/utils/src/Iterators/Mapper.php', + 'Nette\\LegacyObject' => $vendorDir . '/nette/utils/src/Utils/LegacyObject.php', + 'Nette\\Loaders\\RobotLoader' => $vendorDir . '/nette/robot-loader/src/RobotLoader/RobotLoader.php', + 'Nette\\Localization\\ITranslator' => $vendorDir . '/nette/utils/src/Utils/ITranslator.php', + 'Nette\\MemberAccessException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Neon\\Decoder' => $vendorDir . '/nette/neon/src/Neon/Decoder.php', + 'Nette\\Neon\\Encoder' => $vendorDir . '/nette/neon/src/Neon/Encoder.php', + 'Nette\\Neon\\Entity' => $vendorDir . '/nette/neon/src/Neon/Entity.php', + 'Nette\\Neon\\Exception' => $vendorDir . '/nette/neon/src/Neon/Exception.php', + 'Nette\\Neon\\Neon' => $vendorDir . '/nette/neon/src/Neon/Neon.php', + 'Nette\\NotImplementedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\NotSupportedException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\OutOfRangeException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\PhpGenerator\\ClassType' => $vendorDir . '/nette/php-generator/src/PhpGenerator/ClassType.php', + 'Nette\\PhpGenerator\\Closure' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Closure.php', + 'Nette\\PhpGenerator\\Constant' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Constant.php', + 'Nette\\PhpGenerator\\Factory' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Factory.php', + 'Nette\\PhpGenerator\\GlobalFunction' => $vendorDir . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php', + 'Nette\\PhpGenerator\\Helpers' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Helpers.php', + 'Nette\\PhpGenerator\\Method' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Method.php', + 'Nette\\PhpGenerator\\Parameter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Parameter.php', + 'Nette\\PhpGenerator\\PhpFile' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpFile.php', + 'Nette\\PhpGenerator\\PhpLiteral' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php', + 'Nette\\PhpGenerator\\PhpNamespace' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php', + 'Nette\\PhpGenerator\\Printer' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Printer.php', + 'Nette\\PhpGenerator\\Property' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Property.php', + 'Nette\\PhpGenerator\\PsrPrinter' => $vendorDir . '/nette/php-generator/src/PhpGenerator/PsrPrinter.php', + 'Nette\\PhpGenerator\\Traits\\CommentAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php', + 'Nette\\PhpGenerator\\Traits\\FunctionLike' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php', + 'Nette\\PhpGenerator\\Traits\\NameAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php', + 'Nette\\PhpGenerator\\Traits\\VisibilityAware' => $vendorDir . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php', + 'Nette\\SmartObject' => $vendorDir . '/nette/utils/src/Utils/SmartObject.php', + 'Nette\\StaticClass' => $vendorDir . '/nette/utils/src/Utils/StaticClass.php', + 'Nette\\StaticClassException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\UnexpectedValueException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ArrayHash' => $vendorDir . '/nette/utils/src/Utils/ArrayHash.php', + 'Nette\\Utils\\ArrayList' => $vendorDir . '/nette/utils/src/Utils/ArrayList.php', + 'Nette\\Utils\\Arrays' => $vendorDir . '/nette/utils/src/Utils/Arrays.php', + 'Nette\\Utils\\AssertionException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Callback' => $vendorDir . '/nette/utils/src/Utils/Callback.php', + 'Nette\\Utils\\DateTime' => $vendorDir . '/nette/utils/src/Utils/DateTime.php', + 'Nette\\Utils\\FileSystem' => $vendorDir . '/nette/utils/src/Utils/FileSystem.php', + 'Nette\\Utils\\Finder' => $vendorDir . '/nette/finder/src/Utils/Finder.php', + 'Nette\\Utils\\Html' => $vendorDir . '/nette/utils/src/Utils/Html.php', + 'Nette\\Utils\\IHtmlString' => $vendorDir . '/nette/utils/src/Utils/IHtmlString.php', + 'Nette\\Utils\\Image' => $vendorDir . '/nette/utils/src/Utils/Image.php', + 'Nette\\Utils\\ImageException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Json' => $vendorDir . '/nette/utils/src/Utils/Json.php', + 'Nette\\Utils\\JsonException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ObjectHelpers' => $vendorDir . '/nette/utils/src/Utils/ObjectHelpers.php', + 'Nette\\Utils\\ObjectMixin' => $vendorDir . '/nette/utils/src/Utils/ObjectMixin.php', + 'Nette\\Utils\\Paginator' => $vendorDir . '/nette/utils/src/Utils/Paginator.php', + 'Nette\\Utils\\Random' => $vendorDir . '/nette/utils/src/Utils/Random.php', + 'Nette\\Utils\\Reflection' => $vendorDir . '/nette/utils/src/Utils/Reflection.php', + 'Nette\\Utils\\RegexpException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Strings' => $vendorDir . '/nette/utils/src/Utils/Strings.php', + 'Nette\\Utils\\UnknownImageFileException' => $vendorDir . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Validators' => $vendorDir . '/nette/utils/src/Utils/Validators.php', +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 00000000..48c77af2 --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,13 @@ + $vendorDir . '/nette/utils/src/loader.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', + '782b605f6bb82f1cd229995fb6f0c6bf' => $baseDir . '/lib/Constants.php', + '7f0f1b28d901698044d9d248797ab78a' => $baseDir . '/lib/CoreFunctions.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 00000000..b7fc0125 --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Contracts\\' => array($vendorDir . '/symfony/contracts'), + 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'), + 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), + 'PackageVersions\\' => array($vendorDir . '/ocramius/package-versions/src/PackageVersions'), + 'PHPStan\\PhpDocParser\\' => array($vendorDir . '/phpstan/phpdoc-parser/src'), + 'PHPStan\\' => array($vendorDir . '/phpstan/phpstan/src', $vendorDir . '/phpstan/phpstan/build/PHPStan'), + 'Jean85\\' => array($vendorDir . '/jean85/pretty-package-versions/src'), + 'Composer\\XdebugHandler\\' => array($vendorDir . '/composer/xdebug-handler/src'), + '' => array($baseDir . '/lib'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 00000000..9fdf7fee --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,70 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit49e401a41abff8a9005dcbd044d35c5f::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit49e401a41abff8a9005dcbd044d35c5f::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire49e401a41abff8a9005dcbd044d35c5f($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequire49e401a41abff8a9005dcbd044d35c5f($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 00000000..55b31a6c --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,201 @@ + __DIR__ . '/..' . '/nette/utils/src/loader.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + '782b605f6bb82f1cd229995fb6f0c6bf' => __DIR__ . '/../..' . '/lib/Constants.php', + '7f0f1b28d901698044d9d248797ab78a' => __DIR__ . '/../..' . '/lib/CoreFunctions.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'S' => + array ( + 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Contracts\\' => 18, + 'Symfony\\Component\\Finder\\' => 25, + 'Symfony\\Component\\Console\\' => 26, + ), + 'P' => + array ( + 'Psr\\Log\\' => 8, + 'PhpParser\\' => 10, + 'PackageVersions\\' => 16, + 'PHPStan\\PhpDocParser\\' => 21, + 'PHPStan\\' => 8, + ), + 'J' => + array ( + 'Jean85\\' => 7, + ), + 'C' => + array ( + 'Composer\\XdebugHandler\\' => 23, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'Symfony\\Polyfill\\Mbstring\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + ), + 'Symfony\\Contracts\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/contracts', + ), + 'Symfony\\Component\\Finder\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/finder', + ), + 'Symfony\\Component\\Console\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/console', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), + 'PhpParser\\' => + array ( + 0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser', + ), + 'PackageVersions\\' => + array ( + 0 => __DIR__ . '/..' . '/ocramius/package-versions/src/PackageVersions', + ), + 'PHPStan\\PhpDocParser\\' => + array ( + 0 => __DIR__ . '/..' . '/phpstan/phpdoc-parser/src', + ), + 'PHPStan\\' => + array ( + 0 => __DIR__ . '/..' . '/phpstan/phpstan/src', + 1 => __DIR__ . '/..' . '/phpstan/phpstan/build/PHPStan', + ), + 'Jean85\\' => + array ( + 0 => __DIR__ . '/..' . '/jean85/pretty-package-versions/src', + ), + 'Composer\\XdebugHandler\\' => + array ( + 0 => __DIR__ . '/..' . '/composer/xdebug-handler/src', + ), + ); + + public static $fallbackDirsPsr4 = array ( + 0 => __DIR__ . '/../..' . '/lib', + ); + + public static $classMap = array ( + 'Nette\\ArgumentOutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Bridges\\DITracy\\ContainerPanel' => __DIR__ . '/..' . '/nette/di/src/Bridges/DITracy/ContainerPanel.php', + 'Nette\\Bridges\\Framework\\TracyBridge' => __DIR__ . '/..' . '/nette/bootstrap/src/Bridges/Framework/TracyBridge.php', + 'Nette\\Configurator' => __DIR__ . '/..' . '/nette/bootstrap/src/Bootstrap/Configurator.php', + 'Nette\\DI\\Compiler' => __DIR__ . '/..' . '/nette/di/src/DI/Compiler.php', + 'Nette\\DI\\CompilerExtension' => __DIR__ . '/..' . '/nette/di/src/DI/CompilerExtension.php', + 'Nette\\DI\\Config\\Adapters\\IniAdapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapters/IniAdapter.php', + 'Nette\\DI\\Config\\Adapters\\NeonAdapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapters/NeonAdapter.php', + 'Nette\\DI\\Config\\Adapters\\PhpAdapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Adapters/PhpAdapter.php', + 'Nette\\DI\\Config\\Helpers' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Helpers.php', + 'Nette\\DI\\Config\\IAdapter' => __DIR__ . '/..' . '/nette/di/src/DI/Config/IAdapter.php', + 'Nette\\DI\\Config\\Loader' => __DIR__ . '/..' . '/nette/di/src/DI/Config/Loader.php', + 'Nette\\DI\\Container' => __DIR__ . '/..' . '/nette/di/src/DI/Container.php', + 'Nette\\DI\\ContainerBuilder' => __DIR__ . '/..' . '/nette/di/src/DI/ContainerBuilder.php', + 'Nette\\DI\\ContainerLoader' => __DIR__ . '/..' . '/nette/di/src/DI/ContainerLoader.php', + 'Nette\\DI\\DependencyChecker' => __DIR__ . '/..' . '/nette/di/src/DI/DependencyChecker.php', + 'Nette\\DI\\Extensions\\ConstantsExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/ConstantsExtension.php', + 'Nette\\DI\\Extensions\\DIExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/DIExtension.php', + 'Nette\\DI\\Extensions\\DecoratorExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/DecoratorExtension.php', + 'Nette\\DI\\Extensions\\ExtensionsExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/ExtensionsExtension.php', + 'Nette\\DI\\Extensions\\InjectExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/InjectExtension.php', + 'Nette\\DI\\Extensions\\PhpExtension' => __DIR__ . '/..' . '/nette/di/src/DI/Extensions/PhpExtension.php', + 'Nette\\DI\\Helpers' => __DIR__ . '/..' . '/nette/di/src/DI/Helpers.php', + 'Nette\\DI\\MissingServiceException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\PhpGenerator' => __DIR__ . '/..' . '/nette/di/src/DI/PhpGenerator.php', + 'Nette\\DI\\PhpReflection' => __DIR__ . '/..' . '/nette/di/src/DI/PhpReflection.php', + 'Nette\\DI\\ServiceCreationException' => __DIR__ . '/..' . '/nette/di/src/DI/exceptions.php', + 'Nette\\DI\\ServiceDefinition' => __DIR__ . '/..' . '/nette/di/src/DI/ServiceDefinition.php', + 'Nette\\DI\\Statement' => __DIR__ . '/..' . '/nette/di/src/DI/Statement.php', + 'Nette\\DeprecatedException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\DirectoryNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\FileNotFoundException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\IOException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\InvalidArgumentException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\InvalidStateException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Iterators\\CachingIterator' => __DIR__ . '/..' . '/nette/utils/src/Iterators/CachingIterator.php', + 'Nette\\Iterators\\Mapper' => __DIR__ . '/..' . '/nette/utils/src/Iterators/Mapper.php', + 'Nette\\LegacyObject' => __DIR__ . '/..' . '/nette/utils/src/Utils/LegacyObject.php', + 'Nette\\Loaders\\RobotLoader' => __DIR__ . '/..' . '/nette/robot-loader/src/RobotLoader/RobotLoader.php', + 'Nette\\Localization\\ITranslator' => __DIR__ . '/..' . '/nette/utils/src/Utils/ITranslator.php', + 'Nette\\MemberAccessException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Neon\\Decoder' => __DIR__ . '/..' . '/nette/neon/src/Neon/Decoder.php', + 'Nette\\Neon\\Encoder' => __DIR__ . '/..' . '/nette/neon/src/Neon/Encoder.php', + 'Nette\\Neon\\Entity' => __DIR__ . '/..' . '/nette/neon/src/Neon/Entity.php', + 'Nette\\Neon\\Exception' => __DIR__ . '/..' . '/nette/neon/src/Neon/Exception.php', + 'Nette\\Neon\\Neon' => __DIR__ . '/..' . '/nette/neon/src/Neon/Neon.php', + 'Nette\\NotImplementedException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\NotSupportedException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\OutOfRangeException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\PhpGenerator\\ClassType' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/ClassType.php', + 'Nette\\PhpGenerator\\Closure' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Closure.php', + 'Nette\\PhpGenerator\\Constant' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Constant.php', + 'Nette\\PhpGenerator\\Factory' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Factory.php', + 'Nette\\PhpGenerator\\GlobalFunction' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/GlobalFunction.php', + 'Nette\\PhpGenerator\\Helpers' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Helpers.php', + 'Nette\\PhpGenerator\\Method' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Method.php', + 'Nette\\PhpGenerator\\Parameter' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Parameter.php', + 'Nette\\PhpGenerator\\PhpFile' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpFile.php', + 'Nette\\PhpGenerator\\PhpLiteral' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpLiteral.php', + 'Nette\\PhpGenerator\\PhpNamespace' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PhpNamespace.php', + 'Nette\\PhpGenerator\\Printer' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Printer.php', + 'Nette\\PhpGenerator\\Property' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Property.php', + 'Nette\\PhpGenerator\\PsrPrinter' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/PsrPrinter.php', + 'Nette\\PhpGenerator\\Traits\\CommentAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/CommentAware.php', + 'Nette\\PhpGenerator\\Traits\\FunctionLike' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php', + 'Nette\\PhpGenerator\\Traits\\NameAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/NameAware.php', + 'Nette\\PhpGenerator\\Traits\\VisibilityAware' => __DIR__ . '/..' . '/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php', + 'Nette\\SmartObject' => __DIR__ . '/..' . '/nette/utils/src/Utils/SmartObject.php', + 'Nette\\StaticClass' => __DIR__ . '/..' . '/nette/utils/src/Utils/StaticClass.php', + 'Nette\\StaticClassException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\UnexpectedValueException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ArrayHash' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayHash.php', + 'Nette\\Utils\\ArrayList' => __DIR__ . '/..' . '/nette/utils/src/Utils/ArrayList.php', + 'Nette\\Utils\\Arrays' => __DIR__ . '/..' . '/nette/utils/src/Utils/Arrays.php', + 'Nette\\Utils\\AssertionException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Callback' => __DIR__ . '/..' . '/nette/utils/src/Utils/Callback.php', + 'Nette\\Utils\\DateTime' => __DIR__ . '/..' . '/nette/utils/src/Utils/DateTime.php', + 'Nette\\Utils\\FileSystem' => __DIR__ . '/..' . '/nette/utils/src/Utils/FileSystem.php', + 'Nette\\Utils\\Finder' => __DIR__ . '/..' . '/nette/finder/src/Utils/Finder.php', + 'Nette\\Utils\\Html' => __DIR__ . '/..' . '/nette/utils/src/Utils/Html.php', + 'Nette\\Utils\\IHtmlString' => __DIR__ . '/..' . '/nette/utils/src/Utils/IHtmlString.php', + 'Nette\\Utils\\Image' => __DIR__ . '/..' . '/nette/utils/src/Utils/Image.php', + 'Nette\\Utils\\ImageException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Json' => __DIR__ . '/..' . '/nette/utils/src/Utils/Json.php', + 'Nette\\Utils\\JsonException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\ObjectHelpers' => __DIR__ . '/..' . '/nette/utils/src/Utils/ObjectHelpers.php', + 'Nette\\Utils\\ObjectMixin' => __DIR__ . '/..' . '/nette/utils/src/Utils/ObjectMixin.php', + 'Nette\\Utils\\Paginator' => __DIR__ . '/..' . '/nette/utils/src/Utils/Paginator.php', + 'Nette\\Utils\\Random' => __DIR__ . '/..' . '/nette/utils/src/Utils/Random.php', + 'Nette\\Utils\\Reflection' => __DIR__ . '/..' . '/nette/utils/src/Utils/Reflection.php', + 'Nette\\Utils\\RegexpException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Strings' => __DIR__ . '/..' . '/nette/utils/src/Utils/Strings.php', + 'Nette\\Utils\\UnknownImageFileException' => __DIR__ . '/..' . '/nette/utils/src/Utils/exceptions.php', + 'Nette\\Utils\\Validators' => __DIR__ . '/..' . '/nette/utils/src/Utils/Validators.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit49e401a41abff8a9005dcbd044d35c5f::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit49e401a41abff8a9005dcbd044d35c5f::$prefixDirsPsr4; + $loader->fallbackDirsPsr4 = ComposerStaticInit49e401a41abff8a9005dcbd044d35c5f::$fallbackDirsPsr4; + $loader->classMap = ComposerStaticInit49e401a41abff8a9005dcbd044d35c5f::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 00000000..e4ea5b86 --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,1125 @@ +[ + { + "name": "composer/xdebug-handler", + "version": "1.3.2", + "version_normalized": "1.3.2.0", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "d17708133b6c276d6e42ef887a877866b909d892" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/d17708133b6c276d6e42ef887a877866b909d892", + "reference": "d17708133b6c276d6e42ef887a877866b909d892", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "time": "2019-01-28T20:25:53+00:00", + "type": "library", + "installation-source": "dist", + "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" + ] + }, + { + "name": "jean85/pretty-package-versions", + "version": "1.2", + "version_normalized": "1.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/Jean85/pretty-package-versions.git", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48", + "shasum": "" + }, + "require": { + "ocramius/package-versions": "^1.2.0", + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2018-06-13T13:22:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", + "keywords": [ + "composer", + "package", + "release", + "versions" + ] + }, + { + "name": "nette/bootstrap", + "version": "v2.4.6", + "version_normalized": "2.4.6.0", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543", + "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543", + "shasum": "" + }, + "require": { + "nette/di": "~2.4.7", + "nette/utils": "~2.4", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "latte/latte": "~2.2", + "nette/application": "~2.3", + "nette/caching": "~2.3", + "nette/database": "~2.3", + "nette/forms": "~2.3", + "nette/http": "~2.4.0", + "nette/mail": "~2.3", + "nette/robot-loader": "^2.4.2 || ^3.0", + "nette/safe-stream": "~2.2", + "nette/security": "~2.3", + "nette/tester": "~2.0", + "tracy/tracy": "^2.4.1" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "time": "2018-05-17T12:52:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ] + }, + { + "name": "nette/di", + "version": "v2.4.15", + "version_normalized": "2.4.15.0", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "d0561b8f77e8ef2ed6d83328860e16c81a5a8649" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/d0561b8f77e8ef2ed6d83328860e16c81a5a8649", + "reference": "d0561b8f77e8ef2ed6d83328860e16c81a5a8649", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/neon": "^2.3.3 || ~3.0.0", + "nette/php-generator": "^2.6.1 || ^3.0.0", + "nette/utils": "^2.5.0 || ~3.0.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/bootstrap": "<2.4", + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "time": "2019-01-30T13:26:05+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ] + }, + { + "name": "nette/finder", + "version": "v2.4.2", + "version_normalized": "2.4.2.0", + "source": { + "type": "git", + "url": "https://github.com/nette/finder.git", + "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/finder/zipball/ee951a656cb8ac622e5dd33474a01fd2470505a0", + "reference": "ee951a656cb8ac622e5dd33474a01fd2470505a0", + "shasum": "" + }, + "require": { + "nette/utils": "~2.4", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "time": "2018-06-28T11:49:23+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔍 Nette Finder: find files and directories with an intuitive API.", + "homepage": "https://nette.org", + "keywords": [ + "filesystem", + "glob", + "iterator", + "nette" + ] + }, + { + "name": "nette/neon", + "version": "v3.0.0", + "version_normalized": "3.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/cbff32059cbdd8720deccf9e9eace6ee516f02eb", + "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": ">=7.0" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "time": "2019-02-05T21:30:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "http://ne-on.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ] + }, + { + "name": "nette/php-generator", + "version": "v3.2.1", + "version_normalized": "3.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "9de4e093a130f7a1bd175198799ebc0efbac6924" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/9de4e093a130f7a1bd175198799ebc0efbac6924", + "reference": "9de4e093a130f7a1bd175198799ebc0efbac6924", + "shasum": "" + }, + "require": { + "nette/utils": "^2.4.2 || ~3.0.0", + "php": ">=7.1" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "time": "2018-11-27T19:00:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.3 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ] + }, + { + "name": "nette/robot-loader", + "version": "v3.1.0", + "version_normalized": "3.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/fc76c70e740b10f091e502b2e393d0be912f38d4", + "reference": "fc76c70e740b10f091e502b2e393d0be912f38d4", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/finder": "^2.3 || ^3.0", + "nette/utils": "^2.4 || ^3.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "time": "2018-08-13T14:19:06+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ] + }, + { + "name": "nette/utils", + "version": "v2.5.3", + "version_normalized": "2.5.3.0", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/17b9f76f2abd0c943adfb556e56f2165460b15ce", + "reference": "17b9f76f2abd0c943adfb556e56f2165460b15ce", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize() and toAscii()", + "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "time": "2018-09-18T10:22:16+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/loader.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ] + }, + { + "name": "nikic/php-parser", + "version": "v4.2.1", + "version_normalized": "4.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/5221f49a608808c1e4d436df32884cbc1b821ac0", + "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "time": "2019-02-16T20:54:15+00:00", + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "installation-source": "dist", + "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" + ] + }, + { + "name": "ocramius/package-versions", + "version": "1.4.0", + "version_normalized": "1.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.1.0" + }, + "require-dev": { + "composer/composer": "^1.6.3", + "doctrine/coding-standard": "^5.0.1", + "ext-zip": "*", + "infection/infection": "^0.7.1", + "phpunit/phpunit": "^7.0.0" + }, + "time": "2019-02-21T12:16:21+00:00", + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.3.1", + "version_normalized": "0.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/2cc49f47c69b023eaf05b48e6529389893b13d74", + "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "require-dev": { + "consistence/coding-standard": "^2.0.0", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/phpstan": "^0.10", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^3.3.0", + "symfony/process": "^3.4 || ^4.0" + }, + "time": "2019-01-14T12:26:23+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + }, + "installation-source": "dist", + "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" + }, + { + "name": "phpstan/phpstan", + "version": "0.11.2", + "version_normalized": "0.11.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "8e185a74004920419ee97bf9dc62e6a175e8dca5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8e185a74004920419ee97bf9dc62e6a175e8dca5", + "reference": "8e185a74004920419ee97bf9dc62e6a175e8dca5", + "shasum": "" + }, + "require": { + "composer/xdebug-handler": "^1.3.0", + "jean85/pretty-package-versions": "^1.0.3", + "nette/bootstrap": "^2.4 || ^3.0", + "nette/di": "^2.4.7 || ^3.0", + "nette/robot-loader": "^3.0.1", + "nette/utils": "^2.4.5 || ^3.0", + "nikic/php-parser": "^4.0.2", + "php": "~7.1", + "phpstan/phpdoc-parser": "^0.3", + "symfony/console": "~3.2 || ~4.0", + "symfony/finder": "~3.2 || ~4.0" + }, + "conflict": { + "symfony/console": "3.4.16 || 4.1.5" + }, + "require-dev": { + "brianium/paratest": "^2.0", + "consistence/coding-standard": "^3.5", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ext-intl": "*", + "ext-mysqli": "*", + "ext-soap": "*", + "ext-zip": "*", + "jakub-onderka/php-parallel-lint": "^1.0", + "localheinz/composer-normalize": "^1.1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-deprecation-rules": "^0.11", + "phpstan/phpstan-php-parser": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2" + }, + "time": "2019-02-12T14:54:38+00:00", + "bin": [ + "bin/phpstan" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.11-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "PHPStan\\": [ + "src/", + "build/PHPStan" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool" + }, + { + "name": "psr/log", + "version": "1.1.0", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2018-11-20T15:27:04+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "symfony/console", + "version": "v4.2.3", + "version_normalized": "4.2.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4", + "reference": "1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/contracts": "^1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "time": "2019-01-25T14:35:16+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "installation-source": "dist", + "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": "Symfony Console Component", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/contracts", + "version": "v1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/contracts.git", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "require-dev": { + "psr/cache": "^1.0", + "psr/container": "^1.0" + }, + "suggest": { + "psr/cache": "When using the Cache contracts", + "psr/container": "When using the Service contracts", + "symfony/cache-contracts-implementation": "", + "symfony/service-contracts-implementation": "", + "symfony/translation-contracts-implementation": "" + }, + "time": "2018-12-05T08:06:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\": "" + }, + "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": "A set of abstractions extracted out of the Symfony components", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ] + }, + { + "name": "symfony/finder", + "version": "v4.2.3", + "version_normalized": "4.2.3.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "ef71816cbb264988bb57fe6a73f610888b9aa70c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/ef71816cbb264988bb57fe6a73f610888b9aa70c", + "reference": "ef71816cbb264988bb57fe6a73f610888b9aa70c", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "time": "2019-01-16T20:35:37+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "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": "Symfony Finder Component", + "homepage": "https://symfony.com" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.10.0", + "version_normalized": "1.10.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/c79c051f5b3a46be09205c73b80b346e4153e494", + "reference": "c79c051f5b3a46be09205c73b80b346e4153e494", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2018-09-21T13:07:52+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "installation-source": "dist", + "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" + ] + } +] diff --git a/vendor/composer/xdebug-handler/CHANGELOG.md b/vendor/composer/xdebug-handler/CHANGELOG.md new file mode 100644 index 00000000..0ff10561 --- /dev/null +++ b/vendor/composer/xdebug-handler/CHANGELOG.md @@ -0,0 +1,55 @@ +## [Unreleased] + +## [1.3.2] - 2019-28-01 + * Fixed: exit call being blocked by uopz extension, resulting in application code running twice. + +## [1.3.1] - 2018-11-29 + * Fixed: fail restart if `passthru` has been disabled in `disable_functions`. + * Fixed: fail restart if an ini file cannot be opened, otherwise settings will be missing. + +## [1.3.0] - 2018-08-31 + * Added: `setPersistent` method to use environment variables for the restart. + * Fixed: improved debugging by writing output to stderr. + * Fixed: no restart when `php_ini_scanned_files` is not functional and is needed. + +## [1.2.1] - 2018-08-23 + * Fixed: fatal error with apc, when using `apc.mmap_file_mask`. + +## [1.2.0] - 2018-08-16 + * Added: debug information using `XDEBUG_HANDLER_DEBUG`. + * Added: fluent interface for setters. + * Added: `PhpConfig` helper class for calling PHP sub-processes. + * Added: `PHPRC` original value to restart stettings, for use in a restarted process. + * Changed: internal procedure to disable ini-scanning, using `-n` command-line option. + * Fixed: replaced `escapeshellarg` usage to avoid locale problems. + * Fixed: improved color-option handling to respect double-dash delimiter. + * Fixed: color-option handling regression from main script changes. + * Fixed: improved handling when checking main script. + * Fixed: handling for standard input, that never actually did anything. + * Fixed: fatal error when ctype extension is not available. + +## [1.1.0] - 2018-04-11 + * Added: `getRestartSettings` method for calling PHP processes in a restarted process. + * Added: API definition and @internal class annotations. + * Added: protected `requiresRestart` method for extending classes. + * Added: `setMainScript` method for applications that change the working directory. + * Changed: private `tmpIni` variable to protected for extending classes. + * Fixed: environment variables not available in $_SERVER when restored in the restart. + * Fixed: relative path problems caused by Phar::interceptFileFuncs. + * Fixed: incorrect handling when script file cannot be found. + +## [1.0.0] - 2018-03-08 + * Added: PSR3 logging for optional status output. + * Added: existing ini settings are merged to catch command-line overrides. + * Added: code, tests and other artefacts to decouple from Composer. + * Break: the following class was renamed: + - `Composer\XdebugHandler` -> `Composer\XdebugHandler\XdebugHandler` + +[Unreleased]: https://github.com/composer/xdebug-handler/compare/1.3.2...HEAD +[1.3.2]: https://github.com/composer/xdebug-handler/compare/1.3.1...1.3.2 +[1.3.1]: https://github.com/composer/xdebug-handler/compare/1.3.0...1.3.1 +[1.3.0]: https://github.com/composer/xdebug-handler/compare/1.2.1...1.3.0 +[1.2.1]: https://github.com/composer/xdebug-handler/compare/1.2.0...1.2.1 +[1.2.0]: https://github.com/composer/xdebug-handler/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/composer/xdebug-handler/compare/1.0.0...1.1.0 +[1.0.0]: https://github.com/composer/xdebug-handler/compare/d66f0d15cb57...1.0.0 diff --git a/vendor/composer/xdebug-handler/LICENSE b/vendor/composer/xdebug-handler/LICENSE new file mode 100644 index 00000000..963618a1 --- /dev/null +++ b/vendor/composer/xdebug-handler/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Composer + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/composer/xdebug-handler/README.md b/vendor/composer/xdebug-handler/README.md new file mode 100644 index 00000000..3b970607 --- /dev/null +++ b/vendor/composer/xdebug-handler/README.md @@ -0,0 +1,288 @@ +# composer/xdebug-handler + +[![packagist](https://img.shields.io/packagist/v/composer/xdebug-handler.svg)](https://packagist.org/packages/composer/xdebug-handler) +[![linux build](https://img.shields.io/travis/composer/xdebug-handler/master.svg?label=linux+build)](https://travis-ci.org/composer/xdebug-handler) +[![windows build](https://img.shields.io/appveyor/ci/Seldaek/xdebug-handler/master.svg?label=windows+build)](https://ci.appveyor.com/project/Seldaek/xdebug-handler) +![license](https://img.shields.io/github/license/composer/xdebug-handler.svg) +![php](https://img.shields.io/packagist/php-v/composer/xdebug-handler.svg?colorB=8892BF&label=php) + +Restart a CLI process without loading the xdebug extension. + +Originally written as part of [composer/composer](https://github.com/composer/composer), +now extracted and made available as a stand-alone library. + +## Installation + +Install the latest version with: + +```bash +$ composer require composer/xdebug-handler +``` + +## Requirements + +* PHP 5.3.2 minimum, although functionality is disabled below PHP 5.4.0. Using the latest PHP version is highly recommended. + +## Basic Usage +```php +use Composer\XdebugHandler\XdebugHandler; + +$xdebug = new XdebugHandler('myapp'); +$xdebug->check(); +unset($xdebug); +``` + +The constructor takes two parameters: + +#### _$envPrefix_ +This is used to create distinct environment variables and is upper-cased and prepended to default base values. The above example enables the use of: + +- `MYAPP_ALLOW_XDEBUG=1` to override automatic restart and allow xdebug +- `MYAPP_ORIGINAL_INIS` to obtain ini file locations in a restarted process + +#### _$colorOption_ +This optional value is added to the restart command-line and is needed to force color output in a piped child process. Only long-options are supported, for example `--ansi` or `--colors=always` etc. + +If the original command-line contains an argument that pattern matches this value (for example `--no-ansi`, `--colors=never`) then _$colorOption_ is ignored. + +If the pattern match ends with `=auto` (for example `--colors=auto`), the argument is replaced by _$colorOption_. Otherwise it is added at either the end of the command-line, or preceding the first double-dash `--` delimiter. + +## Advanced Usage + +* [How it works](#how-it-works) +* [Limitations](#limitations) +* [Helper methods](#helper-methods) +* [Setter methods](#setter-methods) +* [Process configuration](#process-configuration) +* [Troubleshooting](#troubleshooting) +* [Extending the library](#extending-the-library) + +### How it works + +A temporary ini file is created from the loaded (and scanned) ini files, with any references to the xdebug extension commented out. Current ini settings are merged, so that most ini settings made on the command-line or by the application are included (see [Limitations](#limitations)) + +* `MYAPP_ALLOW_XDEBUG` is set with internal data to flag and use in the restart. +* The command-line and environment are [configured](#process-configuration) for the restart. +* The application is restarted in a new process using `passthru`. + * The restart settings are stored in the environment. + * `MYAPP_ALLOW_XDEBUG` is unset. + * The application runs and exits. +* The main process exits with the exit code from the restarted process. + +### Limitations +There are a few things to be aware of when running inside a restarted process. + +* Extensions set on the command-line will not be loaded. +* Ini file locations will be reported as per the restart - see [getAllIniFiles()](#getallinifiles). +* Php sub-processes may be loaded with xdebug enabled - see [Process configuration](#process-configuration). + +### Helper methods +These static methods provide information from the current process, regardless of whether it has been restarted or not. + +#### _getAllIniFiles()_ +Returns an array of the original ini file locations. Use this instead of calling `php_ini_loaded_file` and `php_ini_scanned_files`, which will report the wrong values in a restarted process. + +```php +use Composer\XdebugHandler\XdebugHandler; + +$files = XdebugHandler::getAllIniFiles(); + +# $files[0] always exists, it could be an empty string +$loadedIni = array_shift($files); +$scannedInis = $files; +``` + +These locations are also available in the `MYAPP_ORIGINAL_INIS` environment variable. This is a path-separated string comprising the location returned from `php_ini_loaded_file`, which could be empty, followed by locations parsed from calling `php_ini_scanned_files`. + +#### _getRestartSettings()_ +Returns an array of settings that can be used with PHP [sub-processes](#sub-processes), or null if the process was not restarted. + +```php +use Composer\XdebugHandler\XdebugHandler; + +$settings = XdebugHandler::getRestartSettings(); +/** + * $settings: array (if the current process was restarted, + * or called with the settings from a previous restart), or null + * + * 'tmpIni' => the temporary ini file used in the restart (string) + * 'scannedInis' => if there were any scanned inis (bool) + * 'scanDir' => the original PHP_INI_SCAN_DIR value (false|string) + * 'phprc' => the original PHPRC value (false|string) + * 'inis' => the original inis from getAllIniFiles (array) + * 'skipped' => the skipped version from getSkippedVersion (string) + */ +``` + +#### _getSkippedVersion()_ +Returns the xdebug version string that was skipped by the restart, or an empty value if there was no restart (or xdebug is still loaded, perhaps by an extending class restarting for a reason other than removing xdebug). + +```php +use Composer\XdebugHandler\XdebugHandler; + +$version = XdebugHandler::getSkippedVersion(); +# $version: '2.6.0' (for example), or an empty string +``` + +### Setter methods +These methods implement a fluent interface and must be called before the main `check()` method. + +#### _setLogger($logger)_ +Enables the output of status messages to an external PSR3 logger. All messages are reported with either `DEBUG` or `WARNING` log levels. For example (showing the level and message): + +``` +// Restart overridden +DEBUG Checking MYAPP_ALLOW_XDEBUG +DEBUG The xdebug extension is loaded (2.5.0) +DEBUG No restart (MYAPP_ALLOW_XDEBUG=1) + +// Failed restart +DEBUG Checking MYAPP_ALLOW_XDEBUG +DEBUG The xdebug extension is loaded (2.5.0) +WARNING No restart (Unable to create temp ini file at: ...) +``` + +Status messages can also be output with `XDEBUG_HANDLER_DEBUG`. See [Troubleshooting](#troubleshooting). + +#### _setMainScript($script)_ +Sets the location of the main script to run in the restart. This is only needed in more esoteric use-cases, or if the `argv[0]` location is inaccessible. The script name `--` is supported for standard input. + +#### _setPersistent()_ +Configures the restart using [persistent settings](#persistent-settings), so that xdebug is not loaded in any sub-process. + +Use this method if your application invokes one or more PHP sub-process and the xdebug extension is not needed. This avoids the overhead of implementing specific [sub-process](#sub-processes) strategies. + +Alternatively, this method can be used to set up a default _xdebug-free_ environment which can be changed if a sub-process requires xdebug, then restored afterwards: + +```php +function SubProcessWithXdebug() +{ + $phpConfig = new Composer\XdebugHandler\PhpConfig(); + + # Set the environment to the original configuration + $phpConfig->useOriginal(); + + # run the process with xdebug loaded + ... + + # Restore xdebug-free environment + $phpConfig->usePersistent(); +} +``` + +### Process configuration +The library offers two strategies to invoke a new PHP process without loading xdebug, using either _standard_ or _persistent_ settings. Note that this is only important if the application calls a PHP sub-process. + +#### Standard settings +Uses command-line options to remove xdebug from the new process only. + +* The -n option is added to the command-line. This tells PHP not to scan for additional inis. +* The temporary ini is added to the command-line with the -c option. + +>_If the new process calls a PHP sub-process, xdebug will be loaded in that sub-process (unless it implements xdebug-handler, in which case there will be another restart)._ + +This is the default strategy used in the restart. + +#### Persistent settings +Uses environment variables to remove xdebug from the new process and persist these settings to any sub-process. + +* `PHP_INI_SCAN_DIR` is set to an empty string. This tells PHP not to scan for additional inis. +* `PHPRC` is set to the temporary ini. + +>_If the new process calls a PHP sub-process, xdebug will not be loaded in that sub-process._ + +This strategy can be used in the restart by calling [setPersistent()](#setpersistent). + +#### Sub-processes +The `PhpConfig` helper class makes it easy to invoke a PHP sub-process (with or without xdebug loaded), regardless of whether there has been a restart. + +Each of its methods returns an array of PHP options (to add to the command-line) and sets up the environment for the required strategy. The [getRestartSettings()](#getrestartsettings) method is used internally. + +* `useOriginal()` - xdebug will be loaded in the new process. +* `useStandard()` - xdebug will **not** be loaded in the new process - see [standard settings](#standard-settings). +* `userPersistent()` - xdebug will **not** be loaded in the new process - see [persistent settings](#persistent-settings) + +If there was no restart, an empty options array is returned and the environment is not changed. + +```php +use Composer\XdebugHandler\PhpConfig; + +$config = new PhpConfig; + +$options = $config->useOriginal(); +# $options: empty array +# environment: PHPRC and PHP_INI_SCAN_DIR set to original values + +$options = $config->useStandard(); +# $options: [-n, -c, tmpIni] +# environment: PHPRC and PHP_INI_SCAN_DIR set to original values + +$options = $config->usePersistent(); +# $options: empty array +# environment: PHPRC=tmpIni, PHP_INI_SCAN_DIR='' +``` + +### Troubleshooting +The following environment settings can be used to troubleshoot unexpected behavior: + +* `XDEBUG_HANDLER_DEBUG=1` Outputs status messages to `STDERR`, if it is defined, irrespective of any PSR3 logger. Each message is prefixed `xdebug-handler[pid]`, where pid is the process identifier. + +* `XDEBUG_HANDLER_DEBUG=2` As above, but additionally saves the temporary ini file and reports its location in a status message. + +### Extending the library +The API is defined by classes and their accessible elements that are not annotated as @internal. The main class has two protected methods that can be overridden to provide additional functionality: + +#### _requiresRestart($isLoaded)_ +By default the process will restart if xdebug is loaded. Extending this method allows an application to decide, by returning a boolean (or equivalent) value. It is only called if `MYAPP_ALLOW_XDEBUG` is empty, so it will not be called in the restarted process (where this variable contains internal data), or if the restart has been overridden. + +Note that the [setMainScript()](#setmainscriptscript) and [setPersistent()](#setpersistent) setters can be used here, if required. + +#### _restart($command)_ +An application can extend this to modify the temporary ini file, its location given in the `tmpIni` property. New settings can be safely appended to the end of the data, which is `PHP_EOL` terminated. + +Note that the `$command` parameter is the escaped command-line string that will be used for the new process and must be treated accordingly. + +Remember to finish with `parent::restart($command)`. + +#### Example +This example demonstrates two ways to extend basic functionality: + +* To avoid the overhead of spinning up a new process, the restart is skipped if a simple help command is requested. + +* The application needs write-access to phar files, so it will force a restart if `phar.readonly` is set (regardless of whether xdebug is loaded) and change this value in the temporary ini file. + +```php +use Composer\XdebugHandler\XdebugHandler; +use MyApp\Command; + +class MyRestarter extends XdebugHandler +{ + private $required; + + protected function requiresRestart($isLoaded) + { + if (Command::isHelp()) { + # No need to disable xdebug for this + return false; + } + + $this->required = (bool) ini_get('phar.readonly'); + return $isLoaded || $this->required; + } + + protected function restart($command) + { + if ($this->required) { + # Add required ini setting to tmpIni + $content = file_get_contents($this->tmpIni); + $content .= 'phar.readonly=0'.PHP_EOL; + file_put_contents($this->tmpIni, $content); + } + + parent::restart($command); + } +} +``` + +## License +composer/xdebug-handler is licensed under the MIT License, see the LICENSE file for details. diff --git a/vendor/composer/xdebug-handler/composer.json b/vendor/composer/xdebug-handler/composer.json new file mode 100644 index 00000000..b93de4d5 --- /dev/null +++ b/vendor/composer/xdebug-handler/composer.json @@ -0,0 +1,40 @@ +{ + "name": "composer/xdebug-handler", + "description": "Restarts a process without xdebug.", + "type": "library", + "license": "MIT", + "keywords": [ + "xdebug", + "performance" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Composer\\XdebugHandler\\": "tests" + } + }, + "scripts": { + "test": "phpunit" + } +} diff --git a/vendor/composer/xdebug-handler/src/PhpConfig.php b/vendor/composer/xdebug-handler/src/PhpConfig.php new file mode 100644 index 00000000..5535eca5 --- /dev/null +++ b/vendor/composer/xdebug-handler/src/PhpConfig.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\XdebugHandler; + +/** + * @author John Stevenson + */ +class PhpConfig +{ + /** + * Use the original PHP configuration + * + * @return array PHP cli options + */ + public function useOriginal() + { + $this->getDataAndReset(); + return array(); + } + + /** + * Use standard restart settings + * + * @return array PHP cli options + */ + public function useStandard() + { + if ($data = $this->getDataAndReset()) { + return array('-n', '-c', $data['tmpIni']); + } + + return array(); + } + + /** + * Use environment variables to persist settings + * + * @return array PHP cli options + */ + public function usePersistent() + { + if ($data = $this->getDataAndReset()) { + Process::setEnv('PHPRC', $data['tmpIni']); + Process::setEnv('PHP_INI_SCAN_DIR', ''); + } + + return array(); + } + + /** + * Returns restart data if available and resets the environment + * + * @return array|null + */ + private function getDataAndReset() + { + if ($data = XdebugHandler::getRestartSettings()) { + Process::setEnv('PHPRC', $data['phprc']); + Process::setEnv('PHP_INI_SCAN_DIR', $data['scanDir']); + } + + return $data; + } +} diff --git a/vendor/composer/xdebug-handler/src/Process.php b/vendor/composer/xdebug-handler/src/Process.php new file mode 100644 index 00000000..5ce877ba --- /dev/null +++ b/vendor/composer/xdebug-handler/src/Process.php @@ -0,0 +1,160 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\XdebugHandler; + +/** + * Provides utility functions to prepare a child process command-line and set + * environment variables in that process. + * + * @author John Stevenson + * @internal + */ +class Process +{ + /** + * Returns an array of parameters, including a color option if required + * + * A color option is needed because child process output is piped. + * + * @param array $args The script parameters + * @param string $colorOption The long option to force color output + * + * @return array + */ + public static function addColorOption(array $args, $colorOption) + { + if (!$colorOption + || in_array($colorOption, $args) + || !preg_match('/^--([a-z]+$)|(^--[a-z]+=)/', $colorOption, $matches)) { + return $args; + } + + if (isset($matches[2])) { + // Handle --color(s)= options + if (false !== ($index = array_search($matches[2].'auto', $args))) { + $args[$index] = $colorOption; + return $args; + } elseif (preg_grep('/^'.$matches[2].'/', $args)) { + return $args; + } + } elseif (in_array('--no-'.$matches[1], $args)) { + return $args; + } + + if (false !== ($index = array_search('--', $args))) { + // Position option before double-dash delimiter + array_splice($args, $index, 0, $colorOption); + } else { + $args[] = $colorOption; + } + + return $args; + } + + /** + * Escapes a string to be used as a shell argument. + * + * From https://github.com/johnstevenson/winbox-args + * MIT Licensed (c) John Stevenson + * + * @param string $arg The argument to be escaped + * @param bool $meta Additionally escape cmd.exe meta characters + * @param bool $module The argument is the module to invoke + * + * @return string The escaped argument + */ + public static function escape($arg, $meta = true, $module = false) + { + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + return "'".str_replace("'", "'\\''", $arg)."'"; + } + + $quote = strpbrk($arg, " \t") !== false || $arg === ''; + + $arg = preg_replace('/(\\\\*)"/', '$1$1\\"', $arg, -1, $dquotes); + + if ($meta) { + $meta = $dquotes || preg_match('/%[^%]+%/', $arg); + + if (!$meta) { + $quote = $quote || strpbrk($arg, '^&|<>()') !== false; + } elseif ($module && !$dquotes && $quote) { + $meta = false; + } + } + + if ($quote) { + $arg = '"'.preg_replace('/(\\\\*)$/', '$1$1', $arg).'"'; + } + + if ($meta) { + $arg = preg_replace('/(["^&|<>()%])/', '^$1', $arg); + } + + return $arg; + } + + /** + * Returns true if the output stream supports colors + * + * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo + * terminals via named pipes, so we can only check the environment. + * + * @param mixed $output A valid CLI output stream + * + * @return bool + */ + public static function supportsColor($output) + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + return (function_exists('sapi_windows_vt100_support') + && sapi_windows_vt100_support($output)) + || false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM'); + } + + if (function_exists('stream_isatty')) { + return stream_isatty($output); + } elseif (function_exists('posix_isatty')) { + return posix_isatty($output); + } + + $stat = fstat($output); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + } + + /** + * Makes putenv environment changes available in $_SERVER + * + * @param string $name + * @param string|false $value A false value unsets the variable + * + * @return bool Whether the environment variable was set + */ + public static function setEnv($name, $value = false) + { + $unset = false === $value; + + if (!putenv($unset ? $name : $name.'='.$value)) { + return false; + } + + if ($unset) { + unset($_SERVER[$name]); + } else { + $_SERVER[$name] = $value; + } + return true; + } +} diff --git a/vendor/composer/xdebug-handler/src/Status.php b/vendor/composer/xdebug-handler/src/Status.php new file mode 100644 index 00000000..24002777 --- /dev/null +++ b/vendor/composer/xdebug-handler/src/Status.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\XdebugHandler; + +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; + +/** + * @author John Stevenson + * @internal + */ +class Status +{ + const ENV_RESTART = 'XDEBUG_HANDLER_RESTART'; + const CHECK = 'Check'; + const ERROR = 'Error'; + const INFO = 'Info'; + const NORESTART = 'NoRestart'; + const RESTART = 'Restart'; + const RESTARTING = 'Restarting'; + const RESTARTED = 'Restarted'; + + private $debug; + private $envAllowXdebug; + private $loaded; + private $logger; + private $time; + + /** + * Constructor + * + * @param string $envAllowXdebug Prefixed _ALLOW_XDEBUG name + * @param bool $debug Whether debug output is required + */ + public function __construct($envAllowXdebug, $debug) + { + $start = getenv(self::ENV_RESTART); + Process::setEnv(self::ENV_RESTART); + $this->time = $start ? round((microtime(true) - $start) * 1000) : 0; + + $this->envAllowXdebug = $envAllowXdebug; + $this->debug = $debug && defined('STDERR'); + } + + /** + * @param LoggerInterface $logger + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * Calls a handler method to report a message + * + * @param string $op The handler constant + * @param null|string $data Data required by the handler + */ + public function report($op, $data) + { + if ($this->logger || $this->debug) { + call_user_func(array($this, 'report'.$op), $data); + } + } + + /** + * Outputs a status message + * + * @param string $text + * @param string $level + */ + private function output($text, $level = null) + { + if ($this->logger) { + $this->logger->log($level ?: LogLevel::DEBUG, $text); + } + + if ($this->debug) { + fwrite(STDERR, sprintf('xdebug-handler[%d] %s', getmypid(), $text.PHP_EOL)); + } + } + + private function reportCheck($loaded) + { + $this->loaded = $loaded; + $this->output('Checking '.$this->envAllowXdebug); + } + + private function reportError($error) + { + $this->output(sprintf('No restart (%s)', $error), LogLevel::WARNING); + } + + private function reportInfo($info) + { + $this->output($info); + } + + private function reportNoRestart() + { + $this->output($this->getLoadedMessage()); + + if ($this->loaded) { + $text = sprintf('No restart (%s)', $this->getEnvAllow()); + if (!getenv($this->envAllowXdebug)) { + $text .= ' Allowed by application'; + } + $this->output($text); + } + } + + private function reportRestart() + { + $this->output($this->getLoadedMessage()); + Process::setEnv(self::ENV_RESTART, (string) microtime(true)); + } + + private function reportRestarted() + { + $loaded = $this->getLoadedMessage(); + $text = sprintf('Restarted (%d ms). %s', $this->time, $loaded); + $level = $this->loaded ? LogLevel::WARNING : null; + $this->output($text, $level); + } + + private function reportRestarting($command) + { + $text = sprintf('Process restarting (%s)', $this->getEnvAllow()); + $this->output($text); + $text = 'Running '.$command; + $this->output($text); + } + + /** + * Returns the _ALLOW_XDEBUG environment variable as name=value + * + * @return string + */ + private function getEnvAllow() + { + return $this->envAllowXdebug.'='.getenv($this->envAllowXdebug); + } + + /** + * Returns the xdebug status and version + * + * @return string + */ + private function getLoadedMessage() + { + $loaded = $this->loaded ? sprintf('loaded (%s)', $this->loaded) : 'not loaded'; + return 'The xdebug extension is '.$loaded; + } +} diff --git a/vendor/composer/xdebug-handler/src/XdebugHandler.php b/vendor/composer/xdebug-handler/src/XdebugHandler.php new file mode 100644 index 00000000..39db8241 --- /dev/null +++ b/vendor/composer/xdebug-handler/src/XdebugHandler.php @@ -0,0 +1,565 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\XdebugHandler; + +use Psr\Log\LoggerInterface; + +/** + * @author John Stevenson + */ +class XdebugHandler +{ + const SUFFIX_ALLOW = '_ALLOW_XDEBUG'; + const SUFFIX_INIS = '_ORIGINAL_INIS'; + const RESTART_ID = 'internal'; + const RESTART_SETTINGS = 'XDEBUG_HANDLER_SETTINGS'; + const DEBUG = 'XDEBUG_HANDLER_DEBUG'; + + /** @var string|null */ + protected $tmpIni; + + private static $inRestart; + private static $name; + private static $skipped; + + private $cli; + private $colorOption; + private $debug; + private $envAllowXdebug; + private $envOriginalInis; + private $loaded; + private $persistent; + private $script; + /** @var Status|null */ + private $statusWriter; + + /** + * Constructor + * + * The $envPrefix is used to create distinct environment variables. It is + * uppercased and prepended to the default base values. For example 'myapp' + * would result in MYAPP_ALLOW_XDEBUG and MYAPP_ORIGINAL_INIS. + * + * @param string $envPrefix Value used in environment variables + * @param string $colorOption Command-line long option to force color output + * @throws \RuntimeException If a parameter is invalid + */ + public function __construct($envPrefix, $colorOption = '') + { + if (!is_string($envPrefix) || empty($envPrefix) || !is_string($colorOption)) { + throw new \RuntimeException('Invalid constructor parameter'); + } + + self::$name = strtoupper($envPrefix); + $this->envAllowXdebug = self::$name.self::SUFFIX_ALLOW; + $this->envOriginalInis = self::$name.self::SUFFIX_INIS; + + $this->colorOption = $colorOption; + + if (extension_loaded('xdebug')) { + $ext = new \ReflectionExtension('xdebug'); + $this->loaded = $ext->getVersion() ?: 'unknown'; + } + + if ($this->cli = PHP_SAPI === 'cli') { + $this->debug = getenv(self::DEBUG); + } + + $this->statusWriter = new Status($this->envAllowXdebug, (bool) $this->debug); + } + + /** + * Activates status message output to a PSR3 logger + * + * @param LoggerInterface $logger + * + * @return $this + */ + public function setLogger(LoggerInterface $logger) + { + $this->statusWriter->setLogger($logger); + return $this; + } + + /** + * Sets the main script location if it cannot be called from argv + * + * @param string $script + * + * @return $this + */ + public function setMainScript($script) + { + $this->script = $script; + return $this; + } + + /** + * Persist the settings to keep xdebug out of sub-processes + * + * @return $this + */ + public function setPersistent() + { + $this->persistent = true; + return $this; + } + + /** + * Checks if xdebug is loaded and the process needs to be restarted + * + * This behaviour can be disabled by setting the MYAPP_ALLOW_XDEBUG + * environment variable to 1. This variable is used internally so that + * the restarted process is created only once. + */ + public function check() + { + $this->notify(Status::CHECK, $this->loaded); + $envArgs = explode('|', (string) getenv($this->envAllowXdebug)); + + if (empty($envArgs[0]) && $this->requiresRestart((bool) $this->loaded)) { + // Restart required + $this->notify(Status::RESTART); + + if ($this->prepareRestart()) { + $command = $this->getCommand(); + $this->notify(Status::RESTARTING, $command); + $this->restart($command); + } + return; + } + + if (self::RESTART_ID === $envArgs[0] && count($envArgs) === 5) { + // Restarting, so unset environment variable and use saved values + $this->notify(Status::RESTARTED); + + Process::setEnv($this->envAllowXdebug); + self::$inRestart = true; + + if (!$this->loaded) { + // Skipped version is only set if xdebug is not loaded + self::$skipped = $envArgs[1]; + } + + // Put restart settings in the environment + $this->setEnvRestartSettings($envArgs); + return; + } + + $this->notify(Status::NORESTART); + + if ($settings = self::getRestartSettings()) { + // Called with existing settings, so sync our settings + $this->syncSettings($settings); + } + } + + /** + * Returns an array of php.ini locations with at least one entry + * + * The equivalent of calling php_ini_loaded_file then php_ini_scanned_files. + * The loaded ini location is the first entry and may be empty. + * + * @return array + */ + public static function getAllIniFiles() + { + if (!empty(self::$name)) { + $env = getenv(self::$name.self::SUFFIX_INIS); + + if (false !== $env) { + return explode(PATH_SEPARATOR, $env); + } + } + + $paths = array((string) php_ini_loaded_file()); + + if ($scanned = php_ini_scanned_files()) { + $paths = array_merge($paths, array_map('trim', explode(',', $scanned))); + } + + return $paths; + } + + /** + * Returns an array of restart settings or null + * + * Settings will be available if the current process was restarted, or + * called with the settings from an existing restart. + * + * @return array|null + */ + public static function getRestartSettings() + { + $envArgs = explode('|', (string) getenv(self::RESTART_SETTINGS)); + + if (count($envArgs) !== 6 + || (!self::$inRestart && php_ini_loaded_file() !== $envArgs[0])) { + return; + } + + return array( + 'tmpIni' => $envArgs[0], + 'scannedInis' => (bool) $envArgs[1], + 'scanDir' => '*' === $envArgs[2] ? false : $envArgs[2], + 'phprc' => '*' === $envArgs[3] ? false : $envArgs[3], + 'inis' => explode(PATH_SEPARATOR, $envArgs[4]), + 'skipped' => $envArgs[5], + ); + } + + /** + * Returns the xdebug version that triggered a successful restart + * + * @return string + */ + public static function getSkippedVersion() + { + return (string) self::$skipped; + } + + /** + * Returns true if xdebug is loaded, or as directed by an extending class + * + * @param bool $isLoaded Whether xdebug is loaded + * + * @return bool + */ + protected function requiresRestart($isLoaded) + { + return $isLoaded; + } + + /** + * Allows an extending class to access the tmpIni + * + * @param string $command + */ + protected function restart($command) + { + $this->doRestart($command); + } + + /** + * Executes the restarted command then deletes the tmp ini + * + * @param string $command + */ + private function doRestart($command) + { + passthru($command, $exitCode); + $this->notify(Status::INFO, 'Restarted process exited '.$exitCode); + + if ($this->debug === '2') { + $this->notify(Status::INFO, 'Temp ini saved: '.$this->tmpIni); + } else { + @unlink($this->tmpIni); + } + + exit($exitCode); + } + + /** + * Returns true if everything was written for the restart + * + * If any of the following fails (however unlikely) we must return false to + * stop potential recursion: + * - tmp ini file creation + * - environment variable creation + * + * @return bool + */ + private function prepareRestart() + { + $error = ''; + $iniFiles = self::getAllIniFiles(); + $scannedInis = count($iniFiles) > 1; + $tmpDir = sys_get_temp_dir(); + + if (!$this->cli) { + $error = 'Unsupported SAPI: '.PHP_SAPI; + } elseif (!defined('PHP_BINARY')) { + $error = 'PHP version is too old: '.PHP_VERSION; + } elseif (!$this->checkConfiguration($info)) { + $error = $info; + } elseif (!$this->checkScanDirConfig()) { + $error = 'PHP version does not report scanned inis: '.PHP_VERSION; + } elseif (!$this->checkMainScript()) { + $error = 'Unable to access main script: '.$this->script; + } elseif (!$this->writeTmpIni($iniFiles, $tmpDir, $error)) { + $error = $error ?: 'Unable to create temp ini file at: '.$tmpDir; + } elseif (!$this->setEnvironment($scannedInis, $iniFiles)) { + $error = 'Unable to set environment variables'; + } + + if ($error) { + $this->notify(Status::ERROR, $error); + } + + return empty($error); + } + + /** + * Returns true if the tmp ini file was written + * + * @param array $iniFiles All ini files used in the current process + * @param string $tmpDir The system temporary directory + * @param string $error Set by method if ini file cannot be read + * + * @return bool + */ + private function writeTmpIni(array $iniFiles, $tmpDir, &$error) + { + if (!$this->tmpIni = @tempnam($tmpDir, '')) { + return false; + } + + // $iniFiles has at least one item and it may be empty + if (empty($iniFiles[0])) { + array_shift($iniFiles); + } + + $content = ''; + $regex = '/^\s*(zend_extension\s*=.*xdebug.*)$/mi'; + + foreach ($iniFiles as $file) { + // Check for inaccessible ini files + if (!$data = @file_get_contents($file)) { + $error = 'Unable to read ini: '.$file; + return false; + } + $content .= preg_replace($regex, ';$1', $data).PHP_EOL; + } + + // Merge loaded settings into our ini content, if it is valid + if ($config = parse_ini_string($content)) { + $loaded = ini_get_all(null, false); + $content .= $this->mergeLoadedConfig($loaded, $config); + } + + // Work-around for https://bugs.php.net/bug.php?id=75932 + $content .= 'opcache.enable_cli=0'.PHP_EOL; + + return @file_put_contents($this->tmpIni, $content); + } + + /** + * Returns the restart command line + * + * @return string + */ + private function getCommand() + { + $php = array(PHP_BINARY); + $args = array_slice($_SERVER['argv'], 1); + + if (!$this->persistent) { + // Use command-line options + array_push($php, '-n', '-c', $this->tmpIni); + } + + if (defined('STDOUT') && Process::supportsColor(STDOUT)) { + $args = Process::addColorOption($args, $this->colorOption); + } + + $args = array_merge($php, array($this->script), $args); + + $cmd = Process::escape(array_shift($args), true, true); + foreach ($args as $arg) { + $cmd .= ' '.Process::escape($arg); + } + + return $cmd; + } + + /** + * Returns true if the restart environment variables were set + * + * No need to update $_SERVER since this is set in the restarted process. + * + * @param bool $scannedInis Whether there were scanned ini files + * @param array $iniFiles All ini files used in the current process + * + * @return bool + */ + private function setEnvironment($scannedInis, array $iniFiles) + { + $scanDir = getenv('PHP_INI_SCAN_DIR'); + $phprc = getenv('PHPRC'); + + // Make original inis available to restarted process + if (!putenv($this->envOriginalInis.'='.implode(PATH_SEPARATOR, $iniFiles))) { + return false; + } + + if ($this->persistent) { + // Use the environment to persist the settings + if (!putenv('PHP_INI_SCAN_DIR=') || !putenv('PHPRC='.$this->tmpIni)) { + return false; + } + } + + // Flag restarted process and save values for it to use + $envArgs = array( + self::RESTART_ID, + $this->loaded, + (int) $scannedInis, + false === $scanDir ? '*' : $scanDir, + false === $phprc ? '*' : $phprc, + ); + + return putenv($this->envAllowXdebug.'='.implode('|', $envArgs)); + } + + /** + * Logs status messages + * + * @param string $op Status handler constant + * @param null|string $data Optional data + */ + private function notify($op, $data = null) + { + $this->statusWriter->report($op, $data); + } + + /** + * Returns default, changed and command-line ini settings + * + * @param array $loadedConfig All current ini settings + * @param array $iniConfig Settings from user ini files + * + * @return string + */ + private function mergeLoadedConfig(array $loadedConfig, array $iniConfig) + { + $content = ''; + + foreach ($loadedConfig as $name => $value) { + // Value will either be null, string or array (HHVM only) + if (!is_string($value) + || strpos($name, 'xdebug') === 0 + || $name === 'apc.mmap_file_mask') { + continue; + } + + if (!isset($iniConfig[$name]) || $iniConfig[$name] !== $value) { + // Double-quote escape each value + $content .= $name.'="'.addcslashes($value, '\\"').'"'.PHP_EOL; + } + } + + return $content; + } + + /** + * Returns true if the script name can be used + * + * @return bool + */ + private function checkMainScript() + { + if (null !== $this->script) { + // Allow an application to set -- for standard input + return file_exists($this->script) || '--' === $this->script; + } + + if (file_exists($this->script = $_SERVER['argv'][0])) { + return true; + } + + // Use a backtrace to resolve Phar and chdir issues + $options = PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false; + $trace = debug_backtrace($options); + + if (($main = end($trace)) && isset($main['file'])) { + return file_exists($this->script = $main['file']); + } + + return false; + } + + /** + * Adds restart settings to the environment + * + * @param string $envArgs + */ + private function setEnvRestartSettings($envArgs) + { + $settings = array( + php_ini_loaded_file(), + $envArgs[2], + $envArgs[3], + $envArgs[4], + getenv($this->envOriginalInis), + self::$skipped, + ); + + Process::setEnv(self::RESTART_SETTINGS, implode('|', $settings)); + } + + /** + * Syncs settings and the environment if called with existing settings + * + * @param array $settings + */ + private function syncSettings(array $settings) + { + if (false === getenv($this->envOriginalInis)) { + // Called by another app, so make original inis available + Process::setEnv($this->envOriginalInis, implode(PATH_SEPARATOR, $settings['inis'])); + } + + self::$skipped = $settings['skipped']; + $this->notify(Status::INFO, 'Process called with existing restart settings'); + } + + /** + * Returns true if there are scanned inis and PHP is able to report them + * + * php_ini_scanned_files will fail when PHP_CONFIG_FILE_SCAN_DIR is empty. + * Fixed in 7.1.13 and 7.2.1 + * + * @return bool + */ + private function checkScanDirConfig() + { + return !(getenv('PHP_INI_SCAN_DIR') + && !PHP_CONFIG_FILE_SCAN_DIR + && (PHP_VERSION_ID < 70113 + || PHP_VERSION_ID === 70200)); + } + + /** + * Returns true if there are no known configuration issues + * + * @param string $info Set by method + */ + private function checkConfiguration(&$info) + { + if (false !== strpos(ini_get('disable_functions'), 'passthru')) { + $info = 'passthru function is disabled'; + return false; + } + + if (extension_loaded('uopz')) { + // uopz works at opcode level and disables exit calls + if (function_exists('uopz_allow_exit')) { + @uopz_allow_exit(true); + } else { + $info = 'uopz extension is not compatible'; + return false; + } + } + + return true; + } +} diff --git a/vendor/jean85/pretty-package-versions/composer.json b/vendor/jean85/pretty-package-versions/composer.json new file mode 100644 index 00000000..02ee3012 --- /dev/null +++ b/vendor/jean85/pretty-package-versions/composer.json @@ -0,0 +1,43 @@ +{ + "name": "jean85/pretty-package-versions", + "description": "A wrapper for ocramius/package-versions to get pretty versions strings", + "type": "library", + "require": { + "php": "^7.0", + "ocramius/package-versions": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "license": "MIT", + "authors": [ + { + "name": "Alessandro Lai", + "email": "alessandro.lai85@gmail.com" + } + ], + "support": { + "issues": "https://github.com/Jean85/pretty-package-versions/issues" + }, + "keywords": [ + "package", + "versions", + "composer", + "release" + ], + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Jean85\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests" + } + } +} diff --git a/vendor/jean85/pretty-package-versions/src/PrettyVersions.php b/vendor/jean85/pretty-package-versions/src/PrettyVersions.php new file mode 100644 index 00000000..5ffebf6e --- /dev/null +++ b/vendor/jean85/pretty-package-versions/src/PrettyVersions.php @@ -0,0 +1,15 @@ +packageName = $packageName; + $splittedVersion = explode('@', $version); + $this->shortVersion = $splittedVersion[0]; + $this->commitHash = $splittedVersion[1]; + $this->versionIsTagged = preg_match('/[^v\d\.]/', $this->getShortVersion()) === 0; + } + + public function getPrettyVersion(): string + { + if ($this->versionIsTagged) { + return $this->getShortVersion(); + } + + return $this->getVersionWithShortCommit(); + } + + public function getFullVersion(): string + { + return $this->getShortVersion() . '@' . $this->getCommitHash(); + } + + public function getVersionWithShortCommit(): string + { + return $this->getShortVersion() . '@' . $this->getShortCommitHash(); + } + + public function getPackageName(): string + { + return $this->packageName; + } + + public function getShortVersion(): string + { + return $this->shortVersion; + } + + public function getCommitHash(): string + { + return $this->commitHash; + } + + public function getShortCommitHash(): string + { + return substr($this->commitHash, 0, self::SHORT_COMMIT_LENGTH); + } + + public function __toString(): string + { + return $this->getPrettyVersion(); + } +} diff --git a/vendor/nette/bootstrap/composer.json b/vendor/nette/bootstrap/composer.json new file mode 100644 index 00000000..4844717c --- /dev/null +++ b/vendor/nette/bootstrap/composer.json @@ -0,0 +1,52 @@ +{ + "name": "nette/bootstrap", + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "keywords": ["nette", "configurator", "bootstrapping"], + "homepage": "https://nette.org", + "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "require": { + "php": ">=5.6.0", + "nette/di": "~2.4.7", + "nette/utils": "~2.4" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "require-dev": { + "nette/application": "~2.3", + "nette/caching": "~2.3", + "nette/database": "~2.3", + "nette/forms": "~2.3", + "nette/http": "~2.4.0", + "nette/mail": "~2.3", + "nette/robot-loader": "^2.4.2 || ^3.0", + "nette/safe-stream": "~2.2", + "nette/security": "~2.3", + "nette/tester": "~2.0", + "latte/latte": "~2.2", + "tracy/tracy": "^2.4.1" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "autoload": { + "classmap": ["src/"] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + } +} diff --git a/vendor/nette/bootstrap/contributing.md b/vendor/nette/bootstrap/contributing.md new file mode 100644 index 00000000..860882bf --- /dev/null +++ b/vendor/nette/bootstrap/contributing.md @@ -0,0 +1,27 @@ +How to contribute & use the issue tracker +========================================= + +The issue tracker is the preferred channel for bug reports, features requests +and submitting pull requests, but please respect the following restrictions: + +* Please **do not** use the issue tracker for personal support requests (use + [Nette forum](https://forum.nette.org) or [Stack Overflow](http://stackoverflow.com)). + +* Please **do not** derail or troll issues. Keep the discussion on topic and + respect the opinions of others. + +* Use the GitHub **issue search** — check if the issue has already been + reported. + +A good **bug report** shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. + +**Feature requests** are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the project's developers of the merits of this feature. + +Nette welcomes **pull requests**. If you'd like to contribute, please take a moment +to [read the guidelines](https://nette.org/en/contributing) in order to make +the contribution process easy and effective for everyone involved. + +Thanks! diff --git a/vendor/nette/bootstrap/license.md b/vendor/nette/bootstrap/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/nette/bootstrap/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" 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. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/bootstrap/readme.md b/vendor/nette/bootstrap/readme.md new file mode 100644 index 00000000..4b11593c --- /dev/null +++ b/vendor/nette/bootstrap/readme.md @@ -0,0 +1,61 @@ +Nette Bootstrap +=============== + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/bootstrap.svg)](https://packagist.org/packages/nette/bootstrap) +[![Build Status](https://travis-ci.org/nette/bootstrap.svg?branch=master)](https://travis-ci.org/nette/bootstrap) +[![Coverage Status](https://coveralls.io/repos/github/nette/bootstrap/badge.svg?branch=master)](https://coveralls.io/github/nette/bootstrap?branch=master) +[![Latest Stable Version](https://poser.pugx.org/nette/bootstrap/v/stable)](https://github.com/nette/bootstrap/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/bootstrap/blob/master/license.md) + +File `bootstrap.php` loads Nette Framework and all libraries that we depend on: + +```php +require __DIR__ . '/../vendor/autoload.php'; +``` + +Class `Configurator` creates so called DI container and handles application initialization. + +```php +$configurator = new Nette\Configurator; +``` + +Activates Tracy in strict mode: + +```php +//$configurator->setDebugMode(true); +$configurator->enableTracy(__DIR__ . '/../log'); +``` + +Setup directory for temporary files + +```php +$configurator->setTempDirectory(__DIR__ . '/../temp'); +``` + +Activate [autoloading](https://doc.nette.org/en/auto-loading#toc-nette-loaders-robotloader), that will automatically load all the files with our classes: + +```php +$configurator->createRobotLoader() + ->addDirectory(__DIR__) + ->addDirectory(__DIR__ . '/../vendor/others') + ->register(); +``` + +And according to the configuration files it generates a DI container. Everything else depends on it. + +We will return this DI Container as a result of calling `app/boostrap.php` + +```php +$configurator->addConfig(__DIR__ . '/config/config.neon'); +$configurator->addConfig(__DIR__ . '/config/config.local.neon'); +return $configurator->createContainer(); +``` + +and we will store it as local variable in `www/index.php` and run the application: + +```php +$container = require __DIR__ . '/../app/bootstrap.php'; +$container->getService('application')->run(); +``` + +That's it. diff --git a/vendor/nette/bootstrap/src/Bootstrap/Configurator.php b/vendor/nette/bootstrap/src/Bootstrap/Configurator.php new file mode 100644 index 00000000..f91abddf --- /dev/null +++ b/vendor/nette/bootstrap/src/Bootstrap/Configurator.php @@ -0,0 +1,395 @@ + Nette\DI\Extensions\PhpExtension::class, + 'constants' => Nette\DI\Extensions\ConstantsExtension::class, + 'extensions' => Nette\DI\Extensions\ExtensionsExtension::class, + 'application' => [Nette\Bridges\ApplicationDI\ApplicationExtension::class, ['%debugMode%', ['%appDir%'], '%tempDir%/cache']], + 'decorator' => Nette\DI\Extensions\DecoratorExtension::class, + 'cache' => [Nette\Bridges\CacheDI\CacheExtension::class, ['%tempDir%']], + 'database' => [Nette\Bridges\DatabaseDI\DatabaseExtension::class, ['%debugMode%']], + 'di' => [Nette\DI\Extensions\DIExtension::class, ['%debugMode%']], + 'forms' => Nette\Bridges\FormsDI\FormsExtension::class, + 'http' => [Nette\Bridges\HttpDI\HttpExtension::class, ['%consoleMode%']], + 'latte' => [Nette\Bridges\ApplicationDI\LatteExtension::class, ['%tempDir%/cache/latte', '%debugMode%']], + 'mail' => Nette\Bridges\MailDI\MailExtension::class, + 'routing' => [Nette\Bridges\ApplicationDI\RoutingExtension::class, ['%debugMode%']], + 'security' => [Nette\Bridges\SecurityDI\SecurityExtension::class, ['%debugMode%']], + 'session' => [Nette\Bridges\HttpDI\SessionExtension::class, ['%debugMode%', '%consoleMode%']], + 'tracy' => [Tracy\Bridges\Nette\TracyExtension::class, ['%debugMode%', '%consoleMode%']], + 'inject' => Nette\DI\Extensions\InjectExtension::class, + ]; + + /** @var string[] of classes which shouldn't be autowired */ + public $autowireExcludedClasses = [ + 'stdClass', + ]; + + /** @var array */ + protected $parameters; + + /** @var array */ + protected $dynamicParameters = []; + + /** @var array */ + protected $services = []; + + /** @var array [file|array, section] */ + protected $files = []; + + + public function __construct() + { + $this->parameters = $this->getDefaultParameters(); + } + + + /** + * Set parameter %debugMode%. + * @param bool|string|array $value + * @return static + */ + public function setDebugMode($value) + { + if (is_string($value) || is_array($value)) { + $value = static::detectDebugMode($value); + } elseif (!is_bool($value)) { + throw new Nette\InvalidArgumentException(sprintf('Value must be either a string, array, or boolean, %s given.', gettype($value))); + } + $this->parameters['debugMode'] = $value; + $this->parameters['productionMode'] = !$this->parameters['debugMode']; // compatibility + return $this; + } + + + /** + * @return bool + */ + public function isDebugMode() + { + return $this->parameters['debugMode']; + } + + + /** + * Sets path to temporary directory. + * @param string $path + * @return static + */ + public function setTempDirectory($path) + { + $this->parameters['tempDir'] = $path; + return $this; + } + + + /** + * Sets the default timezone. + * @param string $timezone + * @return static + */ + public function setTimeZone($timezone) + { + date_default_timezone_set($timezone); + @ini_set('date.timezone', $timezone); // @ - function may be disabled + return $this; + } + + + /** + * Adds new parameters. The %params% will be expanded. + * @return static + */ + public function addParameters(array $params) + { + $this->parameters = DI\Config\Helpers::merge($params, $this->parameters); + return $this; + } + + + /** + * Adds new dynamic parameters. + * @return static + */ + public function addDynamicParameters(array $params) + { + $this->dynamicParameters = $params + $this->dynamicParameters; + return $this; + } + + + /** + * Add instances of services. + * @return static + */ + public function addServices(array $services) + { + $this->services = $services + $this->services; + return $this; + } + + + /** + * @return array + */ + protected function getDefaultParameters() + { + $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + $last = end($trace); + $debugMode = static::detectDebugMode(); + return [ + 'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : null, + 'wwwDir' => isset($last['file']) ? dirname($last['file']) : null, + 'debugMode' => $debugMode, + 'productionMode' => !$debugMode, + 'consoleMode' => PHP_SAPI === 'cli', + ]; + } + + + /** + * @param string $logDirectory + * @param string $email + * @return void + */ + public function enableTracy($logDirectory = null, $email = null) + { + $this->enableDebugger($logDirectory, $email); + } + + + /** + * Alias for enableTracy() + * @param string $logDirectory + * @param string $email + * @return void + */ + public function enableDebugger($logDirectory = null, $email = null) + { + Tracy\Debugger::$strictMode = true; + Tracy\Debugger::enable(!$this->parameters['debugMode'], $logDirectory, $email); + Nette\Bridges\Framework\TracyBridge::initialize(); + } + + + /** + * @return Nette\Loaders\RobotLoader + * @throws Nette\NotSupportedException if RobotLoader is not available + */ + public function createRobotLoader() + { + if (!class_exists(Nette\Loaders\RobotLoader::class)) { + throw new Nette\NotSupportedException('RobotLoader not found, do you have `nette/robot-loader` package installed?'); + } + + $loader = new Nette\Loaders\RobotLoader; + $loader->setTempDirectory($this->getCacheDirectory() . '/Nette.RobotLoader'); + $loader->setAutoRefresh($this->parameters['debugMode']); + return $loader; + } + + + /** + * Adds configuration file. + * @param string|array $file + * @return static + */ + public function addConfig($file) + { + $section = func_num_args() > 1 ? func_get_arg(1) : null; + if ($section !== null) { + trigger_error('Sections in config file are deprecated.', E_USER_DEPRECATED); + } + $this->files[] = [$file, $section === self::AUTO ? ($this->parameters['debugMode'] ? 'development' : 'production') : $section]; + return $this; + } + + + /** + * Returns system DI container. + * @return DI\Container + */ + public function createContainer() + { + $class = $this->loadContainer(); + $container = new $class($this->dynamicParameters); + foreach ($this->services as $name => $service) { + $container->addService($name, $service); + } + $container->initialize(); + if (class_exists(Nette\Environment::class)) { + Nette\Environment::setContext($container); // back compatibility + } + return $container; + } + + + /** + * Loads system DI container class and returns its name. + * @return string + */ + public function loadContainer() + { + $loader = new DI\ContainerLoader( + $this->getCacheDirectory() . '/Nette.Configurator', + $this->parameters['debugMode'] + ); + $class = $loader->load( + [$this, 'generateContainer'], + [$this->parameters, array_keys($this->dynamicParameters), $this->files, PHP_VERSION_ID - PHP_RELEASE_VERSION] + ); + return $class; + } + + + /** + * @return string + * @internal + */ + public function generateContainer(DI\Compiler $compiler) + { + $compiler->addConfig(['parameters' => $this->parameters]); + $compiler->setDynamicParameterNames(array_keys($this->dynamicParameters)); + + $loader = $this->createLoader(); + $fileInfo = []; + foreach ($this->files as $info) { + if (is_scalar($info[0])) { + $fileInfo[] = "// source: $info[0] $info[1]"; + $info[0] = $loader->load($info[0], $info[1]); + } + $compiler->addConfig($this->fixCompatibility($info[0])); + } + $compiler->addDependencies($loader->getDependencies()); + + $builder = $compiler->getContainerBuilder(); + $builder->addExcludedClasses($this->autowireExcludedClasses); + + foreach ($this->defaultExtensions as $name => $extension) { + list($class, $args) = is_string($extension) ? [$extension, []] : $extension; + if (class_exists($class)) { + $args = DI\Helpers::expand($args, $this->parameters, true); + $compiler->addExtension($name, (new \ReflectionClass($class))->newInstanceArgs($args)); + } + } + + $this->onCompile($this, $compiler); + + $classes = $compiler->compile(); + return implode("\n", $fileInfo) . "\n\n" . $classes; + } + + + /** + * @return DI\Config\Loader + */ + protected function createLoader() + { + return new DI\Config\Loader; + } + + + /** + * @return string + */ + protected function getCacheDirectory() + { + if (empty($this->parameters['tempDir'])) { + throw new Nette\InvalidStateException('Set path to temporary directory using setTempDirectory().'); + } + $dir = $this->parameters['tempDir'] . '/cache'; + Nette\Utils\FileSystem::createDir($dir); + return $dir; + } + + + /** + * Back compatibility with < v2.3 + * @return array + */ + protected function fixCompatibility($config) + { + if (isset($config['nette']['security']['frames'])) { + $config['nette']['http']['frames'] = $config['nette']['security']['frames']; + unset($config['nette']['security']['frames']); + } + foreach (['application', 'cache', 'database', 'di' => 'container', 'forms', 'http', + 'latte', 'mail' => 'mailer', 'routing', 'security', 'session', 'tracy' => 'debugger', ] as $new => $old) { + if (isset($config['nette'][$old])) { + $new = is_int($new) ? $old : $new; + if (isset($config[$new])) { + throw new Nette\DeprecatedException("You can use (deprecated) section 'nette.$old' or new section '$new', but not both of them."); + } else { + trigger_error("Configuration section 'nette.$old' is deprecated, use section '$new' (without 'nette')", E_USER_DEPRECATED); + } + $config[$new] = $config['nette'][$old]; + unset($config['nette'][$old]); + } + } + if (isset($config['nette']['xhtml'])) { + trigger_error("Configuration option 'nette.xhtml' is deprecated, use section 'latte.xhtml' instead.", E_USER_DEPRECATED); + $config['latte']['xhtml'] = $config['nette']['xhtml']; + unset($config['nette']['xhtml']); + } + + if (empty($config['nette'])) { + unset($config['nette']); + } + return $config; + } + + + /********************* tools ****************d*g**/ + + + /** + * Detects debug mode by IP addresses or computer names whitelist detection. + * @param string|array $list + * @return bool + */ + public static function detectDebugMode($list = null) + { + $addr = isset($_SERVER['REMOTE_ADDR']) + ? $_SERVER['REMOTE_ADDR'] + : php_uname('n'); + $secret = isset($_COOKIE[self::COOKIE_SECRET]) && is_string($_COOKIE[self::COOKIE_SECRET]) + ? $_COOKIE[self::COOKIE_SECRET] + : null; + $list = is_string($list) + ? preg_split('#[,\s]+#', $list) + : (array) $list; + if (!isset($_SERVER['HTTP_X_FORWARDED_FOR']) && !isset($_SERVER['HTTP_FORWARDED'])) { + $list[] = '127.0.0.1'; + $list[] = '::1'; + } + return in_array($addr, $list, true) || in_array("$secret@$addr", $list, true); + } +} diff --git a/vendor/nette/bootstrap/src/Bridges/Framework/TracyBridge.php b/vendor/nette/bootstrap/src/Bridges/Framework/TracyBridge.php new file mode 100644 index 00000000..addcebbf --- /dev/null +++ b/vendor/nette/bootstrap/src/Bridges/Framework/TracyBridge.php @@ -0,0 +1,74 @@ +getPanel('Tracy:info')->data['Nette Framework'] = $version; + $blueScreen->info[] = "Nette Framework $version"; + } + + if (class_exists(Tracy\Bridges\Nette\Bridge::class)) { + Tracy\Bridges\Nette\Bridge::initialize(); + return; + } + + $blueScreen->addPanel(function ($e) { + if ($e instanceof Latte\CompileException) { + return [ + 'tab' => 'Template', + 'panel' => (preg_match('#\n|\?#', $e->sourceName) + ? '' + : '

' + . (@is_file($e->sourceName) // @ - may trigger error + ? 'File: ' . Helpers::editorLink($e->sourceName, $e->sourceLine) + : '' . htmlspecialchars($e->sourceName . ($e->sourceLine ? ':' . $e->sourceLine : '')) . '') + . '

') + . '
' + . BlueScreen::highlightLine(htmlspecialchars($e->sourceCode, ENT_IGNORE, 'UTF-8'), $e->sourceLine) + . '
', + ]; + } + }); + + $blueScreen->addPanel(function ($e) { + if ( + $e instanceof Nette\Neon\Exception + && preg_match('#line (\d+)#', $e->getMessage(), $m) + && ($trace = Helpers::findTrace($e->getTrace(), 'Nette\Neon\Decoder::decode')) + ) { + return [ + 'tab' => 'NEON', + 'panel' => ($trace2 = Helpers::findTrace($e->getTrace(), 'Nette\DI\Config\Adapters\NeonAdapter::load')) + ? '

File: ' . Helpers::editorLink($trace2['args'][0], $m[1]) . '

' + . BlueScreen::highlightFile($trace2['args'][0], $m[1]) + : BlueScreen::highlightPhp($trace['args'][0], $m[1]), + ]; + } + }); + } +} diff --git a/vendor/nette/di/.phpstorm.meta.php b/vendor/nette/di/.phpstorm.meta.php new file mode 100644 index 00000000..9c69a470 --- /dev/null +++ b/vendor/nette/di/.phpstorm.meta.php @@ -0,0 +1,5 @@ + '@'])); diff --git a/vendor/nette/di/composer.json b/vendor/nette/di/composer.json new file mode 100644 index 00000000..3904c359 --- /dev/null +++ b/vendor/nette/di/composer.json @@ -0,0 +1,41 @@ +{ + "name": "nette/di", + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", + "keywords": ["nette", "di", "dic", "ioc", "factory", "compiled", "static"], + "homepage": "https://nette.org", + "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "require": { + "php": ">=5.6.0", + "ext-tokenizer": "*", + "nette/neon": "^2.3.3 || ~3.0.0", + "nette/php-generator": "^2.6.1 || ^3.0.0", + "nette/utils": "^2.5.0 || ~3.0.0" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "conflict": { + "nette/nette": "<2.2", + "nette/bootstrap": "<2.4" + }, + "autoload": { + "classmap": ["src/"] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + } +} diff --git a/vendor/nette/di/contributing.md b/vendor/nette/di/contributing.md new file mode 100644 index 00000000..184152c0 --- /dev/null +++ b/vendor/nette/di/contributing.md @@ -0,0 +1,33 @@ +How to contribute & use the issue tracker +========================================= + +Nette welcomes your contributions. There are several ways to help out: + +* Create an issue on GitHub, if you have found a bug +* Write test cases for open bug issues +* Write fixes for open bug/feature issues, preferably with test cases included +* Contribute to the [documentation](https://nette.org/en/writing) + +Issues +------ + +Please **do not use the issue tracker to ask questions**. We will be happy to help you +on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette). + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. + +**Feature requests** are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the project's developers of the merits of this feature. + +Contributing +------------ + +If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing). + +The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them. + +Please do not fix whitespace, format code, or make a purely cosmetic patch. + +Thanks! :heart: diff --git a/vendor/nette/di/license.md b/vendor/nette/di/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/nette/di/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" 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. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/di/readme.md b/vendor/nette/di/readme.md new file mode 100644 index 00000000..c05d7a45 --- /dev/null +++ b/vendor/nette/di/readme.md @@ -0,0 +1,330 @@ +Nette Dependency Injection (DI) +=============================== + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/di.svg)](https://packagist.org/packages/nette/di) +[![Build Status](https://travis-ci.org/nette/di.svg?branch=master)](https://travis-ci.org/nette/di) +[![Coverage Status](https://coveralls.io/repos/github/nette/di/badge.svg?branch=master)](https://coveralls.io/github/nette/di?branch=master) +[![Latest Stable Version](https://poser.pugx.org/nette/di/v/stable)](https://github.com/nette/di/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/di/blob/master/license.md) + +Purpose of the Dependecy Injection (DI) is to free classes from the responsibility for obtaining objects that they need for its operation (these objects are called **services**). To pass them these services on their instantiation instead. + +Nette DI is one of the most interesting part of framework. It is compiled DI container, extremely fast and easy to configure. + +Let's have an application for sending newsletters. The code is maximally simplified and is available on the [GitHub](https://github.com/dg/di-example). + +We have the object representing email: + +```php +class Mail +{ + public $subject; + public $message; +} +``` + +An object which can send emails: + +```php +interface Mailer +{ + function send(Mail $mail, $to); +} +``` + +A support for logging: + +```php +interface Logger +{ + function log($message); +} +``` + +And finally, a class that provides sending newsletters: + +```php +class NewsletterManager +{ + private $mailer; + private $logger; + + function __construct(Mailer $mailer, Logger $logger) + { + $this->mailer = $mailer; + $this->logger = $logger; + } + + function distribute(array $recipients) + { + $mail = new Mail; + ... + foreach ($recipients as $recipient) { + $this->mailer->send($mail, $recipient); + } + $this->logger->log(...); + } +} +``` + +The code respects Dependency Injection, ie. **each object uses only variables which we had passed into it.** + +Also, we have a ability to implement own `Logger` or `Mailer`, like this: + +```php +class SendMailMailer implements Mailer +{ + function send(Mail $mail, $to) + { + mail($to, $mail->subject, $mail->message); + } +} + +class FileLogger implements Logger +{ + private $file; + + function __construct($file) + { + $this->file = $file; + } + + function log($message) + { + file_put_contents($this->file, $message . "\n", FILE_APPEND); + } +} +``` + +**DI container is the supreme architect** which can create individual objects (in the terminology DI called services) and assemble and configure them exactly according to our needs. + +Container for our application might look like this: + +```php +class Container +{ + private $logger; + private $mailer; + + function getLogger() + { + if (!$this->logger) { + $this->logger = new FileLogger('log.txt'); + } + return $this->logger; + } + + function getMailer() + { + if (!$this->mailer) { + $this->mailer = new SendMailMailer; + } + return $this->mailer; + } + + function createNewsletterManager() + { + return new NewsletterManager($this->getMailer(), $this->getLogger()); + } +} +``` + +The implementation looks like this because: +- the individual services are created only on demand (lazy loading) +- doubly called `createNewsletterManager` will use the same logger and mailer instances + +Let's instantiate `Container`, let it create manager and we can start spamming users with newsletters :-) + +```php +$container = new Container; +$manager = $container->createNewsletterManager(); +$manager->distribute(...); +``` + +Significant to Dependency Injection is that no class depends on the container. Thus it can be easily replaced with another one. For example with the container generated by Nette DI. + +Nette DI +---------- + +Nette DI is the generator of containers. We instruct it (usually) with configuration files. This is configuration that leads to generate nearly the same class as the class `Container` above: + +```neon +services: + - FileLogger( log.txt ) + - SendMailMailer + - NewsletterManager +``` + +The big advantage is the shortness of configuration. + +Nette DI actually generates PHP code of container. Therefore it is extremely fast. Developer can see the code, so he knows exactly what it is doing. He can even trace it. + +Usage of Nette DI is very easy. In first, install it using Composer: + +``` +composer require nette/di +``` + +Save the (above) configuration to the file `config.neon` and let's create a container: + +```php +$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp'); +$class = $loader->load(function($compiler) { + $compiler->loadConfig(__DIR__ . '/config.neon'); +}); +$container = new $class; +``` + +and then use container to create object `NewsletterManager` and we can send e-mails: + +```php +$manager = $container->getByType(NewsletterManager::class); +$manager->distribute(['john@example.com', ...]); +``` + +The container will be generated only once and the code is stored in cache (in directory `__DIR__ . '/temp'`). Therefore the loading of configuration file is placed in the closure in `$loader->load()`, so it is called only once. + +During development it is useful to activate auto-refresh mode which automatically regenerate the container when any class or configuration file is changed. Just in the constructor `ContainerLoader` append `true` as the second argument: + +```php +$loader = new Nette\DI\ContainerLoader(__DIR__ . '/temp', true); +``` + + +Services +-------- + +Services are registered in the DI container and their dependencies are automatically passed. + +```neon +services: + manager: NewsletterManager +``` + +All dependencies declared in the constructor of this service will be automatically passed. Constructor passing is the preferred way of dependency injection for services. + +If we want to pass dependencies by the setter, we can add the `setup` section to the service definition: + +```neon +services: + manager: + factory: NewsletterManager + setup: + - setAnotherService +``` + +Class of the service: + +```php +class NewsletterManager +{ + private $anotherService; + + public function setAnotherService(AnotherService $service) + { + $this->anotherService = $service; + } + +... +``` + +We can also add the `inject: yes` directive. This directive will enable automatic call of `inject*` methods and passing dependencies to public variables with `@inject` annotations: + +```neon +services: + foo: + factory: FooClass + inject: yes +``` + +Dependency `Service1` will be passed by calling the `inject*` method, dependency `Service2` will be assigned to the `$service2` variable: + +```php +class FooClass +{ + private $service1; + + // 1) inject* method: + + public function injectService1(Service1 $service) + { + $this->service1 = $service1; + } + + // 2) Assign to the variable with the @inject annotation: + + /** @inject @var Service2 */ + public $service2; +} +``` + +However, this method is not ideal, because the variable must be declared as public and there is no way how you can ensure that the passed object will be of the given type. We also lose the ability to handle the assigned dependency in our code and we violate the principles of encapsulation. + + + +Factories +--------- + +We can use factories generated from an interface. The interface must declare the returning type in the `@return` annotation of the method. Nette will generate a proper implementation of the interface. + +The interface must have exactly one method named `create`. Our factory interface could be declared in the following way: + +```php +interface IBarFactory +{ + /** + * @return Bar + */ + public function create(); +} +``` + +The `create` method will instantiate an `Bar` with the following definition: + +```php +class Bar +{ + private $logger; + + public function __construct(Logger $logger) + { + $this->logger = $logger; + } +} +``` + +The factory will be registered in the `config.neon` file: + +```neon +services: + - IBarFactory +``` + +Nette will check if the declared service is an interface. If yes, it will also generate the corresponding implementation of the factory. The definition can be also written in a more verbose form: + +```neon +services: + barFactory: + implement: IBarFactory +``` + +This full definition allows us to declare additional configuration of the object using the `arguments` and `setup` sections, similarly as for all other services. + +In our code, we only have to obtain the factory instance and call the `create` method: + +```php +class Foo +{ + private $barFactory; + + function __construct(IBarFactory $barFactory) + { + $this->barFactory = $barFactory; + } + + function bar() + { + $bar = $this->barFactory->create(); + } +} +``` diff --git a/vendor/nette/di/src/Bridges/DITracy/ContainerPanel.php b/vendor/nette/di/src/Bridges/DITracy/ContainerPanel.php new file mode 100644 index 00000000..314ad647 --- /dev/null +++ b/vendor/nette/di/src/Bridges/DITracy/ContainerPanel.php @@ -0,0 +1,85 @@ +container = $container; + $this->elapsedTime = self::$compilationTime ? microtime(true) - self::$compilationTime : null; + } + + + /** + * Renders tab. + * @return string + */ + public function getTab() + { + ob_start(function () {}); + $elapsedTime = $this->elapsedTime; + require __DIR__ . '/templates/ContainerPanel.tab.phtml'; + return ob_get_clean(); + } + + + /** + * Renders panel. + * @return string + */ + public function getPanel() + { + $container = $this->container; + $registry = $this->getContainerProperty('registry'); + $file = (new \ReflectionClass($container))->getFileName(); + $tags = []; + $meta = $this->getContainerProperty('meta'); + $services = $meta[Container::SERVICES]; + ksort($services); + if (isset($meta[Container::TAGS])) { + foreach ($meta[Container::TAGS] as $tag => $tmp) { + foreach ($tmp as $service => $val) { + $tags[$service][$tag] = $val; + } + } + } + + ob_start(function () {}); + require __DIR__ . '/templates/ContainerPanel.panel.phtml'; + return ob_get_clean(); + } + + + private function getContainerProperty($name) + { + $prop = (new \ReflectionClass(Nette\DI\Container::class))->getProperty($name); + $prop->setAccessible(true); + return $prop->getValue($this->container); + } +} diff --git a/vendor/nette/di/src/Bridges/DITracy/templates/ContainerPanel.panel.phtml b/vendor/nette/di/src/Bridges/DITracy/templates/ContainerPanel.panel.phtml new file mode 100644 index 00000000..29ed512d --- /dev/null +++ b/vendor/nette/di/src/Bridges/DITracy/templates/ContainerPanel.panel.phtml @@ -0,0 +1,70 @@ + + + +

+ +
+
+

Services

+ + + + + + + + + + + + $type): ?> + + + + + + + + + +
NameAutowiredServiceTags
+ + true, Dumper::LIVE => true]); ?> + + + + + + true]); } ?>
+ +

Parameters

+ +
+ parameters); ?> +
+ +

Source:

+
+
diff --git a/vendor/nette/di/src/Bridges/DITracy/templates/ContainerPanel.tab.phtml b/vendor/nette/di/src/Bridges/DITracy/templates/ContainerPanel.tab.phtml new file mode 100644 index 00000000..98922255 --- /dev/null +++ b/vendor/nette/di/src/Bridges/DITracy/templates/ContainerPanel.tab.phtml @@ -0,0 +1,10 @@ + + + + + diff --git a/vendor/nette/di/src/DI/Compiler.php b/vendor/nette/di/src/DI/Compiler.php new file mode 100644 index 00000000..7c62e0cc --- /dev/null +++ b/vendor/nette/di/src/DI/Compiler.php @@ -0,0 +1,507 @@ + 1, 'parameters' => 1]; + + + public function __construct(ContainerBuilder $builder = null) + { + $this->builder = $builder ?: new ContainerBuilder; + $this->dependencies = new DependencyChecker; + } + + + /** + * Add custom configurator extension. + * @param string|null + * @return static + */ + public function addExtension($name, CompilerExtension $extension) + { + if ($name === null) { + $name = '_' . count($this->extensions); + } elseif (isset($this->extensions[$name]) || isset(self::$reserved[$name])) { + throw new Nette\InvalidArgumentException("Name '$name' is already used or reserved."); + } + $this->extensions[$name] = $extension->setCompiler($this, $name); + return $this; + } + + + /** + * @return array + */ + public function getExtensions($type = null) + { + return $type + ? array_filter($this->extensions, function ($item) use ($type) { return $item instanceof $type; }) + : $this->extensions; + } + + + /** + * @return ContainerBuilder + */ + public function getContainerBuilder() + { + return $this->builder; + } + + + /** + * @return static + */ + public function setClassName($className) + { + $this->className = $className; + return $this; + } + + + /** + * Adds new configuration. + * @return static + */ + public function addConfig(array $config) + { + $this->config = Config\Helpers::merge($config, $this->config); + return $this; + } + + + /** + * Adds new configuration from file. + * @return static + */ + public function loadConfig($file) + { + $loader = new Config\Loader; + $this->addConfig($loader->load($file)); + $this->dependencies->add($loader->getDependencies()); + return $this; + } + + + /** + * Returns configuration. + * @return array + */ + public function getConfig() + { + return $this->config; + } + + + /** + * Sets the names of dynamic parameters. + * @return static + */ + public function setDynamicParameterNames(array $names) + { + $this->dynamicParams = $names; + return $this; + } + + + /** + * Adds dependencies to the list. + * @param array of ReflectionClass|\ReflectionFunctionAbstract|string + * @return static + */ + public function addDependencies(array $deps) + { + $this->dependencies->add(array_filter($deps)); + return $this; + } + + + /** + * Exports dependencies. + * @return array + */ + public function exportDependencies() + { + return $this->dependencies->export(); + } + + + /** + * @return string + */ + public function compile() + { + if (func_num_args()) { + trigger_error(__METHOD__ . ' arguments are deprecated, use Compiler::addConfig() and Compiler::setClassName().', E_USER_DEPRECATED); + $this->config = func_get_arg(0) ?: $this->config; + $this->className = @func_get_arg(1) ?: $this->className; + } + $this->processParameters(); + $this->processExtensions(); + $this->processServices(); + $classes = $this->generateCode(); + return implode("\n\n\n", $classes); + } + + + /** @internal */ + public function processParameters() + { + $params = isset($this->config['parameters']) ? $this->config['parameters'] : []; + foreach ($this->dynamicParams as $key) { + $params[$key] = array_key_exists($key, $params) + ? ContainerBuilder::literal('isset($this->parameters[?]) \? $this->parameters[?] : ?', [$key, $key, $params[$key]]) + : ContainerBuilder::literal('$this->parameters[?]', [$key]); + } + $this->builder->parameters = Helpers::expand($params, $params, true); + } + + + /** @internal */ + public function processExtensions() + { + $this->config = Helpers::expand(array_diff_key($this->config, self::$reserved), $this->builder->parameters) + + array_intersect_key($this->config, self::$reserved); + + foreach ($first = $this->getExtensions(Extensions\ExtensionsExtension::class) as $name => $extension) { + $extension->setConfig(isset($this->config[$name]) ? $this->config[$name] : []); + $extension->loadConfiguration(); + } + + $last = $this->getExtensions(Extensions\InjectExtension::class); + $this->extensions = array_merge(array_diff_key($this->extensions, $last), $last); + + $extensions = array_diff_key($this->extensions, $first); + foreach (array_intersect_key($extensions, $this->config) as $name => $extension) { + $extension->setConfig($this->config[$name] ?: []); + } + + foreach ($extensions as $extension) { + $extension->loadConfiguration(); + } + + if ($extra = array_diff_key($this->extensions, $extensions, $first)) { + $extra = implode("', '", array_keys($extra)); + throw new Nette\DeprecatedException("Extensions '$extra' were added while container was being compiled."); + + } elseif ($extra = key(array_diff_key($this->config, self::$reserved, $this->extensions))) { + $hint = Nette\Utils\ObjectHelpers::getSuggestion(array_keys(self::$reserved + $this->extensions), $extra); + throw new Nette\InvalidStateException( + "Found section '$extra' in configuration, but corresponding extension is missing" + . ($hint ? ", did you mean '$hint'?" : '.') + ); + } + } + + + /** @internal */ + public function processServices() + { + if (isset($this->config['services'])) { + self::loadDefinitions($this->builder, $this->config['services']); + } + } + + + /** @internal */ + public function generateCode() + { + if (func_num_args()) { + trigger_error(__METHOD__ . ' arguments are deprecated, use Compiler::setClassName().', E_USER_DEPRECATED); + $this->className = func_get_arg(0) ?: $this->className; + } + + $this->builder->prepareClassList(); + + foreach ($this->extensions as $extension) { + $extension->beforeCompile(); + $this->dependencies->add([(new \ReflectionClass($extension))->getFileName()]); + } + + $generator = new PhpGenerator($this->builder); + $classes = $generator->generate($this->className); + $classes[0]->addMethod('initialize'); + $this->dependencies->add($this->builder->getDependencies()); + + foreach ($this->extensions as $extension) { + $extension->afterCompile($classes[0]); + } + return $classes; + } + + + /********************* tools ****************d*g**/ + + + /** + * Adds service definitions from configuration. + * @return void + */ + public static function loadDefinitions(ContainerBuilder $builder, array $services, $namespace = null) + { + $depths = []; + $sort = false; + foreach ($services as $name => $def) { + $path = []; + while (Config\Helpers::isInheriting($def)) { + $sort = true; + $path[] = $def; + $def = isset($services[$def[Config\Helpers::EXTENDS_KEY]]) ? $services[$def[Config\Helpers::EXTENDS_KEY]] : []; + if (in_array($def, $path, true)) { + throw new ServiceCreationException("Circular reference detected for service '$name'."); + } + } + $depths[$name] = count($path) + preg_match('#^@[\w\\\\]+\z#', $name); + } + if ($sort) { + @array_multisort($depths, $services); // @ may trigger E_NOTICE: Object of class Nette\DI\Statement could not be converted to int + } + + foreach ($services as $name => $def) { + if (is_int($name)) { + $counter = 1; + do { + $name = (string) $counter++; + } while ($builder->hasDefinition($name)); + } elseif (preg_match('#^@[\w\\\\]+\z#', $name)) { + $name = $builder->getByType(substr($name, 1), true); + } elseif ($namespace) { + $name = $namespace . '.' . $name; + } + + if ($def === false) { + $builder->removeDefinition($name); + continue; + } + if ($namespace) { + $def = Helpers::prefixServiceName($def, $namespace); + } + + $params = $builder->parameters; + if (is_array($def) && isset($def['parameters'])) { + foreach ((array) $def['parameters'] as $k => $v) { + $v = explode(' ', is_int($k) ? $v : $k); + $params[end($v)] = $builder::literal('$' . end($v)); + } + } + $def = Helpers::expand($def, $params); + + if (is_array($def) && !empty($def['alteration']) && !$builder->hasDefinition($name)) { + throw new ServiceCreationException("Service '$name': missing original definition for alteration."); + } + + if (($parent = Config\Helpers::takeParent($def)) && $parent !== $name) { + if ($parent !== Config\Helpers::OVERWRITE) { + trigger_error("Section inheritance $name < $parent is deprecated.", E_USER_DEPRECATED); + } + $builder->removeDefinition($name); + $definition = $builder->addDefinition( + $name, + $parent === Config\Helpers::OVERWRITE ? null : clone $builder->getDefinition($parent) + ); + } elseif ($builder->hasDefinition($name)) { + $definition = $builder->getDefinition($name); + } else { + $definition = $builder->addDefinition($name); + } + + try { + static::loadDefinition($definition, $def); + } catch (\Exception $e) { + throw new ServiceCreationException("Service '$name': " . $e->getMessage(), 0, $e); + } + } + } + + + /** + * Parses single service definition from configuration. + * @return void + */ + public static function loadDefinition(ServiceDefinition $definition, $config) + { + if ($config === null) { + return; + + } elseif (is_string($config) && interface_exists($config)) { + $config = ['class' => null, 'implement' => $config]; + + } elseif ($config instanceof Statement && is_string($config->getEntity()) && interface_exists($config->getEntity())) { + $config = ['class' => null, 'implement' => $config->getEntity(), 'factory' => array_shift($config->arguments)]; + + } elseif (!is_array($config) || isset($config[0], $config[1])) { + $config = ['class' => null, 'factory' => $config]; + } + + if (array_key_exists('create', $config)) { + trigger_error("Key 'create' is deprecated, use 'factory' or 'type' in configuration.", E_USER_DEPRECATED); + $config['factory'] = $config['create']; + unset($config['create']); + } + + $known = ['type', 'class', 'factory', 'arguments', 'setup', 'autowired', 'dynamic', 'imported', 'inject', 'parameters', 'implement', 'run', 'tags', 'alteration']; + if ($error = array_diff(array_keys($config), $known)) { + $hints = array_filter(array_map(function ($error) use ($known) { + return Nette\Utils\ObjectHelpers::getSuggestion($known, $error); + }, $error)); + $hint = $hints ? ", did you mean '" . implode("', '", $hints) . "'?" : '.'; + throw new Nette\InvalidStateException(sprintf("Unknown key '%s' in definition of service$hint", implode("', '", $error))); + } + + $config = Helpers::filterArguments($config); + + if (array_key_exists('class', $config) || array_key_exists('factory', $config)) { + $definition->setType(null); + $definition->setFactory(null); + } + + if (array_key_exists('type', $config)) { + Validators::assertField($config, 'type', 'string|null'); + $definition->setType($config['type']); + if (array_key_exists('class', $config)) { + throw new Nette\InvalidStateException("Unexpected 'class' when 'type' is used."); + } + } + + if (array_key_exists('class', $config)) { + Validators::assertField($config, 'class', 'string|Nette\DI\Statement|null'); + if (!$config['class'] instanceof Statement) { + $definition->setType($config['class']); + } + $definition->setFactory($config['class']); + } + + if (array_key_exists('factory', $config)) { + Validators::assertField($config, 'factory', 'callable|Nette\DI\Statement|null'); + $definition->setFactory($config['factory']); + } + + if (array_key_exists('arguments', $config)) { + Validators::assertField($config, 'arguments', 'array'); + $arguments = $config['arguments']; + if (!Config\Helpers::takeParent($arguments) && !Nette\Utils\Arrays::isList($arguments) && $definition->getFactory()) { + $arguments += $definition->getFactory()->arguments; + } + $definition->setArguments($arguments); + } + + if (isset($config['setup'])) { + if (Config\Helpers::takeParent($config['setup'])) { + $definition->setSetup([]); + } + Validators::assertField($config, 'setup', 'list'); + foreach ($config['setup'] as $id => $setup) { + Validators::assert($setup, 'callable|Nette\DI\Statement|array:1', "setup item #$id"); + if (is_array($setup)) { + $setup = new Statement(key($setup), array_values($setup)); + } + $definition->addSetup($setup); + } + } + + if (isset($config['parameters'])) { + Validators::assertField($config, 'parameters', 'array'); + $definition->setParameters($config['parameters']); + } + + if (isset($config['implement'])) { + Validators::assertField($config, 'implement', 'string'); + $definition->setImplement($config['implement']); + $definition->setAutowired(true); + } + + if (isset($config['autowired'])) { + Validators::assertField($config, 'autowired', 'bool|string|array'); + $definition->setAutowired($config['autowired']); + } + + if (isset($config['imported'])) { + $config['dynamic'] = $config['imported']; + } + + if (isset($config['dynamic'])) { + Validators::assertField($config, 'dynamic', 'bool'); + $definition->setDynamic($config['dynamic']); + } + + if (isset($config['inject'])) { + Validators::assertField($config, 'inject', 'bool'); + $definition->addTag(Extensions\InjectExtension::TAG_INJECT, $config['inject']); + } + + if (isset($config['run'])) { + trigger_error("Option 'run' is deprecated, use 'run' as tag.", E_USER_DEPRECATED); + $config['tags']['run'] = (bool) $config['run']; + } + + if (isset($config['tags'])) { + Validators::assertField($config, 'tags', 'array'); + if (Config\Helpers::takeParent($config['tags'])) { + $definition->setTags([]); + } + foreach ($config['tags'] as $tag => $attrs) { + if (is_int($tag) && is_string($attrs)) { + $definition->addTag($attrs); + } else { + $definition->addTag($tag, $attrs); + } + } + } + } + + + /** @deprecated */ + public static function filterArguments(array $args) + { + return Helpers::filterArguments($args); + } + + + /** @deprecated */ + public static function parseServices(ContainerBuilder $builder, array $config, $namespace = null) + { + self::loadDefinitions($builder, isset($config['services']) ? $config['services'] : [], $namespace); + } + + + /** @deprecated */ + public static function parseService(ServiceDefinition $definition, $config) + { + self::loadDefinition($definition, $config); + } +} diff --git a/vendor/nette/di/src/DI/CompilerExtension.php b/vendor/nette/di/src/DI/CompilerExtension.php new file mode 100644 index 00000000..8c7c652a --- /dev/null +++ b/vendor/nette/di/src/DI/CompilerExtension.php @@ -0,0 +1,143 @@ +compiler = $compiler; + $this->name = $name; + return $this; + } + + + /** + * @return static + */ + public function setConfig(array $config) + { + $this->config = $config; + return $this; + } + + + /** + * Returns extension configuration. + * @return array + */ + public function getConfig() + { + if (func_num_args()) { // deprecated + return Config\Helpers::merge($this->config, $this->getContainerBuilder()->expand(func_get_arg(0))); + } + return $this->config; + } + + + /** + * Checks whether $config contains only $expected items and returns combined array. + * @return array + * @throws Nette\InvalidStateException + */ + public function validateConfig(array $expected, array $config = null, $name = null) + { + if (func_num_args() === 1) { + return $this->config = $this->validateConfig($expected, $this->config); + } + if ($extra = array_diff_key((array) $config, $expected)) { + $name = $name ?: $this->name; + $hint = Nette\Utils\ObjectHelpers::getSuggestion(array_keys($expected), key($extra)); + $extra = $hint ? key($extra) : implode("', '{$name} › ", array_keys($extra)); + throw new Nette\InvalidStateException("Unknown configuration option '{$name} › {$extra}'" . ($hint ? ", did you mean '{$name} › {$hint}'?" : '.')); + } + return Config\Helpers::merge($config, $expected); + } + + + /** + * @return ContainerBuilder + */ + public function getContainerBuilder() + { + return $this->compiler->getContainerBuilder(); + } + + + /** + * Reads configuration from file. + * @param string file name + * @return array + */ + public function loadFromFile($file) + { + $loader = new Config\Loader; + $res = $loader->load($file); + $this->compiler->addDependencies($loader->getDependencies()); + return $res; + } + + + /** + * Prepend extension name to identifier or service name. + * @param string + * @return string + */ + public function prefix($id) + { + return substr_replace($id, $this->name . '.', substr($id, 0, 1) === '@' ? 1 : 0, 0); + } + + + /** + * Processes configuration data. Intended to be overridden by descendant. + * @return void + */ + public function loadConfiguration() + { + } + + + /** + * Adjusts DI container before is compiled to PHP class. Intended to be overridden by descendant. + * @return void + */ + public function beforeCompile() + { + } + + + /** + * Adjusts DI container compiled to PHP class. Intended to be overridden by descendant. + * @return void + */ + public function afterCompile(Nette\PhpGenerator\ClassType $class) + { + } +} diff --git a/vendor/nette/di/src/DI/Config/Adapters/IniAdapter.php b/vendor/nette/di/src/DI/Config/Adapters/IniAdapter.php new file mode 100644 index 00000000..3bea1958 --- /dev/null +++ b/vendor/nette/di/src/DI/Config/Adapters/IniAdapter.php @@ -0,0 +1,151 @@ +process($ini); + } + + + /** + * @return array + * @throws Nette\InvalidStateException + */ + public function process(array $arr) + { + $data = []; + foreach ($arr as $secName => $secData) { + if (is_array($secData)) { // is section? + if (substr($secName, -1) === self::RAW_SECTION) { + $secName = substr($secName, 0, -1); + } else { // process key nesting separator (key1.key2.key3) + $tmp = []; + foreach ($secData as $key => $val) { + $cursor = &$tmp; + $key = str_replace(self::ESCAPED_KEY_SEPARATOR, "\xFF", $key); + foreach (explode(self::KEY_SEPARATOR, $key) as $part) { + $part = str_replace("\xFF", self::KEY_SEPARATOR, $part); + if (!isset($cursor[$part]) || is_array($cursor[$part])) { + $cursor = &$cursor[$part]; + } else { + throw new Nette\InvalidStateException("Invalid key '$key' in section [$secName]."); + } + } + $cursor = $val; + } + $secData = $tmp; + } + + $parts = explode(self::INHERITING_SEPARATOR, $secName); + if (count($parts) > 1) { + $secName = trim($parts[0]); + $secData[Helpers::EXTENDS_KEY] = trim($parts[1]); + } + } + + $cursor = &$data; // nesting separator in section name + foreach (explode(self::KEY_SEPARATOR, $secName) as $part) { + if (!isset($cursor[$part]) || is_array($cursor[$part])) { + $cursor = &$cursor[$part]; + } else { + throw new Nette\InvalidStateException("Invalid section [$secName]."); + } + } + + if (is_array($secData) && is_array($cursor)) { + $secData = Helpers::merge($secData, $cursor); + } + + $cursor = $secData; + } + + return $data; + } + + + /** + * Generates configuration in INI format. + * @return string + */ + public function dump(array $data) + { + $output = []; + foreach ($data as $name => $secData) { + if (!is_array($secData)) { + $output = []; + self::build($data, $output, ''); + break; + } + if ($parent = Helpers::takeParent($secData)) { + $output[] = "[$name " . self::INHERITING_SEPARATOR . " $parent]"; + } else { + $output[] = "[$name]"; + } + self::build($secData, $output, ''); + $output[] = ''; + } + return "; generated by Nette\n\n" . implode(PHP_EOL, $output); + } + + + /** + * Recursive builds INI list. + * @return void + */ + private static function build($input, &$output, $prefix) + { + foreach ($input as $key => $val) { + $key = str_replace(self::KEY_SEPARATOR, self::ESCAPED_KEY_SEPARATOR, $key); + if (is_array($val)) { + self::build($val, $output, $prefix . $key . self::KEY_SEPARATOR); + + } elseif (is_bool($val)) { + $output[] = "$prefix$key = " . ($val ? 'true' : 'false'); + + } elseif (is_numeric($val)) { + $output[] = "$prefix$key = $val"; + + } elseif (is_string($val)) { + $output[] = "$prefix$key = \"$val\""; + + } else { + throw new Nette\InvalidArgumentException(sprintf("The '%s' item must be scalar or array, %s given.", $prefix . $key, gettype($val))); + } + } + } +} diff --git a/vendor/nette/di/src/DI/Config/Adapters/NeonAdapter.php b/vendor/nette/di/src/DI/Config/Adapters/NeonAdapter.php new file mode 100644 index 00000000..9ca32901 --- /dev/null +++ b/vendor/nette/di/src/DI/Config/Adapters/NeonAdapter.php @@ -0,0 +1,139 @@ +process((array) Neon\Neon::decode(file_get_contents($file))); + } + + + /** + * @return array + * @throws Nette\InvalidStateException + */ + public function process(array $arr) + { + $res = []; + foreach ($arr as $key => $val) { + if (is_string($key) && substr($key, -1) === self::PREVENT_MERGING) { + if (!is_array($val) && $val !== null) { + throw new Nette\InvalidStateException("Replacing operator is available only for arrays, item '$key' is not array."); + } + $key = substr($key, 0, -1); + $val[Helpers::EXTENDS_KEY] = Helpers::OVERWRITE; + + } elseif (is_string($key) && preg_match('#^(\S+)\s+' . self::INHERITING_SEPARATOR . '\s+(\S+)\z#', $key, $matches)) { + if (!is_array($val) && $val !== null) { + throw new Nette\InvalidStateException("Inheritance operator is available only for arrays, item '$key' is not array."); + } + list(, $key, $val[Helpers::EXTENDS_KEY]) = $matches; + if (isset($res[$key])) { + throw new Nette\InvalidStateException("Duplicated key '$key'."); + } + } + + if (is_array($val)) { + $val = $this->process($val); + + } elseif ($val instanceof Neon\Entity) { + if ($val->value === Neon\Neon::CHAIN) { + $tmp = null; + foreach ($this->process($val->attributes) as $st) { + $tmp = new Statement( + $tmp === null ? $st->getEntity() : [$tmp, ltrim($st->getEntity(), ':')], + $st->arguments + ); + } + $val = $tmp; + } else { + $tmp = $this->process([$val->value]); + $val = new Statement($tmp[0], $this->process($val->attributes)); + } + } + $res[$key] = $val; + } + return $res; + } + + + /** + * Generates configuration in NEON format. + * @return string + */ + public function dump(array $data) + { + $tmp = []; + foreach ($data as $name => $secData) { + if ($parent = Helpers::takeParent($secData)) { + $name .= ' ' . self::INHERITING_SEPARATOR . ' ' . $parent; + } + $tmp[$name] = $secData; + } + array_walk_recursive( + $tmp, + function (&$val) { + if ($val instanceof Statement) { + $val = self::statementToEntity($val); + } + } + ); + + return "# generated by Nette\n\n" . Neon\Neon::encode($tmp, Neon\Neon::BLOCK); + } + + + /** + * @return Neon\Entity + */ + private static function statementToEntity(Statement $val) + { + array_walk_recursive( + $val->arguments, + function (&$val) { + if ($val instanceof Statement) { + $val = self::statementToEntity($val); + } + } + ); + if (is_array($val->getEntity()) && $val->getEntity()[0] instanceof Statement) { + return new Neon\Entity( + Neon\Neon::CHAIN, + [ + self::statementToEntity($val->getEntity()[0]), + new Neon\Entity('::' . $val->getEntity()[1], $val->arguments), + ] + ); + } else { + return new Neon\Entity($val->getEntity(), $val->arguments); + } + } +} diff --git a/vendor/nette/di/src/DI/Config/Adapters/PhpAdapter.php b/vendor/nette/di/src/DI/Config/Adapters/PhpAdapter.php new file mode 100644 index 00000000..1f71064f --- /dev/null +++ b/vendor/nette/di/src/DI/Config/Adapters/PhpAdapter.php @@ -0,0 +1,39 @@ + $val) { + if (is_int($key)) { + $right[] = $val; + } else { + if (is_array($val) && isset($val[self::EXTENDS_KEY])) { + if ($val[self::EXTENDS_KEY] === self::OVERWRITE) { + unset($val[self::EXTENDS_KEY]); + } + } elseif (isset($right[$key])) { + $val = static::merge($val, $right[$key]); + } + $right[$key] = $val; + } + } + return $right; + + } elseif ($left === null && is_array($right)) { + return $right; + + } else { + return $left; + } + } + + + /** + * Finds out and removes information about the parent. + * @return mixed + */ + public static function takeParent(&$data) + { + if (is_array($data) && isset($data[self::EXTENDS_KEY])) { + $parent = $data[self::EXTENDS_KEY]; + unset($data[self::EXTENDS_KEY]); + return $parent; + } + } + + + /** + * @return bool + */ + public static function isOverwriting(&$data) + { + return is_array($data) && isset($data[self::EXTENDS_KEY]) && $data[self::EXTENDS_KEY] === self::OVERWRITE; + } + + + /** + * @return bool + */ + public static function isInheriting(&$data) + { + return is_array($data) && isset($data[self::EXTENDS_KEY]) && $data[self::EXTENDS_KEY] !== self::OVERWRITE; + } +} diff --git a/vendor/nette/di/src/DI/Config/IAdapter.php b/vendor/nette/di/src/DI/Config/IAdapter.php new file mode 100644 index 00000000..88447443 --- /dev/null +++ b/vendor/nette/di/src/DI/Config/IAdapter.php @@ -0,0 +1,29 @@ + Adapters\PhpAdapter::class, + 'ini' => Adapters\IniAdapter::class, + 'neon' => Adapters\NeonAdapter::class, + ]; + + private $dependencies = []; + + private $loadedFiles = []; + + + /** + * Reads configuration from file. + * @param string file name + * @param string optional section to load + * @return array + */ + public function load($file, $section = null) + { + if (!is_file($file) || !is_readable($file)) { + throw new Nette\FileNotFoundException("File '$file' is missing or is not readable."); + } + + if (isset($this->loadedFiles[$file])) { + throw new Nette\InvalidStateException("Recursive included file '$file'"); + } + $this->loadedFiles[$file] = true; + + $this->dependencies[] = $file; + $data = $this->getAdapter($file)->load($file); + + if ($section) { + if (isset($data[self::INCLUDES_KEY])) { + throw new Nette\InvalidStateException("Section 'includes' must be placed under some top section in file '$file'."); + } + $data = $this->getSection($data, $section, $file); + } + + // include child files + $merged = []; + if (isset($data[self::INCLUDES_KEY])) { + Validators::assert($data[self::INCLUDES_KEY], 'list', "section 'includes' in file '$file'"); + foreach ($data[self::INCLUDES_KEY] as $include) { + if (!preg_match('#([a-z]+:)?[/\\\\]#Ai', $include)) { + $include = dirname($file) . '/' . $include; + } + $merged = Helpers::merge($this->load($include), $merged); + } + } + unset($data[self::INCLUDES_KEY], $this->loadedFiles[$file]); + + + return Helpers::merge($data, $merged); + } + + + /** + * Save configuration to file. + * @param array + * @param string file + * @return void + */ + public function save($data, $file) + { + if (file_put_contents($file, $this->getAdapter($file)->dump($data)) === false) { + throw new Nette\IOException("Cannot write file '$file'."); + } + } + + + /** + * Returns configuration files. + * @return array + */ + public function getDependencies() + { + return array_unique($this->dependencies); + } + + + /** + * Registers adapter for given file extension. + * @param string file extension + * @param string|IAdapter + * @return static + */ + public function addAdapter($extension, $adapter) + { + $this->adapters[strtolower($extension)] = $adapter; + return $this; + } + + + /** @return IAdapter */ + private function getAdapter($file) + { + $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + if (!isset($this->adapters[$extension])) { + throw new Nette\InvalidArgumentException("Unknown file extension '$file'."); + } + return is_object($this->adapters[$extension]) ? $this->adapters[$extension] : new $this->adapters[$extension]; + } + + + private function getSection(array $data, $key, $file) + { + Validators::assertField($data, $key, 'array|null', "section '%' in file '$file'"); + $item = $data[$key]; + if ($parent = Helpers::takeParent($item)) { + $item = Helpers::merge($item, $this->getSection($data, $parent, $file)); + } + return $item; + } +} diff --git a/vendor/nette/di/src/DI/Container.php b/vendor/nette/di/src/DI/Container.php new file mode 100644 index 00000000..13241a51 --- /dev/null +++ b/vendor/nette/di/src/DI/Container.php @@ -0,0 +1,345 @@ +parameters = $params + $this->parameters; + } + + + /** + * @return array + */ + public function getParameters() + { + return $this->parameters; + } + + + /** + * Adds the service to the container. + * @param string + * @param object + * @return static + */ + public function addService($name, $service) + { + if (!is_string($name) || !$name) { + throw new Nette\InvalidArgumentException(sprintf('Service name must be a non-empty string, %s given.', gettype($name))); + } + $name = isset($this->meta[self::ALIASES][$name]) ? $this->meta[self::ALIASES][$name] : $name; + if (isset($this->registry[$name])) { + throw new Nette\InvalidStateException("Service '$name' already exists."); + + } elseif (!is_object($service)) { + throw new Nette\InvalidArgumentException(sprintf("Service '%s' must be a object, %s given.", $name, gettype($service))); + + } elseif (isset($this->meta[self::SERVICES][$name]) && !$service instanceof $this->meta[self::SERVICES][$name]) { + throw new Nette\InvalidArgumentException(sprintf("Service '%s' must be instance of %s, %s given.", $name, $this->meta[self::SERVICES][$name], get_class($service))); + } + + $this->registry[$name] = $service; + return $this; + } + + + /** + * Removes the service from the container. + * @param string + * @return void + */ + public function removeService($name) + { + $name = isset($this->meta[self::ALIASES][$name]) ? $this->meta[self::ALIASES][$name] : $name; + unset($this->registry[$name]); + } + + + /** + * Gets the service object by name. + * @param string + * @return object + * @throws MissingServiceException + */ + public function getService($name) + { + if (!isset($this->registry[$name])) { + if (isset($this->meta[self::ALIASES][$name])) { + return $this->getService($this->meta[self::ALIASES][$name]); + } + $this->registry[$name] = $this->createService($name); + } + return $this->registry[$name]; + } + + + /** + * Gets the service type by name. + * @param string + * @return string + * @throws MissingServiceException + */ + public function getServiceType($name) + { + if (isset($this->meta[self::ALIASES][$name])) { + return $this->getServiceType($this->meta[self::ALIASES][$name]); + + } elseif (isset($this->meta[self::SERVICES][$name])) { + return $this->meta[self::SERVICES][$name]; + + } else { + throw new MissingServiceException("Service '$name' not found."); + } + } + + + /** + * Does the service exist? + * @param string service name + * @return bool + */ + public function hasService($name) + { + $name = isset($this->meta[self::ALIASES][$name]) ? $this->meta[self::ALIASES][$name] : $name; + return isset($this->registry[$name]) + || (method_exists($this, $method = self::getMethodName($name)) + && (new \ReflectionMethod($this, $method))->getName() === $method); + } + + + /** + * Is the service created? + * @param string service name + * @return bool + */ + public function isCreated($name) + { + if (!$this->hasService($name)) { + throw new MissingServiceException("Service '$name' not found."); + } + $name = isset($this->meta[self::ALIASES][$name]) ? $this->meta[self::ALIASES][$name] : $name; + return isset($this->registry[$name]); + } + + + /** + * Creates new instance of the service. + * @param string service name + * @return object + * @throws MissingServiceException + */ + public function createService($name, array $args = []) + { + $name = isset($this->meta[self::ALIASES][$name]) ? $this->meta[self::ALIASES][$name] : $name; + $method = self::getMethodName($name); + if (isset($this->creating[$name])) { + throw new Nette\InvalidStateException(sprintf('Circular reference detected for services: %s.', implode(', ', array_keys($this->creating)))); + + } elseif (!method_exists($this, $method) || (new \ReflectionMethod($this, $method))->getName() !== $method) { + throw new MissingServiceException("Service '$name' not found."); + } + + try { + $this->creating[$name] = true; + $service = $this->$method(...$args); + + } finally { + unset($this->creating[$name]); + } + + if (!is_object($service)) { + throw new Nette\UnexpectedValueException("Unable to create service '$name', value returned by method $method() is not object."); + } + + return $service; + } + + + /** + * Resolves service by type. + * @param string class or interface + * @param bool throw exception if service doesn't exist? + * @return object|null service + * @throws MissingServiceException + */ + public function getByType($type, $throw = true) + { + $type = Helpers::normalizeClass($type); + if (!empty($this->meta[self::TYPES][$type][true])) { + if (count($names = $this->meta[self::TYPES][$type][true]) === 1) { + return $this->getService($names[0]); + } + natsort($names); + throw new MissingServiceException("Multiple services of type $type found: " . implode(', ', $names) . '.'); + + } elseif ($throw) { + throw new MissingServiceException("Service of type $type not found."); + } + return null; + } + + + /** + * Gets the service names of the specified type. + * @param string + * @return string[] + */ + public function findByType($type) + { + $type = Helpers::normalizeClass($type); + return empty($this->meta[self::TYPES][$type]) + ? [] + : array_merge(...array_values($this->meta[self::TYPES][$type])); + } + + + /** + * Gets the service names of the specified tag. + * @param string + * @return array of [service name => tag attributes] + */ + public function findByTag($tag) + { + return isset($this->meta[self::TAGS][$tag]) ? $this->meta[self::TAGS][$tag] : []; + } + + + /********************* autowiring ****************d*g**/ + + + /** + * Creates new instance using autowiring. + * @param string class + * @param array arguments + * @return object + * @throws Nette\InvalidArgumentException + */ + public function createInstance($class, array $args = []) + { + $rc = new \ReflectionClass($class); + if (!$rc->isInstantiable()) { + throw new ServiceCreationException("Class $class is not instantiable."); + + } elseif ($constructor = $rc->getConstructor()) { + return $rc->newInstanceArgs(Helpers::autowireArguments($constructor, $args, $this)); + + } elseif ($args) { + throw new ServiceCreationException("Unable to pass arguments, class $class has no constructor."); + } + return new $class; + } + + + /** + * Calls all methods starting with with "inject" using autowiring. + * @param object + * @return void + */ + public function callInjects($service) + { + Extensions\InjectExtension::callInjects($this, $service); + } + + + /** + * Calls method using autowiring. + * @return mixed + */ + public function callMethod(callable $function, array $args = []) + { + return $function(...Helpers::autowireArguments(Nette\Utils\Callback::toReflection($function), $args, $this)); + } + + + /********************* shortcuts ****************d*g**/ + + + /** + * Expands %placeholders%. + * @param mixed + * @return mixed + * @deprecated + */ + public function expand($s) + { + return Helpers::expand($s, $this->parameters); + } + + + /** @deprecated */ + public function &__get($name) + { + trigger_error(__METHOD__ . ' is deprecated; use getService().', E_USER_DEPRECATED); + $tmp = $this->getService($name); + return $tmp; + } + + + /** @deprecated */ + public function __set($name, $service) + { + trigger_error(__METHOD__ . ' is deprecated; use addService().', E_USER_DEPRECATED); + $this->addService($name, $service); + } + + + /** @deprecated */ + public function __isset($name) + { + trigger_error(__METHOD__ . ' is deprecated; use hasService().', E_USER_DEPRECATED); + return $this->hasService($name); + } + + + /** @deprecated */ + public function __unset($name) + { + trigger_error(__METHOD__ . ' is deprecated; use removeService().', E_USER_DEPRECATED); + $this->removeService($name); + } + + + public static function getMethodName($name) + { + return 'createService' + . (preg_match('#^[A-Z]#', $name) ? '__' : '') + . str_replace('.', '__', ucfirst($name)); + } +} diff --git a/vendor/nette/di/src/DI/ContainerBuilder.php b/vendor/nette/di/src/DI/ContainerBuilder.php new file mode 100644 index 00000000..45889fe1 --- /dev/null +++ b/vendor/nette/di/src/DI/ContainerBuilder.php @@ -0,0 +1,880 @@ + service */ + private $aliases = []; + + /** @var array for auto-wiring */ + private $classList = []; + + /** @var bool */ + private $classListNeedsRefresh = true; + + /** @var string[] of classes excluded from auto-wiring */ + private $excludedClasses = []; + + /** @var array */ + private $dependencies = []; + + /** @var string */ + private $currentService; + + + /** + * Adds new service definition. + * @param string + * @return ServiceDefinition + */ + public function addDefinition($name, ServiceDefinition $definition = null) + { + $this->classListNeedsRefresh = true; + if (!is_string($name) || !$name) { // builder is not ready for falsy names such as '0' + throw new Nette\InvalidArgumentException(sprintf('Service name must be a non-empty string, %s given.', gettype($name))); + } + $name = isset($this->aliases[$name]) ? $this->aliases[$name] : $name; + if (isset($this->definitions[$name])) { + throw new Nette\InvalidStateException("Service '$name' has already been added."); + } + if (!$definition) { + $definition = new ServiceDefinition; + } + $definition->setNotifier(function () { + $this->classListNeedsRefresh = true; + }); + return $this->definitions[$name] = $definition; + } + + + /** + * Removes the specified service definition. + * @param string + * @return void + */ + public function removeDefinition($name) + { + $this->classListNeedsRefresh = true; + $name = isset($this->aliases[$name]) ? $this->aliases[$name] : $name; + unset($this->definitions[$name]); + } + + + /** + * Gets the service definition. + * @param string + * @return ServiceDefinition + */ + public function getDefinition($name) + { + $service = isset($this->aliases[$name]) ? $this->aliases[$name] : $name; + if (!isset($this->definitions[$service])) { + throw new MissingServiceException("Service '$name' not found."); + } + return $this->definitions[$service]; + } + + + /** + * Gets all service definitions. + * @return ServiceDefinition[] + */ + public function getDefinitions() + { + return $this->definitions; + } + + + /** + * Does the service definition or alias exist? + * @param string + * @return bool + */ + public function hasDefinition($name) + { + $name = isset($this->aliases[$name]) ? $this->aliases[$name] : $name; + return isset($this->definitions[$name]); + } + + + /** + * @param string + * @param string + */ + public function addAlias($alias, $service) + { + if (!is_string($alias) || !$alias) { // builder is not ready for falsy names such as '0' + throw new Nette\InvalidArgumentException(sprintf('Alias name must be a non-empty string, %s given.', gettype($alias))); + + } elseif (!is_string($service) || !$service) { // builder is not ready for falsy names such as '0' + throw new Nette\InvalidArgumentException(sprintf('Service name must be a non-empty string, %s given.', gettype($service))); + + } elseif (isset($this->aliases[$alias])) { + throw new Nette\InvalidStateException("Alias '$alias' has already been added."); + + } elseif (isset($this->definitions[$alias])) { + throw new Nette\InvalidStateException("Service '$alias' has already been added."); + } + $this->aliases[$alias] = $service; + } + + + /** + * Removes the specified alias. + * @return void + */ + public function removeAlias($alias) + { + unset($this->aliases[$alias]); + } + + + /** + * Gets all service aliases. + * @return array + */ + public function getAliases() + { + return $this->aliases; + } + + + /** + * @param string[] + * @return static + */ + public function addExcludedClasses(array $types) + { + foreach ($types as $type) { + if (class_exists($type) || interface_exists($type)) { + $type = Helpers::normalizeClass($type); + $this->excludedClasses += class_parents($type) + class_implements($type) + [$type => $type]; + } + } + return $this; + } + + + /** + * @deprecated + */ + public function setClassName($name) + { + trigger_error(__METHOD__ . ' has been deprecated', E_USER_DEPRECATED); + return $this; + } + + + /** + * @deprecated + */ + public function getClassName() + { + trigger_error(__METHOD__ . ' has been deprecated', E_USER_DEPRECATED); + } + + + /********************* class resolving ****************d*g**/ + + + /** + * Resolves service name by type. + * @param string class or interface + * @param bool throw exception if service doesn't exist? + * @return string|null service name or null + * @throws ServiceCreationException + */ + public function getByType($type, $throw = false) + { + $type = Helpers::normalizeClass($type); + + if ( + $this->currentService !== null + && is_a($this->definitions[$this->currentService]->getType(), $type, true) + ) { + return $this->currentService; + } + + $types = $this->getClassList(); + if (empty($types[$type][true])) { + if ($throw) { + throw new MissingServiceException("Service of type '$type' not found."); + } + return; + + } elseif (count($types[$type][true]) === 1) { + return $types[$type][true][0]; + + } else { + $list = $types[$type][true]; + natsort($list); + $hint = count($list) === 2 && ($tmp = strpos($list[0], '.') xor strpos($list[1], '.')) + ? '. If you want to overwrite service ' . $list[$tmp ? 0 : 1] . ', give it proper name.' + : ''; + throw new ServiceCreationException("Multiple services of type $type found: " . implode(', ', $list) . $hint); + } + } + + + /** + * Gets the service definition of the specified type. + * @param string + * @return ServiceDefinition + */ + public function getDefinitionByType($type) + { + return $this->getDefinition($this->getByType($type, true)); + } + + + /** + * Gets the service names and definitions of the specified type. + * @param string + * @return ServiceDefinition[] + */ + public function findByType($type) + { + $type = Helpers::normalizeClass($type); + $found = []; + $types = $this->getClassList(); + if (!empty($types[$type])) { + foreach (array_merge(...array_values($types[$type])) as $name) { + $found[$name] = $this->definitions[$name]; + } + } + return $found; + } + + + /** + * Gets the service objects of the specified tag. + * @param string + * @return array of [service name => tag attributes] + */ + public function findByTag($tag) + { + $found = []; + foreach ($this->definitions as $name => $def) { + if (($tmp = $def->getTag($tag)) !== null) { + $found[$name] = $tmp; + } + } + return $found; + } + + + /** + * @internal + */ + public function getClassList() + { + if ($this->classList !== false && $this->classListNeedsRefresh) { + $this->prepareClassList(); + $this->classListNeedsRefresh = false; + } + return $this->classList ?: []; + } + + + /** + * Generates $dependencies, $classList and normalizes class names. + * @return void + * @internal + */ + public function prepareClassList() + { + unset($this->definitions[self::THIS_CONTAINER]); + $this->addDefinition(self::THIS_CONTAINER)->setType(Container::class); + + $this->classList = false; + + foreach ($this->definitions as $name => $def) { + // prepare generated factories + if ($def->getImplement()) { + $this->resolveImplement($def, $name); + } + + if ($def->isDynamic()) { + if (!$def->getType()) { + throw new ServiceCreationException("Type is missing in definition of service '$name'."); + } + $def->setFactory(null); + continue; + } + + // complete class-factory pairs + if (!$def->getEntity()) { + if (!$def->getType()) { + throw new ServiceCreationException("Factory and type are missing in definition of service '$name'."); + } + $def->setFactory($def->getType(), ($factory = $def->getFactory()) ? $factory->arguments : []); + } + + // auto-disable autowiring for aliases + if ( + $def->getAutowired() === true + && ($alias = $this->getServiceName($def->getFactory()->getEntity())) + && (!$def->getImplement() || (!Strings::contains($alias, '\\') && $this->definitions[$alias]->getImplement())) + ) { + $def->setAutowired(false); + } + } + + // resolve and check classes + foreach ($this->definitions as $name => $def) { + $this->resolveServiceType($name); + } + + // build auto-wiring list + $this->classList = $preferred = []; + foreach ($this->definitions as $name => $def) { + if ($type = $def->getImplement() ?: $def->getType()) { + $defAutowired = $def->getAutowired(); + if (is_array($defAutowired)) { + foreach ($defAutowired as $k => $autowiredType) { + if ($autowiredType === self::THIS_SERVICE) { + $defAutowired[$k] = $type; + } elseif (!is_a($type, $autowiredType, true)) { + throw new ServiceCreationException("Incompatible class $autowiredType in autowiring definition of service '$name'."); + } + } + } + + foreach (class_parents($type) + class_implements($type) + [$type] as $parent) { + $autowired = $defAutowired && empty($this->excludedClasses[$parent]); + if ($autowired && is_array($defAutowired)) { + $autowired = false; + foreach ($defAutowired as $autowiredType) { + if (is_a($parent, $autowiredType, true)) { + if (empty($preferred[$parent]) && isset($this->classList[$parent][true])) { + $this->classList[$parent][false] = array_merge(...$this->classList[$parent]); + $this->classList[$parent][true] = []; + } + $preferred[$parent] = $autowired = true; + break; + } + } + } elseif (isset($preferred[$parent])) { + $autowired = false; + } + $this->classList[$parent][$autowired][] = (string) $name; + } + } + } + } + + + private function resolveImplement(ServiceDefinition $def, $name) + { + $interface = $def->getImplement(); + if (!interface_exists($interface)) { + throw new ServiceCreationException("Interface $interface used in service '$name' not found."); + } + $interface = Helpers::normalizeClass($interface); + $def->setImplement($interface); + + $rc = new ReflectionClass($interface); + $this->addDependency($rc); + $method = $rc->hasMethod('create') + ? $rc->getMethod('create') + : ($rc->hasMethod('get') ? $rc->getMethod('get') : null); + + if (count($rc->getMethods()) !== 1 || !$method || $method->isStatic()) { + throw new ServiceCreationException("Interface $interface used in service '$name' must have just one non-static method create() or get()."); + } + $def->setImplementMode($rc->hasMethod('create') ? $def::IMPLEMENT_MODE_CREATE : $def::IMPLEMENT_MODE_GET); + $methodName = Reflection::toString($method) . '()'; + + if (!$def->getType() && !$def->getEntity()) { + $returnType = Helpers::getReturnType($method); + if (!$returnType) { + throw new ServiceCreationException("Method $methodName used in service '$name' has not return type hint or annotation @return."); + } elseif (!class_exists($returnType)) { + throw new ServiceCreationException("Check a type hint or annotation @return of the $methodName method used in service '$name', class '$returnType' cannot be found."); + } + $def->setType($returnType); + } + + if ($rc->hasMethod('get')) { + if ($method->getParameters()) { + throw new ServiceCreationException("Method $methodName used in service '$name' must have no arguments."); + } elseif ($def->getSetup()) { + throw new ServiceCreationException("Service accessor '$name' must have no setup."); + } + if (!$def->getEntity()) { + $def->setFactory('@\\' . ltrim($def->getType(), '\\')); + } elseif (!$this->getServiceName($def->getFactory()->getEntity())) { + throw new ServiceCreationException("Invalid factory in service '$name' definition."); + } + } + + if (!$def->parameters) { + $ctorParams = []; + if (!$def->getEntity()) { + $def->setFactory($def->getType(), $def->getFactory() ? $def->getFactory()->arguments : []); + } + if ( + ($class = $this->resolveEntityType($def->getFactory(), [$name => 1])) + && ($ctor = (new ReflectionClass($class))->getConstructor()) + ) { + foreach ($ctor->getParameters() as $param) { + $ctorParams[$param->getName()] = $param; + } + } + + foreach ($method->getParameters() as $param) { + $hint = Reflection::getParameterType($param); + if (isset($ctorParams[$param->getName()])) { + $arg = $ctorParams[$param->getName()]; + $argHint = Reflection::getParameterType($arg); + if ($hint !== $argHint && !is_a($hint, $argHint, true)) { + throw new ServiceCreationException("Type hint for \${$param->getName()} in $methodName doesn't match type hint in $class constructor."); + } + $def->getFactory()->arguments[$arg->getPosition()] = self::literal('$' . $arg->getName()); + } elseif (!$def->getSetup()) { + $hint = Nette\Utils\ObjectHelpers::getSuggestion(array_keys($ctorParams), $param->getName()); + throw new ServiceCreationException("Unused parameter \${$param->getName()} when implementing method $methodName" . ($hint ? ", did you mean \${$hint}?" : '.')); + } + $nullable = $hint && $param->allowsNull() && (!$param->isDefaultValueAvailable() || $param->getDefaultValue() !== null); + $paramDef = ($nullable ? '?' : '') . $hint . ' ' . $param->getName(); + if ($param->isDefaultValueAvailable()) { + $def->parameters[$paramDef] = Reflection::getParameterDefaultValue($param); + } else { + $def->parameters[] = $paramDef; + } + } + } + } + + + /** @return string|null */ + private function resolveServiceType($name, $recursive = []) + { + if (isset($recursive[$name])) { + throw new ServiceCreationException(sprintf('Circular reference detected for services: %s.', implode(', ', array_keys($recursive)))); + } + $recursive[$name] = true; + + $def = $this->definitions[$name]; + $factoryClass = $def->getFactory() ? $this->resolveEntityType($def->getFactory()->getEntity(), $recursive) : null; // call always to check entities + if ($type = $def->getType() ?: $factoryClass) { + if (!class_exists($type) && !interface_exists($type)) { + throw new ServiceCreationException("Class or interface '$type' used in service '$name' not found."); + } + $type = Helpers::normalizeClass($type); + $def->setType($type); + if (count($recursive) === 1) { + $this->addDependency(new ReflectionClass($factoryClass ?: $type)); + } + + } elseif ($def->getAutowired()) { + throw new ServiceCreationException("Unknown type of service '$name', declare return type of factory method (for PHP 5 use annotation @return)"); + } + return $type; + } + + + /** @return string|null */ + private function resolveEntityType($entity, $recursive = []) + { + $entity = $this->normalizeEntity($entity instanceof Statement ? $entity->getEntity() : $entity); + $serviceName = current(array_slice(array_keys($recursive), -1)); + + if (is_array($entity)) { + if (($service = $this->getServiceName($entity[0])) || $entity[0] instanceof Statement) { + $entity[0] = $this->resolveEntityType($entity[0], $recursive); + if (!$entity[0]) { + return; + } elseif (isset($this->definitions[$service]) && $this->definitions[$service]->getImplement()) { // @Implement::create + return $entity[1] === 'create' ? $this->resolveServiceType($service, $recursive) : null; + } + } + + try { + $reflection = Nette\Utils\Callback::toReflection($entity[0] === '' ? $entity[1] : $entity); + $refClass = $reflection instanceof \ReflectionMethod ? $reflection->getDeclaringClass() : null; + } catch (\ReflectionException $e) { + } + + if (isset($e) || ($refClass && (!$reflection->isPublic() + || ($refClass->isTrait() && !$reflection->isStatic()) + ))) { + throw new ServiceCreationException(sprintf("Method %s() used in service '%s' is not callable.", Nette\Utils\Callback::toString($entity), $serviceName)); + } + $this->addDependency($reflection); + + $type = Helpers::getReturnType($reflection); + if ($type && !class_exists($type) && !interface_exists($type)) { + throw new ServiceCreationException(sprintf("Class or interface '%s' not found. Is return type of %s() used in service '%s' correct?", $type, Nette\Utils\Callback::toString($entity), $serviceName)); + } + return $type; + + } elseif ($service = $this->getServiceName($entity)) { // alias or factory + if (Strings::contains($service, '\\')) { // @\Class + return $service; + } + return $this->definitions[$service]->getImplement() + ?: $this->definitions[$service]->getType() + ?: $this->resolveServiceType($service, $recursive); + + } elseif (is_string($entity)) { // class + if (!class_exists($entity)) { + throw new ServiceCreationException("Class $entity used in service '$serviceName' not found."); + } + return $entity; + } + } + + + /** + * @return void + */ + public function complete() + { + $this->prepareClassList(); + + foreach ($this->definitions as $name => $def) { + if ($def->isDynamic()) { + continue; + } + + $this->currentService = null; + $entity = $def->getFactory()->getEntity(); + $serviceRef = $this->getServiceName($entity); + $factory = $serviceRef && !$def->getFactory()->arguments && !$def->getSetup() && $def->getImplementMode() !== $def::IMPLEMENT_MODE_CREATE + ? new Statement(['@' . self::THIS_CONTAINER, 'getService'], [$serviceRef]) + : $def->getFactory(); + + try { + $def->setFactory($this->completeStatement($factory)); + $this->classListNeedsRefresh = false; + + $this->currentService = $name; + $setups = $def->getSetup(); + foreach ($setups as &$setup) { + if (is_string($setup->getEntity()) && strpbrk($setup->getEntity(), ':@?\\') === false) { // auto-prepend @self + $setup = new Statement(['@' . $name, $setup->getEntity()], $setup->arguments); + } + $setup = $this->completeStatement($setup); + } + $def->setSetup($setups); + + } catch (\Exception $e) { + $type = $def->getType(); + if (!$type) { + $message = "Service '$name': " . $e->getMessage(); + } elseif (ctype_digit($name)) { + $message = "Service of type $type: " . str_replace("$type::", '', $e->getMessage()); + } else { + $message = "Service '$name' (type of $type): " . str_replace("$type::", '', $e->getMessage()); + } + throw $e instanceof ServiceCreationException + ? $e->setMessage($message) + : new ServiceCreationException($message, 0, $e); + + } finally { + $this->currentService = null; + } + } + } + + + /** + * @return Statement + */ + public function completeStatement(Statement $statement) + { + $entity = $this->normalizeEntity($statement->getEntity()); + $arguments = $statement->arguments; + + if (is_string($entity) && Strings::contains($entity, '?')) { // PHP literal + + } elseif ($service = $this->getServiceName($entity)) { // factory calling + $params = []; + foreach ($this->definitions[$service]->parameters as $k => $v) { + $params[] = preg_replace('#\w+\z#', '\$$0', (is_int($k) ? $v : $k)) . (is_int($k) ? '' : ' = ' . PhpHelpers::dump($v)); + } + $rm = new \ReflectionFunction(eval('return function(' . implode(', ', $params) . ') {};')); + $arguments = Helpers::autowireArguments($rm, $arguments, $this); + $entity = '@' . $service; + + } elseif ($entity === 'not') { // operator + + } elseif (is_string($entity)) { // class name + if (!class_exists($entity)) { + throw new ServiceCreationException("Class $entity not found."); + } elseif ((new ReflectionClass($entity))->isAbstract()) { + throw new ServiceCreationException("Class $entity is abstract."); + } elseif (($rm = (new ReflectionClass($entity))->getConstructor()) !== null && !$rm->isPublic()) { + $visibility = $rm->isProtected() ? 'protected' : 'private'; + throw new ServiceCreationException("Class $entity has $visibility constructor."); + } elseif ($constructor = (new ReflectionClass($entity))->getConstructor()) { + $this->addDependency($constructor); + $arguments = Helpers::autowireArguments($constructor, $arguments, $this); + } elseif ($arguments) { + throw new ServiceCreationException("Unable to pass arguments, class $entity has no constructor."); + } + + } elseif (!Nette\Utils\Arrays::isList($entity) || count($entity) !== 2) { + throw new ServiceCreationException(sprintf('Expected class, method or property, %s given.', PhpHelpers::dump($entity))); + + } elseif (!preg_match('#^\$?(\\\\?' . PhpHelpers::PHP_IDENT . ')+(\[\])?\z#', $entity[1])) { + throw new ServiceCreationException("Expected function, method or property name, '$entity[1]' given."); + + } elseif ($entity[0] === '') { // globalFunc + if (!Nette\Utils\Arrays::isList($arguments)) { + throw new ServiceCreationException("Unable to pass specified arguments to $entity[0]."); + } elseif (!function_exists($entity[1])) { + throw new ServiceCreationException("Function $entity[1] doesn't exist."); + } + + $rf = new \ReflectionFunction($entity[1]); + $this->addDependency($rf); + $arguments = Helpers::autowireArguments($rf, $arguments, $this); + + } else { + if ($entity[0] instanceof Statement) { + $entity[0] = $this->completeStatement($entity[0]); + } elseif ($service = $this->getServiceName($entity[0])) { // service method + $entity[0] = '@' . $service; + } + + if ($entity[1][0] === '$') { // property getter, setter or appender + Validators::assert($arguments, 'list:0..1', "setup arguments for '" . Nette\Utils\Callback::toString($entity) . "'"); + if (!$arguments && substr($entity[1], -2) === '[]') { + throw new ServiceCreationException("Missing argument for $entity[1]."); + } + } elseif ( + $type = empty($service) || $entity[1] === 'create' + ? $this->resolveEntityType($entity[0]) + : $this->definitions[$service]->getType() + ) { + $arguments = $this->autowireArguments($type, $entity[1], $arguments); + } + } + + try { + array_walk_recursive($arguments, function (&$val) { + if ($val instanceof Statement) { + $val = $this->completeStatement($val); + + } elseif ($val === $this) { + trigger_error("Replace object ContainerBuilder in Statement arguments with '@container'.", E_USER_DEPRECATED); + $val = self::literal('$this'); + + } elseif ($val instanceof ServiceDefinition) { + $val = '@' . current(array_keys($this->getDefinitions(), $val, true)); + + } elseif (is_string($val) && strlen($val) > 1 && $val[0] === '@' && $val[1] !== '@') { + $pair = explode('::', $val, 2); + $name = $this->getServiceName($pair[0]); + if (!isset($pair[1])) { // @service + $val = '@' . $name; + } elseif (preg_match('#^[A-Z][A-Z0-9_]*\z#', $pair[1], $m)) { // @service::CONSTANT + $val = self::literal($this->getDefinition($name)->getType() . '::' . $pair[1]); + } else { // @service::property + $val = new Statement(['@' . $name, '$' . $pair[1]]); + } + } + }); + + } catch (ServiceCreationException $e) { + if ((is_string($entity) || is_array($entity)) && !strpos($e->getMessage(), ' (used in')) { + $desc = is_string($entity) + ? $entity . '::__construct()' + : (is_string($entity[0]) ? ($entity[0] . '::') : '') + . $entity[1] . (strpos($entity[1], '$') === false ? '()' : ''); + $e->setMessage($e->getMessage() . " (used in $desc)"); + } + throw $e; + } + + return new Statement($entity, $arguments); + } + + + /** + * Adds item to the list of dependencies. + * @param ReflectionClass|\ReflectionFunctionAbstract|string + * @return static + * @internal + */ + public function addDependency($dep) + { + $this->dependencies[] = $dep; + return $this; + } + + + /** + * Returns the list of dependencies. + * @return array + */ + public function getDependencies() + { + return $this->dependencies; + } + + + /** + * Expands %placeholders% in strings. + * @return mixed + * @deprecated + */ + public function expand($value) + { + return Helpers::expand($value, $this->parameters); + } + + + /** + * @return Nette\PhpGenerator\PhpLiteral + */ + public static function literal($code, array $args = null) + { + return new Nette\PhpGenerator\PhpLiteral($args === null ? $code : PhpHelpers::formatArgs($code, $args)); + } + + + /** + * @return string|array Class, @service, [Class, member], [@service, member], [, globalFunc], [Statement, member] + * @internal + */ + public function normalizeEntity($entity) + { + if (is_string($entity) && Strings::contains($entity, '::') && !Strings::contains($entity, '?')) { // Class::method -> [Class, method] + $entity = explode('::', $entity); + } + + if (is_array($entity) && $entity[0] instanceof ServiceDefinition) { // [ServiceDefinition, ...] -> [@serviceName, ...] + $entity[0] = '@' . current(array_keys($this->definitions, $entity[0], true)); + + } elseif ($entity instanceof ServiceDefinition) { // ServiceDefinition -> @serviceName + $entity = '@' . current(array_keys($this->definitions, $entity, true)); + + } elseif (is_array($entity) && $entity[0] === $this) { // [$this, ...] -> [@container, ...] + trigger_error("Replace object ContainerBuilder in Statement entity with '@container'.", E_USER_DEPRECATED); + $entity[0] = '@' . self::THIS_CONTAINER; + } + return $entity; + } + + + /** + * Converts @service or @\Class -> service name and checks its existence. + * @return string of false, if argument is not service name + * @internal + */ + public function getServiceName($arg) + { + if (!is_string($arg) || !preg_match('#^@[\w\\\\.][^:]*\z#', $arg)) { + return false; + } + $service = substr($arg, 1); + if ($service === self::THIS_SERVICE) { + $service = $this->currentService; + } + if (Strings::contains($service, '\\')) { + if ($this->classList === false) { // may be disabled by prepareClassList + return $service; + } + $res = $this->getByType($service); + if (!$res) { + throw new ServiceCreationException("Reference to missing service of type $service."); + } + return $res; + } + $service = isset($this->aliases[$service]) ? $this->aliases[$service] : $service; + if (!isset($this->definitions[$service])) { + throw new ServiceCreationException("Reference to missing service '$service'."); + } + return $service; + } + + + /** + * Creates a list of arguments using autowiring. + * @return array + * @internal + */ + public function autowireArguments($class, $method, array $arguments) + { + $rc = new ReflectionClass($class); + if (!$rc->hasMethod($method)) { + if (!Nette\Utils\Arrays::isList($arguments)) { + throw new ServiceCreationException("Unable to pass specified arguments to $class::$method()."); + } + return $arguments; + } + + $rm = $rc->getMethod($method); + if (!$rm->isPublic()) { + throw new ServiceCreationException("$class::$method() is not callable."); + } + $this->addDependency($rm); + return Helpers::autowireArguments($rm, $arguments, $this); + } + + + /** @deprecated */ + public function generateClasses($className = 'Container', $parentName = null) + { + trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED); + return (new PhpGenerator($this))->generate($className); + } + + + /** @deprecated */ + public function formatStatement(Statement $statement) + { + trigger_error(__METHOD__ . ' is deprecated', E_USER_DEPRECATED); + return (new PhpGenerator($this))->formatStatement($statement); + } + + + /** @deprecated */ + public function formatPhp($statement, $args) + { + array_walk_recursive($args, function (&$val) { + if ($val instanceof Statement) { + $val = $this->completeStatement($val); + + } elseif ($val === $this) { + trigger_error("Replace object ContainerBuilder in Statement arguments with '@container'.", E_USER_DEPRECATED); + $val = self::literal('$this'); + + } elseif ($val instanceof ServiceDefinition) { + $val = '@' . current(array_keys($this->getDefinitions(), $val, true)); + } + }); + return (new PhpGenerator($this))->formatPhp($statement, $args); + } +} diff --git a/vendor/nette/di/src/DI/ContainerLoader.php b/vendor/nette/di/src/DI/ContainerLoader.php new file mode 100644 index 00000000..4d9b5871 --- /dev/null +++ b/vendor/nette/di/src/DI/ContainerLoader.php @@ -0,0 +1,131 @@ +tempDirectory = $tempDirectory; + $this->autoRebuild = $autoRebuild; + } + + + /** + * @param callable function (Nette\DI\Compiler $compiler): string|null + * @param mixed + * @return string + */ + public function load($generator, $key = null) + { + if (!is_callable($generator)) { // back compatiblity + trigger_error(__METHOD__ . ': order of arguments has been swapped.', E_USER_DEPRECATED); + list($generator, $key) = [$key, $generator]; + } + $class = $this->getClassName($key); + if (!class_exists($class, false)) { + $this->loadFile($class, $generator); + } + return $class; + } + + + /** + * @return string + */ + public function getClassName($key) + { + return 'Container_' . substr(md5(serialize($key)), 0, 10); + } + + + /** + * @return void + */ + private function loadFile($class, $generator) + { + $file = "$this->tempDirectory/$class.php"; + if (!$this->isExpired($file) && (@include $file) !== false) { // @ file may not exist + return; + } + + Nette\Utils\FileSystem::createDir($this->tempDirectory); + + $handle = @fopen("$file.lock", 'c+'); // @ is escalated to exception + if (!$handle) { + throw new Nette\IOException("Unable to create file '$file.lock'. " . error_get_last()['message']); + } elseif (!@flock($handle, LOCK_EX)) { // @ is escalated to exception + throw new Nette\IOException("Unable to acquire exclusive lock on '$file.lock'. " . error_get_last()['message']); + } + + if (!is_file($file) || $this->isExpired($file, $updatedMeta)) { + if (isset($updatedMeta)) { + $toWrite["$file.meta"] = $updatedMeta; + } else { + list($toWrite[$file], $toWrite["$file.meta"]) = $this->generate($class, $generator); + } + + foreach ($toWrite as $name => $content) { + if (file_put_contents("$name.tmp", $content) !== strlen($content) || !rename("$name.tmp", $name)) { + @unlink("$name.tmp"); // @ - file may not exist + throw new Nette\IOException("Unable to create file '$name'."); + } elseif (function_exists('opcache_invalidate')) { + @opcache_invalidate($name, true); // @ can be restricted + } + } + } + + if ((@include $file) === false) { // @ - error escalated to exception + throw new Nette\IOException("Unable to include '$file'."); + } + flock($handle, LOCK_UN); + } + + + private function isExpired($file, &$updatedMeta = null) + { + if ($this->autoRebuild) { + $meta = @unserialize((string) file_get_contents("$file.meta")); // @ - file may not exist + $orig = $meta[2]; + return empty($meta[0]) + || DependencyChecker::isExpired(...$meta) + || ($orig !== $meta[2] && $updatedMeta = serialize($meta)); + } + return false; + } + + + /** + * @return array of (code, file[]) + */ + protected function generate($class, $generator) + { + $compiler = new Compiler; + $compiler->setClassName($class); + $code = call_user_func_array($generator, [&$compiler]) ?: $compiler->compile(); + return [ + "exportDependencies()), + ]; + } +} diff --git a/vendor/nette/di/src/DI/DependencyChecker.php b/vendor/nette/di/src/DI/DependencyChecker.php new file mode 100644 index 00000000..739b94fc --- /dev/null +++ b/vendor/nette/di/src/DI/DependencyChecker.php @@ -0,0 +1,176 @@ +dependencies = array_merge($this->dependencies, $deps); + return $this; + } + + + /** + * Exports dependencies. + * @return array + */ + public function export() + { + $files = $phpFiles = $classes = $functions = []; + foreach ($this->dependencies as $dep) { + if (is_string($dep)) { + $files[] = $dep; + + } elseif ($dep instanceof ReflectionClass) { + if (empty($classes[$name = $dep->getName()])) { + $all = [$name] + class_parents($name) + class_implements($name); + foreach ($all as &$item) { + $all += class_uses($item); + $phpFiles[] = (new ReflectionClass($item))->getFileName(); + $classes[$item] = true; + } + } + + } elseif ($dep instanceof \ReflectionFunctionAbstract) { + $phpFiles[] = $dep->getFileName(); + $functions[] = Reflection::toString($dep); + + } else { + throw new Nette\InvalidStateException('Unexpected dependency ' . gettype($dep)); + } + } + + $classes = array_keys($classes); + $functions = array_unique($functions, SORT_REGULAR); + $hash = self::calculateHash($classes, $functions); + $files = @array_map('filemtime', array_combine($files, $files)); // @ - file may not exist + $phpFiles = @array_map('filemtime', array_combine($phpFiles, $phpFiles)); // @ - file may not exist + return [self::VERSION, $files, $phpFiles, $classes, $functions, $hash]; + } + + + /** + * Are dependencies expired? + * @return bool + */ + public static function isExpired($version, $files, &$phpFiles, $classes, $functions, $hash) + { + $current = @array_map('filemtime', array_combine($tmp = array_keys($files), $tmp)); // @ - files may not exist + $origPhpFiles = $phpFiles; + $phpFiles = @array_map('filemtime', array_combine($tmp = array_keys($phpFiles), $tmp)); // @ - files may not exist + return $version !== self::VERSION + || $files !== $current + || ($phpFiles !== $origPhpFiles && $hash !== self::calculateHash($classes, $functions)); + } + + + private static function calculateHash($classes, $functions) + { + $hash = []; + foreach ($classes as $name) { + try { + $class = new ReflectionClass($name); + } catch (\ReflectionException $e) { + return; + } + $hash[] = [ + $name, + Reflection::getUseStatements($class), + $class->isAbstract(), + get_parent_class($name), + class_implements($name), + class_uses($name), + ]; + + foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $prop) { + if ($prop->getDeclaringClass() == $class) { // intentionally == + $hash[] = [$name, $prop->getName(), $prop->getDocComment()]; + } + } + foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { + if ($method->getDeclaringClass() == $class) { // intentionally == + $hash[] = [ + $name, + $method->getName(), + $method->getDocComment(), + self::hashParameters($method), + PHP_VERSION_ID >= 70000 && $method->hasReturnType() + ? [(string) $method->getReturnType(), $method->getReturnType()->allowsNull()] + : null, + ]; + } + } + } + + $flip = array_flip($classes); + foreach ($functions as $name) { + try { + $method = strpos($name, '::') ? new ReflectionMethod($name) : new \ReflectionFunction($name); + } catch (\ReflectionException $e) { + return; + } + $class = $method instanceof ReflectionMethod ? $method->getDeclaringClass() : null; + if ($class && isset($flip[$class->getName()])) { + continue; + } + $hash[] = [ + $name, + $class ? Reflection::getUseStatements($method->getDeclaringClass()) : null, + $method->getDocComment(), + self::hashParameters($method), + PHP_VERSION_ID >= 70000 && $method->hasReturnType() + ? [(string) $method->getReturnType(), $method->getReturnType()->allowsNull()] + : null, + ]; + } + + return md5(serialize($hash)); + } + + + private static function hashParameters(\ReflectionFunctionAbstract $method) + { + $res = []; + if (PHP_VERSION_ID < 70000 && $method->getNumberOfParameters() && $method->getFileName()) { + $res[] = file($method->getFileName())[$method->getStartLine() - 1]; + } + foreach ($method->getParameters() as $param) { + $res[] = [ + $param->getName(), + PHP_VERSION_ID >= 70000 ? [Reflection::getParameterType($param), $param->allowsNull()] : null, + $param->isVariadic(), + $param->isDefaultValueAvailable() + ? [Reflection::getParameterDefaultValue($param)] + : null, + ]; + } + return $res; + } +} diff --git a/vendor/nette/di/src/DI/Extensions/ConstantsExtension.php b/vendor/nette/di/src/DI/Extensions/ConstantsExtension.php new file mode 100644 index 00000000..821b0685 --- /dev/null +++ b/vendor/nette/di/src/DI/Extensions/ConstantsExtension.php @@ -0,0 +1,24 @@ +getConfig() as $name => $value) { + $class->getMethod('initialize')->addBody('define(?, ?);', [$name, $value]); + } + } +} diff --git a/vendor/nette/di/src/DI/Extensions/DIExtension.php b/vendor/nette/di/src/DI/Extensions/DIExtension.php new file mode 100644 index 00000000..5b626ad0 --- /dev/null +++ b/vendor/nette/di/src/DI/Extensions/DIExtension.php @@ -0,0 +1,67 @@ + true, + 'accessors' => false, + 'excluded' => [], + 'parentClass' => null, + ]; + + /** @var bool */ + private $debugMode; + + /** @var int */ + private $time; + + + public function __construct($debugMode = false) + { + $this->debugMode = $debugMode; + $this->time = microtime(true); + } + + + public function loadConfiguration() + { + $config = $this->validateConfig($this->defaults); + $builder = $this->getContainerBuilder(); + $builder->addExcludedClasses($config['excluded']); + } + + + public function afterCompile(Nette\PhpGenerator\ClassType $class) + { + if ($this->config['parentClass']) { + $class->setExtends($this->config['parentClass']); + } + + $initialize = $class->getMethod('initialize'); + $builder = $this->getContainerBuilder(); + + if ($this->debugMode && $this->config['debugger']) { + Nette\Bridges\DITracy\ContainerPanel::$compilationTime = $this->time; + $initialize->addBody($builder->formatPhp('?;', [ + new Nette\DI\Statement('@Tracy\Bar::addPanel', [new Nette\DI\Statement(Nette\Bridges\DITracy\ContainerPanel::class)]), + ])); + } + + foreach (array_filter($builder->findByTag('run')) as $name => $on) { + $initialize->addBody('$this->getService(?);', [$name]); + } + } +} diff --git a/vendor/nette/di/src/DI/Extensions/DecoratorExtension.php b/vendor/nette/di/src/DI/Extensions/DecoratorExtension.php new file mode 100644 index 00000000..35ad35ff --- /dev/null +++ b/vendor/nette/di/src/DI/Extensions/DecoratorExtension.php @@ -0,0 +1,68 @@ + [], + 'tags' => [], + 'inject' => null, + ]; + + + public function beforeCompile() + { + foreach ($this->getConfig() as $type => $info) { + $info = $this->validateConfig($this->defaults, $info, $this->prefix($type)); + if ($info['inject'] !== null) { + $info['tags'][InjectExtension::TAG_INJECT] = $info['inject']; + } + $info = Nette\DI\Helpers::filterArguments($info); + $this->addSetups($type, (array) $info['setup']); + $this->addTags($type, (array) $info['tags']); + } + } + + + public function addSetups($type, array $setups) + { + foreach ($this->findByType($type) as $def) { + foreach ($setups as $setup) { + if (is_array($setup)) { + $setup = new Nette\DI\Statement(key($setup), array_values($setup)); + } + $def->addSetup($setup); + } + } + } + + + public function addTags($type, array $tags) + { + $tags = Nette\Utils\Arrays::normalize($tags, true); + foreach ($this->findByType($type) as $def) { + $def->setTags($def->getTags() + $tags); + } + } + + + private function findByType($type) + { + return array_filter($this->getContainerBuilder()->getDefinitions(), function ($def) use ($type) { + return is_a($def->getImplement(), $type, true) + || ($def->getImplementMode() !== $def::IMPLEMENT_MODE_GET && is_a($def->getType(), $type, true)); + }); + } +} diff --git a/vendor/nette/di/src/DI/Extensions/ExtensionsExtension.php b/vendor/nette/di/src/DI/Extensions/ExtensionsExtension.php new file mode 100644 index 00000000..78b13704 --- /dev/null +++ b/vendor/nette/di/src/DI/Extensions/ExtensionsExtension.php @@ -0,0 +1,32 @@ +getConfig() as $name => $class) { + if (is_int($name)) { + $name = null; + } + if ($class instanceof Nette\DI\Statement) { + $rc = new \ReflectionClass($class->getEntity()); + $this->compiler->addExtension($name, $rc->newInstanceArgs($class->arguments)); + } else { + $this->compiler->addExtension($name, new $class); + } + } + } +} diff --git a/vendor/nette/di/src/DI/Extensions/InjectExtension.php b/vendor/nette/di/src/DI/Extensions/InjectExtension.php new file mode 100644 index 00000000..2f27a74e --- /dev/null +++ b/vendor/nette/di/src/DI/Extensions/InjectExtension.php @@ -0,0 +1,144 @@ +getContainerBuilder()->getDefinitions() as $def) { + if ($def->getTag(self::TAG_INJECT) && $def->getType()) { + $this->updateDefinition($def); + } + } + } + + + private function updateDefinition(DI\ServiceDefinition $def) + { + $class = $def->getType(); + $setups = $def->getSetup(); + + foreach (self::getInjectProperties($class) as $property => $type) { + $builder = $this->getContainerBuilder(); + $inject = new DI\Statement('$' . $property, ['@\\' . ltrim($type, '\\')]); + foreach ($setups as $key => $setup) { + if ($setup->getEntity() === $inject->getEntity()) { + $inject = $setup; + $builder = null; + unset($setups[$key]); + } + } + self::checkType($class, $property, $type, $builder); + array_unshift($setups, $inject); + } + + foreach (array_reverse(self::getInjectMethods($def->getType())) as $method) { + $inject = new DI\Statement($method); + foreach ($setups as $key => $setup) { + if ($setup->getEntity() === $inject->getEntity()) { + $inject = $setup; + unset($setups[$key]); + } + } + array_unshift($setups, $inject); + } + + $def->setSetup($setups); + } + + + /** + * Generates list of inject methods. + * @return array + * @internal + */ + public static function getInjectMethods($class) + { + $res = []; + foreach (get_class_methods($class) as $name) { + if (substr($name, 0, 6) === 'inject') { + $res[$name] = (new \ReflectionMethod($class, $name))->getDeclaringClass()->getName(); + } + } + uksort($res, function ($a, $b) use ($res) { + return $res[$a] === $res[$b] + ? strcmp($a, $b) + : (is_a($res[$a], $res[$b], true) ? 1 : -1); + }); + return array_keys($res); + } + + + /** + * Generates list of properties with annotation @inject. + * @return array + * @internal + */ + public static function getInjectProperties($class) + { + $res = []; + foreach (get_class_vars($class) as $name => $foo) { + $rp = new \ReflectionProperty($class, $name); + if (DI\Helpers::parseAnnotation($rp, 'inject') !== null) { + if ($type = DI\Helpers::parseAnnotation($rp, 'var')) { + $type = Reflection::expandClassName($type, Reflection::getPropertyDeclaringClass($rp)); + } + $res[$name] = $type; + } + } + ksort($res); + return $res; + } + + + /** + * Calls all methods starting with with "inject" using autowiring. + * @return void + */ + public static function callInjects(DI\Container $container, $service) + { + if (!is_object($service)) { + throw new Nette\InvalidArgumentException(sprintf('Service must be object, %s given.', gettype($service))); + } + + foreach (self::getInjectMethods($service) as $method) { + $container->callMethod([$service, $method]); + } + + foreach (self::getInjectProperties(get_class($service)) as $property => $type) { + self::checkType($service, $property, $type, $container); + $service->$property = $container->getByType($type); + } + } + + + /** @internal */ + private static function checkType($class, $name, $type, $container = null) + { + $propName = Reflection::toString(new \ReflectionProperty($class, $name)); + if (!$type) { + throw new Nette\InvalidStateException("Property $propName has no @var annotation."); + } elseif (!class_exists($type) && !interface_exists($type)) { + throw new Nette\InvalidStateException("Class or interface '$type' used in @var annotation at $propName not found. Check annotation and 'use' statements."); + } elseif ($container && !$container->getByType($type, false)) { + throw new Nette\InvalidStateException("Service of type $type used in @var annotation at $propName not found. Did you register it in configuration file?"); + } + } +} diff --git a/vendor/nette/di/src/DI/Extensions/PhpExtension.php b/vendor/nette/di/src/DI/Extensions/PhpExtension.php new file mode 100644 index 00000000..0b2a11aa --- /dev/null +++ b/vendor/nette/di/src/DI/Extensions/PhpExtension.php @@ -0,0 +1,48 @@ +getMethod('initialize'); + foreach ($this->getConfig() as $name => $value) { + if ($value === null) { + continue; + + } elseif (!is_scalar($value)) { + throw new Nette\InvalidStateException("Configuration value for directive '$name' is not scalar."); + + } elseif ($name === 'include_path') { + $initialize->addBody('set_include_path(?);', [str_replace(';', PATH_SEPARATOR, $value)]); + + } elseif ($name === 'ignore_user_abort') { + $initialize->addBody('ignore_user_abort(?);', [$value]); + + } elseif ($name === 'max_execution_time') { + $initialize->addBody('set_time_limit(?);', [$value]); + + } elseif ($name === 'date.timezone') { + $initialize->addBody('date_default_timezone_set(?);', [$value]); + + } elseif (function_exists('ini_set')) { + $initialize->addBody('ini_set(?, ?);', [$name, $value]); + + } elseif (ini_get($name) != $value) { // intentionally == + throw new Nette\NotSupportedException('Required function ini_set() is disabled.'); + } + } + } +} diff --git a/vendor/nette/di/src/DI/Helpers.php b/vendor/nette/di/src/DI/Helpers.php new file mode 100644 index 00000000..da7c1773 --- /dev/null +++ b/vendor/nette/di/src/DI/Helpers.php @@ -0,0 +1,255 @@ + $val) { + $res[$key] = self::expand($val, $params, $recursive); + } + return $res; + + } elseif ($var instanceof Statement) { + return new Statement(self::expand($var->getEntity(), $params, $recursive), self::expand($var->arguments, $params, $recursive)); + + } elseif (!is_string($var)) { + return $var; + } + + $parts = preg_split('#%([\w.-]*)%#i', $var, -1, PREG_SPLIT_DELIM_CAPTURE); + $res = []; + $php = false; + foreach ($parts as $n => $part) { + if ($n % 2 === 0) { + $res[] = $part; + + } elseif ($part === '') { + $res[] = '%'; + + } elseif (isset($recursive[$part])) { + throw new Nette\InvalidArgumentException(sprintf('Circular reference detected for variables: %s.', implode(', ', array_keys($recursive)))); + + } else { + $val = $params; + foreach (explode('.', $part) as $key) { + if (is_array($val) && array_key_exists($key, $val)) { + $val = $val[$key]; + } elseif ($val instanceof PhpLiteral) { + $val = new PhpLiteral($val . '[' . var_export($key, true) . ']'); + } else { + throw new Nette\InvalidArgumentException("Missing parameter '$part'."); + } + } + if ($recursive) { + $val = self::expand($val, $params, (is_array($recursive) ? $recursive : []) + [$part => 1]); + } + if (strlen($part) + 2 === strlen($var)) { + return $val; + } + if ($val instanceof PhpLiteral) { + $php = true; + } elseif (!is_scalar($val)) { + throw new Nette\InvalidArgumentException("Unable to concatenate non-scalar parameter '$part' into '$var'."); + } + $res[] = $val; + } + } + if ($php) { + $res = array_filter($res, function ($val) { return $val !== ''; }); + $res = array_map(function ($val) { return $val instanceof PhpLiteral ? "($val)" : var_export((string) $val, true); }, $res); + return new PhpLiteral(implode(' . ', $res)); + } + return implode('', $res); + } + + + /** + * Generates list of arguments using autowiring. + * @return array + * @throws ServiceCreationException + */ + public static function autowireArguments(\ReflectionFunctionAbstract $method, array $arguments, $container) + { + $optCount = 0; + $num = -1; + $res = []; + $methodName = Reflection::toString($method) . '()'; + + foreach ($method->getParameters() as $num => $parameter) { + $paramName = $parameter->getName(); + if (!$parameter->isVariadic() && array_key_exists($paramName, $arguments)) { + $res[$num] = $arguments[$paramName]; + unset($arguments[$paramName], $arguments[$num]); + $optCount = 0; + + } elseif (array_key_exists($num, $arguments)) { + $res[$num] = $arguments[$num]; + unset($arguments[$num]); + $optCount = 0; + + } elseif (($type = Reflection::getParameterType($parameter)) && !Reflection::isBuiltinType($type)) { + try { + $res[$num] = $container->getByType($type, false); + } catch (ServiceCreationException $e) { + throw new ServiceCreationException("{$e->getMessage()} (needed by $$paramName in $methodName)", 0, $e); + } + if ($res[$num] === null) { + if ($parameter->allowsNull()) { + $optCount++; + } elseif (class_exists($type) || interface_exists($type)) { + throw new ServiceCreationException("Service of type $type needed by $$paramName in $methodName not found. Did you register it in configuration file?"); + } else { + throw new ServiceCreationException("Class $type needed by $$paramName in $methodName not found. Check type hint and 'use' statements."); + } + } else { + if ($container instanceof ContainerBuilder) { + $res[$num] = '@' . $res[$num]; + } + $optCount = 0; + } + + } elseif (($type && $parameter->allowsNull()) || $parameter->isOptional() || $parameter->isDefaultValueAvailable()) { + // !optional + defaultAvailable = func($a = null, $b) since 5.4.7 + // optional + !defaultAvailable = i.e. Exception::__construct, mysqli::mysqli, ... + $res[$num] = $parameter->isDefaultValueAvailable() ? Reflection::getParameterDefaultValue($parameter) : null; + $optCount++; + + } else { + throw new ServiceCreationException("Parameter $$paramName in $methodName has no class type hint or default value, so its value must be specified."); + } + } + + // extra parameters + while (array_key_exists(++$num, $arguments)) { + $res[$num] = $arguments[$num]; + unset($arguments[$num]); + $optCount = 0; + } + if ($arguments) { + throw new ServiceCreationException("Unable to pass specified arguments to $methodName."); + } + + return $optCount ? array_slice($res, 0, -$optCount) : $res; + } + + + /** + * Removes ... and process constants recursively. + * @return array + */ + public static function filterArguments(array $args) + { + foreach ($args as $k => $v) { + if ($v === '...') { + unset($args[$k]); + } elseif (is_string($v) && preg_match('#^[\w\\\\]*::[A-Z][A-Z0-9_]*\z#', $v, $m)) { + $args[$k] = constant(ltrim($v, ':')); + } elseif (is_array($v)) { + $args[$k] = self::filterArguments($v); + } elseif ($v instanceof Statement) { + $tmp = self::filterArguments([$v->getEntity()]); + $args[$k] = new Statement($tmp[0], self::filterArguments($v->arguments)); + } + } + return $args; + } + + + /** + * Replaces @extension with real extension name in service definition. + * @param mixed + * @param string + * @return mixed + */ + public static function prefixServiceName($config, $namespace) + { + if (is_string($config)) { + if (strncmp($config, '@extension.', 10) === 0) { + $config = '@' . $namespace . '.' . substr($config, 11); + } + } elseif ($config instanceof Statement) { + return new Statement( + self::prefixServiceName($config->getEntity(), $namespace), + self::prefixServiceName($config->arguments, $namespace) + ); + } elseif (is_array($config)) { + foreach ($config as &$val) { + $val = self::prefixServiceName($val, $namespace); + } + } + return $config; + } + + + /** + * Returns an annotation value. + * @return string|null + */ + public static function parseAnnotation(\Reflector $ref, $name) + { + if (!Reflection::areCommentsAvailable()) { + throw new Nette\InvalidStateException('You have to enable phpDoc comments in opcode cache.'); + } + $name = preg_quote($name, '#'); + if ($ref->getDocComment() && preg_match("#[\\s*]@$name(?:\\s++([^@]\\S*)?|$)#", trim($ref->getDocComment(), '/*'), $m)) { + return isset($m[1]) ? $m[1] : ''; + } + } + + + /** + * @return string|null + */ + public static function getReturnType(\ReflectionFunctionAbstract $func) + { + if ($type = Reflection::getReturnType($func)) { + return $type; + } elseif ($type = preg_replace('#[|\s].*#', '', (string) self::parseAnnotation($func, 'return'))) { + if ($type === 'object' || $type === 'mixed') { + return null; + } elseif ($func instanceof \ReflectionMethod) { + return $type === 'static' || $type === '$this' + ? $func->getDeclaringClass()->getName() + : Reflection::expandClassName($type, $func->getDeclaringClass()); + } else { + return $type; + } + } + } + + + public static function normalizeClass($type) + { + return class_exists($type) || interface_exists($type) + ? (new \ReflectionClass($type))->getName() + : $type; + } +} diff --git a/vendor/nette/di/src/DI/PhpGenerator.php b/vendor/nette/di/src/DI/PhpGenerator.php new file mode 100644 index 00000000..791f6b9f --- /dev/null +++ b/vendor/nette/di/src/DI/PhpGenerator.php @@ -0,0 +1,275 @@ +builder = $builder; + } + + + /** + * Generates PHP classes. First class is the container. + * @return Nette\PhpGenerator\ClassType[] + */ + public function generate($className) + { + $this->builder->complete(); + + $this->generatedClasses = []; + $this->className = $className; + $containerClass = $this->generatedClasses[] = new Nette\PhpGenerator\ClassType($this->className); + $containerClass->setExtends(Container::class); + $containerClass->addMethod('__construct') + ->addBody('$this->parameters = $params;') + ->addBody('$this->parameters += ?;', [$this->builder->parameters]) + ->addParameter('params', []) + ->setTypeHint('array'); + + $definitions = $this->builder->getDefinitions(); + ksort($definitions); + + $meta = $containerClass->addProperty('meta') + ->setVisibility('protected') + ->setValue([Container::TYPES => $this->builder->getClassList()]); + + foreach ($definitions as $name => $def) { + $meta->value[Container::SERVICES][$name] = $def->getImplement() ?: $def->getType() ?: null; + foreach ($def->getTags() as $tag => $value) { + $meta->value[Container::TAGS][$tag][$name] = $value; + } + } + + foreach ($definitions as $name => $def) { + try { + $name = (string) $name; + $methodName = Container::getMethodName($name); + if (!PhpHelpers::isIdentifier($methodName)) { + throw new ServiceCreationException('Name contains invalid characters.'); + } + $containerClass->addMethod($methodName) + ->addComment(PHP_VERSION_ID < 70000 ? '@return ' . ($def->getImplement() ?: $def->getType()) : '') + ->setReturnType(PHP_VERSION_ID >= 70000 ? ($def->getImplement() ?: $def->getType()) : null) + ->setBody($name === ContainerBuilder::THIS_CONTAINER ? 'return $this;' : $this->generateService($name)) + ->setParameters($def->getImplement() ? [] : $this->convertParameters($def->parameters)); + } catch (\Exception $e) { + throw new ServiceCreationException("Service '$name': " . $e->getMessage(), 0, $e); + } + } + + $aliases = $this->builder->getAliases(); + ksort($aliases); + $meta->value[Container::ALIASES] = $aliases; + + return $this->generatedClasses; + } + + + /** + * Generates body of service method. + * @return string + */ + private function generateService($name) + { + $def = $this->builder->getDefinition($name); + + if ($def->isDynamic()) { + return PhpHelpers::formatArgs('throw new Nette\\DI\\ServiceCreationException(?);', + ["Unable to create dynamic service '$name', it must be added using addService()"] + ); + } + + $entity = $def->getFactory()->getEntity(); + $serviceRef = $this->builder->getServiceName($entity); + $factory = $serviceRef && !$def->getFactory()->arguments && !$def->getSetup() && $def->getImplementMode() !== $def::IMPLEMENT_MODE_CREATE + ? new Statement(['@' . ContainerBuilder::THIS_CONTAINER, 'getService'], [$serviceRef]) + : $def->getFactory(); + + $this->currentService = null; + $code = '$service = ' . $this->formatStatement($factory) . ";\n"; + + if ( + (PHP_VERSION_ID < 70000 || $def->getSetup()) + && ($type = $def->getType()) + && !$serviceRef && $type !== $entity + && !(is_string($entity) && preg_match('#^[\w\\\\]+\z#', $entity) && is_subclass_of($entity, $type)) + ) { + $code .= PhpHelpers::formatArgs("if (!\$service instanceof $type) {\n" + . "\tthrow new Nette\\UnexpectedValueException(?);\n}\n", + ["Unable to create service '$name', value returned by factory is not $type type."] + ); + } + + $this->currentService = $name; + foreach ($def->getSetup() as $setup) { + $code .= $this->formatStatement($setup) . ";\n"; + } + + $code .= 'return $service;'; + + if (!$def->getImplement()) { + return $code; + } + + $factoryClass = (new Nette\PhpGenerator\ClassType) + ->addImplement($def->getImplement()); + + $factoryClass->addProperty('container') + ->setVisibility('private'); + + $factoryClass->addMethod('__construct') + ->addBody('$this->container = $container;') + ->addParameter('container') + ->setTypeHint($this->className); + + $rm = new \ReflectionMethod($def->getImplement(), $def->getImplementMode()); + + $factoryClass->addMethod($def->getImplementMode()) + ->setParameters($this->convertParameters($def->parameters)) + ->setBody(str_replace('$this', '$this->container', $code)) + ->setReturnType(PHP_VERSION_ID >= 70000 ? (Reflection::getReturnType($rm) ?: $def->getType()) : null); + + if (PHP_VERSION_ID < 70000) { + $this->generatedClasses[] = $factoryClass; + $factoryClass->setName(str_replace(['\\', '.'], '_', "{$this->className}_{$def->getImplement()}Impl_{$name}")); + return "return new {$factoryClass->getName()}(\$this);"; + } + + return 'return new class ($this) ' . $factoryClass . ';'; + } + + + /** + * Formats PHP code for class instantiating, function calling or property setting in PHP. + * @return string + */ + private function formatStatement(Statement $statement) + { + $entity = $statement->getEntity(); + $arguments = $statement->arguments; + + if (is_string($entity) && Strings::contains($entity, '?')) { // PHP literal + return $this->formatPhp($entity, $arguments); + + } elseif ($service = $this->builder->getServiceName($entity)) { // factory calling + return $this->formatPhp('$this->?(...?)', [Container::getMethodName($service), $arguments]); + + } elseif ($entity === 'not') { // operator + return $this->formatPhp('!?', [$arguments[0]]); + + } elseif (is_string($entity)) { // class name + return $this->formatPhp("new $entity" . ($arguments ? '(...?)' : ''), $arguments ? [$arguments] : []); + + } elseif ($entity[0] === '') { // globalFunc + return $this->formatPhp("$entity[1](...?)", [$arguments]); + + } elseif ($entity[0] instanceof Statement) { + $inner = $this->formatPhp('?', [$entity[0]]); + if (substr($inner, 0, 4) === 'new ') { + $inner = "($inner)"; + } + return $this->formatPhp("$inner->?(...?)", [$entity[1], $arguments]); + + } elseif ($entity[1][0] === '$') { // property getter, setter or appender + $name = substr($entity[1], 1); + if ($append = (substr($name, -2) === '[]')) { + $name = substr($name, 0, -2); + } + if ($this->builder->getServiceName($entity[0])) { + $prop = $this->formatPhp('?->?', [$entity[0], $name]); + } else { + $prop = $this->formatPhp($entity[0] . '::$?', [$name]); + } + return $arguments + ? $this->formatPhp($prop . ($append ? '[]' : '') . ' = ?', [$arguments[0]]) + : $prop; + + } elseif ($service = $this->builder->getServiceName($entity[0])) { // service method + return $this->formatPhp('?->?(...?)', [$entity[0], $entity[1], $arguments]); + + } else { // static method + return $this->formatPhp("$entity[0]::$entity[1](...?)", [$arguments]); + } + } + + + /** + * Formats PHP statement. + * @return string + * @internal + */ + public function formatPhp($statement, $args) + { + array_walk_recursive($args, function (&$val) { + if ($val instanceof Statement) { + $val = new PhpLiteral($this->formatStatement($val)); + + } elseif (is_string($val) && substr($val, 0, 2) === '@@') { // escaped text @@ + $val = substr($val, 1); + + } elseif (is_string($val) && substr($val, 0, 1) === '@' && strlen($val) > 1) { // service reference + $name = substr($val, 1); + if ($name === ContainerBuilder::THIS_CONTAINER) { + $val = new PhpLiteral('$this'); + } elseif ($name === $this->currentService) { + $val = new PhpLiteral('$service'); + } else { + $val = new PhpLiteral($this->formatStatement(new Statement(['@' . ContainerBuilder::THIS_CONTAINER, 'getService'], [$name]))); + } + } + }); + return PhpHelpers::formatArgs($statement, $args); + } + + + /** + * Converts parameters from ServiceDefinition to PhpGenerator. + * @return Nette\PhpGenerator\Parameter[] + */ + private function convertParameters(array $parameters) + { + $res = []; + foreach ($parameters as $k => $v) { + $tmp = explode(' ', is_int($k) ? $v : $k); + $param = $res[] = new Nette\PhpGenerator\Parameter(end($tmp)); + if (!is_int($k)) { + @$param->setOptional(true); // @ deprecated in nette/php-generator 3.1 + $param->setDefaultValue($v); + } + if (isset($tmp[1])) { + $param->setTypeHint($tmp[0]); + } + } + return $res; + } +} diff --git a/vendor/nette/di/src/DI/PhpReflection.php b/vendor/nette/di/src/DI/PhpReflection.php new file mode 100644 index 00000000..207d7020 --- /dev/null +++ b/vendor/nette/di/src/DI/PhpReflection.php @@ -0,0 +1,273 @@ +getDocComment()) { + throw new Nette\InvalidStateException('You have to enable phpDoc comments in opcode cache.'); + } + $ok = true; + } + $name = preg_quote($name, '#'); + if ($ref->getDocComment() && preg_match("#[\\s*]@$name(?:\\s++([^@]\\S*)?|$)#", trim($ref->getDocComment(), '/*'), $m)) { + return isset($m[1]) ? $m[1] : ''; + } + } + + + /** + * Returns declaring class or trait. + * @return \ReflectionClass + */ + public static function getDeclaringClass(\ReflectionProperty $prop) + { + foreach ($prop->getDeclaringClass()->getTraits() as $trait) { + if ($trait->hasProperty($prop->getName())) { + return self::getDeclaringClass($trait->getProperty($prop->getName())); + } + } + return $prop->getDeclaringClass(); + } + + + /** + * @return string|null + */ + public static function getParameterType(\ReflectionParameter $param) + { + if (PHP_VERSION_ID >= 70000) { + $type = $param->hasType() ? (string) $param->getType() : null; + return strtolower($type) === 'self' ? $param->getDeclaringClass()->getName() : $type; + } elseif ($param->isArray() || $param->isCallable()) { + return $param->isArray() ? 'array' : 'callable'; + } else { + try { + return ($ref = $param->getClass()) ? $ref->getName() : null; + } catch (\ReflectionException $e) { + if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) { + return $m[1]; + } + throw $e; + } + } + } + + + /** + * @return string|null + */ + public static function getReturnType(\ReflectionFunctionAbstract $func) + { + if (PHP_VERSION_ID >= 70000 && $func->hasReturnType()) { + $type = (string) $func->getReturnType(); + return strtolower($type) === 'self' ? $func->getDeclaringClass()->getName() : $type; + } + $type = preg_replace('#[|\s].*#', '', (string) self::parseAnnotation($func, 'return')); + if ($type) { + return $func instanceof \ReflectionMethod + ? self::expandClassName($type, $func->getDeclaringClass()) + : ltrim($type, '\\'); + } + } + + + /** + * @param string + * @return bool + */ + public static function isBuiltinType($type) + { + return in_array(strtolower($type), ['string', 'int', 'float', 'bool', 'array', 'callable'], true); + } + + + /** + * Returns class and all its descendants. + * @return string[] + */ + public static function getClassTree(\ReflectionClass $class) + { + $addTraits = function ($types) use (&$addTraits) { + if ($traits = array_merge(...array_map('class_uses', array_values($types)))) { + $types += $traits + $addTraits($traits); + } + return $types; + }; + $class = $class->getName(); + return array_values($addTraits([$class] + class_parents($class) + class_implements($class))); + } + + + /** + * Expands class name into full name. + * @param string + * @return string full name + * @throws Nette\InvalidArgumentException + */ + public static function expandClassName($name, \ReflectionClass $rc) + { + $lower = strtolower($name); + if (empty($name)) { + throw new Nette\InvalidArgumentException('Class name must not be empty.'); + + } elseif (self::isBuiltinType($lower)) { + return $lower; + + } elseif ($lower === 'self' || $lower === 'static' || $lower === '$this') { + return $rc->getName(); + + } elseif ($name[0] === '\\') { // fully qualified name + return ltrim($name, '\\'); + } + + $uses = self::getUseStatements($rc); + $parts = explode('\\', $name, 2); + if (isset($uses[$parts[0]])) { + $parts[0] = $uses[$parts[0]]; + return implode('\\', $parts); + + } elseif ($rc->inNamespace()) { + return $rc->getNamespaceName() . '\\' . $name; + + } else { + return $name; + } + } + + + /** + * @return array of [alias => class] + */ + public static function getUseStatements(\ReflectionClass $class) + { + static $cache = []; + if (!isset($cache[$name = $class->getName()])) { + if ($class->isInternal()) { + $cache[$name] = []; + } else { + $code = file_get_contents($class->getFileName()); + $cache = self::parseUseStatements($code, $name) + $cache; + } + } + return $cache[$name]; + } + + + /** + * Parses PHP code. + * @param string + * @return array of [class => [alias => class, ...]] + */ + public static function parseUseStatements($code, $forClass = null) + { + $tokens = token_get_all($code); + $namespace = $class = $classLevel = $level = null; + $res = $uses = []; + + while ($token = current($tokens)) { + next($tokens); + switch (is_array($token) ? $token[0] : $token) { + case T_NAMESPACE: + $namespace = ltrim(self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]) . '\\', '\\'); + $uses = []; + break; + + case T_CLASS: + case T_INTERFACE: + case T_TRAIT: + if ($name = self::fetch($tokens, T_STRING)) { + $class = $namespace . $name; + $classLevel = $level + 1; + $res[$class] = $uses; + if ($class === $forClass) { + return $res; + } + } + break; + + case T_USE: + while (!$class && ($name = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]))) { + $name = ltrim($name, '\\'); + if (self::fetch($tokens, '{')) { + while ($suffix = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR])) { + if (self::fetch($tokens, T_AS)) { + $uses[self::fetch($tokens, T_STRING)] = $name . $suffix; + } else { + $tmp = explode('\\', $suffix); + $uses[end($tmp)] = $name . $suffix; + } + if (!self::fetch($tokens, ',')) { + break; + } + } + + } elseif (self::fetch($tokens, T_AS)) { + $uses[self::fetch($tokens, T_STRING)] = $name; + + } else { + $tmp = explode('\\', $name); + $uses[end($tmp)] = $name; + } + if (!self::fetch($tokens, ',')) { + break; + } + } + break; + + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': + $level++; + break; + + case '}': + if ($level === $classLevel) { + $class = $classLevel = null; + } + $level--; + } + } + + return $res; + } + + + private static function fetch(&$tokens, $take) + { + $res = null; + while ($token = current($tokens)) { + list($token, $s) = is_array($token) ? $token : [$token, $token]; + if (in_array($token, (array) $take, true)) { + $res .= $s; + } elseif (!in_array($token, [T_DOC_COMMENT, T_WHITESPACE, T_COMMENT], true)) { + break; + } + next($tokens); + } + return $res; + } +} diff --git a/vendor/nette/di/src/DI/ServiceDefinition.php b/vendor/nette/di/src/DI/ServiceDefinition.php new file mode 100644 index 00000000..2cc1869a --- /dev/null +++ b/vendor/nette/di/src/DI/ServiceDefinition.php @@ -0,0 +1,381 @@ +notifier); + $this->type = $type; + if ($args) { + $this->setFactory($type, $args); + } + return $this; + } + + + /** + * @return string|null + * @deprecated Use getType() instead. + */ + public function getClass() + { + return $this->type; + } + + + /** + * @param string|null + * @return static + */ + public function setType($type) + { + call_user_func($this->notifier); + $this->type = $type; + return $this; + } + + + /** + * @return string|null + */ + public function getType() + { + return $this->type; + } + + + /** + * @return static + */ + public function setFactory($factory, array $args = []) + { + call_user_func($this->notifier); + $this->factory = $factory instanceof Statement ? $factory : new Statement($factory, $args); + return $this; + } + + + /** + * @return Statement|null + */ + public function getFactory() + { + return $this->factory; + } + + + /** + * @return string|array|ServiceDefinition|null + */ + public function getEntity() + { + return $this->factory ? $this->factory->getEntity() : null; + } + + + /** + * @return static + */ + public function setArguments(array $args = []) + { + if (!$this->factory) { + $this->factory = new Statement($this->type); + } + $this->factory->arguments = $args; + return $this; + } + + + /** + * @param Statement[] + * @return static + */ + public function setSetup(array $setup) + { + foreach ($setup as $v) { + if (!$v instanceof Statement) { + throw new Nette\InvalidArgumentException('Argument must be Nette\DI\Statement[].'); + } + } + $this->setup = $setup; + return $this; + } + + + /** + * @return Statement[] + */ + public function getSetup() + { + return $this->setup; + } + + + /** + * @return static + */ + public function addSetup($entity, array $args = []) + { + $this->setup[] = $entity instanceof Statement ? $entity : new Statement($entity, $args); + return $this; + } + + + /** + * @return static + */ + public function setParameters(array $params) + { + $this->parameters = $params; + return $this; + } + + + /** + * @return array + */ + public function getParameters() + { + return $this->parameters; + } + + + /** + * @return static + */ + public function setTags(array $tags) + { + $this->tags = $tags; + return $this; + } + + + /** + * @return array + */ + public function getTags() + { + return $this->tags; + } + + + /** + * @return static + */ + public function addTag($tag, $attr = true) + { + $this->tags[$tag] = $attr; + return $this; + } + + + /** + * @return mixed + */ + public function getTag($tag) + { + return isset($this->tags[$tag]) ? $this->tags[$tag] : null; + } + + + /** + * @param bool|string|string[] + * @return static + */ + public function setAutowired($state = true) + { + call_user_func($this->notifier); + $this->autowired = is_string($state) || is_array($state) ? (array) $state : (bool) $state; + return $this; + } + + + /** + * @return bool|string[] + */ + public function isAutowired() + { + return $this->autowired; + } + + + /** + * @return bool|string[] + */ + public function getAutowired() + { + return $this->autowired; + } + + + /** + * @param bool + * @return static + */ + public function setDynamic($state = true) + { + $this->dynamic = (bool) $state; + return $this; + } + + + /** + * @return bool + */ + public function isDynamic() + { + return $this->dynamic; + } + + + /** + * @param string + * @return static + */ + public function setImplement($interface) + { + call_user_func($this->notifier); + $this->implement = $interface; + return $this; + } + + + /** + * @return string|null + */ + public function getImplement() + { + return $this->implement; + } + + + /** + * @param string + * @return static + */ + public function setImplementMode($mode) + { + if (!in_array($mode, [self::IMPLEMENT_MODE_CREATE, self::IMPLEMENT_MODE_GET], true)) { + throw new Nette\InvalidArgumentException('Argument must be get|create.'); + } + $this->implementMode = $mode; + return $this; + } + + + /** + * @return string|null + */ + public function getImplementMode() + { + return $this->implementMode; + } + + + /** @deprecated */ + public function setImplementType($type) + { + trigger_error(__METHOD__ . '() is deprecated, use setImplementMode()', E_USER_DEPRECATED); + return $this->setImplementMode($type); + } + + + /** @deprecated */ + public function getImplementType() + { + trigger_error(__METHOD__ . '() is deprecated, use getImplementMode()', E_USER_DEPRECATED); + return $this->implementMode; + } + + + /** @return static */ + public function setInject($state = true) + { + //trigger_error(__METHOD__ . '() is deprecated.', E_USER_DEPRECATED); + return $this->addTag(Extensions\InjectExtension::TAG_INJECT, $state); + } + + + /** @return bool|null */ + public function getInject() + { + //trigger_error(__METHOD__ . '() is deprecated.', E_USER_DEPRECATED); + return $this->getTag(Extensions\InjectExtension::TAG_INJECT); + } + + + /** + * @internal + */ + public function setNotifier(callable $notifier) + { + $this->notifier = $notifier; + } + + + public function __clone() + { + $this->factory = unserialize(serialize($this->factory)); + $this->setup = unserialize(serialize($this->setup)); + $this->notifier = 'pi'; + } +} diff --git a/vendor/nette/di/src/DI/Statement.php b/vendor/nette/di/src/DI/Statement.php new file mode 100644 index 00000000..7ac6c3b8 --- /dev/null +++ b/vendor/nette/di/src/DI/Statement.php @@ -0,0 +1,60 @@ +entity = $entity; + $this->arguments = $arguments; + } + + + /** @deprecated */ + public function setEntity($entity) + { + trigger_error(__METHOD__ . ' is deprecated, change Statement object itself.', E_USER_DEPRECATED); + $this->__construct($entity, $this->arguments); + return $this; + } + + + public function getEntity() + { + return $this->entity; + } +} diff --git a/vendor/nette/di/src/DI/exceptions.php b/vendor/nette/di/src/DI/exceptions.php new file mode 100644 index 00000000..ecddc542 --- /dev/null +++ b/vendor/nette/di/src/DI/exceptions.php @@ -0,0 +1,31 @@ +message = $message; + return $this; + } +} diff --git a/vendor/nette/finder/composer.json b/vendor/nette/finder/composer.json new file mode 100644 index 00000000..86da82e7 --- /dev/null +++ b/vendor/nette/finder/composer.json @@ -0,0 +1,37 @@ +{ + "name": "nette/finder", + "description": "🔍 Nette Finder: find files and directories with an intuitive API.", + "keywords": ["nette", "filesystem", "iterator", "glob"], + "homepage": "https://nette.org", + "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "require": { + "php": ">=5.6.0", + "nette/utils": "~2.4" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "autoload": { + "classmap": ["src/"] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + } +} diff --git a/vendor/nette/finder/contributing.md b/vendor/nette/finder/contributing.md new file mode 100644 index 00000000..184152c0 --- /dev/null +++ b/vendor/nette/finder/contributing.md @@ -0,0 +1,33 @@ +How to contribute & use the issue tracker +========================================= + +Nette welcomes your contributions. There are several ways to help out: + +* Create an issue on GitHub, if you have found a bug +* Write test cases for open bug issues +* Write fixes for open bug/feature issues, preferably with test cases included +* Contribute to the [documentation](https://nette.org/en/writing) + +Issues +------ + +Please **do not use the issue tracker to ask questions**. We will be happy to help you +on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette). + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. + +**Feature requests** are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the project's developers of the merits of this feature. + +Contributing +------------ + +If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing). + +The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them. + +Please do not fix whitespace, format code, or make a purely cosmetic patch. + +Thanks! :heart: diff --git a/vendor/nette/finder/license.md b/vendor/nette/finder/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/nette/finder/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" 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. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/finder/readme.md b/vendor/nette/finder/readme.md new file mode 100644 index 00000000..87778d17 --- /dev/null +++ b/vendor/nette/finder/readme.md @@ -0,0 +1,168 @@ +Nette Finder: Files Searching +============================= + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/finder.svg)](https://packagist.org/packages/nette/finder) +[![Build Status](https://travis-ci.org/nette/finder.svg?branch=master)](https://travis-ci.org/nette/finder) +[![Coverage Status](https://coveralls.io/repos/github/nette/finder/badge.svg?branch=master)](https://coveralls.io/github/nette/finder?branch=master) +[![Latest Stable Version](https://poser.pugx.org/nette/finder/v/stable)](https://github.com/nette/finder/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/finder/blob/master/license.md) + +Class `Nette\Utils\Finder` makes browsing the directory structure really easy. + + +All examples assume the following class alias is defined: + +```php +use Nette\Utils\Finder; +``` + + +Searching for Files +------------------- + +How to find all `*.txt` files in `$dir` directory without recursing subdirectories? + +```php +foreach (Finder::findFiles('*.txt')->in($dir) as $key => $file) { + echo $key; // $key is a string containing absolute filename with path + echo $file; // $file is an instance of SplFileInfo +} +``` + +As a result, the finder returns instances of `SplFileInfo`. + +If the directory does not exist, an `UnexpectedValueException` is thrown. + +And what about searching for `*.txt` files in `$dir` including subdirectories? Instead of `in()`, use `from()`: + +```php +foreach (Finder::findFiles('*.txt')->from($dir) as $file) { + echo $file; +} +``` + +Search by more masks, even inside more directories within one iteration: + +```php +foreach (Finder::findFiles('*.txt', '*.php') + ->in($dir1, $dir2) as $file) { + ... +} +``` + +Parameters can also be arrays: + +```php +foreach (Finder::findFiles($masks)->in($dirs) as $file) { + ... +} +``` + +Searching for `*.txt` files containing a number in the name: + +```php +foreach (Finder::findFiles('*[0-9]*.txt')->from($dir) as $file) { + ... +} +``` + +Searching for `*.txt` files, except those containing '`X`' in the name: + +```php +foreach (Finder::findFiles('*.txt') + ->exclude('*X*')->from($dir) as $file) { + ... +} +``` + +`exclude()` is specified just after `findFiles()`, thus it applies to filename. + + +Directories to omit can be specified using the `exclude` **after** `from` clause: + +```php +foreach (Finder::findFiles('*.php') + ->from($dir)->exclude('temp', '.git') as $file) { + ... +} +``` + +Here `exclude()` is after `from()`, thus it applies to the directory name. + + +And now something a bit more complicated: searching for `*.txt` files located in subdirectories starting with '`te`', but not '`temp`': + +```php +foreach (Finder::findFiles('te*/*.txt') + ->exclude('temp*/*')->from($dir) as $file) { + ... +} +``` + +Depth of search can be limited using the `limitDepth()` method. + + + +Searching for directories +---------------- + +In addition to files, it is possible to search for directories using `Finder::findDirectories('subdir*')`, or to search for files and directories: `Finder::find('file.txt')`. + + +Filtering +---------- + +You can also filter results. For example by size. This way we will traverse the files of size between 100B and 200B: + + +```php +foreach (Finder::findFiles('*.php')->size('>=', 100)->size('<=', 200) + ->from($dir) as $file) { + ... +} +``` + +Or files changed in the last two weeks: + +```php +foreach (Finder::findFiles('*.php')->date('>', '- 2 weeks') + ->from($dir) as $file) { + ... +} +``` + +Here we traverse PHP files with number of lines greater than 1000. As a filter we use a custom callback: + +```php +$finder = Finder::findFiles('*.php')->filter(function($file) { + return count(file($file->getPathname())) > 1000; +})->from($dir); +``` + + +Finder, find images larger than 50px × 50px: + +```php +foreach (Finder::findFiles('*') + ->dimensions('>50', '>50')->from($dir) as $file) { + ... +} +``` + + +Connection to Amazon S3 +---------------------- + +It's possible to use custom streams, for example Zend_Service_Amazon_S3: + +```php +$s3 = new Zend_Service_Amazon_S3($key, $secret); +$s3->registerStreamWrapper('s3'); + +foreach (Finder::findFiles('photos*') + ->size('<=', 1e6)->in('s3://bucket-name') as $file) { + echo $file; +} +``` + +Handy, right? You will certainly find a use for Finder in your applications. diff --git a/vendor/nette/finder/src/Utils/Finder.php b/vendor/nette/finder/src/Utils/Finder.php new file mode 100644 index 00000000..f9d2145f --- /dev/null +++ b/vendor/nette/finder/src/Utils/Finder.php @@ -0,0 +1,393 @@ + + * Finder::findFiles('*.php') + * ->size('> 10kB') + * ->from('.') + * ->exclude('temp'); + * + */ +class Finder implements \IteratorAggregate, \Countable +{ + use Nette\SmartObject; + + /** @var array */ + private $paths = []; + + /** @var array of filters */ + private $groups = []; + + /** @var array filter for recursive traversing */ + private $exclude = []; + + /** @var int */ + private $order = RecursiveIteratorIterator::SELF_FIRST; + + /** @var int */ + private $maxDepth = -1; + + /** @var array */ + private $cursor; + + + /** + * Begins search for files matching mask and all directories. + * @param mixed + * @return static + */ + public static function find(...$masks) + { + $masks = $masks && is_array($masks[0]) ? $masks[0] : $masks; + return (new static)->select($masks, 'isDir')->select($masks, 'isFile'); + } + + + /** + * Begins search for files matching mask. + * @param mixed + * @return static + */ + public static function findFiles(...$masks) + { + $masks = $masks && is_array($masks[0]) ? $masks[0] : $masks; + return (new static)->select($masks, 'isFile'); + } + + + /** + * Begins search for directories matching mask. + * @param mixed + * @return static + */ + public static function findDirectories(...$masks) + { + $masks = $masks && is_array($masks[0]) ? $masks[0] : $masks; + return (new static)->select($masks, 'isDir'); + } + + + /** + * Creates filtering group by mask & type selector. + * @param array + * @param string + * @return static + */ + private function select($masks, $type) + { + $this->cursor = &$this->groups[]; + $pattern = self::buildPattern($masks); + if ($type || $pattern) { + $this->filter(function (RecursiveDirectoryIterator $file) use ($type, $pattern) { + return !$file->isDot() + && (!$type || $file->$type()) + && (!$pattern || preg_match($pattern, '/' . strtr($file->getSubPathName(), '\\', '/'))); + }); + } + return $this; + } + + + /** + * Searchs in the given folder(s). + * @param string|array + * @return static + */ + public function in(...$paths) + { + $this->maxDepth = 0; + return $this->from(...$paths); + } + + + /** + * Searchs recursively from the given folder(s). + * @param string|array + * @return static + */ + public function from(...$paths) + { + if ($this->paths) { + throw new Nette\InvalidStateException('Directory to search has already been specified.'); + } + $this->paths = is_array($paths[0]) ? $paths[0] : $paths; + $this->cursor = &$this->exclude; + return $this; + } + + + /** + * Shows folder content prior to the folder. + * @return static + */ + public function childFirst() + { + $this->order = RecursiveIteratorIterator::CHILD_FIRST; + return $this; + } + + + /** + * Converts Finder pattern to regular expression. + * @param array + * @return string|null + */ + private static function buildPattern($masks) + { + $pattern = []; + foreach ($masks as $mask) { + $mask = rtrim(strtr($mask, '\\', '/'), '/'); + $prefix = ''; + if ($mask === '') { + continue; + + } elseif ($mask === '*') { + return null; + + } elseif ($mask[0] === '/') { // absolute fixing + $mask = ltrim($mask, '/'); + $prefix = '(?<=^/)'; + } + $pattern[] = $prefix . strtr(preg_quote($mask, '#'), + ['\*\*' => '.*', '\*' => '[^/]*', '\?' => '[^/]', '\[\!' => '[^', '\[' => '[', '\]' => ']', '\-' => '-']); + } + return $pattern ? '#/(' . implode('|', $pattern) . ')\z#i' : null; + } + + + /********************* iterator generator ****************d*g**/ + + + /** + * Get the number of found files and/or directories. + * @return int + */ + public function count() + { + return iterator_count($this->getIterator()); + } + + + /** + * Returns iterator. + * @return \Iterator + */ + public function getIterator() + { + if (!$this->paths) { + throw new Nette\InvalidStateException('Call in() or from() to specify directory to search.'); + + } elseif (count($this->paths) === 1) { + return $this->buildIterator($this->paths[0]); + + } else { + $iterator = new \AppendIterator(); + $iterator->append($workaround = new \ArrayIterator(['workaround PHP bugs #49104, #63077'])); + foreach ($this->paths as $path) { + $iterator->append($this->buildIterator($path)); + } + unset($workaround[0]); + return $iterator; + } + } + + + /** + * Returns per-path iterator. + * @param string + * @return \Iterator + */ + private function buildIterator($path) + { + $iterator = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::FOLLOW_SYMLINKS); + + if ($this->exclude) { + $iterator = new \RecursiveCallbackFilterIterator($iterator, function ($foo, $bar, RecursiveDirectoryIterator $file) { + if (!$file->isDot() && !$file->isFile()) { + foreach ($this->exclude as $filter) { + if (!call_user_func($filter, $file)) { + return false; + } + } + } + return true; + }); + } + + if ($this->maxDepth !== 0) { + $iterator = new RecursiveIteratorIterator($iterator, $this->order); + $iterator->setMaxDepth($this->maxDepth); + } + + $iterator = new \CallbackFilterIterator($iterator, function ($foo, $bar, \Iterator $file) { + while ($file instanceof \OuterIterator) { + $file = $file->getInnerIterator(); + } + + foreach ($this->groups as $filters) { + foreach ($filters as $filter) { + if (!call_user_func($filter, $file)) { + continue 2; + } + } + return true; + } + return false; + }); + + return $iterator; + } + + + /********************* filtering ****************d*g**/ + + + /** + * Restricts the search using mask. + * Excludes directories from recursive traversing. + * @param mixed + * @return static + */ + public function exclude(...$masks) + { + $masks = $masks && is_array($masks[0]) ? $masks[0] : $masks; + $pattern = self::buildPattern($masks); + if ($pattern) { + $this->filter(function (RecursiveDirectoryIterator $file) use ($pattern) { + return !preg_match($pattern, '/' . strtr($file->getSubPathName(), '\\', '/')); + }); + } + return $this; + } + + + /** + * Restricts the search using callback. + * @param callable function (RecursiveDirectoryIterator $file) + * @return static + */ + public function filter($callback) + { + $this->cursor[] = $callback; + return $this; + } + + + /** + * Limits recursion level. + * @param int + * @return static + */ + public function limitDepth($depth) + { + $this->maxDepth = $depth; + return $this; + } + + + /** + * Restricts the search by size. + * @param string "[operator] [size] [unit]" example: >=10kB + * @param int + * @return static + */ + public function size($operator, $size = null) + { + if (func_num_args() === 1) { // in $operator is predicate + if (!preg_match('#^(?:([=<>!]=?|<>)\s*)?((?:\d*\.)?\d+)\s*(K|M|G|)B?\z#i', $operator, $matches)) { + throw new Nette\InvalidArgumentException('Invalid size predicate format.'); + } + list(, $operator, $size, $unit) = $matches; + static $units = ['' => 1, 'k' => 1e3, 'm' => 1e6, 'g' => 1e9]; + $size *= $units[strtolower($unit)]; + $operator = $operator ?: '='; + } + return $this->filter(function (RecursiveDirectoryIterator $file) use ($operator, $size) { + return self::compare($file->getSize(), $operator, $size); + }); + } + + + /** + * Restricts the search by modified time. + * @param string "[operator] [date]" example: >1978-01-23 + * @param mixed + * @return static + */ + public function date($operator, $date = null) + { + if (func_num_args() === 1) { // in $operator is predicate + if (!preg_match('#^(?:([=<>!]=?|<>)\s*)?(.+)\z#i', $operator, $matches)) { + throw new Nette\InvalidArgumentException('Invalid date predicate format.'); + } + list(, $operator, $date) = $matches; + $operator = $operator ?: '='; + } + $date = DateTime::from($date)->format('U'); + return $this->filter(function (RecursiveDirectoryIterator $file) use ($operator, $date) { + return self::compare($file->getMTime(), $operator, $date); + }); + } + + + /** + * Compares two values. + * @param mixed + * @param mixed + * @return bool + */ + public static function compare($l, $operator, $r) + { + switch ($operator) { + case '>': + return $l > $r; + case '>=': + return $l >= $r; + case '<': + return $l < $r; + case '<=': + return $l <= $r; + case '=': + case '==': + return $l == $r; + case '!': + case '!=': + case '<>': + return $l != $r; + default: + throw new Nette\InvalidArgumentException("Unknown operator $operator."); + } + } + + + /********************* extension methods ****************d*g**/ + + + public function __call($name, $args) + { + if ($callback = Nette\Utils\ObjectMixin::getExtensionMethod(__CLASS__, $name)) { + return $callback($this, ...$args); + } + Nette\Utils\ObjectMixin::strictCall(__CLASS__, $name); + } + + + public static function extensionMethod($name, $callback) + { + Nette\Utils\ObjectMixin::setExtensionMethod(__CLASS__, $name, $callback); + } +} diff --git a/vendor/nette/neon/composer.json b/vendor/nette/neon/composer.json new file mode 100644 index 00000000..16fb77bb --- /dev/null +++ b/vendor/nette/neon/composer.json @@ -0,0 +1,35 @@ +{ + "name": "nette/neon", + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "keywords": ["nette", "neon", "import", "export", "yaml"], + "homepage": "http://ne-on.org", + "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "require": { + "php": ">=7.0", + "ext-iconv": "*", + "ext-json": "*" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "autoload": { + "classmap": ["src/"] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + } +} diff --git a/vendor/nette/neon/contributing.md b/vendor/nette/neon/contributing.md new file mode 100644 index 00000000..184152c0 --- /dev/null +++ b/vendor/nette/neon/contributing.md @@ -0,0 +1,33 @@ +How to contribute & use the issue tracker +========================================= + +Nette welcomes your contributions. There are several ways to help out: + +* Create an issue on GitHub, if you have found a bug +* Write test cases for open bug issues +* Write fixes for open bug/feature issues, preferably with test cases included +* Contribute to the [documentation](https://nette.org/en/writing) + +Issues +------ + +Please **do not use the issue tracker to ask questions**. We will be happy to help you +on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette). + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. + +**Feature requests** are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the project's developers of the merits of this feature. + +Contributing +------------ + +If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing). + +The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them. + +Please do not fix whitespace, format code, or make a purely cosmetic patch. + +Thanks! :heart: diff --git a/vendor/nette/neon/license.md b/vendor/nette/neon/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/nette/neon/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" 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. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/neon/readme.md b/vendor/nette/neon/readme.md new file mode 100644 index 00000000..78b7517b --- /dev/null +++ b/vendor/nette/neon/readme.md @@ -0,0 +1,96 @@ +[NEON](http://ne-on.org): Nette Object Notation +=============================================== + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/neon.svg)](https://packagist.org/packages/nette/neon) +[![Build Status](https://travis-ci.org/nette/neon.svg?branch=master)](https://travis-ci.org/nette/neon) +[![Coverage Status](https://coveralls.io/repos/github/nette/neon/badge.svg?branch=master)](https://coveralls.io/github/nette/neon?branch=master) +[![Latest Stable Version](https://poser.pugx.org/nette/neon/v/stable)](https://github.com/nette/neon/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/neon/blob/master/license.md) + + +Introduction +------------ + +NEON is a human-readable data serialization language. It is commonly used for configuration files, but could be used in many applications where data is being stored + +NEON is very similar to YAML.The main difference is that the NEON supports "entities" (so can be used e.g. to parse phpDoc annotations) and tab characters for indentation. +NEON syntax is a little simpler and the parsing is faster. + +Documentation can be found on the [website](https://doc.nette.org/neon). + +If you like Nette, **[please make a donation now](https://nette.org/donate)**. Thank you! + + +NEON language +------------- + +Try NEON [in sandbox](https://ne-on.org)! + +Example of NEON code: + +``` +# my web application config + +php: + date.timezone: Europe/Prague + zlib.output_compression: yes # use gzip + +database: + driver: mysql + username: root + password: beruska92 + +users: + - Dave + - Kryten + - Rimmer +``` + +Installation +------------ + +The recommended way to install is via Composer: + +``` +composer require nette/neon +``` + +It requires PHP version 5.6 and supports PHP up to 7.3. The dev-master version requires PHP 7.0. + + +Usage +----- + +`Nette\Neon\Neon` is a static class for encoding and decoding NEON files. + +`Neon::encode()` returns $value encoded into NEON. Flags accepts Neon::BLOCK which formats NEON in multiline format. + +```php +use Nette\Neon\Neon; +$neon = Neon::encode($value); // Returns $value encoded in NEON +$neon = Neon::encode($value, Neon::BLOCK); // Returns formatted $value encoded in NEON +``` + +`Neon::decode()` converts given NEON to PHP value: + +```php +$value = Neon::decode('hello: world'); // Returns an array ['hello' => 'world'] +``` + +Both methods throw `Nette\Neon\Exception` on error. + + +Editors plugins +--------------- + +- NetBeans IDE has built-in support +- [PhpStorm](https://plugins.jetbrains.com/plugin/7060?pr) +- [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=Kasik96.latte) +- [Emacs](https://github.com/Fuco1/neon-mode) + + +Other languages +--------------- + +- [Neon for Javascript](https://github.com/matej21/neon-js) +- [Neon for Python](https://github.com/paveldedik/neon-py) diff --git a/vendor/nette/neon/src/Neon/Decoder.php b/vendor/nette/neon/src/Neon/Decoder.php new file mode 100644 index 00000000..007b547b --- /dev/null +++ b/vendor/nette/neon/src/Neon/Decoder.php @@ -0,0 +1,358 @@ + 'TRUE', 'True' => 'TRUE', 'TRUE' => 'TRUE', 'yes' => 'TRUE', 'Yes' => 'TRUE', 'YES' => 'TRUE', 'on' => 'TRUE', 'On' => 'TRUE', 'ON' => 'TRUE', + 'false' => 'FALSE', 'False' => 'FALSE', 'FALSE' => 'FALSE', 'no' => 'FALSE', 'No' => 'FALSE', 'NO' => 'FALSE', 'off' => 'FALSE', 'Off' => 'FALSE', 'OFF' => 'FALSE', + 'null' => 'NULL', 'Null' => 'NULL', 'NULL' => 'NULL', + ]; + + const ESCAPE_SEQUENCES = [ + 't' => "\t", 'n' => "\n", 'r' => "\r", 'f' => "\x0C", 'b' => "\x08", '"' => '"', '\\' => '\\', '/' => '/', '_' => "\u{A0}", + ]; + + const BRACKETS = [ + '[' => ']', + '{' => '}', + '(' => ')', + ]; + + /** @var string */ + private $input; + + /** @var array */ + private $tokens; + + /** @var int */ + private $pos; + + + /** + * Decodes a NEON string. + * @return mixed + */ + public function decode(string $input) + { + if (!is_string($input)) { + throw new \InvalidArgumentException(sprintf('Argument must be a string, %s given.', gettype($input))); + + } elseif (substr($input, 0, 3) === "\u{FEFF}") { // BOM + $input = substr($input, 3); + } + $this->input = "\n" . str_replace("\r", '', $input); // \n forces indent detection + + $pattern = '~(' . implode(')|(', self::PATTERNS) . ')~Amix'; + $this->tokens = preg_split($pattern, $this->input, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_DELIM_CAPTURE); + + $last = end($this->tokens); + if ($this->tokens && !preg_match($pattern, $last[0])) { + $this->pos = count($this->tokens) - 1; + $this->error(); + } + + $this->pos = 0; + $res = $this->parse(null); + + while (isset($this->tokens[$this->pos])) { + if ($this->tokens[$this->pos][0][0] === "\n") { + $this->pos++; + } else { + $this->error(); + } + } + return $res; + } + + + /** + * @param string|bool|null $indent indentation (for block-parser) + * @return mixed + */ + private function parse($indent, array $result = null, $key = null, bool $hasKey = false) + { + $inlineParser = $indent === false; + $value = null; + $hasValue = false; + $tokens = $this->tokens; + $n = &$this->pos; + $count = count($tokens); + $mainResult = &$result; + + for (; $n < $count; $n++) { + $t = $tokens[$n][0]; + + if ($t === ',') { // ArrayEntry separator + if ((!$hasKey && !$hasValue) || !$inlineParser) { + $this->error(); + } + $this->addValue($result, $hasKey ? $key : null, $hasValue ? $value : null); + $hasKey = $hasValue = false; + + } elseif ($t === ':' || $t === '=') { // KeyValuePair separator + if ($hasValue && (is_array($value) || is_object($value))) { + $this->error('Unacceptable key'); + + } elseif ($hasKey && $key === null && $hasValue && !$inlineParser) { + $n++; + $result[] = $this->parse($indent . ' ', [], $value, true); + $newIndent = isset($tokens[$n], $tokens[$n + 1]) ? (string) substr($tokens[$n][0], 1) : ''; // not last + if (strlen($newIndent) > strlen($indent)) { + $n++; + $this->error('Bad indentation'); + } elseif (strlen($newIndent) < strlen($indent)) { + return $mainResult; // block parser exit point + } + $hasKey = $hasValue = false; + + } elseif ($hasKey || !$hasValue) { + $this->error(); + + } else { + $key = (string) $value; + $hasKey = true; + $hasValue = false; + $result = &$mainResult; + } + + } elseif ($t === '-') { // BlockArray bullet + if ($hasKey || $hasValue || $inlineParser) { + $this->error(); + } + $key = null; + $hasKey = true; + + } elseif (isset(self::BRACKETS[$t])) { // Opening bracket [ ( { + if ($hasValue) { + if ($t !== '(') { + $this->error(); + } + $n++; + if ($value instanceof Entity && $value->value === Neon::CHAIN) { + end($value->attributes)->attributes = $this->parse(false, []); + } else { + $value = new Entity($value, $this->parse(false, [])); + } + } else { + $n++; + $value = $this->parse(false, []); + } + $hasValue = true; + if (!isset($tokens[$n]) || $tokens[$n][0] !== self::BRACKETS[$t]) { // unexpected type of bracket or block-parser + $this->error(); + } + + } elseif ($t === ']' || $t === '}' || $t === ')') { // Closing bracket ] ) } + if (!$inlineParser) { + $this->error(); + } + break; + + } elseif ($t[0] === "\n") { // Indent + if ($inlineParser) { + if ($hasKey || $hasValue) { + $this->addValue($result, $hasKey ? $key : null, $hasValue ? $value : null); + $hasKey = $hasValue = false; + } + + } else { + while (isset($tokens[$n + 1]) && $tokens[$n + 1][0][0] === "\n") { + $n++; // skip to last indent + } + if (!isset($tokens[$n + 1])) { + break; + } + + $newIndent = (string) substr($tokens[$n][0], 1); + if ($indent === null) { // first iteration + $indent = $newIndent; + } + $minlen = min(strlen($newIndent), strlen($indent)); + if ($minlen && (string) substr($newIndent, 0, $minlen) !== (string) substr($indent, 0, $minlen)) { + $n++; + $this->error('Invalid combination of tabs and spaces'); + } + + if (strlen($newIndent) > strlen($indent)) { // open new block-array or hash + if ($hasValue || !$hasKey) { + $n++; + $this->error('Bad indentation'); + } + $this->addValue($result, $key, $this->parse($newIndent)); + $newIndent = isset($tokens[$n], $tokens[$n + 1]) ? (string) substr($tokens[$n][0], 1) : ''; // not last + if (strlen($newIndent) > strlen($indent)) { + $n++; + $this->error('Bad indentation'); + } + $hasKey = false; + + } else { + if ($hasValue && !$hasKey) { // block items must have "key"; null key means list item + break; + + } elseif ($hasKey) { + $this->addValue($result, $key, $hasValue ? $value : null); + if ($key !== null && !$hasValue && $newIndent === $indent && isset($tokens[$n + 1]) && $tokens[$n + 1][0] === '-') { + $result = &$result[$key]; + } + $hasKey = $hasValue = false; + } + } + + if (strlen($newIndent) < strlen($indent)) { // close block + return $mainResult; // block parser exit point + } + } + + } else { // Value + if ($t[0] === '"' || $t[0] === "'") { + if (preg_match('#^...\n++([\t ]*+)#', $t, $m)) { + $converted = substr($t, 3, -3); + $converted = str_replace("\n" . $m[1], "\n", $converted); + $converted = preg_replace('#^\n|\n[\t ]*+\z#', '', $converted); + } else { + $converted = substr($t, 1, -1); + } + if ($t[0] === '"') { + $converted = preg_replace_callback('#\\\\(?:ud[89ab][0-9a-f]{2}\\\\ud[c-f][0-9a-f]{2}|u[0-9a-f]{4}|x[0-9a-f]{2}|.)#i', [$this, 'cbString'], $converted); + } + } elseif (($fix56 = self::SIMPLE_TYPES) && isset($fix56[$t]) && (!isset($tokens[$n + 1][0]) || ($tokens[$n + 1][0] !== ':' && $tokens[$n + 1][0] !== '='))) { + $converted = constant(self::SIMPLE_TYPES[$t]); + } elseif (is_numeric($t)) { + $converted = $t * 1; + } elseif (preg_match(self::PATTERN_HEX, $t)) { + $converted = hexdec($t); + } elseif (preg_match(self::PATTERN_OCTAL, $t)) { + $converted = octdec($t); + } elseif (preg_match(self::PATTERN_BINARY, $t)) { + $converted = bindec($t); + } elseif (preg_match(self::PATTERN_DATETIME, $t)) { + $converted = new \DateTimeImmutable($t); + } else { // literal + $converted = $t; + } + if ($hasValue) { + if ($value instanceof Entity) { // Entity chaining + if ($value->value !== Neon::CHAIN) { + $value = new Entity(Neon::CHAIN, [$value]); + } + $value->attributes[] = new Entity($converted); + } else { + $this->error(); + } + } else { + $value = $converted; + $hasValue = true; + } + } + } + + if ($inlineParser) { + if ($hasKey || $hasValue) { + $this->addValue($result, $hasKey ? $key : null, $hasValue ? $value : null); + } + } else { + if ($hasValue && !$hasKey) { // block items must have "key" + if ($result === null) { + $result = $value; // simple value parser + } else { + $this->error(); + } + } elseif ($hasKey) { + $this->addValue($result, $key, $hasValue ? $value : null); + } + } + return $mainResult; + } + + + private function addValue(&$result, $key, $value) + { + if ($key === null) { + $result[] = $value; + } elseif ($result && array_key_exists($key, $result)) { + $this->error("Duplicated key '$key'"); + } else { + $result[$key] = $value; + } + } + + + private function cbString(array $m): string + { + $sq = $m[0]; + if (($fix56 = self::ESCAPE_SEQUENCES) && isset($fix56[$sq[1]])) { // workaround for PHP 5.6 + return self::ESCAPE_SEQUENCES[$sq[1]]; + } elseif ($sq[1] === 'u' && strlen($sq) >= 6) { + $lead = hexdec(substr($sq, 2, 4)); + $tail = hexdec(substr($sq, 8, 4)); + $code = $tail ? (0x2400 + (($lead - 0xD800) << 10) + $tail) : $lead; + if ($code >= 0xD800 && $code <= 0xDFFF) { + $this->error("Invalid UTF-8 (lone surrogate) $sq"); + } + return iconv('UTF-32BE', 'UTF-8//IGNORE', pack('N', $code)); + } elseif ($sq[1] === 'x' && strlen($sq) === 4) { + return chr(hexdec(substr($sq, 2))); + } else { + $this->error("Invalid escaping sequence $sq"); + return ''; + } + } + + + private function error(string $message = "Unexpected '%s'") + { + $last = isset($this->tokens[$this->pos]) ? $this->tokens[$this->pos] : null; + $offset = $last ? $last[1] : strlen($this->input); + $text = substr($this->input, 0, $offset); + $line = substr_count($text, "\n"); + $col = $offset - strrpos("\n" . $text, "\n") + 1; + $token = $last ? str_replace("\n", '', substr($last[0], 0, 40)) : 'end'; + throw new Exception(str_replace('%s', $token, $message) . " on line $line, column $col."); + } +} diff --git a/vendor/nette/neon/src/Neon/Encoder.php b/vendor/nette/neon/src/Neon/Encoder.php new file mode 100644 index 00000000..29a1c092 --- /dev/null +++ b/vendor/nette/neon/src/Neon/Encoder.php @@ -0,0 +1,84 @@ +format('Y-m-d H:i:s O'); + + } elseif ($var instanceof Entity) { + if ($var->value === Neon::CHAIN) { + return implode('', array_map([$this, 'encode'], $var->attributes)); + } + return $this->encode($var->value) . '(' + . (is_array($var->attributes) ? substr($this->encode($var->attributes), 1, -1) : '') . ')'; + } + + if (is_object($var)) { + $obj = $var; + $var = []; + foreach ($obj as $k => $v) { + $var[$k] = $v; + } + } + + if (is_array($var)) { + $isList = !$var || array_keys($var) === range(0, count($var) - 1); + $s = ''; + if ($flags & self::BLOCK) { + if (count($var) === 0) { + return '[]'; + } + foreach ($var as $k => $v) { + $v = $this->encode($v, self::BLOCK); + $s .= ($isList ? '-' : $this->encode($k) . ':') + . (strpos($v, "\n") === false + ? ' ' . $v . "\n" + : "\n" . preg_replace('#^(?=.)#m', "\t", $v) . (substr($v, -2, 1) === "\n" ? '' : "\n")); + } + return $s; + + } else { + foreach ($var as $k => $v) { + $s .= ($isList ? '' : $this->encode($k) . ': ') . $this->encode($v) . ', '; + } + return ($isList ? '[' : '{') . substr($s, 0, -2) . ($isList ? ']' : '}'); + } + + } elseif ( + is_string($var) + && !is_numeric($var) + && !preg_match('~[\x00-\x1F]|^\d{4}|^(true|false|yes|no|on|off|null)\z~i', $var) + && preg_match('~^' . Decoder::PATTERNS[1] . '\z~x', $var) // 1 = literals + ) { + return $var; + + } elseif (is_float($var)) { + $var = json_encode($var); + return strpos($var, '.') === false ? $var . '.0' : $var; + + } else { + return json_encode($var, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + } +} diff --git a/vendor/nette/neon/src/Neon/Entity.php b/vendor/nette/neon/src/Neon/Entity.php new file mode 100644 index 00000000..e7ee95a2 --- /dev/null +++ b/vendor/nette/neon/src/Neon/Entity.php @@ -0,0 +1,36 @@ +value = $value; + $this->attributes = $attrs; + } + + + public static function __set_state(array $properties) + { + return new self($properties['value'], $properties['attributes']); + } +} diff --git a/vendor/nette/neon/src/Neon/Exception.php b/vendor/nette/neon/src/Neon/Exception.php new file mode 100644 index 00000000..0a37ad99 --- /dev/null +++ b/vendor/nette/neon/src/Neon/Exception.php @@ -0,0 +1,18 @@ +encode($var, $flags); + } + + + /** + * Decodes a NEON string. + * @return mixed + */ + public static function decode(string $input) + { + $decoder = new Decoder; + return $decoder->decode($input); + } +} diff --git a/vendor/nette/neon/src/neon.php b/vendor/nette/neon/src/neon.php new file mode 100644 index 00000000..96c56d93 --- /dev/null +++ b/vendor/nette/neon/src/neon.php @@ -0,0 +1,9 @@ +=7.1", + "nette/utils": "^2.4.2 || ~3.0.0" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "autoload": { + "classmap": ["src/"] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + } +} diff --git a/vendor/nette/php-generator/contributing.md b/vendor/nette/php-generator/contributing.md new file mode 100644 index 00000000..184152c0 --- /dev/null +++ b/vendor/nette/php-generator/contributing.md @@ -0,0 +1,33 @@ +How to contribute & use the issue tracker +========================================= + +Nette welcomes your contributions. There are several ways to help out: + +* Create an issue on GitHub, if you have found a bug +* Write test cases for open bug issues +* Write fixes for open bug/feature issues, preferably with test cases included +* Contribute to the [documentation](https://nette.org/en/writing) + +Issues +------ + +Please **do not use the issue tracker to ask questions**. We will be happy to help you +on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette). + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. + +**Feature requests** are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the project's developers of the merits of this feature. + +Contributing +------------ + +If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing). + +The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them. + +Please do not fix whitespace, format code, or make a purely cosmetic patch. + +Thanks! :heart: diff --git a/vendor/nette/php-generator/license.md b/vendor/nette/php-generator/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/nette/php-generator/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" 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. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/php-generator/readme.md b/vendor/nette/php-generator/readme.md new file mode 100644 index 00000000..3c4b8b0f --- /dev/null +++ b/vendor/nette/php-generator/readme.md @@ -0,0 +1,512 @@ +Nette PHP Generator +=================== + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/php-generator.svg)](https://packagist.org/packages/nette/php-generator) +[![Build Status](https://travis-ci.org/nette/php-generator.svg?branch=master)](https://travis-ci.org/nette/php-generator) +[![Coverage Status](https://coveralls.io/repos/github/nette/php-generator/badge.svg?branch=master&v=1)](https://coveralls.io/github/nette/php-generator?branch=master) +[![Latest Stable Version](https://poser.pugx.org/nette/php-generator/v/stable)](https://github.com/nette/php-generator/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/php-generator/blob/master/license.md) + + +Introduction +------------ + +Generate PHP code, classes, namespaces etc. with a simple programmatical API. + +Documentation can be found on the [website](https://doc.nette.org/php-generator). + +If you like Nette, **[please make a donation now](https://nette.org/donate)**. Thank you! + + +Installation +------------ + +The recommended way to install is via Composer: + +``` +composer require nette/php-generator +``` + +- v3.2 requires PHP 7.1 or newer (is compatible up to 7.3) +- v3.1 requires PHP 7.1 or newer (is compatible up to 7.3) +- v3.0 requires PHP 7.0 or newer (is compatible up to 7.3) +- v2.6 requires PHP 5.6 or newer (is compatible up to 7.3) + + +Usage +----- + +Usage is very easy. Let's start with a straightforward example of generating class: + +```php +$class = new Nette\PhpGenerator\ClassType('Demo'); + +$class + ->setFinal() + ->setExtends('ParentClass') + ->addImplement('Countable') + ->addTrait('Nette\SmartObject') + ->addComment("Description of class.\nSecond line\n") + ->addComment('@property-read Nette\Forms\Form $form'); + +// to generate PHP code simply cast to string or use echo: +echo $class; +``` + +It will render this result: + +```php +/** + * Description of class. + * Second line + * + * @property-read Nette\Forms\Form $form + */ +final class Demo extends ParentClass implements Countable +{ + use Nette\SmartObject; +} +``` + +We can add constants and properties: + +```php +$class->addConstant('ID', 123); + +$class->addProperty('items', [1, 2, 3]) + ->setVisibility('private') + ->setStatic() + ->addComment('@var int[]'); +``` + +It generates: + +```php + const ID = 123; + + /** @var int[] */ + private static $items = [1, 2, 3]; +``` + +And we can add methods with parameters: + +```php +$method = $class->addMethod('count') + ->addComment('Count it.') + ->addComment('@return int') + ->setFinal() + ->setVisibility('protected') + ->setBody('return count($items ?: $this->items);'); + +$method->addParameter('items', []) // $items = [] + ->setReference() // &$items = [] + ->setTypeHint('array'); // array &$items = [] +``` + +It results in: + +```php + /** + * Count it. + * @return int + */ + final protected function count(array &$items = []) + { + return count($items ?: $this->items); + } +``` + +If the property, constant, method or parameter already exist, it will be overwritten. + +Members can be removed using `removeProperty()`, `removeConstant()`, `removeMethod()` or `removeParameter()`. + +PHP Generator supports all new PHP 7.3 features: + +```php +$class = new Nette\PhpGenerator\ClassType('Demo'); + +$class->addConstant('ID', 123) + ->setVisibility('private'); // constant visiblity + +$method = $class->addMethod('getValue') + ->setReturnType('int') // method return type + ->setReturnNullable() // nullable return type + ->setBody('return count($this->items);'); + +$method->addParameter('id') + ->setTypeHint('int') // scalar type hint + ->setNullable(); // nullable type hint + +echo $class; +``` + +Result: + +```php +class Demo +{ + private const ID = 123; + + public function getValue(?int $id): ?int + { + return count($this->items); + } +} +``` + +You can also add existing `Method`, `Property` or `Constant` objects to the class: + +```php +$method = new Nette\PhpGenerator\Method('getHandle'); +$property = new Nette\PhpGenerator\Property('handle'); +$const = new Nette\PhpGenerator\Constant('ROLE'); + +$class = (new Nette\PhpGenerator\ClassType('Demo')) + ->addMember($method) + ->addMember($property) + ->addMember($const); +``` + +You can clone existing methods, properties and constants with a different name using `cloneWithName()`: + +```php +$methodCount = $class->getMethod('count'); +$methodRecount = $methodCount->cloneWithName('recount'); +$class->addMember($methodRecount); +``` + +Tabs versus spaces +------------------ + +The generated code uses tabs for indentation. If you want to have the output compatible with PSR-2 or PSR-12, use `PsrPrinter`: + +```php +$printer = new Nette\PhpGenerator\PsrPrinter; + +$class = new Nette\PhpGenerator\ClassType('Demo'); +// ... + +echo $printer->printClass($class); // 4 spaces indentation +``` + +It can be used also for functions, closures, namespaces etc. + + +Literals +-------- + +You can pass any PHP code to property or parameter default values via `PhpLiteral`: + +```php +use Nette\PhpGenerator\PhpLiteral; + +$class = new Nette\PhpGenerator\ClassType('Demo'); + +$class->addProperty('foo', new PhpLiteral('Iterator::SELF_FIRST')); + +$class->addMethod('bar') + ->addParameter('id', new PhpLiteral('1 + 2')); + +echo $class; +``` + +Result: + +```php +class Demo +{ + public $foo = Iterator::SELF_FIRST; + + public function bar($id = 1 + 2) + { + } +} +``` + +Interface or Trait +------------------ + +```php +$class = new Nette\PhpGenerator\ClassType('DemoInterface'); +$class->setType('interface'); +// or $class->setType('trait'); +``` + +Trait Resolutions and Visibility +-------------------------------- + +```php +$class = new Nette\PhpGenerator\ClassType('Demo'); +$class->addTrait('SmartObject', ['sayHello as protected']); +echo $class; +``` + +Result: + +```php +class Demo +{ + use SmartObject { + sayHello as protected; + } +} +``` + +Anonymous Class +--------------- + +```php +$class = new Nette\PhpGenerator\ClassType(null); +$class->addMethod('__construct') + ->addParameter('foo'); + +echo '$obj = new class ($val) ' . $class . ';'; +``` + +Result: + +```php +$obj = new class ($val) { + + public function __construct($foo) + { + } +}; +``` + +Global Function +--------------- + +Code of function: + +```php +$function = new Nette\PhpGenerator\GlobalFunction('foo'); +$function->setBody('return $a + $b;'); +$function->addParameter('a'); +$function->addParameter('b'); +echo $function; + +// or use PsrPrinter for output compatible with PSR-2 / PSR-12 +// echo (new Nette\PhpGenerator\PsrPrinter)->printFunction($function); +``` + +Result: + +```php +function foo($a, $b) +{ + return $a + $b; +} +``` + +Closure +------- + +Code of closure: + +```php +$closure = new Nette\PhpGenerator\Closure; +$closure->setBody('return $a + $b;'); +$closure->addParameter('a'); +$closure->addParameter('b'); +$closure->addUse('c') + ->setReference(); +echo $closure; + +// or use PsrPrinter for output compatible with PSR-2 / PSR-12 +// echo (new Nette\PhpGenerator\PsrPrinter)->printClosure($closure); +``` + +Result: + +```php +function ($a, $b) use (&$c) { + return $a + $b; +} +``` + +Method and Function Body Generator +---------------------------------- + +You can use special placeholders for handy way to generate method or function body. + +Simple placeholders: + +```php +$str = 'any string'; +$num = 3; +$function = new Nette\PhpGenerator\GlobalFunction('foo'); +$function->addBody('return strlen(?, ?);', [$str, $num]); +echo $function; +``` + +Result: + +```php +function foo() +{ + return strlen('any string', 3); +} +``` + +Variadic placeholder: + +```php +$items = [1, 2, 3]; +$function = new Nette\PhpGenerator\GlobalFunction('foo'); +$function->setBody('myfunc(...?);', [$items]); +echo $function; +``` + +Result: + +```php +function foo() +{ + myfunc(1, 2, 3); +} +``` + +Escape placeholder using slash: + +```php +$num = 3; +$function = new Nette\PhpGenerator\GlobalFunction('foo'); +$function->addParameter('a'); +$function->addBody('return $a \? 10 : ?;', [$num]); +echo $function; +``` + +Result: + +```php +function foo($a) +{ + return $a ? 10 : 3; +} +``` + +Namespace +--------- + +Classes, traits and interfaces (hereinafter classes) can be grouped into namespaces: + +```php +$namespace = new Nette\PhpGenerator\PhpNamespace('Foo'); + +$class = $namespace->addClass('Task'); +$interface = $namespace->addInterface('Countable'); +$trait = $namespace->addTrait('NameAware'); + +// or +$class = new Nette\PhpGenerator\ClassType('Task'); +$namespace->add($class); +``` + +If the class already exists, it will be overwritten. + +You can define use-statements: + +```php +$namespace->addUse('Http\Request'); // use Http\Request; +$namespace->addUse('Http\Request', 'HttpReq'); // use Http\Request as HttpReq; +``` + +**IMPORTANT NOTE:** when the class is part of the namespace, it is rendered slightly differently: all types (ie. type hints, return types, parent class name, +implemented interfaces and used traits) are automatically *resolved*. It means that you have to **use full class names** in definitions +and they will be replaced with aliases (according to the use-statements) or fully qualified names in the resulting code: + +```php +$namespace = new Nette\PhpGenerator\PhpNamespace('Foo'); +$namespace->addUse('Bar\AliasedClass'); + +$class = $namespace->addClass('Demo'); +$class->addImplement('Foo\A') // it will resolve to A + ->addTrait('Bar\AliasedClass'); // it will resolve to AliasedClass + +$method = $class->addMethod('method'); +$method->addComment('@return ' . $namespace->unresolveName('Foo\D')); // in comments resolve manually +$method->addParameter('arg') + ->setTypeHint('Bar\OtherClass'); // it will resolve to \Bar\OtherClass + +echo $namespace; + +// or use PsrPrinter for output compatible with PSR-2 / PSR-12 +// echo (new Nette\PhpGenerator\PsrPrinter)->printNamespace($namespace); +``` + +Result: + +```php +namespace Foo; + +use Bar\AliasedClass; + +class Demo implements A +{ + use AliasedClass; + + /** + * @return D + */ + public function method(\Bar\OtherClass $arg) + { + } +} +``` + +PHP Files +--------- + +PHP files can contains multiple classes, namespaces and comments: + +```php +$file = new Nette\PhpGenerator\PhpFile; +$file->addComment('This file is auto-generated.'); +$file->setStrictTypes(); // adds declare(strict_types=1) + +$namespace = $file->addNamespace('Foo'); +$class = $namespace->addClass('A'); +$class->addMethod('hello'); + +echo $file; + +// or use PsrPrinter for output compatible with PSR-2 / PSR-12 +// echo (new Nette\PhpGenerator\PsrPrinter)->printFile($file); +``` + +Result: + +```php + Constant */ + private $consts = []; + + /** @var Property[] name => Property */ + private $properties = []; + + /** @var Method[] name => Method */ + private $methods = []; + + + /** + * @param string|object $class + * @return static + */ + public static function from($class): self + { + return (new Factory)->fromClassReflection(new \ReflectionClass($class)); + } + + + public function __construct(string $name = null, PhpNamespace $namespace = null) + { + $this->setName($name); + $this->namespace = $namespace; + } + + + public function __toString(): string + { + try { + return (new Printer)->printClass($this, $this->namespace); + } catch (\Throwable $e) { + trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); + } + } + + + /** + * Deprecated: an object can be in multiple namespaces. + * @deprecated + */ + public function getNamespace(): ?PhpNamespace + { + return $this->namespace; + } + + + /** + * @return static + */ + public function setName(?string $name): self + { + if ($name !== null && !Helpers::isIdentifier($name)) { + throw new Nette\InvalidArgumentException("Value '$name' is not valid class name."); + } + $this->name = $name; + return $this; + } + + + public function getName(): ?string + { + return $this->name; + } + + + /** + * @return static + */ + public function setType(string $type): self + { + if (!in_array($type, [self::TYPE_CLASS, self::TYPE_INTERFACE, self::TYPE_TRAIT], true)) { + throw new Nette\InvalidArgumentException('Argument must be class|interface|trait.'); + } + $this->type = $type; + return $this; + } + + + public function getType(): string + { + return $this->type; + } + + + /** + * @return static + */ + public function setFinal(bool $state = true): self + { + $this->final = $state; + return $this; + } + + + public function isFinal(): bool + { + return $this->final; + } + + + /** + * @return static + */ + public function setAbstract(bool $state = true): self + { + $this->abstract = $state; + return $this; + } + + + public function isAbstract(): bool + { + return $this->abstract; + } + + + /** + * @param string|string[] $names + * @return static + */ + public function setExtends($names): self + { + if (!is_string($names) && !is_array($names)) { + throw new Nette\InvalidArgumentException('Argument must be string or string[].'); + } + $this->validateNames((array) $names); + $this->extends = $names; + return $this; + } + + + /** + * @return string|string[] + */ + public function getExtends() + { + return $this->extends; + } + + + /** + * @return static + */ + public function addExtend(string $name): self + { + $this->validateNames([$name]); + $this->extends = (array) $this->extends; + $this->extends[] = $name; + return $this; + } + + + /** + * @param string[] $names + * @return static + */ + public function setImplements(array $names): self + { + $this->validateNames($names); + $this->implements = $names; + return $this; + } + + + /** + * @return string[] + */ + public function getImplements(): array + { + return $this->implements; + } + + + /** + * @return static + */ + public function addImplement(string $name): self + { + $this->validateNames([$name]); + $this->implements[] = $name; + return $this; + } + + + /** + * @param string[] $names + * @return static + */ + public function setTraits(array $names): self + { + $this->validateNames($names); + $this->traits = array_fill_keys($names, []); + return $this; + } + + + /** + * @return string[] + */ + public function getTraits(): array + { + return array_keys($this->traits); + } + + + /** + * @internal + */ + public function getTraitResolutions(): array + { + return $this->traits; + } + + + /** + * @return static + */ + public function addTrait(string $name, array $resolutions = []): self + { + $this->validateNames([$name]); + $this->traits[$name] = $resolutions; + return $this; + } + + + /** + * @param Method|Property|Constant $member + * @return static + */ + public function addMember($member): self + { + if ($member instanceof Method) { + if ($this->type === self::TYPE_INTERFACE) { + $member->setBody(null); + } + $this->methods[$member->getName()] = $member; + + } elseif ($member instanceof Property) { + $this->properties[$member->getName()] = $member; + + } elseif ($member instanceof Constant) { + $this->consts[$member->getName()] = $member; + + } else { + throw new Nette\InvalidArgumentException('Argument must be Method|Property|Constant.'); + } + + return $this; + } + + + /** + * @param Constant[]|mixed[] $consts + * @return static + */ + public function setConstants(array $consts): self + { + $this->consts = []; + foreach ($consts as $k => $v) { + $const = $v instanceof Constant ? $v : (new Constant($k))->setValue($v); + $this->consts[$const->getName()] = $const; + } + return $this; + } + + + /** + * @return Constant[] + */ + public function getConstants(): array + { + return $this->consts; + } + + + public function addConstant(string $name, $value): Constant + { + return $this->consts[$name] = (new Constant($name))->setValue($value); + } + + + /** + * @return static + */ + public function removeConstant(string $name): self + { + unset($this->consts[$name]); + return $this; + } + + + /** + * @param Property[] $props + * @return static + */ + public function setProperties(array $props): self + { + $this->properties = []; + foreach ($props as $v) { + if (!$v instanceof Property) { + throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Property[].'); + } + $this->properties[$v->getName()] = $v; + } + return $this; + } + + + /** + * @return Property[] + */ + public function getProperties(): array + { + return $this->properties; + } + + + public function getProperty(string $name): Property + { + if (!isset($this->properties[$name])) { + throw new Nette\InvalidArgumentException("Property '$name' not found."); + } + return $this->properties[$name]; + } + + + /** + * @param string $name without $ + */ + public function addProperty(string $name, $value = null): Property + { + return $this->properties[$name] = (new Property($name))->setValue($value); + } + + + /** + * @param string $name without $ + * @return static + */ + public function removeProperty(string $name): self + { + unset($this->properties[$name]); + return $this; + } + + + /** + * @param Method[] $methods + * @return static + */ + public function setMethods(array $methods): self + { + $this->methods = []; + foreach ($methods as $v) { + if (!$v instanceof Method) { + throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Method[].'); + } + $this->methods[$v->getName()] = $v; + } + return $this; + } + + + /** + * @return Method[] + */ + public function getMethods(): array + { + return $this->methods; + } + + + public function getMethod(string $name): Method + { + if (!isset($this->methods[$name])) { + throw new Nette\InvalidArgumentException("Method '$name' not found."); + } + return $this->methods[$name]; + } + + + public function addMethod(string $name): Method + { + $method = new Method($name); + if ($this->type === self::TYPE_INTERFACE) { + $method->setBody(null); + } else { + $method->setVisibility(self::VISIBILITY_PUBLIC); + } + return $this->methods[$name] = $method; + } + + + /** + * @return static + */ + public function removeMethod(string $name): self + { + unset($this->methods[$name]); + return $this; + } + + + /** + * @throws Nette\InvalidStateException + */ + public function validate(): void + { + if ($this->abstract && $this->final) { + throw new Nette\InvalidStateException('Class cannot be abstract and final.'); + + } elseif (!$this->name && ($this->abstract || $this->final)) { + throw new Nette\InvalidStateException('Anonymous class cannot be abstract or final.'); + } + } + + + private function validateNames(array $names): void + { + foreach ($names as $name) { + if (!Helpers::isNamespaceIdentifier($name, true)) { + throw new Nette\InvalidArgumentException("Value '$name' is not valid class name."); + } + } + } + + + public function __clone() + { + $clone = function ($item) { return clone $item; }; + $this->consts = array_map($clone, $this->consts); + $this->properties = array_map($clone, $this->properties); + $this->methods = array_map($clone, $this->methods); + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Closure.php b/vendor/nette/php-generator/src/PhpGenerator/Closure.php new file mode 100644 index 00000000..f83b04b3 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Closure.php @@ -0,0 +1,70 @@ +fromFunctionReflection(new \ReflectionFunction($closure)); + } + + + public function __toString(): string + { + try { + return (new Printer)->printClosure($this); + } catch (\Throwable $e) { + trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); + } + } + + + /** + * @param Parameter[] $uses + * @return static + */ + public function setUses(array $uses): self + { + (function (Parameter ...$uses) {})(...$uses); + $this->uses = $uses; + return $this; + } + + + public function getUses(): array + { + return $this->uses; + } + + + public function addUse(string $name): Parameter + { + return $this->uses[] = new Parameter($name); + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Constant.php b/vendor/nette/php-generator/src/PhpGenerator/Constant.php new file mode 100644 index 00000000..cba9e5a8 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Constant.php @@ -0,0 +1,43 @@ +value = $val; + return $this; + } + + + public function getValue() + { + return $this->value; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Factory.php b/vendor/nette/php-generator/src/PhpGenerator/Factory.php new file mode 100644 index 00000000..88ad0c2b --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Factory.php @@ -0,0 +1,134 @@ +isAnonymous() + ? new ClassType + : new ClassType($from->getShortName(), new PhpNamespace($from->getNamespaceName())); + $class->setType($from->isInterface() ? $class::TYPE_INTERFACE : ($from->isTrait() ? $class::TYPE_TRAIT : $class::TYPE_CLASS)); + $class->setFinal($from->isFinal() && $class->getType() === $class::TYPE_CLASS); + $class->setAbstract($from->isAbstract() && $class->getType() === $class::TYPE_CLASS); + + $ifaces = $from->getInterfaceNames(); + foreach ($ifaces as $iface) { + $ifaces = array_filter($ifaces, function (string $item) use ($iface): bool { + return !is_subclass_of($iface, $item); + }); + } + $class->setImplements($ifaces); + + $class->setComment(Helpers::unformatDocComment((string) $from->getDocComment())); + if ($from->getParentClass()) { + $class->setExtends($from->getParentClass()->getName()); + $class->setImplements(array_diff($class->getImplements(), $from->getParentClass()->getInterfaceNames())); + } + $props = $methods = []; + foreach ($from->getProperties() as $prop) { + if ($prop->isDefault() && $prop->getDeclaringClass()->getName() === $from->getName()) { + $props[] = $this->fromPropertyReflection($prop); + } + } + $class->setProperties($props); + foreach ($from->getMethods() as $method) { + if ($method->getDeclaringClass()->getName() === $from->getName()) { + $methods[] = $this->fromMethodReflection($method); + } + } + $class->setMethods($methods); + $class->setConstants($from->getConstants()); + return $class; + } + + + public function fromMethodReflection(\ReflectionMethod $from): Method + { + $method = new Method($from->getName()); + $method->setParameters(array_map([$this, 'fromParameterReflection'], $from->getParameters())); + $method->setStatic($from->isStatic()); + $isInterface = $from->getDeclaringClass()->isInterface(); + $method->setVisibility($from->isPrivate() + ? ClassType::VISIBILITY_PRIVATE + : ($from->isProtected() ? ClassType::VISIBILITY_PROTECTED : ($isInterface ? null : ClassType::VISIBILITY_PUBLIC)) + ); + $method->setFinal($from->isFinal()); + $method->setAbstract($from->isAbstract() && !$isInterface); + $method->setBody($from->isAbstract() ? null : ''); + $method->setReturnReference($from->returnsReference()); + $method->setVariadic($from->isVariadic()); + $method->setComment(Helpers::unformatDocComment((string) $from->getDocComment())); + if ($from->hasReturnType()) { + $method->setReturnType((string) $from->getReturnType()); + $method->setReturnNullable($from->getReturnType()->allowsNull()); + } + return $method; + } + + + /** + * @return GlobalFunction|Closure + */ + public function fromFunctionReflection(\ReflectionFunction $from) + { + $function = $from->isClosure() ? new Closure : new GlobalFunction($from->getName()); + $function->setParameters(array_map([$this, 'fromParameterReflection'], $from->getParameters())); + $function->setReturnReference($from->returnsReference()); + $function->setVariadic($from->isVariadic()); + if (!$from->isClosure()) { + $function->setComment(Helpers::unformatDocComment((string) $from->getDocComment())); + } + if ($from->hasReturnType()) { + $function->setReturnType((string) $from->getReturnType()); + $function->setReturnNullable($from->getReturnType()->allowsNull()); + } + return $function; + } + + + public function fromParameterReflection(\ReflectionParameter $from): Parameter + { + $param = new Parameter($from->getName()); + $param->setReference($from->isPassedByReference()); + $param->setTypeHint($from->hasType() ? (string) $from->getType() : null); + $param->setNullable($from->hasType() && $from->getType()->allowsNull()); + if ($from->isDefaultValueAvailable()) { + $param->setDefaultValue($from->isDefaultValueConstant() + ? new PhpLiteral($from->getDefaultValueConstantName()) + : $from->getDefaultValue()); + $param->setNullable($param->isNullable() && $param->getDefaultValue() !== null); + } + return $param; + } + + + public function fromPropertyReflection(\ReflectionProperty $from): Property + { + $prop = new Property($from->getName()); + $prop->setValue($from->getDeclaringClass()->getDefaultProperties()[$prop->getName()] ?? null); + $prop->setStatic($from->isStatic()); + $prop->setVisibility($from->isPrivate() + ? ClassType::VISIBILITY_PRIVATE + : ($from->isProtected() ? ClassType::VISIBILITY_PROTECTED : ClassType::VISIBILITY_PUBLIC) + ); + $prop->setComment(Helpers::unformatDocComment((string) $from->getDocComment())); + return $prop; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/GlobalFunction.php b/vendor/nette/php-generator/src/PhpGenerator/GlobalFunction.php new file mode 100644 index 00000000..1c7e6474 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/GlobalFunction.php @@ -0,0 +1,44 @@ +fromFunctionReflection(new \ReflectionFunction($function)); + } + + + public function __toString(): string + { + try { + return (new Printer)->printFunction($this); + } catch (\Throwable $e) { + trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); + } + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Helpers.php b/vendor/nette/php-generator/src/PhpGenerator/Helpers.php new file mode 100644 index 00000000..e8976dfd --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Helpers.php @@ -0,0 +1,273 @@ + self::MAX_DEPTH || isset($var[$marker])) { + throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.'); + + } else { + $out = ''; + $outWrapped = "\n$space"; + $var[$marker] = true; + $counter = 0; + foreach ($var as $k => &$v) { + if ($k !== $marker) { + $item = ($k === $counter ? '' : self::_dump($k, $level + 1) . ' => ') . self::_dump($v, $level + 1); + $counter = is_int($k) ? max($k + 1, $counter) : $counter; + $out .= ($out === '' ? '' : ', ') . $item; + $outWrapped .= "\t$item,\n$space"; + } + } + unset($var[$marker]); + } + $wrap = strpos($out, "\n") !== false || strlen($out) > self::WRAP_LENGTH - $level * self::INDENT_LENGTH; + return '[' . ($wrap ? $outWrapped : $out) . ']'; + + } elseif ($var instanceof \Serializable) { + $var = serialize($var); + return 'unserialize(' . self::_dump($var, $level) . ')'; + + } elseif ($var instanceof \Closure) { + throw new Nette\InvalidArgumentException('Cannot dump closure.'); + + } elseif (is_object($var)) { + $class = get_class($var); + if ((new \ReflectionObject($var))->isAnonymous()) { + throw new Nette\InvalidArgumentException('Cannot dump anonymous class.'); + + } elseif (in_array($class, ['DateTime', 'DateTimeImmutable'], true)) { + return self::formatArgs("new $class(?, new DateTimeZone(?))", [$var->format('Y-m-d H:i:s.u'), $var->getTimeZone()->getName()]); + } + + $arr = (array) $var; + $space = str_repeat("\t", $level); + + static $list = []; + if ($level > self::MAX_DEPTH || in_array($var, $list, true)) { + throw new Nette\InvalidArgumentException('Nesting level too deep or recursive dependency.'); + + } else { + $out = "\n"; + $list[] = $var; + if (method_exists($var, '__sleep')) { + foreach ($var->__sleep() as $v) { + $props[$v] = $props["\x00*\x00$v"] = $props["\x00$class\x00$v"] = true; + } + } + foreach ($arr as $k => &$v) { + if (!isset($props) || isset($props[$k])) { + $out .= "$space\t" . self::_dump($k, $level + 1) . ' => ' . self::_dump($v, $level + 1) . ",\n"; + } + } + array_pop($list); + $out .= $space; + } + return $class === 'stdClass' + ? "(object) [$out]" + : __CLASS__ . "::createObject('$class', [$out])"; + + } elseif (is_resource($var)) { + throw new Nette\InvalidArgumentException('Cannot dump resource.'); + + } else { + return var_export($var, true); + } + } + + + /** + * Generates PHP statement. + */ + public static function format(string $statement, ...$args): string + { + return self::formatArgs($statement, $args); + } + + + /** + * Generates PHP statement. + */ + public static function formatArgs(string $statement, array $args): string + { + $tokens = preg_split('#(\.\.\.\?|\$\?|->\?|::\?|\\\\\?|\?\*|\?)#', $statement, -1, PREG_SPLIT_DELIM_CAPTURE); + $res = ''; + foreach ($tokens as $n => $token) { + if ($n % 2 === 0) { + $res .= $token; + } elseif ($token === '\\?') { + $res .= '?'; + } elseif (!$args) { + throw new Nette\InvalidArgumentException('Insufficient number of arguments.'); + } elseif ($token === '?') { + $res .= self::dump(array_shift($args)); + } elseif ($token === '...?' || $token === '?*') { + $arg = array_shift($args); + if (!is_array($arg)) { + throw new Nette\InvalidArgumentException('Argument must be an array.'); + } + $items = []; + foreach ($arg as $tmp) { + $items[] = self::dump($tmp); + } + $res .= strlen($tmp = implode(', ', $items)) > self::WRAP_LENGTH && count($items) > 1 + ? "\n" . Nette\Utils\Strings::indent(implode(",\n", $items)) . "\n" + : $tmp; + + } else { // $ -> :: + $res .= substr($token, 0, -1) . self::formatMember(array_shift($args)); + } + } + if ($args) { + throw new Nette\InvalidArgumentException('Insufficient number of placeholders.'); + } + return $res; + } + + + /** + * Returns a PHP representation of a object member. + */ + public static function formatMember($name): string + { + return $name instanceof PhpLiteral || !self::isIdentifier($name) + ? '{' . self::_dump($name) . '}' + : $name; + } + + + public static function formatDocComment(string $content): string + { + if (($s = trim($content)) === '') { + return ''; + } elseif (strpos($content, "\n") === false) { + return "/** $s */\n"; + } else { + return str_replace("\n", "\n * ", "/**\n$s") . "\n */\n"; + } + } + + + public static function unformatDocComment(string $comment): string + { + return preg_replace('#^\s*\* ?#m', '', trim(trim(trim($comment), '/*'))); + } + + + public static function isIdentifier($value): bool + { + return is_string($value) && preg_match('#^' . self::PHP_IDENT . '\z#', $value); + } + + + public static function isNamespaceIdentifier($value, bool $allowLeadingSlash = false): bool + { + $re = '#^' . ($allowLeadingSlash ? '\\\\?' : '') . self::PHP_IDENT . '(\\\\' . self::PHP_IDENT . ')*\z#'; + return is_string($value) && preg_match($re, $value); + } + + + /** + * @return object + * @internal + */ + public static function createObject(string $class, array $props) + { + return unserialize('O' . substr(serialize($class), 1, -1) . substr(serialize($props), 1)); + } + + + public static function extractNamespace(string $name): string + { + return ($pos = strrpos($name, '\\')) ? substr($name, 0, $pos) : ''; + } + + + public static function extractShortName(string $name): string + { + return ($pos = strrpos($name, '\\')) === false ? $name : substr($name, $pos + 1); + } + + + public static function tabsToSpaces(string $s, int $count = self::INDENT_LENGTH): string + { + return str_replace("\t", str_repeat(' ', $count), $s); + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Method.php b/vendor/nette/php-generator/src/PhpGenerator/Method.php new file mode 100644 index 00000000..124240ce --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Method.php @@ -0,0 +1,134 @@ +fromMethodReflection(Nette\Utils\Callback::toReflection($method)); + } + + + public function __toString(): string + { + try { + return (new Printer)->printMethod($this); + } catch (\Throwable $e) { + trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); + } + } + + + /** + * @return static + */ + public function setBody(?string $code, array $args = null): self + { + $this->body = $args === null || $code === null ? $code : Helpers::formatArgs($code, $args); + return $this; + } + + + public function getBody(): ?string + { + return $this->body; + } + + + /** + * @return static + */ + public function setStatic(bool $state = true): self + { + $this->static = $state; + return $this; + } + + + public function isStatic(): bool + { + return $this->static; + } + + + /** + * @return static + */ + public function setFinal(bool $state = true): self + { + $this->final = $state; + return $this; + } + + + public function isFinal(): bool + { + return $this->final; + } + + + /** + * @return static + */ + public function setAbstract(bool $state = true): self + { + $this->abstract = $state; + return $this; + } + + + public function isAbstract(): bool + { + return $this->abstract; + } + + + /** + * @throws Nette\InvalidStateException + */ + public function validate(): void + { + if ($this->abstract && ($this->final || $this->visibility === ClassType::VISIBILITY_PRIVATE)) { + throw new Nette\InvalidStateException('Method cannot be abstract and final or private.'); + } + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Parameter.php b/vendor/nette/php-generator/src/PhpGenerator/Parameter.php new file mode 100644 index 00000000..845e0919 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Parameter.php @@ -0,0 +1,122 @@ +reference = $state; + return $this; + } + + + public function isReference(): bool + { + return $this->reference; + } + + + /** + * @return static + */ + public function setTypeHint(?string $hint): self + { + $this->typeHint = $hint; + return $this; + } + + + public function getTypeHint(): ?string + { + return $this->typeHint; + } + + + /** + * @deprecated just use setDefaultValue() + * @return static + */ + public function setOptional(bool $state = true): self + { + trigger_error(__METHOD__ . '() is deprecated, use setDefaultValue()', E_USER_DEPRECATED); + $this->hasDefaultValue = $state; + return $this; + } + + + /** + * @return static + */ + public function setNullable(bool $state = true): self + { + $this->nullable = $state; + return $this; + } + + + public function isNullable(): bool + { + return $this->nullable; + } + + + /** + * @return static + */ + public function setDefaultValue($val): self + { + $this->defaultValue = $val; + $this->hasDefaultValue = true; + return $this; + } + + + public function getDefaultValue() + { + return $this->defaultValue; + } + + + public function hasDefaultValue(): bool + { + return $this->hasDefaultValue; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/PhpFile.php b/vendor/nette/php-generator/src/PhpGenerator/PhpFile.php new file mode 100644 index 00000000..bcc98c2c --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/PhpFile.php @@ -0,0 +1,115 @@ +addNamespace(Helpers::extractNamespace($name)) + ->addClass(Helpers::extractShortName($name)); + } + + + public function addInterface(string $name): ClassType + { + return $this + ->addNamespace(Helpers::extractNamespace($name)) + ->addInterface(Helpers::extractShortName($name)); + } + + + public function addTrait(string $name): ClassType + { + return $this + ->addNamespace(Helpers::extractNamespace($name)) + ->addTrait(Helpers::extractShortName($name)); + } + + + public function addNamespace(string $name): PhpNamespace + { + if (!isset($this->namespaces[$name])) { + $this->namespaces[$name] = new PhpNamespace($name); + foreach ($this->namespaces as $namespace) { + $namespace->setBracketedSyntax(count($this->namespaces) > 1 && isset($this->namespaces[''])); + } + } + return $this->namespaces[$name]; + } + + + /** + * @return PhpNamespace[] + */ + public function getNamespaces(): array + { + return $this->namespaces; + } + + + /** + * @return static + */ + public function addUse(string $name, string $alias = null): self + { + $this->addNamespace('')->addUse($name, $alias); + return $this; + } + + + /** + * Adds declare(strict_types=1) to output. + * @return static + */ + public function setStrictTypes(bool $on = true): self + { + $this->strictTypes = $on; + return $this; + } + + + public function getStrictTypes(): bool + { + return $this->strictTypes; + } + + + public function __toString(): string + { + try { + return (new Printer)->printFile($this); + } catch (\Throwable $e) { + trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); + } + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/PhpLiteral.php b/vendor/nette/php-generator/src/PhpGenerator/PhpLiteral.php new file mode 100644 index 00000000..816a5290 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/PhpLiteral.php @@ -0,0 +1,32 @@ +value = $value; + } + + + public function __toString(): string + { + return $this->value; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/PhpNamespace.php b/vendor/nette/php-generator/src/PhpGenerator/PhpNamespace.php new file mode 100644 index 00000000..c19828a7 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/PhpNamespace.php @@ -0,0 +1,199 @@ + 1, 'int' => 1, 'float' => 1, 'bool' => 1, 'array' => 1, 'object' => 1, + 'callable' => 1, 'iterable' => 1, 'void' => 1, 'self' => 1, 'parent' => 1, + ]; + + /** @var string */ + private $name; + + /** @var bool */ + private $bracketedSyntax = false; + + /** @var string[] */ + private $uses = []; + + /** @var ClassType[] */ + private $classes = []; + + + public function __construct(string $name) + { + if ($name !== '' && !Helpers::isNamespaceIdentifier($name)) { + throw new Nette\InvalidArgumentException("Value '$name' is not valid name."); + } + $this->name = $name; + } + + + public function getName(): string + { + return $this->name; + } + + + /** + * @return static + * @internal + */ + public function setBracketedSyntax(bool $state = true): self + { + $this->bracketedSyntax = $state; + return $this; + } + + + public function getBracketedSyntax(): bool + { + return $this->bracketedSyntax; + } + + + /** + * @throws InvalidStateException + * @return static + */ + public function addUse(string $name, string $alias = null, string &$aliasOut = null): self + { + $name = ltrim($name, '\\'); + if ($alias === null && $this->name === Helpers::extractNamespace($name)) { + $alias = Helpers::extractShortName($name); + } + if ($alias === null) { + $path = explode('\\', $name); + $counter = null; + do { + if (empty($path)) { + $counter++; + } else { + $alias = array_pop($path) . $alias; + } + } while (isset($this->uses[$alias . $counter]) && $this->uses[$alias . $counter] !== $name); + $alias .= $counter; + + } elseif (isset($this->uses[$alias]) && $this->uses[$alias] !== $name) { + throw new InvalidStateException( + "Alias '$alias' used already for '{$this->uses[$alias]}', cannot use for '{$name}'." + ); + } + + $aliasOut = $alias; + $this->uses[$alias] = $name; + asort($this->uses); + return $this; + } + + + /** + * @return string[] + */ + public function getUses(): array + { + return $this->uses; + } + + + public function unresolveName(string $name): string + { + if (isset(self::KEYWORDS[strtolower($name)]) || $name === '') { + return $name; + } + $name = ltrim($name, '\\'); + $res = null; + $lower = strtolower($name); + foreach ($this->uses as $alias => $original) { + if (Strings::startsWith($lower . '\\', strtolower($original) . '\\')) { + $short = $alias . substr($name, strlen($original)); + if (!isset($res) || strlen($res) > strlen($short)) { + $res = $short; + } + } + } + + if (!$res && Strings::startsWith($lower, strtolower($this->name) . '\\')) { + return substr($name, strlen($this->name) + 1); + } else { + return $res ?: ($this->name ? '\\' : '') . $name; + } + } + + + /** + * @return static + */ + public function add(ClassType $class): self + { + $name = $class->getName(); + if ($name === null) { + throw new Nette\InvalidArgumentException('Class does not have a name.'); + } + $this->addUse($this->name . '\\' . $name); + $this->classes[$name] = $class; + return $this; + } + + + public function addClass(string $name): ClassType + { + $this->add($class = new ClassType($name, $this)); + return $class; + } + + + public function addInterface(string $name): ClassType + { + return $this->addClass($name)->setType(ClassType::TYPE_INTERFACE); + } + + + public function addTrait(string $name): ClassType + { + return $this->addClass($name)->setType(ClassType::TYPE_TRAIT); + } + + + /** + * @return ClassType[] + */ + public function getClasses(): array + { + return $this->classes; + } + + + public function __toString(): string + { + try { + return (new Printer)->printNamespace($this); + } catch (\Throwable $e) { + trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); + } + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Printer.php b/vendor/nette/php-generator/src/PhpGenerator/Printer.php new file mode 100644 index 00000000..580a3f10 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Printer.php @@ -0,0 +1,226 @@ +getComment() . "\n") + . 'function ' + . ($function->getReturnReference() ? '&' : '') + . $function->getName() + . $this->printParameters($function, $namespace) + . $this->printReturnType($function, $namespace) + . "\n{\n" . $this->indent(ltrim(rtrim($function->getBody()) . "\n")) . "}\n"; + } + + + public function printClosure(Closure $closure): string + { + $uses = []; + foreach ($closure->getUses() as $param) { + $uses[] = ($param->isReference() ? '&' : '') . '$' . $param->getName(); + } + $useStr = strlen($tmp = implode(', ', $uses)) > Helpers::WRAP_LENGTH && count($uses) > 1 + ? "\n" . $this->indentation . implode(",\n" . $this->indentation, $uses) . "\n" + : $tmp; + + return 'function ' + . ($closure->getReturnReference() ? '&' : '') + . $this->printParameters($closure, null) + . ($uses ? " use ($useStr)" : '') + . $this->printReturnType($closure, null) + . " {\n" . $this->indent(ltrim(rtrim($closure->getBody()) . "\n")) . '}'; + } + + + public function printMethod(Method $method, PhpNamespace $namespace = null): string + { + $method->validate(); + return Helpers::formatDocComment($method->getComment() . "\n") + . ($method->isAbstract() ? 'abstract ' : '') + . ($method->isFinal() ? 'final ' : '') + . ($method->getVisibility() ? $method->getVisibility() . ' ' : '') + . ($method->isStatic() ? 'static ' : '') + . 'function ' + . ($method->getReturnReference() ? '&' : '') + . $method->getName() + . ($params = $this->printParameters($method, $namespace)) + . $this->printReturnType($method, $namespace) + . ($method->isAbstract() || $method->getBody() === null + ? ";\n" + : (strpos($params, "\n") === false ? "\n" : ' ') + . "{\n" + . $this->indent(ltrim(rtrim($method->getBody()) . "\n")) + . "}\n"); + } + + + public function printClass(ClassType $class, PhpNamespace $namespace = null): string + { + $class->validate(); + $resolver = $namespace ? [$namespace, 'unresolveName'] : function ($s) { return $s; }; + + $traits = []; + foreach ($class->getTraitResolutions() as $trait => $resolutions) { + $traits[] = 'use ' . $resolver($trait) + . ($resolutions ? " {\n" . $this->indentation . implode(";\n" . $this->indentation, $resolutions) . ";\n}\n" : ";\n"); + } + + $consts = []; + foreach ($class->getConstants() as $const) { + $consts[] = Helpers::formatDocComment((string) $const->getComment()) + . ($const->getVisibility() ? $const->getVisibility() . ' ' : '') + . 'const ' . $const->getName() . ' = ' . Helpers::dump($const->getValue()) . ";\n"; + } + + $properties = []; + foreach ($class->getProperties() as $property) { + $properties[] = Helpers::formatDocComment((string) $property->getComment()) + . ($property->getVisibility() ?: 'public') . ($property->isStatic() ? ' static' : '') . ' $' . $property->getName() + . ($property->getValue() === null ? '' : ' = ' . Helpers::dump($property->getValue())) + . ";\n"; + } + + $methods = []; + foreach ($class->getMethods() as $method) { + $methods[] = $this->printMethod($method, $namespace); + } + + $members = array_filter([ + implode('', $traits), + implode('', $consts), + implode("\n", $properties), + ($methods && $properties ? str_repeat("\n", $this->linesBetweenMethods - 1) : '') + . implode(str_repeat("\n", $this->linesBetweenMethods), $methods), + ]); + + return Strings::normalize( + Helpers::formatDocComment($class->getComment() . "\n") + . ($class->isAbstract() ? 'abstract ' : '') + . ($class->isFinal() ? 'final ' : '') + . ($class->getName() ? $class->getType() . ' ' . $class->getName() . ' ' : '') + . ($class->getExtends() ? 'extends ' . implode(', ', array_map($resolver, (array) $class->getExtends())) . ' ' : '') + . ($class->getImplements() ? 'implements ' . implode(', ', array_map($resolver, $class->getImplements())) . ' ' : '') + . ($class->getName() ? "\n" : '') . "{\n" + . ($members ? $this->indent(implode("\n", $members)) : '') + . '}' + ) . ($class->getName() ? "\n" : ''); + } + + + public function printNamespace(PhpNamespace $namespace): string + { + $name = $namespace->getName(); + + $uses = []; + foreach ($namespace->getUses() as $alias => $original) { + if ($original !== ($name ? $name . '\\' . $alias : $alias)) { + if ($alias === $original || substr($original, -(strlen($alias) + 1)) === '\\' . $alias) { + $uses[] = "use $original;"; + } else { + $uses[] = "use $original as $alias;"; + } + } + } + + $classes = []; + foreach ($namespace->getClasses() as $class) { + $classes[] = $this->printClass($class, $namespace); + } + + $body = ($uses ? implode("\n", $uses) . "\n\n" : '') + . implode("\n", $classes); + + if ($namespace->getBracketedSyntax()) { + return 'namespace' . ($name ? " $name" : '') . "\n{\n" + . $this->indent($body) + . "}\n"; + + } else { + return ($name ? "namespace $name;\n\n" : '') + . $body; + } + } + + + public function printFile(PhpFile $file): string + { + $namespaces = []; + foreach ($file->getNamespaces() as $namespace) { + $namespaces[] = $this->printNamespace($namespace); + } + + return Strings::normalize( + "getComment() ? "\n" . Helpers::formatDocComment($file->getComment() . "\n") : '') + . "\n" + . ($file->getStrictTypes() ? "declare(strict_types=1);\n\n" : '') + . implode("\n\n", $namespaces) + ) . "\n"; + } + + + protected function indent(string $s): string + { + return Strings::indent($s, 1, $this->indentation); + } + + + /** + * @param Nette\PhpGenerator\Traits\FunctionLike $function + */ + protected function printParameters($function, ?PhpNamespace $namespace): string + { + $params = []; + $list = $function->getParameters(); + foreach ($list as $param) { + $variadic = $function->isVariadic() && $param === end($list); + $hint = $param->getTypeHint(); + $params[] = ($hint ? ($param->isNullable() ? '?' : '') . ($namespace ? $namespace->unresolveName($hint) : $hint) . ' ' : '') + . ($param->isReference() ? '&' : '') + . ($variadic ? '...' : '') + . '$' . $param->getName() + . ($param->hasDefaultValue() && !$variadic ? ' = ' . Helpers::dump($param->getDefaultValue()) : ''); + } + + return strlen($tmp = implode(', ', $params)) > Helpers::WRAP_LENGTH && count($params) > 1 + ? "(\n" . $this->indentation . implode(",\n" . $this->indentation, $params) . "\n)" + : "($tmp)"; + } + + + /** + * @param Nette\PhpGenerator\Traits\FunctionLike $function + */ + protected function printReturnType($function, ?PhpNamespace $namespace): string + { + return $function->getReturnType() + ? ': ' . ($function->getReturnNullable() ? '?' : '') . ($namespace ? $namespace->unresolveName($function->getReturnType()) : $function->getReturnType()) + : ''; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Property.php b/vendor/nette/php-generator/src/PhpGenerator/Property.php new file mode 100644 index 00000000..5092f4af --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Property.php @@ -0,0 +1,64 @@ +value = $val; + return $this; + } + + + public function &getValue() + { + return $this->value; + } + + + /** + * @return static + */ + public function setStatic(bool $state = true): self + { + $this->static = $state; + return $this; + } + + + public function isStatic(): bool + { + return $this->static; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/PsrPrinter.php b/vendor/nette/php-generator/src/PhpGenerator/PsrPrinter.php new file mode 100644 index 00000000..aef0f7d0 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/PsrPrinter.php @@ -0,0 +1,23 @@ +comment = $val; + return $this; + } + + + public function getComment(): ?string + { + return $this->comment; + } + + + /** + * @return static + */ + public function addComment(string $val): self + { + $this->comment .= $this->comment ? "\n$val" : $val; + return $this; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php b/vendor/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php new file mode 100644 index 00000000..4c368df2 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Traits/FunctionLike.php @@ -0,0 +1,189 @@ + Parameter */ + private $parameters = []; + + /** @var bool */ + private $variadic = false; + + /** @var string|null */ + private $returnType; + + /** @var bool */ + private $returnReference = false; + + /** @var bool */ + private $returnNullable = false; + + + /** + * @return static + */ + public function setBody(string $code, array $args = null): self + { + $this->body = $args === null ? $code : Helpers::formatArgs($code, $args); + return $this; + } + + + public function getBody(): string + { + return $this->body; + } + + + /** + * @return static + */ + public function addBody(string $code, array $args = null): self + { + $this->body .= ($args === null ? $code : Helpers::formatArgs($code, $args)) . "\n"; + return $this; + } + + + /** + * @param Parameter[] $val + * @return static + */ + public function setParameters(array $val): self + { + $this->parameters = []; + foreach ($val as $v) { + if (!$v instanceof Parameter) { + throw new Nette\InvalidArgumentException('Argument must be Nette\PhpGenerator\Parameter[].'); + } + $this->parameters[$v->getName()] = $v; + } + return $this; + } + + + /** + * @return Parameter[] + */ + public function getParameters(): array + { + return $this->parameters; + } + + + /** + * @param string $name without $ + */ + public function addParameter(string $name, $defaultValue = null): Parameter + { + $param = new Parameter($name); + if (func_num_args() > 1) { + $param->setDefaultValue($defaultValue); + } + return $this->parameters[$name] = $param; + } + + + /** + * @param string $name without $ + * @return static + */ + public function removeParameter(string $name): self + { + unset($this->parameters[$name]); + return $this; + } + + + /** + * @return static + */ + public function setVariadic(bool $state = true): self + { + $this->variadic = $state; + return $this; + } + + + public function isVariadic(): bool + { + return $this->variadic; + } + + + /** + * @return static + */ + public function setReturnType(?string $val): self + { + $this->returnType = $val; + return $this; + } + + + public function getReturnType(): ?string + { + return $this->returnType; + } + + + /** + * @return static + */ + public function setReturnReference(bool $state = true): self + { + $this->returnReference = $state; + return $this; + } + + + public function getReturnReference(): bool + { + return $this->returnReference; + } + + + /** + * @return static + */ + public function setReturnNullable(bool $state = true): self + { + $this->returnNullable = $state; + return $this; + } + + + public function getReturnNullable(): bool + { + return $this->returnNullable; + } + + + /** + * @deprecated + */ + public function setNamespace(PhpNamespace $val = null): self + { + trigger_error(__METHOD__ . '() is deprecated', E_USER_DEPRECATED); + return $this; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Traits/NameAware.php b/vendor/nette/php-generator/src/PhpGenerator/Traits/NameAware.php new file mode 100644 index 00000000..157aa0f8 --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Traits/NameAware.php @@ -0,0 +1,49 @@ +name = $name; + } + + + public function getName(): string + { + return $this->name; + } + + + /** + * Returns clone with a different name. + * @return static + */ + public function cloneWithName(string $name): self + { + $dolly = clone $this; + $dolly->__construct($name); + return $dolly; + } +} diff --git a/vendor/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php b/vendor/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php new file mode 100644 index 00000000..5011f02c --- /dev/null +++ b/vendor/nette/php-generator/src/PhpGenerator/Traits/VisibilityAware.php @@ -0,0 +1,43 @@ +visibility = $val; + return $this; + } + + + public function getVisibility(): ?string + { + return $this->visibility; + } +} diff --git a/vendor/nette/robot-loader/composer.json b/vendor/nette/robot-loader/composer.json new file mode 100644 index 00000000..7c5bc717 --- /dev/null +++ b/vendor/nette/robot-loader/composer.json @@ -0,0 +1,39 @@ +{ + "name": "nette/robot-loader", + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "keywords": ["nette", "autoload", "class", "trait", "interface"], + "homepage": "https://nette.org", + "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "require": { + "php": ">=5.6.0", + "ext-tokenizer": "*", + "nette/finder": "^2.3 || ^3.0", + "nette/utils": "^2.4 || ^3.0" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "autoload": { + "classmap": ["src/"] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + } +} diff --git a/vendor/nette/robot-loader/contributing.md b/vendor/nette/robot-loader/contributing.md new file mode 100644 index 00000000..184152c0 --- /dev/null +++ b/vendor/nette/robot-loader/contributing.md @@ -0,0 +1,33 @@ +How to contribute & use the issue tracker +========================================= + +Nette welcomes your contributions. There are several ways to help out: + +* Create an issue on GitHub, if you have found a bug +* Write test cases for open bug issues +* Write fixes for open bug/feature issues, preferably with test cases included +* Contribute to the [documentation](https://nette.org/en/writing) + +Issues +------ + +Please **do not use the issue tracker to ask questions**. We will be happy to help you +on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette). + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. + +**Feature requests** are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the project's developers of the merits of this feature. + +Contributing +------------ + +If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing). + +The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them. + +Please do not fix whitespace, format code, or make a purely cosmetic patch. + +Thanks! :heart: diff --git a/vendor/nette/robot-loader/license.md b/vendor/nette/robot-loader/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/nette/robot-loader/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" 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. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/robot-loader/readme.md b/vendor/nette/robot-loader/readme.md new file mode 100644 index 00000000..7339da97 --- /dev/null +++ b/vendor/nette/robot-loader/readme.md @@ -0,0 +1,78 @@ +RobotLoader: comfortable autoloading +==================================== + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/robot-loader.svg)](https://packagist.org/packages/nette/robot-loader) +[![Build Status](https://travis-ci.org/nette/robot-loader.svg?branch=master)](https://travis-ci.org/nette/robot-loader) +[![Coverage Status](https://coveralls.io/repos/github/nette/robot-loader/badge.svg?branch=master)](https://coveralls.io/github/nette/robot-loader?branch=master) +[![Latest Stable Version](https://poser.pugx.org/nette/robot-loader/v/stable)](https://github.com/nette/robot-loader/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/robot-loader/blob/master/license.md) + + +Introduction +------------ + +RobotLoader is a tool that gives you comfort of automated class loading for your entire application including third-party libraries. + +- get rid of all `require` +- only necessary scripts are loaded +- requires no strict file naming conventions +- allows more classes in single file + +RobotLoader is extremely comfortable and addictive! + +If you like Nette, **[please make a donation now](https://nette.org/donate)**. Thank you! + +So we can forget about those famous code blocks: + +```php +require_once 'Utils/Page.php'; +require_once 'Utils/Style.php'; +require_once 'Utils/Paginator.php'; +... +``` + +Like the Google robot crawls and indexes websites, RobotLoader crawls all PHP scripts and records what classes and interfaces were found in them. +These records are then saved in cache and used during all subsequent requests. + +Documentation can be found on the [website](https://doc.nette.org/robotloader). + + +Installation +------------ + +The recommended way to install is via Composer: + +``` +composer require nette/robot-loader +``` + +It requires PHP version 5.6 and supports PHP up to 7.2. + + +Usage +----- + +You just need to specifiy what directories to index and where to save the cache: + +```php +$loader = new Nette\Loaders\RobotLoader; + +// Add directories for RobotLoader to index +$loader->addDirectory(__DIR__ . '/app'); +$loader->addDirectory(__DIR__ . '/libs'); + +// And set caching to the 'temp' directory +$loader->setTempDirectory(__DIR__ . '/temp'); +$loader->register(); // Run the RobotLoader +``` + +And that's all. From now on, you don't need to use `require`. Great, isn't it? + +When RobotLoader encounters duplicate class name during indexing, it throws an exception and informs you about it. + +The `$loader->setAutoRefresh(true or false)` determines whether RobotLoader should reindex files if asked for nonexistent class. +This feature should be disabled on production server. + +If you want RobotLoader to skip some directory, use `$loader->excludeDirectory('temp')`. + +By default, RobotLoader reports errors in PHP files by throwing exception `ParseError` (since PHP 7.0). It can be disabled via `$loader->reportParseErrors(false)`. diff --git a/vendor/nette/robot-loader/src/RobotLoader/RobotLoader.php b/vendor/nette/robot-loader/src/RobotLoader/RobotLoader.php new file mode 100644 index 00000000..427ee59e --- /dev/null +++ b/vendor/nette/robot-loader/src/RobotLoader/RobotLoader.php @@ -0,0 +1,471 @@ + + * $loader = new Nette\Loaders\RobotLoader; + * $loader->addDirectory('app'); + * $loader->excludeDirectory('app/exclude'); + * $loader->setTempDirectory('temp'); + * $loader->register(); + * + */ +class RobotLoader +{ + use Nette\SmartObject; + + const RETRY_LIMIT = 3; + + /** @var array comma separated wildcards */ + public $ignoreDirs = ['.*', '*.old', '*.bak', '*.tmp', 'temp']; + + /** @var array comma separated wildcards */ + public $acceptFiles = ['*.php']; + + /** @var bool */ + private $autoRebuild = true; + + /** @var bool */ + private $reportParseErrors = true; + + /** @var array */ + private $scanPaths = []; + + /** @var array */ + private $excludeDirs = []; + + /** @var array of class => [file, time] */ + private $classes = []; + + /** @var bool */ + private $refreshed = false; + + /** @var array of missing classes */ + private $missing = []; + + /** @var string|null */ + private $tempDirectory; + + + public function __construct() + { + if (!extension_loaded('tokenizer')) { + throw new Nette\NotSupportedException('PHP extension Tokenizer is not loaded.'); + } + } + + + /** + * Register autoloader. + * @param bool $prepend + * @return static + */ + public function register($prepend = false) + { + $this->loadCache(); + spl_autoload_register([$this, 'tryLoad'], true, $prepend); + return $this; + } + + + /** + * Handles autoloading of classes, interfaces or traits. + * @param string $type + * @return void + */ + public function tryLoad($type) + { + $type = ltrim($type, '\\'); // PHP namespace bug #49143 + $info = isset($this->classes[$type]) ? $this->classes[$type] : null; + + if ($this->autoRebuild) { + if (!$info || !is_file($info['file'])) { + $missing = &$this->missing[$type]; + $missing++; + if (!$this->refreshed && $missing <= self::RETRY_LIMIT) { + $this->refresh(); + $this->saveCache(); + } elseif ($info) { + unset($this->classes[$type]); + $this->saveCache(); + } + + } elseif (!$this->refreshed && filemtime($info['file']) !== $info['time']) { + $this->updateFile($info['file']); + if (empty($this->classes[$type])) { + $this->missing[$type] = 0; + } + $this->saveCache(); + } + $info = isset($this->classes[$type]) ? $this->classes[$type] : null; + } + + if ($info) { + call_user_func(function ($file) { require $file; }, $info['file']); + } + } + + + /** + * Add path or paths to list. + * @param string|string[] $path absolute path + * @return static + */ + public function addDirectory($path) + { + $this->scanPaths = array_merge($this->scanPaths, (array) $path); + return $this; + } + + + /** + * @return static + */ + public function reportParseErrors($on = true) + { + $this->reportParseErrors = (bool) $on; + return $this; + } + + + /** + * Excludes path or paths from list. + * @param string|string[] $path absolute path + * @return static + */ + public function excludeDirectory($path) + { + $this->excludeDirs = array_merge($this->excludeDirs, (array) $path); + return $this; + } + + + /** + * @return array of class => filename + */ + public function getIndexedClasses() + { + $res = []; + foreach ($this->classes as $class => $info) { + $res[$class] = $info['file']; + } + return $res; + } + + + /** + * Rebuilds class list cache. + * @return void + */ + public function rebuild() + { + $this->refresh(); + if ($this->tempDirectory) { + $this->saveCache(); + } + } + + + /** + * Refreshes class list. + * @return void + */ + private function refresh() + { + $this->refreshed = true; // prevents calling refresh() or updateFile() in tryLoad() + $files = []; + foreach ($this->classes as $class => $info) { + $files[$info['file']]['time'] = $info['time']; + $files[$info['file']]['classes'][] = $class; + } + + $this->classes = []; + foreach ($this->scanPaths as $path) { + foreach (is_file($path) ? [new SplFileInfo($path)] : $this->createFileIterator($path) as $file) { + $file = $file->getPathname(); + if (isset($files[$file]) && $files[$file]['time'] == filemtime($file)) { + $classes = $files[$file]['classes']; + } else { + $classes = $this->scanPhp($file); + } + $files[$file] = ['classes' => [], 'time' => filemtime($file)]; + + foreach ($classes as $class) { + $info = &$this->classes[$class]; + if (isset($info['file'])) { + throw new Nette\InvalidStateException("Ambiguous class $class resolution; defined in {$info['file']} and in $file."); + } + $info = ['file' => $file, 'time' => filemtime($file)]; + unset($this->missing[$class]); + } + } + } + } + + + /** + * Creates an iterator scaning directory for PHP files, subdirectories and 'netterobots.txt' files. + * @return Nette\Utils\Finder + * @throws Nette\IOException if path is not found + */ + private function createFileIterator($dir) + { + if (!is_dir($dir)) { + throw new Nette\IOException("File or directory '$dir' not found."); + } + + $ignoreDirs = is_array($this->ignoreDirs) ? $this->ignoreDirs : preg_split('#[,\s]+#', $this->ignoreDirs); + $disallow = []; + foreach (array_merge($ignoreDirs, $this->excludeDirs) as $item) { + if ($item = realpath($item)) { + $disallow[str_replace('\\', '/', $item)] = true; + } + } + + $iterator = Nette\Utils\Finder::findFiles(is_array($this->acceptFiles) ? $this->acceptFiles : preg_split('#[,\s]+#', $this->acceptFiles)) + ->filter(function (SplFileInfo $file) use (&$disallow) { + return !isset($disallow[str_replace('\\', '/', $file->getRealPath())]); + }) + ->from($dir) + ->exclude($ignoreDirs) + ->filter($filter = function (SplFileInfo $dir) use (&$disallow) { + $path = str_replace('\\', '/', $dir->getRealPath()); + if (is_file("$path/netterobots.txt")) { + foreach (file("$path/netterobots.txt") as $s) { + if (preg_match('#^(?:disallow\\s*:)?\\s*(\\S+)#i', $s, $matches)) { + $disallow[$path . rtrim('/' . ltrim($matches[1], '/'), '/')] = true; + } + } + } + return !isset($disallow[$path]); + }); + + $filter(new SplFileInfo($dir)); + return $iterator; + } + + + /** + * @return void + */ + private function updateFile($file) + { + foreach ($this->classes as $class => $info) { + if (isset($info['file']) && $info['file'] === $file) { + unset($this->classes[$class]); + } + } + + $classes = is_file($file) ? $this->scanPhp($file) : []; + foreach ($classes as $class) { + $info = &$this->classes[$class]; + if (isset($info['file']) && @filemtime($info['file']) !== $info['time']) { // @ file may not exists + $this->updateFile($info['file']); + $info = &$this->classes[$class]; + } + if (isset($info['file'])) { + throw new Nette\InvalidStateException("Ambiguous class $class resolution; defined in {$info['file']} and in $file."); + } + $info = ['file' => $file, 'time' => filemtime($file)]; + } + } + + + /** + * Searches classes, interfaces and traits in PHP file. + * @param string $file + * @return string[] + */ + private function scanPhp($file) + { + $code = file_get_contents($file); + $expected = false; + $namespace = ''; + $level = $minLevel = 0; + $classes = []; + + if (preg_match('#//nette' . 'loader=(\S*)#', $code, $matches)) { + foreach (explode(',', $matches[1]) as $name) { + $classes[] = $name; + } + return $classes; + } + + + try { + $tokens = PHP_VERSION_ID >= 70000 + ? token_get_all($code, TOKEN_PARSE) + : @token_get_all($code); // @ can be corrupted or can use newer syntax + } catch (\ParseError $e) { + if ($this->reportParseErrors) { + $rp = new \ReflectionProperty($e, 'file'); + $rp->setAccessible(true); + $rp->setValue($e, $file); + throw $e; + } + $tokens = []; + } + + foreach ($tokens as $token) { + if (is_array($token)) { + switch ($token[0]) { + case T_COMMENT: + case T_DOC_COMMENT: + case T_WHITESPACE: + continue 2; + + case T_NS_SEPARATOR: + case T_STRING: + if ($expected) { + $name .= $token[1]; + } + continue 2; + + case T_NAMESPACE: + case T_CLASS: + case T_INTERFACE: + case T_TRAIT: + $expected = $token[0]; + $name = ''; + continue 2; + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + $level++; + } + } + + if ($expected) { + switch ($expected) { + case T_CLASS: + case T_INTERFACE: + case T_TRAIT: + if ($name && $level === $minLevel) { + $classes[] = $namespace . $name; + } + break; + + case T_NAMESPACE: + $namespace = $name ? $name . '\\' : ''; + $minLevel = $token === '{' ? 1 : 0; + } + + $expected = null; + } + + if ($token === '{') { + $level++; + } elseif ($token === '}') { + $level--; + } + } + return $classes; + } + + + /********************* caching ****************d*g**/ + + + /** + * Sets auto-refresh mode. + * @return static + */ + public function setAutoRefresh($on = true) + { + $this->autoRebuild = (bool) $on; + return $this; + } + + + /** + * Sets path to temporary directory. + * @return static + */ + public function setTempDirectory($dir) + { + Nette\Utils\FileSystem::createDir($dir); + $this->tempDirectory = $dir; + return $this; + } + + + /** + * Loads class list from cache. + * @return void + */ + private function loadCache() + { + $file = $this->getCacheFile(); + list($this->classes, $this->missing) = @include $file; // @ file may not exist + if (is_array($this->classes)) { + return; + } + + $handle = fopen("$file.lock", 'c+'); + if (!$handle || !flock($handle, LOCK_EX)) { + throw new \RuntimeException("Unable to create or acquire exclusive lock on file '$file.lock'."); + } + + list($this->classes, $this->missing) = @include $file; // @ file may not exist + if (!is_array($this->classes)) { + $this->classes = []; + $this->refresh(); + $this->saveCache(); + } + + flock($handle, LOCK_UN); + fclose($handle); + @unlink("$file.lock"); // @ file may become locked on Windows + } + + + /** + * Writes class list to cache. + * @return void + */ + private function saveCache() + { + $file = $this->getCacheFile(); + $tempFile = $file . uniqid('', true) . '.tmp'; + $code = "classes, $this->missing], true) . ";\n"; + if (file_put_contents($tempFile, $code) !== strlen($code) || !rename($tempFile, $file)) { + @unlink($tempFile); // @ - file may not exist + throw new \RuntimeException("Unable to create '$file'."); + } + if (function_exists('opcache_invalidate')) { + @opcache_invalidate($file, true); // @ can be restricted + } + } + + + /** + * @return string + */ + private function getCacheFile() + { + if (!$this->tempDirectory) { + throw new \LogicException('Set path to temporary directory using setTempDirectory().'); + } + return $this->tempDirectory . '/' . md5(serialize($this->getCacheKey())) . '.php'; + } + + + /** + * @return array + */ + protected function getCacheKey() + { + return [$this->ignoreDirs, $this->acceptFiles, $this->scanPaths, $this->excludeDirs]; + } +} diff --git a/vendor/nette/utils/composer.json b/vendor/nette/utils/composer.json new file mode 100644 index 00000000..c7a122ed --- /dev/null +++ b/vendor/nette/utils/composer.json @@ -0,0 +1,45 @@ +{ + "name": "nette/utils", + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "keywords": ["nette", "images", "json", "password", "validation", "utility", "string", "array", "core", "slugify", "utf-8", "unicode", "paginator", "datetime"], + "homepage": "https://nette.org", + "license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "require": { + "php": ">=5.6.0" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-iconv": "to use Strings::webalize() and toAscii()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-intl": "for script transliteration in Strings::webalize() and toAscii()", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-xml": "to use Strings::length() etc. when mbstring is not available", + "ext-gd": "to use Image" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "autoload": { + "classmap": ["src/"], + "files": ["src/loader.php"] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-master": "2.5-dev" + } + } +} diff --git a/vendor/nette/utils/contributing.md b/vendor/nette/utils/contributing.md new file mode 100644 index 00000000..184152c0 --- /dev/null +++ b/vendor/nette/utils/contributing.md @@ -0,0 +1,33 @@ +How to contribute & use the issue tracker +========================================= + +Nette welcomes your contributions. There are several ways to help out: + +* Create an issue on GitHub, if you have found a bug +* Write test cases for open bug issues +* Write fixes for open bug/feature issues, preferably with test cases included +* Contribute to the [documentation](https://nette.org/en/writing) + +Issues +------ + +Please **do not use the issue tracker to ask questions**. We will be happy to help you +on [Nette forum](https://forum.nette.org) or chat with us on [Gitter](https://gitter.im/nette/nette). + +A good bug report shouldn't leave others needing to chase you up for more +information. Please try to be as detailed as possible in your report. + +**Feature requests** are welcome. But take a moment to find out whether your idea +fits with the scope and aims of the project. It's up to *you* to make a strong +case to convince the project's developers of the merits of this feature. + +Contributing +------------ + +If you'd like to contribute, please take a moment to read [the contributing guide](https://nette.org/en/contributing). + +The best way to propose a feature is to discuss your ideas on [Nette forum](https://forum.nette.org) before implementing them. + +Please do not fix whitespace, format code, or make a purely cosmetic patch. + +Thanks! :heart: diff --git a/vendor/nette/utils/license.md b/vendor/nette/utils/license.md new file mode 100644 index 00000000..cf741bd0 --- /dev/null +++ b/vendor/nette/utils/license.md @@ -0,0 +1,60 @@ +Licenses +======== + +Good news! You may use Nette Framework under the terms of either +the New BSD License or the GNU General Public License (GPL) version 2 or 3. + +The BSD License is recommended for most projects. It is easy to understand and it +places almost no restrictions on what you can do with the framework. If the GPL +fits better to your project, you can use the framework under this license. + +You don't have to notify anyone which license you are using. You can freely +use Nette Framework in commercial projects as long as the copyright header +remains intact. + +Please be advised that the name "Nette Framework" is a protected trademark and its +usage has some limitations. So please do not use word "Nette" in the name of your +project or top-level domain, and choose a name that stands on its own merits. +If your stuff is good, it will not take long to establish a reputation for yourselves. + + +New BSD License +--------------- + +Copyright (c) 2004, 2014 David Grudl (https://davidgrudl.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of "Nette Framework" 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. + + +GNU General Public License +-------------------------- + +GPL licenses are very very long, so instead of including them here we offer +you URLs with full text: + +- [GPL version 2](http://www.gnu.org/licenses/gpl-2.0.html) +- [GPL version 3](http://www.gnu.org/licenses/gpl-3.0.html) diff --git a/vendor/nette/utils/readme.md b/vendor/nette/utils/readme.md new file mode 100644 index 00000000..3b6a0534 --- /dev/null +++ b/vendor/nette/utils/readme.md @@ -0,0 +1,154 @@ +Nette Utility Classes +===================== + +[![Downloads this Month](https://img.shields.io/packagist/dm/nette/utils.svg)](https://packagist.org/packages/nette/utils) +[![Build Status](https://travis-ci.org/nette/utils.svg?branch=master)](https://travis-ci.org/nette/utils) +[![Coverage Status](https://coveralls.io/repos/github/nette/utils/badge.svg?branch=master)](https://coveralls.io/github/nette/utils?branch=master) +[![Latest Stable Version](https://poser.pugx.org/nette/utils/v/stable)](https://github.com/nette/utils/releases) +[![License](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://github.com/nette/utils/blob/master/license.md) + +If you like Nette, **[please make a donation now](https://nette.org/donate)**. Thank you! + +Nette\SmartObject: Strict classes +--------------------------------- + +PHP gives a huge freedom to developers, which makes it a perfect language for making mistakes. But you can stop this bad behavior and start writing applications without hardly discoverable mistakes. Do you wonder how? It's really simple -- you just need to have stricter rules. + +Can you find an error in this example? + +```php +class Circle +{ + public $radius; + + public function getArea() + { + return $this->radius * $this->radius * M_PI; + } + +} + +$circle = new Circle; +$circle->raduis = 10; +echo $circle->getArea(); // 10² * π ≈ 314 +``` + +On the first look it seems that code will print out 314; but it returns 0. How is this even possible? Accidentaly, `$circle->radius` was mistyped to `raduis`. Just a small typo, which will give you a hard time correcting it, because PHP does not say a thing when something is wrong. Not even a Warning or Notice error message. Because PHP does not think it is an error. + +The mentioned mistake could be corrected immediately, if class `Circle` would use trait Nette\SmartObject: + +```php +class Circle +{ + use Nette\SmartObject; + ... +``` + +Whereas the former code executed successfully (although it contained an error), the latter did not: + +![](https://files.nette.org/git/doc-2.1/debugger-circle.png) + +Trait `Nette\SmartObject` made `Circle` more strict and threw an exception when you tried to access an undeclared property. And `Tracy\Debugger` displayed error message about it. Line of code with fatal typo is now highlighted and error message has meaningful description: *Cannot write to an undeclared property Circle::$raduis*. Programmer can now fix the mistake he might have otherwise missed and which could be a real pain to find later. + +One of many remarkable abilities of `Nette\SmartObject` is throwing exceptions when accessing undeclared members. + +```php +$circle = new Circle; +echo $circle->undeclared; // throws Nette\MemberAccessException +$circle->undeclared = 1; // throws Nette\MemberAccessException +$circle->unknownMethod(); // throws Nette\MemberAccessException +``` + +But it has much more to offer! + + +Properties, getters a setters +----------------------------- + +In modern object oriented languages *property* describes members of class, which look like variables but are represented by methods. When reading or assigning values to those "variables", methods are called instead (so-called getters and setters). It is really useful feature, which allows us to control the access to these variables. Using this we can validate inputs or postpone the computation of values of these variables to the time when it is actually accessed. + +Any class that uses `Nette\SmartObject` acquires the ability to imitate properties. Only thing you need to do is to keep simple convention: + +- Add annotation `@property type $xyz` +- Getter's name is `getXyz()` or `isXyz()`, setter's is `setXyz()` +- It is possible to have `@property-read` only and `@property-write` only properties +- Names of properties are case-sensitive (first letter being an exception) + +We will make use of properties in the class Circle to make sure variable `$radius` contains only non-negative numbers: + +```php +/** + * @property float $radius + * @property-read float $area + * @property-read bool $visible + */ +class Circle +{ + use Nette\SmartObject; + + private $radius; // not public anymore! + + protected function getRadius() + { + return $this->radius; + } + + protected function setRadius($radius) + { + // sanitizing value before saving it + $this->radius = max(0.0, (float) $radius); + } + + protected function getArea() + { + return $this->radius * $this->radius * M_PI; + } + + protected function isVisible() + { + return $this->radius > 0; + } + +} + +$circle = new Circle; +$circle->radius = 10; // calls setRadius() +echo $circle->area; // calls getArea() +echo $circle->visible; // calls $circle->isVisible() +``` + +Properties are mostly a syntactic sugar to beautify the code and make programmer's life easier. You do not have to use them, if you don't want to. + +Events +------ + +Now we are going to create functions, which will be called when border radius changes. Let's call it `change` event and those functions event handlers: + +```php +class Circle +{ + use Nette\SmartObject; + + /** @var array */ + public $onChange; + + public function setRadius($radius) + { + // call all handlers in array $onChange + $this->onChange($this, $this->radius, $radius); + + $this->radius = max(0.0, (float) $radius); + } +} + +$circle = new Circle; + +// adding an event handler +$circle->onChange[] = function ($circle, $oldValue, $newValue) { + echo 'there was a change!'; +}; + +$circle->setRadius(10); +``` + +There is another syntactic sugar in `setRadius`'s code. Instead of iteration on `$onChange` array and calling each method one by one with unreliable (does not report if callback has any errors) function call_user_func, you just have to write simple `onChange(...)` and given parameters will be handed over to the handlers. diff --git a/vendor/nette/utils/src/Iterators/CachingIterator.php b/vendor/nette/utils/src/Iterators/CachingIterator.php new file mode 100644 index 00000000..401b9751 --- /dev/null +++ b/vendor/nette/utils/src/Iterators/CachingIterator.php @@ -0,0 +1,175 @@ +getIterator(); + } while ($iterator instanceof \IteratorAggregate); + + } elseif ($iterator instanceof \Traversable) { + if (!$iterator instanceof \Iterator) { + $iterator = new \IteratorIterator($iterator); + } + } else { + throw new Nette\InvalidArgumentException(sprintf('Invalid argument passed to %s; array or Traversable expected, %s given.', __CLASS__, is_object($iterator) ? get_class($iterator) : gettype($iterator))); + } + + parent::__construct($iterator, 0); + } + + + /** + * Is the current element the first one? + * @param int grid width + * @return bool + */ + public function isFirst($width = null) + { + return $this->counter === 1 || ($width && $this->counter !== 0 && (($this->counter - 1) % $width) === 0); + } + + + /** + * Is the current element the last one? + * @param int grid width + * @return bool + */ + public function isLast($width = null) + { + return !$this->hasNext() || ($width && ($this->counter % $width) === 0); + } + + + /** + * Is the iterator empty? + * @return bool + */ + public function isEmpty() + { + return $this->counter === 0; + } + + + /** + * Is the counter odd? + * @return bool + */ + public function isOdd() + { + return $this->counter % 2 === 1; + } + + + /** + * Is the counter even? + * @return bool + */ + public function isEven() + { + return $this->counter % 2 === 0; + } + + + /** + * Returns the counter. + * @return int + */ + public function getCounter() + { + return $this->counter; + } + + + /** + * Returns the count of elements. + * @return int + */ + public function count() + { + $inner = $this->getInnerIterator(); + if ($inner instanceof \Countable) { + return $inner->count(); + + } else { + throw new Nette\NotSupportedException('Iterator is not countable.'); + } + } + + + /** + * Forwards to the next element. + * @return void + */ + public function next() + { + parent::next(); + if (parent::valid()) { + $this->counter++; + } + } + + + /** + * Rewinds the Iterator. + * @return void + */ + public function rewind() + { + parent::rewind(); + $this->counter = parent::valid() ? 1 : 0; + } + + + /** + * Returns the next key. + * @return mixed + */ + public function getNextKey() + { + return $this->getInnerIterator()->key(); + } + + + /** + * Returns the next element. + * @return mixed + */ + public function getNextValue() + { + return $this->getInnerIterator()->current(); + } +} diff --git a/vendor/nette/utils/src/Iterators/Mapper.php b/vendor/nette/utils/src/Iterators/Mapper.php new file mode 100644 index 00000000..47b810a3 --- /dev/null +++ b/vendor/nette/utils/src/Iterators/Mapper.php @@ -0,0 +1,32 @@ +callback = $callback; + } + + + public function current() + { + return call_user_func($this->callback, parent::current(), parent::key()); + } +} diff --git a/vendor/nette/utils/src/Utils/ArrayHash.php b/vendor/nette/utils/src/Utils/ArrayHash.php new file mode 100644 index 00000000..91caad70 --- /dev/null +++ b/vendor/nette/utils/src/Utils/ArrayHash.php @@ -0,0 +1,99 @@ + $value) { + if ($recursive && is_array($value)) { + $obj->$key = static::from($value, true); + } else { + $obj->$key = $value; + } + } + return $obj; + } + + + /** + * Returns an iterator over all items. + * @return \RecursiveArrayIterator + */ + public function getIterator() + { + return new \RecursiveArrayIterator((array) $this); + } + + + /** + * Returns items count. + * @return int + */ + public function count() + { + return count((array) $this); + } + + + /** + * Replaces or appends a item. + * @return void + */ + public function offsetSet($key, $value) + { + if (!is_scalar($key)) { // prevents null + throw new Nette\InvalidArgumentException(sprintf('Key must be either a string or an integer, %s given.', gettype($key))); + } + $this->$key = $value; + } + + + /** + * Returns a item. + * @return mixed + */ + public function offsetGet($key) + { + return $this->$key; + } + + + /** + * Determines whether a item exists. + * @return bool + */ + public function offsetExists($key) + { + return isset($this->$key); + } + + + /** + * Removes the element from this list. + * @return void + */ + public function offsetUnset($key) + { + unset($this->$key); + } +} diff --git a/vendor/nette/utils/src/Utils/ArrayList.php b/vendor/nette/utils/src/Utils/ArrayList.php new file mode 100644 index 00000000..471716a4 --- /dev/null +++ b/vendor/nette/utils/src/Utils/ArrayList.php @@ -0,0 +1,125 @@ +list); + } + + + /** + * Returns items count. + * @return int + */ + public function count() + { + return count($this->list); + } + + + /** + * Replaces or appends a item. + * @param int|null + * @param mixed + * @return void + * @throws Nette\OutOfRangeException + */ + public function offsetSet($index, $value) + { + if ($index !== null && !is_int($index)) { + trigger_error('Index is not integer.', E_USER_NOTICE); + } + if ($index === null) { + $this->list[] = $value; + + } elseif ($index < 0 || $index >= count($this->list)) { + throw new Nette\OutOfRangeException('Offset invalid or out of range'); + + } else { + $this->list[(int) $index] = $value; + } + } + + + /** + * Returns a item. + * @param int + * @return mixed + * @throws Nette\OutOfRangeException + */ + public function offsetGet($index) + { + if (!is_int($index)) { + trigger_error('Index is not integer.', E_USER_NOTICE); + } + if ($index < 0 || $index >= count($this->list)) { + throw new Nette\OutOfRangeException('Offset invalid or out of range'); + } + return $this->list[(int) $index]; + } + + + /** + * Determines whether a item exists. + * @param int + * @return bool + */ + public function offsetExists($index) + { + return $index >= 0 && $index < count($this->list); + } + + + /** + * Removes the element at the specified position in this list. + * @param int + * @return void + * @throws Nette\OutOfRangeException + */ + public function offsetUnset($index) + { + if (!is_int($index)) { + trigger_error('Index is not integer.', E_USER_NOTICE); + } + if ($index < 0 || $index >= count($this->list)) { + throw new Nette\OutOfRangeException('Offset invalid or out of range'); + } + array_splice($this->list, (int) $index, 1); + } + + + /** + * Prepends a item. + * @param mixed + * @return void + */ + public function prepend($value) + { + $first = array_slice($this->list, 0, 1); + $this->offsetSet(0, $value); + array_splice($this->list, 1, 0, $first); + } +} diff --git a/vendor/nette/utils/src/Utils/Arrays.php b/vendor/nette/utils/src/Utils/Arrays.php new file mode 100644 index 00000000..e69461b6 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Arrays.php @@ -0,0 +1,296 @@ + $v) { + if (is_array($v) && is_array($arr2[$k])) { + $res[$k] = self::mergeTree($v, $arr2[$k]); + } + } + return $res; + } + + + /** + * Searches the array for a given key and returns the offset if successful. + * @return int|false offset if it is found, false otherwise + */ + public static function searchKey(array $arr, $key) + { + $foo = [$key => null]; + return array_search(key($foo), array_keys($arr), true); + } + + + /** + * Inserts new array before item specified by key. + * @return void + */ + public static function insertBefore(array &$arr, $key, array $inserted) + { + $offset = (int) self::searchKey($arr, $key); + $arr = array_slice($arr, 0, $offset, true) + $inserted + array_slice($arr, $offset, count($arr), true); + } + + + /** + * Inserts new array after item specified by key. + * @return void + */ + public static function insertAfter(array &$arr, $key, array $inserted) + { + $offset = self::searchKey($arr, $key); + $offset = $offset === false ? count($arr) : $offset + 1; + $arr = array_slice($arr, 0, $offset, true) + $inserted + array_slice($arr, $offset, count($arr), true); + } + + + /** + * Renames key in array. + * @return void + */ + public static function renameKey(array &$arr, $oldKey, $newKey) + { + $offset = self::searchKey($arr, $oldKey); + if ($offset !== false) { + $keys = array_keys($arr); + $keys[$offset] = $newKey; + $arr = array_combine($keys, $arr); + } + } + + + /** + * Returns array entries that match the pattern. + * @return array + */ + public static function grep(array $arr, $pattern, $flags = 0) + { + return Strings::pcre('preg_grep', [$pattern, $arr, $flags]); + } + + + /** + * Returns flattened array. + * @return array + */ + public static function flatten(array $arr, $preserveKeys = false) + { + $res = []; + $cb = $preserveKeys + ? function ($v, $k) use (&$res) { $res[$k] = $v; } + : function ($v) use (&$res) { $res[] = $v; }; + array_walk_recursive($arr, $cb); + return $res; + } + + + /** + * Finds whether a variable is a zero-based integer indexed array. + * @return bool + */ + public static function isList($value) + { + return is_array($value) && (!$value || array_keys($value) === range(0, count($value) - 1)); + } + + + /** + * Reformats table to associative tree. Path looks like 'field|field[]field->field=field'. + * @return array|\stdClass + */ + public static function associate(array $arr, $path) + { + $parts = is_array($path) + ? $path + : preg_split('#(\[\]|->|=|\|)#', $path, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); + + if (!$parts || $parts[0] === '=' || $parts[0] === '|' || $parts === ['->']) { + throw new Nette\InvalidArgumentException("Invalid path '$path'."); + } + + $res = $parts[0] === '->' ? new \stdClass : []; + + foreach ($arr as $rowOrig) { + $row = (array) $rowOrig; + $x = &$res; + + for ($i = 0; $i < count($parts); $i++) { + $part = $parts[$i]; + if ($part === '[]') { + $x = &$x[]; + + } elseif ($part === '=') { + if (isset($parts[++$i])) { + $x = $row[$parts[$i]]; + $row = null; + } + + } elseif ($part === '->') { + if (isset($parts[++$i])) { + $x = &$x->{$row[$parts[$i]]}; + } else { + $row = is_object($rowOrig) ? $rowOrig : (object) $row; + } + + } elseif ($part !== '|') { + $x = &$x[(string) $row[$part]]; + } + } + + if ($x === null) { + $x = $row; + } + } + + return $res; + } + + + /** + * Normalizes to associative array. + * @return array + */ + public static function normalize(array $arr, $filling = null) + { + $res = []; + foreach ($arr as $k => $v) { + $res[is_int($k) ? $v : $k] = is_int($k) ? $filling : $v; + } + return $res; + } + + + /** + * Picks element from the array by key and return its value. + * @param array + * @param string|int array key + * @param mixed + * @return mixed + * @throws Nette\InvalidArgumentException if item does not exist and default value is not provided + */ + public static function pick(array &$arr, $key, $default = null) + { + if (array_key_exists($key, $arr)) { + $value = $arr[$key]; + unset($arr[$key]); + return $value; + + } elseif (func_num_args() < 3) { + throw new Nette\InvalidArgumentException("Missing item '$key'."); + + } else { + return $default; + } + } + + + /** + * Tests whether some element in the array passes the callback test. + * @return bool + */ + public static function some(array $arr, callable $callback) + { + foreach ($arr as $k => $v) { + if ($callback($v, $k, $arr)) { + return true; + } + } + return false; + } + + + /** + * Tests whether all elements in the array pass the callback test. + * @return bool + */ + public static function every(array $arr, callable $callback) + { + foreach ($arr as $k => $v) { + if (!$callback($v, $k, $arr)) { + return false; + } + } + return true; + } + + + /** + * Applies the callback to the elements of the array. + * @return array + */ + public static function map(array $arr, callable $callback) + { + $res = []; + foreach ($arr as $k => $v) { + $res[$k] = $callback($v, $k, $arr); + } + return $res; + } +} diff --git a/vendor/nette/utils/src/Utils/Callback.php b/vendor/nette/utils/src/Utils/Callback.php new file mode 100644 index 00000000..64e47eaf --- /dev/null +++ b/vendor/nette/utils/src/Utils/Callback.php @@ -0,0 +1,197 @@ +getClosure(); + + } elseif (is_array($callable) && method_exists($callable[0], $callable[1])) { + return (new \ReflectionMethod($callable[0], $callable[1]))->getClosure($callable[0]); + } + + self::check($callable); + $_callable_ = $callable; + return function (...$args) use ($_callable_) { + return $_callable_(...$args); + }; + } + + + /** + * Invokes callback. + * @return mixed + * @deprecated + */ + public static function invoke($callable, ...$args) + { + self::check($callable); + return call_user_func_array($callable, $args); + } + + + /** + * Invokes callback with an array of parameters. + * @return mixed + * @deprecated + */ + public static function invokeArgs($callable, array $args = []) + { + self::check($callable); + return call_user_func_array($callable, $args); + } + + + /** + * Invokes internal PHP function with own error handler. + * @param string + * @return mixed + */ + public static function invokeSafe($function, array $args, $onError) + { + $prev = set_error_handler(function ($severity, $message, $file) use ($onError, &$prev, $function) { + if ($file === '' && defined('HHVM_VERSION')) { // https://github.com/facebook/hhvm/issues/4625 + $file = func_get_arg(5)[1]['file']; + } + if ($file === __FILE__) { + $msg = $message; + if (ini_get('html_errors')) { + $msg = html_entity_decode(strip_tags($msg)); + } + $msg = preg_replace("#^$function\(.*?\): #", '', $msg); + if ($onError($msg, $severity) !== false) { + return; + } + } + return $prev ? $prev(...func_get_args()) : false; + }); + + try { + return call_user_func_array($function, $args); + } finally { + restore_error_handler(); + } + } + + + /** + * @return callable + */ + public static function check($callable, $syntax = false) + { + if (!is_callable($callable, $syntax)) { + throw new Nette\InvalidArgumentException($syntax + ? 'Given value is not a callable type.' + : sprintf("Callback '%s' is not callable.", self::toString($callable)) + ); + } + return $callable; + } + + + /** + * @return string + */ + public static function toString($callable) + { + if ($callable instanceof \Closure) { + $inner = self::unwrap($callable); + return '{closure' . ($inner instanceof \Closure ? '}' : ' ' . self::toString($inner) . '}'); + } elseif (is_string($callable) && $callable[0] === "\0") { + return '{lambda}'; + } else { + is_callable(is_object($callable) ? [$callable, '__invoke'] : $callable, true, $textual); + return $textual; + } + } + + + /** + * @return \ReflectionMethod|\ReflectionFunction + */ + public static function toReflection($callable) + { + if ($callable instanceof \Closure) { + $callable = self::unwrap($callable); + } + + $class = class_exists(Nette\Reflection\Method::class) ? Nette\Reflection\Method::class : 'ReflectionMethod'; + if (is_string($callable) && strpos($callable, '::')) { + return new $class($callable); + } elseif (is_array($callable)) { + return new $class($callable[0], $callable[1]); + } elseif (is_object($callable) && !$callable instanceof \Closure) { + return new $class($callable, '__invoke'); + } else { + $class = class_exists(Nette\Reflection\GlobalFunction::class) ? Nette\Reflection\GlobalFunction::class : 'ReflectionFunction'; + return new $class($callable); + } + } + + + /** + * @return bool + */ + public static function isStatic($callable) + { + return is_array($callable) ? is_string($callable[0]) : is_string($callable); + } + + + /** + * Unwraps closure created by self::closure() + * @internal + * @return callable + */ + public static function unwrap(\Closure $closure) + { + $r = new \ReflectionFunction($closure); + if (substr($r->getName(), -1) === '}') { + $vars = $r->getStaticVariables(); + return isset($vars['_callable_']) ? $vars['_callable_'] : $closure; + + } elseif ($obj = $r->getClosureThis()) { + return [$obj, $r->getName()]; + + } elseif ($class = $r->getClosureScopeClass()) { + return [$class->getName(), $r->getName()]; + + } else { + return $r->getName(); + } + } +} diff --git a/vendor/nette/utils/src/Utils/DateTime.php b/vendor/nette/utils/src/Utils/DateTime.php new file mode 100644 index 00000000..42b989c7 --- /dev/null +++ b/vendor/nette/utils/src/Utils/DateTime.php @@ -0,0 +1,149 @@ +format('Y-m-d H:i:s.u'), $time->getTimezone()); + + } elseif (is_numeric($time)) { + if ($time <= self::YEAR) { + $time += time(); + } + return (new static('@' . $time))->setTimezone(new \DateTimeZone(date_default_timezone_get())); + + } else { // textual or null + return new static($time); + } + } + + + /** + * Creates DateTime object. + * @return static + */ + public static function fromParts($year, $month, $day, $hour = 0, $minute = 0, $second = 0) + { + $s = sprintf('%04d-%02d-%02d %02d:%02d:%02.5f', $year, $month, $day, $hour, $minute, $second); + if (!checkdate($month, $day, $year) || $hour < 0 || $hour > 23 || $minute < 0 || $minute > 59 || $second < 0 || $second >= 60) { + throw new Nette\InvalidArgumentException("Invalid date '$s'"); + } + return new static($s); + } + + + /** + * Returns new DateTime object formatted according to the specified format. + * @param string The format the $time parameter should be in + * @param string String representing the time + * @param string|\DateTimeZone desired timezone (default timezone is used if null is passed) + * @return static|false + */ + public static function createFromFormat($format, $time, $timezone = null) + { + if ($timezone === null) { + $timezone = new \DateTimeZone(date_default_timezone_get()); + + } elseif (is_string($timezone)) { + $timezone = new \DateTimeZone($timezone); + + } elseif (!$timezone instanceof \DateTimeZone) { + throw new Nette\InvalidArgumentException('Invalid timezone given'); + } + + $date = parent::createFromFormat($format, $time, $timezone); + return $date ? static::from($date) : false; + } + + + /** + * Returns JSON representation in ISO 8601 (used by JavaScript). + * @return string + */ + public function jsonSerialize() + { + return $this->format('c'); + } + + + /** + * @return string + */ + public function __toString() + { + return $this->format('Y-m-d H:i:s'); + } + + + /** + * @param string + * @return static + */ + public function modifyClone($modify = '') + { + $dolly = clone $this; + return $modify ? $dolly->modify($modify) : $dolly; + } + + + /** + * @param int + * @return static + */ + public function setTimestamp($timestamp) + { + $zone = $this->getTimezone(); + $this->__construct('@' . $timestamp); + return $this->setTimezone($zone); + } + + + /** + * @return int|string + */ + public function getTimestamp() + { + $ts = $this->format('U'); + return is_float($tmp = $ts * 1) ? $ts : $tmp; + } +} diff --git a/vendor/nette/utils/src/Utils/FileSystem.php b/vendor/nette/utils/src/Utils/FileSystem.php new file mode 100644 index 00000000..166d1a03 --- /dev/null +++ b/vendor/nette/utils/src/Utils/FileSystem.php @@ -0,0 +1,164 @@ +getPathname()); + } + foreach ($iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item) { + if ($item->isDir()) { + static::createDir($dest . '/' . $iterator->getSubPathName()); + } else { + static::copy($item->getPathname(), $dest . '/' . $iterator->getSubPathName()); + } + } + + } else { + static::createDir(dirname($dest)); + if (@stream_copy_to_stream(fopen($source, 'r'), fopen($dest, 'w')) === false) { // @ is escalated to exception + throw new Nette\IOException("Unable to copy file '$source' to '$dest'. " . self::getLastError()); + } + } + } + + + /** + * Deletes a file or directory. + * @return void + * @throws Nette\IOException + */ + public static function delete($path) + { + if (is_file($path) || is_link($path)) { + $func = DIRECTORY_SEPARATOR === '\\' && is_dir($path) ? 'rmdir' : 'unlink'; + if (!@$func($path)) { // @ is escalated to exception + throw new Nette\IOException("Unable to delete '$path'. " . self::getLastError()); + } + + } elseif (is_dir($path)) { + foreach (new \FilesystemIterator($path) as $item) { + static::delete($item->getPathname()); + } + if (!@rmdir($path)) { // @ is escalated to exception + throw new Nette\IOException("Unable to delete directory '$path'. " . self::getLastError()); + } + } + } + + + /** + * Renames a file or directory. + * @return void + * @throws Nette\IOException + * @throws Nette\InvalidStateException if the target file or directory already exist + */ + public static function rename($name, $newName, $overwrite = true) + { + if (!$overwrite && file_exists($newName)) { + throw new Nette\InvalidStateException("File or directory '$newName' already exists."); + + } elseif (!file_exists($name)) { + throw new Nette\IOException("File or directory '$name' not found."); + + } else { + static::createDir(dirname($newName)); + if (realpath($name) !== realpath($newName)) { + static::delete($newName); + } + if (!@rename($name, $newName)) { // @ is escalated to exception + throw new Nette\IOException("Unable to rename file or directory '$name' to '$newName'. " . self::getLastError()); + } + } + } + + + /** + * Reads file content. + * @return string + * @throws Nette\IOException + */ + public static function read($file) + { + $content = @file_get_contents($file); // @ is escalated to exception + if ($content === false) { + throw new Nette\IOException("Unable to read file '$file'. " . self::getLastError()); + } + return $content; + } + + + /** + * Writes a string to a file. + * @return void + * @throws Nette\IOException + */ + public static function write($file, $content, $mode = 0666) + { + static::createDir(dirname($file)); + if (@file_put_contents($file, $content) === false) { // @ is escalated to exception + throw new Nette\IOException("Unable to write file '$file'. " . self::getLastError()); + } + if ($mode !== null && !@chmod($file, $mode)) { // @ is escalated to exception + throw new Nette\IOException("Unable to chmod file '$file'. " . self::getLastError()); + } + } + + + /** + * Is path absolute? + * @return bool + */ + public static function isAbsolute($path) + { + return (bool) preg_match('#([a-z]:)?[/\\\\]|[a-z][a-z0-9+.-]*://#Ai', $path); + } + + + private static function getLastError() + { + return preg_replace('#^\w+\(.*?\): #', '', error_get_last()['message']); + } +} diff --git a/vendor/nette/utils/src/Utils/Html.php b/vendor/nette/utils/src/Utils/Html.php new file mode 100644 index 00000000..d2dd6206 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Html.php @@ -0,0 +1,668 @@ + + * $el = Html::el('a')->href($link)->setText('Nette'); + * $el->class = 'myclass'; + * echo $el; + * + * echo $el->startTag(), $el->endTag(); + * + */ +class Html implements \ArrayAccess, \Countable, \IteratorAggregate, IHtmlString +{ + use Nette\SmartObject; + + /** @var array element's attributes */ + public $attrs = []; + + /** @var bool use XHTML syntax? */ + public static $xhtml = false; + + /** @var array empty (void) elements */ + public static $emptyElements = [ + 'img' => 1, 'hr' => 1, 'br' => 1, 'input' => 1, 'meta' => 1, 'area' => 1, 'embed' => 1, 'keygen' => 1, + 'source' => 1, 'base' => 1, 'col' => 1, 'link' => 1, 'param' => 1, 'basefont' => 1, 'frame' => 1, + 'isindex' => 1, 'wbr' => 1, 'command' => 1, 'track' => 1, + ]; + + /** @var array of Html | string nodes */ + protected $children = []; + + /** @var string element's name */ + private $name; + + /** @var bool is element empty? */ + private $isEmpty; + + + /** + * Static factory. + * @param string element name (or null) + * @param array|string element's attributes or plain text content + * @return static + */ + public static function el($name = null, $attrs = null) + { + $el = new static; + $parts = explode(' ', (string) $name, 2); + $el->setName($parts[0]); + + if (is_array($attrs)) { + $el->attrs = $attrs; + + } elseif ($attrs !== null) { + $el->setText($attrs); + } + + if (isset($parts[1])) { + foreach (Strings::matchAll($parts[1] . ' ', '#([a-z0-9:-]+)(?:=(["\'])?(.*?)(?(2)\\2|\s))?#i') as $m) { + $el->attrs[$m[1]] = isset($m[3]) ? $m[3] : true; + } + } + + return $el; + } + + + /** + * Changes element's name. + * @param string + * @param bool Is element empty? + * @return static + * @throws Nette\InvalidArgumentException + */ + public function setName($name, $isEmpty = null) + { + if ($name !== null && !is_string($name)) { + throw new Nette\InvalidArgumentException(sprintf('Name must be string or null, %s given.', gettype($name))); + } + + $this->name = $name; + $this->isEmpty = $isEmpty === null ? isset(static::$emptyElements[$name]) : (bool) $isEmpty; + return $this; + } + + + /** + * Returns element's name. + * @return string + */ + public function getName() + { + return $this->name; + } + + + /** + * Is element empty? + * @return bool + */ + public function isEmpty() + { + return $this->isEmpty; + } + + + /** + * Sets multiple attributes. + * @param array + * @return static + */ + public function addAttributes(array $attrs) + { + $this->attrs = array_merge($this->attrs, $attrs); + return $this; + } + + + /** + * Appends value to element's attribute. + * @param string + * @param string|array value to append + * @param string|bool value option + * @return static + */ + public function appendAttribute($name, $value, $option = true) + { + if (is_array($value)) { + $prev = isset($this->attrs[$name]) ? (array) $this->attrs[$name] : []; + $this->attrs[$name] = $value + $prev; + + } elseif ((string) $value === '') { + $tmp = &$this->attrs[$name]; // appending empty value? -> ignore, but ensure it exists + + } elseif (!isset($this->attrs[$name]) || is_array($this->attrs[$name])) { // needs array + $this->attrs[$name][$value] = $option; + + } else { + $this->attrs[$name] = [$this->attrs[$name] => true, $value => $option]; + } + return $this; + } + + + /** + * Sets element's attribute. + * @param string + * @param mixed + * @return static + */ + public function setAttribute($name, $value) + { + $this->attrs[$name] = $value; + return $this; + } + + + /** + * Returns element's attribute. + * @param string + * @return mixed + */ + public function getAttribute($name) + { + return isset($this->attrs[$name]) ? $this->attrs[$name] : null; + } + + + /** + * Unsets element's attribute. + * @param string + * @return static + */ + public function removeAttribute($name) + { + unset($this->attrs[$name]); + return $this; + } + + + /** + * Unsets element's attributes. + * @return static + */ + public function removeAttributes(array $attributes) + { + foreach ($attributes as $name) { + unset($this->attrs[$name]); + } + return $this; + } + + + /** + * Overloaded setter for element's attribute. + * @param string HTML attribute name + * @param mixed HTML attribute value + * @return void + */ + public function __set($name, $value) + { + $this->attrs[$name] = $value; + } + + + /** + * Overloaded getter for element's attribute. + * @param string HTML attribute name + * @return mixed HTML attribute value + */ + public function &__get($name) + { + return $this->attrs[$name]; + } + + + /** + * Overloaded tester for element's attribute. + * @param string HTML attribute name + * @return bool + */ + public function __isset($name) + { + return isset($this->attrs[$name]); + } + + + /** + * Overloaded unsetter for element's attribute. + * @param string HTML attribute name + * @return void + */ + public function __unset($name) + { + unset($this->attrs[$name]); + } + + + /** + * Overloaded setter for element's attribute. + * @param string HTML attribute name + * @param array (string) HTML attribute value or pair? + * @return mixed + */ + public function __call($m, $args) + { + $p = substr($m, 0, 3); + if ($p === 'get' || $p === 'set' || $p === 'add') { + $m = substr($m, 3); + $m[0] = $m[0] | "\x20"; + if ($p === 'get') { + return isset($this->attrs[$m]) ? $this->attrs[$m] : null; + + } elseif ($p === 'add') { + $args[] = true; + } + } + + if (count($args) === 0) { // invalid + + } elseif (count($args) === 1) { // set + $this->attrs[$m] = $args[0]; + + } else { // add + $this->appendAttribute($m, $args[0], $args[1]); + } + + return $this; + } + + + /** + * Special setter for element's attribute. + * @param string path + * @param array query + * @return static + */ + public function href($path, $query = null) + { + if ($query) { + $query = http_build_query($query, '', '&'); + if ($query !== '') { + $path .= '?' . $query; + } + } + $this->attrs['href'] = $path; + return $this; + } + + + /** + * Setter for data-* attributes. Booleans are converted to 'true' resp. 'false'. + * @return static + */ + public function data($name, $value = null) + { + if (func_num_args() === 1) { + $this->attrs['data'] = $name; + } else { + $this->attrs["data-$name"] = is_bool($value) ? json_encode($value) : $value; + } + return $this; + } + + + /** + * Sets element's HTML content. + * @param IHtmlString|string + * @return static + * @throws Nette\InvalidArgumentException + */ + public function setHtml($html) + { + if (is_array($html)) { + throw new Nette\InvalidArgumentException(sprintf('Textual content must be a scalar, %s given.', gettype($html))); + } + $this->removeChildren(); + $this->children[] = (string) $html; + return $this; + } + + + /** + * Returns element's HTML content. + * @return string + */ + public function getHtml() + { + return implode('', $this->children); + } + + + /** + * Sets element's textual content. + * @param IHtmlString|string + * @return static + */ + public function setText($text) + { + if (!$text instanceof IHtmlString) { + $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); + } + return $this->setHtml($text); + } + + + /** + * Returns element's textual content. + * @return string + */ + public function getText() + { + return html_entity_decode(strip_tags($this->getHtml()), ENT_QUOTES, 'UTF-8'); + } + + + /** + * Adds new element's child. + * @param IHtmlString|string Html node or raw HTML string + * @return static + */ + public function addHtml($child) + { + return $this->insert(null, $child); + } + + + /** + * Appends plain-text string to element content. + * @param IHtmlString|string|int|float + * @return static + */ + public function addText($text) + { + if (!$text instanceof IHtmlString) { + $text = htmlspecialchars((string) $text, ENT_NOQUOTES, 'UTF-8'); + } + return $this->insert(null, $text); + } + + + /** + * Creates and adds a new Html child. + * @param string elements's name + * @param array|string element's attributes or raw HTML string + * @return static created element + */ + public function create($name, $attrs = null) + { + $this->insert(null, $child = static::el($name, $attrs)); + return $child; + } + + + /** + * Inserts child node. + * @param int|null position or null for appending + * @param IHtmlString|string Html node or raw HTML string + * @param bool + * @return static + * @throws Nette\InvalidArgumentException + */ + public function insert($index, $child, $replace = false) + { + if ($child instanceof IHtmlString || is_scalar($child)) { + $child = $child instanceof self ? $child : (string) $child; + if ($index === null) { // append + $this->children[] = $child; + + } else { // insert or replace + array_splice($this->children, (int) $index, $replace ? 1 : 0, [$child]); + } + + } else { + throw new Nette\InvalidArgumentException(sprintf('Child node must be scalar or Html object, %s given.', is_object($child) ? get_class($child) : gettype($child))); + } + + return $this; + } + + + /** + * Inserts (replaces) child node (\ArrayAccess implementation). + * @param int|null position or null for appending + * @param Html|string Html node or raw HTML string + * @return void + */ + public function offsetSet($index, $child) + { + $this->insert($index, $child, true); + } + + + /** + * Returns child node (\ArrayAccess implementation). + * @param int + * @return static|string + */ + public function offsetGet($index) + { + return $this->children[$index]; + } + + + /** + * Exists child node? (\ArrayAccess implementation). + * @param int + * @return bool + */ + public function offsetExists($index) + { + return isset($this->children[$index]); + } + + + /** + * Removes child node (\ArrayAccess implementation). + * @param int + * @return void + */ + public function offsetUnset($index) + { + if (isset($this->children[$index])) { + array_splice($this->children, (int) $index, 1); + } + } + + + /** + * Returns children count. + * @return int + */ + public function count() + { + return count($this->children); + } + + + /** + * Removes all children. + * @return void + */ + public function removeChildren() + { + $this->children = []; + } + + + /** + * Iterates over elements. + * @return \ArrayIterator + */ + public function getIterator() + { + return new \ArrayIterator($this->children); + } + + + /** + * Returns all children. + * @return array + */ + public function getChildren() + { + return $this->children; + } + + + /** + * Renders element's start tag, content and end tag. + * @param int + * @return string + */ + public function render($indent = null) + { + $s = $this->startTag(); + + if (!$this->isEmpty) { + // add content + if ($indent !== null) { + $indent++; + } + foreach ($this->children as $child) { + if ($child instanceof self) { + $s .= $child->render($indent); + } else { + $s .= $child; + } + } + + // add end tag + $s .= $this->endTag(); + } + + if ($indent !== null) { + return "\n" . str_repeat("\t", $indent - 1) . $s . "\n" . str_repeat("\t", max(0, $indent - 2)); + } + return $s; + } + + + public function __toString() + { + try { + return $this->render(); + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); + } + + + /** + * Returns element's start tag. + * @return string + */ + public function startTag() + { + if ($this->name) { + return '<' . $this->name . $this->attributes() . (static::$xhtml && $this->isEmpty ? ' />' : '>'); + + } else { + return ''; + } + } + + + /** + * Returns element's end tag. + * @return string + */ + public function endTag() + { + return $this->name && !$this->isEmpty ? 'name . '>' : ''; + } + + + /** + * Returns element's attributes. + * @return string + * @internal + */ + public function attributes() + { + if (!is_array($this->attrs)) { + return ''; + } + + $s = ''; + $attrs = $this->attrs; + foreach ($attrs as $key => $value) { + if ($value === null || $value === false) { + continue; + + } elseif ($value === true) { + if (static::$xhtml) { + $s .= ' ' . $key . '="' . $key . '"'; + } else { + $s .= ' ' . $key; + } + continue; + + } elseif (is_array($value)) { + if (strncmp($key, 'data-', 5) === 0) { + $value = Json::encode($value); + + } else { + $tmp = null; + foreach ($value as $k => $v) { + if ($v != null) { // intentionally ==, skip nulls & empty string + // composite 'style' vs. 'others' + $tmp[] = $v === true ? $k : (is_string($k) ? $k . ':' . $v : $v); + } + } + if ($tmp === null) { + continue; + } + + $value = implode($key === 'style' || !strncmp($key, 'on', 2) ? ';' : ' ', $tmp); + } + + } elseif (is_float($value)) { + $value = rtrim(rtrim(number_format($value, 10, '.', ''), '0'), '.'); + + } else { + $value = (string) $value; + } + + $q = strpos($value, '"') === false ? '"' : "'"; + $s .= ' ' . $key . '=' . $q + . str_replace( + ['&', $q, '<'], + ['&', $q === '"' ? '"' : ''', self::$xhtml ? '<' : '<'], + $value + ) + . (strpos($value, '`') !== false && strpbrk($value, ' <>"\'') === false ? ' ' : '') + . $q; + } + + $s = str_replace('@', '@', $s); + return $s; + } + + + /** + * Clones all children too. + */ + public function __clone() + { + foreach ($this->children as $key => $value) { + if (is_object($value)) { + $this->children[$key] = clone $value; + } + } + } +} diff --git a/vendor/nette/utils/src/Utils/IHtmlString.php b/vendor/nette/utils/src/Utils/IHtmlString.php new file mode 100644 index 00000000..943349e2 --- /dev/null +++ b/vendor/nette/utils/src/Utils/IHtmlString.php @@ -0,0 +1,18 @@ + + * $image = Image::fromFile('nette.jpg'); + * $image->resize(150, 100); + * $image->sharpen(); + * $image->send(); + * + * + * @method void alphaBlending(bool $on) + * @method void antialias(bool $on) + * @method void arc($x, $y, $w, $h, $start, $end, $color) + * @method void char(int $font, $x, $y, string $char, $color) + * @method void charUp(int $font, $x, $y, string $char, $color) + * @method int colorAllocate($red, $green, $blue) + * @method int colorAllocateAlpha($red, $green, $blue, $alpha) + * @method int colorAt($x, $y) + * @method int colorClosest($red, $green, $blue) + * @method int colorClosestAlpha($red, $green, $blue, $alpha) + * @method int colorClosestHWB($red, $green, $blue) + * @method void colorDeallocate($color) + * @method int colorExact($red, $green, $blue) + * @method int colorExactAlpha($red, $green, $blue, $alpha) + * @method void colorMatch(Image $image2) + * @method int colorResolve($red, $green, $blue) + * @method int colorResolveAlpha($red, $green, $blue, $alpha) + * @method void colorSet($index, $red, $green, $blue) + * @method array colorsForIndex($index) + * @method int colorsTotal() + * @method int colorTransparent($color = null) + * @method void convolution(array $matrix, float $div, float $offset) + * @method void copy(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH) + * @method void copyMerge(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH, $opacity) + * @method void copyMergeGray(Image $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH, $opacity) + * @method void copyResampled(Image $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH) + * @method void copyResized(Image $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH) + * @method Image cropAuto(int $mode = -1, float $threshold = .5, int $color = -1) + * @method void dashedLine($x1, $y1, $x2, $y2, $color) + * @method void ellipse($cx, $cy, $w, $h, $color) + * @method void fill($x, $y, $color) + * @method void filledArc($cx, $cy, $w, $h, $s, $e, $color, $style) + * @method void filledEllipse($cx, $cy, $w, $h, $color) + * @method void filledPolygon(array $points, $numPoints, $color) + * @method void filledRectangle($x1, $y1, $x2, $y2, $color) + * @method void fillToBorder($x, $y, $border, $color) + * @method void filter($filtertype) + * @method void flip(int $mode) + * @method array ftText($size, $angle, $x, $y, $col, string $fontFile, string $text, array $extrainfo = null) + * @method void gammaCorrect(float $inputgamma, float $outputgamma) + * @method int interlace($interlace = null) + * @method bool isTrueColor() + * @method void layerEffect($effect) + * @method void line($x1, $y1, $x2, $y2, $color) + * @method void paletteCopy(Image $source) + * @method void paletteToTrueColor() + * @method void polygon(array $points, $numPoints, $color) + * @method array psText(string $text, $font, $size, $color, $backgroundColor, $x, $y, $space = null, $tightness = null, float $angle = null, $antialiasSteps = null) + * @method void rectangle($x1, $y1, $x2, $y2, $col) + * @method Image rotate(float $angle, $backgroundColor) + * @method void saveAlpha(bool $saveflag) + * @method Image scale(int $newWidth, int $newHeight = -1, int $mode = IMG_BILINEAR_FIXED) + * @method void setBrush(Image $brush) + * @method void setPixel($x, $y, $color) + * @method void setStyle(array $style) + * @method void setThickness($thickness) + * @method void setTile(Image $tile) + * @method void string($font, $x, $y, string $s, $col) + * @method void stringUp($font, $x, $y, string $s, $col) + * @method void trueColorToPalette(bool $dither, $ncolors) + * @method array ttfText($size, $angle, $x, $y, $color, string $fontfile, string $text) + * @property-read int $width + * @property-read int $height + * @property-read resource $imageResource + */ +class Image +{ + use Nette\SmartObject; + + /** {@link resize()} only shrinks images */ + const SHRINK_ONLY = 0b0001; + + /** {@link resize()} will ignore aspect ratio */ + const STRETCH = 0b0010; + + /** {@link resize()} fits in given area so its dimensions are less than or equal to the required dimensions */ + const FIT = 0b0000; + + /** {@link resize()} fills given area so its dimensions are greater than or equal to the required dimensions */ + const FILL = 0b0100; + + /** {@link resize()} fills given area exactly */ + const EXACT = 0b1000; + + /** image types */ + const + JPEG = IMAGETYPE_JPEG, + PNG = IMAGETYPE_PNG, + GIF = IMAGETYPE_GIF, + WEBP = 18; // IMAGETYPE_WEBP is available as of PHP 7.1 + + const EMPTY_GIF = "GIF89a\x01\x00\x01\x00\x80\x00\x00\x00\x00\x00\x00\x00\x00!\xf9\x04\x01\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;"; + + private static $formats = [self::JPEG => 'jpeg', self::PNG => 'png', self::GIF => 'gif', self::WEBP => 'webp']; + + /** @var resource */ + private $image; + + + /** + * Returns RGB color. + * @param int red 0..255 + * @param int green 0..255 + * @param int blue 0..255 + * @param int transparency 0..127 + * @return array + */ + public static function rgb($red, $green, $blue, $transparency = 0) + { + return [ + 'red' => max(0, min(255, (int) $red)), + 'green' => max(0, min(255, (int) $green)), + 'blue' => max(0, min(255, (int) $blue)), + 'alpha' => max(0, min(127, (int) $transparency)), + ]; + } + + + /** + * Opens image from file. + * @param string + * @param mixed detected image format + * @throws Nette\NotSupportedException if gd extension is not loaded + * @throws UnknownImageFileException if file not found or file type is not known + * @return static + */ + public static function fromFile($file, &$format = null) + { + if (!extension_loaded('gd')) { + throw new Nette\NotSupportedException('PHP extension GD is not loaded.'); + } + + $format = @getimagesize($file)[2]; // @ - files smaller than 12 bytes causes read error + if (!$format && PHP_VERSION_ID < 70100 && @file_get_contents($file, false, null, 8, 4) === 'WEBP') { // @ - may not exists + $format = self::WEBP; + } + if (!isset(self::$formats[$format])) { + $format = null; + throw new UnknownImageFileException(is_file($file) ? "Unknown type of file '$file'." : "File '$file' not found."); + } + return new static(Callback::invokeSafe('imagecreatefrom' . self::$formats[$format], [$file], function ($message) { + throw new ImageException($message); + })); + } + + + /** + * Create a new image from the image stream in the string. + * @param string + * @param mixed detected image format + * @return static + * @throws ImageException + */ + public static function fromString($s, &$format = null) + { + if (!extension_loaded('gd')) { + throw new Nette\NotSupportedException('PHP extension GD is not loaded.'); + } + + if (func_num_args() > 1) { + $tmp = @getimagesizefromstring($s)[2]; // @ - strings smaller than 12 bytes causes read error + $format = isset(self::$formats[$tmp]) ? $tmp : null; + } + + return new static(Callback::invokeSafe('imagecreatefromstring', [$s], function ($message) { + throw new ImageException($message); + })); + } + + + /** + * Creates blank image. + * @param int + * @param int + * @param array + * @return static + */ + public static function fromBlank($width, $height, $color = null) + { + if (!extension_loaded('gd')) { + throw new Nette\NotSupportedException('PHP extension GD is not loaded.'); + } + + $width = (int) $width; + $height = (int) $height; + if ($width < 1 || $height < 1) { + throw new Nette\InvalidArgumentException('Image width and height must be greater than zero.'); + } + + $image = imagecreatetruecolor($width, $height); + if (is_array($color)) { + $color += ['alpha' => 0]; + $color = imagecolorresolvealpha($image, $color['red'], $color['green'], $color['blue'], $color['alpha']); + imagealphablending($image, false); + imagefilledrectangle($image, 0, 0, $width - 1, $height - 1, $color); + imagealphablending($image, true); + } + return new static($image); + } + + + /** + * Wraps GD image. + * @param resource + */ + public function __construct($image) + { + $this->setImageResource($image); + imagesavealpha($image, true); + } + + + /** + * Returns image width. + * @return int + */ + public function getWidth() + { + return imagesx($this->image); + } + + + /** + * Returns image height. + * @return int + */ + public function getHeight() + { + return imagesy($this->image); + } + + + /** + * Sets image resource. + * @param resource + * @return static + */ + protected function setImageResource($image) + { + if (!is_resource($image) || get_resource_type($image) !== 'gd') { + throw new Nette\InvalidArgumentException('Image is not valid.'); + } + $this->image = $image; + return $this; + } + + + /** + * Returns image GD resource. + * @return resource + */ + public function getImageResource() + { + return $this->image; + } + + + /** + * Resizes image. + * @param mixed width in pixels or percent + * @param mixed height in pixels or percent + * @param int flags + * @return static + */ + public function resize($width, $height, $flags = self::FIT) + { + if ($flags & self::EXACT) { + return $this->resize($width, $height, self::FILL)->crop('50%', '50%', $width, $height); + } + + list($newWidth, $newHeight) = static::calculateSize($this->getWidth(), $this->getHeight(), $width, $height, $flags); + + if ($newWidth !== $this->getWidth() || $newHeight !== $this->getHeight()) { // resize + $newImage = static::fromBlank($newWidth, $newHeight, self::rgb(0, 0, 0, 127))->getImageResource(); + imagecopyresampled( + $newImage, $this->image, + 0, 0, 0, 0, + $newWidth, $newHeight, $this->getWidth(), $this->getHeight() + ); + $this->image = $newImage; + } + + if ($width < 0 || $height < 0) { + imageflip($this->image, $width < 0 ? ($height < 0 ? IMG_FLIP_BOTH : IMG_FLIP_HORIZONTAL) : IMG_FLIP_VERTICAL); + } + return $this; + } + + + /** + * Calculates dimensions of resized image. + * @param mixed source width + * @param mixed source height + * @param mixed width in pixels or percent + * @param mixed height in pixels or percent + * @param int flags + * @return array + */ + public static function calculateSize($srcWidth, $srcHeight, $newWidth, $newHeight, $flags = self::FIT) + { + if (is_string($newWidth) && substr($newWidth, -1) === '%') { + $newWidth = (int) round($srcWidth / 100 * abs(substr($newWidth, 0, -1))); + $percents = true; + } else { + $newWidth = (int) abs($newWidth); + } + + if (is_string($newHeight) && substr($newHeight, -1) === '%') { + $newHeight = (int) round($srcHeight / 100 * abs(substr($newHeight, 0, -1))); + $flags |= empty($percents) ? 0 : self::STRETCH; + } else { + $newHeight = (int) abs($newHeight); + } + + if ($flags & self::STRETCH) { // non-proportional + if (empty($newWidth) || empty($newHeight)) { + throw new Nette\InvalidArgumentException('For stretching must be both width and height specified.'); + } + + if ($flags & self::SHRINK_ONLY) { + $newWidth = (int) round($srcWidth * min(1, $newWidth / $srcWidth)); + $newHeight = (int) round($srcHeight * min(1, $newHeight / $srcHeight)); + } + + } else { // proportional + if (empty($newWidth) && empty($newHeight)) { + throw new Nette\InvalidArgumentException('At least width or height must be specified.'); + } + + $scale = []; + if ($newWidth > 0) { // fit width + $scale[] = $newWidth / $srcWidth; + } + + if ($newHeight > 0) { // fit height + $scale[] = $newHeight / $srcHeight; + } + + if ($flags & self::FILL) { + $scale = [max($scale)]; + } + + if ($flags & self::SHRINK_ONLY) { + $scale[] = 1; + } + + $scale = min($scale); + $newWidth = (int) round($srcWidth * $scale); + $newHeight = (int) round($srcHeight * $scale); + } + + return [max($newWidth, 1), max($newHeight, 1)]; + } + + + /** + * Crops image. + * @param mixed x-offset in pixels or percent + * @param mixed y-offset in pixels or percent + * @param mixed width in pixels or percent + * @param mixed height in pixels or percent + * @return static + */ + public function crop($left, $top, $width, $height) + { + list($r['x'], $r['y'], $r['width'], $r['height']) + = static::calculateCutout($this->getWidth(), $this->getHeight(), $left, $top, $width, $height); + if (PHP_VERSION_ID > 50611) { // PHP bug #67447 + $this->image = imagecrop($this->image, $r); + } else { + $newImage = static::fromBlank($r['width'], $r['height'], self::RGB(0, 0, 0, 127))->getImageResource(); + imagecopy($newImage, $this->image, 0, 0, $r['x'], $r['y'], $r['width'], $r['height']); + $this->image = $newImage; + } + return $this; + } + + + /** + * Calculates dimensions of cutout in image. + * @param mixed source width + * @param mixed source height + * @param mixed x-offset in pixels or percent + * @param mixed y-offset in pixels or percent + * @param mixed width in pixels or percent + * @param mixed height in pixels or percent + * @return array + */ + public static function calculateCutout($srcWidth, $srcHeight, $left, $top, $newWidth, $newHeight) + { + if (is_string($newWidth) && substr($newWidth, -1) === '%') { + $newWidth = (int) round($srcWidth / 100 * substr($newWidth, 0, -1)); + } + if (is_string($newHeight) && substr($newHeight, -1) === '%') { + $newHeight = (int) round($srcHeight / 100 * substr($newHeight, 0, -1)); + } + if (is_string($left) && substr($left, -1) === '%') { + $left = (int) round(($srcWidth - $newWidth) / 100 * substr($left, 0, -1)); + } + if (is_string($top) && substr($top, -1) === '%') { + $top = (int) round(($srcHeight - $newHeight) / 100 * substr($top, 0, -1)); + } + if ($left < 0) { + $newWidth += $left; + $left = 0; + } + if ($top < 0) { + $newHeight += $top; + $top = 0; + } + $newWidth = min($newWidth, $srcWidth - $left); + $newHeight = min($newHeight, $srcHeight - $top); + return [$left, $top, $newWidth, $newHeight]; + } + + + /** + * Sharpen image. + * @return static + */ + public function sharpen() + { + imageconvolution($this->image, [ // my magic numbers ;) + [-1, -1, -1], + [-1, 24, -1], + [-1, -1, -1], + ], 16, 0); + return $this; + } + + + /** + * Puts another image into this image. + * @param Image + * @param mixed x-coordinate in pixels or percent + * @param mixed y-coordinate in pixels or percent + * @param int opacity 0..100 + * @return static + */ + public function place(self $image, $left = 0, $top = 0, $opacity = 100) + { + $opacity = max(0, min(100, (int) $opacity)); + if ($opacity === 0) { + return $this; + } + + $width = $image->getWidth(); + $height = $image->getHeight(); + + if (is_string($left) && substr($left, -1) === '%') { + $left = (int) round(($this->getWidth() - $width) / 100 * substr($left, 0, -1)); + } + + if (is_string($top) && substr($top, -1) === '%') { + $top = (int) round(($this->getHeight() - $height) / 100 * substr($top, 0, -1)); + } + + $output = $input = $image->image; + if ($opacity < 100) { + $tbl = []; + for ($i = 0; $i < 128; $i++) { + $tbl[$i] = round(127 - (127 - $i) * $opacity / 100); + } + + $output = imagecreatetruecolor($width, $height); + imagealphablending($output, false); + if (!$image->isTrueColor()) { + $input = $output; + imagefilledrectangle($output, 0, 0, $width, $height, imagecolorallocatealpha($output, 0, 0, 0, 127)); + imagecopy($output, $image->image, 0, 0, 0, 0, $width, $height); + } + for ($x = 0; $x < $width; $x++) { + for ($y = 0; $y < $height; $y++) { + $c = \imagecolorat($input, $x, $y); + $c = ($c & 0xFFFFFF) + ($tbl[$c >> 24] << 24); + \imagesetpixel($output, $x, $y, $c); + } + } + imagealphablending($output, true); + } + + imagecopy( + $this->image, $output, + $left, $top, 0, 0, $width, $height + ); + return $this; + } + + + /** + * Saves image to the file. + * @param string filename + * @param int quality (0..100 for JPEG and WEBP, 0..9 for PNG) + * @param int optional image type + * @return bool true on success or false on failure. + */ + public function save($file = null, $quality = null, $type = null) + { + if ($type === null) { + if ($file === null) { + throw new Nette\InvalidArgumentException('Either the output file or type must be set.'); + } + $extensions = array_flip(self::$formats) + ['jpg' => self::JPEG]; + $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); + if (!isset($extensions[$ext])) { + throw new Nette\InvalidArgumentException("Unsupported file extension '$ext'."); + } + $type = $extensions[$ext]; + } + + switch ($type) { + case self::JPEG: + $quality = $quality === null ? 85 : max(0, min(100, (int) $quality)); + return imagejpeg($this->image, $file, $quality); + + case self::PNG: + $quality = $quality === null ? 9 : max(0, min(9, (int) $quality)); + return imagepng($this->image, $file, $quality); + + case self::GIF: + return imagegif($this->image, $file); + + case self::WEBP: + $quality = $quality === null ? 80 : max(0, min(100, (int) $quality)); + return imagewebp($this->image, $file, $quality); + + default: + throw new Nette\InvalidArgumentException("Unsupported image type '$type'."); + } + } + + + /** + * Outputs image to string. + * @param int image type + * @param int quality (0..100 for JPEG and WEBP, 0..9 for PNG) + * @return string + */ + public function toString($type = self::JPEG, $quality = null) + { + ob_start(function () {}); + $this->save(null, $quality, $type); + return ob_get_clean(); + } + + + /** + * Outputs image to string. + * @return string + */ + public function __toString() + { + try { + return $this->toString(); + } catch (\Exception $e) { + } catch (\Throwable $e) { + } + if (isset($e)) { + if (func_num_args()) { + throw $e; + } + trigger_error('Exception in ' . __METHOD__ . "(): {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}", E_USER_ERROR); + } + } + + + /** + * Outputs image to browser. + * @param int image type + * @param int quality (0..100 for JPEG and WEBP, 0..9 for PNG) + * @return bool true on success or false on failure. + */ + public function send($type = self::JPEG, $quality = null) + { + if (!isset(self::$formats[$type])) { + throw new Nette\InvalidArgumentException("Unsupported image type '$type'."); + } + header('Content-Type: image/' . self::$formats[$type]); + return $this->save(null, $quality, $type); + } + + + /** + * Call to undefined method. + * + * @param string method name + * @param array arguments + * @return mixed + * @throws Nette\MemberAccessException + */ + public function __call($name, $args) + { + $function = 'image' . $name; + if (!function_exists($function)) { + ObjectHelpers::strictCall(get_class($this), $name); + } + + foreach ($args as $key => $value) { + if ($value instanceof self) { + $args[$key] = $value->getImageResource(); + + } elseif (is_array($value) && isset($value['red'])) { // rgb + $args[$key] = imagecolorallocatealpha( + $this->image, + $value['red'], $value['green'], $value['blue'], $value['alpha'] + ) ?: imagecolorresolvealpha( + $this->image, + $value['red'], $value['green'], $value['blue'], $value['alpha'] + ); + } + } + $res = $function($this->image, ...$args); + return is_resource($res) && get_resource_type($res) === 'gd' ? $this->setImageResource($res) : $res; + } + + + public function __clone() + { + ob_start(function () {}); + imagegd2($this->image); + $this->setImageResource(imagecreatefromstring(ob_get_clean())); + } + + + /** + * Prevents serialization. + */ + public function __sleep() + { + throw new Nette\NotSupportedException('You cannot serialize or unserialize ' . self::class . ' instances.'); + } +} diff --git a/vendor/nette/utils/src/Utils/Json.php b/vendor/nette/utils/src/Utils/Json.php new file mode 100644 index 00000000..2bc88612 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Json.php @@ -0,0 +1,81 @@ + + * $val = $obj->label; // equivalent to $val = $obj->getLabel(); + * $obj->label = 'Nette'; // equivalent to $obj->setLabel('Nette'); + * + * Property names are case-sensitive, and they are written in the camelCaps + * or PascalCaps. + * + * Event functionality is provided by declaration of property named 'on{Something}' + * Multiple handlers are allowed. + * + * public $onClick; // declaration in class + * $this->onClick[] = 'callback'; // attaching event handler + * if (!empty($this->onClick)) ... // are there any handlers? + * $this->onClick($sender, $arg); // raises the event with arguments + * + * + * Adding method to class (i.e. to all instances) works similar to JavaScript + * prototype property. The syntax for adding a new method is: + * + * MyClass::extensionMethod('newMethod', function (MyClass $obj, $arg, ...) { ... }); + * $obj = new MyClass; + * $obj->newMethod($x); + * + * + * @property-read Nette\Reflection\ClassType|\ReflectionClass $reflection + * @deprecated use trait Nette\SmartObject + */ +abstract class LegacyObject +{ + + /** + * Access to reflection. + * @return Nette\Reflection\ClassType|\ReflectionClass + */ + public static function getReflection() + { + $class = class_exists(Nette\Reflection\ClassType::class) ? Nette\Reflection\ClassType::class : 'ReflectionClass'; + return new $class(get_called_class()); + } + + + /** + * Call to undefined method. + * @param string method name + * @param array arguments + * @return mixed + * @throws MemberAccessException + */ + public function __call($name, $args) + { + return @Nette\Utils\ObjectMixin::call($this, $name, $args); // is deprecated + } + + + /** + * Call to undefined static method. + * @param string method name (in lower case!) + * @param array arguments + * @return mixed + * @throws MemberAccessException + */ + public static function __callStatic($name, $args) + { + return @Nette\Utils\ObjectMixin::callStatic(get_called_class(), $name, $args); // is deprecated + } + + + /** + * Adding method to class. + * @param string method name + * @param callable + * @return mixed + */ + public static function extensionMethod($name, $callback = null) + { + trigger_error('Class Nette\Object and extension methods are deprecated', E_USER_DEPRECATED); + if (strpos($name, '::') === false) { + $class = get_called_class(); + } else { + list($class, $name) = explode('::', $name); + $class = (new \ReflectionClass($class))->getName(); + } + if ($callback === null) { + return Nette\Utils\ObjectMixin::getExtensionMethod($class, $name); + } else { + Nette\Utils\ObjectMixin::setExtensionMethod($class, $name, $callback); + } + } + + + /** + * Returns property value. Do not call directly. + * @param string property name + * @return mixed property value + * @throws MemberAccessException if the property is not defined. + */ + public function &__get($name) + { + return Nette\Utils\ObjectMixin::get($this, $name); + } + + + /** + * Sets value of a property. Do not call directly. + * @param string property name + * @param mixed property value + * @return void + * @throws MemberAccessException if the property is not defined or is read-only + */ + public function __set($name, $value) + { + @Nette\Utils\ObjectMixin::set($this, $name, $value); // is deprecated + } + + + /** + * Is property defined? + * @param string property name + * @return bool + */ + public function __isset($name) + { + return @Nette\Utils\ObjectMixin::has($this, $name); // is deprecated + } + + + /** + * Access to undeclared property. + * @param string property name + * @return void + * @throws MemberAccessException + */ + public function __unset($name) + { + @Nette\Utils\ObjectMixin::remove($this, $name); // is deprecated + } +} diff --git a/vendor/nette/utils/src/Utils/ObjectHelpers.php b/vendor/nette/utils/src/Utils/ObjectHelpers.php new file mode 100644 index 00000000..297f8e3f --- /dev/null +++ b/vendor/nette/utils/src/Utils/ObjectHelpers.php @@ -0,0 +1,184 @@ +getProperties(\ReflectionProperty::IS_PUBLIC), function ($p) { return !$p->isStatic(); }), + self::parseFullDoc($rc, '~^[ \t*]*@property(?:-read)?[ \t]+(?:\S+[ \t]+)??\$(\w+)~m') + ), $name); + throw new MemberAccessException("Cannot read an undeclared property $class::\$$name" . ($hint ? ", did you mean \$$hint?" : '.')); + } + + + /** + * @throws MemberAccessException + */ + public static function strictSet($class, $name) + { + $rc = new \ReflectionClass($class); + $hint = self::getSuggestion(array_merge( + array_filter($rc->getProperties(\ReflectionProperty::IS_PUBLIC), function ($p) { return !$p->isStatic(); }), + self::parseFullDoc($rc, '~^[ \t*]*@property(?:-write)?[ \t]+(?:\S+[ \t]+)??\$(\w+)~m') + ), $name); + throw new MemberAccessException("Cannot write to an undeclared property $class::\$$name" . ($hint ? ", did you mean \$$hint?" : '.')); + } + + + /** + * @throws MemberAccessException + */ + public static function strictCall($class, $method, $additionalMethods = []) + { + $hint = self::getSuggestion(array_merge( + get_class_methods($class), + self::parseFullDoc(new \ReflectionClass($class), '~^[ \t*]*@method[ \t]+(?:\S+[ \t]+)??(\w+)\(~m'), + $additionalMethods + ), $method); + + if (method_exists($class, $method)) { // called parent::$method() + $class = 'parent'; + } + throw new MemberAccessException("Call to undefined method $class::$method()" . ($hint ? ", did you mean $hint()?" : '.')); + } + + + /** + * @throws MemberAccessException + */ + public static function strictStaticCall($class, $method) + { + $hint = self::getSuggestion( + array_filter((new \ReflectionClass($class))->getMethods(\ReflectionMethod::IS_PUBLIC), function ($m) { return $m->isStatic(); }), + $method + ); + throw new MemberAccessException("Call to undefined static method $class::$method()" . ($hint ? ", did you mean $hint()?" : '.')); + } + + + /** + * Returns array of magic properties defined by annotation @property. + * @return array of [name => bit mask] + * @internal + */ + public static function getMagicProperties($class) + { + static $cache; + $props = &$cache[$class]; + if ($props !== null) { + return $props; + } + + $rc = new \ReflectionClass($class); + preg_match_all( + '~^ [ \t*]* @property(|-read|-write) [ \t]+ [^\s$]+ [ \t]+ \$ (\w+) ()~mx', + (string) $rc->getDocComment(), $matches, PREG_SET_ORDER + ); + + $props = []; + foreach ($matches as list(, $type, $name)) { + $uname = ucfirst($name); + $write = $type !== '-read' + && $rc->hasMethod($nm = 'set' . $uname) + && ($rm = $rc->getMethod($nm)) && $rm->getName() === $nm && !$rm->isPrivate() && !$rm->isStatic(); + $read = $type !== '-write' + && ($rc->hasMethod($nm = 'get' . $uname) || $rc->hasMethod($nm = 'is' . $uname)) + && ($rm = $rc->getMethod($nm)) && $rm->getName() === $nm && !$rm->isPrivate() && !$rm->isStatic(); + + if ($read || $write) { + $props[$name] = $read << 0 | ($nm[0] === 'g') << 1 | $rm->returnsReference() << 2 | $write << 3; + } + } + + foreach ($rc->getTraits() as $trait) { + $props += self::getMagicProperties($trait->getName()); + } + + if ($parent = get_parent_class($class)) { + $props += self::getMagicProperties($parent); + } + return $props; + } + + + /** + * Finds the best suggestion (for 8-bit encoding). + * @param (\ReflectionFunctionAbstract|\ReflectionParameter|\ReflectionClass|\ReflectionProperty|string)[] + * @internal + */ + public static function getSuggestion(array $possibilities, $value) + { + $norm = preg_replace($re = '#^(get|set|has|is|add)(?=[A-Z])#', '', $value); + $best = null; + $min = (strlen($value) / 4 + 1) * 10 + .1; + foreach (array_unique($possibilities, SORT_REGULAR) as $item) { + $item = $item instanceof \Reflector ? $item->getName() : $item; + if ($item !== $value && ( + ($len = levenshtein($item, $value, 10, 11, 10)) < $min + || ($len = levenshtein(preg_replace($re, '', $item), $norm, 10, 11, 10) + 20) < $min + )) { + $min = $len; + $best = $item; + } + } + return $best; + } + + + private static function parseFullDoc(\ReflectionClass $rc, $pattern) + { + do { + $doc[] = $rc->getDocComment(); + $traits = $rc->getTraits(); + while ($trait = array_pop($traits)) { + $doc[] = $trait->getDocComment(); + $traits += $trait->getTraits(); + } + } while ($rc = $rc->getParentClass()); + return preg_match_all($pattern, implode($doc), $m) ? $m[1] : []; + } + + + /** + * Checks if the public non-static property exists. + * @return bool|string returns 'event' if the property exists and has event like name + * @internal + */ + public static function hasProperty($class, $name) + { + static $cache; + $prop = &$cache[$class][$name]; + if ($prop === null) { + $prop = false; + try { + $rp = new \ReflectionProperty($class, $name); + if ($rp->isPublic() && !$rp->isStatic()) { + $prop = $name >= 'onA' && $name < 'on_' ? 'event' : true; + } + } catch (\ReflectionException $e) { + } + } + return $prop; + } +} diff --git a/vendor/nette/utils/src/Utils/ObjectMixin.php b/vendor/nette/utils/src/Utils/ObjectMixin.php new file mode 100644 index 00000000..8bfa904b --- /dev/null +++ b/vendor/nette/utils/src/Utils/ObjectMixin.php @@ -0,0 +1,493 @@ + [type => callback]] used by extension methods */ + private static $extMethods = []; + + + /********************* strictness ****************d*g**/ + + + /** + * @deprecated use ObjectHelpers::strictGet() + */ + public static function strictGet($class, $name) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + ObjectHelpers::strictGet($class, $name); + } + + + /** + * @deprecated use ObjectHelpers::strictSet() + */ + public static function strictSet($class, $name) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + ObjectHelpers::strictSet($class, $name); + } + + + /** + * @deprecated use ObjectHelpers::strictCall() + */ + public static function strictCall($class, $method, $additionalMethods = []) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + ObjectHelpers::strictCall($class, $method, $additionalMethods); + } + + + /** + * @deprecated use ObjectHelpers::strictStaticCall() + */ + public static function strictStaticCall($class, $method) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + ObjectHelpers::strictStaticCall($class, $method); + } + + + /********************* Nette\Object ****************d*g**/ + + + /** + * __call() implementation. + * @param object + * @param string + * @param array + * @return mixed + * @throws MemberAccessException + */ + public static function call($_this, $name, $args) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + $class = get_class($_this); + $isProp = ObjectHelpers::hasProperty($class, $name); + + if ($name === '') { + throw new MemberAccessException("Call to class '$class' method without name."); + + } elseif ($isProp === 'event') { // calling event handlers + if (is_array($_this->$name) || $_this->$name instanceof \Traversable) { + foreach ($_this->$name as $handler) { + Callback::invokeArgs($handler, $args); + } + } elseif ($_this->$name !== null) { + throw new Nette\UnexpectedValueException("Property $class::$$name must be array or null, " . gettype($_this->$name) . ' given.'); + } + + } elseif ($isProp && $_this->$name instanceof \Closure) { // closure in property + return call_user_func_array($_this->$name, $args); + + } elseif (($methods = &self::getMethods($class)) && isset($methods[$name]) && is_array($methods[$name])) { // magic @methods + list($op, $rp, $type) = $methods[$name]; + if (count($args) !== ($op === 'get' ? 0 : 1)) { + throw new Nette\InvalidArgumentException("$class::$name() expects " . ($op === 'get' ? 'no' : '1') . ' argument, ' . count($args) . ' given.'); + + } elseif ($type && $args && !self::checkType($args[0], $type)) { + throw new Nette\InvalidArgumentException("Argument passed to $class::$name() must be $type, " . gettype($args[0]) . ' given.'); + } + + if ($op === 'get') { + return $rp->getValue($_this); + } elseif ($op === 'set') { + $rp->setValue($_this, $args[0]); + } elseif ($op === 'add') { + $val = $rp->getValue($_this); + $val[] = $args[0]; + $rp->setValue($_this, $val); + } + return $_this; + + } elseif ($cb = self::getExtensionMethod($class, $name)) { // extension methods + return Callback::invoke($cb, $_this, ...$args); + + } else { + ObjectHelpers::strictCall($class, $name, array_keys(self::getExtensionMethods($class))); + } + } + + + /** + * __callStatic() implementation. + * @param string + * @param string + * @param array + * @return void + * @throws MemberAccessException + */ + public static function callStatic($class, $method, $args) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + self::strictStaticCall($class, $method); + } + + + /** + * __get() implementation. + * @param object + * @param string property name + * @return mixed property value + * @throws MemberAccessException if the property is not defined. + */ + public static function &get($_this, $name) + { + $class = get_class($_this); + $uname = ucfirst($name); + $methods = &self::getMethods($class); + + if ($name === '') { + throw new MemberAccessException("Cannot read a class '$class' property without name."); + + } elseif (isset($methods[$m = 'get' . $uname]) || isset($methods[$m = 'is' . $uname])) { // property getter + if ($methods[$m] === 0) { + $methods[$m] = (new \ReflectionMethod($class, $m))->returnsReference(); + } + if ($methods[$m] === true) { + return $_this->$m(); + } else { + $val = $_this->$m(); + return $val; + } + + } elseif (isset($methods[$name])) { // public method as closure getter + if (preg_match('#^(is|get|has)([A-Z]|$)#', $name) && !(new \ReflectionMethod($class, $name))->getNumberOfRequiredParameters()) { + trigger_error("Did you forget parentheses after $name" . self::getSource() . '?', E_USER_WARNING); + } + $val = Callback::closure($_this, $name); + return $val; + + } elseif (isset($methods['set' . $uname])) { // property getter + throw new MemberAccessException("Cannot read a write-only property $class::\$$name."); + + } else { + ObjectHelpers::strictGet($class, $name); + } + } + + + /** + * __set() implementation. + * @param object + * @param string property name + * @param mixed property value + * @return void + * @throws MemberAccessException if the property is not defined or is read-only + */ + public static function set($_this, $name, $value) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + $class = get_class($_this); + $uname = ucfirst($name); + $methods = &self::getMethods($class); + + if ($name === '') { + throw new MemberAccessException("Cannot write to a class '$class' property without name."); + + } elseif (ObjectHelpers::hasProperty($class, $name)) { // unsetted property + $_this->$name = $value; + + } elseif (isset($methods[$m = 'set' . $uname])) { // property setter + $_this->$m($value); + + } elseif (isset($methods['get' . $uname]) || isset($methods['is' . $uname])) { // property setter + throw new MemberAccessException("Cannot write to a read-only property $class::\$$name."); + + } else { + ObjectHelpers::strictSet($class, $name); + } + } + + + /** + * __unset() implementation. + * @param object + * @param string property name + * @return void + * @throws MemberAccessException + */ + public static function remove($_this, $name) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + $class = get_class($_this); + if (!ObjectHelpers::hasProperty($class, $name)) { + throw new MemberAccessException("Cannot unset the property $class::\$$name."); + } + } + + + /** + * __isset() implementation. + * @param object + * @param string property name + * @return bool + */ + public static function has($_this, $name) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + $name = ucfirst($name); + $methods = &self::getMethods(get_class($_this)); + return $name !== '' && (isset($methods['get' . $name]) || isset($methods['is' . $name])); + } + + + /********************* magic @properties ****************d*g**/ + + + /** + * @deprecated use ObjectHelpers::strictStaticCall() + */ + public static function getMagicProperties($class) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + return ObjectHelpers::getMagicProperties($class); + } + + + /** @internal */ + public static function getMagicProperty($class, $name) + { + $props = ObjectHelpers::getMagicProperties($class); + return isset($props[$name]) ? $props[$name] : null; + } + + + /********************* magic @methods ****************d*g**/ + + + /** + * Returns array of magic methods defined by annotation @method. + * @return array + */ + public static function getMagicMethods($class) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + $rc = new \ReflectionClass($class); + preg_match_all('~^ + [ \t*]* @method [ \t]+ + (?: [^\s(]+ [ \t]+ )? + (set|get|is|add) ([A-Z]\w*) + (?: ([ \t]* \() [ \t]* ([^)$\s]*) )? + ()~mx', (string) $rc->getDocComment(), $matches, PREG_SET_ORDER); + + $methods = []; + foreach ($matches as list(, $op, $prop, $bracket, $type)) { + if ($bracket !== '(') { + trigger_error("Bracket must be immediately after @method $op$prop() in class $class.", E_USER_WARNING); + } + $name = $op . $prop; + $prop = strtolower($prop[0]) . substr($prop, 1) . ($op === 'add' ? 's' : ''); + if ($rc->hasProperty($prop) && ($rp = $rc->getProperty($prop)) && !$rp->isStatic()) { + $rp->setAccessible(true); + if ($op === 'get' || $op === 'is') { + $type = null; + $op = 'get'; + } elseif (!$type && preg_match('#@var[ \t]+(\S+)' . ($op === 'add' ? '\[\]#' : '#'), (string) $rp->getDocComment(), $m)) { + $type = $m[1]; + } + if ($rc->inNamespace() && preg_match('#^[A-Z]\w+(\[|\||\z)#', (string) $type)) { + $type = $rc->getNamespaceName() . '\\' . $type; + } + $methods[$name] = [$op, $rp, $type]; + } + } + return $methods; + } + + + /** + * Finds whether a variable is of expected type and do non-data-loss conversion. + * @return bool + * @internal + */ + public static function checkType(&$val, $type) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + if (strpos($type, '|') !== false) { + $found = null; + foreach (explode('|', $type) as $type) { + $tmp = $val; + if (self::checkType($tmp, $type)) { + if ($val === $tmp) { + return true; + } + $found[] = $tmp; + } + } + if ($found) { + $val = $found[0]; + return true; + } + return false; + + } elseif (substr($type, -2) === '[]') { + if (!is_array($val)) { + return false; + } + $type = substr($type, 0, -2); + $res = []; + foreach ($val as $k => $v) { + if (!self::checkType($v, $type)) { + return false; + } + $res[$k] = $v; + } + $val = $res; + return true; + } + + switch (strtolower($type)) { + case null: + case 'mixed': + return true; + case 'bool': + case 'boolean': + return ($val === null || is_scalar($val)) && settype($val, 'bool'); + case 'string': + return ($val === null || is_scalar($val) || (is_object($val) && method_exists($val, '__toString'))) && settype($val, 'string'); + case 'int': + case 'integer': + return ($val === null || is_bool($val) || is_numeric($val)) && ((float) (int) $val === (float) $val) && settype($val, 'int'); + case 'float': + return ($val === null || is_bool($val) || is_numeric($val)) && settype($val, 'float'); + case 'scalar': + case 'array': + case 'object': + case 'callable': + case 'resource': + case 'null': + return call_user_func("is_$type", $val); + default: + return $val instanceof $type; + } + } + + + /********************* extension methods ****************d*g**/ + + + /** + * Adds a method to class. + * @param string + * @param string + * @param mixed callable + * @return void + */ + public static function setExtensionMethod($class, $name, $callback) + { + $name = strtolower($name); + self::$extMethods[$name][$class] = Callback::check($callback); + self::$extMethods[$name][''] = null; + } + + + /** + * Returns extension method. + * @param string + * @param string + * @return mixed + */ + public static function getExtensionMethod($class, $name) + { + $list = &self::$extMethods[strtolower($name)]; + $cache = &$list[''][$class]; + if (isset($cache)) { + return $cache; + } + + foreach ([$class] + class_parents($class) + class_implements($class) as $cl) { + if (isset($list[$cl])) { + return $cache = $list[$cl]; + } + } + return $cache = false; + } + + + /** + * Returns extension methods. + * @param string + * @return array + */ + public static function getExtensionMethods($class) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + $res = []; + foreach (array_keys(self::$extMethods) as $name) { + if ($cb = self::getExtensionMethod($class, $name)) { + $res[$name] = $cb; + } + } + return $res; + } + + + /********************* utilities ****************d*g**/ + + + /** + * @deprecated use ObjectHelpers::getSuggestion() + */ + public static function getSuggestion(array $possibilities, $value) + { + return ObjectHelpers::getSuggestion($possibilities, $value); + } + + + /** + * @deprecated use ObjectHelpers::hasProperty() + */ + public static function hasProperty($class, $name) + { + trigger_error('Class Nette\Utils\ObjectMixin is deprecated', E_USER_DEPRECATED); + return ObjectHelpers::hasProperty($class, $name); + } + + + /** + * Returns array of public (static, non-static and magic) methods. + * @return array + * @internal + */ + public static function &getMethods($class) + { + static $cache; + if (!isset($cache[$class])) { + $cache[$class] = array_fill_keys(get_class_methods($class), 0) + @self::getMagicMethods($class); // is deprecated + if ($parent = get_parent_class($class)) { + $cache[$class] += self::getMethods($parent); + } + } + return $cache[$class]; + } + + + /** @internal */ + public static function getSource() + { + foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $item) { + if (isset($item['file']) && dirname($item['file']) !== __DIR__) { + return " in $item[file]:$item[line]"; + } + } + } +} diff --git a/vendor/nette/utils/src/Utils/Paginator.php b/vendor/nette/utils/src/Utils/Paginator.php new file mode 100644 index 00000000..dfc4c127 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Paginator.php @@ -0,0 +1,227 @@ +page = (int) $page; + return $this; + } + + + /** + * Returns current page number. + * @return int + */ + public function getPage() + { + return $this->base + $this->getPageIndex(); + } + + + /** + * Returns first page number. + * @return int + */ + public function getFirstPage() + { + return $this->base; + } + + + /** + * Returns last page number. + * @return int|null + */ + public function getLastPage() + { + return $this->itemCount === null ? null : $this->base + max(0, $this->getPageCount() - 1); + } + + + /** + * Sets first page (base) number. + * @param int + * @return static + */ + public function setBase($base) + { + $this->base = (int) $base; + return $this; + } + + + /** + * Returns first page (base) number. + * @return int + */ + public function getBase() + { + return $this->base; + } + + + /** + * Returns zero-based page number. + * @return int + */ + protected function getPageIndex() + { + $index = max(0, $this->page - $this->base); + return $this->itemCount === null ? $index : min($index, max(0, $this->getPageCount() - 1)); + } + + + /** + * Is the current page the first one? + * @return bool + */ + public function isFirst() + { + return $this->getPageIndex() === 0; + } + + + /** + * Is the current page the last one? + * @return bool + */ + public function isLast() + { + return $this->itemCount === null ? false : $this->getPageIndex() >= $this->getPageCount() - 1; + } + + + /** + * Returns the total number of pages. + * @return int|null + */ + public function getPageCount() + { + return $this->itemCount === null ? null : (int) ceil($this->itemCount / $this->itemsPerPage); + } + + + /** + * Sets the number of items to display on a single page. + * @param int + * @return static + */ + public function setItemsPerPage($itemsPerPage) + { + $this->itemsPerPage = max(1, (int) $itemsPerPage); + return $this; + } + + + /** + * Returns the number of items to display on a single page. + * @return int + */ + public function getItemsPerPage() + { + return $this->itemsPerPage; + } + + + /** + * Sets the total number of items. + * @param int (or null as infinity) + * @return static + */ + public function setItemCount($itemCount) + { + $this->itemCount = ($itemCount === false || $itemCount === null) ? null : max(0, (int) $itemCount); + return $this; + } + + + /** + * Returns the total number of items. + * @return int|null + */ + public function getItemCount() + { + return $this->itemCount; + } + + + /** + * Returns the absolute index of the first item on current page. + * @return int + */ + public function getOffset() + { + return $this->getPageIndex() * $this->itemsPerPage; + } + + + /** + * Returns the absolute index of the first item on current page in countdown paging. + * @return int|null + */ + public function getCountdownOffset() + { + return $this->itemCount === null + ? null + : max(0, $this->itemCount - ($this->getPageIndex() + 1) * $this->itemsPerPage); + } + + + /** + * Returns the number of items on current page. + * @return int|null + */ + public function getLength() + { + return $this->itemCount === null + ? $this->itemsPerPage + : min($this->itemsPerPage, $this->itemCount - $this->getPageIndex() * $this->itemsPerPage); + } +} diff --git a/vendor/nette/utils/src/Utils/Random.php b/vendor/nette/utils/src/Utils/Random.php new file mode 100644 index 00000000..f1895f13 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Random.php @@ -0,0 +1,80 @@ += 70000) { + for ($i = 0; $i < $length; $i++) { + $res .= $charlist[random_int(0, $chLen - 1)]; + } + return $res; + } + + $bytes = ''; + if (function_exists('openssl_random_pseudo_bytes')) { + $bytes = (string) openssl_random_pseudo_bytes($length, $secure); + if (!$secure) { + $bytes = ''; + } + } + if (strlen($bytes) < $length && function_exists('mcrypt_create_iv')) { + $bytes = (string) mcrypt_create_iv($length, MCRYPT_DEV_URANDOM); + } + if (strlen($bytes) < $length && !defined('PHP_WINDOWS_VERSION_BUILD') && is_readable('/dev/urandom')) { + $bytes = (string) file_get_contents('/dev/urandom', false, null, -1, $length); + } + if (strlen($bytes) < $length) { + $rand3 = md5(serialize($_SERVER), true); + $charlist = str_shuffle($charlist); + for ($i = 0; $i < $length; $i++) { + if ($i % 5 === 0) { + list($rand1, $rand2) = explode(' ', microtime()); + $rand1 += lcg_value(); + } + $rand1 *= $chLen; + $res .= $charlist[($rand1 + $rand2 + ord($rand3[$i % strlen($rand3)])) % $chLen]; + $rand1 -= (int) $rand1; + } + return $res; + } + + for ($i = 0; $i < $length; $i++) { + $res .= $charlist[($i + ord($bytes[$i])) % $chLen]; + } + return $res; + } +} diff --git a/vendor/nette/utils/src/Utils/Reflection.php b/vendor/nette/utils/src/Utils/Reflection.php new file mode 100644 index 00000000..1937c41e --- /dev/null +++ b/vendor/nette/utils/src/Utils/Reflection.php @@ -0,0 +1,316 @@ + 1, 'int' => 1, 'float' => 1, 'bool' => 1, 'array' => 1, 'object' => 1, + 'callable' => 1, 'iterable' => 1, 'void' => 1, + ]; + + + /** + * @param string + * @return bool + */ + public static function isBuiltinType($type) + { + return isset(self::$builtinTypes[strtolower($type)]); + } + + + /** + * @return string|null + */ + public static function getReturnType(\ReflectionFunctionAbstract $func) + { + return PHP_VERSION_ID >= 70000 && $func->hasReturnType() + ? self::normalizeType((string) $func->getReturnType(), $func) + : null; + } + + + /** + * @return string|null + */ + public static function getParameterType(\ReflectionParameter $param) + { + if (PHP_VERSION_ID >= 70000) { + return $param->hasType() + ? self::normalizeType((string) $param->getType(), $param) + : null; + } elseif ($param->isArray() || $param->isCallable()) { + return $param->isArray() ? 'array' : 'callable'; + } else { + try { + return ($ref = $param->getClass()) ? $ref->getName() : null; + } catch (\ReflectionException $e) { + if (preg_match('#Class (.+) does not exist#', $e->getMessage(), $m)) { + return $m[1]; + } + throw $e; + } + } + } + + + private static function normalizeType($type, $reflection) + { + $lower = strtolower($type); + if ($lower === 'self') { + return $reflection->getDeclaringClass()->getName(); + } elseif ($lower === 'parent' && $reflection->getDeclaringClass()->getParentClass()) { + return $reflection->getDeclaringClass()->getParentClass()->getName(); + } else { + return $type; + } + } + + + /** + * @return mixed + * @throws \ReflectionException when default value is not available or resolvable + */ + public static function getParameterDefaultValue(\ReflectionParameter $param) + { + if ($param->isDefaultValueConstant()) { + $const = $orig = $param->getDefaultValueConstantName(); + $pair = explode('::', $const); + if (isset($pair[1]) && strtolower($pair[0]) === 'self') { + $pair[0] = $param->getDeclaringClass()->getName(); + } + if (isset($pair[1]) && PHP_VERSION_ID >= 70100) { + try { + $rcc = new \ReflectionClassConstant($pair[0], $pair[1]); + } catch (\ReflectionException $e) { + $name = self::toString($param); + throw new \ReflectionException("Unable to resolve constant $orig used as default value of $name.", 0, $e); + } + return $rcc->getValue(); + } + $const = implode('::', $pair); + if (!defined($const)) { + $const = substr((string) strrchr($const, '\\'), 1); + if (isset($pair[1]) || !defined($const)) { + $name = self::toString($param); + throw new \ReflectionException("Unable to resolve constant $orig used as default value of $name."); + } + } + return constant($const); + } + return $param->getDefaultValue(); + } + + + /** + * Returns declaring class or trait. + * @return \ReflectionClass + */ + public static function getPropertyDeclaringClass(\ReflectionProperty $prop) + { + foreach ($prop->getDeclaringClass()->getTraits() as $trait) { + if ($trait->hasProperty($prop->getName())) { + return self::getPropertyDeclaringClass($trait->getProperty($prop->getName())); + } + } + return $prop->getDeclaringClass(); + } + + + /** + * Are documentation comments available? + * @return bool + */ + public static function areCommentsAvailable() + { + static $res; + return $res === null + ? $res = (bool) (new \ReflectionMethod(__METHOD__))->getDocComment() + : $res; + } + + + /** + * @return string + */ + public static function toString(\Reflector $ref) + { + if ($ref instanceof \ReflectionClass) { + return $ref->getName(); + } elseif ($ref instanceof \ReflectionMethod) { + return $ref->getDeclaringClass()->getName() . '::' . $ref->getName(); + } elseif ($ref instanceof \ReflectionFunction) { + return $ref->getName(); + } elseif ($ref instanceof \ReflectionProperty) { + return self::getPropertyDeclaringClass($ref)->getName() . '::$' . $ref->getName(); + } elseif ($ref instanceof \ReflectionParameter) { + return '$' . $ref->getName() . ' in ' . self::toString($ref->getDeclaringFunction()) . '()'; + } else { + throw new Nette\InvalidArgumentException; + } + } + + + /** + * Expands class name into full name. + * @param string + * @return string full name + * @throws Nette\InvalidArgumentException + */ + public static function expandClassName($name, \ReflectionClass $rc) + { + $lower = strtolower($name); + if (empty($name)) { + throw new Nette\InvalidArgumentException('Class name must not be empty.'); + + } elseif (isset(self::$builtinTypes[$lower])) { + return $lower; + + } elseif ($lower === 'self') { + return $rc->getName(); + + } elseif ($name[0] === '\\') { // fully qualified name + return ltrim($name, '\\'); + } + + $uses = self::getUseStatements($rc); + $parts = explode('\\', $name, 2); + if (isset($uses[$parts[0]])) { + $parts[0] = $uses[$parts[0]]; + return implode('\\', $parts); + + } elseif ($rc->inNamespace()) { + return $rc->getNamespaceName() . '\\' . $name; + + } else { + return $name; + } + } + + + /** + * @return array of [alias => class] + */ + public static function getUseStatements(\ReflectionClass $class) + { + static $cache = []; + if (!isset($cache[$name = $class->getName()])) { + if ($class->isInternal()) { + $cache[$name] = []; + } else { + $code = file_get_contents($class->getFileName()); + $cache = self::parseUseStatements($code, $name) + $cache; + } + } + return $cache[$name]; + } + + + /** + * Parses PHP code. + * @param string + * @return array of [class => [alias => class, ...]] + */ + private static function parseUseStatements($code, $forClass = null) + { + $tokens = PHP_VERSION_ID >= 70000 ? token_get_all($code, TOKEN_PARSE) : token_get_all($code); + $namespace = $class = $classLevel = $level = null; + $res = $uses = []; + + while ($token = current($tokens)) { + next($tokens); + switch (is_array($token) ? $token[0] : $token) { + case T_NAMESPACE: + $namespace = ltrim(self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]) . '\\', '\\'); + $uses = []; + break; + + case T_CLASS: + case T_INTERFACE: + case T_TRAIT: + if ($name = self::fetch($tokens, T_STRING)) { + $class = $namespace . $name; + $classLevel = $level + 1; + $res[$class] = $uses; + if ($class === $forClass) { + return $res; + } + } + break; + + case T_USE: + while (!$class && ($name = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR]))) { + $name = ltrim($name, '\\'); + if (self::fetch($tokens, '{')) { + while ($suffix = self::fetch($tokens, [T_STRING, T_NS_SEPARATOR])) { + if (self::fetch($tokens, T_AS)) { + $uses[self::fetch($tokens, T_STRING)] = $name . $suffix; + } else { + $tmp = explode('\\', $suffix); + $uses[end($tmp)] = $name . $suffix; + } + if (!self::fetch($tokens, ',')) { + break; + } + } + + } elseif (self::fetch($tokens, T_AS)) { + $uses[self::fetch($tokens, T_STRING)] = $name; + + } else { + $tmp = explode('\\', $name); + $uses[end($tmp)] = $name; + } + if (!self::fetch($tokens, ',')) { + break; + } + } + break; + + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': + $level++; + break; + + case '}': + if ($level === $classLevel) { + $class = $classLevel = null; + } + $level--; + } + } + + return $res; + } + + + private static function fetch(&$tokens, $take) + { + $res = null; + while ($token = current($tokens)) { + list($token, $s) = is_array($token) ? $token : [$token, $token]; + if (in_array($token, (array) $take, true)) { + $res .= $s; + } elseif (!in_array($token, [T_DOC_COMMENT, T_WHITESPACE, T_COMMENT], true)) { + break; + } + next($tokens); + } + return $res; + } +} diff --git a/vendor/nette/utils/src/Utils/SmartObject.php b/vendor/nette/utils/src/Utils/SmartObject.php new file mode 100644 index 00000000..b6112126 --- /dev/null +++ b/vendor/nette/utils/src/Utils/SmartObject.php @@ -0,0 +1,231 @@ +$name) || $this->$name instanceof \Traversable) { + foreach ($this->$name as $handler) { + Callback::invokeArgs($handler, $args); + } + } elseif ($this->$name !== null) { + throw new UnexpectedValueException("Property $class::$$name must be array or null, " . gettype($this->$name) . ' given.'); + } + + } elseif ($isProp && $this->$name instanceof \Closure) { // closure in property + trigger_error("Invoking closure in property via \$obj->$name() is deprecated" . ObjectMixin::getSource(), E_USER_DEPRECATED); + return call_user_func_array($this->$name, $args); + + } elseif (($methods = &ObjectMixin::getMethods($class)) && isset($methods[$name]) && is_array($methods[$name])) { // magic @methods + trigger_error("Magic methods such as $class::$name() are deprecated" . ObjectMixin::getSource(), E_USER_DEPRECATED); + list($op, $rp, $type) = $methods[$name]; + if (count($args) !== ($op === 'get' ? 0 : 1)) { + throw new InvalidArgumentException("$class::$name() expects " . ($op === 'get' ? 'no' : '1') . ' argument, ' . count($args) . ' given.'); + + } elseif ($type && $args && !ObjectMixin::checkType($args[0], $type)) { + throw new InvalidArgumentException("Argument passed to $class::$name() must be $type, " . gettype($args[0]) . ' given.'); + } + + if ($op === 'get') { + return $rp->getValue($this); + } elseif ($op === 'set') { + $rp->setValue($this, $args[0]); + } elseif ($op === 'add') { + $val = $rp->getValue($this); + $val[] = $args[0]; + $rp->setValue($this, $val); + } + return $this; + + } elseif ($cb = ObjectMixin::getExtensionMethod($class, $name)) { // extension methods + trigger_error("Extension methods such as $class::$name() are deprecated" . ObjectMixin::getSource(), E_USER_DEPRECATED); + return Callback::invoke($cb, $this, ...$args); + + } else { + ObjectHelpers::strictCall($class, $name); + } + } + + + /** + * @return void + * @throws MemberAccessException + */ + public static function __callStatic($name, $args) + { + ObjectHelpers::strictStaticCall(get_called_class(), $name); + } + + + /** + * @return mixed property value + * @throws MemberAccessException if the property is not defined. + */ + public function &__get($name) + { + $class = get_class($this); + $uname = ucfirst($name); + + if ($prop = ObjectMixin::getMagicProperty($class, $name)) { // property getter + if (!($prop & 0b0001)) { + throw new MemberAccessException("Cannot read a write-only property $class::\$$name."); + } + $m = ($prop & 0b0010 ? 'get' : 'is') . $uname; + if ($prop & 0b0100) { // return by reference + return $this->$m(); + } else { + $val = $this->$m(); + return $val; + } + + } elseif ($name === '') { + throw new MemberAccessException("Cannot read a class '$class' property without name."); + + } elseif (($methods = &ObjectMixin::getMethods($class)) && isset($methods[$m = 'get' . $uname]) || isset($methods[$m = 'is' . $uname])) { // old property getter + trigger_error("Use $m() or add annotation @property for $class::\$$name" . ObjectMixin::getSource(), E_USER_DEPRECATED); + if ($methods[$m] === 0) { + $methods[$m] = (new \ReflectionMethod($class, $m))->returnsReference(); + } + if ($methods[$m] === true) { + return $this->$m(); + } else { + $val = $this->$m(); + return $val; + } + + } elseif (isset($methods[$name])) { // public method as closure getter + trigger_error("Accessing methods as properties via \$obj->$name is deprecated, use PHP callback [\$obj, '$name']" . ObjectMixin::getSource(), E_USER_DEPRECATED); + $val = Callback::closure($this, $name); + return $val; + + } elseif (isset($methods['set' . $uname])) { // property getter + throw new MemberAccessException("Cannot read a write-only property $class::\$$name."); + + } else { + ObjectHelpers::strictGet($class, $name); + } + } + + + /** + * @return void + * @throws MemberAccessException if the property is not defined or is read-only + */ + public function __set($name, $value) + { + $class = get_class($this); + $uname = ucfirst($name); + + if (ObjectHelpers::hasProperty($class, $name)) { // unsetted property + $this->$name = $value; + + } elseif ($prop = ObjectMixin::getMagicProperty($class, $name)) { // property setter + if (!($prop & 0b1000)) { + throw new MemberAccessException("Cannot write to a read-only property $class::\$$name."); + } + $this->{'set' . $name}($value); + + } elseif ($name === '') { + throw new MemberAccessException("Cannot write to a class '$class' property without name."); + + } elseif (($methods = &ObjectMixin::getMethods($class)) && isset($methods[$m = 'set' . $uname])) { // old property setter + trigger_error("Use $m() or add annotation @property for $class::\$$name" . ObjectMixin::getSource(), E_USER_DEPRECATED); + $this->$m($value); + + } elseif (isset($methods['get' . $uname]) || isset($methods['is' . $uname])) { // property setter + throw new MemberAccessException("Cannot write to a read-only property $class::\$$name."); + + } else { + ObjectHelpers::strictSet($class, $name); + } + } + + + /** + * @return void + * @throws MemberAccessException + */ + public function __unset($name) + { + $class = get_class($this); + if (!ObjectHelpers::hasProperty($class, $name)) { + throw new MemberAccessException("Cannot unset the property $class::\$$name."); + } + } + + + /** + * @return bool + */ + public function __isset($name) + { + $uname = ucfirst($name); + return ObjectMixin::getMagicProperty(get_class($this), $name) + || ($name !== '' && ($methods = ObjectMixin::getMethods(get_class($this))) && (isset($methods['get' . $uname]) || isset($methods['is' . $uname]))); + } + + + /** + * @return Reflection\ClassType|\ReflectionClass + * @deprecated + */ + public static function getReflection() + { + trigger_error(get_called_class() . '::getReflection() is deprecated' . ObjectMixin::getSource(), E_USER_DEPRECATED); + $class = class_exists(Reflection\ClassType::class) ? Reflection\ClassType::class : \ReflectionClass::class; + return new $class(get_called_class()); + } + + + /** + * @return mixed + * @deprecated use Nette\Utils\ObjectMixin::setExtensionMethod() + */ + public static function extensionMethod($name, $callback = null) + { + if (strpos($name, '::') === false) { + $class = get_called_class(); + } else { + list($class, $name) = explode('::', $name); + $class = (new \ReflectionClass($class))->getName(); + } + trigger_error("Extension methods such as $class::$name() are deprecated" . ObjectMixin::getSource(), E_USER_DEPRECATED); + if ($callback === null) { + return ObjectMixin::getExtensionMethod($class, $name); + } else { + ObjectMixin::setExtensionMethod($class, $name, $callback); + } + } +} diff --git a/vendor/nette/utils/src/Utils/StaticClass.php b/vendor/nette/utils/src/Utils/StaticClass.php new file mode 100644 index 00000000..51d6d335 --- /dev/null +++ b/vendor/nette/utils/src/Utils/StaticClass.php @@ -0,0 +1,34 @@ += 0xD800 && $code <= 0xDFFF) || $code > 0x10FFFF) { + throw new Nette\InvalidArgumentException('Code point must be in range 0x0 to 0xD7FF or 0xE000 to 0x10FFFF.'); + } + return iconv('UTF-32BE', 'UTF-8//IGNORE', pack('N', $code)); + } + + + /** + * Starts the $haystack string with the prefix $needle? + * @param string + * @param string + * @return bool + */ + public static function startsWith($haystack, $needle) + { + return strncmp($haystack, $needle, strlen($needle)) === 0; + } + + + /** + * Ends the $haystack string with the suffix $needle? + * @param string + * @param string + * @return bool + */ + public static function endsWith($haystack, $needle) + { + return strlen($needle) === 0 || substr($haystack, -strlen($needle)) === $needle; + } + + + /** + * Does $haystack contain $needle? + * @param string + * @param string + * @return bool + */ + public static function contains($haystack, $needle) + { + return strpos($haystack, $needle) !== false; + } + + + /** + * Returns a part of UTF-8 string. + * @param string + * @param int in characters (code points) + * @param int in characters (code points) + * @return string + */ + public static function substring($s, $start, $length = null) + { + if (function_exists('mb_substr')) { + return mb_substr($s, $start, $length, 'UTF-8'); // MB is much faster + } elseif ($length === null) { + $length = self::length($s); + } elseif ($start < 0 && $length < 0) { + $start += self::length($s); // unifies iconv_substr behavior with mb_substr + } + return iconv_substr($s, $start, $length, 'UTF-8'); + } + + + /** + * Removes special controls characters and normalizes line endings and spaces. + * @param string UTF-8 encoding + * @return string + */ + public static function normalize($s) + { + $s = self::normalizeNewLines($s); + + // remove control characters; leave \t + \n + $s = preg_replace('#[\x00-\x08\x0B-\x1F\x7F-\x9F]+#u', '', $s); + + // right trim + $s = preg_replace('#[\t ]+$#m', '', $s); + + // leading and trailing blank lines + $s = trim($s, "\n"); + + return $s; + } + + + /** + * Standardize line endings to unix-like. + * @param string UTF-8 encoding or 8-bit + * @return string + */ + public static function normalizeNewLines($s) + { + return str_replace(["\r\n", "\r"], "\n", $s); + } + + + /** + * Converts to ASCII. + * @param string UTF-8 encoding + * @return string ASCII + */ + public static function toAscii($s) + { + static $transliterator = null; + if ($transliterator === null && class_exists('Transliterator', false)) { + $transliterator = \Transliterator::create('Any-Latin; Latin-ASCII'); + } + + $s = preg_replace('#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{2FF}\x{370}-\x{10FFFF}]#u', '', $s); + $s = strtr($s, '`\'"^~?', "\x01\x02\x03\x04\x05\x06"); + $s = str_replace( + ["\xE2\x80\x9E", "\xE2\x80\x9C", "\xE2\x80\x9D", "\xE2\x80\x9A", "\xE2\x80\x98", "\xE2\x80\x99", "\xC2\xB0"], + ["\x03", "\x03", "\x03", "\x02", "\x02", "\x02", "\x04"], $s + ); + if ($transliterator !== null) { + $s = $transliterator->transliterate($s); + } + if (ICONV_IMPL === 'glibc') { + $s = str_replace( + ["\xC2\xBB", "\xC2\xAB", "\xE2\x80\xA6", "\xE2\x84\xA2", "\xC2\xA9", "\xC2\xAE"], + ['>>', '<<', '...', 'TM', '(c)', '(R)'], $s + ); + $s = iconv('UTF-8', 'WINDOWS-1250//TRANSLIT//IGNORE', $s); + $s = strtr($s, "\xa5\xa3\xbc\x8c\xa7\x8a\xaa\x8d\x8f\x8e\xaf\xb9\xb3\xbe\x9c\x9a\xba\x9d\x9f\x9e" + . "\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3" + . "\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8" + . "\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe" + . "\x96\xa0\x8b\x97\x9b\xa6\xad\xb7", + 'ALLSSSSTZZZallssstzzzRAAAALCCCEEEEIIDDNNOOOOxRUUUUYTsraaaalccceeeeiiddnnooooruuuuyt- <->|-.'); + $s = preg_replace('#[^\x00-\x7F]++#', '', $s); + } else { + $s = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); + } + $s = str_replace(['`', "'", '"', '^', '~', '?'], '', $s); + return strtr($s, "\x01\x02\x03\x04\x05\x06", '`\'"^~?'); + } + + + /** + * Converts to web safe characters [a-z0-9-] text. + * @param string UTF-8 encoding + * @param string allowed characters + * @param bool + * @return string + */ + public static function webalize($s, $charlist = null, $lower = true) + { + $s = self::toAscii($s); + if ($lower) { + $s = strtolower($s); + } + $s = preg_replace('#[^a-z0-9' . ($charlist !== null ? preg_quote($charlist, '#') : '') . ']+#i', '-', $s); + $s = trim($s, '-'); + return $s; + } + + + /** + * Truncates string to maximal length. + * @param string UTF-8 encoding + * @param int + * @param string UTF-8 encoding + * @return string + */ + public static function truncate($s, $maxLen, $append = "\xE2\x80\xA6") + { + if (self::length($s) > $maxLen) { + $maxLen = $maxLen - self::length($append); + if ($maxLen < 1) { + return $append; + + } elseif ($matches = self::match($s, '#^.{1,' . $maxLen . '}(?=[\s\x00-/:-@\[-`{-~])#us')) { + return $matches[0] . $append; + + } else { + return self::substring($s, 0, $maxLen) . $append; + } + } + return $s; + } + + + /** + * Indents the content from the left. + * @param string UTF-8 encoding or 8-bit + * @param int + * @param string + * @return string + */ + public static function indent($s, $level = 1, $chars = "\t") + { + if ($level > 0) { + $s = self::replace($s, '#(?:^|[\r\n]+)(?=[^\r\n])#', '$0' . str_repeat($chars, $level)); + } + return $s; + } + + + /** + * Convert to lower case. + * @param string UTF-8 encoding + * @return string + */ + public static function lower($s) + { + return mb_strtolower($s, 'UTF-8'); + } + + + /** + * Convert first character to lower case. + * @param string UTF-8 encoding + * @return string + */ + public static function firstLower($s) + { + return self::lower(self::substring($s, 0, 1)) . self::substring($s, 1); + } + + + /** + * Convert to upper case. + * @param string UTF-8 encoding + * @return string + */ + public static function upper($s) + { + return mb_strtoupper($s, 'UTF-8'); + } + + + /** + * Convert first character to upper case. + * @param string UTF-8 encoding + * @return string + */ + public static function firstUpper($s) + { + return self::upper(self::substring($s, 0, 1)) . self::substring($s, 1); + } + + + /** + * Capitalize string. + * @param string UTF-8 encoding + * @return string + */ + public static function capitalize($s) + { + return mb_convert_case($s, MB_CASE_TITLE, 'UTF-8'); + } + + + /** + * Case-insensitive compares UTF-8 strings. + * @param string + * @param string + * @param int + * @return bool + */ + public static function compare($left, $right, $len = null) + { + if ($len < 0) { + $left = self::substring($left, $len, -$len); + $right = self::substring($right, $len, -$len); + } elseif ($len !== null) { + $left = self::substring($left, 0, $len); + $right = self::substring($right, 0, $len); + } + return self::lower($left) === self::lower($right); + } + + + /** + * Finds the length of common prefix of strings. + * @param string|array + * @return string + */ + public static function findPrefix(...$strings) + { + if (is_array($strings[0])) { + $strings = $strings[0]; + } + $first = array_shift($strings); + for ($i = 0; $i < strlen($first); $i++) { + foreach ($strings as $s) { + if (!isset($s[$i]) || $first[$i] !== $s[$i]) { + while ($i && $first[$i - 1] >= "\x80" && $first[$i] >= "\x80" && $first[$i] < "\xC0") { + $i--; + } + return substr($first, 0, $i); + } + } + } + return $first; + } + + + /** + * Returns number of characters (not bytes) in UTF-8 string. + * That is the number of Unicode code points which may differ from the number of graphemes. + * @param string + * @return int + */ + public static function length($s) + { + return function_exists('mb_strlen') ? mb_strlen($s, 'UTF-8') : strlen(utf8_decode($s)); + } + + + /** + * Strips whitespace. + * @param string UTF-8 encoding + * @param string + * @return string + */ + public static function trim($s, $charlist = self::TRIM_CHARACTERS) + { + $charlist = preg_quote($charlist, '#'); + return self::replace($s, '#^[' . $charlist . ']+|[' . $charlist . ']+\z#u', ''); + } + + + /** + * Pad a string to a certain length with another string. + * @param string UTF-8 encoding + * @param int + * @param string + * @return string + */ + public static function padLeft($s, $length, $pad = ' ') + { + $length = max(0, $length - self::length($s)); + $padLen = self::length($pad); + return str_repeat($pad, (int) ($length / $padLen)) . self::substring($pad, 0, $length % $padLen) . $s; + } + + + /** + * Pad a string to a certain length with another string. + * @param string UTF-8 encoding + * @param int + * @param string + * @return string + */ + public static function padRight($s, $length, $pad = ' ') + { + $length = max(0, $length - self::length($s)); + $padLen = self::length($pad); + return $s . str_repeat($pad, (int) ($length / $padLen)) . self::substring($pad, 0, $length % $padLen); + } + + + /** + * Reverse string. + * @param string UTF-8 encoding + * @return string + */ + public static function reverse($s) + { + return iconv('UTF-32LE', 'UTF-8', strrev(iconv('UTF-8', 'UTF-32BE', $s))); + } + + + /** + * Returns part of $haystack before $nth occurence of $needle. + * @param string + * @param string + * @param int negative value means searching from the end + * @return string|false returns false if the needle was not found + */ + public static function before($haystack, $needle, $nth = 1) + { + $pos = self::pos($haystack, $needle, $nth); + return $pos === false + ? false + : substr($haystack, 0, $pos); + } + + + /** + * Returns part of $haystack after $nth occurence of $needle. + * @param string + * @param string + * @param int negative value means searching from the end + * @return string|false returns false if the needle was not found + */ + public static function after($haystack, $needle, $nth = 1) + { + $pos = self::pos($haystack, $needle, $nth); + return $pos === false + ? false + : (string) substr($haystack, $pos + strlen($needle)); + } + + + /** + * Returns position of $nth occurence of $needle in $haystack. + * @param string + * @param string + * @param int negative value means searching from the end + * @return int|false offset in characters or false if the needle was not found + */ + public static function indexOf($haystack, $needle, $nth = 1) + { + $pos = self::pos($haystack, $needle, $nth); + return $pos === false + ? false + : self::length(substr($haystack, 0, $pos)); + } + + + /** + * Returns position of $nth occurence of $needle in $haystack. + * @return int|false offset in bytes or false if the needle was not found + */ + private static function pos($haystack, $needle, $nth = 1) + { + if (!$nth) { + return false; + } elseif ($nth > 0) { + if (strlen($needle) === 0) { + return 0; + } + $pos = 0; + while (($pos = strpos($haystack, $needle, $pos)) !== false && --$nth) { + $pos++; + } + } else { + $len = strlen($haystack); + if (strlen($needle) === 0) { + return $len; + } + $pos = $len - 1; + while (($pos = strrpos($haystack, $needle, $pos - $len)) !== false && ++$nth) { + $pos--; + } + } + return $pos; + } + + + /** + * Splits string by a regular expression. + * @param string + * @param string + * @param int + * @return array + */ + public static function split($subject, $pattern, $flags = 0) + { + return self::pcre('preg_split', [$pattern, $subject, -1, $flags | PREG_SPLIT_DELIM_CAPTURE]); + } + + + /** + * Performs a regular expression match. + * @param string + * @param string + * @param int can be PREG_OFFSET_CAPTURE (returned in bytes) + * @param int offset in bytes + * @return mixed + */ + public static function match($subject, $pattern, $flags = 0, $offset = 0) + { + if ($offset > strlen($subject)) { + return null; + } + return self::pcre('preg_match', [$pattern, $subject, &$m, $flags, $offset]) + ? $m + : null; + } + + + /** + * Performs a global regular expression match. + * @param string + * @param string + * @param int can be PREG_OFFSET_CAPTURE (returned in bytes); PREG_SET_ORDER is default + * @param int offset in bytes + * @return array + */ + public static function matchAll($subject, $pattern, $flags = 0, $offset = 0) + { + if ($offset > strlen($subject)) { + return []; + } + self::pcre('preg_match_all', [ + $pattern, $subject, &$m, + ($flags & PREG_PATTERN_ORDER) ? $flags : ($flags | PREG_SET_ORDER), + $offset, + ]); + return $m; + } + + + /** + * Perform a regular expression search and replace. + * @param string + * @param string|array + * @param string|callable + * @param int + * @return string + */ + public static function replace($subject, $pattern, $replacement = null, $limit = -1) + { + if (is_object($replacement) || is_array($replacement)) { + if (!is_callable($replacement, false, $textual)) { + throw new Nette\InvalidStateException("Callback '$textual' is not callable."); + } + return self::pcre('preg_replace_callback', [$pattern, $replacement, $subject, $limit]); + + } elseif ($replacement === null && is_array($pattern)) { + $replacement = array_values($pattern); + $pattern = array_keys($pattern); + } + + return self::pcre('preg_replace', [$pattern, $replacement, $subject, $limit]); + } + + + /** @internal */ + public static function pcre($func, $args) + { + static $messages = [ + PREG_INTERNAL_ERROR => 'Internal error', + PREG_BACKTRACK_LIMIT_ERROR => 'Backtrack limit was exhausted', + PREG_RECURSION_LIMIT_ERROR => 'Recursion limit was exhausted', + PREG_BAD_UTF8_ERROR => 'Malformed UTF-8 data', + PREG_BAD_UTF8_OFFSET_ERROR => 'Offset didn\'t correspond to the begin of a valid UTF-8 code point', + 6 => 'Failed due to limited JIT stack space', // PREG_JIT_STACKLIMIT_ERROR + ]; + $res = Callback::invokeSafe($func, $args, function ($message) use ($args) { + // compile-time error, not detectable by preg_last_error + throw new RegexpException($message . ' in pattern: ' . implode(' or ', (array) $args[0])); + }); + + if (($code = preg_last_error()) // run-time error, but preg_last_error & return code are liars + && ($res === null || !in_array($func, ['preg_filter', 'preg_replace_callback', 'preg_replace'], true)) + ) { + throw new RegexpException((isset($messages[$code]) ? $messages[$code] : 'Unknown error') + . ' (pattern: ' . implode(' or ', (array) $args[0]) . ')', $code); + } + return $res; + } +} diff --git a/vendor/nette/utils/src/Utils/Validators.php b/vendor/nette/utils/src/Utils/Validators.php new file mode 100644 index 00000000..dd648879 --- /dev/null +++ b/vendor/nette/utils/src/Utils/Validators.php @@ -0,0 +1,362 @@ + 'is_bool', + 'boolean' => 'is_bool', + 'int' => 'is_int', + 'integer' => 'is_int', + 'float' => 'is_float', + 'number' => [__CLASS__, 'isNumber'], + 'numeric' => [__CLASS__, 'isNumeric'], + 'numericint' => [__CLASS__, 'isNumericInt'], + 'string' => 'is_string', + 'unicode' => [__CLASS__, 'isUnicode'], + 'array' => 'is_array', + 'list' => [Arrays::class, 'isList'], + 'object' => 'is_object', + 'resource' => 'is_resource', + 'scalar' => 'is_scalar', + 'callable' => [__CLASS__, 'isCallable'], + 'null' => 'is_null', + 'email' => [__CLASS__, 'isEmail'], + 'url' => [__CLASS__, 'isUrl'], + 'uri' => [__CLASS__, 'isUri'], + 'none' => [__CLASS__, 'isNone'], + 'type' => [__CLASS__, 'isType'], + 'identifier' => [__CLASS__, 'isPhpIdentifier'], + 'pattern' => null, + 'alnum' => 'ctype_alnum', + 'alpha' => 'ctype_alpha', + 'digit' => 'ctype_digit', + 'lower' => 'ctype_lower', + 'upper' => 'ctype_upper', + 'space' => 'ctype_space', + 'xdigit' => 'ctype_xdigit', + 'iterable' => [__CLASS__, 'isIterable'], + ]; + + protected static $counters = [ + 'string' => 'strlen', + 'unicode' => [Strings::class, 'length'], + 'array' => 'count', + 'list' => 'count', + 'alnum' => 'strlen', + 'alpha' => 'strlen', + 'digit' => 'strlen', + 'lower' => 'strlen', + 'space' => 'strlen', + 'upper' => 'strlen', + 'xdigit' => 'strlen', + ]; + + + /** + * Throws exception if a variable is of unexpected type. + * @param mixed + * @param string expected types separated by pipe + * @param string label + * @return void + */ + public static function assert($value, $expected, $label = 'variable') + { + if (!static::is($value, $expected)) { + $expected = str_replace(['|', ':'], [' or ', ' in range '], $expected); + if (is_array($value)) { + $type = 'array(' . count($value) . ')'; + } elseif (is_object($value)) { + $type = 'object ' . get_class($value); + } elseif (is_string($value) && strlen($value) < 40) { + $type = "string '$value'"; + } else { + $type = gettype($value); + } + throw new AssertionException("The $label expects to be $expected, $type given."); + } + } + + + /** + * Throws exception if an array field is missing or of unexpected type. + * @param array + * @param string item + * @param string expected types separated by pipe + * @param string + * @return void + */ + public static function assertField($arr, $field, $expected = null, $label = "item '%' in array") + { + self::assert($arr, 'array', 'first argument'); + if (!array_key_exists($field, $arr)) { + throw new AssertionException('Missing ' . str_replace('%', $field, $label) . '.'); + + } elseif ($expected) { + static::assert($arr[$field], $expected, str_replace('%', $field, $label)); + } + } + + + /** + * Finds whether a variable is of expected type. + * @param mixed + * @param string expected types separated by pipe with optional ranges + * @return bool + */ + public static function is($value, $expected) + { + foreach (explode('|', $expected) as $item) { + if (substr($item, -2) === '[]') { + if (self::everyIs($value, substr($item, 0, -2))) { + return true; + } + continue; + } + + list($type) = $item = explode(':', $item, 2); + if (isset(static::$validators[$type])) { + if (!call_user_func(static::$validators[$type], $value)) { + continue; + } + } elseif ($type === 'pattern') { + if (preg_match('|^' . (isset($item[1]) ? $item[1] : '') . '\z|', $value)) { + return true; + } + continue; + } elseif (!$value instanceof $type) { + continue; + } + + if (isset($item[1])) { + $length = $value; + if (isset(static::$counters[$type])) { + $length = call_user_func(static::$counters[$type], $value); + } + $range = explode('..', $item[1]); + if (!isset($range[1])) { + $range[1] = $range[0]; + } + if (($range[0] !== '' && $length < $range[0]) || ($range[1] !== '' && $length > $range[1])) { + continue; + } + } + return true; + } + return false; + } + + + /** + * Finds whether all values are of expected type. + * @param array|\Traversable + * @param string expected types separated by pipe with optional ranges + * @return bool + */ + public static function everyIs($values, $expected) + { + if (!self::isIterable($values)) { + return false; + } + foreach ($values as $value) { + if (!static::is($value, $expected)) { + return false; + } + } + return true; + } + + + /** + * Finds whether a value is an integer or a float. + * @return bool + */ + public static function isNumber($value) + { + return is_int($value) || is_float($value); + } + + + /** + * Finds whether a value is an integer. + * @return bool + */ + public static function isNumericInt($value) + { + return is_int($value) || is_string($value) && preg_match('#^-?[0-9]+\z#', $value); + } + + + /** + * Finds whether a string is a floating point number in decimal base. + * @return bool + */ + public static function isNumeric($value) + { + return is_float($value) || is_int($value) || is_string($value) && preg_match('#^-?[0-9]*[.]?[0-9]+\z#', $value); + } + + + /** + * Finds whether a value is a syntactically correct callback. + * @return bool + */ + public static function isCallable($value) + { + return $value && is_callable($value, true); + } + + + /** + * Finds whether a value is an UTF-8 encoded string. + * @param string + * @return bool + */ + public static function isUnicode($value) + { + return is_string($value) && preg_match('##u', $value); + } + + + /** + * Finds whether a value is "falsy". + * @return bool + */ + public static function isNone($value) + { + return $value == null; // intentionally == + } + + + /** + * Finds whether a variable is a zero-based integer indexed array. + * @param array + * @return bool + */ + public static function isList($value) + { + return Arrays::isList($value); + } + + + /** + * Is a value in specified range? + * @param mixed + * @param array min and max value pair + * @return bool + */ + public static function isInRange($value, $range) + { + if ($value === null || !(isset($range[0]) || isset($range[1]))) { + return false; + } + $limit = isset($range[0]) ? $range[0] : $range[1]; + if (is_string($limit)) { + $value = (string) $value; + } elseif ($limit instanceof \DateTimeInterface) { + if (!$value instanceof \DateTimeInterface) { + return false; + } + } elseif (is_numeric($value)) { + $value *= 1; + } else { + return false; + } + return (!isset($range[0]) || ($value >= $range[0])) && (!isset($range[1]) || ($value <= $range[1])); + } + + + /** + * Finds whether a string is a valid email address. + * @param string + * @return bool + */ + public static function isEmail($value) + { + $atom = "[-a-z0-9!#$%&'*+/=?^_`{|}~]"; // RFC 5322 unquoted characters in local-part + $alpha = "a-z\x80-\xFF"; // superset of IDN + return (bool) preg_match("(^ + (\"([ !#-[\\]-~]*|\\\\[ -~])+\"|$atom+(\\.$atom+)*) # quoted or unquoted + @ + ([0-9$alpha]([-0-9$alpha]{0,61}[0-9$alpha])?\\.)+ # domain - RFC 1034 + [$alpha]([-0-9$alpha]{0,17}[$alpha])? # top domain + \\z)ix", $value); + } + + + /** + * Finds whether a string is a valid http(s) URL. + * @param string + * @return bool + */ + public static function isUrl($value) + { + $alpha = "a-z\x80-\xFF"; + return (bool) preg_match("(^ + https?://( + (([-_0-9$alpha]+\\.)* # subdomain + [0-9$alpha]([-0-9$alpha]{0,61}[0-9$alpha])?\\.)? # domain + [$alpha]([-0-9$alpha]{0,17}[$alpha])? # top domain + |\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3} # IPv4 + |\[[0-9a-f:]{3,39}\] # IPv6 + )(:\\d{1,5})? # port + (/\\S*)? # path + \\z)ix", $value); + } + + + /** + * Finds whether a string is a valid URI according to RFC 1738. + * @param string + * @return bool + */ + public static function isUri($value) + { + return (bool) preg_match('#^[a-z\d+\.-]+:\S+\z#i', $value); + } + + + /** + * Checks whether the input is a class, interface or trait. + * @param string + * @return bool + */ + public static function isType($type) + { + return class_exists($type) || interface_exists($type) || trait_exists($type); + } + + + /** + * Checks whether the input is a valid PHP identifier. + * @return bool + */ + public static function isPhpIdentifier($value) + { + return is_string($value) && preg_match('#^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\z#', $value); + } + + + /** + * Returns true if value is iterable (array or instance of Traversable). + * @return bool + */ + private static function isIterable($value) + { + return is_array($value) || $value instanceof \Traversable; + } +} diff --git a/vendor/nette/utils/src/Utils/exceptions.php b/vendor/nette/utils/src/Utils/exceptions.php new file mode 100644 index 00000000..16534263 --- /dev/null +++ b/vendor/nette/utils/src/Utils/exceptions.php @@ -0,0 +1,157 @@ +` (with missing property name) is now supported in error recovery mode. +* The error recovery mode is now exposed in the `php-parse` script through the `--with-recovery` + or `-r` flags. + +The following changes are also part of PHP-Parser 2.1.1: + +* The PHP 7 parser will now generate a parse error for `$var =& new Obj` assignments. +* Comments on free-standing code blocks will now be retained as comments on the first statement in + the code block. + +Version 3.0.0-alpha1 (2016-07-25) +--------------------------------- + +### Added + +* [7.1] Added support for `void` and `iterable` types. These will now be represented as strings + (instead of `Name` instances) similar to other builtin types. +* [7.1] Added support for class constant visibility. The `ClassConst` node now has a `flags` subnode + holding the visibility modifier, as well as `isPublic()`, `isProtected()` and `isPrivate()` + methods. The constructor changed to accept the additional subnode. +* [7.1] Added support for nullable types. These are represented using a new `NullableType` node + with a single `type` subnode. +* [7.1] Added support for short array destructuring syntax. This means that `Array` nodes may now + appear as the left-hand-side of assignments and foreach value targets. Additionally the array + items may now contain `null` values if elements are skipped. +* [7.1] Added support for keys in list() destructuring. The `List` subnode `vars` has been renamed + to `items` and now contains `ArrayItem`s instead of plain variables. +* [7.1] Added support for multi-catch. The `Catch` subnode `type` has been renamed to `types` and + is now an array of `Name`s. +* `Name::slice()` now supports lengths and negative offsets. This brings it in line with + `array_slice()` functionality. + +### Changed + +Due to PHP 7.1 support additions described above, the node structure changed as follows: + +* `void` and `iterable` types are now stored as strings if the PHP 7 parser is used. +* The `ClassConst` constructor changed to accept an additional `flags` subnode. +* The `Array` subnode `items` may now contain `null` elements (destructuring). +* The `List` subnode `vars` has been renamed to `items` and now contains `ArrayItem`s instead of + plain variables. +* The `Catch` subnode `type` has been renamed to `types` and is now an array of `Name`s. + +Additionally the following changes were made: + +* The `type` subnode on `Class`, `ClassMethod` and `Property` has been renamed to `flags`. The + `type` subnode has retained for backwards compatibility and is populated to the same value as + `flags`. However, writes to `type` will not update `flags`. +* The `TryCatch` subnode `finallyStmts` has been replaced with a `finally` subnode that holds an + explicit `Finally` node. This allows for more accurate attribute assignment. +* The `Trait` constructor now has the same form as the `Class` and `Interface` constructors: It + takes an array of subnodes. Unlike classes/interfaces, traits can only have a `stmts` subnode. +* The `NodeDumper` now prints class/method/property/constant modifiers, as well as the include and + use type in a textual representation, instead of only showing the number. +* All methods on `PrettyPrinter\Standard` are now protected. Previously most of them were public. + +### Removed + +* Removed support for running on PHP 5.4. It is however still possible to parse PHP 5.2-5.4 code + while running on a newer version. +* The deprecated `Comment::setLine()` and `Comment::setText()` methods have been removed. +* The deprecated `Name::set()`, `Name::setFirst()` and `Name::setLast()` methods have been removed. + +Version 2.1.1 (2016-09-16) +-------------------------- + +### Changed + +* The pretty printer will now escape all control characters in the range `\x00-\x1F` inside double + quoted strings. If no special escape sequence is available, an octal escape will be used. +* The quality of the error recovery has been improved. In particular unterminated expressions should + be handled more gracefully. +* The PHP 7 parser will now generate a parse error for `$var =& new Obj` assignments. +* Comments on free-standing code blocks will no be retained as comments on the first statement in + the code block. + +Version 2.1.0 (2016-04-19) +-------------------------- + +### Fixed + +* Properly support `B""` strings (with uppercase `B`) in a number of places. +* Fixed reformatting of indented parts in a certain non-standard comment style. + +### Added + +* Added `dumpComments` option to node dumper, to enable dumping of comments associated with nodes. +* Added `Stmt\Nop` node, that is used to collect comments located at the end of a block or at the + end of a file (without a following node with which they could otherwise be associated). +* Added `kind` attribute to `Expr\Exit` to distinguish between `exit` and `die`. +* Added `kind` attribute to `Scalar\LNumber` to distinguish between decimal, binary, octal and + hexadecimal numbers. +* Added `kind` attribute to `Expr\Array` to distinguish between `array()` and `[]`. +* Added `kind` attribute to `Scalar\String` and `Scalar\Encapsed` to distinguish between + single-quoted, double-quoted, heredoc and nowdoc string. +* Added `docLabel` attribute to `Scalar\String` and `Scalar\Encapsed`, if it is a heredoc or + nowdoc string. +* Added start file offset information to `Comment` nodes. +* Added `setReturnType()` method to function and method builders. +* Added `-h` and `--help` options to `php-parse` script. + +### Changed + +* Invalid octal literals now throw a parse error in PHP 7 mode. +* The pretty printer takes all the new attributes mentioned in the previous section into account. +* The protected `AbstractPrettyPrinter::pComments()` method no longer returns a trailing newline. +* The bundled autoloader supports library files being stored in a different directory than + `PhpParser` for easier downstream distribution. + +### Deprecated + +* The `Comment::setLine()` and `Comment::setText()` methods have been deprecated. Construct new + objects instead. + +### Removed + +* The internal (but public) method `Scalar\LNumber::parse()` has been removed. A non-internal + `LNumber::fromString()` method has been added instead. + +Version 2.0.1 (2016-02-28) +-------------------------- + +### Fixed + +* `declare() {}` and `declare();` are not semantically equivalent and will now result in different + ASTs. The format case will have an empty `stmts` array, while the latter will set `stmts` to + `null`. +* Magic constants are now supported as semi-reserved keywords. +* A shebang line like `#!/usr/bin/env php` is now allowed at the start of a namespaced file. + Previously this generated an exception. +* The `prettyPrintFile()` method will not strip a trailing `?>` from the raw data that follows a + `__halt_compiler()` statement. +* The `prettyPrintFile()` method will not strip an opening `slice()` which takes a subslice of a name. + +### Changed + +* `PhpParser\Parser` is now an interface, implemented by `Parser\Php5`, `Parser\Php7` and + `Parser\Multiple`. The `Multiple` parser will try multiple parsers, until one succeeds. +* Token constants are now defined on `PhpParser\Parser\Tokens` rather than `PhpParser\Parser`. +* The `Name->set()`, `Name->append()`, `Name->prepend()` and `Name->setFirst()` methods are + deprecated in favor of `Name::concat()` and `Name->slice()`. +* The `NodeTraverser` no longer clones nodes by default. The old behavior can be restored by + passing `true` to the constructor. +* The constructor for `Scalar` nodes no longer has a default value. E.g. `new LNumber()` should now + be written as `new LNumber(0)`. + +--- + +**This changelog only includes changes from the 2.0 series. For older changes see the +[1.x series changelog](https://github.com/nikic/PHP-Parser/blob/1.x/CHANGELOG.md) and the +[0.9 series changelog](https://github.com/nikic/PHP-Parser/blob/0.9/CHANGELOG.md).** diff --git a/vendor/nikic/php-parser/LICENSE b/vendor/nikic/php-parser/LICENSE new file mode 100644 index 00000000..920cc5b1 --- /dev/null +++ b/vendor/nikic/php-parser/LICENSE @@ -0,0 +1,31 @@ +Copyright (c) 2011-2018 by Nikita Popov. + +Some rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * The names of the contributors may not be used to endorse or + promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/nikic/php-parser/README.md b/vendor/nikic/php-parser/README.md new file mode 100644 index 00000000..e62748eb --- /dev/null +++ b/vendor/nikic/php-parser/README.md @@ -0,0 +1,225 @@ +PHP Parser +========== + +[![Build Status](https://travis-ci.org/nikic/PHP-Parser.svg?branch=master)](https://travis-ci.org/nikic/PHP-Parser) [![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master) + +This is a PHP 5.2 to PHP 7.3 parser written in PHP. Its purpose is to simplify static code analysis and +manipulation. + +[**Documentation for version 4.x**][doc_master] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 7.3). + +[Documentation for version 3.x][doc_3_x] (unsupported; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2). + +Features +-------- + +The main features provided by this library are: + + * Parsing PHP 5 and PHP 7 code into an abstract syntax tree (AST). + * Invalid code can be parsed into a partial AST. + * The AST contains accurate location information. + * Dumping the AST in human-readable form. + * Converting an AST back to PHP code. + * Experimental: Formatting can be preserved for partially changed ASTs. + * Infrastructure to traverse and modify ASTs. + * Resolution of namespaced names. + * Evaluation of constant expressions. + * Builders to simplify AST construction for code generation. + * Converting an AST into JSON and back. + +Quick Start +----------- + +Install the library using [composer](https://getcomposer.org): + + php composer.phar require nikic/php-parser + +Parse some PHP code into an AST and dump the result in human-readable form: + +```php +create(ParserFactory::PREFER_PHP7); +try { + $ast = $parser->parse($code); +} catch (Error $error) { + echo "Parse error: {$error->getMessage()}\n"; + return; +} + +$dumper = new NodeDumper; +echo $dumper->dump($ast) . "\n"; +``` + +This dumps an AST looking something like this: + +``` +array( + 0: Stmt_Function( + byRef: false + name: Identifier( + name: test + ) + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: foo + ) + default: null + ) + ) + returnType: null + stmts: array( + 0: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: var_dump + ) + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: foo + ) + byRef: false + unpack: false + ) + ) + ) + ) + ) + ) +) +``` + +Let's traverse the AST and perform some kind of modification. For example, drop all function bodies: + +```php +use PhpParser\Node; +use PhpParser\Node\Stmt\Function_; +use PhpParser\NodeTraverser; +use PhpParser\NodeVisitorAbstract; + +$traverser = new NodeTraverser(); +$traverser->addVisitor(new class extends NodeVisitorAbstract { + public function enterNode(Node $node) { + if ($node instanceof Function_) { + // Clean out the function body + $node->stmts = []; + } + } +}); + +$ast = $traverser->traverse($ast); +echo $dumper->dump($ast) . "\n"; +``` + +This gives us an AST where the `Function_::$stmts` are empty: + +``` +array( + 0: Stmt_Function( + byRef: false + name: Identifier( + name: test + ) + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: foo + ) + default: null + ) + ) + returnType: null + stmts: array( + ) + ) +) +``` + +Finally, we can convert the new AST back to PHP code: + +```php +use PhpParser\PrettyPrinter; + +$prettyPrinter = new PrettyPrinter\Standard; +echo $prettyPrinter->prettyPrintFile($ast); +``` + +This gives us our original code, minus the `var_dump()` call inside the function: + +```php + Expr_AssignOp_BitwiseAnd +Expr_AssignBitwiseOr => Expr_AssignOp_BitwiseOr +Expr_AssignBitwiseXor => Expr_AssignOp_BitwiseXor +Expr_AssignConcat => Expr_AssignOp_Concat +Expr_AssignDiv => Expr_AssignOp_Div +Expr_AssignMinus => Expr_AssignOp_Minus +Expr_AssignMod => Expr_AssignOp_Mod +Expr_AssignMul => Expr_AssignOp_Mul +Expr_AssignPlus => Expr_AssignOp_Plus +Expr_AssignShiftLeft => Expr_AssignOp_ShiftLeft +Expr_AssignShiftRight => Expr_AssignOp_ShiftRight + +Expr_BitwiseAnd => Expr_BinaryOp_BitwiseAnd +Expr_BitwiseOr => Expr_BinaryOp_BitwiseOr +Expr_BitwiseXor => Expr_BinaryOp_BitwiseXor +Expr_BooleanAnd => Expr_BinaryOp_BooleanAnd +Expr_BooleanOr => Expr_BinaryOp_BooleanOr +Expr_Concat => Expr_BinaryOp_Concat +Expr_Div => Expr_BinaryOp_Div +Expr_Equal => Expr_BinaryOp_Equal +Expr_Greater => Expr_BinaryOp_Greater +Expr_GreaterOrEqual => Expr_BinaryOp_GreaterOrEqual +Expr_Identical => Expr_BinaryOp_Identical +Expr_LogicalAnd => Expr_BinaryOp_LogicalAnd +Expr_LogicalOr => Expr_BinaryOp_LogicalOr +Expr_LogicalXor => Expr_BinaryOp_LogicalXor +Expr_Minus => Expr_BinaryOp_Minus +Expr_Mod => Expr_BinaryOp_Mod +Expr_Mul => Expr_BinaryOp_Mul +Expr_NotEqual => Expr_BinaryOp_NotEqual +Expr_NotIdentical => Expr_BinaryOp_NotIdentical +Expr_Plus => Expr_BinaryOp_Plus +Expr_ShiftLeft => Expr_BinaryOp_ShiftLeft +Expr_ShiftRight => Expr_BinaryOp_ShiftRight +Expr_Smaller => Expr_BinaryOp_Smaller +Expr_SmallerOrEqual => Expr_BinaryOp_SmallerOrEqual + +Scalar_ClassConst => Scalar_MagicConst_Class +Scalar_DirConst => Scalar_MagicConst_Dir +Scalar_FileConst => Scalar_MagicConst_File +Scalar_FuncConst => Scalar_MagicConst_Function +Scalar_LineConst => Scalar_MagicConst_Line +Scalar_MethodConst => Scalar_MagicConst_Method +Scalar_NSConst => Scalar_MagicConst_Namespace +Scalar_TraitConst => Scalar_MagicConst_Trait +``` + +These changes may affect custom pretty printers and code comparing the return value of `Node::getType()` to specific +strings. + +### Miscellaneous + + * The classes `Template` and `TemplateLoader` have been removed. You should use some other [code generation][code_gen] + project built on top of PHP-Parser instead. + + * The `PrettyPrinterAbstract::pStmts()` method now emits a leading newline if the statement list is not empty. + Custom pretty printers should remove the explicit newline before `pStmts()` calls. + + Old: + + ```php + public function pStmt_Trait(PHPParser_Node_Stmt_Trait $node) { + return 'trait ' . $node->name + . "\n" . '{' . "\n" . $this->pStmts($node->stmts) . "\n" . '}'; + } + ``` + + New: + + ```php + public function pStmt_Trait(Stmt\Trait_ $node) { + return 'trait ' . $node->name + . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + } + ``` + + [code_gen]: https://github.com/nikic/PHP-Parser/wiki/Projects-using-the-PHP-Parser#code-generation \ No newline at end of file diff --git a/vendor/nikic/php-parser/UPGRADE-2.0.md b/vendor/nikic/php-parser/UPGRADE-2.0.md new file mode 100644 index 00000000..1c61de54 --- /dev/null +++ b/vendor/nikic/php-parser/UPGRADE-2.0.md @@ -0,0 +1,74 @@ +Upgrading from PHP-Parser 1.x to 2.0 +==================================== + +### PHP version requirements + +PHP-Parser now requires PHP 5.4 or newer to run. It is however still possible to *parse* PHP 5.2 and +PHP 5.3 source code, while running on a newer version. + +### Creating a parser instance + +Parser instances should now be created through the `ParserFactory`. Old direct instantiation code +will not work, because the parser class was renamed. + +Old: + +```php +use PhpParser\Parser, PhpParser\Lexer; +$parser = new Parser(new Lexer\Emulative); +``` + +New: + +```php +use PhpParser\ParserFactory; +$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); +``` + +The first argument to `ParserFactory` determines how different PHP versions are handled. The +possible values are: + + * `ParserFactory::PREFER_PHP7`: Try to parse code as PHP 7. If this fails, try to parse it as PHP 5. + * `ParserFactory::PREFER_PHP5`: Try to parse code as PHP 5. If this fails, try to parse it as PHP 7. + * `ParserFactory::ONLY_PHP7`: Parse code as PHP 7. + * `ParserFactory::ONLY_PHP5`: Parse code as PHP 5. + +For most practical purposes the difference between `PREFER_PHP7` and `PREFER_PHP5` is mainly whether +a scalar type hint like `string` will be stored as `'string'` (PHP 7) or as `new Name('string')` +(PHP 5). + +To use a custom lexer, pass it as the second argument to the `create()` method: + +```php +use PhpParser\ParserFactory; +$lexer = new MyLexer; +$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7, $lexer); +``` + +### Rename of the `PhpParser\Parser` class + +`PhpParser\Parser` is now an interface, which is implemented by `Parser\Php5`, `Parser\Php7` and +`Parser\Multiple`. Parser tokens are now defined in `Parser\Tokens`. If you use the `ParserFactory` +described above to create your parser instance, these changes should have no further impact on you. + +### Removal of legacy aliases + +All legacy aliases for classes have been removed. This includes the old non-namespaced `PHPParser_` +classes, as well as the classes that had to be renamed for PHP 7 support. + +### Deprecations + +The `set()`, `setFirst()`, `append()` and `prepend()` methods of the `Node\Name` class have been +deprecated. Instead `Name::concat()` and `Name->slice()` should be used. + +### Miscellaneous + +* The `NodeTraverser` no longer clones nodes by default. If you want to restore the old behavior, + pass `true` to the constructor. +* The legacy node format has been removed. If you use custom nodes, they are now expected to + implement a `getSubNodeNames()` method. +* The default value for `Scalar` node constructors was removed. This means that something like + `new LNumber()` should be replaced by `new LNumber(0)`. +* String parts of encapsed strings are now represented using `Scalar\EncapsStringPart` nodes, while + previously raw strings were used. This affects the `parts` child of `Scalar\Encaps` and + `Expr\ShellExec`. \ No newline at end of file diff --git a/vendor/nikic/php-parser/UPGRADE-3.0.md b/vendor/nikic/php-parser/UPGRADE-3.0.md new file mode 100644 index 00000000..9a2895f4 --- /dev/null +++ b/vendor/nikic/php-parser/UPGRADE-3.0.md @@ -0,0 +1,160 @@ +Upgrading from PHP-Parser 2.x to 3.0 +==================================== + +The backwards-incompatible changes in this release may be summarized as follows: + + * The specific details of the node representation have changed in some cases, primarily to + accommodate new PHP 7.1 features. + * There have been significant changes to the error recovery implementation. This may affect you, + if you used the error recovery mode or have a custom lexer implementation. + * A number of deprecated methods were removed. + +### PHP version requirements + +PHP-Parser now requires PHP 5.5 or newer to run. It is however still possible to *parse* PHP 5.2, +5.3 and 5.4 source code, while running on a newer version. + +### Changes to the node structure + +The following changes are likely to require code changes if the respective nodes are used: + + * The `List` subnode `vars` has been renamed to `items` and now contains `ArrayItem`s instead of + plain variables. + * The `Catch` subnode `type` has been renamed to `types` and is now an array of `Name`s. + * The `TryCatch` subnode `finallyStmts` has been replaced with a `finally` subnode that holds an + explicit `Finally` node. + * The `type` subnode on `Class`, `ClassMethod` and `Property` has been renamed to `flags`. The + `type` subnode has retained for backwards compatibility and is populated to the same value as + `flags`. However, writes to `type` will not update `flags` and use of `type` is discouraged. + +The following changes are unlikely to require code changes: + + * The `ClassConst` constructor changed to accept an additional `flags` subnode. + * The `Trait` constructor now has the same form as the `Class` and `Interface` constructors: It + takes an array of subnodes. Unlike classes/interfaces, traits can only have a `stmts` subnode. + * The `Array` subnode `items` may now contain `null` elements (due to destructuring). + * `void` and `iterable` types are now stored as strings if the PHP 7 parser is used. Previously + these would have been represented as `Name` instances. + +### Changes to error recovery mode + +Previously, error recovery mode was enabled by setting the `throwOnError` option to `false` when +creating the parser, while collected errors were retrieved using the `getErrors()` method: + +```php +$lexer = ...; +$parser = (new ParserFactory)->create(ParserFactor::ONLY_PHP7, $lexer, [ + 'throwOnError' => true, +]); + +$stmts = $parser->parse($code); +$errors = $parser->getErrors(); +if ($errors) { + handleErrors($errors); +} +processAst($stmts); +``` + +Both the `throwOnError` option and the `getErrors()` method have been removed in PHP-Parser 3.0. +Instead an instance of `ErrorHandler\Collecting` should be passed to the `parse()` method: + +```php +$lexer = ...; +$parser = (new ParserFactory)->create(ParserFactor::ONLY_PHP7, $lexer); + +$errorHandler = new ErrorHandler\Collecting; +$stmts = $parser->parse($code, $errorHandler); +if ($errorHandler->hasErrors()) { + handleErrors($errorHandler->getErrors()); +} +processAst($stmts); +``` + +#### Multiple parser fallback in error recovery mode + +As a result of this change, if a `Multiple` parser is used (e.g. through the `ParserFactory` using +`PREFER_PHP7` or `PREFER_PHP5`), it will now return the result of the first *non-throwing* parse. As +parsing never throws in error recovery mode, the result from the first parser will always be +returned. + +The PHP 7 parser is a superset of the PHP 5 parser, with the exceptions that `=& new` and +`global $$foo->bar` are not supported (other differences are in representation only). The PHP 7 +parser will be able to recover from the error in both cases. For this reason, this change will +likely pass unnoticed if you do not specifically test for this syntax. + +It is possible to restore the precise previous behavior with the following code: + +```php +$lexer = ...; +$parser7 = new Parser\Php7($lexer); +$parser5 = new Parser\Php5($lexer); + +$errors7 = new ErrorHandler\Collecting(); +$stmts7 = $parser7->parse($code, $errors7); +if ($errors7->hasErrors()) { + $errors5 = new ErrorHandler\Collecting(); + $stmts5 = $parser5->parse($code, $errors5); + if (!$errors5->hasErrors()) { + // If PHP 7 parse has errors but PHP 5 parse has no errors, use PHP 5 result + return [$stmts5, $errors5]; + } +} +// If PHP 7 succeeds or both fail use PHP 7 result +return [$stmts7, $errors7]; +``` + +#### Error handling in the lexer + +In order to support recovery from lexer errors, the signature of the `startLexing()` method changed +to optionally accept an `ErrorHandler`: + +```php +// OLD +public function startLexing($code); +// NEW +public function startLexing($code, ErrorHandler $errorHandler = null); +``` + +If you use a custom lexer with overridden `startLexing()` method, it needs to be changed to accept +the extra parameter. The value should be passed on to the parent method. + +#### Error checks in node constructors + +The constructors of certain nodes used to contain additional checks for semantic errors, such as +creating a try block without either catch or finally. These checks have been moved from the node +constructors into the parser. This allows recovery from such errors, as well as representing the +resulting (invalid) AST. + +This means that certain error conditions are no longer checked for manually constructed nodes. + +### Removed methods, arguments, options + +The following methods, arguments or options have been removed: + + * `Comment::setLine()`, `Comment::setText()`: Create new `Comment` instances instead. + * `Name::set()`, `Name::setFirst()`, `Name::setLast()`, `Name::append()`, `Name::prepend()`: + Use `Name::concat()` in combination with `Name::slice()` instead. + * `Error::getRawLine()`, `Error::setRawLine()`. Use `Error::getStartLine()` and + `Error::setStartLine()` instead. + * `Parser::getErrors()`. Use `ErrorHandler\Collecting` instead. + * `$separator` argument of `Name::toString()`. Use `strtr()` instead, if you really need it. + * `$cloneNodes` argument of `NodeTraverser::__construct()`. Explicitly clone nodes in the visitor + instead. + * `throwOnError` parser option. Use `ErrorHandler\Collecting` instead. + +### Miscellaneous + + * The `NameResolver` will now resolve unqualified function and constant names in the global + namespace into fully qualified names. For example `foo()` in the global namespace resolves to + `\foo()`. For names where no static resolution is possible, a `namespacedName` attribute is + added now, containing the namespaced variant of the name. + * All methods on `PrettyPrinter\Standard` are now protected. Previously most of them were public. + The pretty printer should only be invoked using the `prettyPrint()`, `prettyPrintFile()` and + `prettyPrintExpr()` methods. + * The node dumper now prints numeric values that act as enums/flags in a string representation. + If node dumper results are used in tests, updates may be needed to account for this. + * The constants on `NameTraverserInterface` have been moved into the `NameTraverser` class. + * The emulative lexer now directly postprocesses tokens, instead of using `~__EMU__~` sequences. + This changes the protected API of the emulative lexer. + * The `Name::slice()` method now returns `null` for empty slices, previously `new Name([])` was + used. `Name::concat()` now also supports concatenation with `null`. diff --git a/vendor/nikic/php-parser/UPGRADE-4.0.md b/vendor/nikic/php-parser/UPGRADE-4.0.md new file mode 100644 index 00000000..628bdbdc --- /dev/null +++ b/vendor/nikic/php-parser/UPGRADE-4.0.md @@ -0,0 +1,77 @@ +Upgrading from PHP-Parser 3.x to 4.0 +==================================== + +### PHP version requirements + +PHP-Parser now requires PHP 7.0 or newer to run. It is however still possible to *parse* PHP 5.2-5.6 +source code, while running on a newer version. + +HHVM is no longer actively supported. + +### Changes to the node structure + +* Many subnodes that previously held simple strings now store `Identifier` nodes instead (or + `VarLikeIdentifier` nodes if they have form `$ident`). The constructors of the affected nodes will + automatically convert strings to `Identifier`s and `Identifier`s implement `__toString()`. As such + some code continues to work without changes, but anything using `is_string()`, type-strict + comparisons or strict-mode may require adjustment. The following is an exhaustive list of all + affected subnodes: + + * `Const_::$name` + * `NullableType::$type` (for simple types) + * `Param::$type` (for simple types) + * `Expr\ClassConstFetch::$name` + * `Expr\Closure::$returnType` (for simple types) + * `Expr\MethodCall::$name` + * `Expr\PropertyFetch::$name` + * `Expr\StaticCall::$name` + * `Expr\StaticPropertyFetch::$name` (uses `VarLikeIdentifier`) + * `Stmt\Class_::$name` + * `Stmt\ClassMethod::$name` + * `Stmt\ClassMethod::$returnType` (for simple types) + * `Stmt\Function_::$name` + * `Stmt\Function_::$returnType` (for simple types) + * `Stmt\Goto_::$name` + * `Stmt\Interface_::$name` + * `Stmt\Label::$name` + * `Stmt\PropertyProperty::$name` (uses `VarLikeIdentifier`) + * `Stmt\TraitUseAdaptation\Alias::$method` + * `Stmt\TraitUseAdaptation\Alias::$newName` + * `Stmt\TraitUseAdaptation\Precedence::$method` + * `Stmt\Trait_::$name` + * `Stmt\UseUse::$alias` + +* Expression statements (`expr;`) are now represented using a `Stmt\Expression` node. Previously + these statements were directly represented as their constituent expression. +* The `name` subnode of `Param` has been renamed to `var` and now contains a `Variable` rather than + a plain string. +* The `name` subnode of `StaticVar` has been renamed to `var` and now contains a `Variable` rather + than a plain string. +* The `var` subnode of `ClosureUse` now contains a `Variable` rather than a plain string. +* The `var` subnode of `Catch_` now contains a `Variable` rather than a plain string. +* The `alias` subnode of `UseUse` is now `null` if no explicit alias is given. As such, + `use Foo\Bar` and `use Foo\Bar as Bar` are now represented differently. The `getAlias()` method + can be used to get the effective alias, even if it is not explicitly given. + +### Miscellaneous + +* The indentation handling in the pretty printer has been changed (this is only relevant if you + extend the pretty printer). Previously indentation was automatic, and parts were excluded using + `pNoindent()`. Now no-indent is the default and newlines that require indentation should use + `$this->nl`. + +### Removed functionality + +* Removed `type` subnode on `Class_`, `ClassMethod` and `Property` nodes. Use `flags` instead. +* The `ClassConst::isStatic()` method has been removed. Constants cannot have a static modifier. +* The `NodeTraverser` no longer accepts `false` as a return value from a `leaveNode()` method. + `NodeTraverser::REMOVE_NODE` should be returned instead. +* The `Node::setLine()` method has been removed. If you really need to, you can use `setAttribute()` + instead. +* The misspelled `Class_::VISIBILITY_MODIFER_MASK` constant has been dropped in favor of + `Class_::VISIBILITY_MODIFIER_MASK`. +* The XML serializer has been removed. As such, the classes `Serializer\XML`, and + `Unserializer\XML`, as well as the interfaces `Serializer` and `Unserializer` no longer exist. +* The `BuilderAbstract` class has been removed. It's functionality is moved into `BuilderHelpers`. + However, this is an internal class and should not be used directly. +* The `Autoloader` class has been removed in favor of relying on the Composer autoloader. diff --git a/vendor/nikic/php-parser/bin/php-parse b/vendor/nikic/php-parser/bin/php-parse new file mode 100755 index 00000000..5dd01ba1 --- /dev/null +++ b/vendor/nikic/php-parser/bin/php-parse @@ -0,0 +1,202 @@ +#!/usr/bin/env php + [ + 'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments' +]]); +$parser = (new PhpParser\ParserFactory)->create( + PhpParser\ParserFactory::PREFER_PHP7, + $lexer +); +$dumper = new PhpParser\NodeDumper([ + 'dumpComments' => true, + 'dumpPositions' => $attributes['with-positions'], +]); +$prettyPrinter = new PhpParser\PrettyPrinter\Standard; + +$traverser = new PhpParser\NodeTraverser(); +$traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver); + +foreach ($files as $file) { + if (strpos($file, ' Code $code\n"; + } else { + if (!file_exists($file)) { + die("File $file does not exist.\n"); + } + + $code = file_get_contents($file); + echo "====> File $file:\n"; + } + + if ($attributes['with-recovery']) { + $errorHandler = new PhpParser\ErrorHandler\Collecting; + $stmts = $parser->parse($code, $errorHandler); + foreach ($errorHandler->getErrors() as $error) { + $message = formatErrorMessage($error, $code, $attributes['with-column-info']); + echo $message . "\n"; + } + if (null === $stmts) { + continue; + } + } else { + try { + $stmts = $parser->parse($code); + } catch (PhpParser\Error $error) { + $message = formatErrorMessage($error, $code, $attributes['with-column-info']); + die($message . "\n"); + } + } + + foreach ($operations as $operation) { + if ('dump' === $operation) { + echo "==> Node dump:\n"; + echo $dumper->dump($stmts, $code), "\n"; + } elseif ('pretty-print' === $operation) { + echo "==> Pretty print:\n"; + echo $prettyPrinter->prettyPrintFile($stmts), "\n"; + } elseif ('json-dump' === $operation) { + echo "==> JSON dump:\n"; + echo json_encode($stmts, JSON_PRETTY_PRINT), "\n"; + } elseif ('var-dump' === $operation) { + echo "==> var_dump():\n"; + var_dump($stmts); + } elseif ('resolve-names' === $operation) { + echo "==> Resolved names.\n"; + $stmts = $traverser->traverse($stmts); + } + } +} + +function formatErrorMessage(PhpParser\Error $e, $code, $withColumnInfo) { + if ($withColumnInfo && $e->hasColumnInfo()) { + return $e->getMessageWithColumnInfo($code); + } else { + return $e->getMessage(); + } +} + +function showHelp($error = '') { + if ($error) { + echo $error . "\n\n"; + } + die(<< false, + 'with-positions' => false, + 'with-recovery' => false, + ]; + + array_shift($args); + $parseOptions = true; + foreach ($args as $arg) { + if (!$parseOptions) { + $files[] = $arg; + continue; + } + + switch ($arg) { + case '--dump': + case '-d': + $operations[] = 'dump'; + break; + case '--pretty-print': + case '-p': + $operations[] = 'pretty-print'; + break; + case '--json-dump': + case '-j': + $operations[] = 'json-dump'; + break; + case '--var-dump': + $operations[] = 'var-dump'; + break; + case '--resolve-names': + case '-N'; + $operations[] = 'resolve-names'; + break; + case '--with-column-info': + case '-c'; + $attributes['with-column-info'] = true; + break; + case '--with-positions': + case '-P': + $attributes['with-positions'] = true; + break; + case '--with-recovery': + case '-r': + $attributes['with-recovery'] = true; + break; + case '--help': + case '-h'; + showHelp(); + break; + case '--': + $parseOptions = false; + break; + default: + if ($arg[0] === '-') { + showHelp("Invalid operation $arg."); + } else { + $files[] = $arg; + } + } + } + + return [$operations, $files, $attributes]; +} diff --git a/vendor/nikic/php-parser/composer.json b/vendor/nikic/php-parser/composer.json new file mode 100644 index 00000000..97428539 --- /dev/null +++ b/vendor/nikic/php-parser/composer.json @@ -0,0 +1,40 @@ +{ + "name": "nikic/php-parser", + "type": "library", + "description": "A PHP parser written in PHP", + "keywords": [ + "php", + "parser" + ], + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Nikita Popov" + } + ], + "require": { + "php": ">=7.0", + "ext-tokenizer": "*" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "autoload-dev": { + "psr-4": { + "PhpParser\\": "test/PhpParser/" + } + }, + "bin": [ + "bin/php-parse" + ] +} diff --git a/vendor/nikic/php-parser/doc/0_Introduction.markdown b/vendor/nikic/php-parser/doc/0_Introduction.markdown new file mode 100644 index 00000000..abc40f2b --- /dev/null +++ b/vendor/nikic/php-parser/doc/0_Introduction.markdown @@ -0,0 +1,80 @@ +Introduction +============ + +This project is a PHP 5.2 to PHP 7.3 parser **written in PHP itself**. + +What is this for? +----------------- + +A parser is useful for [static analysis][0], manipulation of code and basically any other +application dealing with code programmatically. A parser constructs an [Abstract Syntax Tree][1] +(AST) of the code and thus allows dealing with it in an abstract and robust way. + +There are other ways of processing source code. One that PHP supports natively is using the +token stream generated by [`token_get_all`][2]. The token stream is much more low level than +the AST and thus has different applications: It allows to also analyze the exact formatting of +a file. On the other hand the token stream is much harder to deal with for more complex analysis. +For example, an AST abstracts away the fact that, in PHP, variables can be written as `$foo`, but also +as `$$bar`, `${'foobar'}` or even `${!${''}=barfoo()}`. You don't have to worry about recognizing +all the different syntaxes from a stream of tokens. + +Another question is: Why would I want to have a PHP parser *written in PHP*? Well, PHP might not be +a language especially suited for fast parsing, but processing the AST is much easier in PHP than it +would be in other, faster languages like C. Furthermore the people most probably wanting to do +programmatic PHP code analysis are incidentally PHP developers, not C developers. + +What can it parse? +------------------ + +The parser supports parsing PHP 5.2-7.3. + +As the parser is based on the tokens returned by `token_get_all` (which is only able to lex the PHP +version it runs on), additionally a wrapper for emulating tokens from newer versions is provided. +This allows to parse PHP 7.3 source code running on PHP 7.0, for example. This emulation is somewhat +hacky and not perfect, but it should work well on any sane code. + +What output does it produce? +---------------------------- + +The parser produces an [Abstract Syntax Tree][1] (AST) also known as a node tree. How this looks +can best be seen in an example. The program `create(ParserFactory::PREFER_PHP7); +``` + +The factory accepts a kind argument, that determines how different PHP versions are treated: + +Kind | Behavior +-----|--------- +`ParserFactory::PREFER_PHP7` | Try to parse code as PHP 7. If this fails, try to parse it as PHP 5. +`ParserFactory::PREFER_PHP5` | Try to parse code as PHP 5. If this fails, try to parse it as PHP 7. +`ParserFactory::ONLY_PHP7` | Parse code as PHP 7. +`ParserFactory::ONLY_PHP5` | Parse code as PHP 5. + +Unless you have a strong reason to use something else, `PREFER_PHP7` is a reasonable default. + +The `create()` method optionally accepts a `Lexer` instance as the second argument. Some use cases +that require customized lexers are discussed in the [lexer documentation](component/Lexer.markdown). + +Subsequently you can pass PHP code (including the opening `create(ParserFactory::PREFER_PHP7); + +try { + $stmts = $parser->parse($code); + // $stmts is an array of statement nodes +} catch (Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +A parser instance can be reused to parse multiple files. + +Node dumping +------------ + +To dump the abstact syntax tree in human readable form, a `NodeDumper` can be used: + +```php +dump($stmts), "\n"; +``` + +For the sample code from the previous section, this will produce the following output: + +``` +array( + 0: Stmt_Function( + byRef: false + name: Identifier( + name: printLine + ) + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: msg + ) + default: null + ) + ) + returnType: null + stmts: array( + 0: Stmt_Echo( + exprs: array( + 0: Expr_Variable( + name: msg + ) + 1: Scalar_String( + value: + + ) + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: printLine + ) + ) + args: array( + 0: Arg( + value: Scalar_String( + value: Hello World!!! + ) + byRef: false + unpack: false + ) + ) + ) + ) +) +``` + +You can also use the `php-parse` script to obtain such a node dump by calling it either with a file +name or code string: + +```sh +vendor/bin/php-parse file.php +vendor/bin/php-parse " PhpParser\Node\Stmt\Function_` + * `Stmt_Expression -> PhpParser\Node\Stmt\Expression` + +The additional `_` at the end of the first class name is necessary, because `Function` is a +reserved keyword. Many node class names in this library have a trailing `_` to avoid clashing with +a keyword. + +As PHP is a large language there are approximately 140 different nodes. In order to make working +with them easier they are grouped into three categories: + + * `PhpParser\Node\Stmt`s are statement nodes, i.e. language constructs that do not return + a value and can not occur in an expression. For example a class definition is a statement. + It doesn't return a value and you can't write something like `func(class A {});`. + * `PhpParser\Node\Expr`s are expression nodes, i.e. language constructs that return a value + and thus can occur in other expressions. Examples of expressions are `$var` + (`PhpParser\Node\Expr\Variable`) and `func()` (`PhpParser\Node\Expr\FuncCall`). + * `PhpParser\Node\Scalar`s are nodes representing scalar values, like `'string'` + (`PhpParser\Node\Scalar\String_`), `0` (`PhpParser\Node\Scalar\LNumber`) or magic constants + like `__FILE__` (`PhpParser\Node\Scalar\MagicConst\File`). All `PhpParser\Node\Scalar`s extend + `PhpParser\Node\Expr`, as scalars are expressions, too. + * There are some nodes not in either of these groups, for example names (`PhpParser\Node\Name`) + and call arguments (`PhpParser\Node\Arg`). + +The `Node\Stmt\Expression` node is somewhat confusing in that it contains both the terms "statement" +and "expression". This node distinguishes `expr`, which is a `Node\Expr`, from `expr;`, which is +an "expression statement" represented by `Node\Stmt\Expression` and containing `expr` as a sub-node. + +Every node has a (possibly zero) number of subnodes. You can access subnodes by writing +`$node->subNodeName`. The `Stmt\Echo_` node has only one subnode `exprs`. So in order to access it +in the above example you would write `$stmts[0]->exprs`. If you wanted to access the name of the function +call, you would write `$stmts[0]->exprs[1]->name`. + +All nodes also define a `getType()` method that returns the node type. The type is the class name +without the `PhpParser\Node\` prefix and `\` replaced with `_`. It also does not contain a trailing +`_` for reserved-keyword class names. + +It is possible to associate custom metadata with a node using the `setAttribute()` method. This data +can then be retrieved using `hasAttribute()`, `getAttribute()` and `getAttributes()`. + +By default the lexer adds the `startLine`, `endLine` and `comments` attributes. `comments` is an array +of `PhpParser\Comment[\Doc]` instances. + +The start line can also be accessed using `getLine()`/`setLine()` (instead of `getAttribute('startLine')`). +The last doc comment from the `comments` attribute can be obtained using `getDocComment()`. + +Pretty printer +-------------- + +The pretty printer component compiles the AST back to PHP code. As the parser does not retain formatting +information the formatting is done using a specified scheme. Currently there is only one scheme available, +namely `PhpParser\PrettyPrinter\Standard`. + +```php +use PhpParser\Error; +use PhpParser\ParserFactory; +use PhpParser\PrettyPrinter; + +$code = "create(ParserFactory::PREFER_PHP7); +$prettyPrinter = new PrettyPrinter\Standard; + +try { + // parse + $stmts = $parser->parse($code); + + // change + $stmts[0] // the echo statement + ->exprs // sub expressions + [0] // the first of them (the string node) + ->value // it's value, i.e. 'Hi ' + = 'Hello '; // change to 'Hello ' + + // pretty print + $code = $prettyPrinter->prettyPrint($stmts); + + echo $code; +} catch (Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +The above code will output: + + echo 'Hello ', hi\getTarget(); + +As you can see the source code was first parsed using `PhpParser\Parser->parse()`, then changed and then +again converted to code using `PhpParser\PrettyPrinter\Standard->prettyPrint()`. + +The `prettyPrint()` method pretty prints a statements array. It is also possible to pretty print only a +single expression using `prettyPrintExpr()`. + +The `prettyPrintFile()` method can be used to print an entire file. This will include the opening ` Read more: [Pretty printing documentation](component/Pretty_printing.markdown) + +Node traversation +----------------- + +The above pretty printing example used the fact that the source code was known and thus it was easy to +write code that accesses a certain part of a node tree and changes it. Normally this is not the case. +Usually you want to change / analyze code in a generic way, where you don't know how the node tree is +going to look like. + +For this purpose the parser provides a component for traversing and visiting the node tree. The basic +structure of a program using this `PhpParser\NodeTraverser` looks like this: + +```php +use PhpParser\NodeTraverser; +use PhpParser\ParserFactory; +use PhpParser\PrettyPrinter; + +$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); +$traverser = new NodeTraverser; +$prettyPrinter = new PrettyPrinter\Standard; + +// add your visitor +$traverser->addVisitor(new MyNodeVisitor); + +try { + $code = file_get_contents($fileName); + + // parse + $stmts = $parser->parse($code); + + // traverse + $stmts = $traverser->traverse($stmts); + + // pretty print + $code = $prettyPrinter->prettyPrintFile($stmts); + + echo $code; +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +The corresponding node visitor might look like this: + +```php +use PhpParser\Node; +use PhpParser\NodeVisitorAbstract; + +class MyNodeVisitor extends NodeVisitorAbstract +{ + public function leaveNode(Node $node) { + if ($node instanceof Node\Scalar\String_) { + $node->value = 'foo'; + } + } +} +``` + +The above node visitor would change all string literals in the program to `'foo'`. + +All visitors must implement the `PhpParser\NodeVisitor` interface, which defines the following four +methods: + +```php +public function beforeTraverse(array $nodes); +public function enterNode(\PhpParser\Node $node); +public function leaveNode(\PhpParser\Node $node); +public function afterTraverse(array $nodes); +``` + +The `beforeTraverse()` method is called once before the traversal begins and is passed the nodes the +traverser was called with. This method can be used for resetting values before traversation or +preparing the tree for traversal. + +The `afterTraverse()` method is similar to the `beforeTraverse()` method, with the only difference that +it is called once after the traversal. + +The `enterNode()` and `leaveNode()` methods are called on every node, the former when it is entered, +i.e. before its subnodes are traversed, the latter when it is left. + +All four methods can either return the changed node or not return at all (i.e. `null`) in which +case the current node is not changed. + +The `enterNode()` method can additionally return the value `NodeTraverser::DONT_TRAVERSE_CHILDREN`, +which instructs the traverser to skip all children of the current node. To furthermore prevent subsequent +visitors from visiting the current node, `NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN` can be used instead. + +The `leaveNode()` method can additionally return the value `NodeTraverser::REMOVE_NODE`, in which +case the current node will be removed from the parent array. Furthermore it is possible to return +an array of nodes, which will be merged into the parent array at the offset of the current node. +I.e. if in `array(A, B, C)` the node `B` should be replaced with `array(X, Y, Z)` the result will +be `array(A, X, Y, Z, C)`. + +Instead of manually implementing the `NodeVisitor` interface you can also extend the `NodeVisitorAbstract` +class, which will define empty default implementations for all the above methods. + +> Read more: [Walking the AST](component/Walking_the_AST.markdown) + +The NameResolver node visitor +----------------------------- + +One visitor that is already bundled with the package is `PhpParser\NodeVisitor\NameResolver`. This visitor +helps you work with namespaced code by trying to resolve most names to fully qualified ones. + +For example, consider the following code: + + use A as B; + new B\C(); + +In order to know that `B\C` really is `A\C` you would need to track aliases and namespaces yourself. +The `NameResolver` takes care of that and resolves names as far as possible. + +After running it, most names will be fully qualified. The only names that will stay unqualified are +unqualified function and constant names. These are resolved at runtime and thus the visitor can't +know which function they are referring to. In most cases this is a non-issue as the global functions +are meant. + +Also the `NameResolver` adds a `namespacedName` subnode to class, function and constant declarations +that contains the namespaced name instead of only the shortname that is available via `name`. + +> Read more: [Name resolution documentation](component/Name_resolution.markdown) + +Example: Converting namespaced code to pseudo namespaces +-------------------------------------------------------- + +A small example to understand the concept: We want to convert namespaced code to pseudo namespaces +so it works on 5.2, i.e. names like `A\\B` should be converted to `A_B`. Note that such conversions +are fairly complicated if you take PHP's dynamic features into account, so our conversion will +assume that no dynamic features are used. + +We start off with the following base code: + +```php +use PhpParser\ParserFactory; +use PhpParser\PrettyPrinter; +use PhpParser\NodeTraverser; +use PhpParser\NodeVisitor\NameResolver; + +$inDir = '/some/path'; +$outDir = '/some/other/path'; + +$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); +$traverser = new NodeTraverser; +$prettyPrinter = new PrettyPrinter\Standard; + +$traverser->addVisitor(new NameResolver); // we will need resolved names +$traverser->addVisitor(new NamespaceConverter); // our own node visitor + +// iterate over all .php files in the directory +$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($inDir)); +$files = new \RegexIterator($files, '/\.php$/'); + +foreach ($files as $file) { + try { + // read the file that should be converted + $code = file_get_contents($file->getPathName()); + + // parse + $stmts = $parser->parse($code); + + // traverse + $stmts = $traverser->traverse($stmts); + + // pretty print + $code = $prettyPrinter->prettyPrintFile($stmts); + + // write the converted file to the target directory + file_put_contents( + substr_replace($file->getPathname(), $outDir, 0, strlen($inDir)), + $code + ); + } catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); + } +} +``` + +Now lets start with the main code, the `NodeVisitor\NamespaceConverter`. One thing it needs to do +is convert `A\\B` style names to `A_B` style ones. + +```php +use PhpParser\Node; + +class NamespaceConverter extends \PhpParser\NodeVisitorAbstract +{ + public function leaveNode(Node $node) { + if ($node instanceof Node\Name) { + return new Node\Name(str_replace('\\', '_', $node->toString())); + } + } +} +``` + +The above code profits from the fact that the `NameResolver` already resolved all names as far as +possible, so we don't need to do that. We only need to create a string with the name parts separated +by underscores instead of backslashes. This is what `str_replace('\\', '_', $node->toString())` does. (If you want to +create a name with backslashes either write `$node->toString()` or `(string) $node`.) Then we create +a new name from the string and return it. Returning a new node replaces the old node. + +Another thing we need to do is change the class/function/const declarations. Currently they contain +only the shortname (i.e. the last part of the name), but they need to contain the complete name including +the namespace prefix: + +```php +use PhpParser\Node; +use PhpParser\Node\Stmt; + +class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract +{ + public function leaveNode(Node $node) { + if ($node instanceof Node\Name) { + return new Node\Name(str_replace('\\', '_', $node->toString())); + } elseif ($node instanceof Stmt\Class_ + || $node instanceof Stmt\Interface_ + || $node instanceof Stmt\Function_) { + $node->name = str_replace('\\', '_', $node->namespacedName->toString()); + } elseif ($node instanceof Stmt\Const_) { + foreach ($node->consts as $const) { + $const->name = str_replace('\\', '_', $const->namespacedName->toString()); + } + } + } +} +``` + +There is not much more to it than converting the namespaced name to string with `_` as separator. + +The last thing we need to do is remove the `namespace` and `use` statements: + +```php +use PhpParser\Node; +use PhpParser\Node\Stmt; +use PhpParser\NodeTraverser; + +class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract +{ + public function leaveNode(Node $node) { + if ($node instanceof Node\Name) { + return new Node\Name(str_replace('\\', '_', $node->toString())); + } elseif ($node instanceof Stmt\Class_ + || $node instanceof Stmt\Interface_ + || $node instanceof Stmt\Function_) { + $node->name = str_replace('\\', '_', $node->namespacedName->toString(); + } elseif ($node instanceof Stmt\Const_) { + foreach ($node->consts as $const) { + $const->name = str_replace('\\', '_', $const->namespacedName->toString()); + } + } elseif ($node instanceof Stmt\Namespace_) { + // returning an array merges is into the parent array + return $node->stmts; + } elseif ($node instanceof Stmt\Use_) { + // remove use nodes altogether + return NodeTraverser::REMOVE_NODE; + } + } +} +``` + +That's all. diff --git a/vendor/nikic/php-parser/doc/README.md b/vendor/nikic/php-parser/doc/README.md new file mode 100644 index 00000000..3b8cd765 --- /dev/null +++ b/vendor/nikic/php-parser/doc/README.md @@ -0,0 +1,46 @@ +Table of Contents +================= + +Guide +----- + + 1. [Introduction](0_Introduction.markdown) + 2. [Usage of basic components](2_Usage_of_basic_components.markdown) + +Component documentation +----------------------- + + * [Walking the AST](component/Walking_the_AST.markdown) + * Node visitors + * Modifying the AST from a visitor + * Short-circuiting traversals + * Interleaved visitors + * Simple node finding API + * Parent and sibling references + * [Name resolution](component/Name_resolution.markdown) + * Name resolver options + * Name resolution context + * [Pretty printing](component/Pretty_printing.markdown) + * Converting AST back to PHP code + * Customizing formatting + * Formatting-preserving code transformations + * [AST builders](component/AST_builders.markdown) + * Fluent builders for AST nodes + * [Lexer](component/Lexer.markdown) + * Lexer options + * Token and file positions for nodes + * Custom attributes + * [Error handling](component/Error_handling.markdown) + * Column information for errors + * Error recovery (parsing of syntactically incorrect code) + * [Constant expression evaluation](component/Constant_expression_evaluation.markdown) + * Evaluating constant/property/etc initializers + * Handling errors and unsupported expressions + * [JSON representation](component/JSON_representation.markdown) + * JSON encoding and decoding of ASTs + * [Performance](component/Performance.markdown) + * Disabling XDebug + * Reusing objects + * Garbage collection impact + * [Frequently asked questions](component/FAQ.markdown) + * Parent and sibling references diff --git a/vendor/nikic/php-parser/doc/component/AST_builders.markdown b/vendor/nikic/php-parser/doc/component/AST_builders.markdown new file mode 100644 index 00000000..60ae0192 --- /dev/null +++ b/vendor/nikic/php-parser/doc/component/AST_builders.markdown @@ -0,0 +1,138 @@ +AST builders +============ + +When PHP-Parser is used to generate (or modify) code by first creating an Abstract Syntax Tree and +then using the [pretty printer](Pretty_printing.markdown) to convert it to PHP code, it can often +be tedious to manually construct AST nodes. The project provides a number of utilities to simplify +the construction of common AST nodes. + +Fluent builders +--------------- + +The library comes with a number of builders, which allow creating node trees using a fluent +interface. Builders are created using the `BuilderFactory` and the final constructed node is +accessed through `getNode()`. Fluent builders are available for +the following syntactic elements: + + * namespaces and use statements + * classes, interfaces and traits + * methods, functions and parameters + * properties + +Here is an example: + +```php +use PhpParser\BuilderFactory; +use PhpParser\PrettyPrinter; +use PhpParser\Node; + +$factory = new BuilderFactory; +$node = $factory->namespace('Name\Space') + ->addStmt($factory->use('Some\Other\Thingy')->as('SomeClass')) + ->addStmt($factory->useFunction('strlen')) + ->addStmt($factory->useConst('PHP_VERSION')) + ->addStmt($factory->class('SomeOtherClass') + ->extend('SomeClass') + ->implement('A\Few', '\Interfaces') + ->makeAbstract() // ->makeFinal() + + ->addStmt($factory->useTrait('FirstTrait')) + + ->addStmt($factory->useTrait('SecondTrait', 'ThirdTrait') + ->and('AnotherTrait') + ->with($factory->traitUseAdaptation('foo')->as('bar')) + ->with($factory->traitUseAdaptation('AnotherTrait', 'baz')->as('test')) + ->with($factory->traitUseAdaptation('AnotherTrait', 'func')->insteadof('SecondTrait'))) + + ->addStmt($factory->method('someMethod') + ->makePublic() + ->makeAbstract() // ->makeFinal() + ->setReturnType('bool') // ->makeReturnByRef() + ->addParam($factory->param('someParam')->setType('SomeClass')) + ->setDocComment('/** + * This method does something. + * + * @param SomeClass And takes a parameter + */') + ) + + ->addStmt($factory->method('anotherMethod') + ->makeProtected() // ->makePublic() [default], ->makePrivate() + ->addParam($factory->param('someParam')->setDefault('test')) + // it is possible to add manually created nodes + ->addStmt(new Node\Expr\Print_(new Node\Expr\Variable('someParam'))) + ) + + // properties will be correctly reordered above the methods + ->addStmt($factory->property('someProperty')->makeProtected()) + ->addStmt($factory->property('anotherProperty')->makePrivate()->setDefault(array(1, 2, 3))) + ) + + ->getNode() +; + +$stmts = array($node); +$prettyPrinter = new PrettyPrinter\Standard(); +echo $prettyPrinter->prettyPrintFile($stmts); +``` + +This will produce the following output with the standard pretty printer: + +```php +evaluateSilently($someExpr); +} catch (ConstExprEvaluationException $e) { + // Either the expression contains unsupported expression types, + // or an error occurred during evaluation +} +``` + +Error handling +-------------- + +The constant evaluator provides two methods, `evaluateDirectly()` and `evaluateSilently()`, which +differ in error behavior. `evaluateDirectly()` will evaluate the expression as PHP would, including +any generated warnings or Errors. `evaluateSilently()` will instead convert warnings and Errors into +a `ConstExprEvaluationException`. For example: + +```php +evaluateDirectly($expr)); // float(INF) +// Warning: Division by zero + +try { + $evaluator->evaluateSilently($expr); +} catch (ConstExprEvaluationException $e) { + var_dump($e->getPrevious()->getMessage()); // Division by zero +} +``` + +For the purposes of static analysis, you will likely want to use `evaluateSilently()` and leave +erroring expressions unevaluated. + +Unsupported expressions and evaluator fallback +---------------------------------------------- + +The constant expression evaluator supports all expression types that are permitted in constant +expressions, apart from the following: + + * `Scalar\MagicConst\*` + * `Expr\ConstFetch` (only null/false/true are handled) + * `Expr\ClassConstFetch` + +Handling these expression types requires non-local information, such as which global constants are +defined. By default, the evaluator will throw a `ConstExprEvaluationException` when it encounters +an unsupported expression type. + +It is possible to override this behavior and support resolution for these expression types by +specifying an evaluation fallback function: + +```php +getType()} cannot be evaluated"); +}); + +try { + $evalutator->evaluateSilently($someExpr); +} catch (ConstExprEvaluationException $e) { + // Handle exception +} +``` + +Implementers are advised to ensure that evaluation of indirect constant references cannot lead to +infinite recursion. For example, the following code could lead to infinite recursion if constant +lookup is implemented naively. + +```php + array('comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'), +)); +$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer); + +try { + $stmts = $parser->parse($code); + // ... +} catch (PhpParser\Error $e) { + // ... +} +``` + +Before using column information, its availability needs to be checked with `$e->hasColumnInfo()`, as the precise +location of an error cannot always be determined. The methods for retrieving column information also have to be passed +the source code of the parsed file. An example for printing an error: + +```php +if ($e->hasColumnInfo()) { + echo $e->getRawMessage() . ' from ' . $e->getStartLine() . ':' . $e->getStartColumn($code) + . ' to ' . $e->getEndLine() . ':' . $e->getEndColumn($code); + // or: + echo $e->getMessageWithColumnInfo(); +} else { + echo $e->getMessage(); +} +``` + +Both line numbers and column numbers are 1-based. EOF errors will be located at the position one past the end of the +file. + +Error recovery +-------------- + +The error behavior of the parser (and other components) is controlled by an `ErrorHandler`. Whenever an error is +encountered, `ErrorHandler::handleError()` is invoked. The default error handling strategy is `ErrorHandler\Throwing`, +which will immediately throw when an error is encountered. + +To instead collect all encountered errors into an array, while trying to continue parsing the rest of the source code, +an instance of `ErrorHandler\Collecting` can be passed to the `Parser::parse()` method. A usage example: + +```php +$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::ONLY_PHP7); +$errorHandler = new PhpParser\ErrorHandler\Collecting; + +$stmts = $parser->parse($code, $errorHandler); + +if ($errorHandler->hasErrors()) { + foreach ($errorHandler->getErrors() as $error) { + // $error is an ordinary PhpParser\Error + } +} + +if (null !== $stmts) { + // $stmts is a best-effort partial AST +} +``` + +The `NameResolver` visitor also accepts an `ErrorHandler` as a constructor argument. \ No newline at end of file diff --git a/vendor/nikic/php-parser/doc/component/FAQ.markdown b/vendor/nikic/php-parser/doc/component/FAQ.markdown new file mode 100644 index 00000000..b8bf834b --- /dev/null +++ b/vendor/nikic/php-parser/doc/component/FAQ.markdown @@ -0,0 +1,68 @@ +Frequently Asked Questions +========================== + + * [How can the parent of a node be obtained?](#how-can-the-parent-of-a-node-be-obtained) + * [How can the next/previous sibling of a node be obtained?](#how-can-the-nextprevious-sibling-of-a-node-be-obtained) + +How can the parent of a node be obtained? +----- + +The AST does not store parent nodes by default. However, it is easy to add a custom parent node +attribute using a custom node visitor: + +```php +use PhpParser\Node; +use PhpParser\NodeVisitorAbstract; + +class ParentConnector extends NodeVisitorAbstract { + private $stack; + public function beforeTraverse(array $nodes) { + $this->stack = []; + } + public function enterNode(Node $node) { + if (!empty($this->stack)) { + $node->setAttribute('parent', $this->stack[count($this->stack)-1]); + } + $this->stack[] = $node; + } + public function leaveNode(Node $node) { + array_pop($this->stack); + } +} +``` + +After running this visitor, the parent node can be obtained through `$node->getAttribute('parent')`. + +How can the next/previous sibling of a node be obtained? +----- + +Again, siblings are not stored by default, but the visitor from the previous entry can be easily +extended to store the previous / next node with a common parent as well: + +```php +use PhpParser\Node; +use PhpParser\NodeVisitorAbstract; + +class NodeConnector extends NodeVisitorAbstract { + private $stack; + private $prev; + public function beforeTraverse(array $nodes) { + $this->stack = []; + $this->prev = null; + } + public function enterNode(Node $node) { + if (!empty($this->stack)) { + $node->setAttribute('parent', $this->stack[count($this->stack)-1]); + } + if ($this->prev && $this->prev->getAttribute('parent') == $node->getAttribute('parent')) { + $node->setAttribute('prev', $this->prev); + $this->prev->setAttribute('next', $node); + } + $this->stack[] = $node; + } + public function leaveNode(Node $node) { + $this->prev = $node; + array_pop($this->stack); + } +} +``` diff --git a/vendor/nikic/php-parser/doc/component/JSON_representation.markdown b/vendor/nikic/php-parser/doc/component/JSON_representation.markdown new file mode 100644 index 00000000..47c3429c --- /dev/null +++ b/vendor/nikic/php-parser/doc/component/JSON_representation.markdown @@ -0,0 +1,131 @@ +JSON representation +=================== + +Nodes (and comments) implement the `JsonSerializable` interface. As such, it is possible to JSON +encode the AST directly using `json_encode()`: + +```php +create(ParserFactory::PREFER_PHP7); + +try { + $stmts = $parser->parse($code); + + echo json_encode($stmts, JSON_PRETTY_PRINT), "\n"; +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +This will result in the following output (which includes attributes): + +```json +[ + { + "nodeType": "Stmt_Function", + "byRef": false, + "name": { + "nodeType": "Identifier", + "name": "printLine", + "attributes": { + "startLine": 4, + "endLine": 4 + } + }, + "params": [ + { + "nodeType": "Param", + "type": null, + "byRef": false, + "variadic": false, + "var": { + "nodeType": "Expr_Variable", + "name": "msg", + "attributes": { + "startLine": 4, + "endLine": 4 + } + }, + "default": null, + "attributes": { + "startLine": 4, + "endLine": 4 + } + } + ], + "returnType": null, + "stmts": [ + { + "nodeType": "Stmt_Echo", + "exprs": [ + { + "nodeType": "Expr_Variable", + "name": "msg", + "attributes": { + "startLine": 5, + "endLine": 5 + } + }, + { + "nodeType": "Scalar_String", + "value": "\n", + "attributes": { + "startLine": 5, + "endLine": 5, + "kind": 2 + } + } + ], + "attributes": { + "startLine": 5, + "endLine": 5 + } + } + ], + "attributes": { + "startLine": 4, + "comments": [ + { + "nodeType": "Comment_Doc", + "text": "\/** @param string $msg *\/", + "line": 3, + "filePos": 9, + "tokenPos": 2 + } + ], + "endLine": 6 + } + } +] +``` + +The JSON representation may be converted back into an AST using the `JsonDecoder`: + +```php +decode($json); +``` + +Note that not all ASTs can be represented using JSON. In particular: + + * JSON only supports UTF-8 strings. + * JSON does not support non-finite floating-point numbers. This can occur if the original source + code contains non-representable floating-pointing literals such as `1e1000`. + +If the node tree is not representable in JSON, the initial `json_encode()` call will fail. + +From the command line, a JSON dump can be obtained using `vendor/bin/php-parse -j file.php`. diff --git a/vendor/nikic/php-parser/doc/component/Lexer.markdown b/vendor/nikic/php-parser/doc/component/Lexer.markdown new file mode 100644 index 00000000..be26e381 --- /dev/null +++ b/vendor/nikic/php-parser/doc/component/Lexer.markdown @@ -0,0 +1,159 @@ +Lexer component documentation +============================= + +The lexer is responsible for providing tokens to the parser. The project comes with two lexers: `PhpParser\Lexer` and +`PhpParser\Lexer\Emulative`. The latter is an extension of the former, which adds the ability to emulate tokens of +newer PHP versions and thus allows parsing of new code on older versions. + +This documentation discusses options available for the default lexers and explains how lexers can be extended. + +Lexer options +------------- + +The two default lexers accept an `$options` array in the constructor. Currently only the `'usedAttributes'` option is +supported, which allows you to specify which attributes will be added to the AST nodes. The attributes can then be +accessed using `$node->getAttribute()`, `$node->setAttribute()`, `$node->hasAttribute()` and `$node->getAttributes()` +methods. A sample options array: + +```php +$lexer = new PhpParser\Lexer(array( + 'usedAttributes' => array( + 'comments', 'startLine', 'endLine' + ) +)); +``` + +The attributes used in this example match the default behavior of the lexer. The following attributes are supported: + + * `comments`: Array of `PhpParser\Comment` or `PhpParser\Comment\Doc` instances, representing all comments that occurred + between the previous non-discarded token and the current one. Use of this attribute is required for the + `$node->getComments()` and `$node->getDocComment()` methods to work. The attribute is also needed if you wish the pretty + printer to retain comments present in the original code. + * `startLine`: Line in which the node starts. This attribute is required for the `$node->getLine()` to work. It is also + required if syntax errors should contain line number information. + * `endLine`: Line in which the node ends. Required for `$node->getEndLine()`. + * `startTokenPos`: Offset into the token array of the first token in the node. Required for `$node->getStartTokenPos()`. + * `endTokenPos`: Offset into the token array of the last token in the node. Required for `$node->getEndTokenPos()`. + * `startFilePos`: Offset into the code string of the first character that is part of the node. Required for `$node->getStartFilePos()`. + * `endFilePos`: Offset into the code string of the last character that is part of the node. Required for `$node->getEndFilePos()`. + +### Using token positions + +> **Note:** The example in this section is outdated in that this information is directly available in the AST: While +> `$property->isPublic()` does not distinguish between `public` and `var`, directly checking `$property->flags` for +> the `$property->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0` allows making this distinction without resorting to +> tokens. However the general idea behind the example still applies in other cases. + +The token offset information is useful if you wish to examine the exact formatting used for a node. For example the AST +does not distinguish whether a property was declared using `public` or using `var`, but you can retrieve this +information based on the token position: + +```php +function isDeclaredUsingVar(array $tokens, PhpParser\Node\Stmt\Property $prop) { + $i = $prop->getAttribute('startTokenPos'); + return $tokens[$i][0] === T_VAR; +} +``` + +In order to make use of this function, you will have to provide the tokens from the lexer to your node visitor using +code similar to the following: + +```php +class MyNodeVisitor extends PhpParser\NodeVisitorAbstract { + private $tokens; + public function setTokens(array $tokens) { + $this->tokens = $tokens; + } + + public function leaveNode(PhpParser\Node $node) { + if ($node instanceof PhpParser\Node\Stmt\Property) { + var_dump(isDeclaredUsingVar($this->tokens, $node)); + } + } +} + +$lexer = new PhpParser\Lexer(array( + 'usedAttributes' => array( + 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos' + ) +)); +$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::ONLY_PHP7, $lexer); + +$visitor = new MyNodeVisitor(); +$traverser = new PhpParser\NodeTraverser(); +$traverser->addVisitor($visitor); + +try { + $stmts = $parser->parse($code); + $visitor->setTokens($lexer->getTokens()); + $stmts = $traverser->traverse($stmts); +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +The same approach can also be used to perform specific modifications in the code, without changing the formatting in +other places (which is the case when using the pretty printer). + +Lexer extension +--------------- + +A lexer has to define the following public interface: + +```php +function startLexing(string $code, ErrorHandler $errorHandler = null): void; +function getTokens(): array; +function handleHaltCompiler(): string; +function getNextToken(string &$value = null, array &$startAttributes = null, array &$endAttributes = null): int; +``` + +The `startLexing()` method is invoked whenever the `parse()` method of the parser is called and is passed the source +code that is to be lexed (including the opening tag). It can be used to reset state or preprocess the source code or tokens. The +passed `ErrorHandler` should be used to report lexing errors. + +The `getTokens()` method returns the current token array, in the usual `token_get_all()` format. This method is not +used by the parser (which uses `getNextToken()`), but is useful in combination with the token position attributes. + +The `handleHaltCompiler()` method is called whenever a `T_HALT_COMPILER` token is encountered. It has to return the +remaining string after the construct (not including `();`). + +The `getNextToken()` method returns the ID of the next token (as defined by the `Parser::T_*` constants). If no more +tokens are available it must return `0`, which is the ID of the `EOF` token. Furthermore the string content of the +token should be written into the by-reference `$value` parameter (which will then be available as `$n` in the parser). + +### Attribute handling + +The other two by-ref variables `$startAttributes` and `$endAttributes` define which attributes will eventually be +assigned to the generated nodes: The parser will take the `$startAttributes` from the first token which is part of the +node and the `$endAttributes` from the last token that is part of the node. + +E.g. if the tokens `T_FUNCTION T_STRING ... '{' ... '}'` constitute a node, then the `$startAttributes` from the +`T_FUNCTION` token will be taken and the `$endAttributes` from the `'}'` token. + +An application of custom attributes is storing the exact original formatting of literals: While the parser does retain +some information about the formatting of integers (like decimal vs. hexadecimal) or strings (like used quote type), it +does not preserve the exact original formatting (e.g. leading zeros for integers or escape sequences in strings). This +can be remedied by storing the original value in an attribute: + +```php +use PhpParser\Lexer; +use PhpParser\Parser\Tokens; + +class KeepOriginalValueLexer extends Lexer // or Lexer\Emulative +{ + public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { + $tokenId = parent::getNextToken($value, $startAttributes, $endAttributes); + + if ($tokenId == Tokens::T_CONSTANT_ENCAPSED_STRING // non-interpolated string + || $tokenId == Tokens::T_ENCAPSED_AND_WHITESPACE // interpolated string + || $tokenId == Tokens::T_LNUMBER // integer + || $tokenId == Tokens::T_DNUMBER // floating point number + ) { + // could also use $startAttributes, doesn't really matter here + $endAttributes['originalValue'] = $value; + } + + return $tokenId; + } +} +``` diff --git a/vendor/nikic/php-parser/doc/component/Name_resolution.markdown b/vendor/nikic/php-parser/doc/component/Name_resolution.markdown new file mode 100644 index 00000000..2a7eb603 --- /dev/null +++ b/vendor/nikic/php-parser/doc/component/Name_resolution.markdown @@ -0,0 +1,87 @@ +Name resolution +=============== + +Since the introduction of namespaces in PHP 5.3, literal names in PHP code are subject to a +relatively complex name resolution process, which is based on the current namespace, the current +import table state, as well the type of the referenced symbol. PHP-Parser implements name +resolution and related functionality, both as reusable logic (NameContext), as well as a node +visitor (NameResolver) based on it. + +The NameResolver visitor +------------------------ + +The `NameResolver` visitor can (and for nearly all uses of the AST, is) be applied to resolve names +to their fully-qualified form, to the degree that this is possible. + +```php +$nameResolver = new PhpParser\NodeVisitor\NameResolver; +$nodeTraverser = new PhpParser\NodeTraverser; +$nodeTraverser->addVisitor($nameResolver); + +// Resolve names +$stmts = $nodeTraverser->traverse($stmts); +``` + +In the default configuration, the name resolver will perform three actions: + + * Declarations of functions, classes, interfaces, traits and global constants will have a + `namespacedName` property added, which contains the function/class/etc name including the + namespace prefix. For historic reasons this is a **property** rather than an attribute. + * Names will be replaced by fully qualified resolved names, which are instances of + `Node\Name\FullyQualified`. + * Unqualified function and constant names inside a namespace cannot be statically resolved. Inside + a namespace `Foo`, a call to `strlen()` may either refer to the namespaced `\Foo\strlen()`, or + the global `\strlen()`. Because PHP-Parser does not have the necessary context to decide this, + such names are left unresolved. Additionally a `namespacedName` **attribute** is added to the + name node. + +The name resolver accepts an option array as the second argument, with the following default values: + +```php +$nameResolver = new PhpParser\NodeVisitor\NameResolver(null, [ + 'preserveOriginalNames' => false, + 'replaceNodes' => true, +]); +``` + +If the `preserveOriginalNames` option is enabled, then the resolved (fully qualified) name will have +an `originalName` attribute, which contains the unresolved name. + +If the `replaceNodes` option is disabled, then names will no longer be resolved in-place. Instead a +`resolvedName` attribute will be added to each name, which contains the resolved (fully qualified) +name. Once again, if an unqualified function or constant name cannot be resolved, then the +`resolvedName` attribute will not be present, and instead a `namespacedName` attribute is added. + +The `replaceNodes` attribute is useful if you wish to perform modifications on the AST, as you +probably do not wish the resoluting code to have fully resolved names as a side-effect. + +The NameContext +--------------- + +The actual name resolution logic is implemented in the `NameContext` class, which has the following +public API: + +```php +class NameContext { + public function __construct(ErrorHandler $errorHandler); + public function startNamespace(Name $namespace = null); + public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []); + + public function getNamespace(); + public function getResolvedName(Name $name, int $type); + public function getResolvedClassName(Name $name) : Name; + public function getPossibleNames(string $name, int $type) : array; + public function getShortName(string $name, int $type) : Name; +} +``` + +The `$type` parameters accept on of the `Stmt\Use_::TYPE_*` constants, which represent the three +basic symbol types in PHP (functions, constants and everything else). + +Next to name resolution, the `NameContext` also supports the reverse operation of finding a short +representation of a name given the current name resolution environment. + +The name context is intended to be used for name resolution operations outside the AST itself, such +as class names inside doc comments. A visitor running in parallel with the name resolver can access +the name context using `$nameResolver->getNameContext()`. Alternatively a visitor can use an +independent context and explicitly feed `Namespace` and `Use` nodes to it. \ No newline at end of file diff --git a/vendor/nikic/php-parser/doc/component/Performance.markdown b/vendor/nikic/php-parser/doc/component/Performance.markdown new file mode 100644 index 00000000..4281ce8c --- /dev/null +++ b/vendor/nikic/php-parser/doc/component/Performance.markdown @@ -0,0 +1,65 @@ +Performance +=========== + +Parsing is computationally expensive task, to which the PHP language is not very well suited. +Nonetheless, there are a few things you can do to improve the performance of this library, which are +described in the following. + +Xdebug +------ + +Running PHP with XDebug adds a lot of overhead, especially for code that performs many method calls. +Just by loading XDebug (without enabling profiling or other more intrusive XDebug features), you +can expect that code using PHP-Parser will be approximately *five times slower*. + +As such, you should make sure that XDebug is not loaded when using this library. Note that setting +the `xdebug.default_enable=0` ini option does *not* disable XDebug. The *only* way to disable +XDebug is to not load the extension in the first place. + +If you are building a command-line utility for use by developers (who often have XDebug enabled), +you may want to consider automatically restarting PHP with XDebug unloaded. The +[composer/xdebug-handler](https://github.com/composer/xdebug-handler) package can be used to do +this. + +If you do run with XDebug, you may need to increase the `xdebug.max_nesting_level` option to a +higher level, such as 3000. While the parser itself is recursion free, most other code working on +the AST uses recursion and will generate an error if the value of this option is too low. + +Assertions +---------- + +Assertions should be disabled in a production context by setting `zend.assertions=-1` (or +`zend.assertions=0` if set at runtime). The library currently doesn't make heavy use of assertions, +but they are used in an increasing number of places. + +Object reuse +------------ + +Many objects in this project are designed for reuse. For example, one `Parser` object can be used to +parse multiple files. + +When possible, objects should be reused rather than being newly instantiated for every use. Some +objects have expensive initialization procedures, which will be unnecessarily repeated if the object +is not reused. (Currently two objects with particularly expensive setup are lexers and pretty +printers, though the details might change between versions of this library.) + +Garbage collection +------------------ + +A limitation in PHP's cyclic garbage collector may lead to major performance degradation when the +active working set exceeds 10000 objects (or arrays). Especially when parsing very large files this +limit is significantly exceeded and PHP will spend the majority of time performing unnecessary +garbage collection attempts. + +Without GC, parsing time is roughly linear in the input size. With GC, this degenerates to quadratic +runtime for large files. While the specifics may differ, as a rough guideline you may expect a 2.5x +GC overhead for 500KB files and a 5x overhead for 1MB files. + +Because this a limitation in PHP's implementation, there is no easy way to work around this. If +possible, you should avoid parsing very large files, as they will impact overall execution time +disproportionally (and are usually generated anyway). + +Of course, you can also try to (temporarily) disable GC. By design the AST generated by PHP-Parser +is cycle-free, so the AST itself will never cause leaks with GC disabled. However, other code +(including for example the parser object itself) may hold cycles, so disabling of GC should be +approached with care. \ No newline at end of file diff --git a/vendor/nikic/php-parser/doc/component/Pretty_printing.markdown b/vendor/nikic/php-parser/doc/component/Pretty_printing.markdown new file mode 100644 index 00000000..d6198e31 --- /dev/null +++ b/vendor/nikic/php-parser/doc/component/Pretty_printing.markdown @@ -0,0 +1,96 @@ +Pretty printing +=============== + +Pretty printing is the process of converting a syntax tree back to PHP code. In its basic mode of +operation the pretty printer provided by this library will print the AST using a certain predefined +code style and will discard (nearly) all formatting of the original code. Because programmers tend +to be rather picky about their code formatting, this mode of operation is not very suitable for +refactoring code, but can be used for automatically generated code, which is usually only read for +debugging purposes. + +Basic usage +----------- + +```php +$stmts = $parser->parse($code); + +// MODIFY $stmts here + +$prettyPrinter = new PhpParser\PrettyPrinter\Standard; +$newCode = $prettyPrinter->prettyPrintFile($stmts); +``` + +The pretty printer has three basic printing methods: `prettyPrint()`, `prettyPrintFile()` and +`prettyPrintExpr()`. The one that is most commonly useful is `prettyPrintFile()`, which takes an +array of statements and produces a full PHP file, including opening ` **Note:** This functionality is **experimental** and not yet complete. + +For automated code refactoring, migration and similar, you will usually only want to modify a small +portion of the code and leave the remainder alone. The basic pretty printer is not suitable for +this, because it will also reformat parts of the code which have not been modified. + +Since PHP-Parser 4.0, an experimental formatting-preserving pretty-printing mode is available, which +attempts to preserve the formatting of code (those AST nodes that have not changed) and only reformat +code which has been modified or newly inserted. + +Use of the formatting-preservation functionality requires some additional preparatory steps: + +```php +use PhpParser\{Lexer, NodeTraverser, NodeVisitor, Parser, PrettyPrinter}; + +$lexer = new Lexer\Emulative([ + 'usedAttributes' => [ + 'comments', + 'startLine', 'endLine', + 'startTokenPos', 'endTokenPos', + ], +]); +$parser = new Parser\Php7($lexer); + +$traverser = new NodeTraverser(); +$traverser->addVisitor(new NodeVisitor\CloningVisitor()); + +$printer = new PrettyPrinter\Standard(); + +$oldStmts = $parser->parse($code); +$oldTokens = $lexer->getTokens(); + +$newStmts = $traverser->traverse($oldStmts); + +// MODIFY $newStmts HERE + +$newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); +``` + +If you make use of the name resolution functionality, you will likely want to disable the +`replaceNodes` option. This will add resolved names as attributes, instead of directlying modifying +the AST and causing spurious changes to the pretty printed code. For more information, see the +[name resolution documentation](Name_resolution.markdown). + +This functionality is experimental and not yet fully implemented. It should not provide incorrect +code, but it may sometimes reformat more code than necessary. Open issues are tracked in +[issue #344](https://github.com/nikic/PHP-Parser/issues/344). If you encounter problems while using +this functionality, please open an issue, so we know what to prioritize. diff --git a/vendor/nikic/php-parser/doc/component/Walking_the_AST.markdown b/vendor/nikic/php-parser/doc/component/Walking_the_AST.markdown new file mode 100644 index 00000000..69af1e83 --- /dev/null +++ b/vendor/nikic/php-parser/doc/component/Walking_the_AST.markdown @@ -0,0 +1,337 @@ +Walking the AST +=============== + +The most common way to work with the AST is by using a node traverser and one or more node visitors. +As a basic example, the following code changes all literal integers in the AST into strings (e.g., +`42` becomes `'42'`.) + +```php +use PhpParser\{Node, NodeTraverser, NodeVisitorAbstract}; + +$traverser = new NodeTraverser; +$traverser->addVisitor(new class extends NodeVisitorAbstract { + public function leaveNode(Node $node) { + if ($node instanceof Node\Scalar\LNumber) { + return new Node\Scalar\String_((string) $node->value); + } + } +}); + +$stmts = ...; +$modifiedStmts = $traverser->traverse($stmts); +``` + +Node visitors +------------- + +Each node visitor implements an interface with following four methods: + +```php +interface NodeVisitor { + public function beforeTraverse(array $nodes); + public function enterNode(Node $node); + public function leaveNode(Node $node); + public function afterTraverse(array $nodes); +} +``` + +The `beforeTraverse()` and `afterTraverse()` methods are called before and after the traversal +respectively, and are passed the entire AST. They can be used to perform any necessary state +setup or cleanup. + +The `enterNode()` method is called when a node is first encountered, before its children are +processed ("preorder"). The `leaveNode()` method is called after all children have been visited +("postorder"). + +For example, if we have the following excerpt of an AST + +``` +Expr_FuncCall( + name: Name( + parts: array( + 0: printLine + ) + ) + args: array( + 0: Arg( + value: Scalar_String( + value: Hello World!!! + ) + byRef: false + unpack: false + ) + ) +) +``` + +then the enter/leave methods will be called in the following order: + +``` +enterNode(Expr_FuncCall) +enterNode(Name) +leaveNode(Name) +enterNode(Arg) +enterNode(Scalar_String) +leaveNode(Scalar_String) +leaveNode(Arg) +leaveNode(Expr_FuncCall) +``` + +A common pattern is that `enterNode` is used to collect some information and then `leaveNode` +performs modifications based on that. At the time when `leaveNode` is called, all the code inside +the node will have already been visited and necessary information collected. + +As you usually do not want to implement all four methods, it is recommended that you extend +`NodeVisitorAbstract` instead of implementing the interface directly. The abstract class provides +empty default implementations. + +Modifying the AST +----------------- + +There are a number of ways in which the AST can be modified from inside a node visitor. The first +and simplest is to simply change AST properties inside the visitor: + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Scalar\LNumber) { + // increment all integer literals + $node->value++; + } +} +``` + +The second is to replace a node entirely by returning a new node: + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Expr\BinaryOp\BooleanAnd) { + // Convert all $a && $b expressions into !($a && $b) + return new Node\Expr\BooleanNot($node); + } +} +``` + +Doing this is supported both inside enterNode and leaveNode. However, you have to be mindful about +where you perform the replacement: If a node is replaced in enterNode, then the recursive traversal +will also consider the children of the new node. If you aren't careful, this can lead to infinite +recursion. For example, let's take the previous code sample and use enterNode instead: + +```php +public function enterNode(Node $node) { + if ($node instanceof Node\Expr\BinaryOp\BooleanAnd) { + // Convert all $a && $b expressions into !($a && $b) + return new Node\Expr\BooleanNot($node); + } +} +``` + +Now `$a && $b` will be replaced by `!($a && $b)`. Then the traverser will go into the first (and +only) child of `!($a && $b)`, which is `$a && $b`. The transformation applies again and we end up +with `!!($a && $b)`. This will continue until PHP hits the memory limit. + +Finally, two special replacement types are supported only by leaveNode. The first is removal of a +node: + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Stmt\Return_) { + // Remove all return statements + return NodeTraverser::REMOVE_NODE; + } +} +``` + +Node removal only works if the parent structure is an array. This means that usually it only makes +sense to remove nodes of type `Node\Stmt`, as they always occur inside statement lists (and a few +more node types like `Arg` or `Expr\ArrayItem`, which are also always part of lists). + +On the other hand, removing a `Node\Expr` does not make sense: If you have `$a * $b`, there is no +meaningful way in which the `$a` part could be removed. If you want to remove an expression, you +generally want to remove it together with a surrounding expression statement: + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Stmt\Expression + && $node->expr instanceof Node\Expr\FuncCall + && $node->expr->name instanceof Node\Name + && $node->expr->name->toString() === 'var_dump' + ) { + return NodeTraverser::REMOVE_NODE; + } +} +``` + +This example will remove all calls to `var_dump()` which occur as expression statements. This means +that `var_dump($a);` will be removed, but `if (var_dump($a))` will not be removed (and there is no +obvious way in which it can be removed). + +Next to removing nodes, it is also possible to replace one node with multiple nodes. Again, this +only works inside leaveNode and only if the parent structure is an array. + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Stmt\Return_ && $node->expr !== null) { + // Convert "return foo();" into "$retval = foo(); return $retval;" + $var = new Node\Expr\Variable('retval'); + return [ + new Node\Stmt\Expression(new Node\Expr\Assign($var, $node->expr)), + new Node\Stmt\Return_($var), + ]; + } +} +``` + +Short-circuiting traversal +-------------------------- + +An AST can easily contain thousands of nodes, and traversing over all of them may be slow, +especially if you have more than one visitor. In some cases, it is possible to avoid a full +traversal. + +If you are looking for all class declarations in a file (and assuming you're not interested in +anonymous classes), you know that once you've seen a class declaration, there is no point in also +checking all it's child nodes, because PHP does not allow nesting classes. In this case, you can +instruct the traverser to not recurse into the class node: + +``` +private $classes = []; +public function enterNode(Node $node) { + if ($node instanceof Node\Stmt\Class_) { + $this->classes[] = $node; + return NodeTraverser::DONT_TRAVERSE_CHILDREN; + } +} +``` + +Of course, this option is only available in enterNode, because it's already too late by the time +leaveNode is reached. + +If you are only looking for one specific node, it is also possible to abort the traversal entirely +after finding it. For example, if you are looking for the node of a class with a certain name (and +discounting exotic cases like conditionally defining a class two times), you can stop traversal +once you found it: + +``` +private $class = null; +public function enterNode(Node $node) { + if ($node instanceof Node\Stmt\Class_ && + $node->namespacedName->toString() === 'Foo\Bar\Baz' + ) { + $this->class = $node; + return NodeTraverser::STOP_TRAVERSAL; + } +} +``` + +This works both in enterNode and leaveNode. Note that this particular case can also be more easily +handled using a NodeFinder, which will be introduced below. + +Multiple visitors +----------------- + +A single traverser can be used with multiple visitors: + +```php +$traverser = new NodeTraverser; +$traverser->addVisitor($visitorA); +$traverser->addVisitor($visitorB); +$stmts = $traverser->traverse($stmts); +``` + +It is important to understand that if a traverser is run with multiple visitors, the visitors will +be interleaved. Given the following AST excerpt + +``` +Stmt_Return( + expr: Expr_Variable( + name: foobar + ) +) +``` + +the following method calls will be performed: + +``` +$visitorA->enterNode(Stmt_Return) +$visitorB->enterNode(Stmt_Return) +$visitorA->enterNode(Expr_Variable) +$visitorB->enterNode(Expr_Variable) +$visitorA->leaveNode(Expr_Variable) +$visitorB->leaveNode(Expr_Variable) +$visitorA->leaveNode(Stmt_Return) +$visitorB->leaveNode(Stmt_Return) +``` + +That is, when visiting a node, enterNode and leaveNode will always be called for all visitors. +Running multiple visitors in parallel improves performance, as the AST only has to be traversed +once. However, it is not always possible to write visitors in a way that allows interleaved +execution. In this case, you can always fall back to performing multiple traversals: + +```php +$traverserA = new NodeTraverser; +$traverserA->addVisitor($visitorA); +$traverserB = new NodeTraverser; +$traverserB->addVisitor($visitorB); +$stmts = $traverserA->traverser($stmts); +$stmts = $traverserB->traverser($stmts); +``` + +When using multiple visitors, it is important to understand how they interact with the various +special enterNode/leaveNode return values: + + * If *any* visitor returns `DONT_TRAVERSE_CHILDREN`, the children will be skipped for *all* + visitors. + * If *any* visitor returns `DONT_TRAVERSE_CURRENT_AND_CHILDREN`, the children will be skipped for *all* + visitors, and all *subsequent* visitors will not visit the current node. + * If *any* visitor returns `STOP_TRAVERSAL`, traversal is stopped for *all* visitors. + * If a visitor returns a replacement node, subsequent visitors will be passed the replacement node, + not the original one. + * If a visitor returns `REMOVE_NODE`, subsequent visitors will not see this node. + * If a visitor returns an array of replacement nodes, subsequent visitors will see neither the node + that was replaced, nor the replacement nodes. + +Simple node finding +------------------- + +While the node visitor mechanism is very flexible, creating a node visitor can be overly cumbersome +for minor tasks. For this reason a `NodeFinder` is provided, which can find AST nodes that either +satisfy a certain callback, or which are instanced of a certain node type. A couple of examples are +shown in the following: + +```php +use PhpParser\{Node, NodeFinder}; + +$nodeFinder = new NodeFinder; + +// Find all class nodes. +$classes = $nodeFinder->findInstanceOf($stmts, Node\Stmt\Class_::class); + +// Find all classes that extend another class +$extendingClasses = $nodeFinder->find($stmts, function(Node $node) { + return $node instanceof Node\Stmt\Class_ + && $node->extends !== null; +}); + +// Find first class occuring in the AST. Returns null if no class exists. +$class = $nodeFinder->findFirstInstanceOf($stmts, Node\Stmt\Class_::class); + +// Find first class that has name $name +$class = $nodeFinder->findFirst($stmts, function(Node $node) use ($name) { + return $node instanceof Node\Stmt\Class_ + && $node->resolvedName->toString() === $name; +}); +``` + +Internally, the `NodeFinder` also uses a node traverser. It only simplifies the interface for a +common use case. + +Parent and sibling references +----------------------------- + +The node visitor mechanism is somewhat rigid, in that it prescribes an order in which nodes should +be accessed: From parents to children. However, it can often be convenient to operate in the +reverse direction: When working on a node, you might want to check if the parent node satisfies a +certain property. + +PHP-Parser does not add parent (or sibling) references to nodes by itself, but you can easily +emulate this with a visitor. See the [FAQ](FAQ.markdown) for more information. diff --git a/vendor/nikic/php-parser/grammar/README.md b/vendor/nikic/php-parser/grammar/README.md new file mode 100644 index 00000000..90988cf4 --- /dev/null +++ b/vendor/nikic/php-parser/grammar/README.md @@ -0,0 +1,28 @@ +What do all those files mean? +============================= + + * `php5.y`: PHP 5 grammar written in a pseudo language + * `php7.y`: PHP 7 grammar written in a pseudo language + * `tokens.y`: Tokens definition shared between PHP 5 and PHP 7 grammars + * `parser.template`: A `kmyacc` parser prototype file for PHP + * `tokens.template`: A `kmyacc` prototype file for the `Tokens` class + * `rebuildParsers.php`: Preprocesses the grammar and builds the parser using `kmyacc` + +.phpy pseudo language +===================== + +The `.y` file is a normal grammar in `kmyacc` (`yacc`) style, with some transformations +applied to it: + + * Nodes are created using the syntax `Name[..., ...]`. This is transformed into + `new Name(..., ..., attributes())` + * Some function-like constructs are resolved (see `rebuildParsers.php` for a list) + +Building the parser +=================== + +In order to rebuild the parser, you need [moriyoshi's fork of kmyacc](https://github.com/moriyoshi/kmyacc-forked). +After you compiled/installed it, run the `rebuildParsers.php` script. + +By default only the `Parser.php` is built. If you want to additionally emit debug symbols and create `y.output`, run the +script with `--debug`. If you want to retain the preprocessed grammar pass `--keep-tmp-grammar`. diff --git a/vendor/nikic/php-parser/grammar/parser.template b/vendor/nikic/php-parser/grammar/parser.template new file mode 100644 index 00000000..6166607c --- /dev/null +++ b/vendor/nikic/php-parser/grammar/parser.template @@ -0,0 +1,106 @@ +semValue +#semval($,%t) $this->semValue +#semval(%n) $stackPos-(%l-%n) +#semval(%n,%t) $stackPos-(%l-%n) + +namespace PhpParser\Parser; + +use PhpParser\Error; +use PhpParser\Node; +use PhpParser\Node\Expr; +use PhpParser\Node\Name; +use PhpParser\Node\Scalar; +use PhpParser\Node\Stmt; +#include; + +/* This is an automatically GENERATED file, which should not be manually edited. + * Instead edit one of the following: + * * the grammar files grammar/php5.y or grammar/php7.y + * * the skeleton file grammar/parser.template + * * the preprocessing script grammar/rebuildParsers.php + */ +class #(-p) extends \PhpParser\ParserAbstract +{ + protected $tokenToSymbolMapSize = #(YYMAXLEX); + protected $actionTableSize = #(YYLAST); + protected $gotoTableSize = #(YYGLAST); + + protected $invalidSymbol = #(YYBADCH); + protected $errorSymbol = #(YYINTERRTOK); + protected $defaultAction = #(YYDEFAULT); + protected $unexpectedTokenRule = #(YYUNEXPECTED); + + protected $YY2TBLSTATE = #(YY2TBLSTATE); + protected $numNonLeafStates = #(YYNLSTATES); + + protected $symbolToName = array( + #listvar terminals + ); + + protected $tokenToSymbol = array( + #listvar yytranslate + ); + + protected $action = array( + #listvar yyaction + ); + + protected $actionCheck = array( + #listvar yycheck + ); + + protected $actionBase = array( + #listvar yybase + ); + + protected $actionDefault = array( + #listvar yydefault + ); + + protected $goto = array( + #listvar yygoto + ); + + protected $gotoCheck = array( + #listvar yygcheck + ); + + protected $gotoBase = array( + #listvar yygbase + ); + + protected $gotoDefault = array( + #listvar yygdefault + ); + + protected $ruleToNonTerminal = array( + #listvar yylhs + ); + + protected $ruleToLength = array( + #listvar yylen + ); +#if -t + + protected $productions = array( + #production-strings; + ); +#endif + + protected function initReduceCallbacks() { + $this->reduceCallbacks = [ +#reduce + %n => function ($stackPos) { + %b + }, +#noact + %n => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, +#endreduce + ]; + } +} +#tailcode; diff --git a/vendor/nikic/php-parser/grammar/php5.y b/vendor/nikic/php-parser/grammar/php5.y new file mode 100644 index 00000000..9f7b6cfe --- /dev/null +++ b/vendor/nikic/php-parser/grammar/php5.y @@ -0,0 +1,1025 @@ +%pure_parser +%expect 6 + +%tokens + +%% + +start: + top_statement_list { $$ = $this->handleNamespaces($1); } +; + +top_statement_list_ex: + top_statement_list_ex top_statement { pushNormalizing($1, $2); } + | /* empty */ { init(); } +; + +top_statement_list: + top_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +reserved_non_modifiers: + T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND + | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE + | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH + | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO + | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT + | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS + | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER +; + +semi_reserved: + reserved_non_modifiers + | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC +; + +identifier_ex: + T_STRING { $$ = Node\Identifier[$1]; } + | semi_reserved { $$ = Node\Identifier[$1]; } +; + +identifier: + T_STRING { $$ = Node\Identifier[$1]; } +; + +reserved_non_modifiers_identifier: + reserved_non_modifiers { $$ = Node\Identifier[$1]; } +; + +namespace_name_parts: + T_STRING { init($1); } + | namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); } +; + +namespace_name: + namespace_name_parts { $$ = Name[$1]; } +; + +plain_variable: + T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +; + +top_statement: + statement { $$ = $1; } + | function_declaration_statement { $$ = $1; } + | class_declaration_statement { $$ = $1; } + | T_HALT_COMPILER + { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; } + | T_NAMESPACE namespace_name ';' + { $$ = Stmt\Namespace_[$2, null]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($$); } + | T_NAMESPACE namespace_name '{' top_statement_list '}' + { $$ = Stmt\Namespace_[$2, $4]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($$); } + | T_NAMESPACE '{' top_statement_list '}' + { $$ = Stmt\Namespace_[null, $3]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($$); } + | T_USE use_declarations ';' { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; } + | T_USE use_type use_declarations ';' { $$ = Stmt\Use_[$3, $2]; } + | group_use_declaration ';' { $$ = $1; } + | T_CONST constant_declaration_list ';' { $$ = Stmt\Const_[$2]; } +; + +use_type: + T_FUNCTION { $$ = Stmt\Use_::TYPE_FUNCTION; } + | T_CONST { $$ = Stmt\Use_::TYPE_CONSTANT; } +; + +/* Using namespace_name_parts here to avoid s/r conflict on T_NS_SEPARATOR */ +group_use_declaration: + T_USE use_type namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, $2]; } + | T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($4, stackAttributes(#4)), $7, $2]; } + | T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($2, stackAttributes(#2)), $5, Stmt\Use_::TYPE_UNKNOWN]; } + | T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, Stmt\Use_::TYPE_UNKNOWN]; } +; + +unprefixed_use_declarations: + unprefixed_use_declarations ',' unprefixed_use_declaration + { push($1, $3); } + | unprefixed_use_declaration { init($1); } +; + +use_declarations: + use_declarations ',' use_declaration { push($1, $3); } + | use_declaration { init($1); } +; + +inline_use_declarations: + inline_use_declarations ',' inline_use_declaration { push($1, $3); } + | inline_use_declaration { init($1); } +; + +unprefixed_use_declaration: + namespace_name + { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } + | namespace_name T_AS identifier + { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } +; + +use_declaration: + unprefixed_use_declaration { $$ = $1; } + | T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; } +; + +inline_use_declaration: + unprefixed_use_declaration { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; } + | use_type unprefixed_use_declaration { $$ = $2; $$->type = $1; } +; + +constant_declaration_list: + constant_declaration_list ',' constant_declaration { push($1, $3); } + | constant_declaration { init($1); } +; + +constant_declaration: + identifier '=' static_scalar { $$ = Node\Const_[$1, $3]; } +; + +class_const_list: + class_const_list ',' class_const { push($1, $3); } + | class_const { init($1); } +; + +class_const: + identifier_ex '=' static_scalar { $$ = Node\Const_[$1, $3]; } +; + +inner_statement_list_ex: + inner_statement_list_ex inner_statement { pushNormalizing($1, $2); } + | /* empty */ { init(); } +; + +inner_statement_list: + inner_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +inner_statement: + statement { $$ = $1; } + | function_declaration_statement { $$ = $1; } + | class_declaration_statement { $$ = $1; } + | T_HALT_COMPILER + { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); } +; + +non_empty_statement: + '{' inner_statement_list '}' + { + if ($2) { + $$ = $2; prependLeadingComments($$); + } else { + makeNop($$, $this->startAttributeStack[#1], $this->endAttributes); + if (null === $$) { $$ = array(); } + } + } + | T_IF parentheses_expr statement elseif_list else_single + { $$ = Stmt\If_[$2, ['stmts' => toArray($3), 'elseifs' => $4, 'else' => $5]]; } + | T_IF parentheses_expr ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';' + { $$ = Stmt\If_[$2, ['stmts' => $4, 'elseifs' => $5, 'else' => $6]]; } + | T_WHILE parentheses_expr while_statement { $$ = Stmt\While_[$2, $3]; } + | T_DO statement T_WHILE parentheses_expr ';' { $$ = Stmt\Do_ [$4, toArray($2)]; } + | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement + { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; } + | T_SWITCH parentheses_expr switch_case_list { $$ = Stmt\Switch_[$2, $3]; } + | T_BREAK ';' { $$ = Stmt\Break_[null]; } + | T_BREAK expr ';' { $$ = Stmt\Break_[$2]; } + | T_CONTINUE ';' { $$ = Stmt\Continue_[null]; } + | T_CONTINUE expr ';' { $$ = Stmt\Continue_[$2]; } + | T_RETURN ';' { $$ = Stmt\Return_[null]; } + | T_RETURN expr ';' { $$ = Stmt\Return_[$2]; } + | T_GLOBAL global_var_list ';' { $$ = Stmt\Global_[$2]; } + | T_STATIC static_var_list ';' { $$ = Stmt\Static_[$2]; } + | T_ECHO expr_list ';' { $$ = Stmt\Echo_[$2]; } + | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } + | yield_expr ';' { $$ = Stmt\Expression[$1]; } + | expr ';' { $$ = Stmt\Expression[$1]; } + | T_UNSET '(' variables_list ')' ';' { $$ = Stmt\Unset_[$3]; } + | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement + { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } + | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement + { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; } + | T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; } + | T_TRY '{' inner_statement_list '}' catches optional_finally + { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } + | T_THROW expr ';' { $$ = Stmt\Throw_[$2]; } + | T_GOTO identifier ';' { $$ = Stmt\Goto_[$2]; } + | identifier ':' { $$ = Stmt\Label[$1]; } + | expr error { $$ = Stmt\Expression[$1]; } + | error { $$ = array(); /* means: no statement */ } +; + +statement: + non_empty_statement { $$ = $1; } + | ';' + { makeNop($$, $this->startAttributeStack[#1], $this->endAttributes); + if ($$ === null) $$ = array(); /* means: no statement */ } +; + +catches: + /* empty */ { init(); } + | catches catch { push($1, $2); } +; + +catch: + T_CATCH '(' name plain_variable ')' '{' inner_statement_list '}' + { $$ = Stmt\Catch_[array($3), $4, $7]; } +; + +optional_finally: + /* empty */ { $$ = null; } + | T_FINALLY '{' inner_statement_list '}' { $$ = Stmt\Finally_[$3]; } +; + +variables_list: + variable { init($1); } + | variables_list ',' variable { push($1, $3); } +; + +optional_ref: + /* empty */ { $$ = false; } + | '&' { $$ = true; } +; + +optional_ellipsis: + /* empty */ { $$ = false; } + | T_ELLIPSIS { $$ = true; } +; + +function_declaration_statement: + T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' + { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; } +; + +class_declaration_statement: + class_entry_type identifier extends_from implements_list '{' class_statement_list '}' + { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]]; + $this->checkClass($$, #2); } + | T_INTERFACE identifier interface_extends_list '{' class_statement_list '}' + { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; + $this->checkInterface($$, #2); } + | T_TRAIT identifier '{' class_statement_list '}' + { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } +; + +class_entry_type: + T_CLASS { $$ = 0; } + | T_ABSTRACT T_CLASS { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } + | T_FINAL T_CLASS { $$ = Stmt\Class_::MODIFIER_FINAL; } +; + +extends_from: + /* empty */ { $$ = null; } + | T_EXTENDS class_name { $$ = $2; } +; + +interface_extends_list: + /* empty */ { $$ = array(); } + | T_EXTENDS class_name_list { $$ = $2; } +; + +implements_list: + /* empty */ { $$ = array(); } + | T_IMPLEMENTS class_name_list { $$ = $2; } +; + +class_name_list: + class_name { init($1); } + | class_name_list ',' class_name { push($1, $3); } +; + +for_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } +; + +foreach_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } +; + +declare_statement: + non_empty_statement { $$ = toArray($1); } + | ';' { $$ = null; } + | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } +; + +declare_list: + declare_list_element { init($1); } + | declare_list ',' declare_list_element { push($1, $3); } +; + +declare_list_element: + identifier '=' static_scalar { $$ = Stmt\DeclareDeclare[$1, $3]; } +; + +switch_case_list: + '{' case_list '}' { $$ = $2; } + | '{' ';' case_list '}' { $$ = $3; } + | ':' case_list T_ENDSWITCH ';' { $$ = $2; } + | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; } +; + +case_list: + /* empty */ { init(); } + | case_list case { push($1, $2); } +; + +case: + T_CASE expr case_separator inner_statement_list_ex { $$ = Stmt\Case_[$2, $4]; } + | T_DEFAULT case_separator inner_statement_list_ex { $$ = Stmt\Case_[null, $3]; } +; + +case_separator: + ':' + | ';' +; + +while_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } +; + +elseif_list: + /* empty */ { init(); } + | elseif_list elseif { push($1, $2); } +; + +elseif: + T_ELSEIF parentheses_expr statement { $$ = Stmt\ElseIf_[$2, toArray($3)]; } +; + +new_elseif_list: + /* empty */ { init(); } + | new_elseif_list new_elseif { push($1, $2); } +; + +new_elseif: + T_ELSEIF parentheses_expr ':' inner_statement_list { $$ = Stmt\ElseIf_[$2, $4]; } +; + +else_single: + /* empty */ { $$ = null; } + | T_ELSE statement { $$ = Stmt\Else_[toArray($2)]; } +; + +new_else_single: + /* empty */ { $$ = null; } + | T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; } +; + +foreach_variable: + variable { $$ = array($1, false); } + | '&' variable { $$ = array($2, true); } + | list_expr { $$ = array($1, false); } +; + +parameter_list: + non_empty_parameter_list { $$ = $1; } + | /* empty */ { $$ = array(); } +; + +non_empty_parameter_list: + parameter { init($1); } + | non_empty_parameter_list ',' parameter { push($1, $3); } +; + +parameter: + optional_param_type optional_ref optional_ellipsis plain_variable + { $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); } + | optional_param_type optional_ref optional_ellipsis plain_variable '=' static_scalar + { $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); } +; + +type: + name { $$ = $1; } + | T_ARRAY { $$ = Node\Identifier['array']; } + | T_CALLABLE { $$ = Node\Identifier['callable']; } +; + +optional_param_type: + /* empty */ { $$ = null; } + | type { $$ = $1; } +; + +optional_return_type: + /* empty */ { $$ = null; } + | ':' type { $$ = $2; } +; + +argument_list: + '(' ')' { $$ = array(); } + | '(' non_empty_argument_list ')' { $$ = $2; } + | '(' yield_expr ')' { $$ = array(Node\Arg[$2, false, false]); } +; + +non_empty_argument_list: + argument { init($1); } + | non_empty_argument_list ',' argument { push($1, $3); } +; + +argument: + expr { $$ = Node\Arg[$1, false, false]; } + | '&' variable { $$ = Node\Arg[$2, true, false]; } + | T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; } +; + +global_var_list: + global_var_list ',' global_var { push($1, $3); } + | global_var { init($1); } +; + +global_var: + plain_variable { $$ = $1; } + | '$' variable { $$ = Expr\Variable[$2]; } + | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } +; + +static_var_list: + static_var_list ',' static_var { push($1, $3); } + | static_var { init($1); } +; + +static_var: + plain_variable { $$ = Stmt\StaticVar[$1, null]; } + | plain_variable '=' static_scalar { $$ = Stmt\StaticVar[$1, $3]; } +; + +class_statement_list_ex: + class_statement_list_ex class_statement { if ($2 !== null) { push($1, $2); } } + | /* empty */ { init(); } +; + +class_statement_list: + class_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +class_statement: + variable_modifiers property_declaration_list ';' + { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); } + | T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$2, 0]; } + | method_modifiers T_FUNCTION optional_ref identifier_ex '(' parameter_list ')' optional_return_type method_body + { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; + $this->checkClassMethod($$, #1); } + | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } +; + +trait_adaptations: + ';' { $$ = array(); } + | '{' trait_adaptation_list '}' { $$ = $2; } +; + +trait_adaptation_list: + /* empty */ { init(); } + | trait_adaptation_list trait_adaptation { push($1, $2); } +; + +trait_adaptation: + trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';' + { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; } + | trait_method_reference T_AS member_modifier identifier_ex ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; } + | trait_method_reference T_AS member_modifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; } + | trait_method_reference T_AS identifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } + | trait_method_reference T_AS reserved_non_modifiers_identifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } +; + +trait_method_reference_fully_qualified: + name T_PAAMAYIM_NEKUDOTAYIM identifier_ex { $$ = array($1, $3); } +; +trait_method_reference: + trait_method_reference_fully_qualified { $$ = $1; } + | identifier_ex { $$ = array(null, $1); } +; + +method_body: + ';' /* abstract method */ { $$ = null; } + | '{' inner_statement_list '}' { $$ = $2; } +; + +variable_modifiers: + non_empty_member_modifiers { $$ = $1; } + | T_VAR { $$ = 0; } +; + +method_modifiers: + /* empty */ { $$ = 0; } + | non_empty_member_modifiers { $$ = $1; } +; + +non_empty_member_modifiers: + member_modifier { $$ = $1; } + | non_empty_member_modifiers member_modifier { $this->checkModifier($1, $2, #2); $$ = $1 | $2; } +; + +member_modifier: + T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; } + | T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; } + | T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; } + | T_STATIC { $$ = Stmt\Class_::MODIFIER_STATIC; } + | T_ABSTRACT { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } + | T_FINAL { $$ = Stmt\Class_::MODIFIER_FINAL; } +; + +property_declaration_list: + property_declaration { init($1); } + | property_declaration_list ',' property_declaration { push($1, $3); } +; + +property_decl_name: + T_VARIABLE { $$ = Node\VarLikeIdentifier[parseVar($1)]; } +; + +property_declaration: + property_decl_name { $$ = Stmt\PropertyProperty[$1, null]; } + | property_decl_name '=' static_scalar { $$ = Stmt\PropertyProperty[$1, $3]; } +; + +expr_list: + expr_list ',' expr { push($1, $3); } + | expr { init($1); } +; + +for_expr: + /* empty */ { $$ = array(); } + | expr_list { $$ = $1; } +; + +expr: + variable { $$ = $1; } + | list_expr '=' expr { $$ = Expr\Assign[$1, $3]; } + | variable '=' expr { $$ = Expr\Assign[$1, $3]; } + | variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; } + | variable '=' '&' new_expr { $$ = Expr\AssignRef[$1, $4]; } + | new_expr { $$ = $1; } + | T_CLONE expr { $$ = Expr\Clone_[$2]; } + | variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; } + | variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; } + | variable T_MUL_EQUAL expr { $$ = Expr\AssignOp\Mul [$1, $3]; } + | variable T_DIV_EQUAL expr { $$ = Expr\AssignOp\Div [$1, $3]; } + | variable T_CONCAT_EQUAL expr { $$ = Expr\AssignOp\Concat [$1, $3]; } + | variable T_MOD_EQUAL expr { $$ = Expr\AssignOp\Mod [$1, $3]; } + | variable T_AND_EQUAL expr { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; } + | variable T_OR_EQUAL expr { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; } + | variable T_XOR_EQUAL expr { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; } + | variable T_SL_EQUAL expr { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; } + | variable T_SR_EQUAL expr { $$ = Expr\AssignOp\ShiftRight[$1, $3]; } + | variable T_POW_EQUAL expr { $$ = Expr\AssignOp\Pow [$1, $3]; } + | variable T_COALESCE_EQUAL expr { $$ = Expr\AssignOp\Coalesce [$1, $3]; } + | variable T_INC { $$ = Expr\PostInc[$1]; } + | T_INC variable { $$ = Expr\PreInc [$2]; } + | variable T_DEC { $$ = Expr\PostDec[$1]; } + | T_DEC variable { $$ = Expr\PreDec [$2]; } + | expr T_BOOLEAN_OR expr { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } + | expr T_BOOLEAN_AND expr { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } + | expr T_LOGICAL_OR expr { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } + | expr T_LOGICAL_AND expr { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } + | expr T_LOGICAL_XOR expr { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } + | expr '|' expr { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } + | expr '&' expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } + | expr '^' expr { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } + | expr '.' expr { $$ = Expr\BinaryOp\Concat [$1, $3]; } + | expr '+' expr { $$ = Expr\BinaryOp\Plus [$1, $3]; } + | expr '-' expr { $$ = Expr\BinaryOp\Minus [$1, $3]; } + | expr '*' expr { $$ = Expr\BinaryOp\Mul [$1, $3]; } + | expr '/' expr { $$ = Expr\BinaryOp\Div [$1, $3]; } + | expr '%' expr { $$ = Expr\BinaryOp\Mod [$1, $3]; } + | expr T_SL expr { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } + | expr T_SR expr { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } + | expr T_POW expr { $$ = Expr\BinaryOp\Pow [$1, $3]; } + | '+' expr %prec T_INC { $$ = Expr\UnaryPlus [$2]; } + | '-' expr %prec T_INC { $$ = Expr\UnaryMinus[$2]; } + | '!' expr { $$ = Expr\BooleanNot[$2]; } + | '~' expr { $$ = Expr\BitwiseNot[$2]; } + | expr T_IS_IDENTICAL expr { $$ = Expr\BinaryOp\Identical [$1, $3]; } + | expr T_IS_NOT_IDENTICAL expr { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } + | expr T_IS_EQUAL expr { $$ = Expr\BinaryOp\Equal [$1, $3]; } + | expr T_IS_NOT_EQUAL expr { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } + | expr T_SPACESHIP expr { $$ = Expr\BinaryOp\Spaceship [$1, $3]; } + | expr '<' expr { $$ = Expr\BinaryOp\Smaller [$1, $3]; } + | expr T_IS_SMALLER_OR_EQUAL expr { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } + | expr '>' expr { $$ = Expr\BinaryOp\Greater [$1, $3]; } + | expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } + | expr T_INSTANCEOF class_name_reference { $$ = Expr\Instanceof_[$1, $3]; } + | parentheses_expr { $$ = $1; } + /* we need a separate '(' new_expr ')' rule to avoid problems caused by a s/r conflict */ + | '(' new_expr ')' { $$ = $2; } + | expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; } + | expr '?' ':' expr { $$ = Expr\Ternary[$1, null, $4]; } + | expr T_COALESCE expr { $$ = Expr\BinaryOp\Coalesce[$1, $3]; } + | T_ISSET '(' variables_list ')' { $$ = Expr\Isset_[$3]; } + | T_EMPTY '(' expr ')' { $$ = Expr\Empty_[$3]; } + | T_INCLUDE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; } + | T_INCLUDE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; } + | T_EVAL parentheses_expr { $$ = Expr\Eval_[$2]; } + | T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; } + | T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; } + | T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; } + | T_DOUBLE_CAST expr + { $attrs = attributes(); + $attrs['kind'] = $this->getFloatCastKind($1); + $$ = new Expr\Cast\Double($2, $attrs); } + | T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; } + | T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; } + | T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; } + | T_BOOL_CAST expr { $$ = Expr\Cast\Bool_ [$2]; } + | T_UNSET_CAST expr { $$ = Expr\Cast\Unset_ [$2]; } + | T_EXIT exit_expr + { $attrs = attributes(); + $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $$ = new Expr\Exit_($2, $attrs); } + | '@' expr { $$ = Expr\ErrorSuppress[$2]; } + | scalar { $$ = $1; } + | array_expr { $$ = $1; } + | scalar_dereference { $$ = $1; } + | '`' backticks_expr '`' { $$ = Expr\ShellExec[$2]; } + | T_PRINT expr { $$ = Expr\Print_[$2]; } + | T_YIELD { $$ = Expr\Yield_[null, null]; } + | T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; } + | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type + '{' inner_statement_list '}' + { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; } + | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type + '{' inner_statement_list '}' + { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; } +; + +parentheses_expr: + '(' expr ')' { $$ = $2; } + | '(' yield_expr ')' { $$ = $2; } +; + +yield_expr: + T_YIELD expr { $$ = Expr\Yield_[$2, null]; } + | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; } +; + +array_expr: + T_ARRAY '(' array_pair_list ')' + { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG; + $$ = new Expr\Array_($3, $attrs); } + | '[' array_pair_list ']' + { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT; + $$ = new Expr\Array_($2, $attrs); } +; + +scalar_dereference: + array_expr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']' + { $attrs = attributes(); $attrs['kind'] = strKind($1); + $$ = Expr\ArrayDimFetch[new Scalar\String_(Scalar\String_::parse($1), $attrs), $3]; } + | constant '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | scalar_dereference '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + /* alternative array syntax missing intentionally */ +; + +anonymous_class: + T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' + { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); + $this->checkClass($$[0], -1); } +; + +new_expr: + T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } + | T_NEW anonymous_class + { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; } +; + +lexical_vars: + /* empty */ { $$ = array(); } + | T_USE '(' lexical_var_list ')' { $$ = $3; } +; + +lexical_var_list: + lexical_var { init($1); } + | lexical_var_list ',' lexical_var { push($1, $3); } +; + +lexical_var: + optional_ref plain_variable { $$ = Expr\ClosureUse[$2, $1]; } +; + +function_call: + name argument_list { $$ = Expr\FuncCall[$1, $2]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_ex argument_list + { $$ = Expr\StaticCall[$1, $3, $4]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' argument_list + { $$ = Expr\StaticCall[$1, $4, $6]; } + | static_property argument_list + { $$ = $this->fixupPhp5StaticPropCall($1, $2, attributes()); } + | variable_without_objects argument_list + { $$ = Expr\FuncCall[$1, $2]; } + | function_call '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + /* alternative array syntax missing intentionally */ +; + +class_name: + T_STATIC { $$ = Name[$1]; } + | name { $$ = $1; } +; + +name: + namespace_name_parts { $$ = Name[$1]; } + | T_NS_SEPARATOR namespace_name_parts { $$ = Name\FullyQualified[$2]; } + | T_NAMESPACE T_NS_SEPARATOR namespace_name_parts { $$ = Name\Relative[$3]; } +; + +class_name_reference: + class_name { $$ = $1; } + | dynamic_class_name_reference { $$ = $1; } +; + +dynamic_class_name_reference: + object_access_for_dcnr { $$ = $1; } + | base_variable { $$ = $1; } +; + +class_name_or_var: + class_name { $$ = $1; } + | reference_variable { $$ = $1; } +; + +object_access_for_dcnr: + base_variable T_OBJECT_OPERATOR object_property + { $$ = Expr\PropertyFetch[$1, $3]; } + | object_access_for_dcnr T_OBJECT_OPERATOR object_property + { $$ = Expr\PropertyFetch[$1, $3]; } + | object_access_for_dcnr '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | object_access_for_dcnr '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } +; + +exit_expr: + /* empty */ { $$ = null; } + | '(' ')' { $$ = null; } + | parentheses_expr { $$ = $1; } +; + +backticks_expr: + /* empty */ { $$ = array(); } + | T_ENCAPSED_AND_WHITESPACE + { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`', false)]); } + | encaps_list { parseEncapsed($1, '`', false); $$ = $1; } +; + +ctor_arguments: + /* empty */ { $$ = array(); } + | argument_list { $$ = $1; } +; + +common_scalar: + T_LNUMBER { $$ = $this->parseLNumber($1, attributes(), true); } + | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } + | T_CONSTANT_ENCAPSED_STRING + { $attrs = attributes(); $attrs['kind'] = strKind($1); + $$ = new Scalar\String_(Scalar\String_::parse($1, false), $attrs); } + | T_LINE { $$ = Scalar\MagicConst\Line[]; } + | T_FILE { $$ = Scalar\MagicConst\File[]; } + | T_DIR { $$ = Scalar\MagicConst\Dir[]; } + | T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; } + | T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; } + | T_METHOD_C { $$ = Scalar\MagicConst\Method[]; } + | T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; } + | T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; } + | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC + { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), false); } + | T_START_HEREDOC T_END_HEREDOC + { $$ = $this->parseDocString($1, '', $2, attributes(), stackAttributes(#2), false); } +; + +static_scalar: + common_scalar { $$ = $1; } + | class_name T_PAAMAYIM_NEKUDOTAYIM identifier_ex { $$ = Expr\ClassConstFetch[$1, $3]; } + | name { $$ = Expr\ConstFetch[$1]; } + | T_ARRAY '(' static_array_pair_list ')' { $$ = Expr\Array_[$3]; } + | '[' static_array_pair_list ']' { $$ = Expr\Array_[$2]; } + | static_operation { $$ = $1; } +; + +static_operation: + static_scalar T_BOOLEAN_OR static_scalar { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } + | static_scalar T_BOOLEAN_AND static_scalar { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } + | static_scalar T_LOGICAL_OR static_scalar { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } + | static_scalar T_LOGICAL_AND static_scalar { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } + | static_scalar T_LOGICAL_XOR static_scalar { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } + | static_scalar '|' static_scalar { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } + | static_scalar '&' static_scalar { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } + | static_scalar '^' static_scalar { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } + | static_scalar '.' static_scalar { $$ = Expr\BinaryOp\Concat [$1, $3]; } + | static_scalar '+' static_scalar { $$ = Expr\BinaryOp\Plus [$1, $3]; } + | static_scalar '-' static_scalar { $$ = Expr\BinaryOp\Minus [$1, $3]; } + | static_scalar '*' static_scalar { $$ = Expr\BinaryOp\Mul [$1, $3]; } + | static_scalar '/' static_scalar { $$ = Expr\BinaryOp\Div [$1, $3]; } + | static_scalar '%' static_scalar { $$ = Expr\BinaryOp\Mod [$1, $3]; } + | static_scalar T_SL static_scalar { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } + | static_scalar T_SR static_scalar { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } + | static_scalar T_POW static_scalar { $$ = Expr\BinaryOp\Pow [$1, $3]; } + | '+' static_scalar %prec T_INC { $$ = Expr\UnaryPlus [$2]; } + | '-' static_scalar %prec T_INC { $$ = Expr\UnaryMinus[$2]; } + | '!' static_scalar { $$ = Expr\BooleanNot[$2]; } + | '~' static_scalar { $$ = Expr\BitwiseNot[$2]; } + | static_scalar T_IS_IDENTICAL static_scalar { $$ = Expr\BinaryOp\Identical [$1, $3]; } + | static_scalar T_IS_NOT_IDENTICAL static_scalar { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } + | static_scalar T_IS_EQUAL static_scalar { $$ = Expr\BinaryOp\Equal [$1, $3]; } + | static_scalar T_IS_NOT_EQUAL static_scalar { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } + | static_scalar '<' static_scalar { $$ = Expr\BinaryOp\Smaller [$1, $3]; } + | static_scalar T_IS_SMALLER_OR_EQUAL static_scalar { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } + | static_scalar '>' static_scalar { $$ = Expr\BinaryOp\Greater [$1, $3]; } + | static_scalar T_IS_GREATER_OR_EQUAL static_scalar { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } + | static_scalar '?' static_scalar ':' static_scalar { $$ = Expr\Ternary[$1, $3, $5]; } + | static_scalar '?' ':' static_scalar { $$ = Expr\Ternary[$1, null, $4]; } + | static_scalar '[' static_scalar ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | '(' static_scalar ')' { $$ = $2; } +; + +constant: + name { $$ = Expr\ConstFetch[$1]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_ex + { $$ = Expr\ClassConstFetch[$1, $3]; } +; + +scalar: + common_scalar { $$ = $1; } + | constant { $$ = $1; } + | '"' encaps_list '"' + { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); } + | T_START_HEREDOC encaps_list T_END_HEREDOC + { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); } +; + +static_array_pair_list: + /* empty */ { $$ = array(); } + | non_empty_static_array_pair_list optional_comma { $$ = $1; } +; + +optional_comma: + /* empty */ + | ',' +; + +non_empty_static_array_pair_list: + non_empty_static_array_pair_list ',' static_array_pair { push($1, $3); } + | static_array_pair { init($1); } +; + +static_array_pair: + static_scalar T_DOUBLE_ARROW static_scalar { $$ = Expr\ArrayItem[$3, $1, false]; } + | static_scalar { $$ = Expr\ArrayItem[$1, null, false]; } +; + +variable: + object_access { $$ = $1; } + | base_variable { $$ = $1; } + | function_call { $$ = $1; } + | new_expr_array_deref { $$ = $1; } +; + +new_expr_array_deref: + '(' new_expr ')' '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$2, $5]; } + | new_expr_array_deref '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + /* alternative array syntax missing intentionally */ +; + +object_access: + variable_or_new_expr T_OBJECT_OPERATOR object_property + { $$ = Expr\PropertyFetch[$1, $3]; } + | variable_or_new_expr T_OBJECT_OPERATOR object_property argument_list + { $$ = Expr\MethodCall[$1, $3, $4]; } + | object_access argument_list { $$ = Expr\FuncCall[$1, $2]; } + | object_access '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | object_access '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } +; + +variable_or_new_expr: + variable { $$ = $1; } + | '(' new_expr ')' { $$ = $2; } +; + +variable_without_objects: + reference_variable { $$ = $1; } + | '$' variable_without_objects { $$ = Expr\Variable[$2]; } +; + +base_variable: + variable_without_objects { $$ = $1; } + | static_property { $$ = $1; } +; + +static_property: + class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '$' reference_variable + { $$ = Expr\StaticPropertyFetch[$1, $4]; } + | static_property_with_arrays { $$ = $1; } +; + +static_property_simple_name: + T_VARIABLE + { $var = parseVar($1); $$ = \is_string($var) ? Node\VarLikeIdentifier[$var] : $var; } +; + +static_property_with_arrays: + class_name_or_var T_PAAMAYIM_NEKUDOTAYIM static_property_simple_name + { $$ = Expr\StaticPropertyFetch[$1, $3]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '$' '{' expr '}' + { $$ = Expr\StaticPropertyFetch[$1, $5]; } + | static_property_with_arrays '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | static_property_with_arrays '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } +; + +reference_variable: + reference_variable '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | reference_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | plain_variable { $$ = $1; } + | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } +; + +dim_offset: + /* empty */ { $$ = null; } + | expr { $$ = $1; } +; + +object_property: + identifier { $$ = $1; } + | '{' expr '}' { $$ = $2; } + | variable_without_objects { $$ = $1; } + | error { $$ = Expr\Error[]; $this->errorState = 2; } +; + +list_expr: + T_LIST '(' list_expr_elements ')' { $$ = Expr\List_[$3]; } +; + +list_expr_elements: + list_expr_elements ',' list_expr_element { push($1, $3); } + | list_expr_element { init($1); } +; + +list_expr_element: + variable { $$ = Expr\ArrayItem[$1, null, false]; } + | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } + | /* empty */ { $$ = null; } +; + +array_pair_list: + /* empty */ { $$ = array(); } + | non_empty_array_pair_list optional_comma { $$ = $1; } +; + +non_empty_array_pair_list: + non_empty_array_pair_list ',' array_pair { push($1, $3); } + | array_pair { init($1); } +; + +array_pair: + expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; } + | expr { $$ = Expr\ArrayItem[$1, null, false]; } + | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } + | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } +; + +encaps_list: + encaps_list encaps_var { push($1, $2); } + | encaps_list encaps_string_part { push($1, $2); } + | encaps_var { init($1); } + | encaps_string_part encaps_var { init($1, $2); } +; + +encaps_string_part: + T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } +; + +encaps_str_varname: + T_STRING_VARNAME { $$ = Expr\Variable[$1]; } +; + +encaps_var: + plain_variable { $$ = $1; } + | plain_variable '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | plain_variable T_OBJECT_OPERATOR identifier { $$ = Expr\PropertyFetch[$1, $3]; } + | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = Expr\Variable[$2]; } + | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = Expr\Variable[$2]; } + | T_DOLLAR_OPEN_CURLY_BRACES encaps_str_varname '[' expr ']' '}' + { $$ = Expr\ArrayDimFetch[$2, $4]; } + | T_CURLY_OPEN variable '}' { $$ = $2; } +; + +encaps_var_offset: + T_STRING { $$ = Scalar\String_[$1]; } + | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } + | plain_variable { $$ = $1; } +; + +%% diff --git a/vendor/nikic/php-parser/grammar/php7.y b/vendor/nikic/php-parser/grammar/php7.y new file mode 100644 index 00000000..0d927ab6 --- /dev/null +++ b/vendor/nikic/php-parser/grammar/php7.y @@ -0,0 +1,1016 @@ +%pure_parser +%expect 2 + +%tokens + +%% + +start: + top_statement_list { $$ = $this->handleNamespaces($1); } +; + +top_statement_list_ex: + top_statement_list_ex top_statement { pushNormalizing($1, $2); } + | /* empty */ { init(); } +; + +top_statement_list: + top_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +reserved_non_modifiers: + T_INCLUDE | T_INCLUDE_ONCE | T_EVAL | T_REQUIRE | T_REQUIRE_ONCE | T_LOGICAL_OR | T_LOGICAL_XOR | T_LOGICAL_AND + | T_INSTANCEOF | T_NEW | T_CLONE | T_EXIT | T_IF | T_ELSEIF | T_ELSE | T_ENDIF | T_ECHO | T_DO | T_WHILE + | T_ENDWHILE | T_FOR | T_ENDFOR | T_FOREACH | T_ENDFOREACH | T_DECLARE | T_ENDDECLARE | T_AS | T_TRY | T_CATCH + | T_FINALLY | T_THROW | T_USE | T_INSTEADOF | T_GLOBAL | T_VAR | T_UNSET | T_ISSET | T_EMPTY | T_CONTINUE | T_GOTO + | T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT + | T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS + | T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER +; + +semi_reserved: + reserved_non_modifiers + | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC +; + +identifier_ex: + T_STRING { $$ = Node\Identifier[$1]; } + | semi_reserved { $$ = Node\Identifier[$1]; } +; + +identifier: + T_STRING { $$ = Node\Identifier[$1]; } +; + +reserved_non_modifiers_identifier: + reserved_non_modifiers { $$ = Node\Identifier[$1]; } +; + +namespace_name_parts: + T_STRING { init($1); } + | namespace_name_parts T_NS_SEPARATOR T_STRING { push($1, $3); } +; + +namespace_name: + namespace_name_parts { $$ = Name[$1]; } +; + +plain_variable: + T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +; + +semi: + ';' { /* nothing */ } + | error { /* nothing */ } +; + +no_comma: + /* empty */ { /* nothing */ } + | ',' { $this->emitError(new Error('A trailing comma is not allowed here', attributes())); } +; + +optional_comma: + /* empty */ + | ',' + +top_statement: + statement { $$ = $1; } + | function_declaration_statement { $$ = $1; } + | class_declaration_statement { $$ = $1; } + | T_HALT_COMPILER + { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; } + | T_NAMESPACE namespace_name semi + { $$ = Stmt\Namespace_[$2, null]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($$); } + | T_NAMESPACE namespace_name '{' top_statement_list '}' + { $$ = Stmt\Namespace_[$2, $4]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($$); } + | T_NAMESPACE '{' top_statement_list '}' + { $$ = Stmt\Namespace_[null, $3]; + $$->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($$); } + | T_USE use_declarations semi { $$ = Stmt\Use_[$2, Stmt\Use_::TYPE_NORMAL]; } + | T_USE use_type use_declarations semi { $$ = Stmt\Use_[$3, $2]; } + | group_use_declaration semi { $$ = $1; } + | T_CONST constant_declaration_list semi { $$ = Stmt\Const_[$2]; } +; + +use_type: + T_FUNCTION { $$ = Stmt\Use_::TYPE_FUNCTION; } + | T_CONST { $$ = Stmt\Use_::TYPE_CONSTANT; } +; + +/* Using namespace_name_parts here to avoid s/r conflict on T_NS_SEPARATOR */ +group_use_declaration: + T_USE use_type namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, $2]; } + | T_USE use_type T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' unprefixed_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($4, stackAttributes(#4)), $7, $2]; } + | T_USE namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($2, stackAttributes(#2)), $5, Stmt\Use_::TYPE_UNKNOWN]; } + | T_USE T_NS_SEPARATOR namespace_name_parts T_NS_SEPARATOR '{' inline_use_declarations '}' + { $$ = Stmt\GroupUse[new Name($3, stackAttributes(#3)), $6, Stmt\Use_::TYPE_UNKNOWN]; } +; + +unprefixed_use_declarations: + non_empty_unprefixed_use_declarations optional_comma { $$ = $1; } +; + +non_empty_unprefixed_use_declarations: + non_empty_unprefixed_use_declarations ',' unprefixed_use_declaration + { push($1, $3); } + | unprefixed_use_declaration { init($1); } +; + +use_declarations: + non_empty_use_declarations no_comma { $$ = $1; } +; + +non_empty_use_declarations: + non_empty_use_declarations ',' use_declaration { push($1, $3); } + | use_declaration { init($1); } +; + +inline_use_declarations: + non_empty_inline_use_declarations optional_comma { $$ = $1; } +; + +non_empty_inline_use_declarations: + non_empty_inline_use_declarations ',' inline_use_declaration + { push($1, $3); } + | inline_use_declaration { init($1); } +; + +unprefixed_use_declaration: + namespace_name + { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } + | namespace_name T_AS identifier + { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } +; + +use_declaration: + unprefixed_use_declaration { $$ = $1; } + | T_NS_SEPARATOR unprefixed_use_declaration { $$ = $2; } +; + +inline_use_declaration: + unprefixed_use_declaration { $$ = $1; $$->type = Stmt\Use_::TYPE_NORMAL; } + | use_type unprefixed_use_declaration { $$ = $2; $$->type = $1; } +; + +constant_declaration_list: + non_empty_constant_declaration_list no_comma { $$ = $1; } +; + +non_empty_constant_declaration_list: + non_empty_constant_declaration_list ',' constant_declaration + { push($1, $3); } + | constant_declaration { init($1); } +; + +constant_declaration: + identifier '=' expr { $$ = Node\Const_[$1, $3]; } +; + +class_const_list: + non_empty_class_const_list no_comma { $$ = $1; } +; + +non_empty_class_const_list: + non_empty_class_const_list ',' class_const { push($1, $3); } + | class_const { init($1); } +; + +class_const: + identifier_ex '=' expr { $$ = Node\Const_[$1, $3]; } +; + +inner_statement_list_ex: + inner_statement_list_ex inner_statement { pushNormalizing($1, $2); } + | /* empty */ { init(); } +; + +inner_statement_list: + inner_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +inner_statement: + statement { $$ = $1; } + | function_declaration_statement { $$ = $1; } + | class_declaration_statement { $$ = $1; } + | T_HALT_COMPILER + { throw new Error('__HALT_COMPILER() can only be used from the outermost scope', attributes()); } +; + +non_empty_statement: + '{' inner_statement_list '}' + { + if ($2) { + $$ = $2; prependLeadingComments($$); + } else { + makeNop($$, $this->startAttributeStack[#1], $this->endAttributes); + if (null === $$) { $$ = array(); } + } + } + | T_IF '(' expr ')' statement elseif_list else_single + { $$ = Stmt\If_[$3, ['stmts' => toArray($5), 'elseifs' => $6, 'else' => $7]]; } + | T_IF '(' expr ')' ':' inner_statement_list new_elseif_list new_else_single T_ENDIF ';' + { $$ = Stmt\If_[$3, ['stmts' => $6, 'elseifs' => $7, 'else' => $8]]; } + | T_WHILE '(' expr ')' while_statement { $$ = Stmt\While_[$3, $5]; } + | T_DO statement T_WHILE '(' expr ')' ';' { $$ = Stmt\Do_ [$5, toArray($2)]; } + | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement + { $$ = Stmt\For_[['init' => $3, 'cond' => $5, 'loop' => $7, 'stmts' => $9]]; } + | T_SWITCH '(' expr ')' switch_case_list { $$ = Stmt\Switch_[$3, $5]; } + | T_BREAK optional_expr semi { $$ = Stmt\Break_[$2]; } + | T_CONTINUE optional_expr semi { $$ = Stmt\Continue_[$2]; } + | T_RETURN optional_expr semi { $$ = Stmt\Return_[$2]; } + | T_GLOBAL global_var_list semi { $$ = Stmt\Global_[$2]; } + | T_STATIC static_var_list semi { $$ = Stmt\Static_[$2]; } + | T_ECHO expr_list semi { $$ = Stmt\Echo_[$2]; } + | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } + | expr semi { $$ = Stmt\Expression[$1]; } + | T_UNSET '(' variables_list ')' semi { $$ = Stmt\Unset_[$3]; } + | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement + { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } + | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement + { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; } + | T_FOREACH '(' expr error ')' foreach_statement + { $$ = Stmt\Foreach_[$3, new Expr\Error(stackAttributes(#4)), ['stmts' => $6]]; } + | T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; } + | T_TRY '{' inner_statement_list '}' catches optional_finally + { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } + | T_THROW expr semi { $$ = Stmt\Throw_[$2]; } + | T_GOTO identifier semi { $$ = Stmt\Goto_[$2]; } + | identifier ':' { $$ = Stmt\Label[$1]; } + | error { $$ = array(); /* means: no statement */ } +; + +statement: + non_empty_statement { $$ = $1; } + | ';' + { makeNop($$, $this->startAttributeStack[#1], $this->endAttributes); + if ($$ === null) $$ = array(); /* means: no statement */ } +; + +catches: + /* empty */ { init(); } + | catches catch { push($1, $2); } +; + +name_union: + name { init($1); } + | name_union '|' name { push($1, $3); } +; + +catch: + T_CATCH '(' name_union plain_variable ')' '{' inner_statement_list '}' + { $$ = Stmt\Catch_[$3, $4, $7]; } +; + +optional_finally: + /* empty */ { $$ = null; } + | T_FINALLY '{' inner_statement_list '}' { $$ = Stmt\Finally_[$3]; } +; + +variables_list: + non_empty_variables_list optional_comma { $$ = $1; } +; + +non_empty_variables_list: + variable { init($1); } + | non_empty_variables_list ',' variable { push($1, $3); } +; + +optional_ref: + /* empty */ { $$ = false; } + | '&' { $$ = true; } +; + +optional_ellipsis: + /* empty */ { $$ = false; } + | T_ELLIPSIS { $$ = true; } +; + +block_or_error: + '{' inner_statement_list '}' { $$ = $2; } + | error { $$ = []; } +; + +function_declaration_statement: + T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type block_or_error + { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $8]]; } +; + +class_declaration_statement: + class_entry_type identifier extends_from implements_list '{' class_statement_list '}' + { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]]; + $this->checkClass($$, #2); } + | T_INTERFACE identifier interface_extends_list '{' class_statement_list '}' + { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; + $this->checkInterface($$, #2); } + | T_TRAIT identifier '{' class_statement_list '}' + { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } +; + +class_entry_type: + T_CLASS { $$ = 0; } + | T_ABSTRACT T_CLASS { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } + | T_FINAL T_CLASS { $$ = Stmt\Class_::MODIFIER_FINAL; } +; + +extends_from: + /* empty */ { $$ = null; } + | T_EXTENDS class_name { $$ = $2; } +; + +interface_extends_list: + /* empty */ { $$ = array(); } + | T_EXTENDS class_name_list { $$ = $2; } +; + +implements_list: + /* empty */ { $$ = array(); } + | T_IMPLEMENTS class_name_list { $$ = $2; } +; + +class_name_list: + non_empty_class_name_list no_comma { $$ = $1; } +; + +non_empty_class_name_list: + class_name { init($1); } + | non_empty_class_name_list ',' class_name { push($1, $3); } +; + +for_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDFOR ';' { $$ = $2; } +; + +foreach_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDFOREACH ';' { $$ = $2; } +; + +declare_statement: + non_empty_statement { $$ = toArray($1); } + | ';' { $$ = null; } + | ':' inner_statement_list T_ENDDECLARE ';' { $$ = $2; } +; + +declare_list: + non_empty_declare_list no_comma { $$ = $1; } +; + +non_empty_declare_list: + declare_list_element { init($1); } + | non_empty_declare_list ',' declare_list_element { push($1, $3); } +; + +declare_list_element: + identifier '=' expr { $$ = Stmt\DeclareDeclare[$1, $3]; } +; + +switch_case_list: + '{' case_list '}' { $$ = $2; } + | '{' ';' case_list '}' { $$ = $3; } + | ':' case_list T_ENDSWITCH ';' { $$ = $2; } + | ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; } +; + +case_list: + /* empty */ { init(); } + | case_list case { push($1, $2); } +; + +case: + T_CASE expr case_separator inner_statement_list_ex { $$ = Stmt\Case_[$2, $4]; } + | T_DEFAULT case_separator inner_statement_list_ex { $$ = Stmt\Case_[null, $3]; } +; + +case_separator: + ':' + | ';' +; + +while_statement: + statement { $$ = toArray($1); } + | ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; } +; + +elseif_list: + /* empty */ { init(); } + | elseif_list elseif { push($1, $2); } +; + +elseif: + T_ELSEIF '(' expr ')' statement { $$ = Stmt\ElseIf_[$3, toArray($5)]; } +; + +new_elseif_list: + /* empty */ { init(); } + | new_elseif_list new_elseif { push($1, $2); } +; + +new_elseif: + T_ELSEIF '(' expr ')' ':' inner_statement_list { $$ = Stmt\ElseIf_[$3, $6]; } +; + +else_single: + /* empty */ { $$ = null; } + | T_ELSE statement { $$ = Stmt\Else_[toArray($2)]; } +; + +new_else_single: + /* empty */ { $$ = null; } + | T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; } +; + +foreach_variable: + variable { $$ = array($1, false); } + | '&' variable { $$ = array($2, true); } + | list_expr { $$ = array($1, false); } + | array_short_syntax { $$ = array($1, false); } +; + +parameter_list: + non_empty_parameter_list no_comma { $$ = $1; } + | /* empty */ { $$ = array(); } +; + +non_empty_parameter_list: + parameter { init($1); } + | non_empty_parameter_list ',' parameter { push($1, $3); } +; + +parameter: + optional_type optional_ref optional_ellipsis plain_variable + { $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); } + | optional_type optional_ref optional_ellipsis plain_variable '=' expr + { $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); } + | optional_type optional_ref optional_ellipsis error + { $$ = Node\Param[Expr\Error[], null, $1, $2, $3]; } +; + +type_expr: + type { $$ = $1; } + | '?' type { $$ = Node\NullableType[$2]; } +; + +type: + name { $$ = $this->handleBuiltinTypes($1); } + | T_ARRAY { $$ = Node\Identifier['array']; } + | T_CALLABLE { $$ = Node\Identifier['callable']; } +; + +optional_type: + /* empty */ { $$ = null; } + | type_expr { $$ = $1; } +; + +optional_return_type: + /* empty */ { $$ = null; } + | ':' type_expr { $$ = $2; } + | ':' error { $$ = null; } +; + +argument_list: + '(' ')' { $$ = array(); } + | '(' non_empty_argument_list optional_comma ')' { $$ = $2; } +; + +non_empty_argument_list: + argument { init($1); } + | non_empty_argument_list ',' argument { push($1, $3); } +; + +argument: + expr { $$ = Node\Arg[$1, false, false]; } + | '&' variable { $$ = Node\Arg[$2, true, false]; } + | T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; } +; + +global_var_list: + non_empty_global_var_list no_comma { $$ = $1; } +; + +non_empty_global_var_list: + non_empty_global_var_list ',' global_var { push($1, $3); } + | global_var { init($1); } +; + +global_var: + simple_variable { $$ = Expr\Variable[$1]; } +; + +static_var_list: + non_empty_static_var_list no_comma { $$ = $1; } +; + +non_empty_static_var_list: + non_empty_static_var_list ',' static_var { push($1, $3); } + | static_var { init($1); } +; + +static_var: + plain_variable { $$ = Stmt\StaticVar[$1, null]; } + | plain_variable '=' expr { $$ = Stmt\StaticVar[$1, $3]; } +; + +class_statement_list_ex: + class_statement_list_ex class_statement { if ($2 !== null) { push($1, $2); } } + | /* empty */ { init(); } +; + +class_statement_list: + class_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + +class_statement: + variable_modifiers optional_type property_declaration_list ';' + { $attrs = attributes(); + $$ = new Stmt\Property($1, $3, $attrs, $2); $this->checkProperty($$, #1); } + | method_modifiers T_CONST class_const_list ';' + { $$ = Stmt\ClassConst[$3, $1]; $this->checkClassConst($$, #1); } + | method_modifiers T_FUNCTION optional_ref identifier_ex '(' parameter_list ')' optional_return_type method_body + { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; + $this->checkClassMethod($$, #1); } + | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } + | error { $$ = null; /* will be skipped */ } +; + +trait_adaptations: + ';' { $$ = array(); } + | '{' trait_adaptation_list '}' { $$ = $2; } +; + +trait_adaptation_list: + /* empty */ { init(); } + | trait_adaptation_list trait_adaptation { push($1, $2); } +; + +trait_adaptation: + trait_method_reference_fully_qualified T_INSTEADOF class_name_list ';' + { $$ = Stmt\TraitUseAdaptation\Precedence[$1[0], $1[1], $3]; } + | trait_method_reference T_AS member_modifier identifier_ex ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, $4]; } + | trait_method_reference T_AS member_modifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], $3, null]; } + | trait_method_reference T_AS identifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } + | trait_method_reference T_AS reserved_non_modifiers_identifier ';' + { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } +; + +trait_method_reference_fully_qualified: + name T_PAAMAYIM_NEKUDOTAYIM identifier_ex { $$ = array($1, $3); } +; +trait_method_reference: + trait_method_reference_fully_qualified { $$ = $1; } + | identifier_ex { $$ = array(null, $1); } +; + +method_body: + ';' /* abstract method */ { $$ = null; } + | block_or_error { $$ = $1; } +; + +variable_modifiers: + non_empty_member_modifiers { $$ = $1; } + | T_VAR { $$ = 0; } +; + +method_modifiers: + /* empty */ { $$ = 0; } + | non_empty_member_modifiers { $$ = $1; } +; + +non_empty_member_modifiers: + member_modifier { $$ = $1; } + | non_empty_member_modifiers member_modifier { $this->checkModifier($1, $2, #2); $$ = $1 | $2; } +; + +member_modifier: + T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; } + | T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; } + | T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; } + | T_STATIC { $$ = Stmt\Class_::MODIFIER_STATIC; } + | T_ABSTRACT { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } + | T_FINAL { $$ = Stmt\Class_::MODIFIER_FINAL; } +; + +property_declaration_list: + non_empty_property_declaration_list no_comma { $$ = $1; } +; + +non_empty_property_declaration_list: + property_declaration { init($1); } + | non_empty_property_declaration_list ',' property_declaration + { push($1, $3); } +; + +property_decl_name: + T_VARIABLE { $$ = Node\VarLikeIdentifier[parseVar($1)]; } +; + +property_declaration: + property_decl_name { $$ = Stmt\PropertyProperty[$1, null]; } + | property_decl_name '=' expr { $$ = Stmt\PropertyProperty[$1, $3]; } +; + +expr_list: + non_empty_expr_list no_comma { $$ = $1; } +; + +non_empty_expr_list: + non_empty_expr_list ',' expr { push($1, $3); } + | expr { init($1); } +; + +for_expr: + /* empty */ { $$ = array(); } + | expr_list { $$ = $1; } +; + +expr: + variable { $$ = $1; } + | list_expr '=' expr { $$ = Expr\Assign[$1, $3]; } + | array_short_syntax '=' expr { $$ = Expr\Assign[$1, $3]; } + | variable '=' expr { $$ = Expr\Assign[$1, $3]; } + | variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; } + | new_expr { $$ = $1; } + | T_CLONE expr { $$ = Expr\Clone_[$2]; } + | variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; } + | variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; } + | variable T_MUL_EQUAL expr { $$ = Expr\AssignOp\Mul [$1, $3]; } + | variable T_DIV_EQUAL expr { $$ = Expr\AssignOp\Div [$1, $3]; } + | variable T_CONCAT_EQUAL expr { $$ = Expr\AssignOp\Concat [$1, $3]; } + | variable T_MOD_EQUAL expr { $$ = Expr\AssignOp\Mod [$1, $3]; } + | variable T_AND_EQUAL expr { $$ = Expr\AssignOp\BitwiseAnd[$1, $3]; } + | variable T_OR_EQUAL expr { $$ = Expr\AssignOp\BitwiseOr [$1, $3]; } + | variable T_XOR_EQUAL expr { $$ = Expr\AssignOp\BitwiseXor[$1, $3]; } + | variable T_SL_EQUAL expr { $$ = Expr\AssignOp\ShiftLeft [$1, $3]; } + | variable T_SR_EQUAL expr { $$ = Expr\AssignOp\ShiftRight[$1, $3]; } + | variable T_POW_EQUAL expr { $$ = Expr\AssignOp\Pow [$1, $3]; } + | variable T_COALESCE_EQUAL expr { $$ = Expr\AssignOp\Coalesce [$1, $3]; } + | variable T_INC { $$ = Expr\PostInc[$1]; } + | T_INC variable { $$ = Expr\PreInc [$2]; } + | variable T_DEC { $$ = Expr\PostDec[$1]; } + | T_DEC variable { $$ = Expr\PreDec [$2]; } + | expr T_BOOLEAN_OR expr { $$ = Expr\BinaryOp\BooleanOr [$1, $3]; } + | expr T_BOOLEAN_AND expr { $$ = Expr\BinaryOp\BooleanAnd[$1, $3]; } + | expr T_LOGICAL_OR expr { $$ = Expr\BinaryOp\LogicalOr [$1, $3]; } + | expr T_LOGICAL_AND expr { $$ = Expr\BinaryOp\LogicalAnd[$1, $3]; } + | expr T_LOGICAL_XOR expr { $$ = Expr\BinaryOp\LogicalXor[$1, $3]; } + | expr '|' expr { $$ = Expr\BinaryOp\BitwiseOr [$1, $3]; } + | expr '&' expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } + | expr '^' expr { $$ = Expr\BinaryOp\BitwiseXor[$1, $3]; } + | expr '.' expr { $$ = Expr\BinaryOp\Concat [$1, $3]; } + | expr '+' expr { $$ = Expr\BinaryOp\Plus [$1, $3]; } + | expr '-' expr { $$ = Expr\BinaryOp\Minus [$1, $3]; } + | expr '*' expr { $$ = Expr\BinaryOp\Mul [$1, $3]; } + | expr '/' expr { $$ = Expr\BinaryOp\Div [$1, $3]; } + | expr '%' expr { $$ = Expr\BinaryOp\Mod [$1, $3]; } + | expr T_SL expr { $$ = Expr\BinaryOp\ShiftLeft [$1, $3]; } + | expr T_SR expr { $$ = Expr\BinaryOp\ShiftRight[$1, $3]; } + | expr T_POW expr { $$ = Expr\BinaryOp\Pow [$1, $3]; } + | '+' expr %prec T_INC { $$ = Expr\UnaryPlus [$2]; } + | '-' expr %prec T_INC { $$ = Expr\UnaryMinus[$2]; } + | '!' expr { $$ = Expr\BooleanNot[$2]; } + | '~' expr { $$ = Expr\BitwiseNot[$2]; } + | expr T_IS_IDENTICAL expr { $$ = Expr\BinaryOp\Identical [$1, $3]; } + | expr T_IS_NOT_IDENTICAL expr { $$ = Expr\BinaryOp\NotIdentical [$1, $3]; } + | expr T_IS_EQUAL expr { $$ = Expr\BinaryOp\Equal [$1, $3]; } + | expr T_IS_NOT_EQUAL expr { $$ = Expr\BinaryOp\NotEqual [$1, $3]; } + | expr T_SPACESHIP expr { $$ = Expr\BinaryOp\Spaceship [$1, $3]; } + | expr '<' expr { $$ = Expr\BinaryOp\Smaller [$1, $3]; } + | expr T_IS_SMALLER_OR_EQUAL expr { $$ = Expr\BinaryOp\SmallerOrEqual[$1, $3]; } + | expr '>' expr { $$ = Expr\BinaryOp\Greater [$1, $3]; } + | expr T_IS_GREATER_OR_EQUAL expr { $$ = Expr\BinaryOp\GreaterOrEqual[$1, $3]; } + | expr T_INSTANCEOF class_name_reference { $$ = Expr\Instanceof_[$1, $3]; } + | '(' expr ')' { $$ = $2; } + | expr '?' expr ':' expr { $$ = Expr\Ternary[$1, $3, $5]; } + | expr '?' ':' expr { $$ = Expr\Ternary[$1, null, $4]; } + | expr T_COALESCE expr { $$ = Expr\BinaryOp\Coalesce[$1, $3]; } + | T_ISSET '(' variables_list ')' { $$ = Expr\Isset_[$3]; } + | T_EMPTY '(' expr ')' { $$ = Expr\Empty_[$3]; } + | T_INCLUDE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE]; } + | T_INCLUDE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_INCLUDE_ONCE]; } + | T_EVAL '(' expr ')' { $$ = Expr\Eval_[$3]; } + | T_REQUIRE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE]; } + | T_REQUIRE_ONCE expr { $$ = Expr\Include_[$2, Expr\Include_::TYPE_REQUIRE_ONCE]; } + | T_INT_CAST expr { $$ = Expr\Cast\Int_ [$2]; } + | T_DOUBLE_CAST expr + { $attrs = attributes(); + $attrs['kind'] = $this->getFloatCastKind($1); + $$ = new Expr\Cast\Double($2, $attrs); } + | T_STRING_CAST expr { $$ = Expr\Cast\String_ [$2]; } + | T_ARRAY_CAST expr { $$ = Expr\Cast\Array_ [$2]; } + | T_OBJECT_CAST expr { $$ = Expr\Cast\Object_ [$2]; } + | T_BOOL_CAST expr { $$ = Expr\Cast\Bool_ [$2]; } + | T_UNSET_CAST expr { $$ = Expr\Cast\Unset_ [$2]; } + | T_EXIT exit_expr + { $attrs = attributes(); + $attrs['kind'] = strtolower($1) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $$ = new Expr\Exit_($2, $attrs); } + | '@' expr { $$ = Expr\ErrorSuppress[$2]; } + | scalar { $$ = $1; } + | '`' backticks_expr '`' { $$ = Expr\ShellExec[$2]; } + | T_PRINT expr { $$ = Expr\Print_[$2]; } + | T_YIELD { $$ = Expr\Yield_[null, null]; } + | T_YIELD expr { $$ = Expr\Yield_[$2, null]; } + | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; } + | T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; } + | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type + block_or_error + { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $8]]; } + | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type + block_or_error + { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9]]; } +; + +anonymous_class: + T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' + { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); + $this->checkClass($$[0], -1); } +; + +new_expr: + T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } + | T_NEW anonymous_class + { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; } +; + +lexical_vars: + /* empty */ { $$ = array(); } + | T_USE '(' lexical_var_list ')' { $$ = $3; } +; + +lexical_var_list: + non_empty_lexical_var_list no_comma { $$ = $1; } +; + +non_empty_lexical_var_list: + lexical_var { init($1); } + | non_empty_lexical_var_list ',' lexical_var { push($1, $3); } +; + +lexical_var: + optional_ref plain_variable { $$ = Expr\ClosureUse[$2, $1]; } +; + +function_call: + name argument_list { $$ = Expr\FuncCall[$1, $2]; } + | callable_expr argument_list { $$ = Expr\FuncCall[$1, $2]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM member_name argument_list + { $$ = Expr\StaticCall[$1, $3, $4]; } +; + +class_name: + T_STATIC { $$ = Name[$1]; } + | name { $$ = $1; } +; + +name: + namespace_name_parts { $$ = Name[$1]; } + | T_NS_SEPARATOR namespace_name_parts { $$ = Name\FullyQualified[$2]; } + | T_NAMESPACE T_NS_SEPARATOR namespace_name_parts { $$ = Name\Relative[$3]; } +; + +class_name_reference: + class_name { $$ = $1; } + | new_variable { $$ = $1; } + | error { $$ = Expr\Error[]; $this->errorState = 2; } +; + +class_name_or_var: + class_name { $$ = $1; } + | dereferencable { $$ = $1; } +; + +exit_expr: + /* empty */ { $$ = null; } + | '(' optional_expr ')' { $$ = $2; } +; + +backticks_expr: + /* empty */ { $$ = array(); } + | T_ENCAPSED_AND_WHITESPACE + { $$ = array(Scalar\EncapsedStringPart[Scalar\String_::parseEscapeSequences($1, '`')]); } + | encaps_list { parseEncapsed($1, '`', true); $$ = $1; } +; + +ctor_arguments: + /* empty */ { $$ = array(); } + | argument_list { $$ = $1; } +; + +constant: + name { $$ = Expr\ConstFetch[$1]; } + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_ex + { $$ = Expr\ClassConstFetch[$1, $3]; } + /* We interpret and isolated FOO:: as an unfinished class constant fetch. It could also be + an unfinished static property fetch or unfinished scoped call. */ + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM error + { $$ = Expr\ClassConstFetch[$1, new Expr\Error(stackAttributes(#3))]; $this->errorState = 2; } +; + +array_short_syntax: + '[' array_pair_list ']' + { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_SHORT; + $$ = new Expr\Array_($2, $attrs); } +; + +dereferencable_scalar: + T_ARRAY '(' array_pair_list ')' + { $attrs = attributes(); $attrs['kind'] = Expr\Array_::KIND_LONG; + $$ = new Expr\Array_($3, $attrs); } + | array_short_syntax { $$ = $1; } + | T_CONSTANT_ENCAPSED_STRING + { $attrs = attributes(); $attrs['kind'] = strKind($1); + $$ = new Scalar\String_(Scalar\String_::parse($1), $attrs); } +; + +scalar: + T_LNUMBER { $$ = $this->parseLNumber($1, attributes()); } + | T_DNUMBER { $$ = Scalar\DNumber[Scalar\DNumber::parse($1)]; } + | T_LINE { $$ = Scalar\MagicConst\Line[]; } + | T_FILE { $$ = Scalar\MagicConst\File[]; } + | T_DIR { $$ = Scalar\MagicConst\Dir[]; } + | T_CLASS_C { $$ = Scalar\MagicConst\Class_[]; } + | T_TRAIT_C { $$ = Scalar\MagicConst\Trait_[]; } + | T_METHOD_C { $$ = Scalar\MagicConst\Method[]; } + | T_FUNC_C { $$ = Scalar\MagicConst\Function_[]; } + | T_NS_C { $$ = Scalar\MagicConst\Namespace_[]; } + | dereferencable_scalar { $$ = $1; } + | constant { $$ = $1; } + | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC + { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); } + | T_START_HEREDOC T_END_HEREDOC + { $$ = $this->parseDocString($1, '', $2, attributes(), stackAttributes(#2), true); } + | '"' encaps_list '"' + { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); } + | T_START_HEREDOC encaps_list T_END_HEREDOC + { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); } +; + +optional_expr: + /* empty */ { $$ = null; } + | expr { $$ = $1; } +; + +dereferencable: + variable { $$ = $1; } + | '(' expr ')' { $$ = $2; } + | dereferencable_scalar { $$ = $1; } +; + +callable_expr: + callable_variable { $$ = $1; } + | '(' expr ')' { $$ = $2; } + | dereferencable_scalar { $$ = $1; } +; + +callable_variable: + simple_variable { $$ = Expr\Variable[$1]; } + | dereferencable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | constant '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | dereferencable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | function_call { $$ = $1; } + | dereferencable T_OBJECT_OPERATOR property_name argument_list + { $$ = Expr\MethodCall[$1, $3, $4]; } +; + +variable: + callable_variable { $$ = $1; } + | static_member { $$ = $1; } + | dereferencable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } +; + +simple_variable: + T_VARIABLE { $$ = parseVar($1); } + | '$' '{' expr '}' { $$ = $3; } + | '$' simple_variable { $$ = Expr\Variable[$2]; } + | '$' error { $$ = Expr\Error[]; $this->errorState = 2; } +; + +static_member_prop_name: + simple_variable + { $var = $1; $$ = \is_string($var) ? Node\VarLikeIdentifier[$var] : $var; } +; + +static_member: + class_name_or_var T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name + { $$ = Expr\StaticPropertyFetch[$1, $3]; } +; + +new_variable: + simple_variable { $$ = Expr\Variable[$1]; } + | new_variable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | new_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | new_variable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } + | class_name T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name + { $$ = Expr\StaticPropertyFetch[$1, $3]; } + | new_variable T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name + { $$ = Expr\StaticPropertyFetch[$1, $3]; } +; + +member_name: + identifier_ex { $$ = $1; } + | '{' expr '}' { $$ = $2; } + | simple_variable { $$ = Expr\Variable[$1]; } +; + +property_name: + identifier { $$ = $1; } + | '{' expr '}' { $$ = $2; } + | simple_variable { $$ = Expr\Variable[$1]; } + | error { $$ = Expr\Error[]; $this->errorState = 2; } +; + +list_expr: + T_LIST '(' list_expr_elements ')' { $$ = Expr\List_[$3]; } +; + +list_expr_elements: + list_expr_elements ',' list_expr_element { push($1, $3); } + | list_expr_element { init($1); } +; + +list_expr_element: + variable { $$ = Expr\ArrayItem[$1, null, false]; } + | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } + | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } + | expr T_DOUBLE_ARROW variable { $$ = Expr\ArrayItem[$3, $1, false]; } + | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } + | expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; } + | /* empty */ { $$ = null; } +; + +array_pair_list: + inner_array_pair_list + { $$ = $1; $end = count($$)-1; if ($$[$end] === null) array_pop($$); } +; + +comma_or_error: + ',' + | error + { /* do nothing -- prevent default action of $$=$1. See #551. */ } +; + +inner_array_pair_list: + inner_array_pair_list comma_or_error array_pair { push($1, $3); } + | array_pair { init($1); } +; + +array_pair: + expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; } + | expr { $$ = Expr\ArrayItem[$1, null, false]; } + | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } + | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } + | /* empty */ { $$ = null; } +; + +encaps_list: + encaps_list encaps_var { push($1, $2); } + | encaps_list encaps_string_part { push($1, $2); } + | encaps_var { init($1); } + | encaps_string_part encaps_var { init($1, $2); } +; + +encaps_string_part: + T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } +; + +encaps_str_varname: + T_STRING_VARNAME { $$ = Expr\Variable[$1]; } +; + +encaps_var: + plain_variable { $$ = $1; } + | plain_variable '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } + | plain_variable T_OBJECT_OPERATOR identifier { $$ = Expr\PropertyFetch[$1, $3]; } + | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { $$ = Expr\Variable[$2]; } + | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { $$ = Expr\Variable[$2]; } + | T_DOLLAR_OPEN_CURLY_BRACES encaps_str_varname '[' expr ']' '}' + { $$ = Expr\ArrayDimFetch[$2, $4]; } + | T_CURLY_OPEN variable '}' { $$ = $2; } +; + +encaps_var_offset: + T_STRING { $$ = Scalar\String_[$1]; } + | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } + | '-' T_NUM_STRING { $$ = $this->parseNumString('-' . $2, attributes()); } + | plain_variable { $$ = $1; } +; + +%% diff --git a/vendor/nikic/php-parser/grammar/rebuildParsers.php b/vendor/nikic/php-parser/grammar/rebuildParsers.php new file mode 100644 index 00000000..1882d5fe --- /dev/null +++ b/vendor/nikic/php-parser/grammar/rebuildParsers.php @@ -0,0 +1,245 @@ + 'Php5', + __DIR__ . '/php7.y' => 'Php7', +]; + +$tokensFile = __DIR__ . '/tokens.y'; +$tokensTemplate = __DIR__ . '/tokens.template'; +$skeletonFile = __DIR__ . '/parser.template'; +$tmpGrammarFile = __DIR__ . '/tmp_parser.phpy'; +$tmpResultFile = __DIR__ . '/tmp_parser.php'; +$resultDir = __DIR__ . '/../lib/PhpParser/Parser'; +$tokensResultsFile = $resultDir . '/Tokens.php'; + +// check for kmyacc.exe binary in this directory, otherwise fall back to global name +$kmyacc = __DIR__ . '/kmyacc.exe'; +if (!file_exists($kmyacc)) { + $kmyacc = 'kmyacc'; +} + +$options = array_flip($argv); +$optionDebug = isset($options['--debug']); +$optionKeepTmpGrammar = isset($options['--keep-tmp-grammar']); + +/////////////////////////////// +/// Utility regex constants /// +/////////////////////////////// + +const LIB = '(?(DEFINE) + (?\'[^\\\\\']*+(?:\\\\.[^\\\\\']*+)*+\') + (?"[^\\\\"]*+(?:\\\\.[^\\\\"]*+)*+") + (?(?&singleQuotedString)|(?&doubleQuotedString)) + (?/\*[^*]*+(?:\*(?!/)[^*]*+)*+\*/) + (?\{[^\'"/{}]*+(?:(?:(?&string)|(?&comment)|(?&code)|/)[^\'"/{}]*+)*+}) +)'; + +const PARAMS = '\[(?[^[\]]*+(?:\[(?¶ms)\][^[\]]*+)*+)\]'; +const ARGS = '\((?[^()]*+(?:\((?&args)\)[^()]*+)*+)\)'; + +/////////////////// +/// Main script /// +/////////////////// + +$tokens = file_get_contents($tokensFile); + +foreach ($grammarFileToName as $grammarFile => $name) { + echo "Building temporary $name grammar file.\n"; + + $grammarCode = file_get_contents($grammarFile); + $grammarCode = str_replace('%tokens', $tokens, $grammarCode); + + $grammarCode = resolveNodes($grammarCode); + $grammarCode = resolveMacros($grammarCode); + $grammarCode = resolveStackAccess($grammarCode); + + file_put_contents($tmpGrammarFile, $grammarCode); + + $additionalArgs = $optionDebug ? '-t -v' : ''; + + echo "Building $name parser.\n"; + $output = trim(shell_exec("$kmyacc $additionalArgs -l -m $skeletonFile -p $name $tmpGrammarFile 2>&1")); + echo "Output: \"$output\"\n"; + + $resultCode = file_get_contents($tmpResultFile); + $resultCode = removeTrailingWhitespace($resultCode); + + ensureDirExists($resultDir); + file_put_contents("$resultDir/$name.php", $resultCode); + unlink($tmpResultFile); + + echo "Building token definition.\n"; + $output = trim(shell_exec("$kmyacc -l -m $tokensTemplate $tmpGrammarFile 2>&1")); + assert($output === ''); + rename($tmpResultFile, $tokensResultsFile); + + if (!$optionKeepTmpGrammar) { + unlink($tmpGrammarFile); + } +} + +/////////////////////////////// +/// Preprocessing functions /// +/////////////////////////////// + +function resolveNodes($code) { + return preg_replace_callback( + '~\b(?[A-Z][a-zA-Z_\\\\]++)\s*' . PARAMS . '~', + function($matches) { + // recurse + $matches['params'] = resolveNodes($matches['params']); + + $params = magicSplit( + '(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,', + $matches['params'] + ); + + $paramCode = ''; + foreach ($params as $param) { + $paramCode .= $param . ', '; + } + + return 'new ' . $matches['name'] . '(' . $paramCode . 'attributes())'; + }, + $code + ); +} + +function resolveMacros($code) { + return preg_replace_callback( + '~\b(?)(?!array\()(?[a-z][A-Za-z]++)' . ARGS . '~', + function($matches) { + // recurse + $matches['args'] = resolveMacros($matches['args']); + + $name = $matches['name']; + $args = magicSplit( + '(?:' . PARAMS . '|' . ARGS . ')(*SKIP)(*FAIL)|,', + $matches['args'] + ); + + if ('attributes' == $name) { + assertArgs(0, $args, $name); + return '$this->startAttributeStack[#1] + $this->endAttributes'; + } + + if ('stackAttributes' == $name) { + assertArgs(1, $args, $name); + return '$this->startAttributeStack[' . $args[0] . ']' + . ' + $this->endAttributeStack[' . $args[0] . ']'; + } + + if ('init' == $name) { + return '$$ = array(' . implode(', ', $args) . ')'; + } + + if ('push' == $name) { + assertArgs(2, $args, $name); + + return $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0]; + } + + if ('pushNormalizing' == $name) { + assertArgs(2, $args, $name); + + return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); }' + . ' else { ' . $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0] . '; }'; + } + + if ('toArray' == $name) { + assertArgs(1, $args, $name); + + return 'is_array(' . $args[0] . ') ? ' . $args[0] . ' : array(' . $args[0] . ')'; + } + + if ('parseVar' == $name) { + assertArgs(1, $args, $name); + + return 'substr(' . $args[0] . ', 1)'; + } + + if ('parseEncapsed' == $name) { + assertArgs(3, $args, $name); + + return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {' + . ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, ' . $args[1] . ', ' . $args[2] . '); } }'; + } + + if ('makeNop' == $name) { + assertArgs(3, $args, $name); + + return '$startAttributes = ' . $args[1] . ';' + . ' if (isset($startAttributes[\'comments\']))' + . ' { ' . $args[0] . ' = new Stmt\Nop($startAttributes + ' . $args[2] . '); }' + . ' else { ' . $args[0] . ' = null; }'; + } + + if ('strKind' == $name) { + assertArgs(1, $args, $name); + + return '(' . $args[0] . '[0] === "\'" || (' . $args[0] . '[1] === "\'" && ' + . '(' . $args[0] . '[0] === \'b\' || ' . $args[0] . '[0] === \'B\')) ' + . '? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED)'; + } + + if ('prependLeadingComments' == $name) { + assertArgs(1, $args, $name); + + return '$attrs = $this->startAttributeStack[#1]; $stmts = ' . $args[0] . '; ' + . 'if (!empty($attrs[\'comments\'])) {' + . '$stmts[0]->setAttribute(\'comments\', ' + . 'array_merge($attrs[\'comments\'], $stmts[0]->getAttribute(\'comments\', []))); }'; + } + + return $matches[0]; + }, + $code + ); +} + +function assertArgs($num, $args, $name) { + if ($num != count($args)) { + die('Wrong argument count for ' . $name . '().'); + } +} + +function resolveStackAccess($code) { + $code = preg_replace('/\$\d+/', '$this->semStack[$0]', $code); + $code = preg_replace('/#(\d+)/', '$$1', $code); + return $code; +} + +function removeTrailingWhitespace($code) { + $lines = explode("\n", $code); + $lines = array_map('rtrim', $lines); + return implode("\n", $lines); +} + +function ensureDirExists($dir) { + if (!is_dir($dir)) { + mkdir($dir, 0777, true); + } +} + +////////////////////////////// +/// Regex helper functions /// +////////////////////////////// + +function regex($regex) { + return '~' . LIB . '(?:' . str_replace('~', '\~', $regex) . ')~'; +} + +function magicSplit($regex, $string) { + $pieces = preg_split(regex('(?:(?&string)|(?&comment)|(?&code))(*SKIP)(*FAIL)|' . $regex), $string); + + foreach ($pieces as &$piece) { + $piece = trim($piece); + } + + if ($pieces === ['']) { + return []; + } + + return $pieces; +} diff --git a/vendor/nikic/php-parser/grammar/tokens.template b/vendor/nikic/php-parser/grammar/tokens.template new file mode 100644 index 00000000..ba4e4901 --- /dev/null +++ b/vendor/nikic/php-parser/grammar/tokens.template @@ -0,0 +1,17 @@ +semValue +#semval($,%t) $this->semValue +#semval(%n) $this->stackPos-(%l-%n) +#semval(%n,%t) $this->stackPos-(%l-%n) + +namespace PhpParser\Parser; +#include; + +/* GENERATED file based on grammar/tokens.y */ +final class Tokens +{ +#tokenval + const %s = %n; +#endtokenval +} diff --git a/vendor/nikic/php-parser/grammar/tokens.y b/vendor/nikic/php-parser/grammar/tokens.y new file mode 100644 index 00000000..fe7beff0 --- /dev/null +++ b/vendor/nikic/php-parser/grammar/tokens.y @@ -0,0 +1,113 @@ +/* We currently rely on the token ID mapping to be the same between PHP 5 and PHP 7 - so the same lexer can be used for + * both. This is enforced by sharing this token file. */ + +%left T_INCLUDE T_INCLUDE_ONCE T_EVAL T_REQUIRE T_REQUIRE_ONCE +%left ',' +%left T_LOGICAL_OR +%left T_LOGICAL_XOR +%left T_LOGICAL_AND +%right T_PRINT +%right T_YIELD +%right T_DOUBLE_ARROW +%right T_YIELD_FROM +%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_POW_EQUAL T_COALESCE_EQUAL +%left '?' ':' +%right T_COALESCE +%left T_BOOLEAN_OR +%left T_BOOLEAN_AND +%left '|' +%left '^' +%left '&' +%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL T_SPACESHIP +%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL +%left T_SL T_SR +%left '+' '-' '.' +%left '*' '/' '%' +%right '!' +%nonassoc T_INSTANCEOF +%right '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@' +%right T_POW +%right '[' +%nonassoc T_NEW T_CLONE +%token T_EXIT +%token T_IF +%left T_ELSEIF +%left T_ELSE +%left T_ENDIF +%token T_LNUMBER +%token T_DNUMBER +%token T_STRING +%token T_STRING_VARNAME +%token T_VARIABLE +%token T_NUM_STRING +%token T_INLINE_HTML +%token T_CHARACTER +%token T_BAD_CHARACTER +%token T_ENCAPSED_AND_WHITESPACE +%token T_CONSTANT_ENCAPSED_STRING +%token T_ECHO +%token T_DO +%token T_WHILE +%token T_ENDWHILE +%token T_FOR +%token T_ENDFOR +%token T_FOREACH +%token T_ENDFOREACH +%token T_DECLARE +%token T_ENDDECLARE +%token T_AS +%token T_SWITCH +%token T_ENDSWITCH +%token T_CASE +%token T_DEFAULT +%token T_BREAK +%token T_CONTINUE +%token T_GOTO +%token T_FUNCTION +%token T_CONST +%token T_RETURN +%token T_TRY +%token T_CATCH +%token T_FINALLY +%token T_THROW +%token T_USE +%token T_INSTEADOF +%token T_GLOBAL +%right T_STATIC T_ABSTRACT T_FINAL T_PRIVATE T_PROTECTED T_PUBLIC +%token T_VAR +%token T_UNSET +%token T_ISSET +%token T_EMPTY +%token T_HALT_COMPILER +%token T_CLASS +%token T_TRAIT +%token T_INTERFACE +%token T_EXTENDS +%token T_IMPLEMENTS +%token T_OBJECT_OPERATOR +%token T_DOUBLE_ARROW +%token T_LIST +%token T_ARRAY +%token T_CALLABLE +%token T_CLASS_C +%token T_TRAIT_C +%token T_METHOD_C +%token T_FUNC_C +%token T_LINE +%token T_FILE +%token T_COMMENT +%token T_DOC_COMMENT +%token T_OPEN_TAG +%token T_OPEN_TAG_WITH_ECHO +%token T_CLOSE_TAG +%token T_WHITESPACE +%token T_START_HEREDOC +%token T_END_HEREDOC +%token T_DOLLAR_OPEN_CURLY_BRACES +%token T_CURLY_OPEN +%token T_PAAMAYIM_NEKUDOTAYIM +%token T_NAMESPACE +%token T_NS_C +%token T_DIR +%token T_NS_SEPARATOR +%token T_ELLIPSIS diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder.php b/vendor/nikic/php-parser/lib/PhpParser/Builder.php new file mode 100644 index 00000000..26d8921e --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder.php @@ -0,0 +1,13 @@ +name = $name; + } + + /** + * Extends a class. + * + * @param Name|string $class Name of class to extend + * + * @return $this The builder instance (for fluid interface) + */ + public function extend($class) { + $this->extends = BuilderHelpers::normalizeName($class); + + return $this; + } + + /** + * Implements one or more interfaces. + * + * @param Name|string ...$interfaces Names of interfaces to implement + * + * @return $this The builder instance (for fluid interface) + */ + public function implement(...$interfaces) { + foreach ($interfaces as $interface) { + $this->implements[] = BuilderHelpers::normalizeName($interface); + } + + return $this; + } + + /** + * Makes the class abstract. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeAbstract() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT); + + return $this; + } + + /** + * Makes the class final. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeFinal() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL); + + return $this; + } + + /** + * Adds a statement. + * + * @param Stmt|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $stmt = BuilderHelpers::normalizeNode($stmt); + + $targets = [ + Stmt\TraitUse::class => &$this->uses, + Stmt\ClassConst::class => &$this->constants, + Stmt\Property::class => &$this->properties, + Stmt\ClassMethod::class => &$this->methods, + ]; + + $class = \get_class($stmt); + if (!isset($targets[$class])) { + throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType())); + } + + $targets[$class][] = $stmt; + + return $this; + } + + /** + * Returns the built class node. + * + * @return Stmt\Class_ The built class node + */ + public function getNode() : PhpParser\Node { + return new Stmt\Class_($this->name, [ + 'flags' => $this->flags, + 'extends' => $this->extends, + 'implements' => $this->implements, + 'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods), + ], $this->attributes); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php new file mode 100644 index 00000000..83094992 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php @@ -0,0 +1,43 @@ +addStmt($stmt); + } + + return $this; + } + + /** + * Sets doc comment for the declaration. + * + * @param PhpParser\Comment\Doc|string $docComment Doc comment to set + * + * @return $this The builder instance (for fluid interface) + */ + public function setDocComment($docComment) { + $this->attributes['comments'] = [ + BuilderHelpers::normalizeDocComment($docComment) + ]; + + return $this; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php new file mode 100644 index 00000000..8e7db399 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php @@ -0,0 +1,74 @@ +returnByRef = true; + + return $this; + } + + /** + * Adds a parameter. + * + * @param Node\Param|Param $param The parameter to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addParam($param) { + $param = BuilderHelpers::normalizeNode($param); + + if (!$param instanceof Node\Param) { + throw new \LogicException(sprintf('Expected parameter node, got "%s"', $param->getType())); + } + + $this->params[] = $param; + + return $this; + } + + /** + * Adds multiple parameters. + * + * @param array $params The parameters to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addParams(array $params) { + foreach ($params as $param) { + $this->addParam($param); + } + + return $this; + } + + /** + * Sets the return type for PHP 7. + * + * @param string|Node\Name|Node\NullableType $type One of array, callable, string, int, float, + * bool, iterable, or a class/interface name. + * + * @return $this The builder instance (for fluid interface) + */ + public function setReturnType($type) { + $this->returnType = BuilderHelpers::normalizeType($type); + + return $this; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php new file mode 100644 index 00000000..56eda2a8 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php @@ -0,0 +1,50 @@ +name = $name; + } + + /** + * Adds a statement. + * + * @param Node|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $this->stmts[] = BuilderHelpers::normalizeStmt($stmt); + + return $this; + } + + /** + * Returns the built function node. + * + * @return Stmt\Function_ The built function node + */ + public function getNode() : Node { + return new Stmt\Function_($this->name, [ + 'byRef' => $this->returnByRef, + 'params' => $this->params, + 'returnType' => $this->returnType, + 'stmts' => $this->stmts, + ], $this->attributes); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php new file mode 100644 index 00000000..87e5b93e --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php @@ -0,0 +1,75 @@ +name = $name; + } + + /** + * Extends one or more interfaces. + * + * @param Name|string ...$interfaces Names of interfaces to extend + * + * @return $this The builder instance (for fluid interface) + */ + public function extend(...$interfaces) { + foreach ($interfaces as $interface) { + $this->extends[] = BuilderHelpers::normalizeName($interface); + } + + return $this; + } + + /** + * Adds a statement. + * + * @param Stmt|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $stmt = BuilderHelpers::normalizeNode($stmt); + + if ($stmt instanceof Stmt\ClassConst) { + $this->constants[] = $stmt; + } elseif ($stmt instanceof Stmt\ClassMethod) { + // we erase all statements in the body of an interface method + $stmt->stmts = null; + $this->methods[] = $stmt; + } else { + throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType())); + } + + return $this; + } + + /** + * Returns the built interface node. + * + * @return Stmt\Interface_ The built interface node + */ + public function getNode() : PhpParser\Node { + return new Stmt\Interface_($this->name, [ + 'extends' => $this->extends, + 'stmts' => array_merge($this->constants, $this->methods), + ], $this->attributes); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php new file mode 100644 index 00000000..a3e86765 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php @@ -0,0 +1,129 @@ +name = $name; + } + + /** + * Makes the method public. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePublic() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC); + + return $this; + } + + /** + * Makes the method protected. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeProtected() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED); + + return $this; + } + + /** + * Makes the method private. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePrivate() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE); + + return $this; + } + + /** + * Makes the method static. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeStatic() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC); + + return $this; + } + + /** + * Makes the method abstract. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeAbstract() { + if (!empty($this->stmts)) { + throw new \LogicException('Cannot make method with statements abstract'); + } + + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT); + $this->stmts = null; // abstract methods don't have statements + + return $this; + } + + /** + * Makes the method final. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeFinal() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL); + + return $this; + } + + /** + * Adds a statement. + * + * @param Node|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + if (null === $this->stmts) { + throw new \LogicException('Cannot add statements to an abstract method'); + } + + $this->stmts[] = BuilderHelpers::normalizeStmt($stmt); + + return $this; + } + + /** + * Returns the built method node. + * + * @return Stmt\ClassMethod The built method node + */ + public function getNode() : Node { + return new Stmt\ClassMethod($this->name, [ + 'flags' => $this->flags, + 'byRef' => $this->returnByRef, + 'params' => $this->params, + 'returnType' => $this->returnType, + 'stmts' => $this->stmts, + ], $this->attributes); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php new file mode 100644 index 00000000..b9ccab3e --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php @@ -0,0 +1,45 @@ +name = null !== $name ? BuilderHelpers::normalizeName($name) : null; + } + + /** + * Adds a statement. + * + * @param Node|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $this->stmts[] = BuilderHelpers::normalizeStmt($stmt); + + return $this; + } + + /** + * Returns the built node. + * + * @return Node The built node + */ + public function getNode() : Node { + return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php new file mode 100644 index 00000000..184813a6 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php @@ -0,0 +1,106 @@ +name = $name; + } + + /** + * Sets default value for the parameter. + * + * @param mixed $value Default value to use + * + * @return $this The builder instance (for fluid interface) + */ + public function setDefault($value) { + $this->default = BuilderHelpers::normalizeValue($value); + + return $this; + } + + /** + * Sets type for the parameter. + * + * @param string|Node\Name|Node\NullableType $type Parameter type + * + * @return $this The builder instance (for fluid interface) + */ + public function setType($type) { + $this->type = BuilderHelpers::normalizeType($type); + if ($this->type == 'void') { + throw new \LogicException('Parameter type cannot be void'); + } + + return $this; + } + + /** + * Sets type for the parameter. + * + * @param string|Node\Name|Node\NullableType $type Parameter type + * + * @return $this The builder instance (for fluid interface) + * + * @deprecated Use setType() instead + */ + public function setTypeHint($type) { + return $this->setType($type); + } + + /** + * Make the parameter accept the value by reference. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeByRef() { + $this->byRef = true; + + return $this; + } + + /** + * Make the parameter variadic + * + * @return $this The builder instance (for fluid interface) + */ + public function makeVariadic() { + $this->variadic = true; + + return $this; + } + + /** + * Returns the built parameter node. + * + * @return Node\Param The built parameter node + */ + public function getNode() : Node { + return new Node\Param( + new Node\Expr\Variable($this->name), + $this->default, $this->type, $this->byRef, $this->variadic + ); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php new file mode 100644 index 00000000..1f3bdb27 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php @@ -0,0 +1,132 @@ +name = $name; + } + + /** + * Makes the property public. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePublic() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC); + + return $this; + } + + /** + * Makes the property protected. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeProtected() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED); + + return $this; + } + + /** + * Makes the property private. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePrivate() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE); + + return $this; + } + + /** + * Makes the property static. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeStatic() { + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC); + + return $this; + } + + /** + * Sets default value for the property. + * + * @param mixed $value Default value to use + * + * @return $this The builder instance (for fluid interface) + */ + public function setDefault($value) { + $this->default = BuilderHelpers::normalizeValue($value); + + return $this; + } + + /** + * Sets doc comment for the property. + * + * @param PhpParser\Comment\Doc|string $docComment Doc comment to set + * + * @return $this The builder instance (for fluid interface) + */ + public function setDocComment($docComment) { + $this->attributes = [ + 'comments' => [BuilderHelpers::normalizeDocComment($docComment)] + ]; + + return $this; + } + + /** + * Sets the property type for PHP 7.4+. + * + * @param string|Name|NullableType|Identifier $type + * + * @return $this + */ + public function setType($type) { + $this->type = BuilderHelpers::normalizeType($type); + + return $this; + } + + /** + * Returns the built class node. + * + * @return Stmt\Property The built property node + */ + public function getNode() : PhpParser\Node { + return new Stmt\Property( + $this->flags !== 0 ? $this->flags : Stmt\Class_::MODIFIER_PUBLIC, + [ + new Stmt\PropertyProperty($this->name, $this->default) + ], + $this->attributes, + $this->type + ); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php new file mode 100644 index 00000000..311e8cd7 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php @@ -0,0 +1,64 @@ +and($trait); + } + } + + /** + * Adds used trait. + * + * @param Node\Name|string $trait Trait name + * + * @return $this The builder instance (for fluid interface) + */ + public function and($trait) { + $this->traits[] = BuilderHelpers::normalizeName($trait); + return $this; + } + + /** + * Adds trait adaptation. + * + * @param Stmt\TraitUseAdaptation|Builder\TraitUseAdaptation $adaptation Trait adaptation + * + * @return $this The builder instance (for fluid interface) + */ + public function with($adaptation) { + $adaptation = BuilderHelpers::normalizeNode($adaptation); + + if (!$adaptation instanceof Stmt\TraitUseAdaptation) { + throw new \LogicException('Adaptation must have type TraitUseAdaptation'); + } + + $this->adaptations[] = $adaptation; + return $this; + } + + /** + * Returns the built node. + * + * @return Node The built node + */ + public function getNode() : Node { + return new Stmt\TraitUse($this->traits, $this->adaptations); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php new file mode 100644 index 00000000..eb6c0b62 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php @@ -0,0 +1,148 @@ +type = self::TYPE_UNDEFINED; + + $this->trait = is_null($trait)? null: BuilderHelpers::normalizeName($trait); + $this->method = BuilderHelpers::normalizeIdentifier($method); + } + + /** + * Sets alias of method. + * + * @param Node\Identifier|string $alias Alias for adaptated method + * + * @return $this The builder instance (for fluid interface) + */ + public function as($alias) { + if ($this->type === self::TYPE_UNDEFINED) { + $this->type = self::TYPE_ALIAS; + } + + if ($this->type !== self::TYPE_ALIAS) { + throw new \LogicException('Cannot set alias for not alias adaptation buider'); + } + + $this->alias = $alias; + return $this; + } + + /** + * Sets adaptated method public. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePublic() { + $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); + return $this; + } + + /** + * Sets adaptated method protected. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeProtected() { + $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); + return $this; + } + + /** + * Sets adaptated method private. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePrivate() { + $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); + return $this; + } + + /** + * Adds overwritten traits. + * + * @param Node\Name|string ...$traits Traits for overwrite + * + * @return $this The builder instance (for fluid interface) + */ + public function insteadof(...$traits) { + if ($this->type === self::TYPE_UNDEFINED) { + if (is_null($this->trait)) { + throw new \LogicException('Precedence adaptation must have trait'); + } + + $this->type = self::TYPE_PRECEDENCE; + } + + if ($this->type !== self::TYPE_PRECEDENCE) { + throw new \LogicException('Cannot add overwritten traits for not precedence adaptation buider'); + } + + foreach ($traits as $trait) { + $this->insteadof[] = BuilderHelpers::normalizeName($trait); + } + + return $this; + } + + protected function setModifier(int $modifier) { + if ($this->type === self::TYPE_UNDEFINED) { + $this->type = self::TYPE_ALIAS; + } + + if ($this->type !== self::TYPE_ALIAS) { + throw new \LogicException('Cannot set access modifier for not alias adaptation buider'); + } + + if (is_null($this->modifier)) { + $this->modifier = $modifier; + } else { + throw new \LogicException('Multiple access type modifiers are not allowed'); + } + } + + /** + * Returns the built node. + * + * @return Node The built node + */ + public function getNode() : Node { + switch ($this->type) { + case self::TYPE_ALIAS: + return new Stmt\TraitUseAdaptation\Alias($this->trait, $this->method, $this->modifier, $this->alias); + case self::TYPE_PRECEDENCE: + return new Stmt\TraitUseAdaptation\Precedence($this->trait, $this->method, $this->insteadof); + default: + throw new \LogicException('Type of adaptation is not defined'); + } + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php new file mode 100644 index 00000000..a836d40c --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php @@ -0,0 +1,60 @@ +name = $name; + } + + /** + * Adds a statement. + * + * @param Stmt|PhpParser\Builder $stmt The statement to add + * + * @return $this The builder instance (for fluid interface) + */ + public function addStmt($stmt) { + $stmt = BuilderHelpers::normalizeNode($stmt); + + if ($stmt instanceof Stmt\Property) { + $this->properties[] = $stmt; + } elseif ($stmt instanceof Stmt\ClassMethod) { + $this->methods[] = $stmt; + } elseif ($stmt instanceof Stmt\TraitUse) { + $this->uses[] = $stmt; + } else { + throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType())); + } + + return $this; + } + + /** + * Returns the built trait node. + * + * @return Stmt\Trait_ The built interface node + */ + public function getNode() : PhpParser\Node { + return new Stmt\Trait_( + $this->name, [ + 'stmts' => array_merge($this->uses, $this->properties, $this->methods) + ], $this->attributes + ); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php b/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php new file mode 100644 index 00000000..2026a172 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php @@ -0,0 +1,49 @@ +name = BuilderHelpers::normalizeName($name); + $this->type = $type; + } + + /** + * Sets alias for used name. + * + * @param string $alias Alias to use (last component of full name by default) + * + * @return $this The builder instance (for fluid interface) + */ + public function as(string $alias) { + $this->alias = $alias; + return $this; + } + + /** + * Returns the built node. + * + * @return Node The built node + */ + public function getNode() : Node { + return new Stmt\Use_([ + new Stmt\UseUse($this->name, $this->alias) + ], $this->type); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php b/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php new file mode 100644 index 00000000..18bd1cd5 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php @@ -0,0 +1,348 @@ +args($args) + ); + } + + /** + * Creates a method call node. + * + * @param Expr $var Variable the method is called on + * @param string|Identifier|Expr $name Method name + * @param array $args Method arguments + * + * @return Expr\MethodCall + */ + public function methodCall(Expr $var, $name, array $args = []) : Expr\MethodCall { + return new Expr\MethodCall( + $var, + BuilderHelpers::normalizeIdentifierOrExpr($name), + $this->args($args) + ); + } + + /** + * Creates a static method call node. + * + * @param string|Name|Expr $class Class name + * @param string|Identifier|Expr $name Method name + * @param array $args Method arguments + * + * @return Expr\StaticCall + */ + public function staticCall($class, $name, array $args = []) : Expr\StaticCall { + return new Expr\StaticCall( + BuilderHelpers::normalizeNameOrExpr($class), + BuilderHelpers::normalizeIdentifierOrExpr($name), + $this->args($args) + ); + } + + /** + * Creates an object creation node. + * + * @param string|Name|Expr $class Class name + * @param array $args Constructor arguments + * + * @return Expr\New_ + */ + public function new($class, array $args = []) : Expr\New_ { + return new Expr\New_( + BuilderHelpers::normalizeNameOrExpr($class), + $this->args($args) + ); + } + + /** + * Creates a constant fetch node. + * + * @param string|Name $name Constant name + * + * @return Expr\ConstFetch + */ + public function constFetch($name) : Expr\ConstFetch { + return new Expr\ConstFetch(BuilderHelpers::normalizeName($name)); + } + + /** + * Creates a property fetch node. + * + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Property name + * + * @return Expr\PropertyFetch + */ + public function propertyFetch(Expr $var, $name) : Expr\PropertyFetch { + return new Expr\PropertyFetch($var, BuilderHelpers::normalizeIdentifierOrExpr($name)); + } + + /** + * Creates a class constant fetch node. + * + * @param string|Name|Expr $class Class name + * @param string|Identifier $name Constant name + * + * @return Expr\ClassConstFetch + */ + public function classConstFetch($class, $name): Expr\ClassConstFetch { + return new Expr\ClassConstFetch( + BuilderHelpers::normalizeNameOrExpr($class), + BuilderHelpers::normalizeIdentifier($name) + ); + } + + /** + * Creates nested Concat nodes from a list of expressions. + * + * @param Expr|string ...$exprs Expressions or literal strings + * + * @return Concat + */ + public function concat(...$exprs) : Concat { + $numExprs = count($exprs); + if ($numExprs < 2) { + throw new \LogicException('Expected at least two expressions'); + } + + $lastConcat = $this->normalizeStringExpr($exprs[0]); + for ($i = 1; $i < $numExprs; $i++) { + $lastConcat = new Concat($lastConcat, $this->normalizeStringExpr($exprs[$i])); + } + return $lastConcat; + } + + /** + * @param string|Expr $expr + * @return Expr + */ + private function normalizeStringExpr($expr) : Expr { + if ($expr instanceof Expr) { + return $expr; + } + + if (\is_string($expr)) { + return new String_($expr); + } + + throw new \LogicException('Expected string or Expr'); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php b/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php new file mode 100644 index 00000000..790e8877 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php @@ -0,0 +1,277 @@ +getNode(); + } elseif ($node instanceof Node) { + return $node; + } + + throw new \LogicException('Expected node or builder object'); + } + + /** + * Normalizes a node to a statement. + * + * Expressions are wrapped in a Stmt\Expression node. + * + * @param Node|Builder $node The node to normalize + * + * @return Stmt The normalized statement node + */ + public static function normalizeStmt($node) : Stmt { + $node = self::normalizeNode($node); + if ($node instanceof Stmt) { + return $node; + } + + if ($node instanceof Expr) { + return new Stmt\Expression($node); + } + + throw new \LogicException('Expected statement or expression node'); + } + + /** + * Normalizes strings to Identifier. + * + * @param string|Identifier $name The identifier to normalize + * + * @return Identifier The normalized identifier + */ + public static function normalizeIdentifier($name) : Identifier { + if ($name instanceof Identifier) { + return $name; + } + + if (\is_string($name)) { + return new Identifier($name); + } + + throw new \LogicException('Expected string or instance of Node\Identifier'); + } + + /** + * Normalizes strings to Identifier, also allowing expressions. + * + * @param string|Identifier|Expr $name The identifier to normalize + * + * @return Identifier|Expr The normalized identifier or expression + */ + public static function normalizeIdentifierOrExpr($name) { + if ($name instanceof Identifier || $name instanceof Expr) { + return $name; + } + + if (\is_string($name)) { + return new Identifier($name); + } + + throw new \LogicException('Expected string or instance of Node\Identifier or Node\Expr'); + } + + /** + * Normalizes a name: Converts string names to Name nodes. + * + * @param Name|string $name The name to normalize + * + * @return Name The normalized name + */ + public static function normalizeName($name) : Name { + return self::normalizeNameCommon($name, false); + } + + /** + * Normalizes a name: Converts string names to Name nodes, while also allowing expressions. + * + * @param Expr|Name|string $name The name to normalize + * + * @return Name|Expr The normalized name or expression + */ + public static function normalizeNameOrExpr($name) { + return self::normalizeNameCommon($name, true); + } + + /** + * Normalizes a name: Converts string names to Name nodes, optionally allowing expressions. + * + * @param Expr|Name|string $name The name to normalize + * @param bool $allowExpr Whether to also allow expressions + * + * @return Name|Expr The normalized name, or expression (if allowed) + */ + private static function normalizeNameCommon($name, bool $allowExpr) { + if ($name instanceof Name) { + return $name; + } elseif (is_string($name)) { + if (!$name) { + throw new \LogicException('Name cannot be empty'); + } + + if ($name[0] === '\\') { + return new Name\FullyQualified(substr($name, 1)); + } elseif (0 === strpos($name, 'namespace\\')) { + return new Name\Relative(substr($name, strlen('namespace\\'))); + } else { + return new Name($name); + } + } + + if ($allowExpr) { + if ($name instanceof Expr) { + return $name; + } + throw new \LogicException( + 'Name must be a string or an instance of Node\Name or Node\Expr' + ); + } else { + throw new \LogicException('Name must be a string or an instance of Node\Name'); + } + } + + /** + * Normalizes a type: Converts plain-text type names into proper AST representation. + * + * In particular, builtin types become Identifiers, custom types become Names and nullables + * are wrapped in NullableType nodes. + * + * @param string|Name|Identifier|NullableType $type The type to normalize + * + * @return Name|Identifier|NullableType The normalized type + */ + public static function normalizeType($type) { + if (!is_string($type)) { + if (!$type instanceof Name && !$type instanceof Identifier + && !$type instanceof NullableType) { + throw new \LogicException( + 'Type must be a string, or an instance of Name, Identifier or NullableType'); + } + return $type; + } + + $nullable = false; + if (strlen($type) > 0 && $type[0] === '?') { + $nullable = true; + $type = substr($type, 1); + } + + $builtinTypes = [ + 'array', 'callable', 'string', 'int', 'float', 'bool', 'iterable', 'void', 'object' + ]; + + $lowerType = strtolower($type); + if (in_array($lowerType, $builtinTypes)) { + $type = new Identifier($lowerType); + } else { + $type = self::normalizeName($type); + } + + if ($nullable && (string) $type === 'void') { + throw new \LogicException('void type cannot be nullable'); + } + + return $nullable ? new Node\NullableType($type) : $type; + } + + /** + * Normalizes a value: Converts nulls, booleans, integers, + * floats, strings and arrays into their respective nodes + * + * @param Node\Expr|bool|null|int|float|string|array $value The value to normalize + * + * @return Expr The normalized value + */ + public static function normalizeValue($value) : Expr { + if ($value instanceof Node\Expr) { + return $value; + } elseif (is_null($value)) { + return new Expr\ConstFetch( + new Name('null') + ); + } elseif (is_bool($value)) { + return new Expr\ConstFetch( + new Name($value ? 'true' : 'false') + ); + } elseif (is_int($value)) { + return new Scalar\LNumber($value); + } elseif (is_float($value)) { + return new Scalar\DNumber($value); + } elseif (is_string($value)) { + return new Scalar\String_($value); + } elseif (is_array($value)) { + $items = []; + $lastKey = -1; + foreach ($value as $itemKey => $itemValue) { + // for consecutive, numeric keys don't generate keys + if (null !== $lastKey && ++$lastKey === $itemKey) { + $items[] = new Expr\ArrayItem( + self::normalizeValue($itemValue) + ); + } else { + $lastKey = null; + $items[] = new Expr\ArrayItem( + self::normalizeValue($itemValue), + self::normalizeValue($itemKey) + ); + } + } + + return new Expr\Array_($items); + } else { + throw new \LogicException('Invalid value'); + } + } + + /** + * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc. + * + * @param Comment\Doc|string $docComment The doc comment to normalize + * + * @return Comment\Doc The normalized doc comment + */ + public static function normalizeDocComment($docComment) : Comment\Doc { + if ($docComment instanceof Comment\Doc) { + return $docComment; + } elseif (is_string($docComment)) { + return new Comment\Doc($docComment); + } else { + throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc'); + } + } + + /** + * Adds a modifier and returns new modifier bitmask. + * + * @param int $modifiers Existing modifiers + * @param int $modifier Modifier to set + * + * @return int New modifiers + */ + public static function addModifier(int $modifiers, int $modifier) : int { + Stmt\Class_::verifyModifier($modifiers, $modifier); + return $modifiers | $modifier; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Comment.php b/vendor/nikic/php-parser/lib/PhpParser/Comment.php new file mode 100644 index 00000000..5da84209 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Comment.php @@ -0,0 +1,167 @@ +text = $text; + $this->line = $startLine; + $this->filePos = $startFilePos; + $this->tokenPos = $startTokenPos; + } + + /** + * Gets the comment text. + * + * @return string The comment text (including comment delimiters like /*) + */ + public function getText() : string { + return $this->text; + } + + /** + * Gets the line number the comment started on. + * + * @return int Line number + */ + public function getLine() : int { + return $this->line; + } + + /** + * Gets the file offset the comment started on. + * + * @return int File offset + */ + public function getFilePos() : int { + return $this->filePos; + } + + /** + * Gets the token offset the comment started on. + * + * @return int Token offset + */ + public function getTokenPos() : int { + return $this->tokenPos; + } + + /** + * Gets the comment text. + * + * @return string The comment text (including comment delimiters like /*) + */ + public function __toString() : string { + return $this->text; + } + + /** + * Gets the reformatted comment text. + * + * "Reformatted" here means that we try to clean up the whitespace at the + * starts of the lines. This is necessary because we receive the comments + * without trailing whitespace on the first line, but with trailing whitespace + * on all subsequent lines. + * + * @return mixed|string + */ + public function getReformattedText() { + $text = trim($this->text); + $newlinePos = strpos($text, "\n"); + if (false === $newlinePos) { + // Single line comments don't need further processing + return $text; + } elseif (preg_match('((*BSR_ANYCRLF)(*ANYCRLF)^.*(?:\R\s+\*.*)+$)', $text)) { + // Multi line comment of the type + // + // /* + // * Some text. + // * Some more text. + // */ + // + // is handled by replacing the whitespace sequences before the * by a single space + return preg_replace('(^\s+\*)m', ' *', $this->text); + } elseif (preg_match('(^/\*\*?\s*[\r\n])', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) { + // Multi line comment of the type + // + // /* + // Some text. + // Some more text. + // */ + // + // is handled by removing the whitespace sequence on the line before the closing + // */ on all lines. So if the last line is " */", then " " is removed at the + // start of all lines. + return preg_replace('(^' . preg_quote($matches[1]) . ')m', '', $text); + } elseif (preg_match('(^/\*\*?\s*(?!\s))', $text, $matches)) { + // Multi line comment of the type + // + // /* Some text. + // Some more text. + // Indented text. + // Even more text. */ + // + // is handled by removing the difference between the shortest whitespace prefix on all + // lines and the length of the "/* " opening sequence. + $prefixLen = $this->getShortestWhitespacePrefixLen(substr($text, $newlinePos + 1)); + $removeLen = $prefixLen - strlen($matches[0]); + return preg_replace('(^\s{' . $removeLen . '})m', '', $text); + } + + // No idea how to format this comment, so simply return as is + return $text; + } + + /** + * Get length of shortest whitespace prefix (at the start of a line). + * + * If there is a line with no prefix whitespace, 0 is a valid return value. + * + * @param string $str String to check + * @return int Length in characters. Tabs count as single characters. + */ + private function getShortestWhitespacePrefixLen(string $str) : int { + $lines = explode("\n", $str); + $shortestPrefixLen = \INF; + foreach ($lines as $line) { + preg_match('(^\s*)', $line, $matches); + $prefixLen = strlen($matches[0]); + if ($prefixLen < $shortestPrefixLen) { + $shortestPrefixLen = $prefixLen; + } + } + return $shortestPrefixLen; + } + + /** + * @return array + * @psalm-return array{nodeType:string, text:mixed, line:mixed, filePos:mixed} + */ + public function jsonSerialize() : array { + // Technically not a node, but we make it look like one anyway + $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment'; + return [ + 'nodeType' => $type, + 'text' => $this->text, + 'line' => $this->line, + 'filePos' => $this->filePos, + 'tokenPos' => $this->tokenPos, + ]; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php b/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php new file mode 100644 index 00000000..a9db6128 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php @@ -0,0 +1,7 @@ +fallbackEvaluator = $fallbackEvaluator ?? function(Expr $expr) { + throw new ConstExprEvaluationException( + "Expression of type {$expr->getType()} cannot be evaluated" + ); + }; + } + + /** + * Silently evaluates a constant expression into a PHP value. + * + * Thrown Errors, warnings or notices will be converted into a ConstExprEvaluationException. + * The original source of the exception is available through getPrevious(). + * + * If some part of the expression cannot be evaluated, the fallback evaluator passed to the + * constructor will be invoked. By default, if no fallback is provided, an exception of type + * ConstExprEvaluationException is thrown. + * + * See class doc comment for caveats and limitations. + * + * @param Expr $expr Constant expression to evaluate + * @return mixed Result of evaluation + * + * @throws ConstExprEvaluationException if the expression cannot be evaluated or an error occurred + */ + public function evaluateSilently(Expr $expr) { + set_error_handler(function($num, $str, $file, $line) { + throw new \ErrorException($str, 0, $num, $file, $line); + }); + + try { + return $this->evaluate($expr); + } catch (\Throwable $e) { + if (!$e instanceof ConstExprEvaluationException) { + $e = new ConstExprEvaluationException( + "An error occurred during constant expression evaluation", 0, $e); + } + throw $e; + } finally { + restore_error_handler(); + } + } + + /** + * Directly evaluates a constant expression into a PHP value. + * + * May generate Error exceptions, warnings or notices. Use evaluateSilently() to convert these + * into a ConstExprEvaluationException. + * + * If some part of the expression cannot be evaluated, the fallback evaluator passed to the + * constructor will be invoked. By default, if no fallback is provided, an exception of type + * ConstExprEvaluationException is thrown. + * + * See class doc comment for caveats and limitations. + * + * @param Expr $expr Constant expression to evaluate + * @return mixed Result of evaluation + * + * @throws ConstExprEvaluationException if the expression cannot be evaluated + */ + public function evaluateDirectly(Expr $expr) { + return $this->evaluate($expr); + } + + private function evaluate(Expr $expr) { + if ($expr instanceof Scalar\LNumber + || $expr instanceof Scalar\DNumber + || $expr instanceof Scalar\String_ + ) { + return $expr->value; + } + + if ($expr instanceof Expr\Array_) { + return $this->evaluateArray($expr); + } + + // Unary operators + if ($expr instanceof Expr\UnaryPlus) { + return +$this->evaluate($expr->expr); + } + if ($expr instanceof Expr\UnaryMinus) { + return -$this->evaluate($expr->expr); + } + if ($expr instanceof Expr\BooleanNot) { + return !$this->evaluate($expr->expr); + } + if ($expr instanceof Expr\BitwiseNot) { + return ~$this->evaluate($expr->expr); + } + + if ($expr instanceof Expr\BinaryOp) { + return $this->evaluateBinaryOp($expr); + } + + if ($expr instanceof Expr\Ternary) { + return $this->evaluateTernary($expr); + } + + if ($expr instanceof Expr\ArrayDimFetch && null !== $expr->dim) { + return $this->evaluate($expr->var)[$this->evaluate($expr->dim)]; + } + + if ($expr instanceof Expr\ConstFetch) { + return $this->evaluateConstFetch($expr); + } + + return ($this->fallbackEvaluator)($expr); + } + + private function evaluateArray(Expr\Array_ $expr) { + $array = []; + foreach ($expr->items as $item) { + if (null !== $item->key) { + $array[$this->evaluate($item->key)] = $this->evaluate($item->value); + } else { + $array[] = $this->evaluate($item->value); + } + } + return $array; + } + + private function evaluateTernary(Expr\Ternary $expr) { + if (null === $expr->if) { + return $this->evaluate($expr->cond) ?: $this->evaluate($expr->else); + } + + return $this->evaluate($expr->cond) + ? $this->evaluate($expr->if) + : $this->evaluate($expr->else); + } + + private function evaluateBinaryOp(Expr\BinaryOp $expr) { + if ($expr instanceof Expr\BinaryOp\Coalesce + && $expr->left instanceof Expr\ArrayDimFetch + ) { + // This needs to be special cased to respect BP_VAR_IS fetch semantics + return $this->evaluate($expr->left->var)[$this->evaluate($expr->left->dim)] + ?? $this->evaluate($expr->right); + } + + // The evaluate() calls are repeated in each branch, because some of the operators are + // short-circuiting and evaluating the RHS in advance may be illegal in that case + $l = $expr->left; + $r = $expr->right; + switch ($expr->getOperatorSigil()) { + case '&': return $this->evaluate($l) & $this->evaluate($r); + case '|': return $this->evaluate($l) | $this->evaluate($r); + case '^': return $this->evaluate($l) ^ $this->evaluate($r); + case '&&': return $this->evaluate($l) && $this->evaluate($r); + case '||': return $this->evaluate($l) || $this->evaluate($r); + case '??': return $this->evaluate($l) ?? $this->evaluate($r); + case '.': return $this->evaluate($l) . $this->evaluate($r); + case '/': return $this->evaluate($l) / $this->evaluate($r); + case '==': return $this->evaluate($l) == $this->evaluate($r); + case '>': return $this->evaluate($l) > $this->evaluate($r); + case '>=': return $this->evaluate($l) >= $this->evaluate($r); + case '===': return $this->evaluate($l) === $this->evaluate($r); + case 'and': return $this->evaluate($l) and $this->evaluate($r); + case 'or': return $this->evaluate($l) or $this->evaluate($r); + case 'xor': return $this->evaluate($l) xor $this->evaluate($r); + case '-': return $this->evaluate($l) - $this->evaluate($r); + case '%': return $this->evaluate($l) % $this->evaluate($r); + case '*': return $this->evaluate($l) * $this->evaluate($r); + case '!=': return $this->evaluate($l) != $this->evaluate($r); + case '!==': return $this->evaluate($l) !== $this->evaluate($r); + case '+': return $this->evaluate($l) + $this->evaluate($r); + case '**': return $this->evaluate($l) ** $this->evaluate($r); + case '<<': return $this->evaluate($l) << $this->evaluate($r); + case '>>': return $this->evaluate($l) >> $this->evaluate($r); + case '<': return $this->evaluate($l) < $this->evaluate($r); + case '<=': return $this->evaluate($l) <= $this->evaluate($r); + case '<=>': return $this->evaluate($l) <=> $this->evaluate($r); + } + + throw new \Exception('Should not happen'); + } + + private function evaluateConstFetch(Expr\ConstFetch $expr) { + $name = $expr->name->toLowerString(); + switch ($name) { + case 'null': return null; + case 'false': return false; + case 'true': return true; + } + + return ($this->fallbackEvaluator)($expr); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Error.php b/vendor/nikic/php-parser/lib/PhpParser/Error.php new file mode 100644 index 00000000..d1fb959d --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Error.php @@ -0,0 +1,180 @@ +rawMessage = $message; + if (is_array($attributes)) { + $this->attributes = $attributes; + } else { + $this->attributes = ['startLine' => $attributes]; + } + $this->updateMessage(); + } + + /** + * Gets the error message + * + * @return string Error message + */ + public function getRawMessage() : string { + return $this->rawMessage; + } + + /** + * Gets the line the error starts in. + * + * @return int Error start line + */ + public function getStartLine() : int { + return $this->attributes['startLine'] ?? -1; + } + + /** + * Gets the line the error ends in. + * + * @return int Error end line + */ + public function getEndLine() : int { + return $this->attributes['endLine'] ?? -1; + } + + /** + * Gets the attributes of the node/token the error occurred at. + * + * @return array + */ + public function getAttributes() : array { + return $this->attributes; + } + + /** + * Sets the attributes of the node/token the error occurred at. + * + * @param array $attributes + */ + public function setAttributes(array $attributes) { + $this->attributes = $attributes; + $this->updateMessage(); + } + + /** + * Sets the line of the PHP file the error occurred in. + * + * @param string $message Error message + */ + public function setRawMessage(string $message) { + $this->rawMessage = $message; + $this->updateMessage(); + } + + /** + * Sets the line the error starts in. + * + * @param int $line Error start line + */ + public function setStartLine(int $line) { + $this->attributes['startLine'] = $line; + $this->updateMessage(); + } + + /** + * Returns whether the error has start and end column information. + * + * For column information enable the startFilePos and endFilePos in the lexer options. + * + * @return bool + */ + public function hasColumnInfo() : bool { + return isset($this->attributes['startFilePos'], $this->attributes['endFilePos']); + } + + /** + * Gets the start column (1-based) into the line where the error started. + * + * @param string $code Source code of the file + * @return int + */ + public function getStartColumn(string $code) : int { + if (!$this->hasColumnInfo()) { + throw new \RuntimeException('Error does not have column information'); + } + + return $this->toColumn($code, $this->attributes['startFilePos']); + } + + /** + * Gets the end column (1-based) into the line where the error ended. + * + * @param string $code Source code of the file + * @return int + */ + public function getEndColumn(string $code) : int { + if (!$this->hasColumnInfo()) { + throw new \RuntimeException('Error does not have column information'); + } + + return $this->toColumn($code, $this->attributes['endFilePos']); + } + + /** + * Formats message including line and column information. + * + * @param string $code Source code associated with the error, for calculation of the columns + * + * @return string Formatted message + */ + public function getMessageWithColumnInfo(string $code) : string { + return sprintf( + '%s from %d:%d to %d:%d', $this->getRawMessage(), + $this->getStartLine(), $this->getStartColumn($code), + $this->getEndLine(), $this->getEndColumn($code) + ); + } + + /** + * Converts a file offset into a column. + * + * @param string $code Source code that $pos indexes into + * @param int $pos 0-based position in $code + * + * @return int 1-based column (relative to start of line) + */ + private function toColumn(string $code, int $pos) : int { + if ($pos > strlen($code)) { + throw new \RuntimeException('Invalid position information'); + } + + $lineStartPos = strrpos($code, "\n", $pos - strlen($code)); + if (false === $lineStartPos) { + $lineStartPos = -1; + } + + return $pos - $lineStartPos; + } + + /** + * Updates the exception message after a change to rawMessage or rawLine. + */ + protected function updateMessage() { + $this->message = $this->rawMessage; + + if (-1 === $this->getStartLine()) { + $this->message .= ' on unknown line'; + } else { + $this->message .= ' on line ' . $this->getStartLine(); + } + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php b/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php new file mode 100644 index 00000000..d620e745 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php @@ -0,0 +1,13 @@ +errors[] = $error; + } + + /** + * Get collected errors. + * + * @return Error[] + */ + public function getErrors() : array { + return $this->errors; + } + + /** + * Check whether there are any errors. + * + * @return bool + */ + public function hasErrors() : bool { + return !empty($this->errors); + } + + /** + * Reset/clear collected errors. + */ + public function clearErrors() { + $this->errors = []; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php b/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php new file mode 100644 index 00000000..aeee989b --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php @@ -0,0 +1,18 @@ +type = $type; + $this->old = $old; + $this->new = $new; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php b/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php new file mode 100644 index 00000000..7f218c74 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php @@ -0,0 +1,164 @@ +isEqual = $isEqual; + } + + /** + * Calculate diff (edit script) from $old to $new. + * + * @param array $old Original array + * @param array $new New array + * + * @return DiffElem[] Diff (edit script) + */ + public function diff(array $old, array $new) { + list($trace, $x, $y) = $this->calculateTrace($old, $new); + return $this->extractDiff($trace, $x, $y, $old, $new); + } + + /** + * Calculate diff, including "replace" operations. + * + * If a sequence of remove operations is followed by the same number of add operations, these + * will be coalesced into replace operations. + * + * @param array $old Original array + * @param array $new New array + * + * @return DiffElem[] Diff (edit script), including replace operations + */ + public function diffWithReplacements(array $old, array $new) { + return $this->coalesceReplacements($this->diff($old, $new)); + } + + private function calculateTrace(array $a, array $b) { + $n = \count($a); + $m = \count($b); + $max = $n + $m; + $v = [1 => 0]; + $trace = []; + for ($d = 0; $d <= $max; $d++) { + $trace[] = $v; + for ($k = -$d; $k <= $d; $k += 2) { + if ($k === -$d || ($k !== $d && $v[$k-1] < $v[$k+1])) { + $x = $v[$k+1]; + } else { + $x = $v[$k-1] + 1; + } + + $y = $x - $k; + while ($x < $n && $y < $m && ($this->isEqual)($a[$x], $b[$y])) { + $x++; + $y++; + } + + $v[$k] = $x; + if ($x >= $n && $y >= $m) { + return [$trace, $x, $y]; + } + } + } + throw new \Exception('Should not happen'); + } + + private function extractDiff(array $trace, int $x, int $y, array $a, array $b) { + $result = []; + for ($d = \count($trace) - 1; $d >= 0; $d--) { + $v = $trace[$d]; + $k = $x - $y; + + if ($k === -$d || ($k !== $d && $v[$k-1] < $v[$k+1])) { + $prevK = $k + 1; + } else { + $prevK = $k - 1; + } + + $prevX = $v[$prevK]; + $prevY = $prevX - $prevK; + + while ($x > $prevX && $y > $prevY) { + $result[] = new DiffElem(DiffElem::TYPE_KEEP, $a[$x-1], $b[$y-1]); + $x--; + $y--; + } + + if ($d === 0) { + break; + } + + while ($x > $prevX) { + $result[] = new DiffElem(DiffElem::TYPE_REMOVE, $a[$x-1], null); + $x--; + } + + while ($y > $prevY) { + $result[] = new DiffElem(DiffElem::TYPE_ADD, null, $b[$y-1]); + $y--; + } + } + return array_reverse($result); + } + + /** + * Coalesce equal-length sequences of remove+add into a replace operation. + * + * @param DiffElem[] $diff + * @return DiffElem[] + */ + private function coalesceReplacements(array $diff) { + $newDiff = []; + $c = \count($diff); + for ($i = 0; $i < $c; $i++) { + $diffType = $diff[$i]->type; + if ($diffType !== DiffElem::TYPE_REMOVE) { + $newDiff[] = $diff[$i]; + continue; + } + + $j = $i; + while ($j < $c && $diff[$j]->type === DiffElem::TYPE_REMOVE) { + $j++; + } + + $k = $j; + while ($k < $c && $diff[$k]->type === DiffElem::TYPE_ADD) { + $k++; + } + + if ($j - $i === $k - $j) { + $len = $j - $i; + for ($n = 0; $n < $len; $n++) { + $newDiff[] = new DiffElem( + DiffElem::TYPE_REPLACE, $diff[$i + $n]->old, $diff[$j + $n]->new + ); + } + } else { + for (; $i < $k; $i++) { + $newDiff[] = $diff[$i]; + } + } + $i = $k - 1; + } + return $newDiff; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php b/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php new file mode 100644 index 00000000..7b019db8 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php @@ -0,0 +1,57 @@ +args = $args; + $this->extends = $extends; + $this->implements = $implements; + $this->stmts = $stmts; + } + + public static function fromNewNode(Expr\New_ $newNode) { + $class = $newNode->class; + assert($class instanceof Node\Stmt\Class_); + // We don't assert that $class->name is null here, to allow consumers to assign unique names + // to anonymous classes for their own purposes. We simplify ignore the name here. + return new self( + $newNode->args, $class->extends, $class->implements, + $class->stmts, $newNode->getAttributes() + ); + } + + public function getType() : string { + return 'Expr_PrintableNewAnonClass'; + } + + public function getSubNodeNames() : array { + return ['args', 'extends', 'implements', 'stmts']; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php b/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php new file mode 100644 index 00000000..cf9e00ab --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php @@ -0,0 +1,256 @@ +tokens = $tokens; + $this->indentMap = $this->calcIndentMap(); + } + + /** + * Whether the given position is immediately surrounded by parenthesis. + * + * @param int $startPos Start position + * @param int $endPos End position + * + * @return bool + */ + public function haveParens(int $startPos, int $endPos) : bool { + return $this->haveTokenImmediativelyBefore($startPos, '(') + && $this->haveTokenImmediatelyAfter($endPos, ')'); + } + + /** + * Whether the given position is immediately surrounded by braces. + * + * @param int $startPos Start position + * @param int $endPos End position + * + * @return bool + */ + public function haveBraces(int $startPos, int $endPos) : bool { + return $this->haveTokenImmediativelyBefore($startPos, '{') + && $this->haveTokenImmediatelyAfter($endPos, '}'); + } + + /** + * Check whether the position is directly preceded by a certain token type. + * + * During this check whitespace and comments are skipped. + * + * @param int $pos Position before which the token should occur + * @param int|string $expectedTokenType Token to check for + * + * @return bool Whether the expected token was found + */ + public function haveTokenImmediativelyBefore(int $pos, $expectedTokenType) : bool { + $tokens = $this->tokens; + $pos--; + for (; $pos >= 0; $pos--) { + $tokenType = $tokens[$pos][0]; + if ($tokenType === $expectedTokenType) { + return true; + } + if ($tokenType !== \T_WHITESPACE + && $tokenType !== \T_COMMENT && $tokenType !== \T_DOC_COMMENT) { + break; + } + } + return false; + } + + /** + * Check whether the position is directly followed by a certain token type. + * + * During this check whitespace and comments are skipped. + * + * @param int $pos Position after which the token should occur + * @param int|string $expectedTokenType Token to check for + * + * @return bool Whether the expected token was found + */ + public function haveTokenImmediatelyAfter(int $pos, $expectedTokenType) : bool { + $tokens = $this->tokens; + $pos++; + for (; $pos < \count($tokens); $pos++) { + $tokenType = $tokens[$pos][0]; + if ($tokenType === $expectedTokenType) { + return true; + } + if ($tokenType !== \T_WHITESPACE + && $tokenType !== \T_COMMENT && $tokenType !== \T_DOC_COMMENT) { + break; + } + } + return false; + } + + public function skipLeft(int $pos, $skipTokenType) { + $tokens = $this->tokens; + + $pos = $this->skipLeftWhitespace($pos); + if ($skipTokenType === \T_WHITESPACE) { + return $pos; + } + + if ($tokens[$pos][0] !== $skipTokenType) { + // Shouldn't happen. The skip token MUST be there + throw new \Exception('Encountered unexpected token'); + } + $pos--; + + return $this->skipLeftWhitespace($pos); + } + + public function skipRight(int $pos, $skipTokenType) { + $tokens = $this->tokens; + + $pos = $this->skipRightWhitespace($pos); + if ($skipTokenType === \T_WHITESPACE) { + return $pos; + } + + if ($tokens[$pos][0] !== $skipTokenType) { + // Shouldn't happen. The skip token MUST be there + throw new \Exception('Encountered unexpected token'); + } + $pos++; + + return $this->skipRightWhitespace($pos); + } + + /** + * Return first non-whitespace token position smaller or equal to passed position. + * + * @param int $pos Token position + * @return int Non-whitespace token position + */ + public function skipLeftWhitespace(int $pos) { + $tokens = $this->tokens; + for (; $pos >= 0; $pos--) { + $type = $tokens[$pos][0]; + if ($type !== \T_WHITESPACE && $type !== \T_COMMENT && $type !== \T_DOC_COMMENT) { + break; + } + } + return $pos; + } + + /** + * Return first non-whitespace position greater or equal to passed position. + * + * @param int $pos Token position + * @return int Non-whitespace token position + */ + public function skipRightWhitespace(int $pos) { + $tokens = $this->tokens; + for ($count = \count($tokens); $pos < $count; $pos++) { + $type = $tokens[$pos][0]; + if ($type !== \T_WHITESPACE && $type !== \T_COMMENT && $type !== \T_DOC_COMMENT) { + break; + } + } + return $pos; + } + + public function findRight($pos, $findTokenType) { + $tokens = $this->tokens; + for ($count = \count($tokens); $pos < $count; $pos++) { + $type = $tokens[$pos][0]; + if ($type === $findTokenType) { + return $pos; + } + } + return -1; + } + + /** + * Get indentation before token position. + * + * @param int $pos Token position + * + * @return int Indentation depth (in spaces) + */ + public function getIndentationBefore(int $pos) : int { + return $this->indentMap[$pos]; + } + + /** + * Get the code corresponding to a token offset range, optionally adjusted for indentation. + * + * @param int $from Token start position (inclusive) + * @param int $to Token end position (exclusive) + * @param int $indent By how much the code should be indented (can be negative as well) + * + * @return string Code corresponding to token range, adjusted for indentation + */ + public function getTokenCode(int $from, int $to, int $indent) : string { + $tokens = $this->tokens; + $result = ''; + for ($pos = $from; $pos < $to; $pos++) { + $token = $tokens[$pos]; + if (\is_array($token)) { + $type = $token[0]; + $content = $token[1]; + if ($type === \T_CONSTANT_ENCAPSED_STRING || $type === \T_ENCAPSED_AND_WHITESPACE) { + $result .= $content; + } else { + // TODO Handle non-space indentation + if ($indent < 0) { + $result .= str_replace("\n" . str_repeat(" ", -$indent), "\n", $content); + } elseif ($indent > 0) { + $result .= str_replace("\n", "\n" . str_repeat(" ", $indent), $content); + } else { + $result .= $content; + } + } + } else { + $result .= $token; + } + } + return $result; + } + + /** + * Precalculate the indentation at every token position. + * + * @return int[] Token position to indentation map + */ + private function calcIndentMap() { + $indentMap = []; + $indent = 0; + foreach ($this->tokens as $token) { + $indentMap[] = $indent; + + if ($token[0] === \T_WHITESPACE) { + $content = $token[1]; + $newlinePos = \strrpos($content, "\n"); + if (false !== $newlinePos) { + $indent = \strlen($content) - $newlinePos - 1; + } + } + } + + // Add a sentinel for one past end of the file + $indentMap[] = $indent; + + return $indentMap; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php b/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php new file mode 100644 index 00000000..25d1c6ab --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php @@ -0,0 +1,101 @@ +decodeRecursive($value); + } + + private function decodeRecursive($value) { + if (\is_array($value)) { + if (isset($value['nodeType'])) { + if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc') { + return $this->decodeComment($value); + } + return $this->decodeNode($value); + } + return $this->decodeArray($value); + } + return $value; + } + + private function decodeArray(array $array) : array { + $decodedArray = []; + foreach ($array as $key => $value) { + $decodedArray[$key] = $this->decodeRecursive($value); + } + return $decodedArray; + } + + private function decodeNode(array $value) : Node { + $nodeType = $value['nodeType']; + if (!\is_string($nodeType)) { + throw new \RuntimeException('Node type must be a string'); + } + + $reflectionClass = $this->reflectionClassFromNodeType($nodeType); + /** @var Node $node */ + $node = $reflectionClass->newInstanceWithoutConstructor(); + + if (isset($value['attributes'])) { + if (!\is_array($value['attributes'])) { + throw new \RuntimeException('Attributes must be an array'); + } + + $node->setAttributes($this->decodeArray($value['attributes'])); + } + + foreach ($value as $name => $subNode) { + if ($name === 'nodeType' || $name === 'attributes') { + continue; + } + + $node->$name = $this->decodeRecursive($subNode); + } + + return $node; + } + + private function decodeComment(array $value) : Comment { + $className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class; + if (!isset($value['text'])) { + throw new \RuntimeException('Comment must have text'); + } + + return new $className( + $value['text'], $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1 + ); + } + + private function reflectionClassFromNodeType(string $nodeType) : \ReflectionClass { + if (!isset($this->reflectionClassCache[$nodeType])) { + $className = $this->classNameFromNodeType($nodeType); + $this->reflectionClassCache[$nodeType] = new \ReflectionClass($className); + } + return $this->reflectionClassCache[$nodeType]; + } + + private function classNameFromNodeType(string $nodeType) : string { + $className = 'PhpParser\\Node\\' . strtr($nodeType, '_', '\\'); + if (class_exists($className)) { + return $className; + } + + $className .= '_'; + if (class_exists($className)) { + return $className; + } + + throw new \RuntimeException("Unknown node type \"$nodeType\""); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Lexer.php b/vendor/nikic/php-parser/lib/PhpParser/Lexer.php new file mode 100644 index 00000000..125c3b80 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Lexer.php @@ -0,0 +1,378 @@ +tokenMap = $this->createTokenMap(); + + // map of tokens to drop while lexing (the map is only used for isset lookup, + // that's why the value is simply set to 1; the value is never actually used.) + $this->dropTokens = array_fill_keys( + [\T_WHITESPACE, \T_OPEN_TAG, \T_COMMENT, \T_DOC_COMMENT], 1 + ); + + // the usedAttributes member is a map of the used attribute names to a dummy + // value (here "true") + $options += [ + 'usedAttributes' => ['comments', 'startLine', 'endLine'], + ]; + $this->usedAttributes = array_fill_keys($options['usedAttributes'], true); + } + + /** + * Initializes the lexer for lexing the provided source code. + * + * This function does not throw if lexing errors occur. Instead, errors may be retrieved using + * the getErrors() method. + * + * @param string $code The source code to lex + * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to + * ErrorHandler\Throwing + */ + public function startLexing(string $code, ErrorHandler $errorHandler = null) { + if (null === $errorHandler) { + $errorHandler = new ErrorHandler\Throwing(); + } + + $this->code = $code; // keep the code around for __halt_compiler() handling + $this->pos = -1; + $this->line = 1; + $this->filePos = 0; + + // If inline HTML occurs without preceding code, treat it as if it had a leading newline. + // This ensures proper composability, because having a newline is the "safe" assumption. + $this->prevCloseTagHasNewline = true; + + $scream = ini_set('xdebug.scream', '0'); + + error_clear_last(); + $this->tokens = @token_get_all($code); + $this->handleErrors($errorHandler); + + if (false !== $scream) { + ini_set('xdebug.scream', $scream); + } + } + + private function handleInvalidCharacterRange($start, $end, $line, ErrorHandler $errorHandler) { + for ($i = $start; $i < $end; $i++) { + $chr = $this->code[$i]; + if ($chr === 'b' || $chr === 'B') { + // HHVM does not treat b" tokens correctly, so ignore these + continue; + } + + if ($chr === "\0") { + // PHP cuts error message after null byte, so need special case + $errorMsg = 'Unexpected null byte'; + } else { + $errorMsg = sprintf( + 'Unexpected character "%s" (ASCII %d)', $chr, ord($chr) + ); + } + + $errorHandler->handleError(new Error($errorMsg, [ + 'startLine' => $line, + 'endLine' => $line, + 'startFilePos' => $i, + 'endFilePos' => $i, + ])); + } + } + + /** + * Check whether comment token is unterminated. + * + * @return bool + */ + private function isUnterminatedComment($token) : bool { + return ($token[0] === \T_COMMENT || $token[0] === \T_DOC_COMMENT) + && substr($token[1], 0, 2) === '/*' + && substr($token[1], -2) !== '*/'; + } + + /** + * Check whether an error *may* have occurred during tokenization. + * + * @return bool + */ + private function errorMayHaveOccurred() : bool { + if (defined('HHVM_VERSION')) { + // In HHVM token_get_all() does not throw warnings, so we need to conservatively + // assume that an error occurred + return true; + } + + return null !== error_get_last(); + } + + protected function handleErrors(ErrorHandler $errorHandler) { + if (!$this->errorMayHaveOccurred()) { + return; + } + + // PHP's error handling for token_get_all() is rather bad, so if we want detailed + // error information we need to compute it ourselves. Invalid character errors are + // detected by finding "gaps" in the token array. Unterminated comments are detected + // by checking if a trailing comment has a "*/" at the end. + + $filePos = 0; + $line = 1; + foreach ($this->tokens as $token) { + $tokenValue = \is_string($token) ? $token : $token[1]; + $tokenLen = \strlen($tokenValue); + + if (substr($this->code, $filePos, $tokenLen) !== $tokenValue) { + // Something is missing, must be an invalid character + $nextFilePos = strpos($this->code, $tokenValue, $filePos); + $this->handleInvalidCharacterRange( + $filePos, $nextFilePos, $line, $errorHandler); + $filePos = (int) $nextFilePos; + } + + $filePos += $tokenLen; + $line += substr_count($tokenValue, "\n"); + } + + if ($filePos !== \strlen($this->code)) { + if (substr($this->code, $filePos, 2) === '/*') { + // Unlike PHP, HHVM will drop unterminated comments entirely + $comment = substr($this->code, $filePos); + $errorHandler->handleError(new Error('Unterminated comment', [ + 'startLine' => $line, + 'endLine' => $line + substr_count($comment, "\n"), + 'startFilePos' => $filePos, + 'endFilePos' => $filePos + \strlen($comment), + ])); + + // Emulate the PHP behavior + $isDocComment = isset($comment[3]) && $comment[3] === '*'; + $this->tokens[] = [$isDocComment ? \T_DOC_COMMENT : \T_COMMENT, $comment, $line]; + } else { + // Invalid characters at the end of the input + $this->handleInvalidCharacterRange( + $filePos, \strlen($this->code), $line, $errorHandler); + } + return; + } + + if (count($this->tokens) > 0) { + // Check for unterminated comment + $lastToken = $this->tokens[count($this->tokens) - 1]; + if ($this->isUnterminatedComment($lastToken)) { + $errorHandler->handleError(new Error('Unterminated comment', [ + 'startLine' => $line - substr_count($lastToken[1], "\n"), + 'endLine' => $line, + 'startFilePos' => $filePos - \strlen($lastToken[1]), + 'endFilePos' => $filePos, + ])); + } + } + } + + /** + * Fetches the next token. + * + * The available attributes are determined by the 'usedAttributes' option, which can + * be specified in the constructor. The following attributes are supported: + * + * * 'comments' => Array of PhpParser\Comment or PhpParser\Comment\Doc instances, + * representing all comments that occurred between the previous + * non-discarded token and the current one. + * * 'startLine' => Line in which the node starts. + * * 'endLine' => Line in which the node ends. + * * 'startTokenPos' => Offset into the token array of the first token in the node. + * * 'endTokenPos' => Offset into the token array of the last token in the node. + * * 'startFilePos' => Offset into the code string of the first character that is part of the node. + * * 'endFilePos' => Offset into the code string of the last character that is part of the node. + * + * @param mixed $value Variable to store token content in + * @param mixed $startAttributes Variable to store start attributes in + * @param mixed $endAttributes Variable to store end attributes in + * + * @return int Token id + */ + public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) : int { + $startAttributes = []; + $endAttributes = []; + + while (1) { + if (isset($this->tokens[++$this->pos])) { + $token = $this->tokens[$this->pos]; + } else { + // EOF token with ID 0 + $token = "\0"; + } + + if (isset($this->usedAttributes['startLine'])) { + $startAttributes['startLine'] = $this->line; + } + if (isset($this->usedAttributes['startTokenPos'])) { + $startAttributes['startTokenPos'] = $this->pos; + } + if (isset($this->usedAttributes['startFilePos'])) { + $startAttributes['startFilePos'] = $this->filePos; + } + + if (\is_string($token)) { + $value = $token; + if (isset($token[1])) { + // bug in token_get_all + $this->filePos += 2; + $id = ord('"'); + } else { + $this->filePos += 1; + $id = ord($token); + } + } elseif (!isset($this->dropTokens[$token[0]])) { + $value = $token[1]; + $id = $this->tokenMap[$token[0]]; + if (\T_CLOSE_TAG === $token[0]) { + $this->prevCloseTagHasNewline = false !== strpos($token[1], "\n"); + } elseif (\T_INLINE_HTML === $token[0]) { + $startAttributes['hasLeadingNewline'] = $this->prevCloseTagHasNewline; + } + + $this->line += substr_count($value, "\n"); + $this->filePos += \strlen($value); + } else { + if (\T_COMMENT === $token[0] || \T_DOC_COMMENT === $token[0]) { + if (isset($this->usedAttributes['comments'])) { + $comment = \T_DOC_COMMENT === $token[0] + ? new Comment\Doc($token[1], $this->line, $this->filePos, $this->pos) + : new Comment($token[1], $this->line, $this->filePos, $this->pos); + $startAttributes['comments'][] = $comment; + } + } + + $this->line += substr_count($token[1], "\n"); + $this->filePos += \strlen($token[1]); + continue; + } + + if (isset($this->usedAttributes['endLine'])) { + $endAttributes['endLine'] = $this->line; + } + if (isset($this->usedAttributes['endTokenPos'])) { + $endAttributes['endTokenPos'] = $this->pos; + } + if (isset($this->usedAttributes['endFilePos'])) { + $endAttributes['endFilePos'] = $this->filePos - 1; + } + + return $id; + } + + throw new \RuntimeException('Reached end of lexer loop'); + } + + /** + * Returns the token array for current code. + * + * The token array is in the same format as provided by the + * token_get_all() function and does not discard tokens (i.e. + * whitespace and comments are included). The token position + * attributes are against this token array. + * + * @return array Array of tokens in token_get_all() format + */ + public function getTokens() : array { + return $this->tokens; + } + + /** + * Handles __halt_compiler() by returning the text after it. + * + * @return string Remaining text + */ + public function handleHaltCompiler() : string { + // text after T_HALT_COMPILER, still including (); + $textAfter = substr($this->code, $this->filePos); + + // ensure that it is followed by (); + // this simplifies the situation, by not allowing any comments + // in between of the tokens. + if (!preg_match('~^\s*\(\s*\)\s*(?:;|\?>\r?\n?)~', $textAfter, $matches)) { + throw new Error('__HALT_COMPILER must be followed by "();"'); + } + + // prevent the lexer from returning any further tokens + $this->pos = count($this->tokens); + + // return with (); removed + return substr($textAfter, strlen($matches[0])); + } + + /** + * Creates the token map. + * + * The token map maps the PHP internal token identifiers + * to the identifiers used by the Parser. Additionally it + * maps T_OPEN_TAG_WITH_ECHO to T_ECHO and T_CLOSE_TAG to ';'. + * + * @return array The token map + */ + protected function createTokenMap() : array { + $tokenMap = []; + + // 256 is the minimum possible token number, as everything below + // it is an ASCII value + for ($i = 256; $i < 1000; ++$i) { + if (\T_DOUBLE_COLON === $i) { + // T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM + $tokenMap[$i] = Tokens::T_PAAMAYIM_NEKUDOTAYIM; + } elseif(\T_OPEN_TAG_WITH_ECHO === $i) { + // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO + $tokenMap[$i] = Tokens::T_ECHO; + } elseif(\T_CLOSE_TAG === $i) { + // T_CLOSE_TAG is equivalent to ';' + $tokenMap[$i] = ord(';'); + } elseif ('UNKNOWN' !== $name = token_name($i)) { + if ('T_HASHBANG' === $name) { + // HHVM uses a special token for #! hashbang lines + $tokenMap[$i] = Tokens::T_INLINE_HTML; + } elseif (defined($name = Tokens::class . '::' . $name)) { + // Other tokens can be mapped directly + $tokenMap[$i] = constant($name); + } + } + } + + // HHVM uses a special token for numbers that overflow to double + if (defined('T_ONUMBER')) { + $tokenMap[\T_ONUMBER] = Tokens::T_DNUMBER; + } + // HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant + if (defined('T_COMPILER_HALT_OFFSET')) { + $tokenMap[\T_COMPILER_HALT_OFFSET] = Tokens::T_STRING; + } + + return $tokenMap; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php b/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php new file mode 100644 index 00000000..3bae4a47 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php @@ -0,0 +1,272 @@ +\h*)\2(?![a-zA-Z_\x80-\xff])(?(?:;?[\r\n])?)/x +REGEX; + + const T_COALESCE_EQUAL = 1007; + + /** + * @var mixed[] Patches used to reverse changes introduced in the code + */ + private $patches = []; + + /** + * @param mixed[] $options + */ + public function __construct(array $options = []) + { + parent::__construct($options); + + // add emulated tokens here + $this->tokenMap[self::T_COALESCE_EQUAL] = Parser\Tokens::T_COALESCE_EQUAL; + } + + public function startLexing(string $code, ErrorHandler $errorHandler = null) { + $this->patches = []; + + if ($this->isEmulationNeeded($code) === false) { + // Nothing to emulate, yay + parent::startLexing($code, $errorHandler); + return; + } + + $collector = new ErrorHandler\Collecting(); + + // 1. emulation of heredoc and nowdoc new syntax + $preparedCode = $this->processHeredocNowdoc($code); + parent::startLexing($preparedCode, $collector); + + // 2. emulation of ??= token + $this->processCoaleseEqual($code); + $this->fixupTokens(); + + $errors = $collector->getErrors(); + if (!empty($errors)) { + $this->fixupErrors($errors); + foreach ($errors as $error) { + $errorHandler->handleError($error); + } + } + } + + private function isCoalesceEqualEmulationNeeded(string $code): bool + { + // skip version where this works without emulation + if (version_compare(\PHP_VERSION, self::PHP_7_4, '>=')) { + return false; + } + + return strpos($code, '??=') !== false; + } + + private function processCoaleseEqual(string $code) + { + if ($this->isCoalesceEqualEmulationNeeded($code) === false) { + return; + } + + // We need to manually iterate and manage a count because we'll change + // the tokens array on the way + $line = 1; + for ($i = 0, $c = count($this->tokens); $i < $c; ++$i) { + if (isset($this->tokens[$i + 1])) { + if ($this->tokens[$i][0] === T_COALESCE && $this->tokens[$i + 1] === '=') { + array_splice($this->tokens, $i, 2, [ + [self::T_COALESCE_EQUAL, '??=', $line] + ]); + $c--; + continue; + } + } + if (\is_array($this->tokens[$i])) { + $line += substr_count($this->tokens[$i][1], "\n"); + } + } + } + + private function isHeredocNowdocEmulationNeeded(string $code): bool + { + // skip version where this works without emulation + if (version_compare(\PHP_VERSION, self::PHP_7_3, '>=')) { + return false; + } + + return strpos($code, '<<<') !== false; + } + + private function processHeredocNowdoc(string $code): string + { + if ($this->isHeredocNowdocEmulationNeeded($code) === false) { + return $code; + } + + if (!preg_match_all(self::FLEXIBLE_DOC_STRING_REGEX, $code, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE)) { + // No heredoc/nowdoc found + return $code; + } + + // Keep track of how much we need to adjust string offsets due to the modifications we + // already made + $posDelta = 0; + foreach ($matches as $match) { + $indentation = $match['indentation'][0]; + $indentationStart = $match['indentation'][1]; + + $separator = $match['separator'][0]; + $separatorStart = $match['separator'][1]; + + if ($indentation === '' && $separator !== '') { + // Ordinary heredoc/nowdoc + continue; + } + + if ($indentation !== '') { + // Remove indentation + $indentationLen = strlen($indentation); + $code = substr_replace($code, '', $indentationStart + $posDelta, $indentationLen); + $this->patches[] = [$indentationStart + $posDelta, 'add', $indentation]; + $posDelta -= $indentationLen; + } + + if ($separator === '') { + // Insert newline as separator + $code = substr_replace($code, "\n", $separatorStart + $posDelta, 0); + $this->patches[] = [$separatorStart + $posDelta, 'remove', "\n"]; + $posDelta += 1; + } + } + + return $code; + } + + private function isEmulationNeeded(string $code): bool + { + if ($this->isHeredocNowdocEmulationNeeded($code)) { + return true; + } + + if ($this->isCoalesceEqualEmulationNeeded($code)) { + return true; + } + + return false; + } + + private function fixupTokens() + { + if (\count($this->patches) === 0) { + return; + } + + // Load first patch + $patchIdx = 0; + + list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx]; + + // We use a manual loop over the tokens, because we modify the array on the fly + $pos = 0; + for ($i = 0, $c = \count($this->tokens); $i < $c; $i++) { + $token = $this->tokens[$i]; + if (\is_string($token)) { + // We assume that patches don't apply to string tokens + $pos += \strlen($token); + continue; + } + + $len = \strlen($token[1]); + $posDelta = 0; + while ($patchPos >= $pos && $patchPos < $pos + $len) { + $patchTextLen = \strlen($patchText); + if ($patchType === 'remove') { + if ($patchPos === $pos && $patchTextLen === $len) { + // Remove token entirely + array_splice($this->tokens, $i, 1, []); + $i--; + $c--; + } else { + // Remove from token string + $this->tokens[$i][1] = substr_replace( + $token[1], '', $patchPos - $pos + $posDelta, $patchTextLen + ); + $posDelta -= $patchTextLen; + } + } elseif ($patchType === 'add') { + // Insert into the token string + $this->tokens[$i][1] = substr_replace( + $token[1], $patchText, $patchPos - $pos + $posDelta, 0 + ); + $posDelta += $patchTextLen; + } else { + assert(false); + } + + // Fetch the next patch + $patchIdx++; + if ($patchIdx >= \count($this->patches)) { + // No more patches, we're done + return; + } + + list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx]; + + // Multiple patches may apply to the same token. Reload the current one to check + // If the new patch applies + $token = $this->tokens[$i]; + } + + $pos += $len; + } + + // A patch did not apply + assert(false); + } + + /** + * Fixup line and position information in errors. + * + * @param Error[] $errors + */ + private function fixupErrors(array $errors) { + foreach ($errors as $error) { + $attrs = $error->getAttributes(); + + $posDelta = 0; + $lineDelta = 0; + foreach ($this->patches as $patch) { + list($patchPos, $patchType, $patchText) = $patch; + if ($patchPos >= $attrs['startFilePos']) { + // No longer relevant + break; + } + + if ($patchType === 'add') { + $posDelta += strlen($patchText); + $lineDelta += substr_count($patchText, "\n"); + } else { + $posDelta -= strlen($patchText); + $lineDelta -= substr_count($patchText, "\n"); + } + } + + $attrs['startFilePos'] += $posDelta; + $attrs['endFilePos'] += $posDelta; + $attrs['startLine'] += $lineDelta; + $attrs['endLine'] += $lineDelta; + $error->setAttributes($attrs); + } + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NameContext.php b/vendor/nikic/php-parser/lib/PhpParser/NameContext.php new file mode 100644 index 00000000..777a4afd --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NameContext.php @@ -0,0 +1,285 @@ + [aliasName => originalName]] */ + protected $aliases = []; + + /** @var Name[][] Same as $aliases but preserving original case */ + protected $origAliases = []; + + /** @var ErrorHandler Error handler */ + protected $errorHandler; + + /** + * Create a name context. + * + * @param ErrorHandler $errorHandler Error handling used to report errors + */ + public function __construct(ErrorHandler $errorHandler) { + $this->errorHandler = $errorHandler; + } + + /** + * Start a new namespace. + * + * This also resets the alias table. + * + * @param Name|null $namespace Null is the global namespace + */ + public function startNamespace(Name $namespace = null) { + $this->namespace = $namespace; + $this->origAliases = $this->aliases = [ + Stmt\Use_::TYPE_NORMAL => [], + Stmt\Use_::TYPE_FUNCTION => [], + Stmt\Use_::TYPE_CONSTANT => [], + ]; + } + + /** + * Add an alias / import. + * + * @param Name $name Original name + * @param string $aliasName Aliased name + * @param int $type One of Stmt\Use_::TYPE_* + * @param array $errorAttrs Attributes to use to report an error + */ + public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []) { + // Constant names are case sensitive, everything else case insensitive + if ($type === Stmt\Use_::TYPE_CONSTANT) { + $aliasLookupName = $aliasName; + } else { + $aliasLookupName = strtolower($aliasName); + } + + if (isset($this->aliases[$type][$aliasLookupName])) { + $typeStringMap = [ + Stmt\Use_::TYPE_NORMAL => '', + Stmt\Use_::TYPE_FUNCTION => 'function ', + Stmt\Use_::TYPE_CONSTANT => 'const ', + ]; + + $this->errorHandler->handleError(new Error( + sprintf( + 'Cannot use %s%s as %s because the name is already in use', + $typeStringMap[$type], $name, $aliasName + ), + $errorAttrs + )); + return; + } + + $this->aliases[$type][$aliasLookupName] = $name; + $this->origAliases[$type][$aliasName] = $name; + } + + /** + * Get current namespace. + * + * @return null|Name Namespace (or null if global namespace) + */ + public function getNamespace() { + return $this->namespace; + } + + /** + * Get resolved name. + * + * @param Name $name Name to resolve + * @param int $type One of Stmt\Use_::TYPE_{FUNCTION|CONSTANT} + * + * @return null|Name Resolved name, or null if static resolution is not possible + */ + public function getResolvedName(Name $name, int $type) { + // don't resolve special class names + if ($type === Stmt\Use_::TYPE_NORMAL && $name->isSpecialClassName()) { + if (!$name->isUnqualified()) { + $this->errorHandler->handleError(new Error( + sprintf("'\\%s' is an invalid class name", $name->toString()), + $name->getAttributes() + )); + } + return $name; + } + + // fully qualified names are already resolved + if ($name->isFullyQualified()) { + return $name; + } + + // Try to resolve aliases + if (null !== $resolvedName = $this->resolveAlias($name, $type)) { + return $resolvedName; + } + + if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) { + if (null === $this->namespace) { + // outside of a namespace unaliased unqualified is same as fully qualified + return new FullyQualified($name, $name->getAttributes()); + } + + // Cannot resolve statically + return null; + } + + // if no alias exists prepend current namespace + return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); + } + + /** + * Get resolved class name. + * + * @param Name $name Class ame to resolve + * + * @return Name Resolved name + */ + public function getResolvedClassName(Name $name) : Name { + return $this->getResolvedName($name, Stmt\Use_::TYPE_NORMAL); + } + + /** + * Get possible ways of writing a fully qualified name (e.g., by making use of aliases). + * + * @param string $name Fully-qualified name (without leading namespace separator) + * @param int $type One of Stmt\Use_::TYPE_* + * + * @return Name[] Possible representations of the name + */ + public function getPossibleNames(string $name, int $type) : array { + $lcName = strtolower($name); + + if ($type === Stmt\Use_::TYPE_NORMAL) { + // self, parent and static must always be unqualified + if ($lcName === "self" || $lcName === "parent" || $lcName === "static") { + return [new Name($name)]; + } + } + + // Collect possible ways to write this name, starting with the fully-qualified name + $possibleNames = [new FullyQualified($name)]; + + if (null !== $nsRelativeName = $this->getNamespaceRelativeName($name, $lcName, $type)) { + // Make sure there is no alias that makes the normally namespace-relative name + // into something else + if (null === $this->resolveAlias($nsRelativeName, $type)) { + $possibleNames[] = $nsRelativeName; + } + } + + // Check for relevant namespace use statements + foreach ($this->origAliases[Stmt\Use_::TYPE_NORMAL] as $alias => $orig) { + $lcOrig = $orig->toLowerString(); + if (0 === strpos($lcName, $lcOrig . '\\')) { + $possibleNames[] = new Name($alias . substr($name, strlen($lcOrig))); + } + } + + // Check for relevant type-specific use statements + foreach ($this->origAliases[$type] as $alias => $orig) { + if ($type === Stmt\Use_::TYPE_CONSTANT) { + // Constants are are complicated-sensitive + $normalizedOrig = $this->normalizeConstName($orig->toString()); + if ($normalizedOrig === $this->normalizeConstName($name)) { + $possibleNames[] = new Name($alias); + } + } else { + // Everything else is case-insensitive + if ($orig->toLowerString() === $lcName) { + $possibleNames[] = new Name($alias); + } + } + } + + return $possibleNames; + } + + /** + * Get shortest representation of this fully-qualified name. + * + * @param string $name Fully-qualified name (without leading namespace separator) + * @param int $type One of Stmt\Use_::TYPE_* + * + * @return Name Shortest representation + */ + public function getShortName(string $name, int $type) : Name { + $possibleNames = $this->getPossibleNames($name, $type); + + // Find shortest name + $shortestName = null; + $shortestLength = \INF; + foreach ($possibleNames as $possibleName) { + $length = strlen($possibleName->toCodeString()); + if ($length < $shortestLength) { + $shortestName = $possibleName; + $shortestLength = $length; + } + } + + return $shortestName; + } + + private function resolveAlias(Name $name, $type) { + $firstPart = $name->getFirst(); + + if ($name->isQualified()) { + // resolve aliases for qualified names, always against class alias table + $checkName = strtolower($firstPart); + if (isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName])) { + $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName]; + return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); + } + } elseif ($name->isUnqualified()) { + // constant aliases are case-sensitive, function aliases case-insensitive + $checkName = $type === Stmt\Use_::TYPE_CONSTANT ? $firstPart : strtolower($firstPart); + if (isset($this->aliases[$type][$checkName])) { + // resolve unqualified aliases + return new FullyQualified($this->aliases[$type][$checkName], $name->getAttributes()); + } + } + + // No applicable aliases + return null; + } + + private function getNamespaceRelativeName(string $name, string $lcName, int $type) { + if (null === $this->namespace) { + return new Name($name); + } + + if ($type === Stmt\Use_::TYPE_CONSTANT) { + // The constants true/false/null always resolve to the global symbols, even inside a + // namespace, so they may be used without qualification + if ($lcName === "true" || $lcName === "false" || $lcName === "null") { + return new Name($name); + } + } + + $namespacePrefix = strtolower($this->namespace . '\\'); + if (0 === strpos($lcName, $namespacePrefix)) { + return new Name(substr($name, strlen($namespacePrefix))); + } + + return null; + } + + private function normalizeConstName(string $name) { + $nsSep = strrpos($name, '\\'); + if (false === $nsSep) { + return $name; + } + + // Constants have case-insensitive namespace and case-sensitive short-name + $ns = substr($name, 0, $nsSep); + $shortName = substr($name, $nsSep + 1); + return strtolower($ns) . '\\' . $shortName; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node.php b/vendor/nikic/php-parser/lib/PhpParser/Node.php new file mode 100644 index 00000000..7f04c343 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node.php @@ -0,0 +1,153 @@ +value = $value; + $this->byRef = $byRef; + $this->unpack = $unpack; + } + + public function getSubNodeNames() : array { + return ['value', 'byRef', 'unpack']; + } + + public function getType() : string { + return 'Arg'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php new file mode 100644 index 00000000..76a220f4 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php @@ -0,0 +1,37 @@ +name = \is_string($name) ? new Identifier($name) : $name; + $this->value = $value; + } + + public function getSubNodeNames() : array { + return ['name', 'value']; + } + + public function getType() : string { + return 'Const'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php new file mode 100644 index 00000000..6cf4df22 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php @@ -0,0 +1,9 @@ +var = $var; + $this->dim = $dim; + } + + public function getSubNodeNames() : array { + return ['var', 'dim']; + } + + public function getType() : string { + return 'Expr_ArrayDimFetch'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php new file mode 100644 index 00000000..bf9c7fde --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php @@ -0,0 +1,38 @@ +key = $key; + $this->value = $value; + $this->byRef = $byRef; + } + + public function getSubNodeNames() : array { + return ['key', 'value', 'byRef']; + } + + public function getType() : string { + return 'Expr_ArrayItem'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php new file mode 100644 index 00000000..061c52e3 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php @@ -0,0 +1,34 @@ +items = $items; + } + + public function getSubNodeNames() : array { + return ['items']; + } + + public function getType() : string { + return 'Expr_Array'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php new file mode 100644 index 00000000..1306c88f --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php @@ -0,0 +1,34 @@ +var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames() : array { + return ['var', 'expr']; + } + + public function getType() : string { + return 'Expr_Assign'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php new file mode 100644 index 00000000..e5bdbf58 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php @@ -0,0 +1,30 @@ +var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames() : array { + return ['var', 'expr']; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php new file mode 100644 index 00000000..420284cd --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php @@ -0,0 +1,12 @@ +var = $var; + $this->expr = $expr; + } + + public function getSubNodeNames() : array { + return ['var', 'expr']; + } + + public function getType() : string { + return 'Expr_AssignRef'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php new file mode 100644 index 00000000..466b01a2 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php @@ -0,0 +1,40 @@ +left = $left; + $this->right = $right; + } + + public function getSubNodeNames() : array { + return ['left', 'right']; + } + + /** + * Get the operator sigil for this binary operation. + * + * In the case there are multiple possible sigils for an operator, this method does not + * necessarily return the one used in the parsed code. + * + * @return string + */ + abstract public function getOperatorSigil() : string; +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php new file mode 100644 index 00000000..d907393b --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php @@ -0,0 +1,16 @@ +'; + } + + public function getType() : string { + return 'Expr_BinaryOp_Greater'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php new file mode 100644 index 00000000..d677502c --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php @@ -0,0 +1,16 @@ +='; + } + + public function getType() : string { + return 'Expr_BinaryOp_GreaterOrEqual'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php new file mode 100644 index 00000000..3d96285c --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php @@ -0,0 +1,16 @@ +>'; + } + + public function getType() : string { + return 'Expr_BinaryOp_ShiftRight'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php new file mode 100644 index 00000000..3cb8e7e0 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php @@ -0,0 +1,16 @@ +'; + } + + public function getType() : string { + return 'Expr_BinaryOp_Spaceship'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php new file mode 100644 index 00000000..f96fdddc --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_BitwiseNot'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php new file mode 100644 index 00000000..1ae74b16 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_BooleanNot'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php new file mode 100644 index 00000000..8fd0285e --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php @@ -0,0 +1,26 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php new file mode 100644 index 00000000..57cc473b --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php @@ -0,0 +1,12 @@ +class = $class; + $this->name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames() : array { + return ['class', 'name']; + } + + public function getType() : string { + return 'Expr_ClassConstFetch'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php new file mode 100644 index 00000000..9f6931a6 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Clone'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php new file mode 100644 index 00000000..261b4440 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php @@ -0,0 +1,71 @@ + false : Whether the closure is static + * 'byRef' => false : Whether to return by reference + * 'params' => array(): Parameters + * 'uses' => array(): use()s + * 'returnType' => null : Return type + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct(array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->static = $subNodes['static'] ?? false; + $this->byRef = $subNodes['byRef'] ?? false; + $this->params = $subNodes['params'] ?? []; + $this->uses = $subNodes['uses'] ?? []; + $returnType = $subNodes['returnType'] ?? null; + $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames() : array { + return ['static', 'byRef', 'params', 'uses', 'returnType', 'stmts']; + } + + public function returnsByRef() : bool { + return $this->byRef; + } + + public function getParams() : array { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + /** @return Node\Stmt[] */ + public function getStmts() : array { + return $this->stmts; + } + + public function getType() : string { + return 'Expr_Closure'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php new file mode 100644 index 00000000..4c551684 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php @@ -0,0 +1,34 @@ +var = $var; + $this->byRef = $byRef; + } + + public function getSubNodeNames() : array { + return ['var', 'byRef']; + } + + public function getType() : string { + return 'Expr_ClosureUse'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php new file mode 100644 index 00000000..875ddf3c --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php @@ -0,0 +1,31 @@ +name = $name; + } + + public function getSubNodeNames() : array { + return ['name']; + } + + public function getType() : string { + return 'Expr_ConstFetch'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php new file mode 100644 index 00000000..2e0c43b0 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Empty'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php new file mode 100644 index 00000000..90f6cbbc --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php @@ -0,0 +1,31 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_ErrorSuppress'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php new file mode 100644 index 00000000..d421595a --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Eval'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php new file mode 100644 index 00000000..58134811 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php @@ -0,0 +1,34 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Exit'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php new file mode 100644 index 00000000..79457670 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php @@ -0,0 +1,35 @@ +name = $name; + $this->args = $args; + } + + public function getSubNodeNames() : array { + return ['name', 'args']; + } + + public function getType() : string { + return 'Expr_FuncCall'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php new file mode 100644 index 00000000..aa6e55d1 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php @@ -0,0 +1,39 @@ +expr = $expr; + $this->type = $type; + } + + public function getSubNodeNames() : array { + return ['expr', 'type']; + } + + public function getType() : string { + return 'Expr_Include'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php new file mode 100644 index 00000000..5b73d027 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php @@ -0,0 +1,35 @@ +expr = $expr; + $this->class = $class; + } + + public function getSubNodeNames() : array { + return ['expr', 'class']; + } + + public function getType() : string { + return 'Expr_Instanceof'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php new file mode 100644 index 00000000..5e192cfe --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php @@ -0,0 +1,30 @@ +vars = $vars; + } + + public function getSubNodeNames() : array { + return ['vars']; + } + + public function getType() : string { + return 'Expr_Isset'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php new file mode 100644 index 00000000..cc156e3a --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php @@ -0,0 +1,30 @@ +items = $items; + } + + public function getSubNodeNames() : array { + return ['items']; + } + + public function getType() : string { + return 'Expr_List'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php new file mode 100644 index 00000000..e0fe3271 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php @@ -0,0 +1,40 @@ +var = $var; + $this->name = \is_string($name) ? new Identifier($name) : $name; + $this->args = $args; + } + + public function getSubNodeNames() : array { + return ['var', 'name', 'args']; + } + + public function getType() : string { + return 'Expr_MethodCall'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php new file mode 100644 index 00000000..f4380082 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php @@ -0,0 +1,35 @@ +class = $class; + $this->args = $args; + } + + public function getSubNodeNames() : array { + return ['class', 'args']; + } + + public function getType() : string { + return 'Expr_New'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php new file mode 100644 index 00000000..c3f21a2c --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php @@ -0,0 +1,30 @@ +var = $var; + } + + public function getSubNodeNames() : array { + return ['var']; + } + + public function getType() : string { + return 'Expr_PostDec'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php new file mode 100644 index 00000000..e8b07d80 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php @@ -0,0 +1,30 @@ +var = $var; + } + + public function getSubNodeNames() : array { + return ['var']; + } + + public function getType() : string { + return 'Expr_PostInc'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php new file mode 100644 index 00000000..d31b2580 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php @@ -0,0 +1,30 @@ +var = $var; + } + + public function getSubNodeNames() : array { + return ['var']; + } + + public function getType() : string { + return 'Expr_PreDec'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php new file mode 100644 index 00000000..68be695b --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php @@ -0,0 +1,30 @@ +var = $var; + } + + public function getSubNodeNames() : array { + return ['var']; + } + + public function getType() : string { + return 'Expr_PreInc'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php new file mode 100644 index 00000000..9d514e65 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Print'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php new file mode 100644 index 00000000..90efef3d --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php @@ -0,0 +1,35 @@ +var = $var; + $this->name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames() : array { + return ['var', 'name']; + } + + public function getType() : string { + return 'Expr_PropertyFetch'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php new file mode 100644 index 00000000..59708d66 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php @@ -0,0 +1,30 @@ +parts = $parts; + } + + public function getSubNodeNames() : array { + return ['parts']; + } + + public function getType() : string { + return 'Expr_ShellExec'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php new file mode 100644 index 00000000..e467c221 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php @@ -0,0 +1,40 @@ +class = $class; + $this->name = \is_string($name) ? new Identifier($name) : $name; + $this->args = $args; + } + + public function getSubNodeNames() : array { + return ['class', 'name', 'args']; + } + + public function getType() : string { + return 'Expr_StaticCall'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php new file mode 100644 index 00000000..809b6662 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php @@ -0,0 +1,36 @@ +class = $class; + $this->name = \is_string($name) ? new VarLikeIdentifier($name) : $name; + } + + public function getSubNodeNames() : array { + return ['class', 'name']; + } + + public function getType() : string { + return 'Expr_StaticPropertyFetch'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php new file mode 100644 index 00000000..cb36145e --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php @@ -0,0 +1,38 @@ +cond = $cond; + $this->if = $if; + $this->else = $else; + } + + public function getSubNodeNames() : array { + return ['cond', 'if', 'else']; + } + + public function getType() : string { + return 'Expr_Ternary'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php new file mode 100644 index 00000000..90be0e05 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_UnaryMinus'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php new file mode 100644 index 00000000..1a5bc632 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_UnaryPlus'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php new file mode 100644 index 00000000..b100f214 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php @@ -0,0 +1,30 @@ +name = $name; + } + + public function getSubNodeNames() : array { + return ['name']; + } + + public function getType() : string { + return 'Expr_Variable'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php new file mode 100644 index 00000000..ab3a2754 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_YieldFrom'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php new file mode 100644 index 00000000..a28a701a --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php @@ -0,0 +1,34 @@ +key = $key; + $this->value = $value; + } + + public function getSubNodeNames() : array { + return ['key', 'value']; + } + + public function getType() : string { + return 'Expr_Yield'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php b/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php new file mode 100644 index 00000000..d574e020 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php @@ -0,0 +1,36 @@ + true, + 'parent' => true, + 'static' => true, + ]; + + /** + * Constructs an identifier node. + * + * @param string $name Identifier as string + * @param array $attributes Additional attributes + */ + public function __construct(string $name, array $attributes = []) { + parent::__construct($attributes); + $this->name = $name; + } + + public function getSubNodeNames() : array { + return ['name']; + } + + /** + * Get identifier as string. + * + * @return string Identifier as string. + */ + public function toString() : string { + return $this->name; + } + + /** + * Get lowercased identifier as string. + * + * @return string Lowercased identifier as string + */ + public function toLowerString() : string { + return strtolower($this->name); + } + + /** + * Checks whether the identifier is a special class name (self, parent or static). + * + * @return bool Whether identifier is a special class name + */ + public function isSpecialClassName() : bool { + return isset(self::$specialClassNames[strtolower($this->name)]); + } + + /** + * Get identifier as string. + * + * @return string Identifier as string + */ + public function __toString() : string { + return $this->name; + } + + public function getType() : string { + return 'Identifier'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php new file mode 100644 index 00000000..5d923d02 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php @@ -0,0 +1,244 @@ + true, + 'parent' => true, + 'static' => true, + ]; + + /** + * Constructs a name node. + * + * @param string|string[]|self $name Name as string, part array or Name instance (copy ctor) + * @param array $attributes Additional attributes + */ + public function __construct($name, array $attributes = []) { + parent::__construct($attributes); + $this->parts = self::prepareName($name); + } + + public function getSubNodeNames() : array { + return ['parts']; + } + + /** + * Gets the first part of the name, i.e. everything before the first namespace separator. + * + * @return string First part of the name + */ + public function getFirst() : string { + return $this->parts[0]; + } + + /** + * Gets the last part of the name, i.e. everything after the last namespace separator. + * + * @return string Last part of the name + */ + public function getLast() : string { + return $this->parts[count($this->parts) - 1]; + } + + /** + * Checks whether the name is unqualified. (E.g. Name) + * + * @return bool Whether the name is unqualified + */ + public function isUnqualified() : bool { + return 1 === count($this->parts); + } + + /** + * Checks whether the name is qualified. (E.g. Name\Name) + * + * @return bool Whether the name is qualified + */ + public function isQualified() : bool { + return 1 < count($this->parts); + } + + /** + * Checks whether the name is fully qualified. (E.g. \Name) + * + * @return bool Whether the name is fully qualified + */ + public function isFullyQualified() : bool { + return false; + } + + /** + * Checks whether the name is explicitly relative to the current namespace. (E.g. namespace\Name) + * + * @return bool Whether the name is relative + */ + public function isRelative() : bool { + return false; + } + + /** + * Returns a string representation of the name itself, without taking taking the name type into + * account (e.g., not including a leading backslash for fully qualified names). + * + * @return string String representation + */ + public function toString() : string { + return implode('\\', $this->parts); + } + + /** + * Returns a string representation of the name as it would occur in code (e.g., including + * leading backslash for fully qualified names. + * + * @return string String representation + */ + public function toCodeString() : string { + return $this->toString(); + } + + /** + * Returns lowercased string representation of the name, without taking the name type into + * account (e.g., no leading backslash for fully qualified names). + * + * @return string Lowercased string representation + */ + public function toLowerString() : string { + return strtolower(implode('\\', $this->parts)); + } + + /** + * Checks whether the identifier is a special class name (self, parent or static). + * + * @return bool Whether identifier is a special class name + */ + public function isSpecialClassName() : bool { + return count($this->parts) === 1 + && isset(self::$specialClassNames[strtolower($this->parts[0])]); + } + + /** + * Returns a string representation of the name by imploding the namespace parts with the + * namespace separator. + * + * @return string String representation + */ + public function __toString() : string { + return implode('\\', $this->parts); + } + + /** + * Gets a slice of a name (similar to array_slice). + * + * This method returns a new instance of the same type as the original and with the same + * attributes. + * + * If the slice is empty, null is returned. The null value will be correctly handled in + * concatenations using concat(). + * + * Offset and length have the same meaning as in array_slice(). + * + * @param int $offset Offset to start the slice at (may be negative) + * @param int|null $length Length of the slice (may be negative) + * + * @return static|null Sliced name + */ + public function slice(int $offset, int $length = null) { + $numParts = count($this->parts); + + $realOffset = $offset < 0 ? $offset + $numParts : $offset; + if ($realOffset < 0 || $realOffset > $numParts) { + throw new \OutOfBoundsException(sprintf('Offset %d is out of bounds', $offset)); + } + + if (null === $length) { + $realLength = $numParts - $realOffset; + } else { + $realLength = $length < 0 ? $length + $numParts - $realOffset : $length; + if ($realLength < 0 || $realLength > $numParts) { + throw new \OutOfBoundsException(sprintf('Length %d is out of bounds', $length)); + } + } + + if ($realLength === 0) { + // Empty slice is represented as null + return null; + } + + return new static(array_slice($this->parts, $realOffset, $realLength), $this->attributes); + } + + /** + * Concatenate two names, yielding a new Name instance. + * + * The type of the generated instance depends on which class this method is called on, for + * example Name\FullyQualified::concat() will yield a Name\FullyQualified instance. + * + * If one of the arguments is null, a new instance of the other name will be returned. If both + * arguments are null, null will be returned. As such, writing + * Name::concat($namespace, $shortName) + * where $namespace is a Name node or null will work as expected. + * + * @param string|string[]|self|null $name1 The first name + * @param string|string[]|self|null $name2 The second name + * @param array $attributes Attributes to assign to concatenated name + * + * @return static|null Concatenated name + */ + public static function concat($name1, $name2, array $attributes = []) { + if (null === $name1 && null === $name2) { + return null; + } elseif (null === $name1) { + return new static(self::prepareName($name2), $attributes); + } elseif (null === $name2) { + return new static(self::prepareName($name1), $attributes); + } else { + return new static( + array_merge(self::prepareName($name1), self::prepareName($name2)), $attributes + ); + } + } + + /** + * Prepares a (string, array or Name node) name for use in name changing methods by converting + * it to an array. + * + * @param string|string[]|self $name Name to prepare + * + * @return string[] Prepared name + */ + private static function prepareName($name) : array { + if (\is_string($name)) { + if ('' === $name) { + throw new \InvalidArgumentException('Name cannot be empty'); + } + + return explode('\\', $name); + } elseif (\is_array($name)) { + if (empty($name)) { + throw new \InvalidArgumentException('Name cannot be empty'); + } + + return $name; + } elseif ($name instanceof self) { + return $name->parts; + } + + throw new \InvalidArgumentException( + 'Expected string, array of parts or Name instance' + ); + } + + public function getType() : string { + return 'Name'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php new file mode 100644 index 00000000..1df93a56 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php @@ -0,0 +1,50 @@ +toString(); + } + + public function getType() : string { + return 'Name_FullyQualified'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php new file mode 100644 index 00000000..57bf7af2 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php @@ -0,0 +1,50 @@ +toString(); + } + + public function getType() : string { + return 'Name_Relative'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php b/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php new file mode 100644 index 00000000..3679269e --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php @@ -0,0 +1,30 @@ +type = \is_string($type) ? new Identifier($type) : $type; + } + + public function getSubNodeNames() : array { + return ['type']; + } + + public function getType() : string { + return 'NullableType'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php new file mode 100644 index 00000000..37d99392 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php @@ -0,0 +1,49 @@ +type = \is_string($type) ? new Identifier($type) : $type; + $this->byRef = $byRef; + $this->variadic = $variadic; + $this->var = $var; + $this->default = $default; + } + + public function getSubNodeNames() : array { + return ['type', 'byRef', 'variadic', 'var', 'default']; + } + + public function getType() : string { + return 'Param'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php new file mode 100644 index 00000000..8117909b --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php @@ -0,0 +1,7 @@ +value = $value; + } + + public function getSubNodeNames() : array { + return ['value']; + } + + /** + * @internal + * + * Parses a DNUMBER token like PHP would. + * + * @param string $str A string number + * + * @return float The parsed number + */ + public static function parse(string $str) : float { + // if string contains any of .eE just cast it to float + if (false !== strpbrk($str, '.eE')) { + return (float) $str; + } + + // otherwise it's an integer notation that overflowed into a float + // if it starts with 0 it's one of the special integer notations + if ('0' === $str[0]) { + // hex + if ('x' === $str[1] || 'X' === $str[1]) { + return hexdec($str); + } + + // bin + if ('b' === $str[1] || 'B' === $str[1]) { + return bindec($str); + } + + // oct + // substr($str, 0, strcspn($str, '89')) cuts the string at the first invalid digit (8 or 9) + // so that only the digits before that are used + return octdec(substr($str, 0, strcspn($str, '89'))); + } + + // dec + return (float) $str; + } + + public function getType() : string { + return 'Scalar_DNumber'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php new file mode 100644 index 00000000..0541a31e --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php @@ -0,0 +1,31 @@ +parts = $parts; + } + + public function getSubNodeNames() : array { + return ['parts']; + } + + public function getType() : string { + return 'Scalar_Encapsed'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php new file mode 100644 index 00000000..89048e21 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php @@ -0,0 +1,30 @@ +value = $value; + } + + public function getSubNodeNames() : array { + return ['value']; + } + + public function getType() : string { + return 'Scalar_EncapsedStringPart'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php new file mode 100644 index 00000000..7b9ec5e9 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php @@ -0,0 +1,71 @@ +value = $value; + } + + public function getSubNodeNames() : array { + return ['value']; + } + + /** + * Constructs an LNumber node from a string number literal. + * + * @param string $str String number literal (decimal, octal, hex or binary) + * @param array $attributes Additional attributes + * @param bool $allowInvalidOctal Whether to allow invalid octal numbers (PHP 5) + * + * @return LNumber The constructed LNumber, including kind attribute + */ + public static function fromString(string $str, array $attributes = [], bool $allowInvalidOctal = false) : LNumber { + if ('0' !== $str[0] || '0' === $str) { + $attributes['kind'] = LNumber::KIND_DEC; + return new LNumber((int) $str, $attributes); + } + + if ('x' === $str[1] || 'X' === $str[1]) { + $attributes['kind'] = LNumber::KIND_HEX; + return new LNumber(hexdec($str), $attributes); + } + + if ('b' === $str[1] || 'B' === $str[1]) { + $attributes['kind'] = LNumber::KIND_BIN; + return new LNumber(bindec($str), $attributes); + } + + if (!$allowInvalidOctal && strpbrk($str, '89')) { + throw new Error('Invalid numeric literal', $attributes); + } + + // use intval instead of octdec to get proper cutting behavior with malformed numbers + $attributes['kind'] = LNumber::KIND_OCT; + return new LNumber(intval($str, 8), $attributes); + } + + public function getType() : string { + return 'Scalar_LNumber'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php new file mode 100644 index 00000000..841f4f8b --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php @@ -0,0 +1,28 @@ + '\\', + '$' => '$', + 'n' => "\n", + 'r' => "\r", + 't' => "\t", + 'f' => "\f", + 'v' => "\v", + 'e' => "\x1B", + ]; + + /** + * Constructs a string scalar node. + * + * @param string $value Value of the string + * @param array $attributes Additional attributes + */ + public function __construct(string $value, array $attributes = []) { + parent::__construct($attributes); + $this->value = $value; + } + + public function getSubNodeNames() : array { + return ['value']; + } + + /** + * @internal + * + * Parses a string token. + * + * @param string $str String token content + * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes + * + * @return string The parsed string + */ + public static function parse(string $str, bool $parseUnicodeEscape = true) : string { + $bLength = 0; + if ('b' === $str[0] || 'B' === $str[0]) { + $bLength = 1; + } + + if ('\'' === $str[$bLength]) { + return str_replace( + ['\\\\', '\\\''], + ['\\', '\''], + substr($str, $bLength + 1, -1) + ); + } else { + return self::parseEscapeSequences( + substr($str, $bLength + 1, -1), '"', $parseUnicodeEscape + ); + } + } + + /** + * @internal + * + * Parses escape sequences in strings (all string types apart from single quoted). + * + * @param string $str String without quotes + * @param null|string $quote Quote type + * @param bool $parseUnicodeEscape Whether to parse PHP 7 \u escapes + * + * @return string String with escape sequences parsed + */ + public static function parseEscapeSequences(string $str, $quote, bool $parseUnicodeEscape = true) : string { + if (null !== $quote) { + $str = str_replace('\\' . $quote, $quote, $str); + } + + $extra = ''; + if ($parseUnicodeEscape) { + $extra = '|u\{([0-9a-fA-F]+)\}'; + } + + return preg_replace_callback( + '~\\\\([\\\\$nrtfve]|[xX][0-9a-fA-F]{1,2}|[0-7]{1,3}' . $extra . ')~', + function($matches) { + $str = $matches[1]; + + if (isset(self::$replacements[$str])) { + return self::$replacements[$str]; + } elseif ('x' === $str[0] || 'X' === $str[0]) { + return chr(hexdec($str)); + } elseif ('u' === $str[0]) { + return self::codePointToUtf8(hexdec($matches[2])); + } else { + return chr(octdec($str)); + } + }, + $str + ); + } + + /** + * Converts a Unicode code point to its UTF-8 encoded representation. + * + * @param int $num Code point + * + * @return string UTF-8 representation of code point + */ + private static function codePointToUtf8(int $num) : string { + if ($num <= 0x7F) { + return chr($num); + } + if ($num <= 0x7FF) { + return chr(($num>>6) + 0xC0) . chr(($num&0x3F) + 0x80); + } + if ($num <= 0xFFFF) { + return chr(($num>>12) + 0xE0) . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80); + } + if ($num <= 0x1FFFFF) { + return chr(($num>>18) + 0xF0) . chr((($num>>12)&0x3F) + 0x80) + . chr((($num>>6)&0x3F) + 0x80) . chr(($num&0x3F) + 0x80); + } + throw new Error('Invalid UTF-8 codepoint escape sequence: Codepoint too large'); + } + + public function getType() : string { + return 'Scalar_String'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php new file mode 100644 index 00000000..69d33e57 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php @@ -0,0 +1,9 @@ +num = $num; + } + + public function getSubNodeNames() : array { + return ['num']; + } + + public function getType() : string { + return 'Stmt_Break'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php new file mode 100644 index 00000000..81952be0 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php @@ -0,0 +1,34 @@ +cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['cond', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Case'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php new file mode 100644 index 00000000..49cecf39 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php @@ -0,0 +1,41 @@ +types = $types; + $this->var = $var; + $this->stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['types', 'var', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Catch'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php new file mode 100644 index 00000000..ff2f40d2 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php @@ -0,0 +1,62 @@ +flags = $flags; + $this->consts = $consts; + } + + public function getSubNodeNames() : array { + return ['flags', 'consts']; + } + + /** + * Whether constant is explicitly or implicitly public. + * + * @return bool + */ + public function isPublic() : bool { + return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 + || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + } + + /** + * Whether constant is protected. + * + * @return bool + */ + public function isProtected() : bool { + return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + } + + /** + * Whether constant is private. + * + * @return bool + */ + public function isPrivate() : bool { + return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + } + + public function getType() : string { + return 'Stmt_ClassConst'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php new file mode 100644 index 00000000..31cd66ac --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php @@ -0,0 +1,48 @@ +stmts as $stmt) { + if ($stmt instanceof ClassMethod) { + $methods[] = $stmt; + } + } + return $methods; + } + + /** + * Gets method with the given name defined directly in this class/interface/trait. + * + * @param string $name Name of the method (compared case-insensitively) + * + * @return ClassMethod|null Method node or null if the method does not exist + */ + public function getMethod(string $name) { + $lowerName = strtolower($name); + foreach ($this->stmts as $stmt) { + if ($stmt instanceof ClassMethod && $lowerName === $stmt->name->toLowerString()) { + return $stmt; + } + } + return null; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php new file mode 100644 index 00000000..550b54ba --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php @@ -0,0 +1,151 @@ + true, + '__destruct' => true, + '__call' => true, + '__callstatic' => true, + '__get' => true, + '__set' => true, + '__isset' => true, + '__unset' => true, + '__sleep' => true, + '__wakeup' => true, + '__tostring' => true, + '__set_state' => true, + '__clone' => true, + '__invoke' => true, + '__debuginfo' => true, + ]; + + /** + * Constructs a class method node. + * + * @param string|Node\Identifier $name Name + * @param array $subNodes Array of the following optional subnodes: + * 'flags => MODIFIER_PUBLIC: Flags + * 'byRef' => false : Whether to return by reference + * 'params' => array() : Parameters + * 'returnType' => null : Return type + * 'stmts' => array() : Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0; + $this->byRef = $subNodes['byRef'] ?? false; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->params = $subNodes['params'] ?? []; + $returnType = $subNodes['returnType'] ?? null; + $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : []; + } + + public function getSubNodeNames() : array { + return ['flags', 'byRef', 'name', 'params', 'returnType', 'stmts']; + } + + public function returnsByRef() : bool { + return $this->byRef; + } + + public function getParams() : array { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + public function getStmts() { + return $this->stmts; + } + + /** + * Whether the method is explicitly or implicitly public. + * + * @return bool + */ + public function isPublic() : bool { + return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 + || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + } + + /** + * Whether the method is protected. + * + * @return bool + */ + public function isProtected() : bool { + return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + } + + /** + * Whether the method is private. + * + * @return bool + */ + public function isPrivate() : bool { + return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + } + + /** + * Whether the method is abstract. + * + * @return bool + */ + public function isAbstract() : bool { + return (bool) ($this->flags & Class_::MODIFIER_ABSTRACT); + } + + /** + * Whether the method is final. + * + * @return bool + */ + public function isFinal() : bool { + return (bool) ($this->flags & Class_::MODIFIER_FINAL); + } + + /** + * Whether the method is static. + * + * @return bool + */ + public function isStatic() : bool { + return (bool) ($this->flags & Class_::MODIFIER_STATIC); + } + + /** + * Whether the method is magic. + * + * @return bool + */ + public function isMagic() : bool { + return isset(self::$magicNames[$this->name->toLowerString()]); + } + + public function getType() : string { + return 'Stmt_ClassMethod'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php new file mode 100644 index 00000000..78bd1957 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php @@ -0,0 +1,105 @@ + 0 : Flags + * 'extends' => null : Name of extended class + * 'implements' => array(): Names of implemented interfaces + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->extends = $subNodes['extends'] ?? null; + $this->implements = $subNodes['implements'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames() : array { + return ['flags', 'name', 'extends', 'implements', 'stmts']; + } + + /** + * Whether the class is explicitly abstract. + * + * @return bool + */ + public function isAbstract() : bool { + return (bool) ($this->flags & self::MODIFIER_ABSTRACT); + } + + /** + * Whether the class is final. + * + * @return bool + */ + public function isFinal() : bool { + return (bool) ($this->flags & self::MODIFIER_FINAL); + } + + /** + * Whether the class is anonymous. + * + * @return bool + */ + public function isAnonymous() : bool { + return null === $this->name; + } + + /** + * @internal + */ + public static function verifyModifier($a, $b) { + if ($a & self::VISIBILITY_MODIFIER_MASK && $b & self::VISIBILITY_MODIFIER_MASK) { + throw new Error('Multiple access type modifiers are not allowed'); + } + + if ($a & self::MODIFIER_ABSTRACT && $b & self::MODIFIER_ABSTRACT) { + throw new Error('Multiple abstract modifiers are not allowed'); + } + + if ($a & self::MODIFIER_STATIC && $b & self::MODIFIER_STATIC) { + throw new Error('Multiple static modifiers are not allowed'); + } + + if ($a & self::MODIFIER_FINAL && $b & self::MODIFIER_FINAL) { + throw new Error('Multiple final modifiers are not allowed'); + } + + if ($a & 48 && $b & 48) { + throw new Error('Cannot use the final modifier on an abstract class member'); + } + } + + public function getType() : string { + return 'Stmt_Class'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php new file mode 100644 index 00000000..c1786bed --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php @@ -0,0 +1,30 @@ +consts = $consts; + } + + public function getSubNodeNames() : array { + return ['consts']; + } + + public function getType() : string { + return 'Stmt_Const'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php new file mode 100644 index 00000000..7e143ac9 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php @@ -0,0 +1,30 @@ +num = $num; + } + + public function getSubNodeNames() : array { + return ['num']; + } + + public function getType() : string { + return 'Stmt_Continue'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php new file mode 100644 index 00000000..40bec303 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php @@ -0,0 +1,34 @@ +value pair node. + * + * @param string|Node\Identifier $key Key + * @param Node\Expr $value Value + * @param array $attributes Additional attributes + */ + public function __construct($key, Node\Expr $value, array $attributes = []) { + parent::__construct($attributes); + $this->key = \is_string($key) ? new Node\Identifier($key) : $key; + $this->value = $value; + } + + public function getSubNodeNames() : array { + return ['key', 'value']; + } + + public function getType() : string { + return 'Stmt_DeclareDeclare'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php new file mode 100644 index 00000000..305e07d5 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php @@ -0,0 +1,34 @@ +declares = $declares; + $this->stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['declares', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Declare'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php new file mode 100644 index 00000000..778c7398 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php @@ -0,0 +1,34 @@ +cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['stmts', 'cond']; + } + + public function getType() : string { + return 'Stmt_Do'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php new file mode 100644 index 00000000..9c35c616 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php @@ -0,0 +1,30 @@ +exprs = $exprs; + } + + public function getSubNodeNames() : array { + return ['exprs']; + } + + public function getType() : string { + return 'Stmt_Echo'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php new file mode 100644 index 00000000..f518d512 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php @@ -0,0 +1,34 @@ +cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['cond', 'stmts']; + } + + public function getType() : string { + return 'Stmt_ElseIf'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php new file mode 100644 index 00000000..c7015c69 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php @@ -0,0 +1,30 @@ +stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['stmts']; + } + + public function getType() : string { + return 'Stmt_Else'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php new file mode 100644 index 00000000..1e2aa394 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php @@ -0,0 +1,33 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Stmt_Expression'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php new file mode 100644 index 00000000..0498f5bf --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php @@ -0,0 +1,30 @@ +stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['stmts']; + } + + public function getType() : string { + return 'Stmt_Finally'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php new file mode 100644 index 00000000..3e208914 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php @@ -0,0 +1,43 @@ + array(): Init expressions + * 'cond' => array(): Loop conditions + * 'loop' => array(): Loop expressions + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct(array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->init = $subNodes['init'] ?? []; + $this->cond = $subNodes['cond'] ?? []; + $this->loop = $subNodes['loop'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames() : array { + return ['init', 'cond', 'loop', 'stmts']; + } + + public function getType() : string { + return 'Stmt_For'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php new file mode 100644 index 00000000..9c8e88f8 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php @@ -0,0 +1,47 @@ + null : Variable to assign key to + * 'byRef' => false : Whether to assign value by reference + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->expr = $expr; + $this->keyVar = $subNodes['keyVar'] ?? null; + $this->byRef = $subNodes['byRef'] ?? false; + $this->valueVar = $valueVar; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames() : array { + return ['expr', 'keyVar', 'byRef', 'valueVar', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Foreach'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php new file mode 100644 index 00000000..a0bd2570 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php @@ -0,0 +1,69 @@ + false : Whether to return by reference + * 'params' => array(): Parameters + * 'returnType' => null : Return type + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->byRef = $subNodes['byRef'] ?? false; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->params = $subNodes['params'] ?? []; + $returnType = $subNodes['returnType'] ?? null; + $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames() : array { + return ['byRef', 'name', 'params', 'returnType', 'stmts']; + } + + public function returnsByRef() : bool { + return $this->byRef; + } + + public function getParams() : array { + return $this->params; + } + + public function getReturnType() { + return $this->returnType; + } + + /** @return Node\Stmt[] */ + public function getStmts() : array { + return $this->stmts; + } + + public function getType() : string { + return 'Stmt_Function'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php new file mode 100644 index 00000000..8e616487 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php @@ -0,0 +1,30 @@ +vars = $vars; + } + + public function getSubNodeNames() : array { + return ['vars']; + } + + public function getType() : string { + return 'Stmt_Global'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php new file mode 100644 index 00000000..35052b8a --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php @@ -0,0 +1,31 @@ +name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames() : array { + return ['name']; + } + + public function getType() : string { + return 'Stmt_Goto'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php new file mode 100644 index 00000000..e0d7e604 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php @@ -0,0 +1,39 @@ +type = $type; + $this->prefix = $prefix; + $this->uses = $uses; + } + + public function getSubNodeNames() : array { + return ['type', 'prefix', 'uses']; + } + + public function getType() : string { + return 'Stmt_GroupUse'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php new file mode 100644 index 00000000..c86d71e1 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php @@ -0,0 +1,30 @@ +remaining = $remaining; + } + + public function getSubNodeNames() : array { + return ['remaining']; + } + + public function getType() : string { + return 'Stmt_HaltCompiler'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php new file mode 100644 index 00000000..87cd313b --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php @@ -0,0 +1,43 @@ + array(): Statements + * 'elseifs' => array(): Elseif clauses + * 'else' => null : Else clause + * @param array $attributes Additional attributes + */ + public function __construct(Node\Expr $cond, array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->cond = $cond; + $this->stmts = $subNodes['stmts'] ?? []; + $this->elseifs = $subNodes['elseifs'] ?? []; + $this->else = $subNodes['else'] ?? null; + } + + public function getSubNodeNames() : array { + return ['cond', 'stmts', 'elseifs', 'else']; + } + + public function getType() : string { + return 'Stmt_If'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php new file mode 100644 index 00000000..1dec989f --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php @@ -0,0 +1,30 @@ +value = $value; + } + + public function getSubNodeNames() : array { + return ['value']; + } + + public function getType() : string { + return 'Stmt_InlineHTML'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php new file mode 100644 index 00000000..39049aae --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php @@ -0,0 +1,35 @@ + array(): Name of extended interfaces + * 'stmts' => array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->extends = $subNodes['extends'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames() : array { + return ['name', 'extends', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Interface'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php new file mode 100644 index 00000000..332043ba --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php @@ -0,0 +1,31 @@ +name = \is_string($name) ? new Identifier($name) : $name; + } + + public function getSubNodeNames() : array { + return ['name']; + } + + public function getType() : string { + return 'Stmt_Label'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php new file mode 100644 index 00000000..f113998d --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php @@ -0,0 +1,38 @@ +name = $name; + $this->stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['name', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Namespace'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php new file mode 100644 index 00000000..f86f8df7 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php @@ -0,0 +1,17 @@ +flags = $flags; + $this->props = $props; + $this->type = \is_string($type) ? new Identifier($type) : $type; + } + + public function getSubNodeNames() : array { + return ['flags', 'type', 'props']; + } + + /** + * Whether the property is explicitly or implicitly public. + * + * @return bool + */ + public function isPublic() : bool { + return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 + || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; + } + + /** + * Whether the property is protected. + * + * @return bool + */ + public function isProtected() : bool { + return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); + } + + /** + * Whether the property is private. + * + * @return bool + */ + public function isPrivate() : bool { + return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); + } + + /** + * Whether the property is static. + * + * @return bool + */ + public function isStatic() : bool { + return (bool) ($this->flags & Class_::MODIFIER_STATIC); + } + + public function getType() : string { + return 'Stmt_Property'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php new file mode 100644 index 00000000..45e26faa --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php @@ -0,0 +1,34 @@ +name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name; + $this->default = $default; + } + + public function getSubNodeNames() : array { + return ['name', 'default']; + } + + public function getType() : string { + return 'Stmt_PropertyProperty'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php new file mode 100644 index 00000000..346f9bd8 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Stmt_Return'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php new file mode 100644 index 00000000..7fbb7de1 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php @@ -0,0 +1,37 @@ +var = $var; + $this->default = $default; + } + + public function getSubNodeNames() : array { + return ['var', 'default']; + } + + public function getType() : string { + return 'Stmt_StaticVar'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php new file mode 100644 index 00000000..e408f51f --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php @@ -0,0 +1,30 @@ +vars = $vars; + } + + public function getSubNodeNames() : array { + return ['vars']; + } + + public function getType() : string { + return 'Stmt_Static'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php new file mode 100644 index 00000000..ff2ba0d9 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php @@ -0,0 +1,34 @@ +cond = $cond; + $this->cases = $cases; + } + + public function getSubNodeNames() : array { + return ['cond', 'cases']; + } + + public function getType() : string { + return 'Stmt_Switch'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php new file mode 100644 index 00000000..21709bf7 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php @@ -0,0 +1,30 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Stmt_Throw'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php new file mode 100644 index 00000000..43c66b8d --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php @@ -0,0 +1,34 @@ +traits = $traits; + $this->adaptations = $adaptations; + } + + public function getSubNodeNames() : array { + return ['traits', 'adaptations']; + } + + public function getType() : string { + return 'Stmt_TraitUse'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php new file mode 100644 index 00000000..8bdd2c04 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php @@ -0,0 +1,13 @@ +trait = $trait; + $this->method = \is_string($method) ? new Node\Identifier($method) : $method; + $this->newModifier = $newModifier; + $this->newName = \is_string($newName) ? new Node\Identifier($newName) : $newName; + } + + public function getSubNodeNames() : array { + return ['trait', 'method', 'newModifier', 'newName']; + } + + public function getType() : string { + return 'Stmt_TraitUseAdaptation_Alias'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php new file mode 100644 index 00000000..2ec6bff2 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php @@ -0,0 +1,34 @@ +trait = $trait; + $this->method = \is_string($method) ? new Node\Identifier($method) : $method; + $this->insteadof = $insteadof; + } + + public function getSubNodeNames() : array { + return ['trait', 'method', 'insteadof']; + } + + public function getType() : string { + return 'Stmt_TraitUseAdaptation_Precedence'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php new file mode 100644 index 00000000..83980a76 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php @@ -0,0 +1,30 @@ + array(): Statements + * @param array $attributes Additional attributes + */ + public function __construct($name, array $subNodes = [], array $attributes = []) { + parent::__construct($attributes); + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->stmts = $subNodes['stmts'] ?? []; + } + + public function getSubNodeNames() : array { + return ['name', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Trait'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php new file mode 100644 index 00000000..7661ecb7 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php @@ -0,0 +1,38 @@ +stmts = $stmts; + $this->catches = $catches; + $this->finally = $finally; + } + + public function getSubNodeNames() : array { + return ['stmts', 'catches', 'finally']; + } + + public function getType() : string { + return 'Stmt_TryCatch'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php new file mode 100644 index 00000000..8bd2d7d6 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php @@ -0,0 +1,30 @@ +vars = $vars; + } + + public function getSubNodeNames() : array { + return ['vars']; + } + + public function getType() : string { + return 'Stmt_Unset'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php new file mode 100644 index 00000000..fe588d2c --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php @@ -0,0 +1,52 @@ +type = $type; + $this->name = $name; + $this->alias = \is_string($alias) ? new Identifier($alias) : $alias; + } + + public function getSubNodeNames() : array { + return ['type', 'name', 'alias']; + } + + /** + * Get alias. If not explicitly given this is the last component of the used name. + * + * @return Identifier + */ + public function getAlias() : Identifier { + if (null !== $this->alias) { + return $this->alias; + } + + return new Identifier($this->name->getLast()); + } + + public function getType() : string { + return 'Stmt_UseUse'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php new file mode 100644 index 00000000..dafc1090 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php @@ -0,0 +1,47 @@ +type = $type; + $this->uses = $uses; + } + + public function getSubNodeNames() : array { + return ['type', 'uses']; + } + + public function getType() : string { + return 'Stmt_Use'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php new file mode 100644 index 00000000..671207b8 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php @@ -0,0 +1,34 @@ +cond = $cond; + $this->stmts = $stmts; + } + + public function getSubNodeNames() : array { + return ['cond', 'stmts']; + } + + public function getType() : string { + return 'Stmt_While'; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php b/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php new file mode 100644 index 00000000..a30807a6 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php @@ -0,0 +1,17 @@ +attributes = $attributes; + } + + /** + * Gets line the node started in (alias of getStartLine). + * + * @return int Start line (or -1 if not available) + */ + public function getLine() : int { + return $this->attributes['startLine'] ?? -1; + } + + /** + * Gets line the node started in. + * + * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default). + * + * @return int Start line (or -1 if not available) + */ + public function getStartLine() : int { + return $this->attributes['startLine'] ?? -1; + } + + /** + * Gets the line the node ended in. + * + * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default). + * + * @return int End line (or -1 if not available) + */ + public function getEndLine() : int { + return $this->attributes['endLine'] ?? -1; + } + + /** + * Gets the token offset of the first token that is part of this node. + * + * The offset is an index into the array returned by Lexer::getTokens(). + * + * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default). + * + * @return int Token start position (or -1 if not available) + */ + public function getStartTokenPos() : int { + return $this->attributes['startTokenPos'] ?? -1; + } + + /** + * Gets the token offset of the last token that is part of this node. + * + * The offset is an index into the array returned by Lexer::getTokens(). + * + * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default). + * + * @return int Token end position (or -1 if not available) + */ + public function getEndTokenPos() : int { + return $this->attributes['endTokenPos'] ?? -1; + } + + /** + * Gets the file offset of the first character that is part of this node. + * + * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default). + * + * @return int File start position (or -1 if not available) + */ + public function getStartFilePos() : int { + return $this->attributes['startFilePos'] ?? -1; + } + + /** + * Gets the file offset of the last character that is part of this node. + * + * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default). + * + * @return int File end position (or -1 if not available) + */ + public function getEndFilePos() : int { + return $this->attributes['endFilePos'] ?? -1; + } + + /** + * Gets all comments directly preceding this node. + * + * The comments are also available through the "comments" attribute. + * + * @return Comment[] + */ + public function getComments() : array { + return $this->attributes['comments'] ?? []; + } + + /** + * Gets the doc comment of the node. + * + * The doc comment has to be the last comment associated with the node. + * + * @return null|Comment\Doc Doc comment object or null + */ + public function getDocComment() { + $comments = $this->getComments(); + if (!$comments) { + return null; + } + + $lastComment = $comments[count($comments) - 1]; + if (!$lastComment instanceof Comment\Doc) { + return null; + } + + return $lastComment; + } + + /** + * Sets the doc comment of the node. + * + * This will either replace an existing doc comment or add it to the comments array. + * + * @param Comment\Doc $docComment Doc comment to set + */ + public function setDocComment(Comment\Doc $docComment) { + $comments = $this->getComments(); + + $numComments = count($comments); + if ($numComments > 0 && $comments[$numComments - 1] instanceof Comment\Doc) { + // Replace existing doc comment + $comments[$numComments - 1] = $docComment; + } else { + // Append new comment + $comments[] = $docComment; + } + + $this->setAttribute('comments', $comments); + } + + public function setAttribute(string $key, $value) { + $this->attributes[$key] = $value; + } + + public function hasAttribute(string $key) : bool { + return array_key_exists($key, $this->attributes); + } + + public function getAttribute(string $key, $default = null) { + if (array_key_exists($key, $this->attributes)) { + return $this->attributes[$key]; + } + + return $default; + } + + public function getAttributes() : array { + return $this->attributes; + } + + public function setAttributes(array $attributes) { + $this->attributes = $attributes; + } + + /** + * @return array + */ + public function jsonSerialize() : array { + return ['nodeType' => $this->getType()] + get_object_vars($this); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php b/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php new file mode 100644 index 00000000..197ebc14 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php @@ -0,0 +1,203 @@ +dumpComments = !empty($options['dumpComments']); + $this->dumpPositions = !empty($options['dumpPositions']); + } + + /** + * Dumps a node or array. + * + * @param array|Node $node Node or array to dump + * @param string|null $code Code corresponding to dumped AST. This only needs to be passed if + * the dumpPositions option is enabled and the dumping of node offsets + * is desired. + * + * @return string Dumped value + */ + public function dump($node, string $code = null) : string { + $this->code = $code; + return $this->dumpRecursive($node); + } + + protected function dumpRecursive($node) { + if ($node instanceof Node) { + $r = $node->getType(); + if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) { + $r .= $p; + } + $r .= '('; + + foreach ($node->getSubNodeNames() as $key) { + $r .= "\n " . $key . ': '; + + $value = $node->$key; + if (null === $value) { + $r .= 'null'; + } elseif (false === $value) { + $r .= 'false'; + } elseif (true === $value) { + $r .= 'true'; + } elseif (is_scalar($value)) { + if ('flags' === $key || 'newModifier' === $key) { + $r .= $this->dumpFlags($value); + } elseif ('type' === $key && $node instanceof Include_) { + $r .= $this->dumpIncludeType($value); + } elseif ('type' === $key + && ($node instanceof Use_ || $node instanceof UseUse || $node instanceof GroupUse)) { + $r .= $this->dumpUseType($value); + } else { + $r .= $value; + } + } else { + $r .= str_replace("\n", "\n ", $this->dumpRecursive($value)); + } + } + + if ($this->dumpComments && $comments = $node->getComments()) { + $r .= "\n comments: " . str_replace("\n", "\n ", $this->dumpRecursive($comments)); + } + } elseif (is_array($node)) { + $r = 'array('; + + foreach ($node as $key => $value) { + $r .= "\n " . $key . ': '; + + if (null === $value) { + $r .= 'null'; + } elseif (false === $value) { + $r .= 'false'; + } elseif (true === $value) { + $r .= 'true'; + } elseif (is_scalar($value)) { + $r .= $value; + } else { + $r .= str_replace("\n", "\n ", $this->dumpRecursive($value)); + } + } + } elseif ($node instanceof Comment) { + return $node->getReformattedText(); + } else { + throw new \InvalidArgumentException('Can only dump nodes and arrays.'); + } + + return $r . "\n)"; + } + + protected function dumpFlags($flags) { + $strs = []; + if ($flags & Class_::MODIFIER_PUBLIC) { + $strs[] = 'MODIFIER_PUBLIC'; + } + if ($flags & Class_::MODIFIER_PROTECTED) { + $strs[] = 'MODIFIER_PROTECTED'; + } + if ($flags & Class_::MODIFIER_PRIVATE) { + $strs[] = 'MODIFIER_PRIVATE'; + } + if ($flags & Class_::MODIFIER_ABSTRACT) { + $strs[] = 'MODIFIER_ABSTRACT'; + } + if ($flags & Class_::MODIFIER_STATIC) { + $strs[] = 'MODIFIER_STATIC'; + } + if ($flags & Class_::MODIFIER_FINAL) { + $strs[] = 'MODIFIER_FINAL'; + } + + if ($strs) { + return implode(' | ', $strs) . ' (' . $flags . ')'; + } else { + return $flags; + } + } + + protected function dumpIncludeType($type) { + $map = [ + Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', + Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', + Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', + Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQUIRE_ONCE', + ]; + + if (!isset($map[$type])) { + return $type; + } + return $map[$type] . ' (' . $type . ')'; + } + + protected function dumpUseType($type) { + $map = [ + Use_::TYPE_UNKNOWN => 'TYPE_UNKNOWN', + Use_::TYPE_NORMAL => 'TYPE_NORMAL', + Use_::TYPE_FUNCTION => 'TYPE_FUNCTION', + Use_::TYPE_CONSTANT => 'TYPE_CONSTANT', + ]; + + if (!isset($map[$type])) { + return $type; + } + return $map[$type] . ' (' . $type . ')'; + } + + /** + * Dump node position, if possible. + * + * @param Node $node Node for which to dump position + * + * @return string|null Dump of position, or null if position information not available + */ + protected function dumpPosition(Node $node) { + if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) { + return null; + } + + $start = $node->getStartLine(); + $end = $node->getEndLine(); + if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos') + && null !== $this->code + ) { + $start .= ':' . $this->toColumn($this->code, $node->getStartFilePos()); + $end .= ':' . $this->toColumn($this->code, $node->getEndFilePos()); + } + return "[$start - $end]"; + } + + // Copied from Error class + private function toColumn($code, $pos) { + if ($pos > strlen($code)) { + throw new \RuntimeException('Invalid position information'); + } + + $lineStartPos = strrpos($code, "\n", $pos - strlen($code)); + if (false === $lineStartPos) { + $lineStartPos = -1; + } + + return $pos - $lineStartPos; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php b/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php new file mode 100644 index 00000000..2e7cfdad --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php @@ -0,0 +1,81 @@ +addVisitor($visitor); + $traverser->traverse($nodes); + + return $visitor->getFoundNodes(); + } + + /** + * Find all nodes that are instances of a certain class. + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param string $class Class name + * + * @return Node[] Found nodes (all instances of $class) + */ + public function findInstanceOf($nodes, string $class) : array { + return $this->find($nodes, function ($node) use ($class) { + return $node instanceof $class; + }); + } + + /** + * Find first node satisfying a filter callback. + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param callable $filter Filter callback: function(Node $node) : bool + * + * @return null|Node Found node (or null if none found) + */ + public function findFirst($nodes, callable $filter) { + if (!is_array($nodes)) { + $nodes = [$nodes]; + } + + $visitor = new FirstFindingVisitor($filter); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + $traverser->traverse($nodes); + + return $visitor->getFoundNode(); + } + + /** + * Find first node that is an instance of a certain class. + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param string $class Class name + * + * @return null|Node Found node, which is an instance of $class (or null if none found) + */ + public function findFirstInstanceOf($nodes, string $class) { + return $this->findFirst($nodes, function ($node) use ($class) { + return $node instanceof $class; + }); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php b/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php new file mode 100644 index 00000000..97d45bda --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php @@ -0,0 +1,291 @@ +visitors[] = $visitor; + } + + /** + * Removes an added visitor. + * + * @param NodeVisitor $visitor + */ + public function removeVisitor(NodeVisitor $visitor) { + foreach ($this->visitors as $index => $storedVisitor) { + if ($storedVisitor === $visitor) { + unset($this->visitors[$index]); + break; + } + } + } + + /** + * Traverses an array of nodes using the registered visitors. + * + * @param Node[] $nodes Array of nodes + * + * @return Node[] Traversed array of nodes + */ + public function traverse(array $nodes) : array { + $this->stopTraversal = false; + + foreach ($this->visitors as $visitor) { + if (null !== $return = $visitor->beforeTraverse($nodes)) { + $nodes = $return; + } + } + + $nodes = $this->traverseArray($nodes); + + foreach ($this->visitors as $visitor) { + if (null !== $return = $visitor->afterTraverse($nodes)) { + $nodes = $return; + } + } + + return $nodes; + } + + /** + * Recursively traverse a node. + * + * @param Node $node Node to traverse. + * + * @return Node Result of traversal (may be original node or new one) + */ + protected function traverseNode(Node $node) : Node { + foreach ($node->getSubNodeNames() as $name) { + $subNode =& $node->$name; + + if (\is_array($subNode)) { + $subNode = $this->traverseArray($subNode); + if ($this->stopTraversal) { + break; + } + } elseif ($subNode instanceof Node) { + $traverseChildren = true; + $breakVisitorIndex = null; + + foreach ($this->visitors as $visitorIndex => $visitor) { + $return = $visitor->enterNode($subNode); + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($subNode, $return); + $subNode = $return; + } elseif (self::DONT_TRAVERSE_CHILDREN === $return) { + $traverseChildren = false; + } elseif (self::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) { + $traverseChildren = false; + $breakVisitorIndex = $visitorIndex; + break; + } elseif (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } else { + throw new \LogicException( + 'enterNode() returned invalid value of type ' . gettype($return) + ); + } + } + } + + if ($traverseChildren) { + $subNode = $this->traverseNode($subNode); + if ($this->stopTraversal) { + break; + } + } + + foreach ($this->visitors as $visitorIndex => $visitor) { + $return = $visitor->leaveNode($subNode); + + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($subNode, $return); + $subNode = $return; + } elseif (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (\is_array($return)) { + throw new \LogicException( + 'leaveNode() may only return an array ' . + 'if the parent structure is an array' + ); + } else { + throw new \LogicException( + 'leaveNode() returned invalid value of type ' . gettype($return) + ); + } + } + + if ($breakVisitorIndex === $visitorIndex) { + break; + } + } + } + } + + return $node; + } + + /** + * Recursively traverse array (usually of nodes). + * + * @param array $nodes Array to traverse + * + * @return array Result of traversal (may be original array or changed one) + */ + protected function traverseArray(array $nodes) : array { + $doNodes = []; + + foreach ($nodes as $i => &$node) { + if ($node instanceof Node) { + $traverseChildren = true; + $breakVisitorIndex = null; + + foreach ($this->visitors as $visitorIndex => $visitor) { + $return = $visitor->enterNode($node); + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($node, $return); + $node = $return; + } elseif (self::DONT_TRAVERSE_CHILDREN === $return) { + $traverseChildren = false; + } elseif (self::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) { + $traverseChildren = false; + $breakVisitorIndex = $visitorIndex; + break; + } elseif (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } else { + throw new \LogicException( + 'enterNode() returned invalid value of type ' . gettype($return) + ); + } + } + } + + if ($traverseChildren) { + $node = $this->traverseNode($node); + if ($this->stopTraversal) { + break; + } + } + + foreach ($this->visitors as $visitorIndex => $visitor) { + $return = $visitor->leaveNode($node); + + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($node, $return); + $node = $return; + } elseif (\is_array($return)) { + $doNodes[] = [$i, $return]; + break; + } elseif (self::REMOVE_NODE === $return) { + $doNodes[] = [$i, []]; + break; + } elseif (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (false === $return) { + throw new \LogicException( + 'bool(false) return from leaveNode() no longer supported. ' . + 'Return NodeTraverser::REMOVE_NODE instead' + ); + } else { + throw new \LogicException( + 'leaveNode() returned invalid value of type ' . gettype($return) + ); + } + } + + if ($breakVisitorIndex === $visitorIndex) { + break; + } + } + } elseif (\is_array($node)) { + throw new \LogicException('Invalid node structure: Contains nested arrays'); + } + } + + if (!empty($doNodes)) { + while (list($i, $replace) = array_pop($doNodes)) { + array_splice($nodes, $i, 1, $replace); + } + } + + return $nodes; + } + + private function ensureReplacementReasonable($old, $new) { + if ($old instanceof Node\Stmt && $new instanceof Node\Expr) { + throw new \LogicException( + "Trying to replace statement ({$old->getType()}) " . + "with expression ({$new->getType()}). Are you missing a " . + "Stmt_Expression wrapper?" + ); + } + + if ($old instanceof Node\Expr && $new instanceof Node\Stmt) { + throw new \LogicException( + "Trying to replace expression ({$old->getType()}) " . + "with statement ({$new->getType()})" + ); + } + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php b/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php new file mode 100644 index 00000000..77ff3d27 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php @@ -0,0 +1,29 @@ + $node stays as-is + * * NodeTraverser::DONT_TRAVERSE_CHILDREN + * => Children of $node are not traversed. $node stays as-is + * * NodeTraverser::STOP_TRAVERSAL + * => Traversal is aborted. $node stays as-is + * * otherwise + * => $node is set to the return value + * + * @param Node $node Node + * + * @return null|int|Node Replacement node (or special return value) + */ + public function enterNode(Node $node); + + /** + * Called when leaving a node. + * + * Return value semantics: + * * null + * => $node stays as-is + * * NodeTraverser::REMOVE_NODE + * => $node is removed from the parent array + * * NodeTraverser::STOP_TRAVERSAL + * => Traversal is aborted. $node stays as-is + * * array (of Nodes) + * => The return value is merged into the parent array (at the position of the $node) + * * otherwise + * => $node is set to the return value + * + * @param Node $node Node + * + * @return null|int|Node|Node[] Replacement node (or special return value) + */ + public function leaveNode(Node $node); + + /** + * Called once after traversal. + * + * Return value semantics: + * * null: $nodes stays as-is + * * otherwise: $nodes is set to the return value + * + * @param Node[] $nodes Array of nodes + * + * @return null|Node[] Array of nodes + */ + public function afterTraverse(array $nodes); +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php new file mode 100644 index 00000000..a85fa493 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/CloningVisitor.php @@ -0,0 +1,20 @@ +setAttribute('origNode', $origNode); + return $node; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php new file mode 100644 index 00000000..9531edbc --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php @@ -0,0 +1,48 @@ +filterCallback = $filterCallback; + } + + /** + * Get found nodes satisfying the filter callback. + * + * Nodes are returned in pre-order. + * + * @return Node[] Found nodes + */ + public function getFoundNodes() : array { + return $this->foundNodes; + } + + public function beforeTraverse(array $nodes) { + $this->foundNodes = []; + + return null; + } + + public function enterNode(Node $node) { + $filterCallback = $this->filterCallback; + if ($filterCallback($node)) { + $this->foundNodes[] = $node; + } + + return null; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php new file mode 100644 index 00000000..596a7d7f --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php @@ -0,0 +1,50 @@ +filterCallback = $filterCallback; + } + + /** + * Get found node satisfying the filter callback. + * + * Returns null if no node satisfies the filter callback. + * + * @return null|Node Found node (or null if not found) + */ + public function getFoundNode() { + return $this->foundNode; + } + + public function beforeTraverse(array $nodes) { + $this->foundNode = null; + + return null; + } + + public function enterNode(Node $node) { + $filterCallback = $this->filterCallback; + if ($filterCallback($node)) { + $this->foundNode = $node; + return NodeTraverser::STOP_TRAVERSAL; + } + + return null; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php new file mode 100644 index 00000000..cfe8ce76 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php @@ -0,0 +1,221 @@ +nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing); + $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? false; + $this->replaceNodes = $options['replaceNodes'] ?? true; + } + + /** + * Get name resolution context. + * + * @return NameContext + */ + public function getNameContext() : NameContext { + return $this->nameContext; + } + + public function beforeTraverse(array $nodes) { + $this->nameContext->startNamespace(); + return null; + } + + public function enterNode(Node $node) { + if ($node instanceof Stmt\Namespace_) { + $this->nameContext->startNamespace($node->name); + } elseif ($node instanceof Stmt\Use_) { + foreach ($node->uses as $use) { + $this->addAlias($use, $node->type, null); + } + } elseif ($node instanceof Stmt\GroupUse) { + foreach ($node->uses as $use) { + $this->addAlias($use, $node->type, $node->prefix); + } + } elseif ($node instanceof Stmt\Class_) { + if (null !== $node->extends) { + $node->extends = $this->resolveClassName($node->extends); + } + + foreach ($node->implements as &$interface) { + $interface = $this->resolveClassName($interface); + } + + if (null !== $node->name) { + $this->addNamespacedName($node); + } + } elseif ($node instanceof Stmt\Interface_) { + foreach ($node->extends as &$interface) { + $interface = $this->resolveClassName($interface); + } + + $this->addNamespacedName($node); + } elseif ($node instanceof Stmt\Trait_) { + $this->addNamespacedName($node); + } elseif ($node instanceof Stmt\Function_) { + $this->addNamespacedName($node); + $this->resolveSignature($node); + } elseif ($node instanceof Stmt\ClassMethod + || $node instanceof Expr\Closure + ) { + $this->resolveSignature($node); + } elseif ($node instanceof Stmt\Property) { + if (null !== $node->type) { + $node->type = $this->resolveType($node->type); + } + } elseif ($node instanceof Stmt\Const_) { + foreach ($node->consts as $const) { + $this->addNamespacedName($const); + } + } elseif ($node instanceof Expr\StaticCall + || $node instanceof Expr\StaticPropertyFetch + || $node instanceof Expr\ClassConstFetch + || $node instanceof Expr\New_ + || $node instanceof Expr\Instanceof_ + ) { + if ($node->class instanceof Name) { + $node->class = $this->resolveClassName($node->class); + } + } elseif ($node instanceof Stmt\Catch_) { + foreach ($node->types as &$type) { + $type = $this->resolveClassName($type); + } + } elseif ($node instanceof Expr\FuncCall) { + if ($node->name instanceof Name) { + $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION); + } + } elseif ($node instanceof Expr\ConstFetch) { + $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT); + } elseif ($node instanceof Stmt\TraitUse) { + foreach ($node->traits as &$trait) { + $trait = $this->resolveClassName($trait); + } + + foreach ($node->adaptations as $adaptation) { + if (null !== $adaptation->trait) { + $adaptation->trait = $this->resolveClassName($adaptation->trait); + } + + if ($adaptation instanceof Stmt\TraitUseAdaptation\Precedence) { + foreach ($adaptation->insteadof as &$insteadof) { + $insteadof = $this->resolveClassName($insteadof); + } + } + } + } + + return null; + } + + private function addAlias(Stmt\UseUse $use, $type, Name $prefix = null) { + // Add prefix for group uses + $name = $prefix ? Name::concat($prefix, $use->name) : $use->name; + // Type is determined either by individual element or whole use declaration + $type |= $use->type; + + $this->nameContext->addAlias( + $name, (string) $use->getAlias(), $type, $use->getAttributes() + ); + } + + /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure $node */ + private function resolveSignature($node) { + foreach ($node->params as $param) { + $param->type = $this->resolveType($param->type); + } + $node->returnType = $this->resolveType($node->returnType); + } + + private function resolveType($node) { + if ($node instanceof Node\NullableType) { + $node->type = $this->resolveType($node->type); + return $node; + } + if ($node instanceof Name) { + return $this->resolveClassName($node); + } + return $node; + } + + /** + * Resolve name, according to name resolver options. + * + * @param Name $name Function or constant name to resolve + * @param int $type One of Stmt\Use_::TYPE_* + * + * @return Name Resolved name, or original name with attribute + */ + protected function resolveName(Name $name, int $type) : Name { + if (!$this->replaceNodes) { + $resolvedName = $this->nameContext->getResolvedName($name, $type); + if (null !== $resolvedName) { + $name->setAttribute('resolvedName', $resolvedName); + } else { + $name->setAttribute('namespacedName', FullyQualified::concat( + $this->nameContext->getNamespace(), $name, $name->getAttributes())); + } + return $name; + } + + if ($this->preserveOriginalNames) { + // Save the original name + $originalName = $name; + $name = clone $originalName; + $name->setAttribute('originalName', $originalName); + } + + $resolvedName = $this->nameContext->getResolvedName($name, $type); + if (null !== $resolvedName) { + return $resolvedName; + } + + // unqualified names inside a namespace cannot be resolved at compile-time + // add the namespaced version of the name as an attribute + $name->setAttribute('namespacedName', FullyQualified::concat( + $this->nameContext->getNamespace(), $name, $name->getAttributes())); + return $name; + } + + protected function resolveClassName(Name $name) { + return $this->resolveName($name, Stmt\Use_::TYPE_NORMAL); + } + + protected function addNamespacedName(Node $node) { + $node->namespacedName = Name::concat( + $this->nameContext->getNamespace(), (string) $node->name); + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php new file mode 100644 index 00000000..d378d670 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php @@ -0,0 +1,25 @@ +parsers = $parsers; + } + + public function parse(string $code, ErrorHandler $errorHandler = null) { + if (null === $errorHandler) { + $errorHandler = new ErrorHandler\Throwing; + } + + list($firstStmts, $firstError) = $this->tryParse($this->parsers[0], $errorHandler, $code); + if ($firstError === null) { + return $firstStmts; + } + + for ($i = 1, $c = count($this->parsers); $i < $c; ++$i) { + list($stmts, $error) = $this->tryParse($this->parsers[$i], $errorHandler, $code); + if ($error === null) { + return $stmts; + } + } + + throw $firstError; + } + + private function tryParse(Parser $parser, ErrorHandler $errorHandler, $code) { + $stmts = null; + $error = null; + try { + $stmts = $parser->parse($code, $errorHandler); + } catch (Error $error) {} + return [$stmts, $error]; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php new file mode 100644 index 00000000..643aa7f0 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php @@ -0,0 +1,2640 @@ +'", + "T_IS_GREATER_OR_EQUAL", + "T_SL", + "T_SR", + "'+'", + "'-'", + "'.'", + "'*'", + "'/'", + "'%'", + "'!'", + "T_INSTANCEOF", + "'~'", + "T_INC", + "T_DEC", + "T_INT_CAST", + "T_DOUBLE_CAST", + "T_STRING_CAST", + "T_ARRAY_CAST", + "T_OBJECT_CAST", + "T_BOOL_CAST", + "T_UNSET_CAST", + "'@'", + "T_POW", + "'['", + "T_NEW", + "T_CLONE", + "T_EXIT", + "T_IF", + "T_ELSEIF", + "T_ELSE", + "T_ENDIF", + "T_LNUMBER", + "T_DNUMBER", + "T_STRING", + "T_STRING_VARNAME", + "T_VARIABLE", + "T_NUM_STRING", + "T_INLINE_HTML", + "T_ENCAPSED_AND_WHITESPACE", + "T_CONSTANT_ENCAPSED_STRING", + "T_ECHO", + "T_DO", + "T_WHILE", + "T_ENDWHILE", + "T_FOR", + "T_ENDFOR", + "T_FOREACH", + "T_ENDFOREACH", + "T_DECLARE", + "T_ENDDECLARE", + "T_AS", + "T_SWITCH", + "T_ENDSWITCH", + "T_CASE", + "T_DEFAULT", + "T_BREAK", + "T_CONTINUE", + "T_GOTO", + "T_FUNCTION", + "T_CONST", + "T_RETURN", + "T_TRY", + "T_CATCH", + "T_FINALLY", + "T_THROW", + "T_USE", + "T_INSTEADOF", + "T_GLOBAL", + "T_STATIC", + "T_ABSTRACT", + "T_FINAL", + "T_PRIVATE", + "T_PROTECTED", + "T_PUBLIC", + "T_VAR", + "T_UNSET", + "T_ISSET", + "T_EMPTY", + "T_HALT_COMPILER", + "T_CLASS", + "T_TRAIT", + "T_INTERFACE", + "T_EXTENDS", + "T_IMPLEMENTS", + "T_OBJECT_OPERATOR", + "T_LIST", + "T_ARRAY", + "T_CALLABLE", + "T_CLASS_C", + "T_TRAIT_C", + "T_METHOD_C", + "T_FUNC_C", + "T_LINE", + "T_FILE", + "T_START_HEREDOC", + "T_END_HEREDOC", + "T_DOLLAR_OPEN_CURLY_BRACES", + "T_CURLY_OPEN", + "T_PAAMAYIM_NEKUDOTAYIM", + "T_NAMESPACE", + "T_NS_C", + "T_DIR", + "T_NS_SEPARATOR", + "T_ELLIPSIS", + "';'", + "'{'", + "'}'", + "'('", + "')'", + "'$'", + "'`'", + "']'", + "'\"'" + ); + + protected $tokenToSymbol = array( + 0, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 54, 157, 158, 154, 53, 36, 158, + 152, 153, 51, 48, 7, 49, 50, 52, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 30, 149, + 42, 15, 44, 29, 66, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 68, 158, 156, 35, 158, 155, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 150, 34, 151, 56, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 1, 2, 3, 4, + 5, 6, 8, 9, 10, 11, 12, 13, 14, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 31, 32, 33, 37, 38, 39, 40, 41, + 43, 45, 46, 47, 55, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 67, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 158, + 158, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 158, 158, 158, + 158, 158, 158, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148 + ); + + protected $action = array( + 679, 680, 681, 682, 683, 0, 684, 685, 686, 722, + 723, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 208, 229, 230, 231, 232, 233, 234, 235, 236, 237, + 238, 239, 240,-32766,-32766,-32766,-32766,-32766,-32766,-32766, + -32766,-32767,-32767,-32767,-32767, 124, 241, 242,-32766,-32766, + -32766,-32766,-32766, 687,-32766, 30,-32766,-32766,-32766,-32766, + -32766,-32766,-32767,-32767,-32767,-32767,-32767, 688, 689, 690, + 691, 692, 693, 694, 1185, 415, 754, 956, 957, 958, + 955, 954, 953, 695, 696, 697, 698, 699, 700, 701, + 702, 703, 704, 705, 725, 726, 727, 728, 729, 717, + 718, 719, 720, 721, 706, 707, 708, 709, 710, 711, + 712, 748, 749, 750, 751, 752, 753, 713, 714, 715, + 716, 746, 737, 735, 736, 732, 733, 281, 724, 730, + 731, 738, 739, 741, 740, 742, 743, 54, 55, 424, + 56, 57, 734, 745, 744, 423, 58, 59, 338, 60, + -32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, + -32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767, 96, 97, + 98, 99, 100, 330, 101, 102, 103, 831, 302,-32766, + -32766,-32766,-32766, 61, 62, 758, 1049, 761, 296, 63, + 104, 64, 292, 293, 65, 66, 67, 68, 69, 70, + 71, 72, 349, 26, 300, 73, 416,-32766,-32766,-32766, + 219, 1100, 1101, 758,-32766, 761,-32766,-32766,-32766, 473, + 1077, 1049, 832,-32766,-32766,-32766, 333, 283,-32766, 204, + -32766,-32766,-32766,-32766,-32766,-32766, 48,-32766, 436,-32766, + -32766,-32766,-32766,-32766,-32766, 296,-32766,-32766, 497, 352, + 422, 498, 310, 550, 432, 1199, 481, 482, 52, 437, + 446, 334, 903, 904, 298, 483, 484, -219, 1106, 1107, + 1108, 1109, 1103, 1104, 311, 498, 773, 774, 432, 498, + 1110, 1105, 432, 217, 218, 219,-32766, 41,-32766, 334, + 322, 1067, 323, 425, -125, -125, -125, -4, 832, 472, + 127, 1049, 419, 820, 204, 909, 40, 21, 426, -125, + 474, -125, 475, -125, 476, -125, 756, 427, 119, 308, + 409, 31, 32, 428, 429, 822, 33, 477, 218, 219, + 74, 421, 756, 350, 351, 478, 479,-32766,-32766,-32766, + 123, 480, 25, 879, 803, 850, 430, 431, 204, 1049, + 49, 956, 957, 958, 955, 954, 953, 127,-32766, 36, + -32766,-32766,-32766,-32766, 630, 903, 904, 299, 832, 425, + 834, 645, -125, 1200, 761, 472, 1049, 1218, 498, 820, + 447, 432, 40, 21, 426, 1185, 474, -223, 475, 10, + 476, 817, 929, 427,-32766,-32766,-32766, 31, 32, 428, + 429, 407, 33, 477, 129, 420, 74, 321, 334, 350, + 351, 478, 479, 217, 218, 219, 1049, 480,-32766,-32766, + 765, 850, 430, 431,-32766,-32766, 238, 239, 240, 51, + 631, 1150, 120, 432, 204, 29, 295, 934, 832, 425, + 210, 335, 241, 242, 772, 472, 834, 645, -4, 820, + 417, 1049, 40, 21, 426, 128, 474, 592, 475, 338, + 476, 483, 880, 427, -203, -203, -203, 31, 32, 428, + 429, 337, 33, 477, 122, 297, 74, 20,-32766, 350, + 351, 478, 479,-32766,-32766,-32766, 815, 480, 910, 246, + 803, 850, 430, 431,-32766,-32766,-32766, 9, 132, 217, + 218, 219, 583, 326,-32766, 1049,-32766,-32766,-32766, 425, + 524, 121, 948, 813, 1112, 472, 834, 645, -203, 820, + 204, 245, 40, 21, 426, 248, 474, 247, 475, 284, + 476, 930, 449, 427, -204, -204, -204, 31, 32, 428, + 429, 118, 33, 477, -254, 832, 74, 818, 209, 350, + 351, 478, 479, 811, 217, 218, 219, 480, 1151, 243, + 803, 850, 430, 431,-32766,-32766,-32766, 1112, 78, 79, + 80, 235, 236, 237, 648, 204, 98, 99, 100, 77, + 211, 1227, 131, 334, 1228,-32766, 834, 645, -204, 34, + 204, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 832, 302, 425, 217, 218, 219, + 241, 242, 472, 1049, 1049, 498, 820, 104, 432, 40, + 21, 426, 830, 474, 659, 475, 442, 476, 204, 647, + 427, 843, 126, 649, 31, 32, 428, 294, 656, 33, + 477, 461, 599, 74, 456, 22, 350, 351, 773, 774, + 832, 133, 360, 314, 480, 606, 607, 945, 665, 933, + 673, 766, 651, -82,-32766, 302, 53, 104, 614, 758, + 961, 530, 43, 44, 45, 425, 300, 46, 626, 653, + 50, 472, 47, 834, 645, 820, 130, 639, 40, 21, + 426, 759, 474, 756, 475, 604, 476, -273, 445, 427, + 761, 832,-32766, 31, 32, 428, 852, 327, 33, 477, + 586, -80, 74, 851, 329, 350, 351, 1111, 618, 1157, + 11, 425, 448, 480, 280, 603, -404, 472, 589, 440, + 662, 820, 845, 466, 40, 21, 426, 610, 474, 0, + 475, 0, 476, 0, 0, 427, 0, 832, 324, 31, + 32, 428, 834, 645, 33, 477, 0, 0, 74, 0, + 0, 350, 351, 325, 483, 309, 307, -504, -503, 480, + 0, 0, 425, 0, 0, 0, 657, 0, 472, 0, + 0, 0, 820, 14, 5, 40, 21, 426, 6, 474, + 359, 475, 668, 476, -412, 12, 427, -413, 866, 645, + 31, 32, 428, 442, 384, 33, 477, 411, 410, 74, + 385, 393, 350, 351, 373, 532, 832, 847, 425, 812, + 480, 39, 38, 882, 472, 823, 771, 821, 820, 939, + 808, 40, 21, 426, 669, 474, 770, 475, 244, 476, + 829, 938, 427, 941, 814, 769, 31, 32, 428, 834, + 645, 33, 477, 816, 828, 74, 212, 213, 350, 351, + 874, 806, 214, 940, 215, 867, 480, 864, 819, 862, + 937, 873, 1047, 331, 77, 646, 206, 650, 652, 654, + 655, 658, 660, 661, 1100, 1101, 663, 425,-32766, 664, + 332, 405, 1102, 472, 406, 834, 645, 820, 125, 42, + 40, 21, 426, 775, 474, 778, 475, 777, 476, 872, + 670, 427, 804, 1224, 460, 31, 32, 428, 1223, 1193, + 33, 477, 1191, 1176, 74, 1189, 1091, 350, 351, 921, + 1197, 1187, 871, 946, 837, 480, 1052, 846, 1051, 571, + 839, 1106, 1107, 1108, 1109, 1103, 1104, 383, 1063, 212, + 213, 776, 1225, 1110, 1105, 214, 848, 215, 767, 1028, + 216, 849,-32766, 768, 834, 645, 37, 1226, -422, 206, + 28, 414, 408, 339, 75, 76, 306, 1100, 1101, 305, + 304,-32766, 303, 27, 24, 1102, 35, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 291, 290, 282,-32766, 207, 0, 575, 1029, 1053, -220, + 1093, -219, 16, 1116, 911, 1057, 1054, 636, 565, 470, + 465, 464, 457, 378, 18, 17, 0, 285, 988, 990, + 1171, 1170, 571, 1117, 1106, 1107, 1108, 1109, 1103, 1104, + 383, 1221, 1090, 1188, 1060, 1175, 1110, 1105, 1190, 1076, + 1061, 1062, 1059, 216, 1058,-32766, 1156, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -503 + ); + + protected $actionCheck = array( + 2, 3, 4, 5, 6, 0, 8, 9, 10, 11, + 12, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 7, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 8, 9, 10, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 7, 67, 68, 32, 33, + 34, 35, 36, 55, 29, 7, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 69, 70, 71, + 72, 73, 74, 75, 80, 7, 78, 113, 114, 115, + 116, 117, 118, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 13, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 2, 3, 4, + 5, 6, 144, 145, 146, 7, 11, 12, 154, 14, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 8, + 42, 43, 44, 45, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 7, 51, 52, 53, 1, 55, 32, + 33, 34, 35, 48, 49, 78, 12, 80, 36, 54, + 67, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 7, 68, 69, 70, 71, 8, 9, 10, + 10, 76, 77, 78, 80, 80, 8, 9, 10, 84, + 113, 12, 1, 8, 9, 10, 7, 7, 29, 29, + 31, 32, 33, 34, 35, 36, 68, 29, 103, 31, + 32, 33, 34, 35, 29, 36, 31, 32, 113, 7, + 7, 144, 7, 79, 147, 1, 121, 122, 68, 152, + 30, 154, 131, 132, 7, 130, 131, 153, 133, 134, + 135, 136, 137, 138, 139, 144, 103, 104, 147, 144, + 145, 146, 147, 8, 9, 10, 152, 152, 154, 154, + 155, 153, 157, 72, 73, 74, 75, 0, 1, 78, + 148, 12, 7, 82, 29, 153, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 78, 96, 150, 129, + 147, 100, 101, 102, 103, 149, 105, 106, 9, 10, + 109, 7, 78, 112, 113, 114, 115, 8, 9, 10, + 150, 120, 7, 30, 123, 124, 125, 126, 29, 12, + 68, 113, 114, 115, 116, 117, 118, 148, 29, 13, + 31, 32, 33, 34, 78, 131, 132, 36, 1, 72, + 149, 150, 151, 153, 80, 78, 12, 83, 144, 82, + 150, 147, 85, 86, 87, 80, 89, 153, 91, 7, + 93, 149, 149, 96, 8, 9, 10, 100, 101, 102, + 103, 104, 105, 106, 150, 7, 109, 110, 154, 112, + 113, 114, 115, 8, 9, 10, 12, 120, 8, 9, + 123, 124, 125, 126, 32, 33, 51, 52, 53, 68, + 144, 156, 150, 147, 29, 141, 142, 151, 1, 72, + 15, 144, 67, 68, 149, 78, 149, 150, 151, 82, + 124, 12, 85, 86, 87, 150, 89, 83, 91, 154, + 93, 130, 149, 96, 97, 98, 99, 100, 101, 102, + 103, 68, 105, 106, 13, 36, 109, 153, 152, 112, + 113, 114, 115, 8, 9, 10, 149, 120, 153, 15, + 123, 124, 125, 126, 32, 33, 34, 104, 150, 8, + 9, 10, 154, 110, 29, 12, 31, 32, 33, 72, + 83, 150, 119, 149, 140, 78, 149, 150, 151, 82, + 29, 30, 85, 86, 87, 15, 89, 15, 91, 36, + 93, 149, 129, 96, 97, 98, 99, 100, 101, 102, + 103, 15, 105, 106, 151, 1, 109, 149, 15, 112, + 113, 114, 115, 149, 8, 9, 10, 120, 153, 13, + 123, 124, 125, 126, 8, 9, 10, 140, 8, 9, + 10, 48, 49, 50, 30, 29, 48, 49, 50, 150, + 15, 78, 30, 154, 81, 29, 149, 150, 151, 29, + 29, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 1, 55, 72, 8, 9, 10, + 67, 68, 78, 12, 12, 144, 82, 67, 147, 85, + 86, 87, 30, 89, 30, 91, 147, 93, 29, 150, + 96, 36, 30, 30, 100, 101, 102, 36, 30, 105, + 106, 73, 74, 109, 73, 74, 112, 113, 103, 104, + 1, 98, 99, 30, 120, 107, 108, 149, 150, 149, + 150, 149, 150, 30, 32, 55, 68, 67, 75, 78, + 80, 83, 68, 68, 68, 72, 69, 68, 92, 30, + 68, 78, 68, 149, 150, 82, 68, 90, 85, 86, + 87, 78, 89, 78, 91, 110, 93, 80, 87, 96, + 80, 1, 83, 100, 101, 102, 124, 111, 105, 106, + 88, 95, 109, 124, 127, 112, 113, 140, 94, 140, + 95, 72, 95, 120, 95, 97, 143, 78, 97, 103, + 30, 82, 148, 103, 85, 86, 87, 156, 89, -1, + 91, -1, 93, -1, -1, 96, -1, 1, 127, 100, + 101, 102, 149, 150, 105, 106, -1, -1, 109, -1, + -1, 112, 113, 128, 130, 129, 129, 129, 129, 120, + -1, -1, 72, -1, -1, -1, 30, -1, 78, -1, + -1, -1, 82, 143, 143, 85, 86, 87, 143, 89, + 143, 91, 149, 93, 143, 143, 96, 143, 149, 150, + 100, 101, 102, 147, 147, 105, 106, 147, 147, 109, + 147, 147, 112, 113, 147, 147, 1, 151, 72, 149, + 120, 149, 149, 149, 78, 149, 149, 149, 82, 149, + 149, 85, 86, 87, 149, 89, 149, 91, 30, 93, + 149, 149, 96, 149, 149, 149, 100, 101, 102, 149, + 150, 105, 106, 149, 149, 109, 48, 49, 112, 113, + 149, 149, 54, 149, 56, 149, 120, 149, 149, 149, + 149, 149, 155, 150, 150, 150, 68, 150, 150, 150, + 150, 150, 150, 150, 76, 77, 150, 72, 80, 150, + 150, 150, 84, 78, 150, 149, 150, 82, 150, 152, + 85, 86, 87, 151, 89, 151, 91, 151, 93, 151, + 151, 96, 151, 151, 151, 100, 101, 102, 151, 151, + 105, 106, 151, 151, 109, 151, 151, 112, 113, 151, + 151, 151, 151, 151, 151, 120, 151, 151, 151, 131, + 151, 133, 134, 135, 136, 137, 138, 139, 151, 48, + 49, 151, 151, 145, 146, 54, 151, 56, 151, 153, + 152, 151, 154, 151, 149, 150, 152, 151, 155, 68, + 152, 152, 152, 152, 152, 152, 152, 76, 77, 152, + 152, 80, 152, 152, 152, 84, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 152, 152, 152, 152, 152, -1, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, -1, 154, 57, 58, + 156, 156, 131, 156, 133, 134, 135, 136, 137, 138, + 139, 156, 156, 156, 156, 156, 145, 146, 156, 156, + 156, 156, 156, 152, 156, 154, 157, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 129 + ); + + protected $actionBase = array( + 0, 221, 297, 437, 367, 305, 305, 286, 690, -2, + -2, 238, -2, -2, -2, 613, 756, 710, 756, 544, + 659, 825, 825, 825, 152, 209, 611, 611, 867, 174, + 611, 404, 364, 337, 612, 493, 439, 289, 289, 289, + 289, 135, 135, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 289, 289, 289, 289, 289, 289, + 289, 289, 289, 289, 313, 176, 461, 346, 680, 705, + 714, 715, 865, 639, 864, 777, 778, 552, 781, 782, + 784, 785, 788, 773, 789, 591, 790, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 151, 546, + 405, 491, 275, 410, 609, 609, 609, 609, 609, 609, + 609, 386, 386, 386, 386, 386, 386, 386, 386, 386, + 386, 386, 386, 386, 386, 386, 386, 386, 386, 319, + 556, 556, 556, 200, 818, 561, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 911, + 911, 911, 911, 911, 911, 911, 911, 911, 911, 215, + -21, -21, 475, 642, 329, 392, 208, 462, 199, 25, + 25, 25, 25, 25, 147, 16, 4, 4, 4, 4, + 981, 122, 122, 122, 122, 118, 118, 118, 118, 393, + 331, 331, 644, 644, 617, 758, 528, 528, 523, 523, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 326, 627, 861, 234, 234, 234, 234, 254, 254, 254, + 131, 427, 589, 909, 131, 123, 123, 123, 375, 375, + 375, 173, 598, 294, 134, 134, 134, 134, 294, 134, + 134, 555, 555, 555, 429, 489, 629, 503, 348, 481, + 282, 641, 791, 638, 768, 520, 664, 190, 671, 670, + 883, 636, 883, 581, 578, 558, 593, 230, 840, -6, + 313, 518, 361, 620, 729, 295, 706, 242, 398, 403, + 522, 168, 324, 733, 697, 863, 816, 220, 648, 620, + 620, 620, 335, 374, 750, 751, 168, 114, 553, 553, + 553, 553, 766, 754, 553, 553, 553, 553, 764, 762, + 382, 243, 810, 138, 731, 601, 601, 625, 625, 601, + 601, 601, 601, 600, 605, 601, 828, 842, 842, 625, + 630, 625, 600, 605, 757, 757, 757, 757, 625, 605, + 625, 625, 601, 625, 842, 842, 605, 617, 842, 48, + 605, 631, 601, 597, 597, 757, 653, 695, 625, 625, + 645, 842, 842, 842, 645, 605, 757, 595, 594, 13, + 842, 757, 633, 630, 633, 595, 605, 633, 630, 630, + 633, 5, 643, 614, 824, 832, 830, 735, 599, 592, + 859, 858, 833, 860, 841, 602, 678, 687, 688, 526, + 615, 616, 619, 624, 651, 622, 647, 636, 666, 610, + 610, 610, 649, 655, 649, 610, 610, 610, 610, 610, + 610, 610, 610, 908, 661, 657, 646, 621, 701, 533, + 677, 637, 425, 737, 587, 678, 678, 771, 873, 880, + 823, 727, 623, 840, 875, 649, 898, 683, 38, 565, + 838, 769, 667, 673, 649, 837, 649, 738, 649, 872, + 772, 628, 826, 678, 822, 610, 871, 906, 905, 904, + 903, 902, 899, 884, 897, 608, 896, 691, 632, 879, + 245, 862, 593, 662, 674, 686, 820, 166, 895, 817, + 649, 649, 739, 734, 649, 740, 684, 682, 869, 732, + 878, 887, 587, 877, 649, 640, 815, 885, 166, 618, + 603, 866, 634, 721, 829, 870, 831, 741, 474, 512, + 811, 676, 807, 604, 722, 882, 881, 868, 726, 742, + 510, 743, 596, 799, 746, 834, 728, 797, 796, 874, + 626, 666, 650, 606, 635, 607, 749, 795, 876, 730, + 724, 704, 793, 702, 792, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 135, 135, 135, 135, -2, + -2, -2, -2, 0, 0, -2, 0, 0, 0, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 0, 0, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 560, -21, -21, -21, -21, 560, -21, -21, + -21, -21, -21, -21, -21, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, -21, 560, 560, 560, -21, 107, -21, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 560, 0, 0, 560, -21, 560, -21, + 560, -21, 560, 560, 560, 560, 560, 560, -21, -21, + -21, -21, -21, -21, 0, 123, 123, 123, 123, -21, + -21, -21, -21, -36, 107, 107, 107, 107, 107, 107, + 123, 123, 375, 375, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 107, -36, 107, 601, 601, 601, + 601, 630, 630, 630, 601, 294, 294, 294, 601, 0, + 0, 0, 0, 0, 0, 601, 294, 0, 107, 107, + 107, 107, 0, 107, 107, 601, 601, 601, 630, 601, + 294, 630, 630, 601, 842, 563, 563, 563, 563, 166, + 168, 0, 601, 601, 630, 630, 630, 0, 0, 0, + 842, 0, 625, 0, 0, 0, 0, 610, 38, 0, + 195, 0, 0, 0, 0, 0, 0, 623, 195, 257, + 257, 0, 608, 610, 610, 610, 0, 0, 623, 623, + 0, 0, 0, 0, 0, 0, 219, 623, 0, 0, + 0, 0, 219, 68, 0, 0, 68, 0, 166 + ); + + protected $actionDefault = array( + 3,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 532, 532,32767,32767, + 487,32767,32767,32767,32767,32767,32767, 292, 292, 292, + 32767,32767,32767, 520, 520, 520, 520, 520, 520, 520, + 520, 520, 520, 520,32767,32767,32767,32767,32767, 375, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 381, 537,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767, 356, 357, 359, + 360, 291, 521, 240, 382, 536, 290, 242, 320, 491, + 32767,32767,32767, 322, 119, 251, 196, 490, 122, 289, + 227, 374, 376, 321, 296, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 312, 313, 295, 447, + 353, 352, 351, 449,32767, 448, 484, 484, 487,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 318, + 475, 474, 319, 445, 323, 446, 325, 450, 324, 341, + 342, 339, 340, 343, 452, 451, 468, 469, 466, 467, + 294, 344, 345, 346, 347, 470, 471, 472, 473, 275, + 32767,32767, 531, 531,32767,32767, 332, 333, 459, 460, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 276,32767, 231, 231, 231, 231,32767,32767,32767, + 231,32767,32767,32767,32767, 327, 328, 326, 454, 455, + 453,32767, 421,32767,32767,32767,32767,32767, 423,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 492,32767,32767,32767,32767,32767, 505, 410,32767,32767, + 32767, 403,32767, 215, 217, 164, 478,32767,32767,32767, + 32767,32767, 510, 337,32767,32767,32767,32767,32767, 546, + 32767, 505,32767,32767,32767,32767,32767,32767, 350, 329, + 330, 331,32767,32767,32767,32767, 509, 503, 462, 463, + 464, 465,32767,32767, 456, 457, 458, 461,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 168,32767, 418, 424, 424,32767, + 32767,32767,32767, 168,32767,32767,32767,32767,32767, 168, + 32767,32767,32767,32767, 508, 507, 168,32767, 404, 486, + 168, 181,32767, 179, 179,32767, 201, 201,32767,32767, + 183, 479, 498,32767, 183, 168,32767, 392, 170, 486, + 32767,32767, 233,32767, 233, 392, 168, 233,32767,32767, + 233,32767, 84, 428,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 405,32767,32767,32767, + 371, 372, 481, 494,32767, 495,32767, 403,32767, 335, + 336, 338, 315,32767, 317, 361, 362, 363, 364, 365, + 366, 367, 369,32767, 408,32767, 411,32767,32767,32767, + 86, 111, 250,32767, 544, 86, 406,32767,32767, 299, + 544,32767,32767,32767,32767, 539,32767,32767, 293,32767, + 32767,32767, 86, 86, 246,32767, 166,32767, 529,32767, + 545,32767, 503, 407,32767, 334,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 504,32767,32767,32767,32767, + 222,32767, 441,32767, 86,32767,32767, 182,32767,32767, + 297, 241,32767,32767, 538,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 167,32767,32767,32767, 184,32767, + 32767, 503,32767,32767,32767,32767,32767,32767,32767, 288, + 32767,32767,32767,32767,32767,32767,32767, 503,32767,32767, + 226,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 84, 60,32767, 269,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 124, 124, 3, 124, 124, + 253, 3, 253, 124, 253, 253, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 209, 212, 201, 201, + 161, 124, 124, 261 + ); + + protected $goto = array( + 163, 163, 137, 137, 142, 145, 137, 138, 139, 140, + 147, 184, 165, 161, 161, 161, 161, 142, 142, 162, + 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, + 157, 158, 159, 160, 181, 136, 182, 499, 500, 363, + 501, 505, 506, 507, 508, 509, 510, 511, 512, 974, + 141, 143, 144, 146, 168, 173, 183, 200, 249, 252, + 254, 256, 258, 259, 260, 261, 262, 263, 271, 272, + 273, 274, 286, 287, 315, 316, 317, 379, 380, 381, + 555, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 148, 149, 150, 164, 151, + 166, 152, 201, 167, 153, 154, 155, 202, 156, 134, + 632, 573, 794, 573, 573, 573, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 573, 573, 573, 573, + 573, 573, 573, 573, 573, 573, 1113, 342, 1113, 1113, + 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, + 1113, 503, 503, 503, 503, 503, 503, 514, 640, 514, + 764, 503, 503, 503, 503, 503, 503, 503, 503, 503, + 503, 515, 763, 515, 895, 895, 1204, 1204, 529, 587, + 615, 859, 859, 859, 859, 171, 854, 860, 1089, 1088, + 174, 175, 176, 388, 389, 390, 391, 170, 199, 203, + 205, 253, 255, 257, 264, 265, 266, 267, 268, 269, + 275, 276, 277, 278, 288, 289, 318, 319, 320, 394, + 395, 396, 397, 172, 177, 250, 251, 178, 179, 180, + 757, 387, 617, 548, 548, 580, 544, 1215, 1215, 328, + 313, 546, 546, 502, 504, 535, 552, 581, 584, 594, + 601, 825, 621, 1215, 516, 624, 516, 572, 361, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 572, 572, 572, 572, 572, 572, 572, 572, + 572, 572, 557, 558, 559, 560, 561, 562, 563, 564, + 566, 597, 520, 556, 3, 4, 596, 528, 611, 612, + 951, 554, 525, 525, 525, 579, 525, 865, 343, 344, + 528, 528, 549, 438, 438, 438, 438, 438, 438, 543, + 525, 913, 952, 438, 438, 438, 438, 438, 438, 438, + 438, 438, 438, 1078, 1208, 1078, 902, 902, 902, 902, + 590, 593, 638, 902, 598, 345, 404, 902, 1182, 364, + 1182, 605, 616, 369, 369, 369, 1162, 1078, 1078, 1078, + 1078, 787, 1078, 1078, 369, 369, 1181, 1201, 1181, 1174, + 369, 376, 469, 1198, 1198, 1198, 525, 525, 369, 1229, + 542, 574, 525, 525, 1022, 1071, 525, 899, 787, 787, + 908, 348, 919, 522, 919, 398, 370, 783, 374, 917, + 1180, 972, 781, 526, 541, 671, 667, 568, 402, 1064, + 922, 602, 762, 553, 892, 622, 623, 888, 627, 628, + 635, 637, 642, 644, 791, 881, 863, 861, 863, 666, + 1094, 517, 890, 885, 1196, 1196, 1196, 869, 1032, 19, + 15, 357, 960, 454, 1159, 780, 780, 358, 1069, 788, + 788, 788, 790, 467, 533, 779, 0, 585, 545, 567, + 0, 0, 522, 1074, 1075, 0, 0, 1071, 0, 0, + 23, 1214, 1214, 458, 0, 613, 371, 371, 371, 0, + 1072, 1173, 1072, 0, 13, 540, 0, 1214, 0, 1073, + 451, 453, 944, 643, 0, 1217, 0, 1114, 625, 942, + 0, 0, 0, 371, 0, 620, 0, 386, 0, 0, + 1070, 629, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 519, 539, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 519, 0, 539, 0, + 0, 0, 0, 0, 534, 518, 0, 523, 441, 0, + 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 786, 1222 + ); + + protected $gotoCheck = array( + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 56, 66, 28, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 124, 69, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 115, 115, 115, 115, 115, 115, 66, 8, 66, + 15, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 115, 14, 115, 74, 74, 74, 74, 99, 39, + 39, 66, 66, 66, 66, 26, 66, 66, 122, 122, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 5, 50, 50, 50, 50, 50, 50, 140, 140, 123, + 123, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 49, 60, 140, 120, 60, 120, 56, 60, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 108, 108, 108, 108, 108, 108, 108, 108, + 108, 108, 10, 46, 29, 29, 64, 46, 64, 64, + 95, 2, 10, 10, 10, 2, 10, 32, 69, 69, + 46, 46, 107, 56, 56, 56, 56, 56, 56, 10, + 10, 81, 95, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 138, 56, 56, 56, 56, 56, + 59, 59, 59, 56, 67, 67, 67, 56, 116, 45, + 116, 125, 48, 12, 12, 12, 129, 56, 56, 56, + 56, 22, 56, 56, 12, 12, 117, 136, 117, 79, + 12, 47, 56, 117, 117, 117, 10, 10, 12, 12, + 10, 10, 10, 10, 100, 79, 10, 76, 22, 22, + 78, 17, 12, 12, 12, 21, 11, 24, 16, 82, + 117, 99, 23, 10, 31, 71, 31, 31, 20, 111, + 83, 31, 13, 10, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 25, 13, 13, 13, 13, 13, + 33, 13, 13, 13, 8, 8, 8, 68, 33, 33, + 33, 33, 97, 62, 128, 22, 22, 57, 113, 22, + 22, 22, 22, 106, 57, 22, -1, 63, 57, 33, + -1, -1, 12, 79, 79, -1, -1, 79, -1, -1, + 33, 139, 139, 57, -1, 33, 121, 121, 121, -1, + 79, 79, 79, -1, 57, 8, -1, 139, -1, 79, + 7, 7, 7, 7, -1, 139, -1, 7, 7, 7, + -1, -1, -1, 121, -1, 12, -1, 121, -1, -1, + 12, 12, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8, 8, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8, -1, 8, -1, + -1, -1, -1, -1, 99, 8, -1, 8, 8, -1, + 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 8, 8 + ); + + protected $gotoBase = array( + 0, 0, -276, 0, 0, 269, 0, 555, 197, 0, + 41, 131, 112, 480, 220, 208, 120, 140, 0, 0, + 72, 133, 110, 123, 134, 75, 31, 0, 102, -307, + 0, -172, 357, 84, 0, 0, 0, 0, 0, 191, + 0, 0, -24, 0, 0, 379, 339, 150, 141, 283, + 1, 0, 0, 0, 0, 0, 103, 88, 0, 106, + -162, 0, 69, 73, -286, 0, -93, 89, 86, -290, + 0, 115, 0, 0, -56, 0, 147, 0, 146, 99, + 0, 366, 117, 60, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 91, 0, 90, 0, 187, + 152, 0, 0, 0, 0, 0, 58, 355, 308, 0, + 0, 61, 0, 95, 0, -79, 118, 136, 0, 0, + 4, 239, -70, -33, -48, 214, 0, 0, 55, 218, + 0, 0, 0, 0, 0, 0, 154, 0, 374, 229, + -25, 0, 0 + ); + + protected $gotoDefault = array( + -32768, 471, 675, 2, 676, 747, 755, 608, 485, 641, + 486, 521, 1192, 800, 801, 802, 366, 412, 487, 365, + 399, 392, 789, 782, 784, 792, 169, 400, 795, 1, + 797, 527, 833, 1023, 353, 805, 354, 600, 807, 537, + 809, 810, 135, 367, 368, 538, 488, 375, 588, 824, + 270, 372, 826, 355, 827, 836, 356, 468, 463, 569, + 619, 433, 450, 582, 576, 547, 1086, 577, 868, 341, + 876, 672, 884, 887, 489, 570, 898, 455, 906, 1099, + 382, 912, 918, 923, 279, 926, 413, 401, 595, 931, + 932, 7, 936, 633, 634, 8, 301, 959, 609, 973, + 418, 1042, 1044, 490, 491, 531, 462, 513, 536, 492, + 1065, 444, 403, 1068, 493, 494, 434, 435, 1083, 347, + 1167, 346, 452, 312, 1154, 591, 1118, 459, 1207, 1163, + 340, 495, 496, 362, 1186, 377, 1202, 439, 1209, 1216, + 336, 551, 578 + ); + + protected $ruleToNonTerminal = array( + 0, 1, 3, 3, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 8, 9, 10, 10, 11, 12, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, + 17, 18, 18, 18, 18, 20, 20, 16, 16, 21, + 21, 22, 22, 23, 23, 24, 24, 19, 19, 25, + 27, 27, 28, 29, 29, 31, 30, 30, 30, 30, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, + 13, 53, 53, 55, 54, 54, 47, 47, 57, 57, + 58, 58, 14, 15, 15, 15, 61, 61, 61, 62, + 62, 65, 65, 63, 63, 67, 67, 40, 40, 49, + 49, 52, 52, 52, 51, 51, 68, 41, 41, 41, + 41, 69, 69, 70, 70, 71, 71, 38, 38, 34, + 34, 72, 36, 36, 73, 35, 35, 37, 37, 48, + 48, 48, 59, 59, 75, 75, 76, 76, 78, 78, + 78, 77, 77, 60, 60, 79, 79, 79, 80, 80, + 81, 81, 81, 43, 43, 82, 82, 82, 44, 44, + 83, 83, 84, 84, 64, 85, 85, 85, 85, 90, + 90, 91, 91, 92, 92, 92, 92, 92, 93, 94, + 94, 89, 89, 86, 86, 88, 88, 96, 96, 95, + 95, 95, 95, 95, 95, 87, 87, 98, 97, 97, + 45, 45, 39, 39, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 33, + 33, 46, 46, 103, 103, 104, 104, 104, 104, 110, + 99, 99, 106, 106, 112, 112, 113, 114, 114, 114, + 114, 114, 114, 66, 66, 56, 56, 56, 100, 100, + 118, 118, 115, 115, 119, 119, 119, 119, 101, 101, + 101, 105, 105, 105, 111, 111, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 26, + 26, 26, 26, 26, 26, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 109, 109, + 102, 102, 102, 102, 125, 125, 128, 128, 127, 127, + 129, 129, 50, 50, 50, 50, 131, 131, 130, 130, + 130, 130, 130, 132, 132, 117, 117, 120, 120, 116, + 116, 134, 133, 133, 133, 133, 121, 121, 121, 121, + 108, 108, 122, 122, 122, 122, 74, 135, 135, 136, + 136, 136, 107, 107, 137, 137, 138, 138, 138, 138, + 123, 123, 123, 123, 140, 141, 139, 139, 139, 139, + 139, 139, 139, 142, 142, 142 + ); + + protected $ruleToLength = array( + 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, + 1, 1, 3, 5, 4, 3, 4, 2, 3, 1, + 1, 7, 8, 6, 7, 3, 1, 3, 1, 3, + 1, 1, 3, 1, 2, 1, 2, 3, 1, 3, + 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, + 3, 5, 8, 3, 5, 9, 3, 2, 3, 2, + 3, 2, 3, 3, 3, 3, 1, 2, 2, 5, + 7, 9, 5, 6, 3, 3, 2, 2, 1, 1, + 1, 0, 2, 8, 0, 4, 1, 3, 0, 1, + 0, 1, 10, 7, 6, 5, 1, 2, 2, 0, + 2, 0, 2, 0, 2, 1, 3, 1, 4, 1, + 4, 1, 1, 4, 1, 3, 3, 3, 4, 4, + 5, 0, 2, 4, 3, 1, 1, 1, 4, 0, + 2, 3, 0, 2, 4, 0, 2, 0, 3, 1, + 2, 1, 1, 0, 1, 3, 4, 6, 1, 1, + 1, 0, 1, 0, 2, 2, 3, 3, 1, 3, + 1, 2, 2, 3, 1, 1, 2, 4, 3, 1, + 1, 3, 2, 0, 1, 3, 3, 9, 3, 1, + 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, + 1, 1, 3, 1, 1, 0, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, + 3, 1, 0, 1, 1, 3, 3, 4, 4, 1, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, + 3, 5, 4, 3, 4, 4, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 3, 2, 1, 2, 10, 11, 3, + 3, 2, 4, 4, 3, 4, 4, 4, 4, 7, + 3, 2, 0, 4, 1, 3, 2, 2, 4, 6, + 2, 2, 4, 1, 1, 1, 2, 3, 1, 1, + 1, 1, 1, 1, 3, 3, 4, 4, 0, 2, + 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, + 3, 1, 4, 3, 1, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, + 3, 3, 3, 3, 5, 4, 4, 3, 1, 3, + 1, 1, 3, 3, 0, 2, 0, 1, 3, 1, + 3, 1, 1, 1, 1, 1, 6, 4, 3, 4, + 2, 4, 4, 1, 3, 1, 2, 1, 1, 4, + 1, 1, 3, 6, 4, 4, 4, 4, 1, 4, + 0, 1, 1, 3, 1, 1, 4, 3, 1, 1, + 1, 0, 0, 2, 3, 1, 3, 1, 4, 2, + 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, + 3, 6, 3, 1, 1, 1 + ); + + protected function initReduceCallbacks() { + $this->reduceCallbacks = [ + 0 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 1 => function ($stackPos) { + $this->semValue = $this->handleNamespaces($this->semStack[$stackPos-(1-1)]); + }, + 2 => function ($stackPos) { + if (is_array($this->semStack[$stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); } else { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }; + }, + 3 => function ($stackPos) { + $this->semValue = array(); + }, + 4 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 5 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 6 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 7 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 8 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 9 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 10 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 11 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 12 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 13 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 14 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 15 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 16 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 17 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 18 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 19 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 20 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 21 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 22 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 23 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 24 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 25 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 26 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 27 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 28 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 29 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 30 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 31 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 32 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 33 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 34 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 35 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 36 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 37 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 38 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 39 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 40 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 41 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 42 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 43 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 44 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 45 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 46 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 47 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 48 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 49 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 50 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 51 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 52 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 53 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 54 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 55 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 56 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 57 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 58 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 59 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 60 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 61 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 62 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 63 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 64 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 65 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 66 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 67 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 68 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 69 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 70 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 71 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 72 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 73 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 74 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 75 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 76 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 77 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 78 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 79 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 80 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 81 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 82 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 83 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 84 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 85 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 86 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 87 => function ($stackPos) { + $this->semValue = new Expr\Variable(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 88 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 89 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 90 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 91 => function ($stackPos) { + $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 92 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos-(3-2)], null, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($this->semValue); + }, + 93 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos-(5-2)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + }, + 94 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + }, + 95 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 96 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 97 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 98 => function ($stackPos) { + $this->semValue = new Stmt\Const_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 99 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_FUNCTION; + }, + 100 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_CONSTANT; + }, + 101 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(7-3)], $this->startAttributeStack[$stackPos-(7-3)] + $this->endAttributeStack[$stackPos-(7-3)]), $this->semStack[$stackPos-(7-6)], $this->semStack[$stackPos-(7-2)], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 102 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(8-4)], $this->startAttributeStack[$stackPos-(8-4)] + $this->endAttributeStack[$stackPos-(8-4)]), $this->semStack[$stackPos-(8-7)], $this->semStack[$stackPos-(8-2)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 103 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(6-2)], $this->startAttributeStack[$stackPos-(6-2)] + $this->endAttributeStack[$stackPos-(6-2)]), $this->semStack[$stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 104 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(7-3)], $this->startAttributeStack[$stackPos-(7-3)] + $this->endAttributeStack[$stackPos-(7-3)]), $this->semStack[$stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 105 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 106 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 107 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 108 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 109 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 110 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 111 => function ($stackPos) { + $this->semValue = new Stmt\UseUse($this->semStack[$stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $stackPos-(1-1)); + }, + 112 => function ($stackPos) { + $this->semValue = new Stmt\UseUse($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $stackPos-(3-3)); + }, + 113 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 114 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 115 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; + }, + 116 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; $this->semValue->type = $this->semStack[$stackPos-(2-1)]; + }, + 117 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 118 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 119 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 120 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 121 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 122 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 123 => function ($stackPos) { + if (is_array($this->semStack[$stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); } else { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }; + }, + 124 => function ($stackPos) { + $this->semValue = array(); + }, + 125 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 126 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 127 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 128 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 129 => function ($stackPos) { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 130 => function ($stackPos) { + + if ($this->semStack[$stackPos-(3-2)]) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; $attrs = $this->startAttributeStack[$stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; + } else { + $startAttributes = $this->startAttributeStack[$stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $this->semValue = null; }; + if (null === $this->semValue) { $this->semValue = array(); } + } + + }, + 131 => function ($stackPos) { + $this->semValue = new Stmt\If_($this->semStack[$stackPos-(5-2)], ['stmts' => is_array($this->semStack[$stackPos-(5-3)]) ? $this->semStack[$stackPos-(5-3)] : array($this->semStack[$stackPos-(5-3)]), 'elseifs' => $this->semStack[$stackPos-(5-4)], 'else' => $this->semStack[$stackPos-(5-5)]], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 132 => function ($stackPos) { + $this->semValue = new Stmt\If_($this->semStack[$stackPos-(8-2)], ['stmts' => $this->semStack[$stackPos-(8-4)], 'elseifs' => $this->semStack[$stackPos-(8-5)], 'else' => $this->semStack[$stackPos-(8-6)]], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 133 => function ($stackPos) { + $this->semValue = new Stmt\While_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 134 => function ($stackPos) { + $this->semValue = new Stmt\Do_($this->semStack[$stackPos-(5-4)], is_array($this->semStack[$stackPos-(5-2)]) ? $this->semStack[$stackPos-(5-2)] : array($this->semStack[$stackPos-(5-2)]), $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 135 => function ($stackPos) { + $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos-(9-3)], 'cond' => $this->semStack[$stackPos-(9-5)], 'loop' => $this->semStack[$stackPos-(9-7)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 136 => function ($stackPos) { + $this->semValue = new Stmt\Switch_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 137 => function ($stackPos) { + $this->semValue = new Stmt\Break_(null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 138 => function ($stackPos) { + $this->semValue = new Stmt\Break_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 139 => function ($stackPos) { + $this->semValue = new Stmt\Continue_(null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 140 => function ($stackPos) { + $this->semValue = new Stmt\Continue_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 141 => function ($stackPos) { + $this->semValue = new Stmt\Return_(null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 142 => function ($stackPos) { + $this->semValue = new Stmt\Return_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 143 => function ($stackPos) { + $this->semValue = new Stmt\Global_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 144 => function ($stackPos) { + $this->semValue = new Stmt\Static_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 145 => function ($stackPos) { + $this->semValue = new Stmt\Echo_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 146 => function ($stackPos) { + $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 147 => function ($stackPos) { + $this->semValue = new Stmt\Expression($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 148 => function ($stackPos) { + $this->semValue = new Stmt\Expression($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 149 => function ($stackPos) { + $this->semValue = new Stmt\Unset_($this->semStack[$stackPos-(5-3)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 150 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(7-3)], $this->semStack[$stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos-(7-5)][1], 'stmts' => $this->semStack[$stackPos-(7-7)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 151 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(9-3)], $this->semStack[$stackPos-(9-7)][0], ['keyVar' => $this->semStack[$stackPos-(9-5)], 'byRef' => $this->semStack[$stackPos-(9-7)][1], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 152 => function ($stackPos) { + $this->semValue = new Stmt\Declare_($this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 153 => function ($stackPos) { + $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-5)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); + }, + 154 => function ($stackPos) { + $this->semValue = new Stmt\Throw_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 155 => function ($stackPos) { + $this->semValue = new Stmt\Goto_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 156 => function ($stackPos) { + $this->semValue = new Stmt\Label($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 157 => function ($stackPos) { + $this->semValue = new Stmt\Expression($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 158 => function ($stackPos) { + $this->semValue = array(); /* means: no statement */ + }, + 159 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 160 => function ($stackPos) { + $startAttributes = $this->startAttributeStack[$stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $this->semValue = null; }; + if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ + }, + 161 => function ($stackPos) { + $this->semValue = array(); + }, + 162 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 163 => function ($stackPos) { + $this->semValue = new Stmt\Catch_(array($this->semStack[$stackPos-(8-3)]), $this->semStack[$stackPos-(8-4)], $this->semStack[$stackPos-(8-7)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 164 => function ($stackPos) { + $this->semValue = null; + }, + 165 => function ($stackPos) { + $this->semValue = new Stmt\Finally_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 166 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 167 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 168 => function ($stackPos) { + $this->semValue = false; + }, + 169 => function ($stackPos) { + $this->semValue = true; + }, + 170 => function ($stackPos) { + $this->semValue = false; + }, + 171 => function ($stackPos) { + $this->semValue = true; + }, + 172 => function ($stackPos) { + $this->semValue = new Stmt\Function_($this->semStack[$stackPos-(10-3)], ['byRef' => $this->semStack[$stackPos-(10-2)], 'params' => $this->semStack[$stackPos-(10-5)], 'returnType' => $this->semStack[$stackPos-(10-7)], 'stmts' => $this->semStack[$stackPos-(10-9)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); + }, + 173 => function ($stackPos) { + $this->semValue = new Stmt\Class_($this->semStack[$stackPos-(7-2)], ['type' => $this->semStack[$stackPos-(7-1)], 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + $this->checkClass($this->semValue, $stackPos-(7-2)); + }, + 174 => function ($stackPos) { + $this->semValue = new Stmt\Interface_($this->semStack[$stackPos-(6-2)], ['extends' => $this->semStack[$stackPos-(6-3)], 'stmts' => $this->semStack[$stackPos-(6-5)]], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + $this->checkInterface($this->semValue, $stackPos-(6-2)); + }, + 175 => function ($stackPos) { + $this->semValue = new Stmt\Trait_($this->semStack[$stackPos-(5-2)], ['stmts' => $this->semStack[$stackPos-(5-4)]], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 176 => function ($stackPos) { + $this->semValue = 0; + }, + 177 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + }, + 178 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + }, + 179 => function ($stackPos) { + $this->semValue = null; + }, + 180 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 181 => function ($stackPos) { + $this->semValue = array(); + }, + 182 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 183 => function ($stackPos) { + $this->semValue = array(); + }, + 184 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 185 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 186 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 187 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 188 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 189 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 190 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 191 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 192 => function ($stackPos) { + $this->semValue = null; + }, + 193 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 194 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 195 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 196 => function ($stackPos) { + $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 197 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 198 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 199 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 200 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(5-3)]; + }, + 201 => function ($stackPos) { + $this->semValue = array(); + }, + 202 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 203 => function ($stackPos) { + $this->semValue = new Stmt\Case_($this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 204 => function ($stackPos) { + $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 205 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 206 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 207 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 208 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 209 => function ($stackPos) { + $this->semValue = array(); + }, + 210 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 211 => function ($stackPos) { + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(3-2)], is_array($this->semStack[$stackPos-(3-3)]) ? $this->semStack[$stackPos-(3-3)] : array($this->semStack[$stackPos-(3-3)]), $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 212 => function ($stackPos) { + $this->semValue = array(); + }, + 213 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 214 => function ($stackPos) { + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 215 => function ($stackPos) { + $this->semValue = null; + }, + 216 => function ($stackPos) { + $this->semValue = new Stmt\Else_(is_array($this->semStack[$stackPos-(2-2)]) ? $this->semStack[$stackPos-(2-2)] : array($this->semStack[$stackPos-(2-2)]), $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 217 => function ($stackPos) { + $this->semValue = null; + }, + 218 => function ($stackPos) { + $this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 219 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 220 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(2-2)], true); + }, + 221 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 222 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 223 => function ($stackPos) { + $this->semValue = array(); + }, + 224 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 225 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 226 => function ($stackPos) { + $this->semValue = new Node\Param($this->semStack[$stackPos-(4-4)], null, $this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); + }, + 227 => function ($stackPos) { + $this->semValue = new Node\Param($this->semStack[$stackPos-(6-4)], $this->semStack[$stackPos-(6-6)], $this->semStack[$stackPos-(6-1)], $this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-3)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); + }, + 228 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 229 => function ($stackPos) { + $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 230 => function ($stackPos) { + $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 231 => function ($stackPos) { + $this->semValue = null; + }, + 232 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 233 => function ($stackPos) { + $this->semValue = null; + }, + 234 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 235 => function ($stackPos) { + $this->semValue = array(); + }, + 236 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 237 => function ($stackPos) { + $this->semValue = array(new Node\Arg($this->semStack[$stackPos-(3-2)], false, false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes)); + }, + 238 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 239 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 240 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(1-1)], false, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 241 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], true, false, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 242 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], false, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 243 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 244 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 245 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 246 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 247 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 248 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 249 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 250 => function ($stackPos) { + $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 251 => function ($stackPos) { + $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 252 => function ($stackPos) { + if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; } + }, + 253 => function ($stackPos) { + $this->semValue = array(); + }, + 254 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 255 => function ($stackPos) { + $this->semValue = new Stmt\Property($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $stackPos-(3-1)); + }, + 256 => function ($stackPos) { + $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos-(3-2)], 0, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 257 => function ($stackPos) { + $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos-(9-4)], ['type' => $this->semStack[$stackPos-(9-1)], 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-6)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + $this->checkClassMethod($this->semValue, $stackPos-(9-1)); + }, + 258 => function ($stackPos) { + $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 259 => function ($stackPos) { + $this->semValue = array(); + }, + 260 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 261 => function ($stackPos) { + $this->semValue = array(); + }, + 262 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 263 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 264 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(5-1)][0], $this->semStack[$stackPos-(5-1)][1], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 265 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], null, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 266 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 267 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 268 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)]); + }, + 269 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 270 => function ($stackPos) { + $this->semValue = array(null, $this->semStack[$stackPos-(1-1)]); + }, + 271 => function ($stackPos) { + $this->semValue = null; + }, + 272 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 273 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 274 => function ($stackPos) { + $this->semValue = 0; + }, + 275 => function ($stackPos) { + $this->semValue = 0; + }, + 276 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 277 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 278 => function ($stackPos) { + $this->checkModifier($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $this->semValue = $this->semStack[$stackPos-(2-1)] | $this->semStack[$stackPos-(2-2)]; + }, + 279 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; + }, + 280 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; + }, + 281 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; + }, + 282 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_STATIC; + }, + 283 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + }, + 284 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + }, + 285 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 286 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 287 => function ($stackPos) { + $this->semValue = new Node\VarLikeIdentifier(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 288 => function ($stackPos) { + $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 289 => function ($stackPos) { + $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 290 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 291 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 292 => function ($stackPos) { + $this->semValue = array(); + }, + 293 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 294 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 295 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 296 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 297 => function ($stackPos) { + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 298 => function ($stackPos) { + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 299 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 300 => function ($stackPos) { + $this->semValue = new Expr\Clone_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 301 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 302 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 303 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 304 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 305 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 306 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 307 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 308 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 309 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 310 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 311 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 312 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 313 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 314 => function ($stackPos) { + $this->semValue = new Expr\PostInc($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 315 => function ($stackPos) { + $this->semValue = new Expr\PreInc($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 316 => function ($stackPos) { + $this->semValue = new Expr\PostDec($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 317 => function ($stackPos) { + $this->semValue = new Expr\PreDec($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 318 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 319 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 320 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 321 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 322 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 323 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 324 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 325 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 326 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 327 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 328 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 329 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 330 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 331 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 332 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 333 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 334 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 335 => function ($stackPos) { + $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 336 => function ($stackPos) { + $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 337 => function ($stackPos) { + $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 338 => function ($stackPos) { + $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 339 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 340 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 341 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 342 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 343 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 344 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 345 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 346 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 347 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 348 => function ($stackPos) { + $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 349 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 350 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 351 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(5-1)], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 352 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(4-1)], null, $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 353 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 354 => function ($stackPos) { + $this->semValue = new Expr\Isset_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 355 => function ($stackPos) { + $this->semValue = new Expr\Empty_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 356 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 357 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 358 => function ($stackPos) { + $this->semValue = new Expr\Eval_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 359 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 360 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 361 => function ($stackPos) { + $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 362 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; + $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos-(2-1)]); + $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos-(2-2)], $attrs); + }, + 363 => function ($stackPos) { + $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 364 => function ($stackPos) { + $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 365 => function ($stackPos) { + $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 366 => function ($stackPos) { + $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 367 => function ($stackPos) { + $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 368 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; + $attrs['kind'] = strtolower($this->semStack[$stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $this->semValue = new Expr\Exit_($this->semStack[$stackPos-(2-2)], $attrs); + }, + 369 => function ($stackPos) { + $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 370 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 371 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 372 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 373 => function ($stackPos) { + $this->semValue = new Expr\ShellExec($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 374 => function ($stackPos) { + $this->semValue = new Expr\Print_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 375 => function ($stackPos) { + $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 376 => function ($stackPos) { + $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 377 => function ($stackPos) { + $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$stackPos-(10-2)], 'params' => $this->semStack[$stackPos-(10-4)], 'uses' => $this->semStack[$stackPos-(10-6)], 'returnType' => $this->semStack[$stackPos-(10-7)], 'stmts' => $this->semStack[$stackPos-(10-9)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); + }, + 378 => function ($stackPos) { + $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$stackPos-(11-3)], 'params' => $this->semStack[$stackPos-(11-5)], 'uses' => $this->semStack[$stackPos-(11-7)], 'returnType' => $this->semStack[$stackPos-(11-8)], 'stmts' => $this->semStack[$stackPos-(11-10)]], $this->startAttributeStack[$stackPos-(11-1)] + $this->endAttributes); + }, + 379 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 380 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 381 => function ($stackPos) { + $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(2-2)], null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 382 => function ($stackPos) { + $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 383 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(4-3)], $attrs); + }, + 384 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(3-2)], $attrs); + }, + 385 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 386 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(4-1)][0] === "'" || ($this->semStack[$stackPos-(4-1)][1] === "'" && ($this->semStack[$stackPos-(4-1)][0] === 'b' || $this->semStack[$stackPos-(4-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Expr\ArrayDimFetch(new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(4-1)]), $attrs), $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 387 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 388 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 389 => function ($stackPos) { + $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes), $this->semStack[$stackPos-(7-2)]); + $this->checkClass($this->semValue[0], -1); + }, + 390 => function ($stackPos) { + $this->semValue = new Expr\New_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 391 => function ($stackPos) { + list($class, $ctorArgs) = $this->semStack[$stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 392 => function ($stackPos) { + $this->semValue = array(); + }, + 393 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 394 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 395 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 396 => function ($stackPos) { + $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos-(2-2)], $this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 397 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 398 => function ($stackPos) { + $this->semValue = new Expr\StaticCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 399 => function ($stackPos) { + $this->semValue = new Expr\StaticCall($this->semStack[$stackPos-(6-1)], $this->semStack[$stackPos-(6-4)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 400 => function ($stackPos) { + $this->semValue = $this->fixupPhp5StaticPropCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 401 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 402 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 403 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 404 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 405 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 406 => function ($stackPos) { + $this->semValue = new Name\FullyQualified($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 407 => function ($stackPos) { + $this->semValue = new Name\Relative($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 408 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 409 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 410 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 411 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 412 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 413 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 414 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 415 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 416 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 417 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 418 => function ($stackPos) { + $this->semValue = null; + }, + 419 => function ($stackPos) { + $this->semValue = null; + }, + 420 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 421 => function ($stackPos) { + $this->semValue = array(); + }, + 422 => function ($stackPos) { + $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos-(1-1)], '`', false), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes)); + }, + 423 => function ($stackPos) { + foreach ($this->semStack[$stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', false); } }; $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 424 => function ($stackPos) { + $this->semValue = array(); + }, + 425 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 426 => function ($stackPos) { + $this->semValue = $this->parseLNumber($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes, true); + }, + 427 => function ($stackPos) { + $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$stackPos-(1-1)]), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 428 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(1-1)][0] === "'" || ($this->semStack[$stackPos-(1-1)][1] === "'" && ($this->semStack[$stackPos-(1-1)][0] === 'b' || $this->semStack[$stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(1-1)], false), $attrs); + }, + 429 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 430 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 431 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 432 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 433 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 434 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 435 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 436 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 437 => function ($stackPos) { + $this->semValue = $this->parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)], false); + }, + 438 => function ($stackPos) { + $this->semValue = $this->parseDocString($this->semStack[$stackPos-(2-1)], '', $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(2-2)] + $this->endAttributeStack[$stackPos-(2-2)], false); + }, + 439 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 440 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 441 => function ($stackPos) { + $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 442 => function ($stackPos) { + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 443 => function ($stackPos) { + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 444 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 445 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 446 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 447 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 448 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 449 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 450 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 451 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 452 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 453 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 454 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 455 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 456 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 457 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 458 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 459 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 460 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 461 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 462 => function ($stackPos) { + $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 463 => function ($stackPos) { + $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 464 => function ($stackPos) { + $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 465 => function ($stackPos) { + $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 466 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 467 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 468 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 469 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 470 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 471 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 472 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 473 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 474 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(5-1)], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 475 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(4-1)], null, $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 476 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 477 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 478 => function ($stackPos) { + $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 479 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 480 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 481 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 482 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($this->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos-(3-2)], $attrs); + }, + 483 => function ($stackPos) { + $this->semValue = $this->parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)], true); + }, + 484 => function ($stackPos) { + $this->semValue = array(); + }, + 485 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 486 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 487 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 488 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 489 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 490 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 491 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 492 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 493 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 494 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 495 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 496 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-5)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 497 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 498 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 499 => function ($stackPos) { + $this->semValue = new Expr\MethodCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 500 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 501 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 502 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 503 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 504 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 505 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 506 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 507 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 508 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 509 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 510 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 511 => function ($stackPos) { + $var = substr($this->semStack[$stackPos-(1-1)], 1); $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes) : $var; + }, + 512 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 513 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(6-1)], $this->semStack[$stackPos-(6-5)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 514 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 515 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 516 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 517 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 518 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 519 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 520 => function ($stackPos) { + $this->semValue = null; + }, + 521 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 522 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 523 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 524 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 525 => function ($stackPos) { + $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + }, + 526 => function ($stackPos) { + $this->semValue = new Expr\List_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 527 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 528 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 529 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 530 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 531 => function ($stackPos) { + $this->semValue = null; + }, + 532 => function ($stackPos) { + $this->semValue = array(); + }, + 533 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 534 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 535 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 536 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 537 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 538 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-1)], true, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 539 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 540 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 541 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 542 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 543 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); + }, + 544 => function ($stackPos) { + $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 545 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 546 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 547 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 548 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 549 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 550 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 551 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-4)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 552 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 553 => function ($stackPos) { + $this->semValue = new Scalar\String_($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 554 => function ($stackPos) { + $this->semValue = $this->parseNumString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 555 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + ]; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php new file mode 100644 index 00000000..fc8fa6ac --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php @@ -0,0 +1,2458 @@ +'", + "T_IS_GREATER_OR_EQUAL", + "T_SL", + "T_SR", + "'+'", + "'-'", + "'.'", + "'*'", + "'/'", + "'%'", + "'!'", + "T_INSTANCEOF", + "'~'", + "T_INC", + "T_DEC", + "T_INT_CAST", + "T_DOUBLE_CAST", + "T_STRING_CAST", + "T_ARRAY_CAST", + "T_OBJECT_CAST", + "T_BOOL_CAST", + "T_UNSET_CAST", + "'@'", + "T_POW", + "'['", + "T_NEW", + "T_CLONE", + "T_EXIT", + "T_IF", + "T_ELSEIF", + "T_ELSE", + "T_ENDIF", + "T_LNUMBER", + "T_DNUMBER", + "T_STRING", + "T_STRING_VARNAME", + "T_VARIABLE", + "T_NUM_STRING", + "T_INLINE_HTML", + "T_ENCAPSED_AND_WHITESPACE", + "T_CONSTANT_ENCAPSED_STRING", + "T_ECHO", + "T_DO", + "T_WHILE", + "T_ENDWHILE", + "T_FOR", + "T_ENDFOR", + "T_FOREACH", + "T_ENDFOREACH", + "T_DECLARE", + "T_ENDDECLARE", + "T_AS", + "T_SWITCH", + "T_ENDSWITCH", + "T_CASE", + "T_DEFAULT", + "T_BREAK", + "T_CONTINUE", + "T_GOTO", + "T_FUNCTION", + "T_CONST", + "T_RETURN", + "T_TRY", + "T_CATCH", + "T_FINALLY", + "T_THROW", + "T_USE", + "T_INSTEADOF", + "T_GLOBAL", + "T_STATIC", + "T_ABSTRACT", + "T_FINAL", + "T_PRIVATE", + "T_PROTECTED", + "T_PUBLIC", + "T_VAR", + "T_UNSET", + "T_ISSET", + "T_EMPTY", + "T_HALT_COMPILER", + "T_CLASS", + "T_TRAIT", + "T_INTERFACE", + "T_EXTENDS", + "T_IMPLEMENTS", + "T_OBJECT_OPERATOR", + "T_LIST", + "T_ARRAY", + "T_CALLABLE", + "T_CLASS_C", + "T_TRAIT_C", + "T_METHOD_C", + "T_FUNC_C", + "T_LINE", + "T_FILE", + "T_START_HEREDOC", + "T_END_HEREDOC", + "T_DOLLAR_OPEN_CURLY_BRACES", + "T_CURLY_OPEN", + "T_PAAMAYIM_NEKUDOTAYIM", + "T_NAMESPACE", + "T_NS_C", + "T_DIR", + "T_NS_SEPARATOR", + "T_ELLIPSIS", + "';'", + "'{'", + "'}'", + "'('", + "')'", + "'`'", + "']'", + "'\"'", + "'$'" + ); + + protected $tokenToSymbol = array( + 0, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 54, 156, 158, 157, 53, 36, 158, + 152, 153, 51, 48, 7, 49, 50, 52, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 30, 149, + 42, 15, 44, 29, 66, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 68, 158, 155, 35, 158, 154, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 150, 34, 151, 56, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 1, 2, 3, 4, + 5, 6, 8, 9, 10, 11, 12, 13, 14, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 31, 32, 33, 37, 38, 39, 40, 41, + 43, 45, 46, 47, 55, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 67, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 79, 80, 81, 82, 158, + 158, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 158, 158, 158, + 158, 158, 158, 139, 140, 141, 142, 143, 144, 145, + 146, 147, 148 + ); + + protected $action = array( + 589, 590, 591, 592, 593, 666, 594, 595, 596, 632, + 633, 0, 32, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114,-32767,-32767,-32767,-32767, + 93, 94, 95, 96, 97,-32766,-32766,-32766, 837, 668, + 885, 886, 887, 884, 883, 882, 885, 886, 887, 884, + 883, 882, 861, 597, 919, 921,-32766, 24,-32766,-32766, + -32766,-32766,-32766,-32766,-32766,-32766, 253, 598, 599, 600, + 601, 602, 603, 604, 431, 827, 664,-32766,-32766,-32766, + 1055,-32766, 118, 605, 606, 607, 608, 609, 610, 611, + 612, 613, 614, 615, 635, 636, 637, 638, 639, 627, + 628, 629, 630, 631, 616, 617, 618, 619, 620, 621, + 622, 658, 659, 660, 661, 662, 663, 623, 624, 625, + 626, 656, 647, 645, 646, 642, 643, 220, 634, 640, + 641, 648, 649, 651, 650, 652, 653, 45, 46, 408, + 47, 48, 644, 655, 654, 9, 49, 50, 120, 51, + -32766,-32766,-32766, 233, -294, -294, 673,-32766,-32766,-32766, + -455, 263, 123, 33,-32766,-32766,-32766, 767, 831, 832, + 877,-32766, 1002,-32766,-32766,-32766,-32766,-32766,-32766, -454, + -32766,-32766,-32766, 52, 53,-32766, 543,-32766,-32766, 54, + 245, 55, 225, 226, 56, 57, 58, 59, 60, 61, + 62, 63, -272, 25, 236, 64, 360,-32766,-32766,-32766, + 668, 1019, 1020, 410, 671, 1052, -490, 1095, 493, 1018, + 1002, -455, 749, 98, 99, 100, 221, 244,-32766, 74, + -32766,-32766,-32766,-32766, -259, -455, 668, 253, 368, 101, + -454, 231, -455, 231, -458, 431, 253, 1104, 294, 268, + 1105, 1052, 544, 280, -454, 365, 420, 421, -491, 863, + 295, -454, 489, -457, -494, 422, 423, -233, 1024, 1025, + 1026, 1027, 1021, 1022, 248, 28, 228, -453, 1014, 432, + 1028, 1023, 365, 668, 995, 668, 30, 66, 298, 260, + 115, 265, 270, 409, -136, -136, -136, -4, 749, 1052, + 1052, 1070, 432, 738, 672, 365, 37, 20, 411, -136, + 412, -136, 413, -136, 414, -136, 571, 415, 431, 235, + 431, 38, 39, 361, 362, 302, 40, 416, 270, 353, + 65, 1083, 995, 293, 42, 417, 418, 1082, -453, 831, + 832, 419, 25, 354, 724, 772, 363, 364, 831, 832, + -176, 25, -453, 124, 1052, 124, 219, 1052, 1018, -453, + 838, -91, -490, 1052,-32766,-32766,-32766, 1018, 749, 409, + 751, 558, -136, 668, 477, 253, 270, 270, 666, 738, + -259, -177, 37, 20, 411,-32766, 412, 995, 413, 803, + 414, 391, 356, 415, 232, 251, 995, 38, 39, 361, + 362, 345, 40, 416, -491, 423, 65, 259, 431, 293, + -494, 417, 418, 422, 423, 357, 117, 419, -493, -453, + 681, 772, 363, 364, 748, 44, 68, 125,-32766,-32766, + -32766, 270, 1071, 230, 270, 68, 668, 269, 749, 409, + 270, 282, 131, 320, 689, 690, 751, 558, -4, 738, + 126, 116, 37, 20, 411, 227, 412, 121, 413, 376, + 414, 122, 560, 415, -218, -218, -218, 38, 39, 361, + 362, 431, 40, 416, 358, 668, 65, 831, 832, 293, + -453, 417, 418, -497, 454, -497, 252, 419, 349, 229, + 724, 772, 363, 364, -453, 359, -176, 668, 382, -238, + 297, -453, 95, 96, 97, 518, 21, 119, 804, 409, + 431, 392, 532, 533, 511, 512, 751, 558, -218, 738, + 400, 8, 37, 20, 411, 128, 412, -177, 413, 133, + 414, 668, 431, 415, -217, -217, -217, 38, 39, 361, + 362, 1032, 40, 416, 134, 749, 65, 689, 690, 293, + 135, 417, 418, -295, -295, 831, 832, 419, 862, 581, + 724, 772, 363, 364, -493, 284, 431, -82, 75, 76, + 77, 130, 246, 575, 569, 572, 763, 244, 101, 540, + 43, 129, 891, 669, 666, 668, 751, 558, -217, 31, + 1106, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 749, 244, 409, 458, 671,-32766, + 463, 524, 552, 10, 373, -80, 738, 101, 510, 37, + 20, 411, 995, 412, 519, 413, 525, 414, 1034, 535, + 415, 773, 267, 565, 38, 39, 361, 380, 536, 40, + 416, 261, 806, 65, 262, 376, 293, 1033, 0, 234, + 749, 264, 0, 1031, 419, 874, 0, 350, 12, 0, + 0, 0, 774, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 409, 0, 0, 0, 566, + 0, 25, 296, 751, 558, 738, -412, 5, 37, 20, + 411, 0, 412, 1052, 413, 351, 414, 1018, 327, 415, + 338, 749, 334, 38, 39, 361, 333, 460, 40, 416, + 765, 559, 65, 729, 580, 293, 36, 35, 579, 790, + 867, 409, 797, 419, 870, 869, 995, 866, 785, 727, + 564, 738, 798, 749, 37, 20, 411, 787, 412, 858, + 413, 857, 414, 422, 423, 415, 868, 796, 561, 38, + 39, 361, 751, 558, 40, 416, 344, 343, 65, 563, + 279, 293, 573, 795, 278, 68, 574, 570, 568, 419, + 270, 567, 409, 562, 41, 749, 756, 766, 758, 692, + 983, 769, 738, 725, 1046, 37, 20, 411, 1101, 412, + 1103, 413, 684, 414, 771, 683, 415, 693, 789, 558, + 38, 39, 361, 770, 409, 40, 416, 694, 691, 65, + 1100, 1053, 293, 1102, 738, 1060, 1065, 37, 20, 411, + 419, 412, 1068, 413, 576, 414, 34, 27, 415, 26, + 23, -456, 38, 39, 361, -457, -458, 40, 416, -480, + -482, 65, 240, 348, 293, 346, 409, 281, 243, 751, + 558, 242, 419, 241, 224, 223, 738, 136, 132, 37, + 20, 411, 127, 412, 73, 413, 72, 414, 71, 70, + 415, 69, 67, 515, 38, 39, 361, 959, 962, 40, + 416, 751, 558, 65, 551, 1015, 293,-32766,-32766,-32766, + 506, 487, 316, 255, 419, 22, 18, 13, -236, 987, + 839, 1016, 958, 1006, 549, 406, 399, 397,-32766, 393, + -32766,-32766,-32766,-32766,-32766,-32766,-32767,-32767,-32767,-32767, + -32767, 317, 19, 751, 558, 17, -91, 0, 16, 15, + 14, -233, -234, 0, 975, -424, 0, 1098, 1059, 1045, + 1044 + ); + + protected $actionCheck = array( + 2, 3, 4, 5, 6, 78, 8, 9, 10, 11, + 12, 0, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 8, 9, 10, 1, 78, + 113, 114, 115, 116, 117, 118, 113, 114, 115, 116, + 117, 118, 1, 55, 57, 58, 29, 7, 31, 32, + 33, 34, 35, 36, 8, 9, 29, 69, 70, 71, + 72, 73, 74, 75, 113, 1, 78, 8, 9, 10, + 1, 8, 13, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, + 122, 123, 124, 125, 126, 127, 128, 13, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 2, 3, 4, + 5, 6, 144, 145, 146, 7, 11, 12, 7, 14, + 8, 9, 10, 7, 103, 104, 1, 8, 9, 10, + 68, 110, 30, 13, 8, 9, 10, 1, 131, 132, + 119, 29, 1, 31, 32, 33, 34, 35, 29, 68, + 31, 32, 33, 48, 49, 29, 78, 31, 32, 54, + 7, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 151, 68, 69, 70, 71, 8, 9, 10, + 78, 76, 77, 78, 80, 80, 7, 83, 49, 84, + 1, 129, 1, 51, 52, 53, 13, 55, 29, 150, + 31, 32, 33, 34, 7, 143, 78, 29, 103, 67, + 129, 36, 150, 36, 152, 113, 29, 78, 113, 7, + 81, 80, 144, 7, 143, 147, 121, 122, 7, 151, + 7, 150, 1, 152, 7, 130, 131, 153, 133, 134, + 135, 136, 137, 138, 139, 141, 142, 68, 1, 144, + 145, 146, 147, 78, 113, 78, 7, 152, 7, 154, + 15, 156, 157, 72, 73, 74, 75, 0, 1, 80, + 80, 1, 144, 82, 149, 147, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 150, 96, 113, 36, + 113, 100, 101, 102, 103, 7, 105, 106, 157, 7, + 109, 1, 113, 112, 68, 114, 115, 7, 129, 131, + 132, 120, 68, 124, 123, 124, 125, 126, 131, 132, + 7, 68, 143, 148, 80, 148, 95, 80, 84, 150, + 153, 153, 153, 80, 8, 9, 10, 84, 1, 72, + 149, 150, 151, 78, 79, 29, 157, 157, 78, 82, + 153, 7, 85, 86, 87, 29, 89, 113, 91, 30, + 93, 30, 7, 96, 36, 129, 113, 100, 101, 102, + 103, 104, 105, 106, 153, 131, 109, 110, 113, 112, + 153, 114, 115, 130, 131, 7, 150, 120, 7, 68, + 123, 124, 125, 126, 30, 68, 152, 150, 8, 9, + 10, 157, 153, 36, 157, 152, 78, 68, 1, 72, + 157, 144, 98, 99, 103, 104, 149, 150, 151, 82, + 150, 15, 85, 86, 87, 36, 89, 15, 91, 147, + 93, 15, 150, 96, 97, 98, 99, 100, 101, 102, + 103, 113, 105, 106, 7, 78, 109, 131, 132, 112, + 129, 114, 115, 153, 83, 155, 129, 120, 147, 36, + 123, 124, 125, 126, 143, 7, 153, 78, 129, 153, + 143, 150, 48, 49, 50, 73, 74, 150, 149, 72, + 113, 150, 73, 74, 107, 108, 149, 150, 151, 82, + 103, 104, 85, 86, 87, 15, 89, 153, 91, 15, + 93, 78, 113, 96, 97, 98, 99, 100, 101, 102, + 103, 140, 105, 106, 15, 1, 109, 103, 104, 112, + 15, 114, 115, 103, 104, 131, 132, 120, 149, 150, + 123, 124, 125, 126, 153, 34, 113, 30, 8, 9, + 10, 30, 30, 30, 30, 30, 36, 55, 67, 75, + 68, 68, 80, 78, 78, 78, 149, 150, 151, 29, + 81, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 1, 55, 72, 83, 80, 83, + 87, 94, 90, 95, 103, 95, 82, 67, 110, 85, + 86, 87, 113, 89, 88, 91, 97, 93, 140, 92, + 96, 124, 127, 30, 100, 101, 102, 95, 97, 105, + 106, 127, 149, 109, 128, 147, 112, 156, -1, 36, + 1, 111, -1, 140, 120, 149, -1, 147, 143, -1, + -1, -1, 124, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 72, -1, -1, -1, 30, + -1, 68, 143, 149, 150, 82, 143, 143, 85, 86, + 87, -1, 89, 80, 91, 147, 93, 84, 147, 96, + 147, 1, 147, 100, 101, 102, 147, 147, 105, 106, + 148, 150, 109, 149, 149, 112, 149, 149, 149, 149, + 149, 72, 149, 120, 149, 149, 113, 149, 149, 149, + 30, 82, 149, 1, 85, 86, 87, 149, 89, 149, + 91, 149, 93, 130, 131, 96, 149, 151, 150, 100, + 101, 102, 149, 150, 105, 106, 150, 150, 109, 150, + 150, 112, 30, 151, 150, 152, 150, 150, 150, 120, + 157, 150, 72, 150, 152, 1, 151, 151, 151, 151, + 151, 151, 82, 151, 151, 85, 86, 87, 151, 89, + 151, 91, 151, 93, 151, 151, 96, 151, 149, 150, + 100, 101, 102, 151, 72, 105, 106, 151, 151, 109, + 151, 151, 112, 151, 82, 151, 151, 85, 86, 87, + 120, 89, 151, 91, 151, 93, 152, 152, 96, 152, + 152, 152, 100, 101, 102, 152, 152, 105, 106, 152, + 152, 109, 152, 152, 112, 152, 72, 152, 152, 149, + 150, 152, 120, 152, 152, 152, 82, 152, 152, 85, + 86, 87, 152, 89, 152, 91, 152, 93, 152, 152, + 96, 152, 152, 155, 100, 101, 102, 153, 153, 105, + 106, 149, 150, 109, 153, 155, 112, 8, 9, 10, + 153, 153, 153, 153, 120, 153, 153, 153, 153, 153, + 153, 153, 153, 153, 153, 153, 153, 153, 29, 153, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 153, 153, 149, 150, 153, 153, -1, 153, 153, + 153, 153, 153, -1, 154, 154, -1, 155, 155, 155, + 155 + ); + + protected $actionBase = array( + 0, 221, 297, 367, 437, 277, 108, 607, -2, -2, + -73, -2, -2, 613, 544, 544, 742, 544, 710, 659, + 784, 784, 784, 207, 205, 419, 419, 453, 295, 419, + 453, 132, 397, 358, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, 155, 155, 359, + 261, 150, 750, 735, 748, 753, 754, 749, 734, 213, + 669, 670, 541, 643, 674, 675, 681, 747, 728, 752, + 741, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 73, 69, 56, + 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, + 420, 420, 420, 420, 420, 420, 420, 420, 420, 420, + 356, 356, 356, 156, 209, 149, 199, 351, 142, 27, + 889, 889, 889, 889, 889, -16, -16, -16, -16, 623, + 623, 283, 51, 274, 274, 274, 274, 274, 274, 274, + 274, 274, 274, 274, 274, 274, 219, 450, 454, 454, + 346, 346, 346, 346, 171, 208, 37, 217, 401, 498, + 501, 300, 300, 424, 92, 111, 172, 172, 172, 341, + 534, 519, 519, 519, 519, 134, 134, 519, 519, 169, + 79, 330, 351, 351, 357, 351, 351, 351, 444, 444, + 444, 158, 312, 536, 158, 516, 633, 539, 622, 551, + 606, 266, 520, 220, 521, 558, 220, 220, 220, 407, + 432, 439, 783, 155, 553, 155, 155, 155, 155, 700, + 155, 155, 155, 155, 155, 155, 361, 155, 74, 409, + 359, 166, 166, 531, 166, 522, 369, 624, 343, 279, + 522, 522, 522, 620, 617, 251, 227, 114, 616, 374, + 417, 411, 257, 507, 507, 506, 506, 502, 540, 507, + 507, 507, 507, 507, 688, 688, 506, 538, 506, 502, + 632, 506, 540, 506, 506, 507, 506, 688, 540, 141, + 385, 253, 281, 540, 408, 524, 507, 515, 515, 467, + 506, 146, 506, 50, 526, 688, 688, 526, 183, 540, + 242, 579, 575, 518, 572, 246, 542, 542, 322, 518, + 540, 542, 488, 138, 538, 318, 542, 11, 730, 729, + 537, 727, 684, 726, 703, 724, 571, 517, 548, 713, + 712, 722, 685, 687, 394, 570, 275, 436, 554, 512, + 689, 521, 508, 511, 511, 511, 512, 694, 511, 511, + 511, 511, 511, 511, 511, 511, 740, 549, 533, 442, + 561, 552, 446, 608, 523, 570, 570, 642, 791, 790, + 505, 700, 760, 720, 578, 510, 779, 711, 683, 569, + 565, 709, 778, 759, 619, 275, 758, 647, 513, 649, + 570, 651, 511, 697, 698, 795, 794, 693, 793, 787, + 766, 563, 653, 509, 792, 654, 757, 631, 628, 577, + 786, 755, 764, 656, 763, 662, 574, 546, 789, 527, + 701, 705, 627, 666, 667, 672, 640, 639, 716, 503, + 785, 547, 782, 788, 580, 583, 514, 638, 602, 529, + 535, 600, 715, 545, 504, 598, 593, 756, 637, 706, + 590, 636, 761, 530, 508, 525, 550, 528, 532, 626, + 762, 543, 589, 588, 586, 585, 635, 581, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 135, 135, 135, 135, -2, + -2, -2, 0, 0, -2, 0, 0, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 135, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, -3, 560, + 560, -3, 560, 560, 560, 560, 560, 560, 560, 172, + 172, 172, 172, 158, 158, 158, -67, 158, 158, 158, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 158, -67, 172, 172, 158, 158, 158, 158, 158, 158, + 158, 158, 134, 134, 134, 220, 220, 158, 0, 0, + 0, 0, 0, 507, 134, 158, 158, 158, 158, 0, + 0, 158, 158, 538, 220, 0, 0, 0, 0, 0, + 0, 0, 507, 507, 507, 0, 507, 134, 0, 166, + 155, 344, 344, 344, 344, 0, 507, 0, 538, 507, + 0, 0, 0, 0, 0, 0, 540, 0, 688, 0, + 0, 0, 0, 506, 0, 0, 0, 0, 0, 0, + 0, 0, 538, 0, 0, 0, 0, 538, 0, 511, + 0, 505, 0, 0, 511, 511, 511, 505, 505, 0, + 0, 0, 505 + ); + + protected $actionDefault = array( + 3,32767,32767,32767,32767,32767,32767,32767,32767, 91, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 93, 506, 506, 496,32767, 506, + 496,32767,32767,32767, 313, 313, 313,32767, 451, 451, + 451, 451, 451, 451, 451,32767,32767,32767,32767,32767, + 393,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 91,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 503,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 376, 377, 379, 380, 312, 452, 258, 502, 311, + 129, 269, 260, 210, 242, 309, 133, 341, 394, 343, + 392, 396, 342, 318, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 333, 334, 316, 317, 395, + 373, 372, 371, 339, 315, 340, 344, 315, 346, 345, + 362, 363, 360, 361, 364, 365, 366, 367, 368,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 93,32767,32767,32767, 292, 353, 354, + 249, 249, 249, 249,32767, 249,32767, 249,32767,32767, + 32767,32767,32767,32767, 445, 370, 348, 349, 347,32767, + 423,32767,32767,32767,32767,32767, 425,32767, 91,32767, + 32767,32767, 336, 338, 417, 505, 319, 504,32767,32767, + 93,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 420,32767,32767, 411, 91,32767,32767, 91, 173, + 229, 231, 178,32767, 428,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 358, 513,32767, 453,32767, + 350, 351, 352,32767,32767, 453, 453, 453,32767, 453, + 32767, 453, 453,32767,32767,32767,32767,32767, 178,32767, + 32767,32767,32767, 93, 426, 426, 91, 91, 91, 91, + 421,32767, 178,32767,32767,32767,32767,32767, 178, 90, + 90, 90, 90, 178, 90, 193,32767, 191, 191, 90, + 32767, 92,32767, 92, 195,32767, 467, 195, 90, 178, + 90, 215, 215, 402, 180, 92, 251, 251, 92, 402, + 178, 251, 90, 90,32767, 90, 251,32767,32767,32767, + 84,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 413,32767, 433,32767, 446, + 465, 411,32767, 356, 357, 359,32767, 455, 381, 382, + 383, 384, 385, 386, 387, 389,32767, 416,32767,32767, + 86, 120, 268,32767, 511, 86, 414,32767, 511,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 86, + 86,32767,32767,32767,32767, 492,32767, 512,32767, 453, + 415,32767, 355, 429, 472,32767,32767, 454,32767,32767, + 32767, 86,32767,32767,32767,32767,32767,32767,32767,32767, + 32767, 433,32767,32767,32767,32767,32767,32767, 453,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 453,32767,32767, 241,32767,32767, 308, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 84, 60,32767, 288,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 135, 135, + 3, 271, 3, 271, 135, 135, 135, 271, 271, 135, + 135, 135, 135, 135, 135, 135, 168, 223, 226, 215, + 215, 280, 135, 135 + ); + + protected $goto = array( + 167, 167, 141, 141, 149, 150, 141, 149, 152, 183, + 168, 165, 165, 165, 165, 166, 166, 166, 166, 166, + 166, 166, 161, 162, 163, 164, 180, 178, 181, 433, + 434, 325, 435, 438, 439, 440, 441, 442, 443, 444, + 445, 905, 138, 142, 143, 144, 145, 146, 140, 147, + 148, 151, 177, 179, 182, 200, 203, 205, 206, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 238, 239, 256, 257, 258, 330, 331, 332, 482, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 153, 199, 154, 169, 170, 171, + 201, 172, 155, 156, 157, 173, 158, 202, 139, 159, + 174, 175, 176, 160, 545, 204, 450, 554, 204, 746, + 307, 311, 462, 485, 486, 488, 483, 873, 557, 680, + 992, 496, 539, 871, 484, 455, 455, 455, 288, 455, + 266, 475, 679, 701, 475, 250, 695, 322, 741, 470, + 742, 324, 455, 436, 436, 436, 285, 436, 436, 436, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 437, 437, 437, 715, 437, 437, 437, 437, 437, 437, + 437, 437, 437, 437, 437, 437, 437, 1091, 1091, 481, + 505, 495, 667, 993, 516, 517, 788, 1092, 1092, 841, + 455, 455, 981, 768, 1091, 982, 469, 491, 455, 455, + 455, 994, 1048, 468, 1092, 780, 319, 553, 578, 507, + 509, 1094, 456, 521, 538, 541, 816, 548, 556, 812, + 501, 501, 1017, 480, 1017, 1017, 1017, 1017, 1017, 1017, + 1017, 1017, 1017, 1017, 1017, 1017, 1017, 706, 499, 520, + 678, 502, 504, 550, 1062, 1063, 880, 3, 4, 476, + 1084, 805, 786, 786, 784, 786, 577, 682, 448, 814, + 809, 881, 1072, 305, 447, 522, 473, 953, 836, 1061, + 706, 824, 447, 706, 687, 292, 737, 732, 733, 747, + 347, 688, 734, 685, 735, 736, 686, 829, 740, 782, + 782, 782, 782, 513, 286, 776, 783, 337, 523, 341, + 702, 328, 328, 272, 273, 275, 479, 335, 276, 336, + 277, 339, 508, 342, 699, 289, 290, 315, 582, 846, + 527, 697, 697, 819, 819, 1079, 309, 707, 707, 707, + 709, 696, 461, 989, 996, 984, 850, 471, 830, 830, + 830, 830, 996, 830, 830, 830, 793, 711, 1067, 1067, + 387, 830, 890, 394, 401, 1058, 498, 0, 0, 996, + 996, 996, 996, 1058, 11, 996, 996, 0, 0, 1107, + 1069, 1069, 710, 698, 845, 0, 849, 0, 0, 754, + 0, 791, 755, 0, 0, 0, 0, 0, 0, 1054, + 821, 0, 781, 0, 452, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 888, 714, 467, 988, 0, 0, + 0, 0, 848, 0, 0, 1056, 1056, 848, 526, 0, + 0, 0, 0, 542, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 449, 465, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 449, 0, 465, 0, 452, 308, 0, + 453, 375, 0, 377, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 705, 0, 1099, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 991 + ); + + protected $gotoCheck = array( + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 63, 56, 10, 8, 56, 13, + 49, 49, 49, 49, 49, 49, 7, 7, 7, 18, + 92, 15, 7, 7, 97, 10, 10, 10, 80, 10, + 134, 85, 17, 15, 85, 134, 15, 69, 55, 10, + 55, 69, 10, 135, 135, 135, 69, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 135, + 137, 137, 137, 36, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 137, 147, 147, 2, + 73, 2, 5, 92, 73, 73, 40, 148, 148, 94, + 10, 10, 67, 67, 147, 67, 10, 10, 10, 10, + 10, 92, 92, 39, 148, 76, 76, 76, 39, 39, + 39, 147, 10, 39, 39, 39, 39, 39, 39, 39, + 86, 86, 86, 10, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 26, 46, 46, + 16, 68, 68, 68, 141, 141, 111, 37, 37, 136, + 146, 16, 16, 16, 16, 16, 16, 13, 16, 16, + 16, 111, 143, 52, 75, 54, 53, 118, 90, 139, + 26, 88, 75, 26, 13, 20, 13, 13, 13, 13, + 89, 13, 13, 13, 13, 13, 13, 91, 13, 75, + 75, 75, 75, 24, 11, 75, 75, 56, 56, 56, + 30, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 28, 80, 80, 19, 82, 96, + 23, 26, 26, 85, 85, 85, 65, 26, 26, 26, + 26, 26, 65, 127, 63, 124, 99, 65, 63, 63, + 63, 63, 63, 63, 63, 63, 79, 32, 8, 8, + 71, 63, 114, 65, 122, 97, 72, -1, -1, 63, + 63, 63, 63, 97, 65, 63, 63, -1, -1, 12, + 97, 97, 14, 14, 14, -1, 14, -1, -1, 63, + -1, 14, 63, -1, -1, -1, -1, -1, -1, 97, + 14, -1, 14, -1, 12, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 14, 14, 8, 14, -1, -1, + -1, -1, 97, -1, -1, 97, 97, 97, 12, -1, + -1, -1, -1, 12, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8, 8, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8, -1, 8, -1, 12, 8, -1, + 8, 8, -1, 8, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8, -1, 8, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 12 + ); + + protected $gotoBase = array( + 0, 0, -371, 0, 0, 182, 0, 121, 107, 0, + -143, 22, 110, -19, 12, -252, 248, 140, 127, 35, + 26, 0, 0, -14, 24, 0, -12, 0, 29, 0, + 30, 0, 1, -23, 0, 0, 164, -325, 0, -346, + 177, 0, 0, 0, 0, 0, 213, 0, 0, 81, + 0, 0, 236, 52, 55, 133, 88, 0, 0, 0, + 0, 0, 0, 108, 0, -26, 0, -119, 10, -250, + 0, -18, -21, -373, 0, 38, -47, 0, 0, -2, + -254, 0, 8, 0, 0, 114, 11, 0, 36, 43, + 32, 44, -174, 0, 175, 0, 31, 129, 0, -11, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 34, 0, 0, 3, 0, 0, 0, 33, 0, + 0, 0, -35, 0, -10, 0, 0, -5, 0, 0, + 0, 0, 0, 0, -120, -66, 233, -49, 0, 27, + 0, -42, 0, 242, 0, 0, 231, -62, -52, 0, + 0 + ); + + protected $gotoDefault = array( + -32768, 407, 585, 2, 586, 657, 665, 530, 424, 555, + 425, 451, 326, 739, 894, 759, 721, 722, 723, 312, + 352, 303, 310, 514, 503, 398, 708, 371, 700, 395, + 703, 370, 712, 137, 531, 403, 716, 1, 718, 457, + 750, 300, 726, 301, 534, 728, 464, 730, 731, 306, + 313, 314, 898, 472, 500, 743, 207, 466, 744, 299, + 745, 753, 323, 304, 381, 404, 318, 875, 490, 321, + 366, 384, 497, 492, 474, 1003, 778, 390, 379, 792, + 287, 800, 583, 808, 811, 426, 427, 388, 823, 389, + 834, 828, 1011, 383, 840, 372, 847, 1043, 374, 851, + 222, 854, 247, 528, 340, 859, 860, 6, 865, 546, + 547, 7, 237, 402, 889, 529, 369, 904, 355, 972, + 974, 459, 396, 985, 378, 537, 405, 990, 1047, 367, + 428, 385, 274, 291, 249, 429, 446, 254, 430, 386, + 1050, 1057, 329, 1073, 271, 29, 1085, 1093, 283, 478, + 494 + ); + + protected $ruleToNonTerminal = array( + 0, 1, 3, 3, 2, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, + 14, 14, 15, 15, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 20, 20, 21, 21, 21, + 21, 23, 25, 25, 19, 27, 27, 24, 29, 29, + 26, 26, 28, 28, 30, 30, 22, 31, 31, 32, + 34, 35, 35, 36, 37, 37, 39, 38, 38, 38, + 38, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 16, 16, 59, 59, + 62, 62, 61, 60, 60, 53, 64, 64, 65, 65, + 66, 66, 67, 67, 17, 18, 18, 18, 70, 70, + 70, 71, 71, 74, 74, 72, 72, 76, 77, 77, + 47, 47, 55, 55, 58, 58, 58, 57, 78, 78, + 79, 48, 48, 48, 48, 80, 80, 81, 81, 82, + 82, 45, 45, 41, 41, 83, 43, 43, 84, 42, + 42, 44, 44, 54, 54, 54, 54, 68, 68, 87, + 87, 88, 88, 88, 90, 90, 91, 91, 91, 89, + 89, 69, 69, 69, 92, 92, 93, 93, 94, 94, + 94, 50, 95, 95, 96, 51, 98, 98, 99, 99, + 100, 100, 73, 101, 101, 101, 101, 101, 106, 106, + 107, 107, 108, 108, 108, 108, 108, 109, 110, 110, + 105, 105, 102, 102, 104, 104, 112, 112, 111, 111, + 111, 111, 111, 111, 103, 113, 113, 115, 114, 114, + 52, 116, 116, 46, 46, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 123, + 117, 117, 122, 122, 125, 126, 126, 127, 128, 128, + 128, 75, 75, 63, 63, 63, 118, 118, 118, 130, + 130, 119, 119, 121, 121, 121, 124, 124, 135, 135, + 135, 86, 137, 137, 137, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, + 120, 49, 49, 133, 133, 133, 129, 129, 129, 138, + 138, 138, 138, 138, 138, 56, 56, 56, 97, 97, + 97, 97, 141, 140, 132, 132, 132, 132, 132, 132, + 131, 131, 131, 139, 139, 139, 139, 85, 142, 142, + 143, 143, 143, 143, 143, 143, 143, 136, 145, 145, + 144, 144, 146, 146, 146, 146, 146, 134, 134, 134, + 134, 148, 149, 147, 147, 147, 147, 147, 147, 147, + 150, 150, 150, 150 + ); + + protected $ruleToLength = array( + 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, + 0, 1, 0, 1, 1, 1, 1, 1, 3, 5, + 4, 3, 4, 2, 3, 1, 1, 7, 8, 6, + 7, 2, 3, 1, 2, 3, 1, 2, 3, 1, + 1, 3, 1, 2, 1, 2, 2, 3, 1, 3, + 2, 3, 1, 3, 2, 0, 1, 1, 1, 1, + 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, + 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, + 5, 6, 3, 3, 2, 1, 1, 1, 0, 2, + 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, + 0, 1, 3, 1, 8, 7, 6, 5, 1, 2, + 2, 0, 2, 0, 2, 0, 2, 2, 1, 3, + 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, + 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, + 1, 1, 4, 0, 2, 5, 0, 2, 6, 0, + 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, + 3, 4, 6, 4, 1, 2, 1, 1, 1, 0, + 1, 0, 2, 2, 2, 4, 1, 3, 1, 2, + 2, 2, 3, 1, 1, 2, 3, 1, 1, 3, + 2, 0, 1, 4, 4, 9, 3, 1, 1, 3, + 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, + 1, 1, 1, 1, 0, 1, 1, 2, 1, 1, + 1, 1, 1, 1, 2, 1, 3, 1, 1, 3, + 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, + 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 3, 2, 1, 2, 4, 2, 8, 9, 7, + 3, 2, 0, 4, 2, 1, 3, 2, 2, 2, + 4, 1, 1, 1, 2, 3, 1, 1, 1, 1, + 1, 0, 3, 0, 1, 1, 0, 1, 1, 3, + 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 2, 3, + 3, 0, 1, 1, 3, 1, 1, 3, 1, 1, + 4, 4, 4, 1, 4, 1, 1, 3, 1, 4, + 2, 2, 1, 3, 1, 4, 4, 3, 3, 3, + 1, 3, 1, 1, 3, 1, 1, 4, 3, 1, + 1, 2, 1, 3, 4, 3, 0, 1, 1, 1, + 3, 1, 3, 1, 4, 2, 0, 2, 2, 1, + 2, 1, 1, 1, 4, 3, 3, 3, 6, 3, + 1, 1, 2, 1 + ); + + protected function initReduceCallbacks() { + $this->reduceCallbacks = [ + 0 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 1 => function ($stackPos) { + $this->semValue = $this->handleNamespaces($this->semStack[$stackPos-(1-1)]); + }, + 2 => function ($stackPos) { + if (is_array($this->semStack[$stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); } else { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }; + }, + 3 => function ($stackPos) { + $this->semValue = array(); + }, + 4 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 5 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 6 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 7 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 8 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 9 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 10 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 11 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 12 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 13 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 14 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 15 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 16 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 17 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 18 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 19 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 20 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 21 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 22 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 23 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 24 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 25 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 26 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 27 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 28 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 29 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 30 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 31 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 32 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 33 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 34 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 35 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 36 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 37 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 38 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 39 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 40 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 41 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 42 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 43 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 44 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 45 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 46 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 47 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 48 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 49 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 50 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 51 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 52 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 53 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 54 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 55 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 56 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 57 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 58 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 59 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 60 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 61 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 62 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 63 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 64 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 65 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 66 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 67 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 68 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 69 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 70 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 71 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 72 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 73 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 74 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 75 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 76 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 77 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 78 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 79 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 80 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 81 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 82 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 83 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 84 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 85 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 86 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 87 => function ($stackPos) { + $this->semValue = new Expr\Variable(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 88 => function ($stackPos) { + /* nothing */ + }, + 89 => function ($stackPos) { + /* nothing */ + }, + 90 => function ($stackPos) { + /* nothing */ + }, + 91 => function ($stackPos) { + $this->emitError(new Error('A trailing comma is not allowed here', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes)); + }, + 92 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 93 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 94 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 95 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 96 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 97 => function ($stackPos) { + $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 98 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos-(3-2)], null, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); + $this->checkNamespace($this->semValue); + }, + 99 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos-(5-2)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + }, + 100 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); + $this->checkNamespace($this->semValue); + }, + 101 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 102 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 103 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 104 => function ($stackPos) { + $this->semValue = new Stmt\Const_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 105 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_FUNCTION; + }, + 106 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_CONSTANT; + }, + 107 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(7-3)], $this->startAttributeStack[$stackPos-(7-3)] + $this->endAttributeStack[$stackPos-(7-3)]), $this->semStack[$stackPos-(7-6)], $this->semStack[$stackPos-(7-2)], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 108 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(8-4)], $this->startAttributeStack[$stackPos-(8-4)] + $this->endAttributeStack[$stackPos-(8-4)]), $this->semStack[$stackPos-(8-7)], $this->semStack[$stackPos-(8-2)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 109 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(6-2)], $this->startAttributeStack[$stackPos-(6-2)] + $this->endAttributeStack[$stackPos-(6-2)]), $this->semStack[$stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 110 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(7-3)], $this->startAttributeStack[$stackPos-(7-3)] + $this->endAttributeStack[$stackPos-(7-3)]), $this->semStack[$stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 111 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 112 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 113 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 114 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 115 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 116 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 117 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 118 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 119 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 120 => function ($stackPos) { + $this->semValue = new Stmt\UseUse($this->semStack[$stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $stackPos-(1-1)); + }, + 121 => function ($stackPos) { + $this->semValue = new Stmt\UseUse($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $stackPos-(3-3)); + }, + 122 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 123 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 124 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; + }, + 125 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; $this->semValue->type = $this->semStack[$stackPos-(2-1)]; + }, + 126 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 127 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 128 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 129 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 130 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 131 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 132 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 133 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 134 => function ($stackPos) { + if (is_array($this->semStack[$stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); } else { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }; + }, + 135 => function ($stackPos) { + $this->semValue = array(); + }, + 136 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 137 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 138 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 139 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 140 => function ($stackPos) { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 141 => function ($stackPos) { + + if ($this->semStack[$stackPos-(3-2)]) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; $attrs = $this->startAttributeStack[$stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; + } else { + $startAttributes = $this->startAttributeStack[$stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $this->semValue = null; }; + if (null === $this->semValue) { $this->semValue = array(); } + } + + }, + 142 => function ($stackPos) { + $this->semValue = new Stmt\If_($this->semStack[$stackPos-(7-3)], ['stmts' => is_array($this->semStack[$stackPos-(7-5)]) ? $this->semStack[$stackPos-(7-5)] : array($this->semStack[$stackPos-(7-5)]), 'elseifs' => $this->semStack[$stackPos-(7-6)], 'else' => $this->semStack[$stackPos-(7-7)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 143 => function ($stackPos) { + $this->semValue = new Stmt\If_($this->semStack[$stackPos-(10-3)], ['stmts' => $this->semStack[$stackPos-(10-6)], 'elseifs' => $this->semStack[$stackPos-(10-7)], 'else' => $this->semStack[$stackPos-(10-8)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); + }, + 144 => function ($stackPos) { + $this->semValue = new Stmt\While_($this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 145 => function ($stackPos) { + $this->semValue = new Stmt\Do_($this->semStack[$stackPos-(7-5)], is_array($this->semStack[$stackPos-(7-2)]) ? $this->semStack[$stackPos-(7-2)] : array($this->semStack[$stackPos-(7-2)]), $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 146 => function ($stackPos) { + $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos-(9-3)], 'cond' => $this->semStack[$stackPos-(9-5)], 'loop' => $this->semStack[$stackPos-(9-7)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 147 => function ($stackPos) { + $this->semValue = new Stmt\Switch_($this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 148 => function ($stackPos) { + $this->semValue = new Stmt\Break_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 149 => function ($stackPos) { + $this->semValue = new Stmt\Continue_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 150 => function ($stackPos) { + $this->semValue = new Stmt\Return_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 151 => function ($stackPos) { + $this->semValue = new Stmt\Global_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 152 => function ($stackPos) { + $this->semValue = new Stmt\Static_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 153 => function ($stackPos) { + $this->semValue = new Stmt\Echo_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 154 => function ($stackPos) { + $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 155 => function ($stackPos) { + $this->semValue = new Stmt\Expression($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 156 => function ($stackPos) { + $this->semValue = new Stmt\Unset_($this->semStack[$stackPos-(5-3)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 157 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(7-3)], $this->semStack[$stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos-(7-5)][1], 'stmts' => $this->semStack[$stackPos-(7-7)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 158 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(9-3)], $this->semStack[$stackPos-(9-7)][0], ['keyVar' => $this->semStack[$stackPos-(9-5)], 'byRef' => $this->semStack[$stackPos-(9-7)][1], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 159 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(6-3)], new Expr\Error($this->startAttributeStack[$stackPos-(6-4)] + $this->endAttributeStack[$stackPos-(6-4)]), ['stmts' => $this->semStack[$stackPos-(6-6)]], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 160 => function ($stackPos) { + $this->semValue = new Stmt\Declare_($this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 161 => function ($stackPos) { + $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-5)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); + }, + 162 => function ($stackPos) { + $this->semValue = new Stmt\Throw_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 163 => function ($stackPos) { + $this->semValue = new Stmt\Goto_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 164 => function ($stackPos) { + $this->semValue = new Stmt\Label($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 165 => function ($stackPos) { + $this->semValue = array(); /* means: no statement */ + }, + 166 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 167 => function ($stackPos) { + $startAttributes = $this->startAttributeStack[$stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $this->semValue = null; }; + if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ + }, + 168 => function ($stackPos) { + $this->semValue = array(); + }, + 169 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 170 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 171 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 172 => function ($stackPos) { + $this->semValue = new Stmt\Catch_($this->semStack[$stackPos-(8-3)], $this->semStack[$stackPos-(8-4)], $this->semStack[$stackPos-(8-7)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 173 => function ($stackPos) { + $this->semValue = null; + }, + 174 => function ($stackPos) { + $this->semValue = new Stmt\Finally_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 175 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 176 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 177 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 178 => function ($stackPos) { + $this->semValue = false; + }, + 179 => function ($stackPos) { + $this->semValue = true; + }, + 180 => function ($stackPos) { + $this->semValue = false; + }, + 181 => function ($stackPos) { + $this->semValue = true; + }, + 182 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 183 => function ($stackPos) { + $this->semValue = []; + }, + 184 => function ($stackPos) { + $this->semValue = new Stmt\Function_($this->semStack[$stackPos-(8-3)], ['byRef' => $this->semStack[$stackPos-(8-2)], 'params' => $this->semStack[$stackPos-(8-5)], 'returnType' => $this->semStack[$stackPos-(8-7)], 'stmts' => $this->semStack[$stackPos-(8-8)]], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 185 => function ($stackPos) { + $this->semValue = new Stmt\Class_($this->semStack[$stackPos-(7-2)], ['type' => $this->semStack[$stackPos-(7-1)], 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + $this->checkClass($this->semValue, $stackPos-(7-2)); + }, + 186 => function ($stackPos) { + $this->semValue = new Stmt\Interface_($this->semStack[$stackPos-(6-2)], ['extends' => $this->semStack[$stackPos-(6-3)], 'stmts' => $this->semStack[$stackPos-(6-5)]], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + $this->checkInterface($this->semValue, $stackPos-(6-2)); + }, + 187 => function ($stackPos) { + $this->semValue = new Stmt\Trait_($this->semStack[$stackPos-(5-2)], ['stmts' => $this->semStack[$stackPos-(5-4)]], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 188 => function ($stackPos) { + $this->semValue = 0; + }, + 189 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + }, + 190 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + }, + 191 => function ($stackPos) { + $this->semValue = null; + }, + 192 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 193 => function ($stackPos) { + $this->semValue = array(); + }, + 194 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 195 => function ($stackPos) { + $this->semValue = array(); + }, + 196 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 197 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 198 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 199 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 200 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 201 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 202 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 203 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 204 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 205 => function ($stackPos) { + $this->semValue = null; + }, + 206 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 207 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 208 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 209 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 210 => function ($stackPos) { + $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 211 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 212 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 213 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 214 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(5-3)]; + }, + 215 => function ($stackPos) { + $this->semValue = array(); + }, + 216 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 217 => function ($stackPos) { + $this->semValue = new Stmt\Case_($this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 218 => function ($stackPos) { + $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 219 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 220 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 221 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 222 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 223 => function ($stackPos) { + $this->semValue = array(); + }, + 224 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 225 => function ($stackPos) { + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(5-3)], is_array($this->semStack[$stackPos-(5-5)]) ? $this->semStack[$stackPos-(5-5)] : array($this->semStack[$stackPos-(5-5)]), $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 226 => function ($stackPos) { + $this->semValue = array(); + }, + 227 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 228 => function ($stackPos) { + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 229 => function ($stackPos) { + $this->semValue = null; + }, + 230 => function ($stackPos) { + $this->semValue = new Stmt\Else_(is_array($this->semStack[$stackPos-(2-2)]) ? $this->semStack[$stackPos-(2-2)] : array($this->semStack[$stackPos-(2-2)]), $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 231 => function ($stackPos) { + $this->semValue = null; + }, + 232 => function ($stackPos) { + $this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 233 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 234 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(2-2)], true); + }, + 235 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 236 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 237 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 238 => function ($stackPos) { + $this->semValue = array(); + }, + 239 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 240 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 241 => function ($stackPos) { + $this->semValue = new Node\Param($this->semStack[$stackPos-(4-4)], null, $this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); + }, + 242 => function ($stackPos) { + $this->semValue = new Node\Param($this->semStack[$stackPos-(6-4)], $this->semStack[$stackPos-(6-6)], $this->semStack[$stackPos-(6-1)], $this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-3)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); + }, + 243 => function ($stackPos) { + $this->semValue = new Node\Param(new Expr\Error($this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes), null, $this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 244 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 245 => function ($stackPos) { + $this->semValue = new Node\NullableType($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 246 => function ($stackPos) { + $this->semValue = $this->handleBuiltinTypes($this->semStack[$stackPos-(1-1)]); + }, + 247 => function ($stackPos) { + $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 248 => function ($stackPos) { + $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 249 => function ($stackPos) { + $this->semValue = null; + }, + 250 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 251 => function ($stackPos) { + $this->semValue = null; + }, + 252 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 253 => function ($stackPos) { + $this->semValue = null; + }, + 254 => function ($stackPos) { + $this->semValue = array(); + }, + 255 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 256 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 257 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 258 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(1-1)], false, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 259 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], true, false, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 260 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], false, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 261 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 262 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 263 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 264 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 265 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 266 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 267 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 268 => function ($stackPos) { + $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 269 => function ($stackPos) { + $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 270 => function ($stackPos) { + if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; } + }, + 271 => function ($stackPos) { + $this->semValue = array(); + }, + 272 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 273 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; + $this->semValue = new Stmt\Property($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $attrs, $this->semStack[$stackPos-(4-2)]); $this->checkProperty($this->semValue, $stackPos-(4-1)); + }, + 274 => function ($stackPos) { + $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-1)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); $this->checkClassConst($this->semValue, $stackPos-(4-1)); + }, + 275 => function ($stackPos) { + $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos-(9-4)], ['type' => $this->semStack[$stackPos-(9-1)], 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-6)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + $this->checkClassMethod($this->semValue, $stackPos-(9-1)); + }, + 276 => function ($stackPos) { + $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 277 => function ($stackPos) { + $this->semValue = null; /* will be skipped */ + }, + 278 => function ($stackPos) { + $this->semValue = array(); + }, + 279 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 280 => function ($stackPos) { + $this->semValue = array(); + }, + 281 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 282 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 283 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(5-1)][0], $this->semStack[$stackPos-(5-1)][1], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 284 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], null, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 285 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 286 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 287 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)]); + }, + 288 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 289 => function ($stackPos) { + $this->semValue = array(null, $this->semStack[$stackPos-(1-1)]); + }, + 290 => function ($stackPos) { + $this->semValue = null; + }, + 291 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 292 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 293 => function ($stackPos) { + $this->semValue = 0; + }, + 294 => function ($stackPos) { + $this->semValue = 0; + }, + 295 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 296 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 297 => function ($stackPos) { + $this->checkModifier($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $this->semValue = $this->semStack[$stackPos-(2-1)] | $this->semStack[$stackPos-(2-2)]; + }, + 298 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; + }, + 299 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; + }, + 300 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; + }, + 301 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_STATIC; + }, + 302 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + }, + 303 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + }, + 304 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 305 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 306 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 307 => function ($stackPos) { + $this->semValue = new Node\VarLikeIdentifier(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 308 => function ($stackPos) { + $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 309 => function ($stackPos) { + $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 310 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 311 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 312 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 313 => function ($stackPos) { + $this->semValue = array(); + }, + 314 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 315 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 316 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 317 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 318 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 319 => function ($stackPos) { + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 320 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 321 => function ($stackPos) { + $this->semValue = new Expr\Clone_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 322 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 323 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 324 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 325 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 326 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 327 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 328 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 329 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 330 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 331 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 332 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 333 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 334 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Coalesce($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 335 => function ($stackPos) { + $this->semValue = new Expr\PostInc($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 336 => function ($stackPos) { + $this->semValue = new Expr\PreInc($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 337 => function ($stackPos) { + $this->semValue = new Expr\PostDec($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 338 => function ($stackPos) { + $this->semValue = new Expr\PreDec($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 339 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 340 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 341 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 342 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 343 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 344 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 345 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 346 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 347 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 348 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 349 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 350 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 351 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 352 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 353 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 354 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 355 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 356 => function ($stackPos) { + $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 357 => function ($stackPos) { + $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 358 => function ($stackPos) { + $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 359 => function ($stackPos) { + $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 360 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 361 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 362 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 363 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 364 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 365 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 366 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 367 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 368 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 369 => function ($stackPos) { + $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 370 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 371 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(5-1)], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 372 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(4-1)], null, $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 373 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 374 => function ($stackPos) { + $this->semValue = new Expr\Isset_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 375 => function ($stackPos) { + $this->semValue = new Expr\Empty_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 376 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 377 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 378 => function ($stackPos) { + $this->semValue = new Expr\Eval_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 379 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 380 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 381 => function ($stackPos) { + $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 382 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; + $attrs['kind'] = $this->getFloatCastKind($this->semStack[$stackPos-(2-1)]); + $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos-(2-2)], $attrs); + }, + 383 => function ($stackPos) { + $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 384 => function ($stackPos) { + $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 385 => function ($stackPos) { + $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 386 => function ($stackPos) { + $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 387 => function ($stackPos) { + $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 388 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; + $attrs['kind'] = strtolower($this->semStack[$stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $this->semValue = new Expr\Exit_($this->semStack[$stackPos-(2-2)], $attrs); + }, + 389 => function ($stackPos) { + $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 390 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 391 => function ($stackPos) { + $this->semValue = new Expr\ShellExec($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 392 => function ($stackPos) { + $this->semValue = new Expr\Print_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 393 => function ($stackPos) { + $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 394 => function ($stackPos) { + $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(2-2)], null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 395 => function ($stackPos) { + $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 396 => function ($stackPos) { + $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 397 => function ($stackPos) { + $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$stackPos-(8-2)], 'params' => $this->semStack[$stackPos-(8-4)], 'uses' => $this->semStack[$stackPos-(8-6)], 'returnType' => $this->semStack[$stackPos-(8-7)], 'stmts' => $this->semStack[$stackPos-(8-8)]], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 398 => function ($stackPos) { + $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-5)], 'uses' => $this->semStack[$stackPos-(9-7)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 399 => function ($stackPos) { + $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes), $this->semStack[$stackPos-(7-2)]); + $this->checkClass($this->semValue[0], -1); + }, + 400 => function ($stackPos) { + $this->semValue = new Expr\New_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 401 => function ($stackPos) { + list($class, $ctorArgs) = $this->semStack[$stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 402 => function ($stackPos) { + $this->semValue = array(); + }, + 403 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 404 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 405 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 406 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 407 => function ($stackPos) { + $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos-(2-2)], $this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 408 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 409 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 410 => function ($stackPos) { + $this->semValue = new Expr\StaticCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 411 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 412 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 413 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 414 => function ($stackPos) { + $this->semValue = new Name\FullyQualified($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 415 => function ($stackPos) { + $this->semValue = new Name\Relative($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 416 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 417 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 418 => function ($stackPos) { + $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + }, + 419 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 420 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 421 => function ($stackPos) { + $this->semValue = null; + }, + 422 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 423 => function ($stackPos) { + $this->semValue = array(); + }, + 424 => function ($stackPos) { + $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos-(1-1)], '`'), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes)); + }, + 425 => function ($stackPos) { + foreach ($this->semStack[$stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', true); } }; $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 426 => function ($stackPos) { + $this->semValue = array(); + }, + 427 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 428 => function ($stackPos) { + $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 429 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 430 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], new Expr\Error($this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)]), $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->errorState = 2; + }, + 431 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(3-2)], $attrs); + }, + 432 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(4-3)], $attrs); + }, + 433 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 434 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(1-1)][0] === "'" || ($this->semStack[$stackPos-(1-1)][1] === "'" && ($this->semStack[$stackPos-(1-1)][0] === 'b' || $this->semStack[$stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(1-1)]), $attrs); + }, + 435 => function ($stackPos) { + $this->semValue = $this->parseLNumber($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 436 => function ($stackPos) { + $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$stackPos-(1-1)]), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 437 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 438 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 439 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 440 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 441 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 442 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 443 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 444 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 445 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 446 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 447 => function ($stackPos) { + $this->semValue = $this->parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)], true); + }, + 448 => function ($stackPos) { + $this->semValue = $this->parseDocString($this->semStack[$stackPos-(2-1)], '', $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(2-2)] + $this->endAttributeStack[$stackPos-(2-2)], true); + }, + 449 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($this->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos-(3-2)], $attrs); + }, + 450 => function ($stackPos) { + $this->semValue = $this->parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes, $this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)], true); + }, + 451 => function ($stackPos) { + $this->semValue = null; + }, + 452 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 453 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 454 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 455 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 456 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 457 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 458 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 459 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 460 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 461 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 462 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 463 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 464 => function ($stackPos) { + $this->semValue = new Expr\MethodCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 465 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 466 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 467 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 468 => function ($stackPos) { + $this->semValue = substr($this->semStack[$stackPos-(1-1)], 1); + }, + 469 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 470 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 471 => function ($stackPos) { + $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); $this->errorState = 2; + }, + 472 => function ($stackPos) { + $var = $this->semStack[$stackPos-(1-1)]; $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes) : $var; + }, + 473 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 474 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 475 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 476 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 477 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 478 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 479 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 480 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 481 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 482 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 483 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 484 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 485 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 486 => function ($stackPos) { + $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + }, + 487 => function ($stackPos) { + $this->semValue = new Expr\List_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 488 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 489 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 490 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 491 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 492 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 493 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 494 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-1)], true, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 495 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 496 => function ($stackPos) { + $this->semValue = null; + }, + 497 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; $end = count($this->semValue)-1; if ($this->semValue[$end] === null) array_pop($this->semValue); + }, + 498 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 499 => function ($stackPos) { + /* do nothing -- prevent default action of $$=$this->semStack[$1]. See $551. */ + }, + 500 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 501 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 502 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 503 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 504 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-1)], true, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 505 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 506 => function ($stackPos) { + $this->semValue = null; + }, + 507 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 508 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 509 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 510 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); + }, + 511 => function ($stackPos) { + $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 512 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 513 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 514 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 515 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 516 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 517 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 518 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-4)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 519 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 520 => function ($stackPos) { + $this->semValue = new Scalar\String_($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 521 => function ($stackPos) { + $this->semValue = $this->parseNumString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 522 => function ($stackPos) { + $this->semValue = $this->parseNumString('-' . $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 523 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + ]; + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/Parser/Tokens.php b/vendor/nikic/php-parser/lib/PhpParser/Parser/Tokens.php new file mode 100644 index 00000000..3fb3fb44 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/Parser/Tokens.php @@ -0,0 +1,145 @@ +lexer = $lexer; + + if (isset($options['throwOnError'])) { + throw new \LogicException( + '"throwOnError" is no longer supported, use "errorHandler" instead'); + } + + $this->initReduceCallbacks(); + } + + /** + * Parses PHP code into a node tree. + * + * If a non-throwing error handler is used, the parser will continue parsing after an error + * occurred and attempt to build a partial AST. + * + * @param string $code The source code to parse + * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults + * to ErrorHandler\Throwing. + * + * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and + * the parser was unable to recover from an error). + */ + public function parse(string $code, ErrorHandler $errorHandler = null) { + $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing; + + $this->lexer->startLexing($code, $this->errorHandler); + $result = $this->doParse(); + + // Clear out some of the interior state, so we don't hold onto unnecessary + // memory between uses of the parser + $this->startAttributeStack = []; + $this->endAttributeStack = []; + $this->semStack = []; + $this->semValue = null; + + return $result; + } + + protected function doParse() { + // We start off with no lookahead-token + $symbol = self::SYMBOL_NONE; + + // The attributes for a node are taken from the first and last token of the node. + // From the first token only the startAttributes are taken and from the last only + // the endAttributes. Both are merged using the array union operator (+). + $startAttributes = []; + $endAttributes = []; + $this->endAttributes = $endAttributes; + + // Keep stack of start and end attributes + $this->startAttributeStack = []; + $this->endAttributeStack = [$endAttributes]; + + // Start off in the initial state and keep a stack of previous states + $state = 0; + $stateStack = [$state]; + + // Semantic value stack (contains values of tokens and semantic action results) + $this->semStack = []; + + // Current position in the stack(s) + $stackPos = 0; + + $this->errorState = 0; + + for (;;) { + //$this->traceNewState($state, $symbol); + + if ($this->actionBase[$state] === 0) { + $rule = $this->actionDefault[$state]; + } else { + if ($symbol === self::SYMBOL_NONE) { + // Fetch the next token id from the lexer and fetch additional info by-ref. + // The end attributes are fetched into a temporary variable and only set once the token is really + // shifted (not during read). Otherwise you would sometimes get off-by-one errors, when a rule is + // reduced after a token was read but not yet shifted. + $tokenId = $this->lexer->getNextToken($tokenValue, $startAttributes, $endAttributes); + + // map the lexer token id to the internally used symbols + $symbol = $tokenId >= 0 && $tokenId < $this->tokenToSymbolMapSize + ? $this->tokenToSymbol[$tokenId] + : $this->invalidSymbol; + + if ($symbol === $this->invalidSymbol) { + throw new \RangeException(sprintf( + 'The lexer returned an invalid token (id=%d, value=%s)', + $tokenId, $tokenValue + )); + } + + // This is necessary to assign some meaningful attributes to /* empty */ productions. They'll get + // the attributes of the next token, even though they don't contain it themselves. + $this->startAttributeStack[$stackPos+1] = $startAttributes; + $this->endAttributeStack[$stackPos+1] = $endAttributes; + $this->lookaheadStartAttributes = $startAttributes; + + //$this->traceRead($symbol); + } + + $idx = $this->actionBase[$state] + $symbol; + if ((($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) + || ($state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol)) + && ($action = $this->action[$idx]) !== $this->defaultAction) { + /* + * >= numNonLeafStates: shift and reduce + * > 0: shift + * = 0: accept + * < 0: reduce + * = -YYUNEXPECTED: error + */ + if ($action > 0) { + /* shift */ + //$this->traceShift($symbol); + + ++$stackPos; + $stateStack[$stackPos] = $state = $action; + $this->semStack[$stackPos] = $tokenValue; + $this->startAttributeStack[$stackPos] = $startAttributes; + $this->endAttributeStack[$stackPos] = $endAttributes; + $this->endAttributes = $endAttributes; + $symbol = self::SYMBOL_NONE; + + if ($this->errorState) { + --$this->errorState; + } + + if ($action < $this->numNonLeafStates) { + continue; + } + + /* $yyn >= numNonLeafStates means shift-and-reduce */ + $rule = $action - $this->numNonLeafStates; + } else { + $rule = -$action; + } + } else { + $rule = $this->actionDefault[$state]; + } + } + + for (;;) { + if ($rule === 0) { + /* accept */ + //$this->traceAccept(); + return $this->semValue; + } elseif ($rule !== $this->unexpectedTokenRule) { + /* reduce */ + //$this->traceReduce($rule); + + try { + $this->reduceCallbacks[$rule]($stackPos); + } catch (Error $e) { + if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) { + $e->setStartLine($startAttributes['startLine']); + } + + $this->emitError($e); + // Can't recover from this type of error + return null; + } + + /* Goto - shift nonterminal */ + $lastEndAttributes = $this->endAttributeStack[$stackPos]; + $stackPos -= $this->ruleToLength[$rule]; + $nonTerminal = $this->ruleToNonTerminal[$rule]; + $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos]; + if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] === $nonTerminal) { + $state = $this->goto[$idx]; + } else { + $state = $this->gotoDefault[$nonTerminal]; + } + + ++$stackPos; + $stateStack[$stackPos] = $state; + $this->semStack[$stackPos] = $this->semValue; + $this->endAttributeStack[$stackPos] = $lastEndAttributes; + } else { + /* error */ + switch ($this->errorState) { + case 0: + $msg = $this->getErrorMessage($symbol, $state); + $this->emitError(new Error($msg, $startAttributes + $endAttributes)); + // Break missing intentionally + case 1: + case 2: + $this->errorState = 3; + + // Pop until error-expecting state uncovered + while (!( + (($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) + || ($state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $this->errorSymbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) + ) || ($action = $this->action[$idx]) === $this->defaultAction) { // Not totally sure about this + if ($stackPos <= 0) { + // Could not recover from error + return null; + } + $state = $stateStack[--$stackPos]; + //$this->tracePop($state); + } + + //$this->traceShift($this->errorSymbol); + ++$stackPos; + $stateStack[$stackPos] = $state = $action; + + // We treat the error symbol as being empty, so we reset the end attributes + // to the end attributes of the last non-error symbol + $this->endAttributeStack[$stackPos] = $this->endAttributeStack[$stackPos - 1]; + $this->endAttributes = $this->endAttributeStack[$stackPos - 1]; + break; + + case 3: + if ($symbol === 0) { + // Reached EOF without recovering from error + return null; + } + + //$this->traceDiscard($symbol); + $symbol = self::SYMBOL_NONE; + break 2; + } + } + + if ($state < $this->numNonLeafStates) { + break; + } + + /* >= numNonLeafStates means shift-and-reduce */ + $rule = $state - $this->numNonLeafStates; + } + } + + throw new \RuntimeException('Reached end of parser loop'); + } + + protected function emitError(Error $error) { + $this->errorHandler->handleError($error); + } + + /** + * Format error message including expected tokens. + * + * @param int $symbol Unexpected symbol + * @param int $state State at time of error + * + * @return string Formatted error message + */ + protected function getErrorMessage(int $symbol, int $state) : string { + $expectedString = ''; + if ($expected = $this->getExpectedTokens($state)) { + $expectedString = ', expecting ' . implode(' or ', $expected); + } + + return 'Syntax error, unexpected ' . $this->symbolToName[$symbol] . $expectedString; + } + + /** + * Get limited number of expected tokens in given state. + * + * @param int $state State + * + * @return string[] Expected tokens. If too many, an empty array is returned. + */ + protected function getExpectedTokens(int $state) : array { + $expected = []; + + $base = $this->actionBase[$state]; + foreach ($this->symbolToName as $symbol => $name) { + $idx = $base + $symbol; + if ($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol + || $state < $this->YY2TBLSTATE + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol + ) { + if ($this->action[$idx] !== $this->unexpectedTokenRule + && $this->action[$idx] !== $this->defaultAction + && $symbol !== $this->errorSymbol + ) { + if (count($expected) === 4) { + /* Too many expected tokens */ + return []; + } + + $expected[] = $name; + } + } + } + + return $expected; + } + + /* + * Tracing functions used for debugging the parser. + */ + + /* + protected function traceNewState($state, $symbol) { + echo '% State ' . $state + . ', Lookahead ' . ($symbol == self::SYMBOL_NONE ? '--none--' : $this->symbolToName[$symbol]) . "\n"; + } + + protected function traceRead($symbol) { + echo '% Reading ' . $this->symbolToName[$symbol] . "\n"; + } + + protected function traceShift($symbol) { + echo '% Shift ' . $this->symbolToName[$symbol] . "\n"; + } + + protected function traceAccept() { + echo "% Accepted.\n"; + } + + protected function traceReduce($n) { + echo '% Reduce by (' . $n . ') ' . $this->productions[$n] . "\n"; + } + + protected function tracePop($state) { + echo '% Recovering, uncovered state ' . $state . "\n"; + } + + protected function traceDiscard($symbol) { + echo '% Discard ' . $this->symbolToName[$symbol] . "\n"; + } + */ + + /* + * Helper functions invoked by semantic actions + */ + + /** + * Moves statements of semicolon-style namespaces into $ns->stmts and checks various error conditions. + * + * @param Node\Stmt[] $stmts + * @return Node\Stmt[] + */ + protected function handleNamespaces(array $stmts) : array { + $hasErrored = false; + $style = $this->getNamespacingStyle($stmts); + if (null === $style) { + // not namespaced, nothing to do + return $stmts; + } elseif ('brace' === $style) { + // For braced namespaces we only have to check that there are no invalid statements between the namespaces + $afterFirstNamespace = false; + foreach ($stmts as $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + $afterFirstNamespace = true; + } elseif (!$stmt instanceof Node\Stmt\HaltCompiler + && !$stmt instanceof Node\Stmt\Nop + && $afterFirstNamespace && !$hasErrored) { + $this->emitError(new Error( + 'No code may exist outside of namespace {}', $stmt->getAttributes())); + $hasErrored = true; // Avoid one error for every statement + } + } + return $stmts; + } else { + // For semicolon namespaces we have to move the statements after a namespace declaration into ->stmts + $resultStmts = []; + $targetStmts =& $resultStmts; + $lastNs = null; + foreach ($stmts as $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + if ($lastNs !== null) { + $this->fixupNamespaceAttributes($lastNs); + } + if ($stmt->stmts === null) { + $stmt->stmts = []; + $targetStmts =& $stmt->stmts; + $resultStmts[] = $stmt; + } else { + // This handles the invalid case of mixed style namespaces + $resultStmts[] = $stmt; + $targetStmts =& $resultStmts; + } + $lastNs = $stmt; + } elseif ($stmt instanceof Node\Stmt\HaltCompiler) { + // __halt_compiler() is not moved into the namespace + $resultStmts[] = $stmt; + } else { + $targetStmts[] = $stmt; + } + } + if ($lastNs !== null) { + $this->fixupNamespaceAttributes($lastNs); + } + return $resultStmts; + } + } + + private function fixupNamespaceAttributes(Node\Stmt\Namespace_ $stmt) { + // We moved the statements into the namespace node, as such the end of the namespace node + // needs to be extended to the end of the statements. + if (empty($stmt->stmts)) { + return; + } + + // We only move the builtin end attributes here. This is the best we can do with the + // knowledge we have. + $endAttributes = ['endLine', 'endFilePos', 'endTokenPos']; + $lastStmt = $stmt->stmts[count($stmt->stmts) - 1]; + foreach ($endAttributes as $endAttribute) { + if ($lastStmt->hasAttribute($endAttribute)) { + $stmt->setAttribute($endAttribute, $lastStmt->getAttribute($endAttribute)); + } + } + } + + /** + * Determine namespacing style (semicolon or brace) + * + * @param Node[] $stmts Top-level statements. + * + * @return null|string One of "semicolon", "brace" or null (no namespaces) + */ + private function getNamespacingStyle(array $stmts) { + $style = null; + $hasNotAllowedStmts = false; + foreach ($stmts as $i => $stmt) { + if ($stmt instanceof Node\Stmt\Namespace_) { + $currentStyle = null === $stmt->stmts ? 'semicolon' : 'brace'; + if (null === $style) { + $style = $currentStyle; + if ($hasNotAllowedStmts) { + $this->emitError(new Error( + 'Namespace declaration statement has to be the very first statement in the script', + $stmt->getLine() // Avoid marking the entire namespace as an error + )); + } + } elseif ($style !== $currentStyle) { + $this->emitError(new Error( + 'Cannot mix bracketed namespace declarations with unbracketed namespace declarations', + $stmt->getLine() // Avoid marking the entire namespace as an error + )); + // Treat like semicolon style for namespace normalization + return 'semicolon'; + } + continue; + } + + /* declare(), __halt_compiler() and nops can be used before a namespace declaration */ + if ($stmt instanceof Node\Stmt\Declare_ + || $stmt instanceof Node\Stmt\HaltCompiler + || $stmt instanceof Node\Stmt\Nop) { + continue; + } + + /* There may be a hashbang line at the very start of the file */ + if ($i === 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) { + continue; + } + + /* Everything else if forbidden before namespace declarations */ + $hasNotAllowedStmts = true; + } + return $style; + } + + /** + * Fix up parsing of static property calls in PHP 5. + * + * In PHP 5 A::$b[c][d] and A::$b[c][d]() have very different interpretation. The former is + * interpreted as (A::$b)[c][d], while the latter is the same as A::{$b[c][d]}(). We parse the + * latter as the former initially and this method fixes the AST into the correct form when we + * encounter the "()". + * + * @param Node\Expr\StaticPropertyFetch|Node\Expr\ArrayDimFetch $prop + * @param Node\Arg[] $args + * @param array $attributes + * + * @return Expr\StaticCall + */ + protected function fixupPhp5StaticPropCall($prop, array $args, array $attributes) : Expr\StaticCall { + if ($prop instanceof Node\Expr\StaticPropertyFetch) { + $name = $prop->name instanceof VarLikeIdentifier + ? $prop->name->toString() : $prop->name; + $var = new Expr\Variable($name, $prop->name->getAttributes()); + return new Expr\StaticCall($prop->class, $var, $args, $attributes); + } elseif ($prop instanceof Node\Expr\ArrayDimFetch) { + $tmp = $prop; + while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { + $tmp = $tmp->var; + } + + /** @var Expr\StaticPropertyFetch $staticProp */ + $staticProp = $tmp->var; + + // Set start attributes to attributes of innermost node + $tmp = $prop; + $this->fixupStartAttributes($tmp, $staticProp->name); + while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { + $tmp = $tmp->var; + $this->fixupStartAttributes($tmp, $staticProp->name); + } + + $name = $staticProp->name instanceof VarLikeIdentifier + ? $staticProp->name->toString() : $staticProp->name; + $tmp->var = new Expr\Variable($name, $staticProp->name->getAttributes()); + return new Expr\StaticCall($staticProp->class, $prop, $args, $attributes); + } else { + throw new \Exception; + } + } + + protected function fixupStartAttributes(Node $to, Node $from) { + $startAttributes = ['startLine', 'startFilePos', 'startTokenPos']; + foreach ($startAttributes as $startAttribute) { + if ($from->hasAttribute($startAttribute)) { + $to->setAttribute($startAttribute, $from->getAttribute($startAttribute)); + } + } + } + + protected function handleBuiltinTypes(Name $name) { + $scalarTypes = [ + 'bool' => true, + 'int' => true, + 'float' => true, + 'string' => true, + 'iterable' => true, + 'void' => true, + 'object' => true, + ]; + + if (!$name->isUnqualified()) { + return $name; + } + + $lowerName = $name->toLowerString(); + if (!isset($scalarTypes[$lowerName])) { + return $name; + } + + return new Node\Identifier($lowerName, $name->getAttributes()); + } + + /** + * Get combined start and end attributes at a stack location + * + * @param int $pos Stack location + * + * @return array Combined start and end attributes + */ + protected function getAttributesAt(int $pos) : array { + return $this->startAttributeStack[$pos] + $this->endAttributeStack[$pos]; + } + + protected function getFloatCastKind(string $cast): int + { + $cast = strtolower($cast); + if (strpos($cast, 'float') !== false) { + return Double::KIND_FLOAT; + } + + if (strpos($cast, 'real') !== false) { + return Double::KIND_REAL; + } + + return Double::KIND_DOUBLE; + } + + protected function parseLNumber($str, $attributes, $allowInvalidOctal = false) { + try { + return LNumber::fromString($str, $attributes, $allowInvalidOctal); + } catch (Error $error) { + $this->emitError($error); + // Use dummy value + return new LNumber(0, $attributes); + } + } + + /** + * Parse a T_NUM_STRING token into either an integer or string node. + * + * @param string $str Number string + * @param array $attributes Attributes + * + * @return LNumber|String_ Integer or string node. + */ + protected function parseNumString(string $str, array $attributes) { + if (!preg_match('/^(?:0|-?[1-9][0-9]*)$/', $str)) { + return new String_($str, $attributes); + } + + $num = +$str; + if (!is_int($num)) { + return new String_($str, $attributes); + } + + return new LNumber($num, $attributes); + } + + protected function stripIndentation( + string $string, int $indentLen, string $indentChar, + bool $newlineAtStart, bool $newlineAtEnd, array $attributes + ) { + if ($indentLen === 0) { + return $string; + } + + $start = $newlineAtStart ? '(?:(?<=\n)|\A)' : '(?<=\n)'; + $end = $newlineAtEnd ? '(?:(?=[\r\n])|\z)' : '(?=[\r\n])'; + $regex = '/' . $start . '([ \t]*)(' . $end . ')?/'; + return preg_replace_callback( + $regex, + function ($matches) use ($indentLen, $indentChar, $attributes) { + $prefix = substr($matches[1], 0, $indentLen); + if (false !== strpos($prefix, $indentChar === " " ? "\t" : " ")) { + $this->emitError(new Error( + 'Invalid indentation - tabs and spaces cannot be mixed', $attributes + )); + } elseif (strlen($prefix) < $indentLen && !isset($matches[2])) { + $this->emitError(new Error( + 'Invalid body indentation level ' . + '(expecting an indentation level of at least ' . $indentLen . ')', + $attributes + )); + } + return substr($matches[0], strlen($prefix)); + }, + $string + ); + } + + protected function parseDocString( + string $startToken, $contents, string $endToken, + array $attributes, array $endTokenAttributes, bool $parseUnicodeEscape + ) { + $kind = strpos($startToken, "'") === false + ? String_::KIND_HEREDOC : String_::KIND_NOWDOC; + + $regex = '/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/'; + $result = preg_match($regex, $startToken, $matches); + assert($result === 1); + $label = $matches[1]; + + $result = preg_match('/\A[ \t]*/', $endToken, $matches); + assert($result === 1); + $indentation = $matches[0]; + + $attributes['kind'] = $kind; + $attributes['docLabel'] = $label; + $attributes['docIndentation'] = $indentation; + + $indentHasSpaces = false !== strpos($indentation, " "); + $indentHasTabs = false !== strpos($indentation, "\t"); + if ($indentHasSpaces && $indentHasTabs) { + $this->emitError(new Error( + 'Invalid indentation - tabs and spaces cannot be mixed', + $endTokenAttributes + )); + + // Proceed processing as if this doc string is not indented + $indentation = ''; + } + + $indentLen = \strlen($indentation); + $indentChar = $indentHasSpaces ? " " : "\t"; + + if (\is_string($contents)) { + if ($contents === '') { + return new String_('', $attributes); + } + + $contents = $this->stripIndentation( + $contents, $indentLen, $indentChar, true, true, $attributes + ); + $contents = preg_replace('~(\r\n|\n|\r)\z~', '', $contents); + + if ($kind === String_::KIND_HEREDOC) { + $contents = String_::parseEscapeSequences($contents, null, $parseUnicodeEscape); + } + + return new String_($contents, $attributes); + } else { + assert(count($contents) > 0); + if (!$contents[0] instanceof Node\Scalar\EncapsedStringPart) { + // If there is no leading encapsed string part, pretend there is an empty one + $this->stripIndentation( + '', $indentLen, $indentChar, true, false, $contents[0]->getAttributes() + ); + } + + $newContents = []; + foreach ($contents as $i => $part) { + if ($part instanceof Node\Scalar\EncapsedStringPart) { + $isLast = $i === \count($contents) - 1; + $part->value = $this->stripIndentation( + $part->value, $indentLen, $indentChar, + $i === 0, $isLast, $part->getAttributes() + ); + $part->value = String_::parseEscapeSequences($part->value, null, $parseUnicodeEscape); + if ($isLast) { + $part->value = preg_replace('~(\r\n|\n|\r)\z~', '', $part->value); + } + if ('' === $part->value) { + continue; + } + } + $newContents[] = $part; + } + return new Encapsed($newContents, $attributes); + } + } + + protected function checkModifier($a, $b, $modifierPos) { + // Jumping through some hoops here because verifyModifier() is also used elsewhere + try { + Class_::verifyModifier($a, $b); + } catch (Error $error) { + $error->setAttributes($this->getAttributesAt($modifierPos)); + $this->emitError($error); + } + } + + protected function checkParam(Param $node) { + if ($node->variadic && null !== $node->default) { + $this->emitError(new Error( + 'Variadic parameter cannot have a default value', + $node->default->getAttributes() + )); + } + } + + protected function checkTryCatch(TryCatch $node) { + if (empty($node->catches) && null === $node->finally) { + $this->emitError(new Error( + 'Cannot use try without catch or finally', $node->getAttributes() + )); + } + } + + protected function checkNamespace(Namespace_ $node) { + if ($node->name && $node->name->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as namespace name', $node->name), + $node->name->getAttributes() + )); + } + + if (null !== $node->stmts) { + foreach ($node->stmts as $stmt) { + if ($stmt instanceof Namespace_) { + $this->emitError(new Error( + 'Namespace declarations cannot be nested', $stmt->getAttributes() + )); + } + } + } + } + + protected function checkClass(Class_ $node, $namePos) { + if (null !== $node->name && $node->name->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as class name as it is reserved', $node->name), + $this->getAttributesAt($namePos) + )); + } + + if ($node->extends && $node->extends->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as class name as it is reserved', $node->extends), + $node->extends->getAttributes() + )); + } + + foreach ($node->implements as $interface) { + if ($interface->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), + $interface->getAttributes() + )); + } + } + } + + protected function checkInterface(Interface_ $node, $namePos) { + if (null !== $node->name && $node->name->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as class name as it is reserved', $node->name), + $this->getAttributesAt($namePos) + )); + } + + foreach ($node->extends as $interface) { + if ($interface->isSpecialClassName()) { + $this->emitError(new Error( + sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), + $interface->getAttributes() + )); + } + } + } + + protected function checkClassMethod(ClassMethod $node, $modifierPos) { + if ($node->flags & Class_::MODIFIER_STATIC) { + switch ($node->name->toLowerString()) { + case '__construct': + $this->emitError(new Error( + sprintf('Constructor %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + case '__destruct': + $this->emitError(new Error( + sprintf('Destructor %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + case '__clone': + $this->emitError(new Error( + sprintf('Clone method %s() cannot be static', $node->name), + $this->getAttributesAt($modifierPos))); + break; + } + } + } + + protected function checkClassConst(ClassConst $node, $modifierPos) { + if ($node->flags & Class_::MODIFIER_STATIC) { + $this->emitError(new Error( + "Cannot use 'static' as constant modifier", + $this->getAttributesAt($modifierPos))); + } + if ($node->flags & Class_::MODIFIER_ABSTRACT) { + $this->emitError(new Error( + "Cannot use 'abstract' as constant modifier", + $this->getAttributesAt($modifierPos))); + } + if ($node->flags & Class_::MODIFIER_FINAL) { + $this->emitError(new Error( + "Cannot use 'final' as constant modifier", + $this->getAttributesAt($modifierPos))); + } + } + + protected function checkProperty(Property $node, $modifierPos) { + if ($node->flags & Class_::MODIFIER_ABSTRACT) { + $this->emitError(new Error('Properties cannot be declared abstract', + $this->getAttributesAt($modifierPos))); + } + + if ($node->flags & Class_::MODIFIER_FINAL) { + $this->emitError(new Error('Properties cannot be declared final', + $this->getAttributesAt($modifierPos))); + } + } + + protected function checkUseUse(UseUse $node, $namePos) { + if ($node->alias && $node->alias->isSpecialClassName()) { + $this->emitError(new Error( + sprintf( + 'Cannot use %s as %s because \'%2$s\' is a special class name', + $node->name, $node->alias + ), + $this->getAttributesAt($namePos) + )); + } + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php b/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php new file mode 100644 index 00000000..f041e7ff --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php @@ -0,0 +1,44 @@ +type ? $this->p($node->type) . ' ' : '') + . ($node->byRef ? '&' : '') + . ($node->variadic ? '...' : '') + . $this->p($node->var) + . ($node->default ? ' = ' . $this->p($node->default) : ''); + } + + protected function pArg(Node\Arg $node) { + return ($node->byRef ? '&' : '') . ($node->unpack ? '...' : '') . $this->p($node->value); + } + + protected function pConst(Node\Const_ $node) { + return $node->name . ' = ' . $this->p($node->value); + } + + protected function pNullableType(Node\NullableType $node) { + return '?' . $this->p($node->type); + } + + protected function pIdentifier(Node\Identifier $node) { + return $node->name; + } + + protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node) { + return '$' . $node->name; + } + + // Names + + protected function pName(Name $node) { + return implode('\\', $node->parts); + } + + protected function pName_FullyQualified(Name\FullyQualified $node) { + return '\\' . implode('\\', $node->parts); + } + + protected function pName_Relative(Name\Relative $node) { + return 'namespace\\' . implode('\\', $node->parts); + } + + // Magic Constants + + protected function pScalar_MagicConst_Class(MagicConst\Class_ $node) { + return '__CLASS__'; + } + + protected function pScalar_MagicConst_Dir(MagicConst\Dir $node) { + return '__DIR__'; + } + + protected function pScalar_MagicConst_File(MagicConst\File $node) { + return '__FILE__'; + } + + protected function pScalar_MagicConst_Function(MagicConst\Function_ $node) { + return '__FUNCTION__'; + } + + protected function pScalar_MagicConst_Line(MagicConst\Line $node) { + return '__LINE__'; + } + + protected function pScalar_MagicConst_Method(MagicConst\Method $node) { + return '__METHOD__'; + } + + protected function pScalar_MagicConst_Namespace(MagicConst\Namespace_ $node) { + return '__NAMESPACE__'; + } + + protected function pScalar_MagicConst_Trait(MagicConst\Trait_ $node) { + return '__TRAIT__'; + } + + // Scalars + + protected function pScalar_String(Scalar\String_ $node) { + $kind = $node->getAttribute('kind', Scalar\String_::KIND_SINGLE_QUOTED); + switch ($kind) { + case Scalar\String_::KIND_NOWDOC: + $label = $node->getAttribute('docLabel'); + if ($label && !$this->containsEndLabel($node->value, $label)) { + if ($node->value === '') { + return "<<<'$label'\n$label" . $this->docStringEndToken; + } + + return "<<<'$label'\n$node->value\n$label" + . $this->docStringEndToken; + } + /* break missing intentionally */ + case Scalar\String_::KIND_SINGLE_QUOTED: + return $this->pSingleQuotedString($node->value); + case Scalar\String_::KIND_HEREDOC: + $label = $node->getAttribute('docLabel'); + if ($label && !$this->containsEndLabel($node->value, $label)) { + if ($node->value === '') { + return "<<<$label\n$label" . $this->docStringEndToken; + } + + $escaped = $this->escapeString($node->value, null); + return "<<<$label\n" . $escaped . "\n$label" + . $this->docStringEndToken; + } + /* break missing intentionally */ + case Scalar\String_::KIND_DOUBLE_QUOTED: + return '"' . $this->escapeString($node->value, '"') . '"'; + } + throw new \Exception('Invalid string kind'); + } + + protected function pScalar_Encapsed(Scalar\Encapsed $node) { + if ($node->getAttribute('kind') === Scalar\String_::KIND_HEREDOC) { + $label = $node->getAttribute('docLabel'); + if ($label && !$this->encapsedContainsEndLabel($node->parts, $label)) { + if (count($node->parts) === 1 + && $node->parts[0] instanceof Scalar\EncapsedStringPart + && $node->parts[0]->value === '' + ) { + return "<<<$label\n$label" . $this->docStringEndToken; + } + + return "<<<$label\n" . $this->pEncapsList($node->parts, null) . "\n$label" + . $this->docStringEndToken; + } + } + return '"' . $this->pEncapsList($node->parts, '"') . '"'; + } + + protected function pScalar_LNumber(Scalar\LNumber $node) { + if ($node->value === -\PHP_INT_MAX-1) { + // PHP_INT_MIN cannot be represented as a literal, + // because the sign is not part of the literal + return '(-' . \PHP_INT_MAX . '-1)'; + } + + $kind = $node->getAttribute('kind', Scalar\LNumber::KIND_DEC); + if (Scalar\LNumber::KIND_DEC === $kind) { + return (string) $node->value; + } + + $sign = $node->value < 0 ? '-' : ''; + $str = (string) $node->value; + switch ($kind) { + case Scalar\LNumber::KIND_BIN: + return $sign . '0b' . base_convert($str, 10, 2); + case Scalar\LNumber::KIND_OCT: + return $sign . '0' . base_convert($str, 10, 8); + case Scalar\LNumber::KIND_HEX: + return $sign . '0x' . base_convert($str, 10, 16); + } + throw new \Exception('Invalid number kind'); + } + + protected function pScalar_DNumber(Scalar\DNumber $node) { + if (!is_finite($node->value)) { + if ($node->value === \INF) { + return '\INF'; + } elseif ($node->value === -\INF) { + return '-\INF'; + } else { + return '\NAN'; + } + } + + // Try to find a short full-precision representation + $stringValue = sprintf('%.16G', $node->value); + if ($node->value !== (double) $stringValue) { + $stringValue = sprintf('%.17G', $node->value); + } + + // %G is locale dependent and there exists no locale-independent alternative. We don't want + // mess with switching locales here, so let's assume that a comma is the only non-standard + // decimal separator we may encounter... + $stringValue = str_replace(',', '.', $stringValue); + + // ensure that number is really printed as float + return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue; + } + + protected function pScalar_EncapsedStringPart(Scalar\EncapsedStringPart $node) { + throw new \LogicException('Cannot directly print EncapsedStringPart'); + } + + // Assignments + + protected function pExpr_Assign(Expr\Assign $node) { + return $this->pInfixOp(Expr\Assign::class, $node->var, ' = ', $node->expr); + } + + protected function pExpr_AssignRef(Expr\AssignRef $node) { + return $this->pInfixOp(Expr\AssignRef::class, $node->var, ' =& ', $node->expr); + } + + protected function pExpr_AssignOp_Plus(AssignOp\Plus $node) { + return $this->pInfixOp(AssignOp\Plus::class, $node->var, ' += ', $node->expr); + } + + protected function pExpr_AssignOp_Minus(AssignOp\Minus $node) { + return $this->pInfixOp(AssignOp\Minus::class, $node->var, ' -= ', $node->expr); + } + + protected function pExpr_AssignOp_Mul(AssignOp\Mul $node) { + return $this->pInfixOp(AssignOp\Mul::class, $node->var, ' *= ', $node->expr); + } + + protected function pExpr_AssignOp_Div(AssignOp\Div $node) { + return $this->pInfixOp(AssignOp\Div::class, $node->var, ' /= ', $node->expr); + } + + protected function pExpr_AssignOp_Concat(AssignOp\Concat $node) { + return $this->pInfixOp(AssignOp\Concat::class, $node->var, ' .= ', $node->expr); + } + + protected function pExpr_AssignOp_Mod(AssignOp\Mod $node) { + return $this->pInfixOp(AssignOp\Mod::class, $node->var, ' %= ', $node->expr); + } + + protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node) { + return $this->pInfixOp(AssignOp\BitwiseAnd::class, $node->var, ' &= ', $node->expr); + } + + protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node) { + return $this->pInfixOp(AssignOp\BitwiseOr::class, $node->var, ' |= ', $node->expr); + } + + protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node) { + return $this->pInfixOp(AssignOp\BitwiseXor::class, $node->var, ' ^= ', $node->expr); + } + + protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node) { + return $this->pInfixOp(AssignOp\ShiftLeft::class, $node->var, ' <<= ', $node->expr); + } + + protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node) { + return $this->pInfixOp(AssignOp\ShiftRight::class, $node->var, ' >>= ', $node->expr); + } + + protected function pExpr_AssignOp_Pow(AssignOp\Pow $node) { + return $this->pInfixOp(AssignOp\Pow::class, $node->var, ' **= ', $node->expr); + } + + protected function pExpr_AssignOp_Coalesce(AssignOp\Coalesce $node) { + return $this->pInfixOp(AssignOp\Coalesce::class, $node->var, ' ??= ', $node->expr); + } + + // Binary expressions + + protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node) { + return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right); + } + + protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node) { + return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right); + } + + protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node) { + return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right); + } + + protected function pExpr_BinaryOp_Div(BinaryOp\Div $node) { + return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right); + } + + protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node) { + return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right); + } + + protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node) { + return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right); + } + + protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node) { + return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right); + } + + protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node) { + return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right); + } + + protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node) { + return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right); + } + + protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node) { + return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right); + } + + protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node) { + return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right); + } + + protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node) { + return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right); + } + + protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node) { + return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right); + } + + protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node) { + return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right); + } + + protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node) { + return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right); + } + + protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node) { + return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right); + } + + protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node) { + return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right); + } + + protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node) { + return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right); + } + + protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node) { + return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right); + } + + protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node) { + return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right); + } + + protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node) { + return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right); + } + + protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node) { + return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right); + } + + protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node) { + return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right); + } + + protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node) { + return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right); + } + + protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node) { + return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right); + } + + protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node) { + return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right); + } + + protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node) { + return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right); + } + + protected function pExpr_Instanceof(Expr\Instanceof_ $node) { + return $this->pInfixOp(Expr\Instanceof_::class, $node->expr, ' instanceof ', $node->class); + } + + // Unary expressions + + protected function pExpr_BooleanNot(Expr\BooleanNot $node) { + return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr); + } + + protected function pExpr_BitwiseNot(Expr\BitwiseNot $node) { + return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr); + } + + protected function pExpr_UnaryMinus(Expr\UnaryMinus $node) { + if ($node->expr instanceof Expr\UnaryMinus || $node->expr instanceof Expr\PreDec) { + // Enforce -(-$expr) instead of --$expr + return '-(' . $this->p($node->expr) . ')'; + } + return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr); + } + + protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) { + if ($node->expr instanceof Expr\UnaryPlus || $node->expr instanceof Expr\PreInc) { + // Enforce +(+$expr) instead of ++$expr + return '+(' . $this->p($node->expr) . ')'; + } + return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr); + } + + protected function pExpr_PreInc(Expr\PreInc $node) { + return $this->pPrefixOp(Expr\PreInc::class, '++', $node->var); + } + + protected function pExpr_PreDec(Expr\PreDec $node) { + return $this->pPrefixOp(Expr\PreDec::class, '--', $node->var); + } + + protected function pExpr_PostInc(Expr\PostInc $node) { + return $this->pPostfixOp(Expr\PostInc::class, $node->var, '++'); + } + + protected function pExpr_PostDec(Expr\PostDec $node) { + return $this->pPostfixOp(Expr\PostDec::class, $node->var, '--'); + } + + protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) { + return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr); + } + + protected function pExpr_YieldFrom(Expr\YieldFrom $node) { + return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr); + } + + protected function pExpr_Print(Expr\Print_ $node) { + return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr); + } + + // Casts + + protected function pExpr_Cast_Int(Cast\Int_ $node) { + return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr); + } + + protected function pExpr_Cast_Double(Cast\Double $node) { + $kind = $node->getAttribute('kind', Cast\Double::KIND_DOUBLE); + if ($kind === Cast\Double::KIND_DOUBLE) { + $cast = '(double)'; + } elseif ($kind === Cast\Double::KIND_FLOAT) { + $cast = '(float)'; + } elseif ($kind === Cast\Double::KIND_REAL) { + $cast = '(real)'; + } + return $this->pPrefixOp(Cast\Double::class, $cast . ' ', $node->expr); + } + + protected function pExpr_Cast_String(Cast\String_ $node) { + return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr); + } + + protected function pExpr_Cast_Array(Cast\Array_ $node) { + return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr); + } + + protected function pExpr_Cast_Object(Cast\Object_ $node) { + return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr); + } + + protected function pExpr_Cast_Bool(Cast\Bool_ $node) { + return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr); + } + + protected function pExpr_Cast_Unset(Cast\Unset_ $node) { + return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr); + } + + // Function calls and similar constructs + + protected function pExpr_FuncCall(Expr\FuncCall $node) { + return $this->pCallLhs($node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_MethodCall(Expr\MethodCall $node) { + return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_StaticCall(Expr\StaticCall $node) { + return $this->pDereferenceLhs($node->class) . '::' + . ($node->name instanceof Expr + ? ($node->name instanceof Expr\Variable + ? $this->p($node->name) + : '{' . $this->p($node->name) . '}') + : $node->name) + . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_Empty(Expr\Empty_ $node) { + return 'empty(' . $this->p($node->expr) . ')'; + } + + protected function pExpr_Isset(Expr\Isset_ $node) { + return 'isset(' . $this->pCommaSeparated($node->vars) . ')'; + } + + protected function pExpr_Eval(Expr\Eval_ $node) { + return 'eval(' . $this->p($node->expr) . ')'; + } + + protected function pExpr_Include(Expr\Include_ $node) { + static $map = [ + Expr\Include_::TYPE_INCLUDE => 'include', + Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once', + Expr\Include_::TYPE_REQUIRE => 'require', + Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once', + ]; + + return $map[$node->type] . ' ' . $this->p($node->expr); + } + + protected function pExpr_List(Expr\List_ $node) { + return 'list(' . $this->pCommaSeparated($node->items) . ')'; + } + + // Other + + protected function pExpr_Error(Expr\Error $node) { + throw new \LogicException('Cannot pretty-print AST with Error nodes'); + } + + protected function pExpr_Variable(Expr\Variable $node) { + if ($node->name instanceof Expr) { + return '${' . $this->p($node->name) . '}'; + } else { + return '$' . $node->name; + } + } + + protected function pExpr_Array(Expr\Array_ $node) { + $syntax = $node->getAttribute('kind', + $this->options['shortArraySyntax'] ? Expr\Array_::KIND_SHORT : Expr\Array_::KIND_LONG); + if ($syntax === Expr\Array_::KIND_SHORT) { + return '[' . $this->pMaybeMultiline($node->items, true) . ']'; + } else { + return 'array(' . $this->pMaybeMultiline($node->items, true) . ')'; + } + } + + protected function pExpr_ArrayItem(Expr\ArrayItem $node) { + return (null !== $node->key ? $this->p($node->key) . ' => ' : '') + . ($node->byRef ? '&' : '') . $this->p($node->value); + } + + protected function pExpr_ArrayDimFetch(Expr\ArrayDimFetch $node) { + return $this->pDereferenceLhs($node->var) + . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']'; + } + + protected function pExpr_ConstFetch(Expr\ConstFetch $node) { + return $this->p($node->name); + } + + protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) { + return $this->p($node->class) . '::' . $this->p($node->name); + } + + protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) { + return $this->pDereferenceLhs($node->var) . '->' . $this->pObjectProperty($node->name); + } + + protected function pExpr_StaticPropertyFetch(Expr\StaticPropertyFetch $node) { + return $this->pDereferenceLhs($node->class) . '::$' . $this->pObjectProperty($node->name); + } + + protected function pExpr_ShellExec(Expr\ShellExec $node) { + return '`' . $this->pEncapsList($node->parts, '`') . '`'; + } + + protected function pExpr_Closure(Expr\Closure $node) { + return ($node->static ? 'static ' : '') + . 'function ' . ($node->byRef ? '&' : '') + . '(' . $this->pCommaSeparated($node->params) . ')' + . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')' : '') + . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') + . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pExpr_ClosureUse(Expr\ClosureUse $node) { + return ($node->byRef ? '&' : '') . $this->p($node->var); + } + + protected function pExpr_New(Expr\New_ $node) { + if ($node->class instanceof Stmt\Class_) { + $args = $node->args ? '(' . $this->pMaybeMultiline($node->args) . ')' : ''; + return 'new ' . $this->pClassCommon($node->class, $args); + } + return 'new ' . $this->p($node->class) . '(' . $this->pMaybeMultiline($node->args) . ')'; + } + + protected function pExpr_Clone(Expr\Clone_ $node) { + return 'clone ' . $this->p($node->expr); + } + + protected function pExpr_Ternary(Expr\Ternary $node) { + // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator. + // this is okay because the part between ? and : never needs parentheses. + return $this->pInfixOp(Expr\Ternary::class, + $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else + ); + } + + protected function pExpr_Exit(Expr\Exit_ $node) { + $kind = $node->getAttribute('kind', Expr\Exit_::KIND_DIE); + return ($kind === Expr\Exit_::KIND_EXIT ? 'exit' : 'die') + . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : ''); + } + + protected function pExpr_Yield(Expr\Yield_ $node) { + if ($node->value === null) { + return 'yield'; + } else { + // this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary + return '(yield ' + . ($node->key !== null ? $this->p($node->key) . ' => ' : '') + . $this->p($node->value) + . ')'; + } + } + + // Declarations + + protected function pStmt_Namespace(Stmt\Namespace_ $node) { + if ($this->canUseSemicolonNamespaces) { + return 'namespace ' . $this->p($node->name) . ';' + . $this->nl . $this->pStmts($node->stmts, false); + } else { + return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') + . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + } + + protected function pStmt_Use(Stmt\Use_ $node) { + return 'use ' . $this->pUseType($node->type) + . $this->pCommaSeparated($node->uses) . ';'; + } + + protected function pStmt_GroupUse(Stmt\GroupUse $node) { + return 'use ' . $this->pUseType($node->type) . $this->pName($node->prefix) + . '\{' . $this->pCommaSeparated($node->uses) . '};'; + } + + protected function pStmt_UseUse(Stmt\UseUse $node) { + return $this->pUseType($node->type) . $this->p($node->name) + . (null !== $node->alias ? ' as ' . $node->alias : ''); + } + + protected function pUseType($type) { + return $type === Stmt\Use_::TYPE_FUNCTION ? 'function ' + : ($type === Stmt\Use_::TYPE_CONSTANT ? 'const ' : ''); + } + + protected function pStmt_Interface(Stmt\Interface_ $node) { + return 'interface ' . $node->name + . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Class(Stmt\Class_ $node) { + return $this->pClassCommon($node, ' ' . $node->name); + } + + protected function pStmt_Trait(Stmt\Trait_ $node) { + return 'trait ' . $node->name + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_TraitUse(Stmt\TraitUse $node) { + return 'use ' . $this->pCommaSeparated($node->traits) + . (empty($node->adaptations) + ? ';' + : ' {' . $this->pStmts($node->adaptations) . $this->nl . '}'); + } + + protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) { + return $this->p($node->trait) . '::' . $node->method + . ' insteadof ' . $this->pCommaSeparated($node->insteadof) . ';'; + } + + protected function pStmt_TraitUseAdaptation_Alias(Stmt\TraitUseAdaptation\Alias $node) { + return (null !== $node->trait ? $this->p($node->trait) . '::' : '') + . $node->method . ' as' + . (null !== $node->newModifier ? ' ' . rtrim($this->pModifiers($node->newModifier), ' ') : '') + . (null !== $node->newName ? ' ' . $node->newName : '') + . ';'; + } + + protected function pStmt_Property(Stmt\Property $node) { + return (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags)) + . ($node->type ? $this->p($node->type) . ' ' : '') + . $this->pCommaSeparated($node->props) . ';'; + } + + protected function pStmt_PropertyProperty(Stmt\PropertyProperty $node) { + return '$' . $node->name + . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); + } + + protected function pStmt_ClassMethod(Stmt\ClassMethod $node) { + return $this->pModifiers($node->flags) + . 'function ' . ($node->byRef ? '&' : '') . $node->name + . '(' . $this->pCommaSeparated($node->params) . ')' + . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') + . (null !== $node->stmts + ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}' + : ';'); + } + + protected function pStmt_ClassConst(Stmt\ClassConst $node) { + return $this->pModifiers($node->flags) + . 'const ' . $this->pCommaSeparated($node->consts) . ';'; + } + + protected function pStmt_Function(Stmt\Function_ $node) { + return 'function ' . ($node->byRef ? '&' : '') . $node->name + . '(' . $this->pCommaSeparated($node->params) . ')' + . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Const(Stmt\Const_ $node) { + return 'const ' . $this->pCommaSeparated($node->consts) . ';'; + } + + protected function pStmt_Declare(Stmt\Declare_ $node) { + return 'declare (' . $this->pCommaSeparated($node->declares) . ')' + . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . $this->nl . '}' : ';'); + } + + protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) { + return $node->key . '=' . $this->p($node->value); + } + + // Control flow + + protected function pStmt_If(Stmt\If_ $node) { + return 'if (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}' + . ($node->elseifs ? ' ' . $this->pImplode($node->elseifs, ' ') : '') + . (null !== $node->else ? ' ' . $this->p($node->else) : ''); + } + + protected function pStmt_ElseIf(Stmt\ElseIf_ $node) { + return 'elseif (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Else(Stmt\Else_ $node) { + return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_For(Stmt\For_ $node) { + return 'for (' + . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '') + . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '') + . $this->pCommaSeparated($node->loop) + . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Foreach(Stmt\Foreach_ $node) { + return 'foreach (' . $this->p($node->expr) . ' as ' + . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') + . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_While(Stmt\While_ $node) { + return 'while (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Do(Stmt\Do_ $node) { + return 'do {' . $this->pStmts($node->stmts) . $this->nl + . '} while (' . $this->p($node->cond) . ');'; + } + + protected function pStmt_Switch(Stmt\Switch_ $node) { + return 'switch (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->cases) . $this->nl . '}'; + } + + protected function pStmt_Case(Stmt\Case_ $node) { + return (null !== $node->cond ? 'case ' . $this->p($node->cond) : 'default') . ':' + . $this->pStmts($node->stmts); + } + + protected function pStmt_TryCatch(Stmt\TryCatch $node) { + return 'try {' . $this->pStmts($node->stmts) . $this->nl . '}' + . ($node->catches ? ' ' . $this->pImplode($node->catches, ' ') : '') + . ($node->finally !== null ? ' ' . $this->p($node->finally) : ''); + } + + protected function pStmt_Catch(Stmt\Catch_ $node) { + return 'catch (' . $this->pImplode($node->types, '|') . ' ' + . $this->p($node->var) + . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Finally(Stmt\Finally_ $node) { + return 'finally {' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pStmt_Break(Stmt\Break_ $node) { + return 'break' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; + } + + protected function pStmt_Continue(Stmt\Continue_ $node) { + return 'continue' . ($node->num !== null ? ' ' . $this->p($node->num) : '') . ';'; + } + + protected function pStmt_Return(Stmt\Return_ $node) { + return 'return' . (null !== $node->expr ? ' ' . $this->p($node->expr) : '') . ';'; + } + + protected function pStmt_Throw(Stmt\Throw_ $node) { + return 'throw ' . $this->p($node->expr) . ';'; + } + + protected function pStmt_Label(Stmt\Label $node) { + return $node->name . ':'; + } + + protected function pStmt_Goto(Stmt\Goto_ $node) { + return 'goto ' . $node->name . ';'; + } + + // Other + + protected function pStmt_Expression(Stmt\Expression $node) { + return $this->p($node->expr) . ';'; + } + + protected function pStmt_Echo(Stmt\Echo_ $node) { + return 'echo ' . $this->pCommaSeparated($node->exprs) . ';'; + } + + protected function pStmt_Static(Stmt\Static_ $node) { + return 'static ' . $this->pCommaSeparated($node->vars) . ';'; + } + + protected function pStmt_Global(Stmt\Global_ $node) { + return 'global ' . $this->pCommaSeparated($node->vars) . ';'; + } + + protected function pStmt_StaticVar(Stmt\StaticVar $node) { + return $this->p($node->var) + . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); + } + + protected function pStmt_Unset(Stmt\Unset_ $node) { + return 'unset(' . $this->pCommaSeparated($node->vars) . ');'; + } + + protected function pStmt_InlineHTML(Stmt\InlineHTML $node) { + $newline = $node->getAttribute('hasLeadingNewline', true) ? "\n" : ''; + return '?>' . $newline . $node->value . 'remaining; + } + + protected function pStmt_Nop(Stmt\Nop $node) { + return ''; + } + + // Helpers + + protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) { + return $this->pModifiers($node->flags) + . 'class' . $afterClassToken + . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '') + . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; + } + + protected function pObjectProperty($node) { + if ($node instanceof Expr) { + return '{' . $this->p($node) . '}'; + } else { + return $node; + } + } + + protected function pEncapsList(array $encapsList, $quote) { + $return = ''; + foreach ($encapsList as $element) { + if ($element instanceof Scalar\EncapsedStringPart) { + $return .= $this->escapeString($element->value, $quote); + } else { + $return .= '{' . $this->p($element) . '}'; + } + } + + return $return; + } + + protected function pSingleQuotedString(string $string) { + return '\'' . addcslashes($string, '\'\\') . '\''; + } + + protected function escapeString($string, $quote) { + if (null === $quote) { + // For doc strings, don't escape newlines + $escaped = addcslashes($string, "\t\f\v$\\"); + } else { + $escaped = addcslashes($string, "\n\r\t\f\v$" . $quote . "\\"); + } + + // Escape other control characters + return preg_replace_callback('/([\0-\10\16-\37])(?=([0-7]?))/', function ($matches) { + $oct = decoct(ord($matches[1])); + if ($matches[2] !== '') { + // If there is a trailing digit, use the full three character form + return '\\' . str_pad($oct, 3, '0', \STR_PAD_LEFT); + } + return '\\' . $oct; + }, $escaped); + } + + protected function containsEndLabel($string, $label, $atStart = true, $atEnd = true) { + $start = $atStart ? '(?:^|[\r\n])' : '[\r\n]'; + $end = $atEnd ? '(?:$|[;\r\n])' : '[;\r\n]'; + return false !== strpos($string, $label) + && preg_match('/' . $start . $label . $end . '/', $string); + } + + protected function encapsedContainsEndLabel(array $parts, $label) { + foreach ($parts as $i => $part) { + $atStart = $i === 0; + $atEnd = $i === count($parts) - 1; + if ($part instanceof Scalar\EncapsedStringPart + && $this->containsEndLabel($part->value, $label, $atStart, $atEnd) + ) { + return true; + } + } + return false; + } + + protected function pDereferenceLhs(Node $node) { + if (!$this->dereferenceLhsRequiresParens($node)) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + + protected function pCallLhs(Node $node) { + if (!$this->callLhsRequiresParens($node)) { + return $this->p($node); + } else { + return '(' . $this->p($node) . ')'; + } + } + + /** + * @param Node[] $nodes + * @return bool + */ + private function hasNodeWithComments(array $nodes) { + foreach ($nodes as $node) { + if ($node && $node->getComments()) { + return true; + } + } + return false; + } + + private function pMaybeMultiline(array $nodes, $trailingComma = false) { + if (!$this->hasNodeWithComments($nodes)) { + return $this->pCommaSeparated($nodes); + } else { + return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl; + } + } +} diff --git a/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php b/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php new file mode 100644 index 00000000..f6789a15 --- /dev/null +++ b/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php @@ -0,0 +1,1350 @@ + [ 0, 1], + Expr\BitwiseNot::class => [ 10, 1], + Expr\PreInc::class => [ 10, 1], + Expr\PreDec::class => [ 10, 1], + Expr\PostInc::class => [ 10, -1], + Expr\PostDec::class => [ 10, -1], + Expr\UnaryPlus::class => [ 10, 1], + Expr\UnaryMinus::class => [ 10, 1], + Cast\Int_::class => [ 10, 1], + Cast\Double::class => [ 10, 1], + Cast\String_::class => [ 10, 1], + Cast\Array_::class => [ 10, 1], + Cast\Object_::class => [ 10, 1], + Cast\Bool_::class => [ 10, 1], + Cast\Unset_::class => [ 10, 1], + Expr\ErrorSuppress::class => [ 10, 1], + Expr\Instanceof_::class => [ 20, 0], + Expr\BooleanNot::class => [ 30, 1], + BinaryOp\Mul::class => [ 40, -1], + BinaryOp\Div::class => [ 40, -1], + BinaryOp\Mod::class => [ 40, -1], + BinaryOp\Plus::class => [ 50, -1], + BinaryOp\Minus::class => [ 50, -1], + BinaryOp\Concat::class => [ 50, -1], + BinaryOp\ShiftLeft::class => [ 60, -1], + BinaryOp\ShiftRight::class => [ 60, -1], + BinaryOp\Smaller::class => [ 70, 0], + BinaryOp\SmallerOrEqual::class => [ 70, 0], + BinaryOp\Greater::class => [ 70, 0], + BinaryOp\GreaterOrEqual::class => [ 70, 0], + BinaryOp\Equal::class => [ 80, 0], + BinaryOp\NotEqual::class => [ 80, 0], + BinaryOp\Identical::class => [ 80, 0], + BinaryOp\NotIdentical::class => [ 80, 0], + BinaryOp\Spaceship::class => [ 80, 0], + BinaryOp\BitwiseAnd::class => [ 90, -1], + BinaryOp\BitwiseXor::class => [100, -1], + BinaryOp\BitwiseOr::class => [110, -1], + BinaryOp\BooleanAnd::class => [120, -1], + BinaryOp\BooleanOr::class => [130, -1], + BinaryOp\Coalesce::class => [140, 1], + Expr\Ternary::class => [150, -1], + // parser uses %left for assignments, but they really behave as %right + Expr\Assign::class => [160, 1], + Expr\AssignRef::class => [160, 1], + AssignOp\Plus::class => [160, 1], + AssignOp\Minus::class => [160, 1], + AssignOp\Mul::class => [160, 1], + AssignOp\Div::class => [160, 1], + AssignOp\Concat::class => [160, 1], + AssignOp\Mod::class => [160, 1], + AssignOp\BitwiseAnd::class => [160, 1], + AssignOp\BitwiseOr::class => [160, 1], + AssignOp\BitwiseXor::class => [160, 1], + AssignOp\ShiftLeft::class => [160, 1], + AssignOp\ShiftRight::class => [160, 1], + AssignOp\Pow::class => [160, 1], + AssignOp\Coalesce::class => [160, 1], + Expr\YieldFrom::class => [165, 1], + Expr\Print_::class => [168, 1], + BinaryOp\LogicalAnd::class => [170, -1], + BinaryOp\LogicalXor::class => [180, -1], + BinaryOp\LogicalOr::class => [190, -1], + Expr\Include_::class => [200, -1], + ]; + + /** @var int Current indentation level. */ + protected $indentLevel; + /** @var string Newline including current indentation. */ + protected $nl; + /** @var string Token placed at end of doc string to ensure it is followed by a newline. */ + protected $docStringEndToken; + /** @var bool Whether semicolon namespaces can be used (i.e. no global namespace is used) */ + protected $canUseSemicolonNamespaces; + /** @var array Pretty printer options */ + protected $options; + + /** @var TokenStream Original tokens for use in format-preserving pretty print */ + protected $origTokens; + /** @var Internal\Differ Differ for node lists */ + protected $nodeListDiffer; + /** @var bool[] Map determining whether a certain character is a label character */ + protected $labelCharMap; + /** + * @var int[][] Map from token classes and subnode names to FIXUP_* constants. This is used + * during format-preserving prints to place additional parens/braces if necessary. + */ + protected $fixupMap; + /** + * @var int[][] Map from "{$node->getType()}->{$subNode}" to ['left' => $l, 'right' => $r], + * where $l and $r specify the token type that needs to be stripped when removing + * this node. + */ + protected $removalMap; + /** + * @var mixed[] Map from "{$node->getType()}->{$subNode}" to [$find, $extraLeft, $extraRight]. + * $find is an optional token after which the insertion occurs. $extraLeft/Right + * are optionally added before/after the main insertions. + */ + protected $insertionMap; + /** + * @var string[] Map From "{$node->getType()}->{$subNode}" to string that should be inserted + * between elements of this list subnode. + */ + protected $listInsertionMap; + /** @var int[] Map from "{$node->getType()}->{$subNode}" to token before which the modifiers + * should be reprinted. */ + protected $modifierChangeMap; + + /** + * Creates a pretty printer instance using the given options. + * + * Supported options: + * * bool $shortArraySyntax = false: Whether to use [] instead of array() as the default array + * syntax, if the node does not specify a format. + * + * @param array $options Dictionary of formatting options + */ + public function __construct(array $options = []) { + $this->docStringEndToken = '_DOC_STRING_END_' . mt_rand(); + + $defaultOptions = ['shortArraySyntax' => false]; + $this->options = $options + $defaultOptions; + } + + /** + * Reset pretty printing state. + */ + protected function resetState() { + $this->indentLevel = 0; + $this->nl = "\n"; + $this->origTokens = null; + } + + /** + * Set indentation level + * + * @param int $level Level in number of spaces + */ + protected function setIndentLevel(int $level) { + $this->indentLevel = $level; + $this->nl = "\n" . \str_repeat(' ', $level); + } + + /** + * Increase indentation level. + */ + protected function indent() { + $this->indentLevel += 4; + $this->nl .= ' '; + } + + /** + * Decrease indentation level. + */ + protected function outdent() { + assert($this->indentLevel >= 4); + $this->indentLevel -= 4; + $this->nl = "\n" . str_repeat(' ', $this->indentLevel); + } + + /** + * Pretty prints an array of statements. + * + * @param Node[] $stmts Array of statements + * + * @return string Pretty printed statements + */ + public function prettyPrint(array $stmts) : string { + $this->resetState(); + $this->preprocessNodes($stmts); + + return ltrim($this->handleMagicTokens($this->pStmts($stmts, false))); + } + + /** + * Pretty prints an expression. + * + * @param Expr $node Expression node + * + * @return string Pretty printed node + */ + public function prettyPrintExpr(Expr $node) : string { + $this->resetState(); + return $this->handleMagicTokens($this->p($node)); + } + + /** + * Pretty prints a file of statements (includes the opening prettyPrint($stmts); + + if ($stmts[0] instanceof Stmt\InlineHTML) { + $p = preg_replace('/^<\?php\s+\?>\n?/', '', $p); + } + if ($stmts[count($stmts) - 1] instanceof Stmt\InlineHTML) { + $p = preg_replace('/<\?php$/', '', rtrim($p)); + } + + return $p; + } + + /** + * Preprocesses the top-level nodes to initialize pretty printer state. + * + * @param Node[] $nodes Array of nodes + */ + protected function preprocessNodes(array $nodes) { + /* We can use semicolon-namespaces unless there is a global namespace declaration */ + $this->canUseSemicolonNamespaces = true; + foreach ($nodes as $node) { + if ($node instanceof Stmt\Namespace_ && null === $node->name) { + $this->canUseSemicolonNamespaces = false; + break; + } + } + } + + /** + * Handles (and removes) no-indent and doc-string-end tokens. + * + * @param string $str + * @return string + */ + protected function handleMagicTokens(string $str) : string { + // Replace doc-string-end tokens with nothing or a newline + $str = str_replace($this->docStringEndToken . ";\n", ";\n", $str); + $str = str_replace($this->docStringEndToken, "\n", $str); + + return $str; + } + + /** + * Pretty prints an array of nodes (statements) and indents them optionally. + * + * @param Node[] $nodes Array of nodes + * @param bool $indent Whether to indent the printed nodes + * + * @return string Pretty printed statements + */ + protected function pStmts(array $nodes, bool $indent = true) : string { + if ($indent) { + $this->indent(); + } + + $result = ''; + foreach ($nodes as $node) { + $comments = $node->getComments(); + if ($comments) { + $result .= $this->nl . $this->pComments($comments); + if ($node instanceof Stmt\Nop) { + continue; + } + } + + $result .= $this->nl . $this->p($node); + } + + if ($indent) { + $this->outdent(); + } + + return $result; + } + + /** + * Pretty-print an infix operation while taking precedence into account. + * + * @param string $class Node class of operator + * @param Node $leftNode Left-hand side node + * @param string $operatorString String representation of the operator + * @param Node $rightNode Right-hand side node + * + * @return string Pretty printed infix operation + */ + protected function pInfixOp(string $class, Node $leftNode, string $operatorString, Node $rightNode) : string { + list($precedence, $associativity) = $this->precedenceMap[$class]; + + return $this->pPrec($leftNode, $precedence, $associativity, -1) + . $operatorString + . $this->pPrec($rightNode, $precedence, $associativity, 1); + } + + /** + * Pretty-print a prefix operation while taking precedence into account. + * + * @param string $class Node class of operator + * @param string $operatorString String representation of the operator + * @param Node $node Node + * + * @return string Pretty printed prefix operation + */ + protected function pPrefixOp(string $class, string $operatorString, Node $node) : string { + list($precedence, $associativity) = $this->precedenceMap[$class]; + return $operatorString . $this->pPrec($node, $precedence, $associativity, 1); + } + + /** + * Pretty-print a postfix operation while taking precedence into account. + * + * @param string $class Node class of operator + * @param string $operatorString String representation of the operator + * @param Node $node Node + * + * @return string Pretty printed postfix operation + */ + protected function pPostfixOp(string $class, Node $node, string $operatorString) : string { + list($precedence, $associativity) = $this->precedenceMap[$class]; + return $this->pPrec($node, $precedence, $associativity, -1) . $operatorString; + } + + /** + * Prints an expression node with the least amount of parentheses necessary to preserve the meaning. + * + * @param Node $node Node to pretty print + * @param int $parentPrecedence Precedence of the parent operator + * @param int $parentAssociativity Associativity of parent operator + * (-1 is left, 0 is nonassoc, 1 is right) + * @param int $childPosition Position of the node relative to the operator + * (-1 is left, 1 is right) + * + * @return string The pretty printed node + */ + protected function pPrec(Node $node, int $parentPrecedence, int $parentAssociativity, int $childPosition) : string { + $class = \get_class($node); + if (isset($this->precedenceMap[$class])) { + $childPrecedence = $this->precedenceMap[$class][0]; + if ($childPrecedence > $parentPrecedence + || ($parentPrecedence === $childPrecedence && $parentAssociativity !== $childPosition) + ) { + return '(' . $this->p($node) . ')'; + } + } + + return $this->p($node); + } + + /** + * Pretty prints an array of nodes and implodes the printed values. + * + * @param Node[] $nodes Array of Nodes to be printed + * @param string $glue Character to implode with + * + * @return string Imploded pretty printed nodes + */ + protected function pImplode(array $nodes, string $glue = '') : string { + $pNodes = []; + foreach ($nodes as $node) { + if (null === $node) { + $pNodes[] = ''; + } else { + $pNodes[] = $this->p($node); + } + } + + return implode($glue, $pNodes); + } + + /** + * Pretty prints an array of nodes and implodes the printed values with commas. + * + * @param Node[] $nodes Array of Nodes to be printed + * + * @return string Comma separated pretty printed nodes + */ + protected function pCommaSeparated(array $nodes) : string { + return $this->pImplode($nodes, ', '); + } + + /** + * Pretty prints a comma-separated list of nodes in multiline style, including comments. + * + * The result includes a leading newline and one level of indentation (same as pStmts). + * + * @param Node[] $nodes Array of Nodes to be printed + * @param bool $trailingComma Whether to use a trailing comma + * + * @return string Comma separated pretty printed nodes in multiline style + */ + protected function pCommaSeparatedMultiline(array $nodes, bool $trailingComma) : string { + $this->indent(); + + $result = ''; + $lastIdx = count($nodes) - 1; + foreach ($nodes as $idx => $node) { + if ($node !== null) { + $comments = $node->getComments(); + if ($comments) { + $result .= $this->nl . $this->pComments($comments); + } + + $result .= $this->nl . $this->p($node); + } else { + $result .= $this->nl; + } + if ($trailingComma || $idx !== $lastIdx) { + $result .= ','; + } + } + + $this->outdent(); + return $result; + } + + /** + * Prints reformatted text of the passed comments. + * + * @param Comment[] $comments List of comments + * + * @return string Reformatted text of comments + */ + protected function pComments(array $comments) : string { + $formattedComments = []; + + foreach ($comments as $comment) { + $formattedComments[] = str_replace("\n", $this->nl, $comment->getReformattedText()); + } + + return implode($this->nl, $formattedComments); + } + + /** + * Perform a format-preserving pretty print of an AST. + * + * The format preservation is best effort. For some changes to the AST the formatting will not + * be preserved (at least not locally). + * + * In order to use this method a number of prerequisites must be satisfied: + * * The startTokenPos and endTokenPos attributes in the lexer must be enabled. + * * The CloningVisitor must be run on the AST prior to modification. + * * The original tokens must be provided, using the getTokens() method on the lexer. + * + * @param Node[] $stmts Modified AST with links to original AST + * @param Node[] $origStmts Original AST with token offset information + * @param array $origTokens Tokens of the original code + * + * @return string + */ + public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens) : string { + $this->initializeNodeListDiffer(); + $this->initializeLabelCharMap(); + $this->initializeFixupMap(); + $this->initializeRemovalMap(); + $this->initializeInsertionMap(); + $this->initializeListInsertionMap(); + $this->initializeModifierChangeMap(); + + $this->resetState(); + $this->origTokens = new TokenStream($origTokens); + + $this->preprocessNodes($stmts); + + $pos = 0; + $result = $this->pArray($stmts, $origStmts, $pos, 0, 'stmts', null, "\n"); + if (null !== $result) { + $result .= $this->origTokens->getTokenCode($pos, count($origTokens), 0); + } else { + // Fallback + // TODO Add pStmts($stmts, false); + } + + return ltrim($this->handleMagicTokens($result)); + } + + protected function pFallback(Node $node) { + return $this->{'p' . $node->getType()}($node); + } + + /** + * Pretty prints a node. + * + * This method also handles formatting preservation for nodes. + * + * @param Node $node Node to be pretty printed + * @param bool $parentFormatPreserved Whether parent node has preserved formatting + * + * @return string Pretty printed node + */ + protected function p(Node $node, $parentFormatPreserved = false) : string { + // No orig tokens means this is a normal pretty print without preservation of formatting + if (!$this->origTokens) { + return $this->{'p' . $node->getType()}($node); + } + + /** @var Node $origNode */ + $origNode = $node->getAttribute('origNode'); + if (null === $origNode) { + return $this->pFallback($node); + } + + $class = \get_class($node); + \assert($class === \get_class($origNode)); + + $startPos = $origNode->getStartTokenPos(); + $endPos = $origNode->getEndTokenPos(); + \assert($startPos >= 0 && $endPos >= 0); + + $fallbackNode = $node; + if ($node instanceof Expr\New_ && $node->class instanceof Stmt\Class_) { + // Normalize node structure of anonymous classes + $node = PrintableNewAnonClassNode::fromNewNode($node); + $origNode = PrintableNewAnonClassNode::fromNewNode($origNode); + } + + // InlineHTML node does not contain closing and opening PHP tags. If the parent formatting + // is not preserved, then we need to use the fallback code to make sure the tags are + // printed. + if ($node instanceof Stmt\InlineHTML && !$parentFormatPreserved) { + return $this->pFallback($fallbackNode); + } + + $indentAdjustment = $this->indentLevel - $this->origTokens->getIndentationBefore($startPos); + + $type = $node->getType(); + $fixupInfo = $this->fixupMap[$class] ?? null; + + $result = ''; + $pos = $startPos; + foreach ($node->getSubNodeNames() as $subNodeName) { + $subNode = $node->$subNodeName; + $origSubNode = $origNode->$subNodeName; + + if ((!$subNode instanceof Node && $subNode !== null) + || (!$origSubNode instanceof Node && $origSubNode !== null) + ) { + if ($subNode === $origSubNode) { + // Unchanged, can reuse old code + continue; + } + + if (is_array($subNode) && is_array($origSubNode)) { + // Array subnode changed, we might be able to reconstruct it + $listResult = $this->pArray( + $subNode, $origSubNode, $pos, $indentAdjustment, $subNodeName, + $fixupInfo[$subNodeName] ?? null, + $this->listInsertionMap[$type . '->' . $subNodeName] ?? null + ); + if (null === $listResult) { + return $this->pFallback($fallbackNode); + } + + $result .= $listResult; + continue; + } + + if (is_int($subNode) && is_int($origSubNode)) { + // Check if this is a modifier change + $key = $type . '->' . $subNodeName; + if (!isset($this->modifierChangeMap[$key])) { + return $this->pFallback($fallbackNode); + } + + $findToken = $this->modifierChangeMap[$key]; + $result .= $this->pModifiers($subNode); + $pos = $this->origTokens->findRight($pos, $findToken); + continue; + } + + // If a non-node, non-array subnode changed, we don't be able to do a partial + // reconstructions, as we don't have enough offset information. Pretty print the + // whole node instead. + return $this->pFallback($fallbackNode); + } + + $extraLeft = ''; + $extraRight = ''; + if ($origSubNode !== null) { + $subStartPos = $origSubNode->getStartTokenPos(); + $subEndPos = $origSubNode->getEndTokenPos(); + \assert($subStartPos >= 0 && $subEndPos >= 0); + } else { + if ($subNode === null) { + // Both null, nothing to do + continue; + } + + // A node has been inserted, check if we have insertion information for it + $key = $type . '->' . $subNodeName; + if (!isset($this->insertionMap[$key])) { + return $this->pFallback($fallbackNode); + } + + list($findToken, $beforeToken, $extraLeft, $extraRight) = $this->insertionMap[$key]; + if (null !== $findToken) { + $subStartPos = $this->origTokens->findRight($pos, $findToken) + + (int) !$beforeToken; + } else { + $subStartPos = $pos; + } + + if (null === $extraLeft && null !== $extraRight) { + // If inserting on the right only, skipping whitespace looks better + $subStartPos = $this->origTokens->skipRightWhitespace($subStartPos); + } + $subEndPos = $subStartPos - 1; + } + + if (null === $subNode) { + // A node has been removed, check if we have removal information for it + $key = $type . '->' . $subNodeName; + if (!isset($this->removalMap[$key])) { + return $this->pFallback($fallbackNode); + } + + // Adjust positions to account for additional tokens that must be skipped + $removalInfo = $this->removalMap[$key]; + if (isset($removalInfo['left'])) { + $subStartPos = $this->origTokens->skipLeft($subStartPos - 1, $removalInfo['left']) + 1; + } + if (isset($removalInfo['right'])) { + $subEndPos = $this->origTokens->skipRight($subEndPos + 1, $removalInfo['right']) - 1; + } + } + + $result .= $this->origTokens->getTokenCode($pos, $subStartPos, $indentAdjustment); + + if (null !== $subNode) { + $result .= $extraLeft; + + $origIndentLevel = $this->indentLevel; + $this->setIndentLevel($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment); + + // If it's the same node that was previously in this position, it certainly doesn't + // need fixup. It's important to check this here, because our fixup checks are more + // conservative than strictly necessary. + if (isset($fixupInfo[$subNodeName]) + && $subNode->getAttribute('origNode') !== $origSubNode + ) { + $fixup = $fixupInfo[$subNodeName]; + $res = $this->pFixup($fixup, $subNode, $class, $subStartPos, $subEndPos); + } else { + $res = $this->p($subNode, true); + } + + $this->safeAppend($result, $res); + $this->setIndentLevel($origIndentLevel); + + $result .= $extraRight; + } + + $pos = $subEndPos + 1; + } + + $result .= $this->origTokens->getTokenCode($pos, $endPos + 1, $indentAdjustment); + return $result; + } + + /** + * Perform a format-preserving pretty print of an array. + * + * @param array $nodes New nodes + * @param array $origNodes Original nodes + * @param int $pos Current token position (updated by reference) + * @param int $indentAdjustment Adjustment for indentation + * @param string $subNodeName Name of array subnode. + * @param null|int $fixup Fixup information for array item nodes + * @param null|string $insertStr Separator string to use for insertions + * + * @return null|string Result of pretty print or null if cannot preserve formatting + */ + protected function pArray( + array $nodes, array $origNodes, int &$pos, int $indentAdjustment, + string $subNodeName, $fixup, $insertStr + ) { + $diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes); + + $beforeFirstKeepOrReplace = true; + $delayedAdd = []; + $lastElemIndentLevel = $this->indentLevel; + + $insertNewline = false; + if ($insertStr === "\n") { + $insertStr = ''; + $insertNewline = true; + } + + if ($subNodeName === 'stmts' && \count($origNodes) === 1 && \count($nodes) !== 1) { + $startPos = $origNodes[0]->getStartTokenPos(); + $endPos = $origNodes[0]->getEndTokenPos(); + \assert($startPos >= 0 && $endPos >= 0); + if (!$this->origTokens->haveBraces($startPos, $endPos)) { + // This was a single statement without braces, but either additional statements + // have been added, or the single statement has been removed. This requires the + // addition of braces. For now fall back. + // TODO: Try to preserve formatting + return null; + } + } + + $result = ''; + foreach ($diff as $i => $diffElem) { + $diffType = $diffElem->type; + /** @var Node|null $arrItem */ + $arrItem = $diffElem->new; + /** @var Node|null $origArrItem */ + $origArrItem = $diffElem->old; + + if ($diffType === DiffElem::TYPE_KEEP || $diffType === DiffElem::TYPE_REPLACE) { + $beforeFirstKeepOrReplace = false; + + if ($origArrItem === null || $arrItem === null) { + // We can only handle the case where both are null + if ($origArrItem === $arrItem) { + continue; + } + return null; + } + + if (!$arrItem instanceof Node || !$origArrItem instanceof Node) { + // We can only deal with nodes. This can occur for Names, which use string arrays. + return null; + } + + $itemStartPos = $origArrItem->getStartTokenPos(); + $itemEndPos = $origArrItem->getEndTokenPos(); + \assert($itemStartPos >= 0 && $itemEndPos >= 0); + + if ($itemEndPos < $itemStartPos) { + // End can be before start for Nop nodes, because offsets refer to non-whitespace + // locations, which for an "empty" node might result in an inverted order. + assert($origArrItem instanceof Stmt\Nop); + continue; + } + + $origIndentLevel = $this->indentLevel; + $lastElemIndentLevel = $this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment; + $this->setIndentLevel($lastElemIndentLevel); + + $comments = $arrItem->getComments(); + $origComments = $origArrItem->getComments(); + $commentStartPos = $origComments ? $origComments[0]->getTokenPos() : $itemStartPos; + \assert($commentStartPos >= 0); + + $commentsChanged = $comments !== $origComments; + if ($commentsChanged) { + // Remove old comments + $itemStartPos = $commentStartPos; + } + + if (!empty($delayedAdd)) { + $result .= $this->origTokens->getTokenCode( + $pos, $commentStartPos, $indentAdjustment); + + /** @var Node $delayedAddNode */ + foreach ($delayedAdd as $delayedAddNode) { + if ($insertNewline) { + $delayedAddComments = $delayedAddNode->getComments(); + if ($delayedAddComments) { + $result .= $this->pComments($delayedAddComments) . $this->nl; + } + } + + $this->safeAppend($result, $this->p($delayedAddNode, true)); + + if ($insertNewline) { + $result .= $insertStr . $this->nl; + } else { + $result .= $insertStr; + } + } + + $result .= $this->origTokens->getTokenCode( + $commentStartPos, $itemStartPos, $indentAdjustment); + + $delayedAdd = []; + } else { + $result .= $this->origTokens->getTokenCode( + $pos, $itemStartPos, $indentAdjustment); + } + + if ($commentsChanged && $comments) { + // Add new comments + $result .= $this->pComments($comments) . $this->nl; + } + } elseif ($diffType === DiffElem::TYPE_ADD) { + if (null === $insertStr) { + // We don't have insertion information for this list type + return null; + } + + if ($insertStr === ', ' && $this->isMultiline($origNodes)) { + $insertStr = ','; + $insertNewline = true; + } + + if ($beforeFirstKeepOrReplace) { + // Will be inserted at the next "replace" or "keep" element + $delayedAdd[] = $arrItem; + continue; + } + + $itemStartPos = $pos; + $itemEndPos = $pos - 1; + + $origIndentLevel = $this->indentLevel; + $this->setIndentLevel($lastElemIndentLevel); + + if ($insertNewline) { + $comments = $arrItem->getComments(); + if ($comments) { + $result .= $this->nl . $this->pComments($comments); + } + $result .= $insertStr . $this->nl; + } else { + $result .= $insertStr; + } + } elseif ($diffType === DiffElem::TYPE_REMOVE) { + if ($i === 0) { + // TODO Handle removal at the start + return null; + } + + if (!$origArrItem instanceof Node) { + // We only support removal for nodes + return null; + } + + $itemEndPos = $origArrItem->getEndTokenPos(); + \assert($itemEndPos >= 0); + + $pos = $itemEndPos + 1; + continue; + } else { + throw new \Exception("Shouldn't happen"); + } + + if (null !== $fixup && $arrItem->getAttribute('origNode') !== $origArrItem) { + $res = $this->pFixup($fixup, $arrItem, null, $itemStartPos, $itemEndPos); + } else { + $res = $this->p($arrItem, true); + } + $this->safeAppend($result, $res); + + $this->setIndentLevel($origIndentLevel); + $pos = $itemEndPos + 1; + } + + if (!empty($delayedAdd)) { + // TODO Handle insertion into empty list + return null; + } + + return $result; + } + + /** + * Print node with fixups. + * + * Fixups here refer to the addition of extra parentheses, braces or other characters, that + * are required to preserve program semantics in a certain context (e.g. to maintain precedence + * or because only certain expressions are allowed in certain places). + * + * @param int $fixup Fixup type + * @param Node $subNode Subnode to print + * @param string|null $parentClass Class of parent node + * @param int $subStartPos Original start pos of subnode + * @param int $subEndPos Original end pos of subnode + * + * @return string Result of fixed-up print of subnode + */ + protected function pFixup(int $fixup, Node $subNode, $parentClass, int $subStartPos, int $subEndPos) : string { + switch ($fixup) { + case self::FIXUP_PREC_LEFT: + case self::FIXUP_PREC_RIGHT: + if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) { + list($precedence, $associativity) = $this->precedenceMap[$parentClass]; + return $this->pPrec($subNode, $precedence, $associativity, + $fixup === self::FIXUP_PREC_LEFT ? -1 : 1); + } + break; + case self::FIXUP_CALL_LHS: + if ($this->callLhsRequiresParens($subNode) + && !$this->origTokens->haveParens($subStartPos, $subEndPos) + ) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_DEREF_LHS: + if ($this->dereferenceLhsRequiresParens($subNode) + && !$this->origTokens->haveParens($subStartPos, $subEndPos) + ) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_BRACED_NAME: + case self::FIXUP_VAR_BRACED_NAME: + if ($subNode instanceof Expr + && !$this->origTokens->haveBraces($subStartPos, $subEndPos) + ) { + return ($fixup === self::FIXUP_VAR_BRACED_NAME ? '$' : '') + . '{' . $this->p($subNode) . '}'; + } + break; + case self::FIXUP_ENCAPSED: + if (!$subNode instanceof Scalar\EncapsedStringPart + && !$this->origTokens->haveBraces($subStartPos, $subEndPos) + ) { + return '{' . $this->p($subNode) . '}'; + } + break; + default: + throw new \Exception('Cannot happen'); + } + + // Nothing special to do + return $this->p($subNode); + } + + /** + * Appends to a string, ensuring whitespace between label characters. + * + * Example: "echo" and "$x" result in "echo$x", but "echo" and "x" result in "echo x". + * Without safeAppend the result would be "echox", which does not preserve semantics. + * + * @param string $str + * @param string $append + */ + protected function safeAppend(string &$str, string $append) { + if ($str === "") { + $str = $append; + return; + } + + if ($append === "") { + return; + } + + if (!$this->labelCharMap[$append[0]] + || !$this->labelCharMap[$str[\strlen($str) - 1]]) { + $str .= $append; + } else { + $str .= " " . $append; + } + } + + /** + * Determines whether the LHS of a call must be wrapped in parenthesis. + * + * @param Node $node LHS of a call + * + * @return bool Whether parentheses are required + */ + protected function callLhsRequiresParens(Node $node) : bool { + return !($node instanceof Node\Name + || $node instanceof Expr\Variable + || $node instanceof Expr\ArrayDimFetch + || $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\StaticCall + || $node instanceof Expr\Array_); + } + + /** + * Determines whether the LHS of a dereferencing operation must be wrapped in parenthesis. + * + * @param Node $node LHS of dereferencing operation + * + * @return bool Whether parentheses are required + */ + protected function dereferenceLhsRequiresParens(Node $node) : bool { + return !($node instanceof Expr\Variable + || $node instanceof Node\Name + || $node instanceof Expr\ArrayDimFetch + || $node instanceof Expr\PropertyFetch + || $node instanceof Expr\StaticPropertyFetch + || $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\StaticCall + || $node instanceof Expr\Array_ + || $node instanceof Scalar\String_ + || $node instanceof Expr\ConstFetch + || $node instanceof Expr\ClassConstFetch); + } + + /** + * Print modifiers, including trailing whitespace. + * + * @param int $modifiers Modifier mask to print + * + * @return string Printed modifiers + */ + protected function pModifiers(int $modifiers) { + return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : ''); + } + + /** + * Determine whether a list of nodes uses multiline formatting. + * + * @param (Node|null)[] $nodes Node list + * + * @return bool Whether multiline formatting is used + */ + protected function isMultiline(array $nodes) : bool { + if (\count($nodes) < 2) { + return false; + } + + $pos = -1; + foreach ($nodes as $node) { + if (null === $node) { + continue; + } + + $endPos = $node->getEndTokenPos() + 1; + if ($pos >= 0) { + $text = $this->origTokens->getTokenCode($pos, $endPos, 0); + if (false === strpos($text, "\n")) { + // We require that a newline is present between *every* item. If the formatting + // is inconsistent, with only some items having newlines, we don't consider it + // as multiline + return false; + } + } + $pos = $endPos; + } + + return true; + } + + /** + * Lazily initializes label char map. + * + * The label char map determines whether a certain character may occur in a label. + */ + protected function initializeLabelCharMap() { + if ($this->labelCharMap) return; + + $this->labelCharMap = []; + for ($i = 0; $i < 256; $i++) { + // Since PHP 7.1 The lower range is 0x80. However, we also want to support code for + // older versions. + $this->labelCharMap[chr($i)] = $i >= 0x7f || ctype_alnum($i); + } + } + + /** + * Lazily initializes node list differ. + * + * The node list differ is used to determine differences between two array subnodes. + */ + protected function initializeNodeListDiffer() { + if ($this->nodeListDiffer) return; + + $this->nodeListDiffer = new Internal\Differ(function ($a, $b) { + if ($a instanceof Node && $b instanceof Node) { + return $a === $b->getAttribute('origNode'); + } + // Can happen for array destructuring + return $a === null && $b === null; + }); + } + + /** + * Lazily initializes fixup map. + * + * The fixup map is used to determine whether a certain subnode of a certain node may require + * some kind of "fixup" operation, e.g. the addition of parenthesis or braces. + */ + protected function initializeFixupMap() { + if ($this->fixupMap) return; + + $this->fixupMap = [ + Expr\PreInc::class => ['var' => self::FIXUP_PREC_RIGHT], + Expr\PreDec::class => ['var' => self::FIXUP_PREC_RIGHT], + Expr\PostInc::class => ['var' => self::FIXUP_PREC_LEFT], + Expr\PostDec::class => ['var' => self::FIXUP_PREC_LEFT], + Expr\Instanceof_::class => [ + 'expr' => self::FIXUP_PREC_LEFT, + 'class' => self::FIXUP_PREC_RIGHT, + ], + Expr\Ternary::class => [ + 'cond' => self::FIXUP_PREC_LEFT, + 'else' => self::FIXUP_PREC_RIGHT, + ], + + Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS], + Expr\StaticCall::class => ['class' => self::FIXUP_DEREF_LHS], + Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS], + Expr\MethodCall::class => [ + 'var' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Expr\StaticPropertyFetch::class => [ + 'class' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_VAR_BRACED_NAME, + ], + Expr\PropertyFetch::class => [ + 'var' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Scalar\Encapsed::class => [ + 'parts' => self::FIXUP_ENCAPSED, + ], + ]; + + $binaryOps = [ + BinaryOp\Pow::class, BinaryOp\Mul::class, BinaryOp\Div::class, BinaryOp\Mod::class, + BinaryOp\Plus::class, BinaryOp\Minus::class, BinaryOp\Concat::class, + BinaryOp\ShiftLeft::class, BinaryOp\ShiftRight::class, BinaryOp\Smaller::class, + BinaryOp\SmallerOrEqual::class, BinaryOp\Greater::class, BinaryOp\GreaterOrEqual::class, + BinaryOp\Equal::class, BinaryOp\NotEqual::class, BinaryOp\Identical::class, + BinaryOp\NotIdentical::class, BinaryOp\Spaceship::class, BinaryOp\BitwiseAnd::class, + BinaryOp\BitwiseXor::class, BinaryOp\BitwiseOr::class, BinaryOp\BooleanAnd::class, + BinaryOp\BooleanOr::class, BinaryOp\Coalesce::class, BinaryOp\LogicalAnd::class, + BinaryOp\LogicalXor::class, BinaryOp\LogicalOr::class, + ]; + foreach ($binaryOps as $binaryOp) { + $this->fixupMap[$binaryOp] = [ + 'left' => self::FIXUP_PREC_LEFT, + 'right' => self::FIXUP_PREC_RIGHT + ]; + } + + $assignOps = [ + Expr\Assign::class, Expr\AssignRef::class, AssignOp\Plus::class, AssignOp\Minus::class, + AssignOp\Mul::class, AssignOp\Div::class, AssignOp\Concat::class, AssignOp\Mod::class, + AssignOp\BitwiseAnd::class, AssignOp\BitwiseOr::class, AssignOp\BitwiseXor::class, + AssignOp\ShiftLeft::class, AssignOp\ShiftRight::class, AssignOp\Pow::class, AssignOp\Coalesce::class + ]; + foreach ($assignOps as $assignOp) { + $this->fixupMap[$assignOp] = [ + 'var' => self::FIXUP_PREC_LEFT, + 'expr' => self::FIXUP_PREC_RIGHT, + ]; + } + + $prefixOps = [ + Expr\BitwiseNot::class, Expr\BooleanNot::class, Expr\UnaryPlus::class, Expr\UnaryMinus::class, + Cast\Int_::class, Cast\Double::class, Cast\String_::class, Cast\Array_::class, + Cast\Object_::class, Cast\Bool_::class, Cast\Unset_::class, Expr\ErrorSuppress::class, + Expr\YieldFrom::class, Expr\Print_::class, Expr\Include_::class, + ]; + foreach ($prefixOps as $prefixOp) { + $this->fixupMap[$prefixOp] = ['expr' => self::FIXUP_PREC_RIGHT]; + } + } + + /** + * Lazily initializes the removal map. + * + * The removal map is used to determine which additional tokens should be returned when a + * certain node is replaced by null. + */ + protected function initializeRemovalMap() { + if ($this->removalMap) return; + + $stripBoth = ['left' => \T_WHITESPACE, 'right' => \T_WHITESPACE]; + $stripLeft = ['left' => \T_WHITESPACE]; + $stripRight = ['right' => \T_WHITESPACE]; + $stripDoubleArrow = ['right' => \T_DOUBLE_ARROW]; + $stripColon = ['left' => ':']; + $stripEquals = ['left' => '=']; + $this->removalMap = [ + 'Expr_ArrayDimFetch->dim' => $stripBoth, + 'Expr_ArrayItem->key' => $stripDoubleArrow, + 'Expr_Closure->returnType' => $stripColon, + 'Expr_Exit->expr' => $stripBoth, + 'Expr_Ternary->if' => $stripBoth, + 'Expr_Yield->key' => $stripDoubleArrow, + 'Expr_Yield->value' => $stripBoth, + 'Param->type' => $stripRight, + 'Param->default' => $stripEquals, + 'Stmt_Break->num' => $stripBoth, + 'Stmt_ClassMethod->returnType' => $stripColon, + 'Stmt_Class->extends' => ['left' => \T_EXTENDS], + 'Expr_PrintableNewAnonClass->extends' => ['left' => \T_EXTENDS], + 'Stmt_Continue->num' => $stripBoth, + 'Stmt_Foreach->keyVar' => $stripDoubleArrow, + 'Stmt_Function->returnType' => $stripColon, + 'Stmt_If->else' => $stripLeft, + 'Stmt_Namespace->name' => $stripLeft, + 'Stmt_Property->type' => $stripRight, + 'Stmt_PropertyProperty->default' => $stripEquals, + 'Stmt_Return->expr' => $stripBoth, + 'Stmt_StaticVar->default' => $stripEquals, + 'Stmt_TraitUseAdaptation_Alias->newName' => $stripLeft, + 'Stmt_TryCatch->finally' => $stripLeft, + // 'Stmt_Case->cond': Replace with "default" + // 'Stmt_Class->name': Unclear what to do + // 'Stmt_Declare->stmts': Not a plain node + // 'Stmt_TraitUseAdaptation_Alias->newModifier': Not a plain node + ]; + } + + protected function initializeInsertionMap() { + if ($this->insertionMap) return; + + // TODO: "yield" where both key and value are inserted doesn't work + $this->insertionMap = [ + 'Expr_ArrayDimFetch->dim' => ['[', false, null, null], + 'Expr_ArrayItem->key' => [null, false, null, ' => '], + 'Expr_Closure->returnType' => [')', false, ' : ', null], + 'Expr_Ternary->if' => ['?', false, ' ', ' '], + 'Expr_Yield->key' => [\T_YIELD, false, null, ' => '], + 'Expr_Yield->value' => [\T_YIELD, false, ' ', null], + 'Param->type' => [null, false, null, ' '], + 'Param->default' => [null, false, ' = ', null], + 'Stmt_Break->num' => [\T_BREAK, false, ' ', null], + 'Stmt_ClassMethod->returnType' => [')', false, ' : ', null], + 'Stmt_Class->extends' => [null, false, ' extends ', null], + 'Expr_PrintableNewAnonClass->extends' => [null, ' extends ', null], + 'Stmt_Continue->num' => [\T_CONTINUE, false, ' ', null], + 'Stmt_Foreach->keyVar' => [\T_AS, false, null, ' => '], + 'Stmt_Function->returnType' => [')', false, ' : ', null], + 'Stmt_If->else' => [null, false, ' ', null], + 'Stmt_Namespace->name' => [\T_NAMESPACE, false, ' ', null], + 'Stmt_Property->type' => [\T_VARIABLE, true, null, ' '], + 'Stmt_PropertyProperty->default' => [null, false, ' = ', null], + 'Stmt_Return->expr' => [\T_RETURN, false, ' ', null], + 'Stmt_StaticVar->default' => [null, false, ' = ', null], + //'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, false, ' ', null], // TODO + 'Stmt_TryCatch->finally' => [null, false, ' ', null], + + // 'Expr_Exit->expr': Complicated due to optional () + // 'Stmt_Case->cond': Conversion from default to case + // 'Stmt_Class->name': Unclear + // 'Stmt_Declare->stmts': Not a proper node + // 'Stmt_TraitUseAdaptation_Alias->newModifier': Not a proper node + ]; + } + + protected function initializeListInsertionMap() { + if ($this->listInsertionMap) return; + + $this->listInsertionMap = [ + // special + //'Expr_ShellExec->parts' => '', // TODO These need to be treated more carefully + //'Scalar_Encapsed->parts' => '', + 'Stmt_Catch->types' => '|', + 'Stmt_If->elseifs' => ' ', + 'Stmt_TryCatch->catches' => ' ', + + // comma-separated lists + 'Expr_Array->items' => ', ', + 'Expr_Closure->params' => ', ', + 'Expr_Closure->uses' => ', ', + 'Expr_FuncCall->args' => ', ', + 'Expr_Isset->vars' => ', ', + 'Expr_List->items' => ', ', + 'Expr_MethodCall->args' => ', ', + 'Expr_New->args' => ', ', + 'Expr_PrintableNewAnonClass->args' => ', ', + 'Expr_StaticCall->args' => ', ', + 'Stmt_ClassConst->consts' => ', ', + 'Stmt_ClassMethod->params' => ', ', + 'Stmt_Class->implements' => ', ', + 'Expr_PrintableNewAnonClass->implements' => ', ', + 'Stmt_Const->consts' => ', ', + 'Stmt_Declare->declares' => ', ', + 'Stmt_Echo->exprs' => ', ', + 'Stmt_For->init' => ', ', + 'Stmt_For->cond' => ', ', + 'Stmt_For->loop' => ', ', + 'Stmt_Function->params' => ', ', + 'Stmt_Global->vars' => ', ', + 'Stmt_GroupUse->uses' => ', ', + 'Stmt_Interface->extends' => ', ', + 'Stmt_Property->props' => ', ', + 'Stmt_StaticVar->vars' => ', ', + 'Stmt_TraitUse->traits' => ', ', + 'Stmt_TraitUseAdaptation_Precedence->insteadof' => ', ', + 'Stmt_Unset->vars' => ', ', + 'Stmt_Use->uses' => ', ', + + // statement lists + 'Expr_Closure->stmts' => "\n", + 'Stmt_Case->stmts' => "\n", + 'Stmt_Catch->stmts' => "\n", + 'Stmt_Class->stmts' => "\n", + 'Expr_PrintableNewAnonClass->stmts' => "\n", + 'Stmt_Interface->stmts' => "\n", + 'Stmt_Trait->stmts' => "\n", + 'Stmt_ClassMethod->stmts' => "\n", + 'Stmt_Declare->stmts' => "\n", + 'Stmt_Do->stmts' => "\n", + 'Stmt_ElseIf->stmts' => "\n", + 'Stmt_Else->stmts' => "\n", + 'Stmt_Finally->stmts' => "\n", + 'Stmt_Foreach->stmts' => "\n", + 'Stmt_For->stmts' => "\n", + 'Stmt_Function->stmts' => "\n", + 'Stmt_If->stmts' => "\n", + 'Stmt_Namespace->stmts' => "\n", + 'Stmt_Switch->cases' => "\n", + 'Stmt_TraitUse->adaptations' => "\n", + 'Stmt_TryCatch->stmts' => "\n", + 'Stmt_While->stmts' => "\n", + ]; + } + + protected function initializeModifierChangeMap() { + if ($this->modifierChangeMap) return; + + $this->modifierChangeMap = [ + 'Stmt_ClassConst->flags' => \T_CONST, + 'Stmt_ClassMethod->flags' => \T_FUNCTION, + 'Stmt_Class->flags' => \T_CLASS, + 'Stmt_Property->flags' => \T_VARIABLE, + //'Stmt_TraitUseAdaptation_Alias->newModifier' => 0, // TODO + ]; + + // List of integer subnodes that are not modifiers: + // Expr_Include->type + // Stmt_GroupUse->type + // Stmt_Use->type + // Stmt_UseUse->type + } +} diff --git a/vendor/nikic/php-parser/phpunit.xml.dist b/vendor/nikic/php-parser/phpunit.xml.dist new file mode 100644 index 00000000..5271264c --- /dev/null +++ b/vendor/nikic/php-parser/phpunit.xml.dist @@ -0,0 +1,20 @@ + + + + + + ./test/ + + + + + + ./lib/PhpParser/ + + + diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php new file mode 100644 index 00000000..2cfa7872 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php @@ -0,0 +1,153 @@ +createClassBuilder('SomeLogger') + ->extend('BaseLogger') + ->implement('Namespaced\Logger', new Name('SomeInterface')) + ->implement('\Fully\Qualified', 'namespace\NamespaceRelative') + ->getNode() + ; + + $this->assertEquals( + new Stmt\Class_('SomeLogger', [ + 'extends' => new Name('BaseLogger'), + 'implements' => [ + new Name('Namespaced\Logger'), + new Name('SomeInterface'), + new Name\FullyQualified('Fully\Qualified'), + new Name\Relative('NamespaceRelative'), + ], + ]), + $node + ); + } + + public function testAbstract() { + $node = $this->createClassBuilder('Test') + ->makeAbstract() + ->getNode() + ; + + $this->assertEquals( + new Stmt\Class_('Test', [ + 'flags' => Stmt\Class_::MODIFIER_ABSTRACT + ]), + $node + ); + } + + public function testFinal() { + $node = $this->createClassBuilder('Test') + ->makeFinal() + ->getNode() + ; + + $this->assertEquals( + new Stmt\Class_('Test', [ + 'flags' => Stmt\Class_::MODIFIER_FINAL + ]), + $node + ); + } + + public function testStatementOrder() { + $method = new Stmt\ClassMethod('testMethod'); + $property = new Stmt\Property( + Stmt\Class_::MODIFIER_PUBLIC, + [new Stmt\PropertyProperty('testProperty')] + ); + $const = new Stmt\ClassConst([ + new Node\Const_('TEST_CONST', new Node\Scalar\String_('ABC')) + ]); + $use = new Stmt\TraitUse([new Name('SomeTrait')]); + + $node = $this->createClassBuilder('Test') + ->addStmt($method) + ->addStmt($property) + ->addStmts([$const, $use]) + ->getNode() + ; + + $this->assertEquals( + new Stmt\Class_('Test', [ + 'stmts' => [$use, $const, $property, $method] + ]), + $node + ); + } + + public function testDocComment() { + $docComment = <<<'DOC' +/** + * Test + */ +DOC; + $class = $this->createClassBuilder('Test') + ->setDocComment($docComment) + ->getNode(); + + $this->assertEquals( + new Stmt\Class_('Test', [], [ + 'comments' => [ + new Comment\Doc($docComment) + ] + ]), + $class + ); + + $class = $this->createClassBuilder('Test') + ->setDocComment(new Comment\Doc($docComment)) + ->getNode(); + + $this->assertEquals( + new Stmt\Class_('Test', [], [ + 'comments' => [ + new Comment\Doc($docComment) + ] + ]), + $class + ); + } + + public function testInvalidStmtError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Unexpected node of type "Stmt_Echo"'); + $this->createClassBuilder('Test') + ->addStmt(new Stmt\Echo_([])) + ; + } + + public function testInvalidDocComment() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Doc comment must be a string or an instance of PhpParser\Comment\Doc'); + $this->createClassBuilder('Test') + ->setDocComment(new Comment('Test')); + } + + public function testEmptyName() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Name cannot be empty'); + $this->createClassBuilder('Test') + ->extend(''); + } + + public function testInvalidName() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Name must be a string or an instance of Node\Name'); + $this->createClassBuilder('Test') + ->extend(['Foo']); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php new file mode 100644 index 00000000..c17045b8 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php @@ -0,0 +1,114 @@ +createFunctionBuilder('test') + ->makeReturnByRef() + ->getNode() + ; + + $this->assertEquals( + new Stmt\Function_('test', [ + 'byRef' => true + ]), + $node + ); + } + + public function testParams() { + $param1 = new Node\Param(new Variable('test1')); + $param2 = new Node\Param(new Variable('test2')); + $param3 = new Node\Param(new Variable('test3')); + + $node = $this->createFunctionBuilder('test') + ->addParam($param1) + ->addParams([$param2, $param3]) + ->getNode() + ; + + $this->assertEquals( + new Stmt\Function_('test', [ + 'params' => [$param1, $param2, $param3] + ]), + $node + ); + } + + public function testStmts() { + $stmt1 = new Print_(new String_('test1')); + $stmt2 = new Print_(new String_('test2')); + $stmt3 = new Print_(new String_('test3')); + + $node = $this->createFunctionBuilder('test') + ->addStmt($stmt1) + ->addStmts([$stmt2, $stmt3]) + ->getNode() + ; + + $this->assertEquals( + new Stmt\Function_('test', [ + 'stmts' => [ + new Stmt\Expression($stmt1), + new Stmt\Expression($stmt2), + new Stmt\Expression($stmt3), + ] + ]), + $node + ); + } + + public function testDocComment() { + $node = $this->createFunctionBuilder('test') + ->setDocComment('/** Test */') + ->getNode(); + + $this->assertEquals(new Stmt\Function_('test', [], [ + 'comments' => [new Comment\Doc('/** Test */')] + ]), $node); + } + + public function testReturnType() { + $node = $this->createFunctionBuilder('test') + ->setReturnType('void') + ->getNode(); + + $this->assertEquals(new Stmt\Function_('test', [ + 'returnType' => 'void' + ], []), $node); + } + + public function testInvalidNullableVoidType() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('void type cannot be nullable'); + $this->createFunctionBuilder('test')->setReturnType('?void'); + } + + public function testInvalidParamError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Expected parameter node, got "Name"'); + $this->createFunctionBuilder('test') + ->addParam(new Node\Name('foo')) + ; + } + + public function testAddNonStmt() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Expected statement or expression node'); + $this->createFunctionBuilder('test') + ->addStmt(new Node\Name('Test')); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php new file mode 100644 index 00000000..7f7f56a2 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php @@ -0,0 +1,102 @@ +builder = new Interface_('Contract'); + } + + private function dump($node) { + $pp = new \PhpParser\PrettyPrinter\Standard; + return $pp->prettyPrint([$node]); + } + + public function testEmpty() { + $contract = $this->builder->getNode(); + $this->assertInstanceOf(Stmt\Interface_::class, $contract); + $this->assertEquals(new Node\Identifier('Contract'), $contract->name); + } + + public function testExtending() { + $contract = $this->builder->extend('Space\Root1', 'Root2')->getNode(); + $this->assertEquals( + new Stmt\Interface_('Contract', [ + 'extends' => [ + new Node\Name('Space\Root1'), + new Node\Name('Root2') + ], + ]), $contract + ); + } + + public function testAddMethod() { + $method = new Stmt\ClassMethod('doSomething'); + $contract = $this->builder->addStmt($method)->getNode(); + $this->assertSame([$method], $contract->stmts); + } + + public function testAddConst() { + $const = new Stmt\ClassConst([ + new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458.0)) + ]); + $contract = $this->builder->addStmt($const)->getNode(); + $this->assertSame(299792458.0, $contract->stmts[0]->consts[0]->value->value); + } + + public function testOrder() { + $const = new Stmt\ClassConst([ + new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458)) + ]); + $method = new Stmt\ClassMethod('doSomething'); + $contract = $this->builder + ->addStmt($method) + ->addStmt($const) + ->getNode() + ; + + $this->assertInstanceOf(Stmt\ClassConst::class, $contract->stmts[0]); + $this->assertInstanceOf(Stmt\ClassMethod::class, $contract->stmts[1]); + } + + public function testDocComment() { + $node = $this->builder + ->setDocComment('/** Test */') + ->getNode(); + + $this->assertEquals(new Stmt\Interface_('Contract', [], [ + 'comments' => [new Comment\Doc('/** Test */')] + ]), $node); + } + + public function testInvalidStmtError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Unexpected node of type "Stmt_PropertyProperty"'); + $this->builder->addStmt(new Stmt\PropertyProperty('invalid')); + } + + public function testFullFunctional() { + $const = new Stmt\ClassConst([ + new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458)) + ]); + $method = new Stmt\ClassMethod('doSomething'); + $contract = $this->builder + ->addStmt($method) + ->addStmt($const) + ->getNode() + ; + + eval($this->dump($contract)); + + $this->assertTrue(interface_exists('Contract', false)); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php new file mode 100644 index 00000000..529f0354 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php @@ -0,0 +1,162 @@ +createMethodBuilder('test') + ->makePublic() + ->makeAbstract() + ->makeStatic() + ->getNode() + ; + + $this->assertEquals( + new Stmt\ClassMethod('test', [ + 'flags' => Stmt\Class_::MODIFIER_PUBLIC + | Stmt\Class_::MODIFIER_ABSTRACT + | Stmt\Class_::MODIFIER_STATIC, + 'stmts' => null, + ]), + $node + ); + + $node = $this->createMethodBuilder('test') + ->makeProtected() + ->makeFinal() + ->getNode() + ; + + $this->assertEquals( + new Stmt\ClassMethod('test', [ + 'flags' => Stmt\Class_::MODIFIER_PROTECTED + | Stmt\Class_::MODIFIER_FINAL + ]), + $node + ); + + $node = $this->createMethodBuilder('test') + ->makePrivate() + ->getNode() + ; + + $this->assertEquals( + new Stmt\ClassMethod('test', [ + 'type' => Stmt\Class_::MODIFIER_PRIVATE + ]), + $node + ); + } + + public function testReturnByRef() { + $node = $this->createMethodBuilder('test') + ->makeReturnByRef() + ->getNode() + ; + + $this->assertEquals( + new Stmt\ClassMethod('test', [ + 'byRef' => true + ]), + $node + ); + } + + public function testParams() { + $param1 = new Node\Param(new Variable('test1')); + $param2 = new Node\Param(new Variable('test2')); + $param3 = new Node\Param(new Variable('test3')); + + $node = $this->createMethodBuilder('test') + ->addParam($param1) + ->addParams([$param2, $param3]) + ->getNode() + ; + + $this->assertEquals( + new Stmt\ClassMethod('test', [ + 'params' => [$param1, $param2, $param3] + ]), + $node + ); + } + + public function testStmts() { + $stmt1 = new Print_(new String_('test1')); + $stmt2 = new Print_(new String_('test2')); + $stmt3 = new Print_(new String_('test3')); + + $node = $this->createMethodBuilder('test') + ->addStmt($stmt1) + ->addStmts([$stmt2, $stmt3]) + ->getNode() + ; + + $this->assertEquals( + new Stmt\ClassMethod('test', [ + 'stmts' => [ + new Stmt\Expression($stmt1), + new Stmt\Expression($stmt2), + new Stmt\Expression($stmt3), + ] + ]), + $node + ); + } + public function testDocComment() { + $node = $this->createMethodBuilder('test') + ->setDocComment('/** Test */') + ->getNode(); + + $this->assertEquals(new Stmt\ClassMethod('test', [], [ + 'comments' => [new Comment\Doc('/** Test */')] + ]), $node); + } + + public function testReturnType() { + $node = $this->createMethodBuilder('test') + ->setReturnType('bool') + ->getNode(); + $this->assertEquals(new Stmt\ClassMethod('test', [ + 'returnType' => 'bool' + ], []), $node); + } + + public function testAddStmtToAbstractMethodError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot add statements to an abstract method'); + $this->createMethodBuilder('test') + ->makeAbstract() + ->addStmt(new Print_(new String_('test'))) + ; + } + + public function testMakeMethodWithStmtsAbstractError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot make method with statements abstract'); + $this->createMethodBuilder('test') + ->addStmt(new Print_(new String_('test'))) + ->makeAbstract() + ; + } + + public function testInvalidParamError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Expected parameter node, got "Name"'); + $this->createMethodBuilder('test') + ->addParam(new Node\Name('foo')) + ; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php new file mode 100644 index 00000000..689001bc --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php @@ -0,0 +1,46 @@ + [$docComment]] + ); + + $node = $this->createNamespaceBuilder('Name\Space') + ->addStmt($stmt1) + ->addStmts([$stmt2, $stmt3]) + ->setDocComment($docComment) + ->getNode() + ; + $this->assertEquals($expected, $node); + + $node = $this->createNamespaceBuilder(new Node\Name(['Name', 'Space'])) + ->setDocComment($docComment) + ->addStmts([$stmt1, $stmt2]) + ->addStmt($stmt3) + ->getNode() + ; + $this->assertEquals($expected, $node); + + $node = $this->createNamespaceBuilder(null)->getNode(); + $this->assertNull($node->name); + $this->assertEmpty($node->stmts); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php new file mode 100644 index 00000000..c9cbfcac --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php @@ -0,0 +1,166 @@ +createParamBuilder('test') + ->setDefault($value) + ->getNode() + ; + + $this->assertEquals($expectedValueNode, $node->default); + } + + public function provideTestDefaultValues() { + return [ + [ + null, + new Expr\ConstFetch(new Node\Name('null')) + ], + [ + true, + new Expr\ConstFetch(new Node\Name('true')) + ], + [ + false, + new Expr\ConstFetch(new Node\Name('false')) + ], + [ + 31415, + new Scalar\LNumber(31415) + ], + [ + 3.1415, + new Scalar\DNumber(3.1415) + ], + [ + 'Hallo World', + new Scalar\String_('Hallo World') + ], + [ + [1, 2, 3], + new Expr\Array_([ + new Expr\ArrayItem(new Scalar\LNumber(1)), + new Expr\ArrayItem(new Scalar\LNumber(2)), + new Expr\ArrayItem(new Scalar\LNumber(3)), + ]) + ], + [ + ['foo' => 'bar', 'bar' => 'foo'], + new Expr\Array_([ + new Expr\ArrayItem( + new Scalar\String_('bar'), + new Scalar\String_('foo') + ), + new Expr\ArrayItem( + new Scalar\String_('foo'), + new Scalar\String_('bar') + ), + ]) + ], + [ + new Scalar\MagicConst\Dir, + new Scalar\MagicConst\Dir + ] + ]; + } + + /** + * @dataProvider provideTestTypes + */ + public function testTypes($typeHint, $expectedType) { + $node = $this->createParamBuilder('test') + ->setTypeHint($typeHint) + ->getNode() + ; + $type = $node->type; + + /* Manually implement comparison to avoid __toString stupidity */ + if ($expectedType instanceof Node\NullableType) { + $this->assertInstanceOf(get_class($expectedType), $type); + $expectedType = $expectedType->type; + $type = $type->type; + } + + $this->assertInstanceOf(get_class($expectedType), $type); + $this->assertEquals($expectedType, $type); + } + + public function provideTestTypes() { + return [ + ['array', new Node\Identifier('array')], + ['callable', new Node\Identifier('callable')], + ['bool', new Node\Identifier('bool')], + ['int', new Node\Identifier('int')], + ['float', new Node\Identifier('float')], + ['string', new Node\Identifier('string')], + ['iterable', new Node\Identifier('iterable')], + ['object', new Node\Identifier('object')], + ['Array', new Node\Identifier('array')], + ['CALLABLE', new Node\Identifier('callable')], + ['Some\Class', new Node\Name('Some\Class')], + ['\Foo', new Node\Name\FullyQualified('Foo')], + ['self', new Node\Name('self')], + ['?array', new Node\NullableType(new Node\Identifier('array'))], + ['?Some\Class', new Node\NullableType(new Node\Name('Some\Class'))], + [new Node\Name('Some\Class'), new Node\Name('Some\Class')], + [ + new Node\NullableType(new Node\Identifier('int')), + new Node\NullableType(new Node\Identifier('int')) + ], + [ + new Node\NullableType(new Node\Name('Some\Class')), + new Node\NullableType(new Node\Name('Some\Class')) + ], + ]; + } + + public function testVoidTypeError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Parameter type cannot be void'); + $this->createParamBuilder('test')->setType('void'); + } + + public function testInvalidTypeError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Type must be a string, or an instance of Name, Identifier or NullableType'); + $this->createParamBuilder('test')->setType(new \stdClass); + } + + public function testByRef() { + $node = $this->createParamBuilder('test') + ->makeByRef() + ->getNode() + ; + + $this->assertEquals( + new Node\Param(new Expr\Variable('test'), null, null, true), + $node + ); + } + + public function testVariadic() { + $node = $this->createParamBuilder('test') + ->makeVariadic() + ->getNode() + ; + + $this->assertEquals( + new Node\Param(new Expr\Variable('test'), null, null, false, true), + $node + ); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php new file mode 100644 index 00000000..a15cd43c --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php @@ -0,0 +1,147 @@ +createPropertyBuilder('test') + ->makePrivate() + ->makeStatic() + ->getNode() + ; + + $this->assertEquals( + new Stmt\Property( + Stmt\Class_::MODIFIER_PRIVATE + | Stmt\Class_::MODIFIER_STATIC, + [ + new Stmt\PropertyProperty('test') + ] + ), + $node + ); + + $node = $this->createPropertyBuilder('test') + ->makeProtected() + ->getNode() + ; + + $this->assertEquals( + new Stmt\Property( + Stmt\Class_::MODIFIER_PROTECTED, + [ + new Stmt\PropertyProperty('test') + ] + ), + $node + ); + + $node = $this->createPropertyBuilder('test') + ->makePublic() + ->getNode() + ; + + $this->assertEquals( + new Stmt\Property( + Stmt\Class_::MODIFIER_PUBLIC, + [ + new Stmt\PropertyProperty('test') + ] + ), + $node + ); + } + + public function testDocComment() { + $node = $this->createPropertyBuilder('test') + ->setDocComment('/** Test */') + ->getNode(); + + $this->assertEquals(new Stmt\Property( + Stmt\Class_::MODIFIER_PUBLIC, + [ + new Stmt\PropertyProperty('test') + ], + [ + 'comments' => [new Comment\Doc('/** Test */')] + ] + ), $node); + } + + /** + * @dataProvider provideTestDefaultValues + */ + public function testDefaultValues($value, $expectedValueNode) { + $node = $this->createPropertyBuilder('test') + ->setDefault($value) + ->getNode() + ; + + $this->assertEquals($expectedValueNode, $node->props[0]->default); + } + + public function provideTestDefaultValues() { + return [ + [ + null, + new Expr\ConstFetch(new Name('null')) + ], + [ + true, + new Expr\ConstFetch(new Name('true')) + ], + [ + false, + new Expr\ConstFetch(new Name('false')) + ], + [ + 31415, + new Scalar\LNumber(31415) + ], + [ + 3.1415, + new Scalar\DNumber(3.1415) + ], + [ + 'Hallo World', + new Scalar\String_('Hallo World') + ], + [ + [1, 2, 3], + new Expr\Array_([ + new Expr\ArrayItem(new Scalar\LNumber(1)), + new Expr\ArrayItem(new Scalar\LNumber(2)), + new Expr\ArrayItem(new Scalar\LNumber(3)), + ]) + ], + [ + ['foo' => 'bar', 'bar' => 'foo'], + new Expr\Array_([ + new Expr\ArrayItem( + new Scalar\String_('bar'), + new Scalar\String_('foo') + ), + new Expr\ArrayItem( + new Scalar\String_('foo'), + new Scalar\String_('bar') + ), + ]) + ], + [ + new Scalar\MagicConst\Dir, + new Scalar\MagicConst\Dir + ] + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php new file mode 100644 index 00000000..4d99ef88 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php @@ -0,0 +1,46 @@ +createTraitBuilder('TestTrait') + ->setDocComment('/** Nice trait */') + ->addStmt($method1) + ->addStmts([$method2, $method3]) + ->addStmt($prop) + ->addStmt($use) + ->getNode(); + $this->assertEquals(new Stmt\Trait_('TestTrait', [ + 'stmts' => [$use, $prop, $method1, $method2, $method3] + ], [ + 'comments' => [ + new Comment\Doc('/** Nice trait */') + ] + ]), $trait); + } + + public function testInvalidStmtError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Unexpected node of type "Stmt_Echo"'); + $this->createTraitBuilder('Test') + ->addStmt(new Stmt\Echo_([])) + ; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseAdaptationTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseAdaptationTest.php new file mode 100644 index 00000000..4961ccfa --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseAdaptationTest.php @@ -0,0 +1,106 @@ +createTraitUseAdaptationBuilder(null, 'foo'); + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar'), + (clone $builder)->as('bar')->getNode() + ); + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PUBLIC, null), + (clone $builder)->makePublic()->getNode() + ); + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PROTECTED, null), + (clone $builder)->makeProtected()->getNode() + ); + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PRIVATE, null), + (clone $builder)->makePrivate()->getNode() + ); + } + + public function testInsteadof() { + $node = $this->createTraitUseAdaptationBuilder('SomeTrait', 'foo') + ->insteadof('AnotherTrait') + ->getNode() + ; + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Precedence( + new Name('SomeTrait'), + 'foo', + [new Name('AnotherTrait')] + ), + $node + ); + } + + public function testAsOnNotAlias() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot set alias for not alias adaptation buider'); + $this->createTraitUseAdaptationBuilder('Test', 'foo') + ->insteadof('AnotherTrait') + ->as('bar') + ; + } + + public function testInsteadofOnNotPrecedence() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot add overwritten traits for not precedence adaptation buider'); + $this->createTraitUseAdaptationBuilder('Test', 'foo') + ->as('bar') + ->insteadof('AnotherTrait') + ; + } + + public function testInsteadofWithoutTrait() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Precedence adaptation must have trait'); + $this->createTraitUseAdaptationBuilder(null, 'foo') + ->insteadof('AnotherTrait') + ; + } + + public function testMakeOnNotAlias() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot set access modifier for not alias adaptation buider'); + $this->createTraitUseAdaptationBuilder('Test', 'foo') + ->insteadof('AnotherTrait') + ->makePublic() + ; + } + + public function testMultipleMake() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Multiple access type modifiers are not allowed'); + $this->createTraitUseAdaptationBuilder(null, 'foo') + ->makePrivate() + ->makePublic() + ; + } + + public function testUndefinedType() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Type of adaptation is not defined'); + $this->createTraitUseAdaptationBuilder(null, 'foo') + ->getNode() + ; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseTest.php new file mode 100644 index 00000000..8d20dfbd --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseTest.php @@ -0,0 +1,52 @@ +createTraitUseBuilder('SomeTrait') + ->and('AnotherTrait') + ->getNode() + ; + + $this->assertEquals( + new Stmt\TraitUse([ + new Name('SomeTrait'), + new Name('AnotherTrait') + ]), + $node + ); + } + + public function testWith() { + $node = $this->createTraitUseBuilder('SomeTrait') + ->with(new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar')) + ->with((new TraitUseAdaptation(null, 'test'))->as('baz')) + ->getNode() + ; + + $this->assertEquals( + new Stmt\TraitUse([new Name('SomeTrait')], [ + new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar'), + new Stmt\TraitUseAdaptation\Alias(null, 'test', null, 'baz') + ]), + $node + ); + } + + public function testInvalidAdaptationNode() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Adaptation must have type TraitUseAdaptation'); + $this->createTraitUseBuilder('Test') + ->with(new Stmt\Echo_([])) + ; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php b/vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php new file mode 100644 index 00000000..f17da59b --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php @@ -0,0 +1,36 @@ +createUseBuilder('Foo\Bar')->getNode(); + $this->assertEquals(new Stmt\Use_([ + new Stmt\UseUse(new Name('Foo\Bar'), null) + ]), $node); + + $node = $this->createUseBuilder(new Name('Foo\Bar'))->as('XYZ')->getNode(); + $this->assertEquals(new Stmt\Use_([ + new Stmt\UseUse(new Name('Foo\Bar'), 'XYZ') + ]), $node); + + $node = $this->createUseBuilder('foo\bar', Stmt\Use_::TYPE_FUNCTION)->as('foo')->getNode(); + $this->assertEquals(new Stmt\Use_([ + new Stmt\UseUse(new Name('foo\bar'), 'foo') + ], Stmt\Use_::TYPE_FUNCTION), $node); + + $node = $this->createUseBuilder('foo\BAR', Stmt\Use_::TYPE_CONSTANT)->as('FOO')->getNode(); + $this->assertEquals(new Stmt\Use_([ + new Stmt\UseUse(new Name('foo\BAR'), 'FOO') + ], Stmt\Use_::TYPE_CONSTANT), $node); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php b/vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php new file mode 100644 index 00000000..a80e1c58 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php @@ -0,0 +1,327 @@ +assertInstanceOf($className, $factory->$methodName('test')); + } + + public function provideTestFactory() { + return [ + ['namespace', Builder\Namespace_::class], + ['class', Builder\Class_::class], + ['interface', Builder\Interface_::class], + ['trait', Builder\Trait_::class], + ['method', Builder\Method::class], + ['function', Builder\Function_::class], + ['property', Builder\Property::class], + ['param', Builder\Param::class], + ['use', Builder\Use_::class], + ['useFunction', Builder\Use_::class], + ['useConst', Builder\Use_::class], + ]; + } + + public function testVal() { + // This method is a wrapper around BuilderHelpers::normalizeValue(), + // which is already tested elsewhere + $factory = new BuilderFactory(); + $this->assertEquals( + new String_("foo"), + $factory->val("foo") + ); + } + + public function testConcat() { + $factory = new BuilderFactory(); + $varA = new Expr\Variable('a'); + $varB = new Expr\Variable('b'); + $varC = new Expr\Variable('c'); + + $this->assertEquals( + new Concat($varA, $varB), + $factory->concat($varA, $varB) + ); + $this->assertEquals( + new Concat(new Concat($varA, $varB), $varC), + $factory->concat($varA, $varB, $varC) + ); + $this->assertEquals( + new Concat(new Concat(new String_("a"), $varB), new String_("c")), + $factory->concat("a", $varB, "c") + ); + } + + public function testConcatOneError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Expected at least two expressions'); + (new BuilderFactory())->concat("a"); + } + + public function testConcatInvalidExpr() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Expected string or Expr'); + (new BuilderFactory())->concat("a", 42); + } + + public function testArgs() { + $factory = new BuilderFactory(); + $unpack = new Arg(new Expr\Variable('c'), false, true); + $this->assertEquals( + [ + new Arg(new Expr\Variable('a')), + new Arg(new String_('b')), + $unpack + ], + $factory->args([new Expr\Variable('a'), 'b', $unpack]) + ); + } + + public function testCalls() { + $factory = new BuilderFactory(); + + // Simple function call + $this->assertEquals( + new Expr\FuncCall( + new Name('var_dump'), + [new Arg(new String_('str'))] + ), + $factory->funcCall('var_dump', ['str']) + ); + // Dynamic function call + $this->assertEquals( + new Expr\FuncCall(new Expr\Variable('fn')), + $factory->funcCall(new Expr\Variable('fn')) + ); + + // Simple method call + $this->assertEquals( + new Expr\MethodCall( + new Expr\Variable('obj'), + new Identifier('method'), + [new Arg(new LNumber(42))] + ), + $factory->methodCall(new Expr\Variable('obj'), 'method', [42]) + ); + // Explicitly pass Identifier node + $this->assertEquals( + new Expr\MethodCall( + new Expr\Variable('obj'), + new Identifier('method') + ), + $factory->methodCall(new Expr\Variable('obj'), new Identifier('method')) + ); + // Dynamic method call + $this->assertEquals( + new Expr\MethodCall( + new Expr\Variable('obj'), + new Expr\Variable('method') + ), + $factory->methodCall(new Expr\Variable('obj'), new Expr\Variable('method')) + ); + + // Simple static method call + $this->assertEquals( + new Expr\StaticCall( + new Name\FullyQualified('Foo'), + new Identifier('bar'), + [new Arg(new Expr\Variable('baz'))] + ), + $factory->staticCall('\Foo', 'bar', [new Expr\Variable('baz')]) + ); + // Dynamic static method call + $this->assertEquals( + new Expr\StaticCall( + new Expr\Variable('foo'), + new Expr\Variable('bar') + ), + $factory->staticCall(new Expr\Variable('foo'), new Expr\Variable('bar')) + ); + + // Simple new call + $this->assertEquals( + new Expr\New_(new Name\FullyQualified('stdClass')), + $factory->new('\stdClass') + ); + // Dynamic new call + $this->assertEquals( + new Expr\New_( + new Expr\Variable('foo'), + [new Arg(new String_('bar'))] + ), + $factory->new(new Expr\Variable('foo'), ['bar']) + ); + } + + public function testConstFetches() { + $factory = new BuilderFactory(); + $this->assertEquals( + new Expr\ConstFetch(new Name('FOO')), + $factory->constFetch('FOO') + ); + $this->assertEquals( + new Expr\ClassConstFetch(new Name('Foo'), new Identifier('BAR')), + $factory->classConstFetch('Foo', 'BAR') + ); + $this->assertEquals( + new Expr\ClassConstFetch(new Expr\Variable('foo'), new Identifier('BAR')), + $factory->classConstFetch(new Expr\Variable('foo'), 'BAR') + ); + } + + public function testVar() { + $factory = new BuilderFactory(); + $this->assertEquals( + new Expr\Variable("foo"), + $factory->var("foo") + ); + $this->assertEquals( + new Expr\Variable(new Expr\Variable("foo")), + $factory->var($factory->var("foo")) + ); + } + + public function testPropertyFetch() { + $f = new BuilderFactory(); + $this->assertEquals( + new Expr\PropertyFetch(new Expr\Variable('foo'), 'bar'), + $f->propertyFetch($f->var('foo'), 'bar') + ); + $this->assertEquals( + new Expr\PropertyFetch(new Expr\Variable('foo'), 'bar'), + $f->propertyFetch($f->var('foo'), new Identifier('bar')) + ); + $this->assertEquals( + new Expr\PropertyFetch(new Expr\Variable('foo'), new Expr\Variable('bar')), + $f->propertyFetch($f->var('foo'), $f->var('bar')) + ); + } + + public function testInvalidIdentifier() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Expected string or instance of Node\Identifier'); + (new BuilderFactory())->classConstFetch('Foo', new Expr\Variable('foo')); + } + + public function testInvalidIdentifierOrExpr() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Expected string or instance of Node\Identifier or Node\Expr'); + (new BuilderFactory())->staticCall('Foo', new Name('bar')); + } + + public function testInvalidNameOrExpr() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Name must be a string or an instance of Node\Name or Node\Expr'); + (new BuilderFactory())->funcCall(new Node\Stmt\Return_()); + } + + public function testInvalidVar() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Variable name must be string or Expr'); + (new BuilderFactory())->var(new Node\Stmt\Return_()); + } + + public function testIntegration() { + $factory = new BuilderFactory; + $node = $factory->namespace('Name\Space') + ->addStmt($factory->use('Foo\Bar\SomeOtherClass')) + ->addStmt($factory->use('Foo\Bar')->as('A')) + ->addStmt($factory->useFunction('strlen')) + ->addStmt($factory->useConst('PHP_VERSION')) + ->addStmt($factory + ->class('SomeClass') + ->extend('SomeOtherClass') + ->implement('A\Few', '\Interfaces') + ->makeAbstract() + + ->addStmt($factory->useTrait('FirstTrait')) + + ->addStmt($factory->useTrait('SecondTrait', 'ThirdTrait') + ->and('AnotherTrait') + ->with($factory->traitUseAdaptation('foo')->as('bar')) + ->with($factory->traitUseAdaptation('AnotherTrait', 'baz')->as('test')) + ->with($factory->traitUseAdaptation('AnotherTrait', 'func')->insteadof('SecondTrait'))) + + ->addStmt($factory->method('firstMethod')) + + ->addStmt($factory->method('someMethod') + ->makePublic() + ->makeAbstract() + ->addParam($factory->param('someParam')->setType('SomeClass')) + ->setDocComment('/** + * This method does something. + * + * @param SomeClass And takes a parameter + */')) + + ->addStmt($factory->method('anotherMethod') + ->makeProtected() + ->addParam($factory->param('someParam')->setDefault('test')) + ->addStmt(new Expr\Print_(new Expr\Variable('someParam')))) + + ->addStmt($factory->property('someProperty')->makeProtected()) + ->addStmt($factory->property('anotherProperty') + ->makePrivate() + ->setDefault([1, 2, 3]))) + ->getNode() + ; + + $expected = <<<'EOC' +prettyPrintFile($stmts); + + $this->assertEquals( + str_replace("\r\n", "\n", $expected), + str_replace("\r\n", "\n", $generated) + ); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php b/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php new file mode 100644 index 00000000..24e93dd5 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php @@ -0,0 +1,119 @@ +createParsers($modes); + list($stmts5, $output5) = $this->getParseOutput($parser5, $code, $modes); + list($stmts7, $output7) = $this->getParseOutput($parser7, $code, $modes); + + if (isset($modes['php5'])) { + $this->assertSame($expected, $output5, $name); + $this->assertNotSame($expected, $output7, $name); + } elseif (isset($modes['php7'])) { + $this->assertNotSame($expected, $output5, $name); + $this->assertSame($expected, $output7, $name); + } else { + $this->assertSame($expected, $output5, $name); + $this->assertSame($expected, $output7, $name); + } + + $this->checkAttributes($stmts5); + $this->checkAttributes($stmts7); + } + + public function createParsers(array $modes) { + $lexer = new Lexer\Emulative(['usedAttributes' => [ + 'startLine', 'endLine', + 'startFilePos', 'endFilePos', + 'startTokenPos', 'endTokenPos', + 'comments' + ]]); + + return [ + new Parser\Php5($lexer), + new Parser\Php7($lexer), + ]; + } + + // Must be public for updateTests.php + public function getParseOutput(Parser $parser, $code, array $modes) { + $dumpPositions = isset($modes['positions']); + + $errors = new ErrorHandler\Collecting; + $stmts = $parser->parse($code, $errors); + + $output = ''; + foreach ($errors->getErrors() as $error) { + $output .= $this->formatErrorMessage($error, $code) . "\n"; + } + + if (null !== $stmts) { + $dumper = new NodeDumper(['dumpComments' => true, 'dumpPositions' => $dumpPositions]); + $output .= $dumper->dump($stmts, $code); + } + + return [$stmts, canonicalize($output)]; + } + + public function provideTestParse() { + return $this->getTests(__DIR__ . '/../code/parser', 'test'); + } + + private function formatErrorMessage(Error $e, $code) { + if ($e->hasColumnInfo()) { + return $e->getMessageWithColumnInfo($code); + } + + return $e->getMessage(); + } + + private function checkAttributes($stmts) { + if ($stmts === null) { + return; + } + + $traverser = new NodeTraverser(); + $traverser->addVisitor(new class extends NodeVisitorAbstract { + public function enterNode(Node $node) { + $startLine = $node->getStartLine(); + $endLine = $node->getEndLine(); + $startFilePos = $node->getStartFilePos(); + $endFilePos = $node->getEndFilePos(); + $startTokenPos = $node->getStartTokenPos(); + $endTokenPos = $node->getEndTokenPos(); + if ($startLine < 0 || $endLine < 0 || + $startFilePos < 0 || $endFilePos < 0 || + $startTokenPos < 0 || $endTokenPos < 0 + ) { + throw new \Exception('Missing location information on ' . $node->getType()); + } + + if ($endLine < $startLine || + $endFilePos < $startFilePos || + $endTokenPos < $startTokenPos + ) { + // Nops and error can have inverted order, if they are empty + if (!$node instanceof Stmt\Nop && !$node instanceof Expr\Error) { + throw new \Exception('End < start on ' . $node->getType()); + } + } + } + }); + $traverser->traverse($stmts); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php b/vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php new file mode 100644 index 00000000..f5f40875 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php @@ -0,0 +1,26 @@ + $fileContents) { + list($name, $tests) = $parser->parseTest($fileContents, $chunksPerTest); + + // first part is the name + $name .= ' (' . $fileName . ')'; + $shortName = ltrim(str_replace($directory, '', $fileName), '/\\'); + + // multiple sections possible with always two forming a pair + foreach ($tests as $i => list($mode, $parts)) { + $dataSetName = $shortName . (count($parts) > 1 ? '#' . $i : ''); + $allTests[$dataSetName] = array_merge([$name], $parts, [$mode]); + } + } + + return $allTests; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/CodeTestParser.php b/vendor/nikic/php-parser/test/PhpParser/CodeTestParser.php new file mode 100644 index 00000000..f63dc926 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/CodeTestParser.php @@ -0,0 +1,68 @@ + $chunk) { + $lastPart = array_pop($chunk); + list($lastPart, $mode) = $this->extractMode($lastPart); + $tests[] = [$mode, array_merge($chunk, [$lastPart])]; + } + + return [$name, $tests]; + } + + public function reconstructTest($name, array $tests) { + $result = $name; + foreach ($tests as list($mode, $parts)) { + $lastPart = array_pop($parts); + foreach ($parts as $part) { + $result .= "\n-----\n$part"; + } + + $result .= "\n-----\n"; + if (null !== $mode) { + $result .= "!!$mode\n"; + } + $result .= $lastPart; + } + return $result; + } + + private function extractMode($expected) { + $firstNewLine = strpos($expected, "\n"); + if (false === $firstNewLine) { + $firstNewLine = strlen($expected); + } + + $firstLine = substr($expected, 0, $firstNewLine); + if (0 !== strpos($firstLine, '!!')) { + return [$expected, null]; + } + + $expected = (string) substr($expected, $firstNewLine + 1); + return [$expected, substr($firstLine, 2)]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/CommentTest.php b/vendor/nikic/php-parser/test/PhpParser/CommentTest.php new file mode 100644 index 00000000..409841aa --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/CommentTest.php @@ -0,0 +1,74 @@ +assertSame('/* Some comment */', $comment->getText()); + $this->assertSame('/* Some comment */', (string) $comment); + $this->assertSame(1, $comment->getLine()); + $this->assertSame(10, $comment->getFilePos()); + $this->assertSame(2, $comment->getTokenPos()); + } + + /** + * @dataProvider provideTestReformatting + */ + public function testReformatting($commentText, $reformattedText) { + $comment = new Comment($commentText); + $this->assertSame($reformattedText, $comment->getReformattedText()); + } + + public function provideTestReformatting() { + return [ + ['// Some text' . "\n", '// Some text'], + ['/* Some text */', '/* Some text */'], + [ + '/** + * Some text. + * Some more text. + */', + '/** + * Some text. + * Some more text. + */' + ], + [ + '/* + Some text. + Some more text. + */', + '/* + Some text. + Some more text. +*/' + ], + [ + '/* Some text. + More text. + Even more text. */', + '/* Some text. + More text. + Even more text. */' + ], + [ + '/* Some text. + More text. + Indented text. */', + '/* Some text. + More text. + Indented text. */', + ], + // invalid comment -> no reformatting + [ + 'hallo + world', + 'hallo + world', + ], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/ConstExprEvaluatorTest.php b/vendor/nikic/php-parser/test/PhpParser/ConstExprEvaluatorTest.php new file mode 100644 index 00000000..02d992e5 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/ConstExprEvaluatorTest.php @@ -0,0 +1,130 @@ +parse('expr; + $evaluator = new ConstExprEvaluator(); + $this->assertSame($expected, $evaluator->evaluateDirectly($expr)); + } + + public function provideTestEvaluate() { + return [ + ['1', 1], + ['1.0', 1.0], + ['"foo"', "foo"], + ['[0, 1]', [0, 1]], + ['["foo" => "bar"]', ["foo" => "bar"]], + ['NULL', null], + ['False', false], + ['true', true], + ['+1', 1], + ['-1', -1], + ['~0', -1], + ['!true', false], + ['[0][0]', 0], + ['"a"[0]', "a"], + ['true ? 1 : (1/0)', 1], + ['false ? (1/0) : 1', 1], + ['42 ?: (1/0)', 42], + ['false ?: 42', 42], + ['false ?? 42', false], + ['null ?? 42', 42], + ['[0][0] ?? 42', 0], + ['[][0] ?? 42', 42], + ['0b11 & 0b10', 0b10], + ['0b11 | 0b10', 0b11], + ['0b11 ^ 0b10', 0b01], + ['1 << 2', 4], + ['4 >> 2', 1], + ['"a" . "b"', "ab"], + ['4 + 2', 6], + ['4 - 2', 2], + ['4 * 2', 8], + ['4 / 2', 2], + ['4 % 2', 0], + ['4 ** 2', 16], + ['1 == 1.0', true], + ['1 != 1.0', false], + ['1 < 2.0', true], + ['1 <= 2.0', true], + ['1 > 2.0', false], + ['1 >= 2.0', false], + ['1 <=> 2.0', -1], + ['1 === 1.0', false], + ['1 !== 1.0', true], + ['true && true', true], + ['true and true', true], + ['false && (1/0)', false], + ['false and (1/0)', false], + ['false || false', false], + ['false or false', false], + ['true || (1/0)', true], + ['true or (1/0)', true], + ['true xor false', true], + ]; + } + + public function testEvaluateFails() { + $this->expectException(ConstExprEvaluationException::class); + $this->expectExceptionMessage('Expression of type Expr_Variable cannot be evaluated'); + $evaluator = new ConstExprEvaluator(); + $evaluator->evaluateDirectly(new Expr\Variable('a')); + } + + public function testEvaluateFallback() { + $evaluator = new ConstExprEvaluator(function(Expr $expr) { + if ($expr instanceof Scalar\MagicConst\Line) { + return 42; + } + throw new ConstExprEvaluationException(); + }); + $expr = new Expr\BinaryOp\Plus( + new Scalar\LNumber(8), + new Scalar\MagicConst\Line() + ); + $this->assertSame(50, $evaluator->evaluateDirectly($expr)); + } + + /** + * @dataProvider provideTestEvaluateSilently + */ + public function testEvaluateSilently($expr, $exception, $msg) { + $evaluator = new ConstExprEvaluator(); + + try { + $evaluator->evaluateSilently($expr); + } catch (ConstExprEvaluationException $e) { + $this->assertSame( + 'An error occurred during constant expression evaluation', + $e->getMessage() + ); + + $prev = $e->getPrevious(); + $this->assertInstanceOf($exception, $prev); + $this->assertSame($msg, $prev->getMessage()); + } + } + + public function provideTestEvaluateSilently() { + return [ + [ + new Expr\BinaryOp\Mod(new Scalar\LNumber(42), new Scalar\LNumber(0)), + \Error::class, + 'Modulo by zero' + ], + [ + new Expr\BinaryOp\Div(new Scalar\LNumber(42), new Scalar\LNumber(0)), + \ErrorException::class, + 'Division by zero' + ], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php b/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php new file mode 100644 index 00000000..a20101a8 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php @@ -0,0 +1,23 @@ +assertFalse($errorHandler->hasErrors()); + $this->assertEmpty($errorHandler->getErrors()); + + $errorHandler->handleError($e1 = new Error('Test 1')); + $errorHandler->handleError($e2 = new Error('Test 2')); + $this->assertTrue($errorHandler->hasErrors()); + $this->assertSame([$e1, $e2], $errorHandler->getErrors()); + + $errorHandler->clearErrors(); + $this->assertFalse($errorHandler->hasErrors()); + $this->assertEmpty($errorHandler->getErrors()); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php b/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php new file mode 100644 index 00000000..be641ec7 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php @@ -0,0 +1,15 @@ +expectException(Error::class); + $this->expectExceptionMessage('Test'); + $errorHandler = new Throwing(); + $errorHandler->handleError(new Error('Test')); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/ErrorTest.php b/vendor/nikic/php-parser/test/PhpParser/ErrorTest.php new file mode 100644 index 00000000..cc2d3fa5 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/ErrorTest.php @@ -0,0 +1,104 @@ + 10, + 'endLine' => 11, + ]; + $error = new Error('Some error', $attributes); + + $this->assertSame('Some error', $error->getRawMessage()); + $this->assertSame($attributes, $error->getAttributes()); + $this->assertSame(10, $error->getStartLine()); + $this->assertSame(11, $error->getEndLine()); + $this->assertSame('Some error on line 10', $error->getMessage()); + + return $error; + } + + /** + * @depends testConstruct + */ + public function testSetMessageAndLine(Error $error) { + $error->setRawMessage('Some other error'); + $this->assertSame('Some other error', $error->getRawMessage()); + + $error->setStartLine(15); + $this->assertSame(15, $error->getStartLine()); + $this->assertSame('Some other error on line 15', $error->getMessage()); + } + + public function testUnknownLine() { + $error = new Error('Some error'); + + $this->assertSame(-1, $error->getStartLine()); + $this->assertSame(-1, $error->getEndLine()); + $this->assertSame('Some error on unknown line', $error->getMessage()); + } + + /** @dataProvider provideTestColumnInfo */ + public function testColumnInfo($code, $startPos, $endPos, $startColumn, $endColumn) { + $error = new Error('Some error', [ + 'startFilePos' => $startPos, + 'endFilePos' => $endPos, + ]); + + $this->assertTrue($error->hasColumnInfo()); + $this->assertSame($startColumn, $error->getStartColumn($code)); + $this->assertSame($endColumn, $error->getEndColumn($code)); + + } + + public function provideTestColumnInfo() { + return [ + // Error at "bar" + ["assertFalse($error->hasColumnInfo()); + try { + $error->getStartColumn(''); + $this->fail('Expected RuntimeException'); + } catch (\RuntimeException $e) { + $this->assertSame('Error does not have column information', $e->getMessage()); + } + try { + $error->getEndColumn(''); + $this->fail('Expected RuntimeException'); + } catch (\RuntimeException $e) { + $this->assertSame('Error does not have column information', $e->getMessage()); + } + } + + public function testInvalidPosInfo() { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Invalid position information'); + $error = new Error('Some error', [ + 'startFilePos' => 10, + 'endFilePos' => 11, + ]); + $error->getStartColumn('code'); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Internal/DifferTest.php b/vendor/nikic/php-parser/test/PhpParser/Internal/DifferTest.php new file mode 100644 index 00000000..6fac3fd3 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Internal/DifferTest.php @@ -0,0 +1,65 @@ +type) { + case DiffElem::TYPE_KEEP: + $diffStr .= $diffElem->old; + break; + case DiffElem::TYPE_REMOVE: + $diffStr .= '-' . $diffElem->old; + break; + case DiffElem::TYPE_ADD: + $diffStr .= '+' . $diffElem->new; + break; + case DiffElem::TYPE_REPLACE: + $diffStr .= '/' . $diffElem->old . $diffElem->new; + break; + default: + assert(false); + break; + } + } + return $diffStr; + } + + /** @dataProvider provideTestDiff */ + public function testDiff($oldStr, $newStr, $expectedDiffStr) { + $differ = new Differ(function($a, $b) { return $a === $b; }); + $diff = $differ->diff(str_split($oldStr), str_split($newStr)); + $this->assertSame($expectedDiffStr, $this->formatDiffString($diff)); + } + + public function provideTestDiff() { + return [ + ['abc', 'abc', 'abc'], + ['abc', 'abcdef', 'abc+d+e+f'], + ['abcdef', 'abc', 'abc-d-e-f'], + ['abcdef', 'abcxyzdef', 'abc+x+y+zdef'], + ['axyzb', 'ab', 'a-x-y-zb'], + ['abcdef', 'abxyef', 'ab-c-d+x+yef'], + ['abcdef', 'cdefab', '-a-bcdef+a+b'], + ]; + } + + /** @dataProvider provideTestDiffWithReplacements */ + public function testDiffWithReplacements($oldStr, $newStr, $expectedDiffStr) { + $differ = new Differ(function($a, $b) { return $a === $b; }); + $diff = $differ->diffWithReplacements(str_split($oldStr), str_split($newStr)); + $this->assertSame($expectedDiffStr, $this->formatDiffString($diff)); + } + + public function provideTestDiffWithReplacements() { + return [ + ['abcde', 'axyze', 'a/bx/cy/dze'], + ['abcde', 'xbcdy', '/axbcd/ey'], + ['abcde', 'axye', 'a-b-c-d+x+ye'], + ['abcde', 'axyzue', 'a-b-c-d+x+y+z+ue'], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/JsonDecoderTest.php b/vendor/nikic/php-parser/test/PhpParser/JsonDecoderTest.php new file mode 100644 index 00000000..d5cb0597 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/JsonDecoderTest.php @@ -0,0 +1,43 @@ +parse($code); + $json = json_encode($stmts); + + $jsonDecoder = new JsonDecoder(); + $decodedStmts = $jsonDecoder->decode($json); + $this->assertEquals($stmts, $decodedStmts); + } + + /** @dataProvider provideTestDecodingError */ + public function testDecodingError($json, $expectedMessage) { + $jsonDecoder = new JsonDecoder(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage($expectedMessage); + $jsonDecoder->decode($json); + } + + public function provideTestDecodingError() { + return [ + ['???', 'JSON decoding error: Syntax error'], + ['{"nodeType":123}', 'Node type must be a string'], + ['{"nodeType":"Name","attributes":123}', 'Attributes must be an array'], + ['{"nodeType":"Comment"}', 'Comment must have text'], + ['{"nodeType":"xxx"}', 'Unknown node type "xxx"'], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php b/vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php new file mode 100644 index 00000000..cc00caac --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php @@ -0,0 +1,195 @@ +getLexer(); + $lexer->startLexing('assertSame($expectedToken, $lexer->getNextToken()); + $this->assertSame(0, $lexer->getNextToken()); + } + + /** + * @dataProvider provideTestReplaceKeywords + */ + public function testNoReplaceKeywordsAfterObjectOperator($keyword) { + $lexer = $this->getLexer(); + $lexer->startLexing('' . $keyword); + + $this->assertSame(Tokens::T_OBJECT_OPERATOR, $lexer->getNextToken()); + $this->assertSame(Tokens::T_STRING, $lexer->getNextToken()); + $this->assertSame(0, $lexer->getNextToken()); + } + + public function provideTestReplaceKeywords() { + return [ + // PHP 5.5 + ['finally', Tokens::T_FINALLY], + ['yield', Tokens::T_YIELD], + + // PHP 5.4 + ['callable', Tokens::T_CALLABLE], + ['insteadof', Tokens::T_INSTEADOF], + ['trait', Tokens::T_TRAIT], + ['__TRAIT__', Tokens::T_TRAIT_C], + + // PHP 5.3 + ['__DIR__', Tokens::T_DIR], + ['goto', Tokens::T_GOTO], + ['namespace', Tokens::T_NAMESPACE], + ['__NAMESPACE__', Tokens::T_NS_C], + ]; + } + + /** + * @dataProvider provideTestLexNewFeatures + */ + public function testLexNewFeatures($code, array $expectedTokens) { + $lexer = $this->getLexer(); + $lexer->startLexing('getNextToken($text)) { + $tokens[] = [$token, $text]; + } + $this->assertSame($expectedTokens, $tokens); + } + + /** + * @dataProvider provideTestLexNewFeatures + */ + public function testLeaveStuffAloneInStrings($code) { + $stringifiedToken = '"' . addcslashes($code, '"\\') . '"'; + + $lexer = $this->getLexer(); + $lexer->startLexing('assertSame(Tokens::T_CONSTANT_ENCAPSED_STRING, $lexer->getNextToken($text)); + $this->assertSame($stringifiedToken, $text); + $this->assertSame(0, $lexer->getNextToken()); + } + + /** + * @dataProvider provideTestLexNewFeatures + */ + public function testErrorAfterEmulation($code) { + $errorHandler = new ErrorHandler\Collecting; + $lexer = $this->getLexer([]); + $lexer->startLexing('getErrors(); + $this->assertCount(1, $errors); + + $error = $errors[0]; + $this->assertSame('Unexpected null byte', $error->getRawMessage()); + + $attrs = $error->getAttributes(); + $expPos = strlen('assertSame($expPos, $attrs['startFilePos']); + $this->assertSame($expPos, $attrs['endFilePos']); + $this->assertSame($expLine, $attrs['startLine']); + $this->assertSame($expLine, $attrs['endLine']); + } + + public function provideTestLexNewFeatures() { + return [ + // PHP 7.4 + ['??=', [ + [Tokens::T_COALESCE_EQUAL, '??='], + ]], + ['yield from', [ + [Tokens::T_YIELD_FROM, 'yield from'], + ]], + ["yield\r\nfrom", [ + [Tokens::T_YIELD_FROM, "yield\r\nfrom"], + ]], + ['...', [ + [Tokens::T_ELLIPSIS, '...'], + ]], + ['**', [ + [Tokens::T_POW, '**'], + ]], + ['**=', [ + [Tokens::T_POW_EQUAL, '**='], + ]], + ['??', [ + [Tokens::T_COALESCE, '??'], + ]], + ['<=>', [ + [Tokens::T_SPACESHIP, '<=>'], + ]], + ['0b1010110', [ + [Tokens::T_LNUMBER, '0b1010110'], + ]], + ['0b1011010101001010110101010010101011010101010101101011001110111100', [ + [Tokens::T_DNUMBER, '0b1011010101001010110101010010101011010101010101101011001110111100'], + ]], + ['\\', [ + [Tokens::T_NS_SEPARATOR, '\\'], + ]], + ["<<<'NOWDOC'\nNOWDOC;\n", [ + [Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"], + [Tokens::T_END_HEREDOC, 'NOWDOC'], + [ord(';'), ';'], + ]], + ["<<<'NOWDOC'\nFoobar\nNOWDOC;\n", [ + [Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"], + [Tokens::T_ENCAPSED_AND_WHITESPACE, "Foobar\n"], + [Tokens::T_END_HEREDOC, 'NOWDOC'], + [ord(';'), ';'], + ]], + + // Flexible heredoc/nowdoc + ["<<markTestSkipped('HHVM does not throw warnings from token_get_all()'); + } + + $errorHandler = new ErrorHandler\Collecting(); + $lexer = $this->getLexer(['usedAttributes' => [ + 'comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos' + ]]); + $lexer->startLexing($code, $errorHandler); + $errors = $errorHandler->getErrors(); + + $this->assertCount(count($messages), $errors); + for ($i = 0; $i < count($messages); $i++) { + $this->assertSame($messages[$i], $errors[$i]->getMessageWithColumnInfo($code)); + } + } + + public function provideTestError() { + return [ + ["getLexer($options); + $lexer->startLexing($code); + while ($id = $lexer->getNextToken($value, $startAttributes, $endAttributes)) { + $token = array_shift($tokens); + + $this->assertSame($token[0], $id); + $this->assertSame($token[1], $value); + $this->assertEquals($token[2], $startAttributes); + $this->assertEquals($token[3], $endAttributes); + } + } + + public function provideTestLex() { + return [ + // tests conversion of closing PHP tag and drop of whitespace and opening tags + [ + 'plaintext', + [], + [ + [ + Tokens::T_STRING, 'tokens', + ['startLine' => 1], ['endLine' => 1] + ], + [ + ord(';'), '?>', + ['startLine' => 1], ['endLine' => 1] + ], + [ + Tokens::T_INLINE_HTML, 'plaintext', + ['startLine' => 1, 'hasLeadingNewline' => false], + ['endLine' => 1] + ], + ] + ], + // tests line numbers + [ + ' 2], ['endLine' => 2] + ], + [ + Tokens::T_STRING, 'token', + ['startLine' => 2], ['endLine' => 2] + ], + [ + ord('$'), '$', + [ + 'startLine' => 3, + 'comments' => [ + new Comment\Doc('/** doc' . "\n" . 'comment */', 2, 14, 5), + ] + ], + ['endLine' => 3] + ], + ] + ], + // tests comment extraction + [ + ' 2, + 'comments' => [ + new Comment('/* comment */', 1, 6, 1), + new Comment('// comment' . "\n", 1, 20, 3), + new Comment\Doc('/** docComment 1 */', 2, 31, 4), + new Comment\Doc('/** docComment 2 */', 2, 50, 5), + ], + ], + ['endLine' => 2] + ], + ] + ], + // tests differing start and end line + [ + ' 1], ['endLine' => 2] + ], + ] + ], + // tests exact file offsets + [ + ' ['startFilePos', 'endFilePos']], + [ + [ + Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"', + ['startFilePos' => 6], ['endFilePos' => 8] + ], + [ + ord(';'), ';', + ['startFilePos' => 9], ['endFilePos' => 9] + ], + [ + Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"', + ['startFilePos' => 18], ['endFilePos' => 20] + ], + [ + ord(';'), ';', + ['startFilePos' => 21], ['endFilePos' => 21] + ], + ] + ], + // tests token offsets + [ + ' ['startTokenPos', 'endTokenPos']], + [ + [ + Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"', + ['startTokenPos' => 1], ['endTokenPos' => 1] + ], + [ + ord(';'), ';', + ['startTokenPos' => 2], ['endTokenPos' => 2] + ], + [ + Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"', + ['startTokenPos' => 5], ['endTokenPos' => 5] + ], + [ + ord(';'), ';', + ['startTokenPos' => 6], ['endTokenPos' => 6] + ], + ] + ], + // tests all attributes being disabled + [ + ' []], + [ + [ + Tokens::T_VARIABLE, '$bar', + [], [] + ], + [ + ord(';'), ';', + [], [] + ] + ] + ], + // tests no tokens + [ + '', + [], + [] + ], + ]; + } + + /** + * @dataProvider provideTestHaltCompiler + */ + public function testHandleHaltCompiler($code, $remaining) { + $lexer = $this->getLexer(); + $lexer->startLexing($code); + + while (Tokens::T_HALT_COMPILER !== $lexer->getNextToken()); + + $this->assertSame($remaining, $lexer->handleHaltCompiler()); + $this->assertSame(0, $lexer->getNextToken()); + } + + public function provideTestHaltCompiler() { + return [ + ['Remaining Text', 'Remaining Text'], + //array('expectException(Error::class); + $this->expectExceptionMessage('__HALT_COMPILER must be followed by "();"'); + $lexer = $this->getLexer(); + $lexer->startLexing('getNextToken()); + $lexer->handleHaltCompiler(); + } + + public function testGetTokens() { + $code = 'getLexer(); + $lexer->startLexing($code); + $this->assertSame($expectedTokens, $lexer->getTokens()); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/NameContextTest.php b/vendor/nikic/php-parser/test/PhpParser/NameContextTest.php new file mode 100644 index 00000000..ee8458b6 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/NameContextTest.php @@ -0,0 +1,65 @@ +startNamespace(new Name('NS')); + $nameContext->addAlias(new Name('Foo'), 'Foo', Use_::TYPE_NORMAL); + $nameContext->addAlias(new Name('Foo\Bar'), 'Alias', Use_::TYPE_NORMAL); + $nameContext->addAlias(new Name('Foo\fn'), 'fn', Use_::TYPE_FUNCTION); + $nameContext->addAlias(new Name('Foo\CN'), 'CN', Use_::TYPE_CONSTANT); + + $possibleNames = $nameContext->getPossibleNames($name, $type); + $possibleNames = array_map(function (Name $name) { + return $name->toCodeString(); + }, $possibleNames); + + $this->assertSame($expectedPossibleNames, $possibleNames); + + // Here the last name is always the shortest one + $expectedShortName = $expectedPossibleNames[count($expectedPossibleNames) - 1]; + $this->assertSame( + $expectedShortName, + $nameContext->getShortName($name, $type)->toCodeString() + ); + } + + public function provideTestGetPossibleNames() { + return [ + [Use_::TYPE_NORMAL, 'Test', ['\Test']], + [Use_::TYPE_NORMAL, 'Test\Namespaced', ['\Test\Namespaced']], + [Use_::TYPE_NORMAL, 'NS\Test', ['\NS\Test', 'Test']], + [Use_::TYPE_NORMAL, 'ns\Test', ['\ns\Test', 'Test']], + [Use_::TYPE_NORMAL, 'NS\Foo\Bar', ['\NS\Foo\Bar']], + [Use_::TYPE_NORMAL, 'ns\foo\Bar', ['\ns\foo\Bar']], + [Use_::TYPE_NORMAL, 'Foo', ['\Foo', 'Foo']], + [Use_::TYPE_NORMAL, 'Foo\Bar', ['\Foo\Bar', 'Foo\Bar', 'Alias']], + [Use_::TYPE_NORMAL, 'Foo\Bar\Baz', ['\Foo\Bar\Baz', 'Foo\Bar\Baz', 'Alias\Baz']], + [Use_::TYPE_NORMAL, 'Foo\fn\Bar', ['\Foo\fn\Bar', 'Foo\fn\Bar']], + [Use_::TYPE_FUNCTION, 'Foo\fn\bar', ['\Foo\fn\bar', 'Foo\fn\bar']], + [Use_::TYPE_FUNCTION, 'Foo\fn', ['\Foo\fn', 'Foo\fn', 'fn']], + [Use_::TYPE_FUNCTION, 'Foo\FN', ['\Foo\FN', 'Foo\FN', 'fn']], + [Use_::TYPE_CONSTANT, 'Foo\CN\BAR', ['\Foo\CN\BAR', 'Foo\CN\BAR']], + [Use_::TYPE_CONSTANT, 'Foo\CN', ['\Foo\CN', 'Foo\CN', 'CN']], + [Use_::TYPE_CONSTANT, 'foo\CN', ['\foo\CN', 'Foo\CN', 'CN']], + [Use_::TYPE_CONSTANT, 'foo\cn', ['\foo\cn', 'Foo\cn']], + // self/parent/static must not be fully qualified + [Use_::TYPE_NORMAL, 'self', ['self']], + [Use_::TYPE_NORMAL, 'parent', ['parent']], + [Use_::TYPE_NORMAL, 'static', ['static']], + // true/false/null do not need to be fully qualified, even in namespaces + [Use_::TYPE_CONSTANT, 'true', ['\true', 'true']], + [Use_::TYPE_CONSTANT, 'false', ['\false', 'false']], + [Use_::TYPE_CONSTANT, 'null', ['\null', 'null']], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/IdentifierTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/IdentifierTest.php new file mode 100644 index 00000000..2bd58fc8 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/IdentifierTest.php @@ -0,0 +1,29 @@ +assertSame('Foo', (string) $identifier); + $this->assertSame('Foo', $identifier->toString()); + $this->assertSame('foo', $identifier->toLowerString()); + } + + /** @dataProvider provideTestIsSpecialClassName */ + public function testIsSpecialClassName($identifier, $expected) { + $identifier = new Identifier($identifier); + $this->assertSame($expected, $identifier->isSpecialClassName()); + } + + public function provideTestIsSpecialClassName() { + return [ + ['self', true], + ['PARENT', true], + ['Static', true], + ['other', false], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php new file mode 100644 index 00000000..5e69ebba --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php @@ -0,0 +1,157 @@ +assertSame(['foo', 'bar'], $name->parts); + + $name = new Name('foo\bar'); + $this->assertSame(['foo', 'bar'], $name->parts); + + $name = new Name($name); + $this->assertSame(['foo', 'bar'], $name->parts); + } + + public function testGet() { + $name = new Name('foo'); + $this->assertSame('foo', $name->getFirst()); + $this->assertSame('foo', $name->getLast()); + + $name = new Name('foo\bar'); + $this->assertSame('foo', $name->getFirst()); + $this->assertSame('bar', $name->getLast()); + } + + public function testToString() { + $name = new Name('Foo\Bar'); + + $this->assertSame('Foo\Bar', (string) $name); + $this->assertSame('Foo\Bar', $name->toString()); + $this->assertSame('foo\bar', $name->toLowerString()); + } + + public function testSlice() { + $name = new Name('foo\bar\baz'); + $this->assertEquals(new Name('foo\bar\baz'), $name->slice(0)); + $this->assertEquals(new Name('bar\baz'), $name->slice(1)); + $this->assertNull($name->slice(3)); + $this->assertEquals(new Name('foo\bar\baz'), $name->slice(-3)); + $this->assertEquals(new Name('bar\baz'), $name->slice(-2)); + $this->assertEquals(new Name('foo\bar'), $name->slice(0, -1)); + $this->assertNull($name->slice(0, -3)); + $this->assertEquals(new Name('bar'), $name->slice(1, -1)); + $this->assertNull($name->slice(1, -2)); + $this->assertEquals(new Name('bar'), $name->slice(-2, 1)); + $this->assertEquals(new Name('bar'), $name->slice(-2, -1)); + $this->assertNull($name->slice(-2, -2)); + } + + public function testSliceOffsetTooLarge() { + $this->expectException(\OutOfBoundsException::class); + $this->expectExceptionMessage('Offset 4 is out of bounds'); + (new Name('foo\bar\baz'))->slice(4); + } + + public function testSliceOffsetTooSmall() { + $this->expectException(\OutOfBoundsException::class); + $this->expectExceptionMessage('Offset -4 is out of bounds'); + (new Name('foo\bar\baz'))->slice(-4); + } + + public function testSliceLengthTooLarge() { + $this->expectException(\OutOfBoundsException::class); + $this->expectExceptionMessage('Length 4 is out of bounds'); + (new Name('foo\bar\baz'))->slice(0, 4); + } + + public function testSliceLengthTooSmall() { + $this->expectException(\OutOfBoundsException::class); + $this->expectExceptionMessage('Length -4 is out of bounds'); + (new Name('foo\bar\baz'))->slice(0, -4); + } + + public function testConcat() { + $this->assertEquals(new Name('foo\bar\baz'), Name::concat('foo', 'bar\baz')); + $this->assertEquals( + new Name\FullyQualified('foo\bar'), + Name\FullyQualified::concat(['foo'], new Name('bar')) + ); + + $attributes = ['foo' => 'bar']; + $this->assertEquals( + new Name\Relative('foo\bar\baz', $attributes), + Name\Relative::concat(new Name\FullyQualified('foo\bar'), 'baz', $attributes) + ); + + $this->assertEquals(new Name('foo'), Name::concat(null, 'foo')); + $this->assertEquals(new Name('foo'), Name::concat('foo', null)); + $this->assertNull(Name::concat(null, null)); + } + + public function testNameTypes() { + $name = new Name('foo'); + $this->assertTrue($name->isUnqualified()); + $this->assertFalse($name->isQualified()); + $this->assertFalse($name->isFullyQualified()); + $this->assertFalse($name->isRelative()); + $this->assertSame('foo', $name->toCodeString()); + + $name = new Name('foo\bar'); + $this->assertFalse($name->isUnqualified()); + $this->assertTrue($name->isQualified()); + $this->assertFalse($name->isFullyQualified()); + $this->assertFalse($name->isRelative()); + $this->assertSame('foo\bar', $name->toCodeString()); + + $name = new Name\FullyQualified('foo'); + $this->assertFalse($name->isUnqualified()); + $this->assertFalse($name->isQualified()); + $this->assertTrue($name->isFullyQualified()); + $this->assertFalse($name->isRelative()); + $this->assertSame('\foo', $name->toCodeString()); + + $name = new Name\Relative('foo'); + $this->assertFalse($name->isUnqualified()); + $this->assertFalse($name->isQualified()); + $this->assertFalse($name->isFullyQualified()); + $this->assertTrue($name->isRelative()); + $this->assertSame('namespace\foo', $name->toCodeString()); + } + + public function testInvalidArg() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Expected string, array of parts or Name instance'); + Name::concat('foo', new \stdClass); + } + + public function testInvalidEmptyString() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Name cannot be empty'); + new Name(''); + } + + public function testInvalidEmptyArray() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Name cannot be empty'); + new Name([]); + } + + /** @dataProvider provideTestIsSpecialClassName */ + public function testIsSpecialClassName($name, $expected) { + $name = new Name($name); + $this->assertSame($expected, $name->isSpecialClassName()); + } + + public function provideTestIsSpecialClassName() { + return [ + ['self', true], + ['PARENT', true], + ['Static', true], + ['self\not', false], + ['not\self', false], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php new file mode 100644 index 00000000..c8ae433b --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php @@ -0,0 +1,26 @@ +assertSame($name, $magicConst->getName()); + } + + public function provideTestGetName() { + return [ + [new MagicConst\Class_, '__CLASS__'], + [new MagicConst\Dir, '__DIR__'], + [new MagicConst\File, '__FILE__'], + [new MagicConst\Function_, '__FUNCTION__'], + [new MagicConst\Line, '__LINE__'], + [new MagicConst\Method, '__METHOD__'], + [new MagicConst\Namespace_, '__NAMESPACE__'], + [new MagicConst\Trait_, '__TRAIT__'], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/StringTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/StringTest.php new file mode 100644 index 00000000..814a7758 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/StringTest.php @@ -0,0 +1,61 @@ +assertSame( + $expected, + String_::parseEscapeSequences($string, $quote) + ); + } + + /** + * @dataProvider provideTestParse + */ + public function testCreate($expected, $string) { + $this->assertSame( + $expected, + String_::parse($string) + ); + } + + public function provideTestParseEscapeSequences() { + return [ + ['"', '\\"', '"'], + ['\\"', '\\"', '`'], + ['\\"\\`', '\\"\\`', null], + ["\\\$\n\r\t\f\v", '\\\\\$\n\r\t\f\v', null], + ["\x1B", '\e', null], + [chr(255), '\xFF', null], + [chr(255), '\377', null], + [chr(0), '\400', null], + ["\0", '\0', null], + ['\xFF', '\\\\xFF', null], + ]; + } + + public function provideTestParse() { + $tests = [ + ['A', '\'A\''], + ['A', 'b\'A\''], + ['A', '"A"'], + ['A', 'b"A"'], + ['\\', '\'\\\\\''], + ['\'', '\'\\\'\''], + ]; + + foreach ($this->provideTestParseEscapeSequences() as $i => $test) { + // skip second and third tests, they aren't for double quotes + if ($i !== 1 && $i !== 2) { + $tests[] = [$test[0], '"' . $test[1] . '"']; + } + } + + return $tests; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php new file mode 100644 index 00000000..9a1b4697 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php @@ -0,0 +1,34 @@ +assertTrue($node->{'is' . $modifier}()); + } + + public function testNoModifiers() { + $node = new ClassConst([], 0); + + $this->assertTrue($node->isPublic()); + $this->assertFalse($node->isProtected()); + $this->assertFalse($node->isPrivate()); + } + + public function provideModifiers() { + return [ + ['public'], + ['protected'], + ['private'], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php new file mode 100644 index 00000000..51c5f1c2 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php @@ -0,0 +1,123 @@ + constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier)) + ]); + + $this->assertTrue($node->{'is' . $modifier}()); + } + + public function testNoModifiers() { + $node = new ClassMethod('foo', ['type' => 0]); + + $this->assertTrue($node->isPublic()); + $this->assertFalse($node->isProtected()); + $this->assertFalse($node->isPrivate()); + $this->assertFalse($node->isAbstract()); + $this->assertFalse($node->isFinal()); + $this->assertFalse($node->isStatic()); + $this->assertFalse($node->isMagic()); + } + + public function provideModifiers() { + return [ + ['public'], + ['protected'], + ['private'], + ['abstract'], + ['final'], + ['static'], + ]; + } + + /** + * Checks that implicit public modifier detection for method is working + * + * @dataProvider implicitPublicModifiers + * + * @param string $modifier Node type modifier + */ + public function testImplicitPublic(string $modifier) + { + $node = new ClassMethod('foo', [ + 'type' => constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier)) + ]); + + $this->assertTrue($node->isPublic(), 'Node should be implicitly public'); + } + + public function implicitPublicModifiers() { + return [ + ['abstract'], + ['final'], + ['static'], + ]; + } + + /** + * @dataProvider provideMagics + * + * @param string $name Node name + */ + public function testMagic(string $name) { + $node = new ClassMethod($name); + $this->assertTrue($node->isMagic(), 'Method should be magic'); + } + + public function provideMagics() { + return [ + ['__construct'], + ['__DESTRUCT'], + ['__caLL'], + ['__callstatic'], + ['__get'], + ['__set'], + ['__isset'], + ['__unset'], + ['__sleep'], + ['__wakeup'], + ['__tostring'], + ['__set_state'], + ['__clone'], + ['__invoke'], + ['__debuginfo'], + ]; + } + + public function testFunctionLike() { + $param = new Param(new Variable('a')); + $type = new Name('Foo'); + $return = new Return_(new Variable('a')); + $method = new ClassMethod('test', [ + 'byRef' => false, + 'params' => [$param], + 'returnType' => $type, + 'stmts' => [$return], + ]); + + $this->assertFalse($method->returnsByRef()); + $this->assertSame([$param], $method->getParams()); + $this->assertSame($type, $method->getReturnType()); + $this->assertSame([$return], $method->getStmts()); + + $method = new ClassMethod('test', [ + 'byRef' => true, + 'stmts' => null, + ]); + + $this->assertTrue($method->returnsByRef()); + $this->assertNull($method->getStmts()); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php new file mode 100644 index 00000000..9b7c7de1 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php @@ -0,0 +1,59 @@ + Class_::MODIFIER_ABSTRACT]); + $this->assertTrue($class->isAbstract()); + + $class = new Class_('Foo'); + $this->assertFalse($class->isAbstract()); + } + + public function testIsFinal() { + $class = new Class_('Foo', ['type' => Class_::MODIFIER_FINAL]); + $this->assertTrue($class->isFinal()); + + $class = new Class_('Foo'); + $this->assertFalse($class->isFinal()); + } + + public function testGetMethods() { + $methods = [ + new ClassMethod('foo'), + new ClassMethod('bar'), + new ClassMethod('fooBar'), + ]; + $class = new Class_('Foo', [ + 'stmts' => [ + new TraitUse([]), + $methods[0], + new ClassConst([]), + $methods[1], + new Property(0, []), + $methods[2], + ] + ]); + + $this->assertSame($methods, $class->getMethods()); + } + + public function testGetMethod() { + $methodConstruct = new ClassMethod('__CONSTRUCT'); + $methodTest = new ClassMethod('test'); + $class = new Class_('Foo', [ + 'stmts' => [ + new ClassConst([]), + $methodConstruct, + new Property(0, []), + $methodTest, + ] + ]); + + $this->assertSame($methodConstruct, $class->getMethod('__construct')); + $this->assertSame($methodTest, $class->getMethod('test')); + $this->assertNull($class->getMethod('nonExisting')); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php new file mode 100644 index 00000000..da6e8eb6 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php @@ -0,0 +1,26 @@ + [ + new Node\Stmt\ClassConst([new Node\Const_('C1', new Node\Scalar\String_('C1'))]), + $methods[0], + new Node\Stmt\ClassConst([new Node\Const_('C2', new Node\Scalar\String_('C2'))]), + $methods[1], + new Node\Stmt\ClassConst([new Node\Const_('C3', new Node\Scalar\String_('C3'))]), + ] + ]); + + $this->assertSame($methods, $interface->getMethods()); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php new file mode 100644 index 00000000..e5d69fba --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php @@ -0,0 +1,44 @@ +assertTrue($node->{'is' . $modifier}()); + } + + public function testNoModifiers() { + $node = new Property(0, []); + + $this->assertTrue($node->isPublic()); + $this->assertFalse($node->isProtected()); + $this->assertFalse($node->isPrivate()); + $this->assertFalse($node->isStatic()); + } + + public function testStaticImplicitlyPublic() { + $node = new Property(Class_::MODIFIER_STATIC, []); + $this->assertTrue($node->isPublic()); + $this->assertFalse($node->isProtected()); + $this->assertFalse($node->isPrivate()); + $this->assertTrue($node->isStatic()); + } + + public function provideModifiers() { + return [ + ['public'], + ['protected'], + ['private'], + ['static'], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php b/vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php new file mode 100644 index 00000000..071b8f2a --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php @@ -0,0 +1,325 @@ +subNode1 = $subNode1; + $this->subNode2 = $subNode2; + } + + public function getSubNodeNames() : array { + return ['subNode1', 'subNode2']; + } + + // This method is only overwritten because the node is located in an unusual namespace + public function getType() : string { + return 'Dummy'; + } +} + +class NodeAbstractTest extends \PHPUnit\Framework\TestCase +{ + public function provideNodes() { + $attributes = [ + 'startLine' => 10, + 'endLine' => 11, + 'startTokenPos' => 12, + 'endTokenPos' => 13, + 'startFilePos' => 14, + 'endFilePos' => 15, + 'comments' => [ + new Comment('// Comment' . "\n"), + new Comment\Doc('/** doc comment */'), + ], + ]; + + $node = new DummyNode('value1', 'value2', $attributes); + $node->notSubNode = 'value3'; + + return [ + [$attributes, $node], + ]; + } + + /** + * @dataProvider provideNodes + */ + public function testConstruct(array $attributes, Node $node) { + $this->assertSame('Dummy', $node->getType()); + $this->assertSame(['subNode1', 'subNode2'], $node->getSubNodeNames()); + $this->assertSame(10, $node->getLine()); + $this->assertSame(10, $node->getStartLine()); + $this->assertSame(11, $node->getEndLine()); + $this->assertSame(12, $node->getStartTokenPos()); + $this->assertSame(13, $node->getEndTokenPos()); + $this->assertSame(14, $node->getStartFilePos()); + $this->assertSame(15, $node->getEndFilePos()); + $this->assertSame('/** doc comment */', $node->getDocComment()->getText()); + $this->assertSame('value1', $node->subNode1); + $this->assertSame('value2', $node->subNode2); + $this->assertObjectHasAttribute('subNode1', $node); + $this->assertObjectHasAttribute('subNode2', $node); + $this->assertObjectNotHasAttribute('subNode3', $node); + $this->assertSame($attributes, $node->getAttributes()); + $this->assertSame($attributes['comments'], $node->getComments()); + + return $node; + } + + /** + * @dataProvider provideNodes + */ + public function testGetDocComment(array $attributes, Node $node) { + $this->assertSame('/** doc comment */', $node->getDocComment()->getText()); + $comments = $node->getComments(); + + array_pop($comments); // remove doc comment + $node->setAttribute('comments', $comments); + $this->assertNull($node->getDocComment()); + + array_pop($comments); // remove comment + $node->setAttribute('comments', $comments); + $this->assertNull($node->getDocComment()); + } + + public function testSetDocComment() { + $node = new DummyNode(null, null, []); + + // Add doc comment to node without comments + $docComment = new Comment\Doc('/** doc */'); + $node->setDocComment($docComment); + $this->assertSame($docComment, $node->getDocComment()); + + // Replace it + $docComment = new Comment\Doc('/** doc 2 */'); + $node->setDocComment($docComment); + $this->assertSame($docComment, $node->getDocComment()); + + // Add docmment to node with other comments + $c1 = new Comment('/* foo */'); + $c2 = new Comment('/* bar */'); + $docComment = new Comment\Doc('/** baz */'); + $node->setAttribute('comments', [$c1, $c2]); + $node->setDocComment($docComment); + $this->assertSame([$c1, $c2, $docComment], $node->getAttribute('comments')); + } + + /** + * @dataProvider provideNodes + */ + public function testChange(array $attributes, Node $node) { + // direct modification + $node->subNode = 'newValue'; + $this->assertSame('newValue', $node->subNode); + + // indirect modification + $subNode =& $node->subNode; + $subNode = 'newNewValue'; + $this->assertSame('newNewValue', $node->subNode); + + // removal + unset($node->subNode); + $this->assertObjectNotHasAttribute('subNode', $node); + } + + /** + * @dataProvider provideNodes + */ + public function testIteration(array $attributes, Node $node) { + // Iteration is simple object iteration over properties, + // not over subnodes + $i = 0; + foreach ($node as $key => $value) { + if ($i === 0) { + $this->assertSame('subNode1', $key); + $this->assertSame('value1', $value); + } elseif ($i === 1) { + $this->assertSame('subNode2', $key); + $this->assertSame('value2', $value); + } elseif ($i === 2) { + $this->assertSame('notSubNode', $key); + $this->assertSame('value3', $value); + } else { + throw new \Exception; + } + $i++; + } + $this->assertSame(3, $i); + } + + public function testAttributes() { + /** @var $node Node */ + $node = $this->getMockForAbstractClass(NodeAbstract::class); + + $this->assertEmpty($node->getAttributes()); + + $node->setAttribute('key', 'value'); + $this->assertTrue($node->hasAttribute('key')); + $this->assertSame('value', $node->getAttribute('key')); + + $this->assertFalse($node->hasAttribute('doesNotExist')); + $this->assertNull($node->getAttribute('doesNotExist')); + $this->assertSame('default', $node->getAttribute('doesNotExist', 'default')); + + $node->setAttribute('null', null); + $this->assertTrue($node->hasAttribute('null')); + $this->assertNull($node->getAttribute('null')); + $this->assertNull($node->getAttribute('null', 'default')); + + $this->assertSame( + [ + 'key' => 'value', + 'null' => null, + ], + $node->getAttributes() + ); + + $node->setAttributes( + [ + 'a' => 'b', + 'c' => null, + ] + ); + $this->assertSame( + [ + 'a' => 'b', + 'c' => null, + ], + $node->getAttributes() + ); + } + + public function testJsonSerialization() { + $code = <<<'PHP' +parse(canonicalize($code)); + $json = json_encode($stmts, JSON_PRETTY_PRINT); + $this->assertEquals(canonicalize($expected), canonicalize($json)); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php b/vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php new file mode 100644 index 00000000..cfba269e --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php @@ -0,0 +1,105 @@ +assertSame($this->canonicalize($dump), $this->canonicalize($dumper->dump($node))); + } + + public function provideTestDump() { + return [ + [ + [], +'array( +)' + ], + [ + ['Foo', 'Bar', 'Key' => 'FooBar'], +'array( + 0: Foo + 1: Bar + Key: FooBar +)' + ], + [ + new Node\Name(['Hallo', 'World']), +'Name( + parts: array( + 0: Hallo + 1: World + ) +)' + ], + [ + new Node\Expr\Array_([ + new Node\Expr\ArrayItem(new Node\Scalar\String_('Foo')) + ]), +'Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: Foo + ) + byRef: false + ) + ) +)' + ], + ]; + } + + public function testDumpWithPositions() { + $parser = (new ParserFactory)->create( + ParserFactory::ONLY_PHP7, + new Lexer(['usedAttributes' => ['startLine', 'endLine', 'startFilePos', 'endFilePos']]) + ); + $dumper = new NodeDumper(['dumpPositions' => true]); + + $code = "parse($code); + $dump = $dumper->dump($stmts, $code); + + $this->assertSame($this->canonicalize($expected), $this->canonicalize($dump)); + } + + public function testError() { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Can only dump nodes and arrays.'); + $dumper = new NodeDumper; + $dumper->dump(new \stdClass); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/NodeFinderTest.php b/vendor/nikic/php-parser/test/PhpParser/NodeFinderTest.php new file mode 100644 index 00000000..909738a7 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/NodeFinderTest.php @@ -0,0 +1,59 @@ +var, $assign->expr->left, $assign->expr->right]; + return [$stmts, $vars]; + } + + public function testFind() { + $finder = new NodeFinder; + list($stmts, $vars) = $this->getStmtsAndVars(); + $varFilter = function(Node $node) { + return $node instanceof Expr\Variable; + }; + $this->assertSame($vars, $finder->find($stmts, $varFilter)); + $this->assertSame($vars, $finder->find($stmts[0], $varFilter)); + + $noneFilter = function () { return false; }; + $this->assertSame([], $finder->find($stmts, $noneFilter)); + } + + public function testFindInstanceOf() { + $finder = new NodeFinder; + list($stmts, $vars) = $this->getStmtsAndVars(); + $this->assertSame($vars, $finder->findInstanceOf($stmts, Expr\Variable::class)); + $this->assertSame($vars, $finder->findInstanceOf($stmts[0], Expr\Variable::class)); + $this->assertSame([], $finder->findInstanceOf($stmts, Expr\BinaryOp\Mul::class)); + } + + public function testFindFirst() { + $finder = new NodeFinder; + list($stmts, $vars) = $this->getStmtsAndVars(); + $varFilter = function(Node $node) { + return $node instanceof Expr\Variable; + }; + $this->assertSame($vars[0], $finder->findFirst($stmts, $varFilter)); + $this->assertSame($vars[0], $finder->findFirst($stmts[0], $varFilter)); + + $noneFilter = function () { return false; }; + $this->assertNull($finder->findFirst($stmts, $noneFilter)); + } + + public function testFindFirstInstanceOf() { + $finder = new NodeFinder; + list($stmts, $vars) = $this->getStmtsAndVars(); + $this->assertSame($vars[0], $finder->findFirstInstanceOf($stmts, Expr\Variable::class)); + $this->assertSame($vars[0], $finder->findFirstInstanceOf($stmts[0], Expr\Variable::class)); + $this->assertNull($finder->findFirstInstanceOf($stmts, Expr\BinaryOp\Mul::class)); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php b/vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php new file mode 100644 index 00000000..2daa9cea --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php @@ -0,0 +1,344 @@ +getMockBuilder(NodeVisitor::class)->getMock(); + + $visitor->expects($this->at(0))->method('beforeTraverse')->with($stmts); + $visitor->expects($this->at(1))->method('enterNode')->with($echoNode); + $visitor->expects($this->at(2))->method('enterNode')->with($str1Node); + $visitor->expects($this->at(3))->method('leaveNode')->with($str1Node); + $visitor->expects($this->at(4))->method('enterNode')->with($str2Node); + $visitor->expects($this->at(5))->method('leaveNode')->with($str2Node); + $visitor->expects($this->at(6))->method('leaveNode')->with($echoNode); + $visitor->expects($this->at(7))->method('afterTraverse')->with($stmts); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + + $this->assertEquals($stmts, $traverser->traverse($stmts)); + } + + public function testModifying() { + $str1Node = new String_('Foo'); + $str2Node = new String_('Bar'); + $printNode = new Expr\Print_($str1Node); + + // first visitor changes the node, second verifies the change + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + + // replace empty statements with string1 node + $visitor1->expects($this->at(0))->method('beforeTraverse')->with([]) + ->willReturn([$str1Node]); + $visitor2->expects($this->at(0))->method('beforeTraverse')->with([$str1Node]); + + // replace string1 node with print node + $visitor1->expects($this->at(1))->method('enterNode')->with($str1Node) + ->willReturn($printNode); + $visitor2->expects($this->at(1))->method('enterNode')->with($printNode); + + // replace string1 node with string2 node + $visitor1->expects($this->at(2))->method('enterNode')->with($str1Node) + ->willReturn($str2Node); + $visitor2->expects($this->at(2))->method('enterNode')->with($str2Node); + + // replace string2 node with string1 node again + $visitor1->expects($this->at(3))->method('leaveNode')->with($str2Node) + ->willReturn($str1Node); + $visitor2->expects($this->at(3))->method('leaveNode')->with($str1Node); + + // replace print node with string1 node again + $visitor1->expects($this->at(4))->method('leaveNode')->with($printNode) + ->willReturn($str1Node); + $visitor2->expects($this->at(4))->method('leaveNode')->with($str1Node); + + // replace string1 node with empty statements again + $visitor1->expects($this->at(5))->method('afterTraverse')->with([$str1Node]) + ->willReturn([]); + $visitor2->expects($this->at(5))->method('afterTraverse')->with([]); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor1); + $traverser->addVisitor($visitor2); + + // as all operations are reversed we end where we start + $this->assertEquals([], $traverser->traverse([])); + } + + public function testRemove() { + $str1Node = new String_('Foo'); + $str2Node = new String_('Bar'); + + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); + + // remove the string1 node, leave the string2 node + $visitor->expects($this->at(2))->method('leaveNode')->with($str1Node) + ->willReturn(NodeTraverser::REMOVE_NODE); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + + $this->assertEquals([$str2Node], $traverser->traverse([$str1Node, $str2Node])); + } + + public function testMerge() { + $strStart = new String_('Start'); + $strMiddle = new String_('End'); + $strEnd = new String_('Middle'); + $strR1 = new String_('Replacement 1'); + $strR2 = new String_('Replacement 2'); + + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); + + // replace strMiddle with strR1 and strR2 by merge + $visitor->expects($this->at(4))->method('leaveNode')->with($strMiddle) + ->willReturn([$strR1, $strR2]); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + + $this->assertEquals( + [$strStart, $strR1, $strR2, $strEnd], + $traverser->traverse([$strStart, $strMiddle, $strEnd]) + ); + } + + public function testInvalidDeepArray() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Invalid node structure: Contains nested arrays'); + $strNode = new String_('Foo'); + $stmts = [[[$strNode]]]; + + $traverser = new NodeTraverser; + $this->assertEquals($stmts, $traverser->traverse($stmts)); + } + + public function testDontTraverseChildren() { + $strNode = new String_('str'); + $printNode = new Expr\Print_($strNode); + $varNode = new Expr\Variable('foo'); + $mulNode = new Expr\BinaryOp\Mul($varNode, $varNode); + $negNode = new Expr\UnaryMinus($mulNode); + $stmts = [$printNode, $negNode]; + + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + + $visitor1->expects($this->at(1))->method('enterNode')->with($printNode) + ->willReturn(NodeTraverser::DONT_TRAVERSE_CHILDREN); + $visitor2->expects($this->at(1))->method('enterNode')->with($printNode); + + $visitor1->expects($this->at(2))->method('leaveNode')->with($printNode); + $visitor2->expects($this->at(2))->method('leaveNode')->with($printNode); + + $visitor1->expects($this->at(3))->method('enterNode')->with($negNode); + $visitor2->expects($this->at(3))->method('enterNode')->with($negNode); + + $visitor1->expects($this->at(4))->method('enterNode')->with($mulNode); + $visitor2->expects($this->at(4))->method('enterNode')->with($mulNode) + ->willReturn(NodeTraverser::DONT_TRAVERSE_CHILDREN); + + $visitor1->expects($this->at(5))->method('leaveNode')->with($mulNode); + $visitor2->expects($this->at(5))->method('leaveNode')->with($mulNode); + + $visitor1->expects($this->at(6))->method('leaveNode')->with($negNode); + $visitor2->expects($this->at(6))->method('leaveNode')->with($negNode); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor1); + $traverser->addVisitor($visitor2); + + $this->assertEquals($stmts, $traverser->traverse($stmts)); + } + + public function testDontTraverseCurrentAndChildren() { + // print 'str'; -($foo * $foo); + $strNode = new String_('str'); + $printNode = new Expr\Print_($strNode); + $varNode = new Expr\Variable('foo'); + $mulNode = new Expr\BinaryOp\Mul($varNode, $varNode); + $divNode = new Expr\BinaryOp\Div($varNode, $varNode); + $negNode = new Expr\UnaryMinus($mulNode); + $stmts = [$printNode, $negNode]; + + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + + $visitor1->expects($this->at(1))->method('enterNode')->with($printNode) + ->willReturn(NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN); + $visitor1->expects($this->at(2))->method('leaveNode')->with($printNode); + + $visitor1->expects($this->at(3))->method('enterNode')->with($negNode); + $visitor2->expects($this->at(1))->method('enterNode')->with($negNode); + + $visitor1->expects($this->at(4))->method('enterNode')->with($mulNode) + ->willReturn(NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN); + $visitor1->expects($this->at(5))->method('leaveNode')->with($mulNode)->willReturn($divNode); + + $visitor1->expects($this->at(6))->method('leaveNode')->with($negNode); + $visitor2->expects($this->at(2))->method('leaveNode')->with($negNode); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor1); + $traverser->addVisitor($visitor2); + + $resultStmts = $traverser->traverse($stmts); + + $this->assertInstanceOf(Expr\BinaryOp\Div::class, $resultStmts[1]->expr); + } + + public function testStopTraversal() { + $varNode1 = new Expr\Variable('a'); + $varNode2 = new Expr\Variable('b'); + $varNode3 = new Expr\Variable('c'); + $mulNode = new Expr\BinaryOp\Mul($varNode1, $varNode2); + $printNode = new Expr\Print_($varNode3); + $stmts = [$mulNode, $printNode]; + + // From enterNode() with array parent + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor->expects($this->at(1))->method('enterNode')->with($mulNode) + ->willReturn(NodeTraverser::STOP_TRAVERSAL); + $visitor->expects($this->at(2))->method('afterTraverse'); + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + $this->assertEquals($stmts, $traverser->traverse($stmts)); + + // From enterNode with Node parent + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor->expects($this->at(2))->method('enterNode')->with($varNode1) + ->willReturn(NodeTraverser::STOP_TRAVERSAL); + $visitor->expects($this->at(3))->method('afterTraverse'); + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + $this->assertEquals($stmts, $traverser->traverse($stmts)); + + // From leaveNode with Node parent + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor->expects($this->at(3))->method('leaveNode')->with($varNode1) + ->willReturn(NodeTraverser::STOP_TRAVERSAL); + $visitor->expects($this->at(4))->method('afterTraverse'); + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + $this->assertEquals($stmts, $traverser->traverse($stmts)); + + // From leaveNode with array parent + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor->expects($this->at(6))->method('leaveNode')->with($mulNode) + ->willReturn(NodeTraverser::STOP_TRAVERSAL); + $visitor->expects($this->at(7))->method('afterTraverse'); + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + $this->assertEquals($stmts, $traverser->traverse($stmts)); + + // Check that pending array modifications are still carried out + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor->expects($this->at(6))->method('leaveNode')->with($mulNode) + ->willReturn(NodeTraverser::REMOVE_NODE); + $visitor->expects($this->at(7))->method('enterNode')->with($printNode) + ->willReturn(NodeTraverser::STOP_TRAVERSAL); + $visitor->expects($this->at(8))->method('afterTraverse'); + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + $this->assertEquals([$printNode], $traverser->traverse($stmts)); + + } + + public function testRemovingVisitor() { + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor3 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor1); + $traverser->addVisitor($visitor2); + $traverser->addVisitor($visitor3); + + $preExpected = [$visitor1, $visitor2, $visitor3]; + $this->assertAttributeSame($preExpected, 'visitors', $traverser, 'The appropriate visitors have not been added'); + + $traverser->removeVisitor($visitor2); + + $postExpected = [0 => $visitor1, 2 => $visitor3]; + $this->assertAttributeSame($postExpected, 'visitors', $traverser, 'The appropriate visitors are not present after removal'); + } + + public function testNoCloneNodes() { + $stmts = [new Node\Stmt\Echo_([new String_('Foo'), new String_('Bar')])]; + + $traverser = new NodeTraverser; + + $this->assertSame($stmts, $traverser->traverse($stmts)); + } + + /** + * @dataProvider provideTestInvalidReturn + */ + public function testInvalidReturn($visitor, $message) { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage($message); + + $stmts = [new Node\Stmt\Expression(new Node\Scalar\LNumber(42))]; + + $traverser = new NodeTraverser(); + $traverser->addVisitor($visitor); + $traverser->traverse($stmts); + } + + public function provideTestInvalidReturn() { + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor1->expects($this->at(1))->method('enterNode') + ->willReturn('foobar'); + + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2->expects($this->at(2))->method('enterNode') + ->willReturn('foobar'); + + $visitor3 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor3->expects($this->at(3))->method('leaveNode') + ->willReturn('foobar'); + + $visitor4 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor4->expects($this->at(4))->method('leaveNode') + ->willReturn('foobar'); + + $visitor5 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor5->expects($this->at(3))->method('leaveNode') + ->willReturn([new Node\Scalar\DNumber(42.0)]); + + $visitor6 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor6->expects($this->at(4))->method('leaveNode') + ->willReturn(false); + + $visitor7 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor7->expects($this->at(1))->method('enterNode') + ->willReturn(new Node\Scalar\LNumber(42)); + + $visitor8 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor8->expects($this->at(2))->method('enterNode') + ->willReturn(new Node\Stmt\Return_()); + + return [ + [$visitor1, 'enterNode() returned invalid value of type string'], + [$visitor2, 'enterNode() returned invalid value of type string'], + [$visitor3, 'leaveNode() returned invalid value of type string'], + [$visitor4, 'leaveNode() returned invalid value of type string'], + [$visitor5, 'leaveNode() may only return an array if the parent structure is an array'], + [$visitor6, 'bool(false) return from leaveNode() no longer supported. Return NodeTraverser::REMOVE_NODE instead'], + [$visitor7, 'Trying to replace statement (Stmt_Expression) with expression (Scalar_LNumber). Are you missing a Stmt_Expression wrapper?'], + [$visitor8, 'Trying to replace expression (Scalar_LNumber) with statement (Stmt_Return)'], + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FindingVisitorTest.php b/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FindingVisitorTest.php new file mode 100644 index 00000000..27cb6dd4 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FindingVisitorTest.php @@ -0,0 +1,53 @@ +addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat( + new Expr\Variable('b'), new Expr\Variable('c') + )); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertSame([ + $assign->var, + $assign->expr->left, + $assign->expr->right, + ], $visitor->getFoundNodes()); + } + + public function testFindAll() { + $traverser = new NodeTraverser(); + $visitor = new FindingVisitor(function(Node $node) { + return true; // All nodes + }); + $traverser->addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat( + new Expr\Variable('b'), new Expr\Variable('c') + )); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertSame([ + $stmts[0], + $assign, + $assign->var, + $assign->expr, + $assign->expr->left, + $assign->expr->right, + ], $visitor->getFoundNodes()); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FirstFindingVisitorTest.php b/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FirstFindingVisitorTest.php new file mode 100644 index 00000000..9ae8932f --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FirstFindingVisitorTest.php @@ -0,0 +1,38 @@ +addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertSame($assign->var, $visitor->getFoundNode()); + } + + public function testFindNone() { + $traverser = new NodeTraverser(); + $visitor = new FirstFindingVisitor(function(Node $node) { + return $node instanceof Node\Expr\BinaryOp; + }); + $traverser->addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertNull($visitor->getFoundNode()); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php b/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php new file mode 100644 index 00000000..6bfbc550 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php @@ -0,0 +1,505 @@ +addVisitor(new NameResolver); + + $stmts = $parser->parse($code); + $stmts = $traverser->traverse($stmts); + + $this->assertSame( + $this->canonicalize($expectedCode), + $prettyPrinter->prettyPrint($stmts) + ); + } + + /** + * @covers \PhpParser\NodeVisitor\NameResolver + */ + public function testResolveLocations() { + $code = <<<'EOC' +addVisitor(new NameResolver); + + $stmts = $parser->parse($code); + $stmts = $traverser->traverse($stmts); + + $this->assertSame( + $this->canonicalize($expectedCode), + $prettyPrinter->prettyPrint($stmts) + ); + } + + public function testNoResolveSpecialName() { + $stmts = [new Node\Expr\New_(new Name('self'))]; + + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver); + + $this->assertEquals($stmts, $traverser->traverse($stmts)); + } + + public function testAddDeclarationNamespacedName() { + $nsStmts = [ + new Stmt\Class_('A'), + new Stmt\Interface_('B'), + new Stmt\Function_('C'), + new Stmt\Const_([ + new Node\Const_('D', new Node\Scalar\LNumber(42)) + ]), + new Stmt\Trait_('E'), + new Expr\New_(new Stmt\Class_(null)), + ]; + + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver); + + $stmts = $traverser->traverse([new Stmt\Namespace_(new Name('NS'), $nsStmts)]); + $this->assertSame('NS\\A', (string) $stmts[0]->stmts[0]->namespacedName); + $this->assertSame('NS\\B', (string) $stmts[0]->stmts[1]->namespacedName); + $this->assertSame('NS\\C', (string) $stmts[0]->stmts[2]->namespacedName); + $this->assertSame('NS\\D', (string) $stmts[0]->stmts[3]->consts[0]->namespacedName); + $this->assertSame('NS\\E', (string) $stmts[0]->stmts[4]->namespacedName); + $this->assertObjectNotHasAttribute('namespacedName', $stmts[0]->stmts[5]->class); + + $stmts = $traverser->traverse([new Stmt\Namespace_(null, $nsStmts)]); + $this->assertSame('A', (string) $stmts[0]->stmts[0]->namespacedName); + $this->assertSame('B', (string) $stmts[0]->stmts[1]->namespacedName); + $this->assertSame('C', (string) $stmts[0]->stmts[2]->namespacedName); + $this->assertSame('D', (string) $stmts[0]->stmts[3]->consts[0]->namespacedName); + $this->assertSame('E', (string) $stmts[0]->stmts[4]->namespacedName); + $this->assertObjectNotHasAttribute('namespacedName', $stmts[0]->stmts[5]->class); + } + + public function testAddRuntimeResolvedNamespacedName() { + $stmts = [ + new Stmt\Namespace_(new Name('NS'), [ + new Expr\FuncCall(new Name('foo')), + new Expr\ConstFetch(new Name('FOO')), + ]), + new Stmt\Namespace_(null, [ + new Expr\FuncCall(new Name('foo')), + new Expr\ConstFetch(new Name('FOO')), + ]), + ]; + + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver); + $stmts = $traverser->traverse($stmts); + + $this->assertSame('NS\\foo', (string) $stmts[0]->stmts[0]->name->getAttribute('namespacedName')); + $this->assertSame('NS\\FOO', (string) $stmts[0]->stmts[1]->name->getAttribute('namespacedName')); + + $this->assertFalse($stmts[1]->stmts[0]->name->hasAttribute('namespacedName')); + $this->assertFalse($stmts[1]->stmts[1]->name->hasAttribute('namespacedName')); + } + + /** + * @dataProvider provideTestError + */ + public function testError(Node $stmt, $errorMsg) { + $this->expectException(\PhpParser\Error::class); + $this->expectExceptionMessage($errorMsg); + + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver); + $traverser->traverse([$stmt]); + } + + public function provideTestError() { + return [ + [ + new Stmt\Use_([ + new Stmt\UseUse(new Name('A\B'), 'B', 0, ['startLine' => 1]), + new Stmt\UseUse(new Name('C\D'), 'B', 0, ['startLine' => 2]), + ], Stmt\Use_::TYPE_NORMAL), + 'Cannot use C\D as B because the name is already in use on line 2' + ], + [ + new Stmt\Use_([ + new Stmt\UseUse(new Name('a\b'), 'b', 0, ['startLine' => 1]), + new Stmt\UseUse(new Name('c\d'), 'B', 0, ['startLine' => 2]), + ], Stmt\Use_::TYPE_FUNCTION), + 'Cannot use function c\d as B because the name is already in use on line 2' + ], + [ + new Stmt\Use_([ + new Stmt\UseUse(new Name('A\B'), 'B', 0, ['startLine' => 1]), + new Stmt\UseUse(new Name('C\D'), 'B', 0, ['startLine' => 2]), + ], Stmt\Use_::TYPE_CONSTANT), + 'Cannot use const C\D as B because the name is already in use on line 2' + ], + [ + new Expr\New_(new Name\FullyQualified('self', ['startLine' => 3])), + "'\\self' is an invalid class name on line 3" + ], + [ + new Expr\New_(new Name\Relative('self', ['startLine' => 3])), + "'\\self' is an invalid class name on line 3" + ], + [ + new Expr\New_(new Name\FullyQualified('PARENT', ['startLine' => 3])), + "'\\PARENT' is an invalid class name on line 3" + ], + [ + new Expr\New_(new Name\Relative('STATIC', ['startLine' => 3])), + "'\\STATIC' is an invalid class name on line 3" + ], + ]; + } + + public function testClassNameIsCaseInsensitive() + { + $source = <<<'EOC' +parse($source); + + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver); + + $stmts = $traverser->traverse($stmts); + $stmt = $stmts[0]; + + $assign = $stmt->stmts[1]->expr; + $this->assertSame(['Bar', 'Baz'], $assign->expr->class->parts); + } + + public function testSpecialClassNamesAreCaseInsensitive() { + $source = <<<'EOC' +parse($source); + + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver); + + $stmts = $traverser->traverse($stmts); + $classStmt = $stmts[0]; + $methodStmt = $classStmt->stmts[0]->stmts[0]; + + $this->assertSame('SELF', (string) $methodStmt->stmts[0]->expr->class); + $this->assertSame('PARENT', (string) $methodStmt->stmts[1]->expr->class); + $this->assertSame('STATIC', (string) $methodStmt->stmts[2]->expr->class); + } + + public function testAddOriginalNames() { + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver(null, ['preserveOriginalNames' => true])); + + $n1 = new Name('Bar'); + $n2 = new Name('bar'); + $origStmts = [ + new Stmt\Namespace_(new Name('Foo'), [ + new Expr\ClassConstFetch($n1, 'FOO'), + new Expr\FuncCall($n2), + ]) + ]; + + $stmts = $traverser->traverse($origStmts); + + $this->assertSame($n1, $stmts[0]->stmts[0]->class->getAttribute('originalName')); + $this->assertSame($n2, $stmts[0]->stmts[1]->name->getAttribute('originalName')); + } + + public function testAttributeOnlyMode() { + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver(null, ['replaceNodes' => false])); + + $n1 = new Name('Bar'); + $n2 = new Name('bar'); + $origStmts = [ + new Stmt\Namespace_(new Name('Foo'), [ + new Expr\ClassConstFetch($n1, 'FOO'), + new Expr\FuncCall($n2), + ]) + ]; + + $traverser->traverse($origStmts); + + $this->assertEquals( + new Name\FullyQualified('Foo\Bar'), $n1->getAttribute('resolvedName')); + $this->assertFalse($n2->hasAttribute('resolvedName')); + $this->assertEquals( + new Name\FullyQualified('Foo\bar'), $n2->getAttribute('namespacedName')); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php b/vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php new file mode 100644 index 00000000..f89e7bf6 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php @@ -0,0 +1,94 @@ + []]); + return new Multiple([new Php7($lexer), new Php5($lexer)]); + } + + private function getPrefer5() { + $lexer = new Lexer(['usedAttributes' => []]); + return new Multiple([new Php5($lexer), new Php7($lexer)]); + } + + /** @dataProvider provideTestParse */ + public function testParse($code, Multiple $parser, $expected) { + $this->assertEquals($expected, $parser->parse($code)); + } + + public function provideTestParse() { + return [ + [ + // PHP 7 only code + 'getPrefer5(), + [ + new Stmt\Class_('Test', ['stmts' => [ + new Stmt\ClassMethod('function') + ]]), + ] + ], + [ + // PHP 5 only code + 'b;', + $this->getPrefer7(), + [ + new Stmt\Global_([ + new Expr\Variable(new Expr\PropertyFetch(new Expr\Variable('a'), 'b')) + ]) + ] + ], + [ + // Different meaning (PHP 5) + 'getPrefer5(), + [ + new Stmt\Expression(new Expr\Variable( + new Expr\ArrayDimFetch(new Expr\Variable('a'), LNumber::fromString('0')) + )) + ] + ], + [ + // Different meaning (PHP 7) + 'getPrefer7(), + [ + new Stmt\Expression(new Expr\ArrayDimFetch( + new Expr\Variable(new Expr\Variable('a')), LNumber::fromString('0') + )) + ] + ], + ]; + } + + public function testThrownError() { + $this->expectException(Error::class); + $this->expectExceptionMessage('FAIL A'); + + $parserA = $this->getMockBuilder(\PhpParser\Parser::class)->getMock(); + $parserA->expects($this->at(0)) + ->method('parse')->willThrowException(new Error('FAIL A')); + + $parserB = $this->getMockBuilder(\PhpParser\Parser::class)->getMock(); + $parserB->expects($this->at(0)) + ->method('parse')->willThrowException(new Error('FAIL B')); + + $parser = new Multiple([$parserA, $parserB]); + $parser->parse('dummy'); + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php b/vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php new file mode 100644 index 00000000..4386b512 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php @@ -0,0 +1,13 @@ +assertInstanceOf($expected, (new ParserFactory)->create($kind, $lexer)); + } + + public function provideTestCreate() { + $lexer = new Lexer(); + return [ + [ + ParserFactory::PREFER_PHP7, $lexer, + Parser\Multiple::class + ], + [ + ParserFactory::PREFER_PHP5, null, + Parser\Multiple::class + ], + [ + ParserFactory::ONLY_PHP7, null, + Parser\Php7::class + ], + [ + ParserFactory::ONLY_PHP5, $lexer, + Parser\Php5::class + ] + ]; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/ParserTest.php b/vendor/nikic/php-parser/test/PhpParser/ParserTest.php new file mode 100644 index 00000000..0f7f1b79 --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/ParserTest.php @@ -0,0 +1,183 @@ +expectException(Error::class); + $this->expectExceptionMessage('Syntax error, unexpected EOF on line 1'); + $parser = $this->getParser(new Lexer()); + $parser->parse('expectException(Error::class); + $this->expectExceptionMessage('Cannot use foo as self because \'self\' is a special class name on line 1'); + $parser = $this->getParser(new Lexer()); + $parser->parse('expectException(Error::class); + $this->expectExceptionMessage('Unterminated comment on line 1'); + $parser = $this->getParser(new Lexer()); + $parser->parse(' [ + 'comments', 'startLine', 'endLine', + 'startTokenPos', 'endTokenPos', + ] + ]); + + $code = <<<'EOC' +getParser($lexer); + $stmts = $parser->parse($code); + + /** @var Stmt\Function_ $fn */ + $fn = $stmts[0]; + $this->assertInstanceOf(Stmt\Function_::class, $fn); + $this->assertEquals([ + 'comments' => [ + new Comment\Doc('/** Doc comment */', 2, 6, 1), + ], + 'startLine' => 3, + 'endLine' => 7, + 'startTokenPos' => 3, + 'endTokenPos' => 21, + ], $fn->getAttributes()); + + $param = $fn->params[0]; + $this->assertInstanceOf(Node\Param::class, $param); + $this->assertEquals([ + 'startLine' => 3, + 'endLine' => 3, + 'startTokenPos' => 7, + 'endTokenPos' => 7, + ], $param->getAttributes()); + + /** @var Stmt\Echo_ $echo */ + $echo = $fn->stmts[0]; + $this->assertInstanceOf(Stmt\Echo_::class, $echo); + $this->assertEquals([ + 'comments' => [ + new Comment("// Line\n", 4, 49, 12), + new Comment("// Comments\n", 5, 61, 14), + ], + 'startLine' => 6, + 'endLine' => 6, + 'startTokenPos' => 16, + 'endTokenPos' => 19, + ], $echo->getAttributes()); + + /** @var \PhpParser\Node\Expr\Variable $var */ + $var = $echo->exprs[0]; + $this->assertInstanceOf(Expr\Variable::class, $var); + $this->assertEquals([ + 'startLine' => 6, + 'endLine' => 6, + 'startTokenPos' => 18, + 'endTokenPos' => 18, + ], $var->getAttributes()); + } + + public function testInvalidToken() { + $this->expectException(\RangeException::class); + $this->expectExceptionMessage('The lexer returned an invalid token (id=999, value=foobar)'); + $lexer = new InvalidTokenLexer; + $parser = $this->getParser($lexer); + $parser->parse('dummy'); + } + + /** + * @dataProvider provideTestExtraAttributes + */ + public function testExtraAttributes($code, $expectedAttributes) { + $parser = $this->getParser(new Lexer\Emulative); + $stmts = $parser->parse("expr : $stmts[0]; + $attributes = $node->getAttributes(); + foreach ($expectedAttributes as $name => $value) { + $this->assertSame($value, $attributes[$name]); + } + } + + public function provideTestExtraAttributes() { + return [ + ['0', ['kind' => Scalar\LNumber::KIND_DEC]], + ['9', ['kind' => Scalar\LNumber::KIND_DEC]], + ['07', ['kind' => Scalar\LNumber::KIND_OCT]], + ['0xf', ['kind' => Scalar\LNumber::KIND_HEX]], + ['0XF', ['kind' => Scalar\LNumber::KIND_HEX]], + ['0b1', ['kind' => Scalar\LNumber::KIND_BIN]], + ['0B1', ['kind' => Scalar\LNumber::KIND_BIN]], + ['[]', ['kind' => Expr\Array_::KIND_SHORT]], + ['array()', ['kind' => Expr\Array_::KIND_LONG]], + ["'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]], + ["b'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]], + ["B'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]], + ['"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['b"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['B"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['b"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['B"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ["<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["<< String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["<<<\"STR\"\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["b<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["B<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["<<< \t 'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["<<<'\xff'\n\xff\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => "\xff", 'docIndentation' => '']], + ["<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["b<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["B<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["<<< \t \"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => '']], + ["<< String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => ' ']], + ["<< String_::KIND_HEREDOC, 'docLabel' => 'STR', 'docIndentation' => "\t"]], + ["<<<'STR'\n Foo\n STR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR', 'docIndentation' => ' ']], + ["die", ['kind' => Expr\Exit_::KIND_DIE]], + ["die('done')", ['kind' => Expr\Exit_::KIND_DIE]], + ["exit", ['kind' => Expr\Exit_::KIND_EXIT]], + ["exit(1)", ['kind' => Expr\Exit_::KIND_EXIT]], + ["?>Foo", ['hasLeadingNewline' => false]], + ["?>\nFoo", ['hasLeadingNewline' => true]], + ["namespace Foo;", ['kind' => Stmt\Namespace_::KIND_SEMICOLON]], + ["namespace Foo {}", ['kind' => Stmt\Namespace_::KIND_BRACED]], + ["namespace {}", ['kind' => Stmt\Namespace_::KIND_BRACED]], + ["(float) 5.0", ['kind' => Expr\Cast\Double::KIND_FLOAT]], + ["(double) 5.0", ['kind' => Expr\Cast\Double::KIND_DOUBLE]], + ["(real) 5.0", ['kind' => Expr\Cast\Double::KIND_REAL]], + [" ( REAL ) 5.0", ['kind' => Expr\Cast\Double::KIND_REAL]], + ]; + } +} + +class InvalidTokenLexer extends Lexer +{ + public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) : int { + $value = 'foobar'; + return 999; + } +} diff --git a/vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php b/vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php new file mode 100644 index 00000000..e5b8a1ae --- /dev/null +++ b/vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php @@ -0,0 +1,307 @@ +parseModeLine($modeLine); + $prettyPrinter = new Standard($options); + + try { + $output5 = canonicalize($prettyPrinter->$method($parser5->parse($code))); + } catch (Error $e) { + $output5 = null; + if ('php7' !== $version) { + throw $e; + } + } + + try { + $output7 = canonicalize($prettyPrinter->$method($parser7->parse($code))); + } catch (Error $e) { + $output7 = null; + if ('php5' !== $version) { + throw $e; + } + } + + if ('php5' === $version) { + $this->assertSame($expected, $output5, $name); + $this->assertNotSame($expected, $output7, $name); + } elseif ('php7' === $version) { + $this->assertSame($expected, $output7, $name); + $this->assertNotSame($expected, $output5, $name); + } else { + $this->assertSame($expected, $output5, $name); + $this->assertSame($expected, $output7, $name); + } + } + + /** + * @dataProvider provideTestPrettyPrint + * @covers \PhpParser\PrettyPrinter\Standard + */ + public function testPrettyPrint($name, $code, $expected, $mode) { + $this->doTestPrettyPrintMethod('prettyPrint', $name, $code, $expected, $mode); + } + + /** + * @dataProvider provideTestPrettyPrintFile + * @covers \PhpParser\PrettyPrinter\Standard + */ + public function testPrettyPrintFile($name, $code, $expected, $mode) { + $this->doTestPrettyPrintMethod('prettyPrintFile', $name, $code, $expected, $mode); + } + + public function provideTestPrettyPrint() { + return $this->getTests(__DIR__ . '/../code/prettyPrinter', 'test'); + } + + public function provideTestPrettyPrintFile() { + return $this->getTests(__DIR__ . '/../code/prettyPrinter', 'file-test'); + } + + public function testPrettyPrintExpr() { + $prettyPrinter = new Standard; + $expr = new Expr\BinaryOp\Mul( + new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')), + new Expr\Variable('c') + ); + $this->assertEquals('($a + $b) * $c', $prettyPrinter->prettyPrintExpr($expr)); + + $expr = new Expr\Closure([ + 'stmts' => [new Stmt\Return_(new String_("a\nb"))] + ]); + $this->assertEquals("function () {\n return 'a\nb';\n}", $prettyPrinter->prettyPrintExpr($expr)); + } + + public function testCommentBeforeInlineHTML() { + $prettyPrinter = new PrettyPrinter\Standard; + $comment = new Comment\Doc("/**\n * This is a comment\n */"); + $stmts = [new Stmt\InlineHTML('Hello World!', ['comments' => [$comment]])]; + $expected = "\nHello World!"; + $this->assertSame($expected, $prettyPrinter->prettyPrintFile($stmts)); + } + + private function parseModeLine($modeLine) { + $parts = explode(' ', (string) $modeLine, 2); + $version = $parts[0] ?? 'both'; + $options = isset($parts[1]) ? json_decode($parts[1], true) : []; + return [$version, $options]; + } + + public function testArraySyntaxDefault() { + $prettyPrinter = new Standard(['shortArraySyntax' => true]); + $expr = new Expr\Array_([ + new Expr\ArrayItem(new String_('val'), new String_('key')) + ]); + $expected = "['key' => 'val']"; + $this->assertSame($expected, $prettyPrinter->prettyPrintExpr($expr)); + } + + /** + * @dataProvider provideTestKindAttributes + */ + public function testKindAttributes($node, $expected) { + $prttyPrinter = new PrettyPrinter\Standard; + $result = $prttyPrinter->prettyPrintExpr($node); + $this->assertSame($expected, $result); + } + + public function provideTestKindAttributes() { + $nowdoc = ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']; + $heredoc = ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']; + return [ + // Defaults to single quoted + [new String_('foo'), "'foo'"], + // Explicit single/double quoted + [new String_('foo', ['kind' => String_::KIND_SINGLE_QUOTED]), "'foo'"], + [new String_('foo', ['kind' => String_::KIND_DOUBLE_QUOTED]), '"foo"'], + // Fallback from doc string if no label + [new String_('foo', ['kind' => String_::KIND_NOWDOC]), "'foo'"], + [new String_('foo', ['kind' => String_::KIND_HEREDOC]), '"foo"'], + // Fallback if string contains label + [new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'A']), "'A\nB\nC'"], + [new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'B']), "'A\nB\nC'"], + [new String_("A\nB\nC", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'C']), "'A\nB\nC'"], + [new String_("STR;", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), "'STR;'"], + // Doc string if label not contained (or not in ending position) + [new String_("foo", $nowdoc), "<<<'STR'\nfoo\nSTR\n"], + [new String_("foo", $heredoc), "<<prettyPrintExpr($node); + $this->assertSame($expected, $result); + } + + public function provideTestUnnaturalLiterals() { + return [ + [new LNumber(-1), '-1'], + [new LNumber(-PHP_INT_MAX - 1), '(-' . PHP_INT_MAX . '-1)'], + [new LNumber(-1, ['kind' => LNumber::KIND_BIN]), '-0b1'], + [new LNumber(-1, ['kind' => LNumber::KIND_OCT]), '-01'], + [new LNumber(-1, ['kind' => LNumber::KIND_HEX]), '-0x1'], + [new DNumber(\INF), '\INF'], + [new DNumber(-\INF), '-\INF'], + [new DNumber(-\NAN), '\NAN'], + ]; + } + + public function testPrettyPrintWithError() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot pretty-print AST with Error nodes'); + $stmts = [new Stmt\Expression( + new Expr\PropertyFetch(new Expr\Variable('a'), new Expr\Error()) + )]; + $prettyPrinter = new PrettyPrinter\Standard; + $prettyPrinter->prettyPrint($stmts); + } + + public function testPrettyPrintWithErrorInClassConstFetch() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot pretty-print AST with Error nodes'); + $stmts = [new Stmt\Expression( + new Expr\ClassConstFetch(new Name('Foo'), new Expr\Error()) + )]; + $prettyPrinter = new PrettyPrinter\Standard; + $prettyPrinter->prettyPrint($stmts); + } + + public function testPrettyPrintEncapsedStringPart() { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage('Cannot directly print EncapsedStringPart'); + $expr = new Node\Scalar\EncapsedStringPart('foo'); + $prettyPrinter = new PrettyPrinter\Standard; + $prettyPrinter->prettyPrintExpr($expr); + } + + /** + * @dataProvider provideTestFormatPreservingPrint + * @covers \PhpParser\PrettyPrinter\Standard + */ + public function testFormatPreservingPrint($name, $code, $modification, $expected, $modeLine) { + $lexer = new Lexer\Emulative([ + 'usedAttributes' => [ + 'comments', + 'startLine', 'endLine', + 'startTokenPos', 'endTokenPos', + ], + ]); + + $parser = new Parser\Php7($lexer); + $traverser = new NodeTraverser(); + $traverser->addVisitor(new NodeVisitor\CloningVisitor()); + + $printer = new PrettyPrinter\Standard(); + + $oldStmts = $parser->parse($code); + $oldTokens = $lexer->getTokens(); + + $newStmts = $traverser->traverse($oldStmts); + + /** @var callable $fn */ + eval(<<printFormatPreserving($newStmts, $oldStmts, $oldTokens); + $this->assertSame(canonicalize($expected), canonicalize($newCode), $name); + } + + public function provideTestFormatPreservingPrint() { + return $this->getTests(__DIR__ . '/../code/formatPreservation', 'test', 3); + } + + /** + * @dataProvider provideTestRoundTripPrint + * @covers \PhpParser\PrettyPrinter\Standard + */ + public function testRoundTripPrint($name, $code, $expected, $modeLine) { + /** + * This test makes sure that the format-preserving pretty printer round-trips for all + * the pretty printer tests (i.e. returns the input if no changes occurred). + */ + + list($version) = $this->parseModeLine($modeLine); + + $lexer = new Lexer\Emulative([ + 'usedAttributes' => [ + 'comments', + 'startLine', 'endLine', + 'startTokenPos', 'endTokenPos', + ], + ]); + + $parserClass = $version === 'php5' ? Parser\Php5::class : Parser\Php7::class; + /** @var Parser $parser */ + $parser = new $parserClass($lexer); + + $traverser = new NodeTraverser(); + $traverser->addVisitor(new NodeVisitor\CloningVisitor()); + + $printer = new PrettyPrinter\Standard(); + + try { + $oldStmts = $parser->parse($code); + } catch (Error $e) { + // Can't do a format-preserving print on a file with errors + return; + } + + $oldTokens = $lexer->getTokens(); + + $newStmts = $traverser->traverse($oldStmts); + + $newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); + $this->assertSame(canonicalize($code), canonicalize($newCode), $name); + } + + public function provideTestRoundTripPrint() { + return array_merge( + $this->getTests(__DIR__ . '/../code/prettyPrinter', 'test'), + $this->getTests(__DIR__ . '/../code/parser', 'test') + ); + } +} diff --git a/vendor/nikic/php-parser/test/bootstrap.php b/vendor/nikic/php-parser/test/bootstrap.php new file mode 100644 index 00000000..0bfa9d0a --- /dev/null +++ b/vendor/nikic/php-parser/test/bootstrap.php @@ -0,0 +1,31 @@ +getPathname(); + yield $fileName => file_get_contents($fileName); + } +} diff --git a/vendor/nikic/php-parser/test/code/formatPreservation/addingPropertyType.test b/vendor/nikic/php-parser/test/code/formatPreservation/addingPropertyType.test new file mode 100644 index 00000000..2ef332b2 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/formatPreservation/addingPropertyType.test @@ -0,0 +1,39 @@ +Adding property type +----- +stmts[0]->type = new Node\Identifier('string'); +----- +stmts[0]->type = new Node\Identifier('int'); +----- +expr; +$new->class->extends = null; +$new->args[] = new Expr\Variable('y'); +----- +expr; +$new->class->name = new Node\Identifier('Anon1'); +----- +exprs[0]->left->right->value = 42; +----- +name = new Node\Identifier('bar'); +----- +byRef = true; +----- +byRef = true; +----- +stmts[0]; +$stmts[0]->stmts[0] = $stmts[1]; +$stmts[1] = $tmp; +----- +stmts[0]; +$stmts[1]->stmts[0] = $stmts[2]; +$stmts[2] = $tmp; +// Same test, but also removing first statement, triggering fallback +array_splice($stmts, 0, 1, []); +----- +exprs[0] = new Expr\ConstFetch(new Node\Name('C')); +----- +exprs[0]->parts[0] = new Expr\Variable('bar'); +$stmts[1]->exprs[0]->parts[0] = new Expr\Variable('bar'); +----- +stmts[] = new Stmt\Expression(new Expr\Variable('c')); +----- +stmts[] = new Stmt\Expression(new Expr\Variable('c')); +----- +setAttribute('comments', []); +----- +getComments(); +$comments[] = new Comment("// foo"); +$stmts[1]->setAttribute('comments', $comments); +----- +stmts[0]; +$method->setAttribute('comments', [new Comment\Doc("/**\n *\n */")]); +----- +expr->left = new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')); +// The parens here are "correct", because add is left assoc +$stmts[1]->expr->right = new Expr\BinaryOp\Plus(new Expr\Variable('b'), new Expr\Variable('c')); +// No parens necessary +$stmts[2]->expr->left = new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')); +// Parens for RHS not strictly necessary due to assign speciality +$stmts[3]->expr->cond = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[3]->expr->if = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[3]->expr->else = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); +// Already has parens +$stmts[4]->expr->left = new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[5]->expr->left = new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')); +----- + bar; +$foo -> bar; +$foo -> bar; +$foo -> bar; +$foo -> bar; +self :: $foo; +self :: $foo; +----- +$stmts[0]->expr->name = new Expr\Variable('a'); +$stmts[1]->expr->name = new Expr\BinaryOp\Concat(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[2]->expr->var = new Expr\Variable('bar'); +$stmts[3]->expr->var = new Expr\BinaryOp\Concat(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[4]->expr->name = new Node\Identifier('foo'); +// In this case the braces are not strictly necessary. However, on PHP 5 they may be required +// depending on where the property fetch node itself occurs. +$stmts[5]->expr->name = new Expr\Variable('bar'); +$stmts[6]->expr->name = new Expr\BinaryOp\Concat(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[7]->expr->name = new Node\VarLikeIdentifier('bar'); +$stmts[8]->expr->name = new Expr\BinaryOp\Concat(new Expr\Variable('a'), new Expr\Variable('b')); +----- + bar; +($a . $b) -> bar; +$foo -> foo; +$foo -> {$bar}; +$foo -> {$a . $b}; +self :: $bar; +self :: ${$a . $b}; \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/formatPreservation/inlineHtml.test b/vendor/nikic/php-parser/test/code/formatPreservation/inlineHtml.test new file mode 100644 index 00000000..7494e535 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/formatPreservation/inlineHtml.test @@ -0,0 +1,54 @@ +Handling of inline HTML +----- +FoosetAttribute('origNode', null); +----- +FooBarstmts[2] = $stmts[0]->stmts[1]; +----- +BarBarstmts[1] = $stmts[0]->stmts[2]; +----- +returnType = new Node\Name('Foo'); +$stmts[0]->params[0]->type = new Node\Identifier('int'); +$stmts[0]->params[1]->type = new Node\Identifier('array'); +$stmts[0]->params[1]->default = new Expr\ConstFetch(new Node\Name('null')); +$stmts[1]->expr->dim = new Expr\Variable('a'); +$stmts[2]->expr->items[0]->key = new Scalar\String_('X'); +$stmts[3]->expr->returnType = new Node\Name('Bar'); +$stmts[4]->expr->if = new Expr\Variable('z'); +$stmts[5]->expr->key = new Expr\Variable('k'); +$stmts[6]->expr->value = new Expr\Variable('v'); +$stmts[7]->num = new Scalar\LNumber(2); +$stmts[8]->num = new Scalar\LNumber(2); +$stmts[9]->expr = new Expr\Variable('x'); +$stmts[10]->extends = new Node\Name\FullyQualified('Bar'); +$stmts[10]->stmts[0]->returnType = new Node\Name('Y'); +$stmts[10]->stmts[1]->props[0]->default = new Scalar\DNumber(42.0); +$stmts[11]->keyVar = new Expr\Variable('z'); +$stmts[12]->vars[0]->default = new Scalar\String_('abc'); +$stmts[13]->finally = new Stmt\Finally_([]); +$stmts[14]->else = new Stmt\Else_([]); +----- + $value +]; + +function +() : Bar +{}; + +$x +? $z +: +$y; + +yield +$k => $v ; +yield $v ; + +break 2 +; +continue 2 +; +return $x +; + +class +X extends \Bar +{ + public + function y() : Y + {} + + private + $x = 42.0 + ; +} + +foreach ( + $x + as + $z => $y +) {} + +static +$var = 'abc' +; + +try { +} catch (X +$y) { +} finally { +} + +if ($cond) { // Foo +} elseif ($cond2) { // Bar +} else { +} +----- +name = new Node\Name('Foo'); +----- +stmts[] = new Stmt\Expression(new Expr\Variable('baz')); +----- +params[] = new Node\Param(new Expr\Variable('param2')); +----- +catches[0]->types[] = new Node\Name('Bar'); +----- +params, new Node\Param(new Expr\Variable('param0'))); +----- +params[] = new Node\Param(new Expr\Variable('param0')); +/* Insertion into empty list not handled yet */ +----- +elseifs[] = new Stmt\ElseIf_(new Expr\Variable('cond3'), []); +----- +catches[] = new Stmt\Catch_([new Node\Name('Bar')], new Expr\Variable('bar'), []); +----- +setAttribute('comments', [new Comment('// Test')]); +$stmts[] = $node; +----- +setAttribute('comments', [new Comment('// Test'), new Comment('// Test 2')]); +$stmts[0]->stmts[] = $node; +----- +name->parts[0] = 'Xyz'; +----- +stmts, $node); +----- +setAttribute('comments', [new Comment('// Test')]); +array_unshift($stmts[0]->stmts, $node); +----- +setAttribute('comments', [new Comment('// Test')]); +array_unshift($stmts[0]->stmts, $node); +----- +setAttribute('comments', [new Comment('// Test')]); +array_unshift($stmts[0]->stmts, $node); +$stmts[0]->stmts[1]->setAttribute('comments', [new Comment('// Bar foo')]); +----- +setAttribute('comments', [new Comment('// Test')]); +array_unshift($stmts[0]->stmts, $node); +$stmts[0]->stmts[1]->setAttribute('comments', []); +----- +stmts, + new Stmt\Expression(new Expr\Variable('a')), + new Stmt\Expression(new Expr\Variable('b'))); +----- +stmts = [ + new Stmt\Expression(new Expr\Variable('a')), + new Stmt\Expression(new Expr\Variable('b')), +]; +----- +expr->expr->items, new Expr\ArrayItem(new Scalar\LNumber(42))); +$stmts[0]->expr->expr->items[] = new Expr\ArrayItem(new Scalar\LNumber(24)); +----- +expr->expr->items[] = new Expr\ArrayItem(new Scalar\LNumber(24)); +----- +foo = new Foo; +$this->foo->a() + ->b(); +----- +$outerCall = $stmts[1]->expr; +$innerCall = $outerCall->var; +$var = $innerCall->var; +$stmts[1]->expr = $innerCall; +$stmts[2] = new Stmt\Expression(new Expr\MethodCall($var, $outerCall->name)); +----- +foo = new Foo; +$this->foo->a(); +$this->foo->b(); \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/formatPreservation/listRemoval.test b/vendor/nikic/php-parser/test/code/formatPreservation/listRemoval.test new file mode 100644 index 00000000..0ac42390 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/formatPreservation/listRemoval.test @@ -0,0 +1,41 @@ +Removing from list nodes +----- +params); +----- +params); +$stmts[0]->params[] = new Node\Param(new Expr\Variable('x')); +$stmts[0]->params[] = new Node\Param(new Expr\Variable('y')); +----- +flags = Stmt\Class_::MODIFIER_ABSTRACT; +$stmts[1]->flags = 0; +$stmts[1]->stmts[0]->flags = Stmt\Class_::MODIFIER_PRIVATE; +$stmts[1]->stmts[1]->flags = Stmt\Class_::MODIFIER_PROTECTED; +$stmts[1]->stmts[2]->flags |= Stmt\Class_::MODIFIER_FINAL; +----- + [new Comment('//Some comment here')]]); +----- + $b +, $c => $d]; + +yield +$foo +=> +$bar; +yield +$bar; + +break +2 +; +continue +2 +; + +foreach( + $array +as + $key + => + $value +) {} + +if +($x) +{ +} + +else {} + +return +$val +; +static + $x + = + $y +; + +try {} catch + (X $y) + {} +finally +{} +----- +$stmts[0]->returnType = null; +$stmts[0]->params[0]->default = null; +$stmts[0]->params[1]->type = null; +$stmts[1]->expr->returnType = null; +$stmts[2]->extends = null; +$stmts[2]->stmts[0]->returnType = null; +$stmts[2]->stmts[1]->props[0]->default = null; +$stmts[2]->stmts[2]->adaptations[0]->newName = null; +$stmts[3]->expr->dim = null; +$stmts[4]->expr->expr = null; +$stmts[5]->expr->if = null; +$stmts[6]->expr->items[1]->key = null; +$stmts[7]->expr->key = null; +$stmts[8]->expr->value = null; +$stmts[9]->num = null; +$stmts[10]->num = null; +$stmts[11]->keyVar = null; +$stmts[12]->else = null; +$stmts[13]->expr = null; +$stmts[14]->vars[0]->default = null; +$stmts[15]->finally = null; +----- + $b +, $d]; + +yield +$bar; +yield; + +break; +continue; + +foreach( + $array +as + $value +) {} + +if +($x) +{ +} + +return; +static + $x +; + +try {} catch + (X $y) + {} +----- +name = null; +----- +stmts[0]->type = null; +----- + +----- +array( + 0: Stmt_Nop( + comments: array( + 0: /** doc */ + 1: /* foobar */ + 2: // foo + 3: // bar + ) + ) +) +----- + +; +----- +!!positions +Syntax error, unexpected ';', expecting T_STRING or T_VARIABLE or '{' or '$' from 3:1 to 3:1 +array( + 0: Stmt_Expression[2:1 - 3:1]( + expr: Expr_PropertyFetch[2:1 - 2:6]( + var: Expr_Variable[2:1 - 2:4]( + name: foo + ) + name: Expr_Error[3:1 - 2:6]( + ) + ) + ) +) +----- + +} +----- +!!positions +Syntax error, unexpected '}', expecting T_STRING or T_VARIABLE or '{' or '$' from 4:1 to 4:1 +array( + 0: Stmt_Function[2:1 - 4:1]( + byRef: false + name: Identifier[2:10 - 2:12]( + name: foo + ) + params: array( + ) + returnType: null + stmts: array( + 0: Stmt_Expression[3:5 - 3:10]( + expr: Expr_PropertyFetch[3:5 - 3:10]( + var: Expr_Variable[3:5 - 3:8]( + name: bar + ) + name: Expr_Error[4:1 - 3:10]( + ) + ) + ) + ) + ) +) +----- +value $oopsAnotherValue->get() +]; +$array = [ + $value $oopsAnotherValue +]; +$array = [ + 'key' => $value $oopsAnotherValue +]; +----- +!!php7 +Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 3:18 to 3:34 +Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 6:12 to 6:28 +Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 9:21 to 9:37 +array( + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: array + ) + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_PropertyFetch( + var: Expr_Variable( + name: this + ) + name: Identifier( + name: value + ) + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_MethodCall( + var: Expr_Variable( + name: oopsAnotherValue + ) + name: Identifier( + name: get + ) + args: array( + ) + ) + byRef: false + ) + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: array + ) + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: value + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: oopsAnotherValue + ) + byRef: false + ) + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: array + ) + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: key + ) + value: Expr_Variable( + name: value + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: oopsAnotherValue + ) + byRef: false + ) + ) + ) + ) + ) +) +----- + 'd', 'e' => &$f); + +// short array syntax +[]; +[1, 2, 3]; +['a' => 'b']; +----- +array( + 0: Stmt_Expression( + expr: Expr_Array( + items: array( + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: a + ) + byRef: false + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: a + ) + byRef: false + ) + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: a + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Scalar_String( + value: b + ) + byRef: false + ) + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: a + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: true + ) + 2: Expr_ArrayItem( + key: Scalar_String( + value: c + ) + value: Scalar_String( + value: d + ) + byRef: false + ) + 3: Expr_ArrayItem( + key: Scalar_String( + value: e + ) + value: Expr_Variable( + name: f + ) + byRef: true + ) + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_Array( + items: array( + ) + comments: array( + 0: // short array syntax + ) + ) + comments: array( + 0: // short array syntax + ) + ) + 6: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 2 + ) + byRef: false + ) + 2: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 3 + ) + byRef: false + ) + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Scalar_String( + value: b + ) + byRef: false + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/arrayDestructuring.test b/vendor/nikic/php-parser/test/code/parser/expr/arrayDestructuring.test new file mode 100644 index 00000000..7865e6ff --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/arrayDestructuring.test @@ -0,0 +1,152 @@ +Array destructuring +----- + $b, 'b' => $a] = $baz; +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false + ) + ) + ) + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: c + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: d + ) + byRef: false + ) + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: null + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false + ) + 2: null + 3: null + 4: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false + ) + 5: null + ) + ) + expr: Expr_Variable( + name: foo + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: null + 1: Expr_ArrayItem( + key: null + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false + ) + ) + ) + byRef: false + ) + ) + ) + byRef: false + ) + 2: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false + ) + ) + ) + expr: Expr_Variable( + name: bar + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Expr_Variable( + name: b + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: Scalar_String( + value: b + ) + value: Expr_Variable( + name: a + ) + byRef: false + ) + ) + ) + expr: Expr_Variable( + name: baz + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/assign.test b/vendor/nikic/php-parser/test/code/parser/expr/assign.test new file mode 100644 index 00000000..8d2ff695 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/assign.test @@ -0,0 +1,374 @@ +Assignments +----- +>= $b; +$a **= $b; +$a ??= $b; + +// chained assign +$a = $b *= $c **= $d; + +// by ref assign +$a =& $b; + +// list() assign +list($a) = $b; +list($a, , $b) = $c; +list($a, list(, $c), $d) = $e; + +// inc/dec +++$a; +$a++; +--$a; +$a--; +----- +array( + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: a + comments: array( + 0: // simple assign + ) + ) + expr: Expr_Variable( + name: b + ) + comments: array( + 0: // simple assign + ) + ) + comments: array( + 0: // simple assign + ) + ) + 1: Stmt_Expression( + expr: Expr_AssignOp_BitwiseAnd( + var: Expr_Variable( + name: a + comments: array( + 0: // combined assign + ) + ) + expr: Expr_Variable( + name: b + ) + comments: array( + 0: // combined assign + ) + ) + comments: array( + 0: // combined assign + ) + ) + 2: Stmt_Expression( + expr: Expr_AssignOp_BitwiseOr( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_AssignOp_BitwiseXor( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_AssignOp_Concat( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_AssignOp_Div( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 6: Stmt_Expression( + expr: Expr_AssignOp_Minus( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_AssignOp_Mod( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 8: Stmt_Expression( + expr: Expr_AssignOp_Mul( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 9: Stmt_Expression( + expr: Expr_AssignOp_Plus( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 10: Stmt_Expression( + expr: Expr_AssignOp_ShiftLeft( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 11: Stmt_Expression( + expr: Expr_AssignOp_ShiftRight( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 12: Stmt_Expression( + expr: Expr_AssignOp_Pow( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 13: Stmt_Expression( + expr: Expr_AssignOp_Coalesce( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + ) + 14: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: a + comments: array( + 0: // chained assign + ) + ) + expr: Expr_AssignOp_Mul( + var: Expr_Variable( + name: b + ) + expr: Expr_AssignOp_Pow( + var: Expr_Variable( + name: c + ) + expr: Expr_Variable( + name: d + ) + ) + ) + comments: array( + 0: // chained assign + ) + ) + comments: array( + 0: // chained assign + ) + ) + 15: Stmt_Expression( + expr: Expr_AssignRef( + var: Expr_Variable( + name: a + comments: array( + 0: // by ref assign + ) + ) + expr: Expr_Variable( + name: b + ) + comments: array( + 0: // by ref assign + ) + ) + comments: array( + 0: // by ref assign + ) + ) + 16: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false + ) + ) + comments: array( + 0: // list() assign + ) + ) + expr: Expr_Variable( + name: b + ) + comments: array( + 0: // list() assign + ) + ) + comments: array( + 0: // list() assign + ) + ) + 17: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false + ) + 1: null + 2: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false + ) + ) + ) + expr: Expr_Variable( + name: c + ) + ) + ) + 18: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_List( + items: array( + 0: null + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: c + ) + byRef: false + ) + ) + ) + byRef: false + ) + 2: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: d + ) + byRef: false + ) + ) + ) + expr: Expr_Variable( + name: e + ) + ) + ) + 19: Stmt_Expression( + expr: Expr_PreInc( + var: Expr_Variable( + name: a + ) + comments: array( + 0: // inc/dec + ) + ) + comments: array( + 0: // inc/dec + ) + ) + 20: Stmt_Expression( + expr: Expr_PostInc( + var: Expr_Variable( + name: a + ) + ) + ) + 21: Stmt_Expression( + expr: Expr_PreDec( + var: Expr_Variable( + name: a + ) + ) + ) + 22: Stmt_Expression( + expr: Expr_PostDec( + var: Expr_Variable( + name: a + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/assignNewByRef.test b/vendor/nikic/php-parser/test/code/parser/expr/assignNewByRef.test new file mode 100644 index 00000000..a66d943a --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/assignNewByRef.test @@ -0,0 +1,43 @@ +Assigning new by reference (PHP 5 only) +----- + $b; +$a >= $b; +$a == $b; +$a === $b; +$a != $b; +$a !== $b; +$a <=> $b; +$a instanceof B; +$a instanceof $b; +----- +array( + 0: Stmt_Expression( + expr: Expr_BinaryOp_Smaller( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_BinaryOp_SmallerOrEqual( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_BinaryOp_Greater( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_BinaryOp_GreaterOrEqual( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_BinaryOp_Equal( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_BinaryOp_Identical( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 6: Stmt_Expression( + expr: Expr_BinaryOp_NotEqual( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_BinaryOp_NotIdentical( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 8: Stmt_Expression( + expr: Expr_BinaryOp_Spaceship( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 9: Stmt_Expression( + expr: Expr_Instanceof( + expr: Expr_Variable( + name: a + ) + class: Name( + parts: array( + 0: B + ) + ) + ) + ) + 10: Stmt_Expression( + expr: Expr_Instanceof( + expr: Expr_Variable( + name: a + ) + class: Expr_Variable( + name: b + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/constant_expr.test b/vendor/nikic/php-parser/test/code/parser/expr/constant_expr.test new file mode 100644 index 00000000..d774de71 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/constant_expr.test @@ -0,0 +1,691 @@ +Expressions in static scalar context +----- + 0; +const T_20 = 1 >= 0; +const T_21 = 1 === 1; +const T_22 = 1 !== 1; +const T_23 = 0 != "0"; +const T_24 = 1 == "1"; +const T_25 = 1 + 2 * 3; +const T_26 = "1" + 2 + "3"; +const T_27 = 2 ** 3; +const T_28 = [1, 2, 3][1]; +const T_29 = 12 - 13; +const T_30 = 12 ^ 13; +const T_31 = 12 & 13; +const T_32 = 12 | 13; +const T_33 = 12 % 3; +const T_34 = 100 >> 4; +const T_35 = !false; +----- +array( + 0: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_1 + ) + value: Expr_BinaryOp_ShiftLeft( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 1 + ) + ) + ) + ) + ) + 1: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_2 + ) + value: Expr_BinaryOp_Div( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 2 + ) + ) + ) + ) + ) + 2: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_3 + ) + value: Expr_BinaryOp_Plus( + left: Scalar_DNumber( + value: 1.5 + ) + right: Scalar_DNumber( + value: 1.5 + ) + ) + ) + ) + ) + 3: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_4 + ) + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: foo + ) + right: Scalar_String( + value: bar + ) + ) + ) + ) + ) + 4: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_5 + ) + value: Expr_BinaryOp_Mul( + left: Expr_BinaryOp_Plus( + left: Scalar_DNumber( + value: 1.5 + ) + right: Scalar_DNumber( + value: 1.5 + ) + ) + right: Scalar_LNumber( + value: 2 + ) + ) + ) + ) + ) + 5: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_6 + ) + value: Expr_BinaryOp_Concat( + left: Expr_BinaryOp_Concat( + left: Expr_BinaryOp_Concat( + left: Scalar_String( + value: foo + ) + right: Scalar_LNumber( + value: 2 + ) + ) + right: Scalar_LNumber( + value: 3 + ) + ) + right: Scalar_DNumber( + value: 4 + ) + ) + ) + ) + ) + 6: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_7 + ) + value: Scalar_MagicConst_Line( + ) + ) + ) + ) + 7: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_8 + ) + value: Scalar_String( + value: This is a test string + ) + ) + ) + ) + 8: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_9 + ) + value: Expr_BitwiseNot( + expr: Expr_UnaryMinus( + expr: Scalar_LNumber( + value: 1 + ) + ) + ) + ) + ) + ) + 9: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_10 + ) + value: Expr_BinaryOp_Plus( + left: Expr_Ternary( + cond: Expr_UnaryMinus( + expr: Scalar_LNumber( + value: 1 + ) + ) + if: null + else: Scalar_LNumber( + value: 1 + ) + ) + right: Expr_Ternary( + cond: Scalar_LNumber( + value: 0 + ) + if: Scalar_LNumber( + value: 2 + ) + else: Scalar_LNumber( + value: 3 + ) + ) + ) + ) + ) + ) + 10: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_11 + ) + value: Expr_BinaryOp_BooleanAnd( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 11: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_12 + ) + value: Expr_BinaryOp_LogicalAnd( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 1 + ) + ) + ) + ) + ) + 12: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_13 + ) + value: Expr_BinaryOp_BooleanOr( + left: Scalar_LNumber( + value: 0 + ) + right: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 13: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_14 + ) + value: Expr_BinaryOp_LogicalOr( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 14: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_15 + ) + value: Expr_BinaryOp_LogicalXor( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 1 + ) + ) + ) + ) + ) + 15: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_16 + ) + value: Expr_BinaryOp_LogicalXor( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 16: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_17 + ) + value: Expr_BinaryOp_Smaller( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 17: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_18 + ) + value: Expr_BinaryOp_SmallerOrEqual( + left: Scalar_LNumber( + value: 0 + ) + right: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 18: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_19 + ) + value: Expr_BinaryOp_Greater( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 19: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_20 + ) + value: Expr_BinaryOp_GreaterOrEqual( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 20: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_21 + ) + value: Expr_BinaryOp_Identical( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 1 + ) + ) + ) + ) + ) + 21: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_22 + ) + value: Expr_BinaryOp_NotIdentical( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_LNumber( + value: 1 + ) + ) + ) + ) + ) + 22: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_23 + ) + value: Expr_BinaryOp_NotEqual( + left: Scalar_LNumber( + value: 0 + ) + right: Scalar_String( + value: 0 + ) + ) + ) + ) + ) + 23: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_24 + ) + value: Expr_BinaryOp_Equal( + left: Scalar_LNumber( + value: 1 + ) + right: Scalar_String( + value: 1 + ) + ) + ) + ) + ) + 24: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_25 + ) + value: Expr_BinaryOp_Plus( + left: Scalar_LNumber( + value: 1 + ) + right: Expr_BinaryOp_Mul( + left: Scalar_LNumber( + value: 2 + ) + right: Scalar_LNumber( + value: 3 + ) + ) + ) + ) + ) + ) + 25: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_26 + ) + value: Expr_BinaryOp_Plus( + left: Expr_BinaryOp_Plus( + left: Scalar_String( + value: 1 + ) + right: Scalar_LNumber( + value: 2 + ) + ) + right: Scalar_String( + value: 3 + ) + ) + ) + ) + ) + 26: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_27 + ) + value: Expr_BinaryOp_Pow( + left: Scalar_LNumber( + value: 2 + ) + right: Scalar_LNumber( + value: 3 + ) + ) + ) + ) + ) + 27: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_28 + ) + value: Expr_ArrayDimFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 2 + ) + byRef: false + ) + 2: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 3 + ) + byRef: false + ) + ) + ) + dim: Scalar_LNumber( + value: 1 + ) + ) + ) + ) + ) + 28: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_29 + ) + value: Expr_BinaryOp_Minus( + left: Scalar_LNumber( + value: 12 + ) + right: Scalar_LNumber( + value: 13 + ) + ) + ) + ) + ) + 29: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_30 + ) + value: Expr_BinaryOp_BitwiseXor( + left: Scalar_LNumber( + value: 12 + ) + right: Scalar_LNumber( + value: 13 + ) + ) + ) + ) + ) + 30: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_31 + ) + value: Expr_BinaryOp_BitwiseAnd( + left: Scalar_LNumber( + value: 12 + ) + right: Scalar_LNumber( + value: 13 + ) + ) + ) + ) + ) + 31: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_32 + ) + value: Expr_BinaryOp_BitwiseOr( + left: Scalar_LNumber( + value: 12 + ) + right: Scalar_LNumber( + value: 13 + ) + ) + ) + ) + ) + 32: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_33 + ) + value: Expr_BinaryOp_Mod( + left: Scalar_LNumber( + value: 12 + ) + right: Scalar_LNumber( + value: 3 + ) + ) + ) + ) + ) + 33: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_34 + ) + value: Expr_BinaryOp_ShiftRight( + left: Scalar_LNumber( + value: 100 + ) + right: Scalar_LNumber( + value: 4 + ) + ) + ) + ) + ) + 34: Stmt_Const( + consts: array( + 0: Const( + name: Identifier( + name: T_35 + ) + value: Expr_BooleanNot( + expr: Expr_ConstFetch( + name: Name( + parts: array( + 0: false + ) + ) + ) + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/errorSuppress.test b/vendor/nikic/php-parser/test/code/parser/expr/errorSuppress.test new file mode 100644 index 00000000..7f099988 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/errorSuppress.test @@ -0,0 +1,14 @@ +Error suppression +----- +b['c'](); + +// array dereferencing +a()['b']; +----- +array( + 0: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: a + ) + comments: array( + 0: // function name variations + ) + ) + args: array( + ) + comments: array( + 0: // function name variations + ) + ) + comments: array( + 0: // function name variations + ) + ) + 1: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_Variable( + name: a + ) + args: array( + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_Variable( + name: Scalar_String( + value: a + ) + ) + args: array( + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_Variable( + name: Expr_Variable( + name: a + ) + ) + args: array( + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_Variable( + name: Expr_Variable( + name: Expr_Variable( + name: a + ) + ) + ) + args: array( + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: Scalar_String( + value: b + ) + ) + args: array( + ) + ) + ) + 6: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: Scalar_String( + value: b + ) + ) + args: array( + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c + ) + ) + args: array( + ) + ) + ) + 8: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_FuncCall( + name: Name( + parts: array( + 0: a + ) + comments: array( + 0: // array dereferencing + ) + ) + args: array( + ) + comments: array( + 0: // array dereferencing + ) + ) + dim: Scalar_String( + value: b + ) + comments: array( + 0: // array dereferencing + ) + ) + comments: array( + 0: // array dereferencing + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/newDeref.test b/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/newDeref.test new file mode 100644 index 00000000..a4b7a724 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/newDeref.test @@ -0,0 +1,82 @@ +New expression dereferencing +----- +b; +(new A)->b(); +(new A)['b']; +(new A)['b']['c']; +----- +array( + 0: Stmt_Expression( + expr: Expr_PropertyFetch( + var: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( + ) + ) + name: Identifier( + name: b + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( + ) + ) + name: Identifier( + name: b + ) + args: array( + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( + ) + ) + dim: Scalar_String( + value: b + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_ArrayDimFetch( + var: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( + ) + ) + dim: Scalar_String( + value: b + ) + ) + dim: Scalar_String( + value: c + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/objectAccess.test b/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/objectAccess.test new file mode 100644 index 00000000..2d1808b0 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/objectAccess.test @@ -0,0 +1,184 @@ +Object access +----- +b; +$a->b['c']; +$a->b{'c'}; + +// method call variations +$a->b(); +$a->{'b'}(); +$a->$b(); +$a->$b['c'](); + +// array dereferencing +$a->b()['c']; +$a->b(){'c'}; // invalid PHP: drop Support? +----- +!!php5 +array( + 0: Stmt_Expression( + expr: Expr_PropertyFetch( + var: Expr_Variable( + name: a + comments: array( + 0: // property fetch variations + ) + ) + name: Identifier( + name: b + ) + comments: array( + 0: // property fetch variations + ) + ) + comments: array( + 0: // property fetch variations + ) + ) + 1: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: a + comments: array( + 0: // method call variations + ) + ) + name: Identifier( + name: b + ) + args: array( + ) + comments: array( + 0: // method call variations + ) + ) + comments: array( + 0: // method call variations + ) + ) + 4: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: a + ) + name: Scalar_String( + value: b + ) + args: array( + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: a + ) + name: Expr_Variable( + name: b + ) + args: array( + ) + ) + ) + 6: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: a + ) + name: Expr_ArrayDimFetch( + var: Expr_Variable( + name: b + ) + dim: Scalar_String( + value: c + ) + ) + args: array( + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_MethodCall( + var: Expr_Variable( + name: a + comments: array( + 0: // array dereferencing + ) + ) + name: Identifier( + name: b + ) + args: array( + ) + comments: array( + 0: // array dereferencing + ) + ) + dim: Scalar_String( + value: c + ) + comments: array( + 0: // array dereferencing + ) + ) + comments: array( + 0: // array dereferencing + ) + ) + 8: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_MethodCall( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + args: array( + ) + ) + dim: Scalar_String( + value: c + ) + ) + ) + 9: Stmt_Nop( + comments: array( + 0: // invalid PHP: drop Support? + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/simpleArrayAccess.test b/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/simpleArrayAccess.test new file mode 100644 index 00000000..133771b7 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/simpleArrayAccess.test @@ -0,0 +1,72 @@ +Simple array access +----- + &$v) = $x; +[&$v] = $x; +['k' => &$v] = $x; +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: v + ) + byRef: true + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: k + ) + value: Expr_Variable( + name: v + ) + byRef: true + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: v + ) + byRef: true + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: k + ) + value: Expr_Variable( + name: v + ) + byRef: true + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/listWithKeys.test b/vendor/nikic/php-parser/test/code/parser/expr/listWithKeys.test new file mode 100644 index 00000000..d0cfbb5f --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/listWithKeys.test @@ -0,0 +1,79 @@ +List destructing with keys +----- + $b) = ['a' => 'b']; +list('a' => list($b => $c), 'd' => $e) = $x; +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Expr_Variable( + name: b + ) + byRef: false + ) + ) + ) + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Scalar_String( + value: b + ) + byRef: false + ) + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: Expr_Variable( + name: b + ) + value: Expr_Variable( + name: c + ) + byRef: false + ) + ) + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: Scalar_String( + value: d + ) + value: Expr_Variable( + name: e + ) + byRef: false + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/logic.test b/vendor/nikic/php-parser/test/code/parser/expr/logic.test new file mode 100644 index 00000000..6b434565 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/logic.test @@ -0,0 +1,190 @@ +Logical operators +----- +> $b; +$a ** $b; + +// associativity +$a * $b * $c; +$a * ($b * $c); + +// precedence +$a + $b * $c; +($a + $b) * $c; + +// pow is special +$a ** $b ** $c; +($a ** $b) ** $c; +----- +array( + 0: Stmt_Expression( + expr: Expr_BitwiseNot( + expr: Expr_Variable( + name: a + ) + comments: array( + 0: // unary ops + ) + ) + comments: array( + 0: // unary ops + ) + ) + 1: Stmt_Expression( + expr: Expr_UnaryPlus( + expr: Expr_Variable( + name: a + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_UnaryMinus( + expr: Expr_Variable( + name: a + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_BinaryOp_BitwiseAnd( + left: Expr_Variable( + name: a + comments: array( + 0: // binary ops + ) + ) + right: Expr_Variable( + name: b + ) + comments: array( + 0: // binary ops + ) + ) + comments: array( + 0: // binary ops + ) + ) + 4: Stmt_Expression( + expr: Expr_BinaryOp_BitwiseOr( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_BinaryOp_BitwiseXor( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 6: Stmt_Expression( + expr: Expr_BinaryOp_Concat( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_BinaryOp_Div( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 8: Stmt_Expression( + expr: Expr_BinaryOp_Minus( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 9: Stmt_Expression( + expr: Expr_BinaryOp_Mod( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 10: Stmt_Expression( + expr: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 11: Stmt_Expression( + expr: Expr_BinaryOp_Plus( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 12: Stmt_Expression( + expr: Expr_BinaryOp_ShiftLeft( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 13: Stmt_Expression( + expr: Expr_BinaryOp_ShiftRight( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 14: Stmt_Expression( + expr: Expr_BinaryOp_Pow( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 15: Stmt_Expression( + expr: Expr_BinaryOp_Mul( + left: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: a + comments: array( + 0: // associativity + ) + ) + right: Expr_Variable( + name: b + ) + comments: array( + 0: // associativity + ) + ) + right: Expr_Variable( + name: c + ) + comments: array( + 0: // associativity + ) + ) + comments: array( + 0: // associativity + ) + ) + 16: Stmt_Expression( + expr: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: a + ) + right: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) + ) + ) + ) + 17: Stmt_Expression( + expr: Expr_BinaryOp_Plus( + left: Expr_Variable( + name: a + comments: array( + 0: // precedence + ) + ) + right: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) + ) + comments: array( + 0: // precedence + ) + ) + comments: array( + 0: // precedence + ) + ) + 18: Stmt_Expression( + expr: Expr_BinaryOp_Mul( + left: Expr_BinaryOp_Plus( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + right: Expr_Variable( + name: c + ) + ) + ) + 19: Stmt_Expression( + expr: Expr_BinaryOp_Pow( + left: Expr_Variable( + name: a + comments: array( + 0: // pow is special + ) + ) + right: Expr_BinaryOp_Pow( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) + ) + comments: array( + 0: // pow is special + ) + ) + comments: array( + 0: // pow is special + ) + ) + 20: Stmt_Expression( + expr: Expr_BinaryOp_Pow( + left: Expr_BinaryOp_Pow( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) + ) + right: Expr_Variable( + name: c + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/new.test b/vendor/nikic/php-parser/test/code/parser/expr/new.test new file mode 100644 index 00000000..2735bfe9 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/new.test @@ -0,0 +1,187 @@ +New +----- +b(); +new $a->b->c(); +new $a->b['c'](); +new $a->b{'c'}(); + +// test regression introduces by new dereferencing syntax +(new A); +----- +array( + 0: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_New( + class: Expr_Variable( + name: a + ) + args: array( + ) + comments: array( + 0: // class name variations + ) + ) + comments: array( + 0: // class name variations + ) + ) + 3: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: Scalar_String( + value: b + ) + ) + args: array( + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_New( + class: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: VarLikeIdentifier( + name: b + ) + ) + args: array( + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_New( + class: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + args: array( + ) + comments: array( + 0: // DNCR object access + ) + ) + comments: array( + 0: // DNCR object access + ) + ) + 6: Stmt_Expression( + expr: Expr_New( + class: Expr_PropertyFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + name: Identifier( + name: c + ) + ) + args: array( + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c + ) + ) + args: array( + ) + ) + ) + 8: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c + ) + ) + args: array( + ) + ) + ) + 9: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( + ) + ) + comments: array( + 0: // test regression introduces by new dereferencing syntax + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/newWithoutClass.test b/vendor/nikic/php-parser/test/code/parser/expr/newWithoutClass.test new file mode 100644 index 00000000..318f9301 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/newWithoutClass.test @@ -0,0 +1,25 @@ +New without a class +----- +bar($a, $b, ); +Foo::bar($a, $b, ); +new Foo($a, $b, ); +unset($a, $b, ); +isset($a, $b, ); +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: foo + ) + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: foo + ) + name: Identifier( + name: bar + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: Foo + ) + ) + name: Identifier( + name: bar + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: Foo + ) + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 4: Stmt_Unset( + vars: array( + 0: Expr_Variable( + name: a + ) + 1: Expr_Variable( + name: b + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_Variable( + name: a + ) + 1: Expr_Variable( + name: b + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/uvs/globalNonSimpleVarError.test b/vendor/nikic/php-parser/test/code/parser/expr/uvs/globalNonSimpleVarError.test new file mode 100644 index 00000000..5ae4f958 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/uvs/globalNonSimpleVarError.test @@ -0,0 +1,27 @@ +Non-simple variables are forbidden in PHP 7 +----- +bar; +----- +!!php7 +Syntax error, unexpected T_OBJECT_OPERATOR, expecting ';' from 2:13 to 2:14 +array( + 0: Stmt_Global( + vars: array( + 0: Expr_Variable( + name: Expr_Variable( + name: foo + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_ConstFetch( + name: Name( + parts: array( + 0: bar + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/uvs/indirectCall.test b/vendor/nikic/php-parser/test/code/parser/expr/uvs/indirectCall.test new file mode 100644 index 00000000..2f36cc7a --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/uvs/indirectCall.test @@ -0,0 +1,507 @@ +UVS indirect calls +----- + 'b']->a); +isset("str"->a); +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_ArrayDimFetch( + var: Expr_BinaryOp_Plus( + left: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 0 + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false + ) + ) + ) + right: Expr_Array( + items: array( + ) + ) + ) + dim: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_PropertyFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Scalar_String( + value: b + ) + byRef: false + ) + ) + ) + name: Identifier( + name: a + ) + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_PropertyFetch( + var: Scalar_String( + value: str + ) + name: Identifier( + name: a + ) + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/uvs/misc.test b/vendor/nikic/php-parser/test/code/parser/expr/uvs/misc.test new file mode 100644 index 00000000..73b515f0 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/uvs/misc.test @@ -0,0 +1,127 @@ +Uniform variable syntax in PHP 7 (misc) +----- +length(); +(clone $obj)->b[0](1); +[0, 1][0] = 1; +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: Identifier( + name: A + ) + ) + dim: Scalar_LNumber( + value: 0 + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_ArrayDimFetch( + var: Expr_ArrayDimFetch( + var: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: Identifier( + name: A + ) + ) + dim: Scalar_LNumber( + value: 0 + ) + ) + dim: Scalar_LNumber( + value: 1 + ) + ) + dim: Scalar_LNumber( + value: 2 + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_MethodCall( + var: Scalar_String( + value: string + ) + name: Identifier( + name: length + ) + args: array( + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Clone( + expr: Expr_Variable( + name: obj + ) + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_LNumber( + value: 0 + ) + ) + args: array( + 0: Arg( + value: Scalar_LNumber( + value: 1 + ) + byRef: false + unpack: false + ) + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_Assign( + var: Expr_ArrayDimFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 0 + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false + ) + ) + ) + dim: Scalar_LNumber( + value: 0 + ) + ) + expr: Scalar_LNumber( + value: 1 + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/uvs/new.test b/vendor/nikic/php-parser/test/code/parser/expr/uvs/new.test new file mode 100644 index 00000000..5e1caf2f --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/uvs/new.test @@ -0,0 +1,119 @@ +UVS new expressions +----- +className; +new Test::$className; +new $test::$className; +new $weird[0]->foo::$className; +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_New( + class: Expr_Variable( + name: className + ) + args: array( + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_Variable( + name: array + ) + dim: Scalar_String( + value: className + ) + ) + args: array( + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_Variable( + name: array + ) + dim: Scalar_String( + value: className + ) + ) + args: array( + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_New( + class: Expr_PropertyFetch( + var: Expr_Variable( + name: obj + ) + name: Identifier( + name: className + ) + ) + args: array( + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_New( + class: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: Test + ) + ) + name: VarLikeIdentifier( + name: className + ) + ) + args: array( + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_New( + class: Expr_StaticPropertyFetch( + class: Expr_Variable( + name: test + ) + name: VarLikeIdentifier( + name: className + ) + ) + args: array( + ) + ) + ) + 6: Stmt_Expression( + expr: Expr_New( + class: Expr_StaticPropertyFetch( + class: Expr_PropertyFetch( + var: Expr_ArrayDimFetch( + var: Expr_Variable( + name: weird + ) + dim: Scalar_LNumber( + value: 0 + ) + ) + name: Identifier( + name: foo + ) + ) + name: VarLikeIdentifier( + name: className + ) + ) + args: array( + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/expr/uvs/staticProperty.test b/vendor/nikic/php-parser/test/code/parser/expr/uvs/staticProperty.test new file mode 100644 index 00000000..bf3547ca --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/expr/uvs/staticProperty.test @@ -0,0 +1,123 @@ +UVS static access +----- +c test +EOS; + +b<<B"; +"$A[B]"; +"$A[0]"; +"$A[1234]"; +"$A[9223372036854775808]"; +"$A[000]"; +"$A[0x0]"; +"$A[0b0]"; +"$A[$B]"; +"{$A}"; +"{$A['B']}"; +"${A}"; +"${A['B']}"; +"${$A}"; +"\{$A}"; +"\{ $A }"; +"\\{$A}"; +"\\{ $A }"; +"{$$A}[B]"; +"$$A[B]"; +"A $B C"; +b"$A"; +B"$A"; +----- +array( + 0: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: A + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_PropertyFetch( + var: Expr_Variable( + name: A + ) + name: Identifier( + name: B + ) + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: B + ) + ) + ) + ) + ) + 3: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_LNumber( + value: 0 + ) + ) + ) + ) + ) + 4: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_LNumber( + value: 1234 + ) + ) + ) + ) + ) + 5: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: 9223372036854775808 + ) + ) + ) + ) + ) + 6: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: 000 + ) + ) + ) + ) + ) + 7: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: 0x0 + ) + ) + ) + ) + ) + 8: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: 0b0 + ) + ) + ) + ) + ) + 9: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Expr_Variable( + name: B + ) + ) + ) + ) + ) + 10: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: A + ) + ) + ) + ) + 11: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: B + ) + ) + ) + ) + ) + 12: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: A + ) + ) + ) + ) + 13: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: B + ) + ) + ) + ) + ) + 14: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: Expr_Variable( + name: A + ) + ) + ) + ) + ) + 15: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Scalar_EncapsedStringPart( + value: \{ + ) + 1: Expr_Variable( + name: A + ) + 2: Scalar_EncapsedStringPart( + value: } + ) + ) + ) + ) + 16: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Scalar_EncapsedStringPart( + value: \{ + ) + 1: Expr_Variable( + name: A + ) + 2: Scalar_EncapsedStringPart( + value: } + ) + ) + ) + ) + 17: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Scalar_EncapsedStringPart( + value: \ + ) + 1: Expr_Variable( + name: A + ) + ) + ) + ) + 18: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Scalar_EncapsedStringPart( + value: \{ + ) + 1: Expr_Variable( + name: A + ) + 2: Scalar_EncapsedStringPart( + value: } + ) + ) + ) + ) + 19: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: Expr_Variable( + name: A + ) + ) + 1: Scalar_EncapsedStringPart( + value: [B] + ) + ) + ) + ) + 20: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Scalar_EncapsedStringPart( + value: $ + ) + 1: Expr_ArrayDimFetch( + var: Expr_Variable( + name: A + ) + dim: Scalar_String( + value: B + ) + ) + ) + ) + ) + 21: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Scalar_EncapsedStringPart( + value: A + ) + 1: Expr_Variable( + name: B + ) + 2: Scalar_EncapsedStringPart( + value: C + ) + ) + ) + ) + 22: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: A + ) + ) + ) + ) + 23: Stmt_Expression( + expr: Scalar_Encapsed( + parts: array( + 0: Expr_Variable( + name: A + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/scalar/flexibleDocString.test b/vendor/nikic/php-parser/test/code/parser/scalar/flexibleDocString.test new file mode 100644 index 00000000..4460912c --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/scalar/flexibleDocString.test @@ -0,0 +1,359 @@ +Flexible heredoc/nowdoc (PHP 7.3) +----- + float overflows +// (all are actually the same number, just in different representations) +18446744073709551615; +0xFFFFFFFFFFFFFFFF; +01777777777777777777777; +0177777777777777777777787; +0b1111111111111111111111111111111111111111111111111111111111111111; +----- +array( + 0: Stmt_Expression( + expr: Scalar_DNumber( + value: 0 + ) + ) + 1: Stmt_Expression( + expr: Scalar_DNumber( + value: 0 + ) + ) + 2: Stmt_Expression( + expr: Scalar_DNumber( + value: 0 + ) + ) + 3: Stmt_Expression( + expr: Scalar_DNumber( + value: 0 + ) + ) + 4: Stmt_Expression( + expr: Scalar_DNumber( + value: 0 + ) + ) + 5: Stmt_Expression( + expr: Scalar_DNumber( + value: 0 + ) + ) + 6: Stmt_Expression( + expr: Scalar_DNumber( + value: 0 + ) + ) + 7: Stmt_Expression( + expr: Scalar_DNumber( + value: 302000000000 + ) + ) + 8: Stmt_Expression( + expr: Scalar_DNumber( + value: 3.002E+102 + ) + ) + 9: Stmt_Expression( + expr: Scalar_DNumber( + value: INF + ) + ) + 10: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + comments: array( + 0: // various integer -> float overflows + 1: // (all are actually the same number, just in different representations) + ) + ) + comments: array( + 0: // various integer -> float overflows + 1: // (all are actually the same number, just in different representations) + ) + ) + 11: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + ) + ) + 12: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + ) + ) + 13: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + ) + ) + 14: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/scalar/int.test b/vendor/nikic/php-parser/test/code/parser/scalar/int.test new file mode 100644 index 00000000..b65858db --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/scalar/int.test @@ -0,0 +1,61 @@ +Different integer syntaxes +----- +array(); +$t->public(); + +Test::list(); +Test::protected(); + +$t->class; +$t->private; + +Test::TRAIT; +Test::FINAL; + +class Foo { + use TraitA, TraitB { + TraitA::catch insteadof namespace\TraitB; + TraitA::list as foreach; + TraitB::throw as protected public; + TraitB::self as protected; + exit as die; + \TraitC::exit as bye; + namespace\TraitC::exit as byebye; + TraitA:: + // + /** doc comment */ + # + catch /* comment */ + // comment + # comment + insteadof TraitB; + } +} +----- +array( + 0: Stmt_Class( + flags: 0 + name: Identifier( + name: Test + ) + extends: null + implements: array( + ) + stmts: array( + 0: Stmt_ClassMethod( + flags: 0 + byRef: false + name: Identifier( + name: array + ) + params: array( + ) + returnType: null + stmts: array( + ) + ) + 1: Stmt_ClassMethod( + flags: 0 + byRef: false + name: Identifier( + name: public + ) + params: array( + ) + returnType: null + stmts: array( + ) + ) + 2: Stmt_ClassMethod( + flags: MODIFIER_STATIC (8) + byRef: false + name: Identifier( + name: list + ) + params: array( + ) + returnType: null + stmts: array( + ) + ) + 3: Stmt_ClassMethod( + flags: MODIFIER_STATIC (8) + byRef: false + name: Identifier( + name: protected + ) + params: array( + ) + returnType: null + stmts: array( + ) + ) + 4: Stmt_Property( + flags: MODIFIER_PUBLIC (1) + type: null + props: array( + 0: Stmt_PropertyProperty( + name: VarLikeIdentifier( + name: class + ) + default: null + ) + ) + ) + 5: Stmt_Property( + flags: MODIFIER_PUBLIC (1) + type: null + props: array( + 0: Stmt_PropertyProperty( + name: VarLikeIdentifier( + name: private + ) + default: null + ) + ) + ) + 6: Stmt_ClassConst( + flags: 0 + consts: array( + 0: Const( + name: Identifier( + name: TRAIT + ) + value: Scalar_LNumber( + value: 3 + ) + ) + 1: Const( + name: Identifier( + name: FINAL + ) + value: Scalar_LNumber( + value: 4 + ) + ) + ) + ) + 7: Stmt_ClassConst( + flags: 0 + consts: array( + 0: Const( + name: Identifier( + name: __CLASS__ + ) + value: Scalar_LNumber( + value: 1 + ) + ) + 1: Const( + name: Identifier( + name: __TRAIT__ + ) + value: Scalar_LNumber( + value: 2 + ) + ) + 2: Const( + name: Identifier( + name: __FUNCTION__ + ) + value: Scalar_LNumber( + value: 3 + ) + ) + 3: Const( + name: Identifier( + name: __METHOD__ + ) + value: Scalar_LNumber( + value: 4 + ) + ) + 4: Const( + name: Identifier( + name: __LINE__ + ) + value: Scalar_LNumber( + value: 5 + ) + ) + 5: Const( + name: Identifier( + name: __FILE__ + ) + value: Scalar_LNumber( + value: 6 + ) + ) + 6: Const( + name: Identifier( + name: __DIR__ + ) + value: Scalar_LNumber( + value: 7 + ) + ) + 7: Const( + name: Identifier( + name: __NAMESPACE__ + ) + value: Scalar_LNumber( + value: 8 + ) + ) + ) + ) + 8: Stmt_Nop( + comments: array( + 0: // __halt_compiler does not work + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: t + ) + expr: Expr_New( + class: Name( + parts: array( + 0: Test + ) + ) + args: array( + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: t + ) + name: Identifier( + name: array + ) + args: array( + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: t + ) + name: Identifier( + name: public + ) + args: array( + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: Test + ) + ) + name: Identifier( + name: list + ) + args: array( + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: Test + ) + ) + name: Identifier( + name: protected + ) + args: array( + ) + ) + ) + 6: Stmt_Expression( + expr: Expr_PropertyFetch( + var: Expr_Variable( + name: t + ) + name: Identifier( + name: class + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_PropertyFetch( + var: Expr_Variable( + name: t + ) + name: Identifier( + name: private + ) + ) + ) + 8: Stmt_Expression( + expr: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: Test + ) + ) + name: Identifier( + name: TRAIT + ) + ) + ) + 9: Stmt_Expression( + expr: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: Test + ) + ) + name: Identifier( + name: FINAL + ) + ) + ) + 10: Stmt_Class( + flags: 0 + name: Identifier( + name: Foo + ) + extends: null + implements: array( + ) + stmts: array( + 0: Stmt_TraitUse( + traits: array( + 0: Name( + parts: array( + 0: TraitA + ) + ) + 1: Name( + parts: array( + 0: TraitB + ) + ) + ) + adaptations: array( + 0: Stmt_TraitUseAdaptation_Precedence( + trait: Name( + parts: array( + 0: TraitA + ) + ) + method: Identifier( + name: catch + ) + insteadof: array( + 0: Name_Relative( + parts: array( + 0: TraitB + ) + ) + ) + ) + 1: Stmt_TraitUseAdaptation_Alias( + trait: Name( + parts: array( + 0: TraitA + ) + ) + method: Identifier( + name: list + ) + newModifier: null + newName: Identifier( + name: foreach + ) + ) + 2: Stmt_TraitUseAdaptation_Alias( + trait: Name( + parts: array( + 0: TraitB + ) + ) + method: Identifier( + name: throw + ) + newModifier: MODIFIER_PROTECTED (2) + newName: Identifier( + name: public + ) + ) + 3: Stmt_TraitUseAdaptation_Alias( + trait: Name( + parts: array( + 0: TraitB + ) + ) + method: Identifier( + name: self + ) + newModifier: MODIFIER_PROTECTED (2) + newName: null + ) + 4: Stmt_TraitUseAdaptation_Alias( + trait: null + method: Identifier( + name: exit + ) + newModifier: null + newName: Identifier( + name: die + ) + ) + 5: Stmt_TraitUseAdaptation_Alias( + trait: Name_FullyQualified( + parts: array( + 0: TraitC + ) + ) + method: Identifier( + name: exit + ) + newModifier: null + newName: Identifier( + name: bye + ) + ) + 6: Stmt_TraitUseAdaptation_Alias( + trait: Name_Relative( + parts: array( + 0: TraitC + ) + ) + method: Identifier( + name: exit + ) + newModifier: null + newName: Identifier( + name: byebye + ) + ) + 7: Stmt_TraitUseAdaptation_Precedence( + trait: Name( + parts: array( + 0: TraitA + ) + ) + method: Identifier( + name: catch + comments: array( + 0: // + 1: /** doc comment */ + 2: # + ) + ) + insteadof: array( + 0: Name( + parts: array( + 0: TraitB + ) + ) + ) + ) + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/stmt/blocklessStatement.test b/vendor/nikic/php-parser/test/code/parser/stmt/blocklessStatement.test new file mode 100644 index 00000000..abf58646 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/stmt/blocklessStatement.test @@ -0,0 +1,130 @@ +Blockless statements for if/for/etc +----- + 'baz'] +) {} +----- +array( + 0: Stmt_Function( + byRef: false + name: Identifier( + name: a + ) + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: b + ) + default: Expr_ConstFetch( + name: Name( + parts: array( + 0: null + ) + ) + ) + ) + 1: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: c + ) + default: Scalar_String( + value: foo + ) + ) + 2: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: d + ) + default: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: Identifier( + name: B + ) + ) + ) + 3: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: f + ) + default: Expr_UnaryPlus( + expr: Scalar_LNumber( + value: 1 + ) + ) + ) + 4: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: g + ) + default: Expr_UnaryMinus( + expr: Scalar_DNumber( + value: 1 + ) + ) + ) + 5: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: h + ) + default: Expr_Array( + items: array( + ) + ) + ) + 6: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: i + ) + default: Expr_Array( + items: array( + ) + ) + ) + 7: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: j + ) + default: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: foo + ) + byRef: false + ) + ) + ) + ) + 8: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: k + ) + default: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: foo + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: Scalar_String( + value: bar + ) + value: Scalar_String( + value: baz + ) + byRef: false + ) + ) + ) + ) + ) + returnType: null + stmts: array( + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/stmt/function/nullableTypes.test b/vendor/nikic/php-parser/test/code/parser/stmt/function/nullableTypes.test new file mode 100644 index 00000000..8bf2d31d --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/stmt/function/nullableTypes.test @@ -0,0 +1,55 @@ +Nullable types +----- + $value; + + // expressions + $data = yield; + $data = (yield $value); + $data = (yield $key => $value); + + // yield in language constructs with their own parentheses + if (yield $foo); elseif (yield $foo); + if (yield $foo): elseif (yield $foo): endif; + while (yield $foo); + do {} while (yield $foo); + switch (yield $foo) {} + die(yield $foo); + + // yield in function calls + func(yield $foo); + $foo->func(yield $foo); + new Foo(yield $foo); + + yield from $foo; + yield from $foo and yield from $bar; + yield from $foo + $bar; +} +----- +array( + 0: Stmt_Function( + byRef: false + name: Identifier( + name: gen + ) + params: array( + ) + returnType: null + stmts: array( + 0: Stmt_Expression( + expr: Expr_Yield( + key: null + value: null + comments: array( + 0: // statements + ) + ) + comments: array( + 0: // statements + ) + ) + 1: Stmt_Expression( + expr: Expr_Yield( + key: null + value: Expr_Variable( + name: value + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Yield( + key: Expr_Variable( + name: key + ) + value: Expr_Variable( + name: value + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: data + comments: array( + 0: // expressions + ) + ) + expr: Expr_Yield( + key: null + value: null + ) + comments: array( + 0: // expressions + ) + ) + comments: array( + 0: // expressions + ) + ) + 4: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: data + ) + expr: Expr_Yield( + key: null + value: Expr_Variable( + name: value + ) + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: data + ) + expr: Expr_Yield( + key: Expr_Variable( + name: key + ) + value: Expr_Variable( + name: value + ) + ) + ) + ) + 6: Stmt_If( + cond: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + stmts: array( + ) + elseifs: array( + 0: Stmt_ElseIf( + cond: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + stmts: array( + ) + ) + ) + else: null + comments: array( + 0: // yield in language constructs with their own parentheses + ) + ) + 7: Stmt_If( + cond: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + stmts: array( + ) + elseifs: array( + 0: Stmt_ElseIf( + cond: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + stmts: array( + ) + ) + ) + else: null + ) + 8: Stmt_While( + cond: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + stmts: array( + ) + ) + 9: Stmt_Do( + stmts: array( + ) + cond: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + ) + 10: Stmt_Switch( + cond: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + cases: array( + ) + ) + 11: Stmt_Expression( + expr: Expr_Exit( + expr: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + ) + ) + 12: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: func + ) + comments: array( + 0: // yield in function calls + ) + ) + args: array( + 0: Arg( + value: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + byRef: false + unpack: false + ) + ) + comments: array( + 0: // yield in function calls + ) + ) + comments: array( + 0: // yield in function calls + ) + ) + 13: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: foo + ) + name: Identifier( + name: func + ) + args: array( + 0: Arg( + value: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + byRef: false + unpack: false + ) + ) + ) + ) + 14: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: Foo + ) + ) + args: array( + 0: Arg( + value: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) + ) + byRef: false + unpack: false + ) + ) + ) + ) + 15: Stmt_Expression( + expr: Expr_YieldFrom( + expr: Expr_Variable( + name: foo + ) + ) + ) + 16: Stmt_Expression( + expr: Expr_BinaryOp_LogicalAnd( + left: Expr_YieldFrom( + expr: Expr_Variable( + name: foo + ) + ) + right: Expr_YieldFrom( + expr: Expr_Variable( + name: bar + ) + ) + ) + ) + 17: Stmt_Expression( + expr: Expr_YieldFrom( + expr: Expr_BinaryOp_Plus( + left: Expr_Variable( + name: foo + ) + right: Expr_Variable( + name: bar + ) + ) + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldPrecedence.test b/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldPrecedence.test new file mode 100644 index 00000000..1f843c31 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldPrecedence.test @@ -0,0 +1,250 @@ +Yield operator precedence +----- + "a" . "b"; + yield "k" => "a" or die; + var_dump([yield "k" => "a" . "b"]); + yield yield "k1" => yield "k2" => "a" . "b"; + yield yield "k1" => (yield "k2") => "a" . "b"; + var_dump([yield "k1" => yield "k2" => "a" . "b"]); + var_dump([yield "k1" => (yield "k2") => "a" . "b"]); +} +----- +!!php7 +array( + 0: Stmt_Function( + byRef: false + name: Identifier( + name: gen + ) + params: array( + ) + returnType: null + stmts: array( + 0: Stmt_Expression( + expr: Expr_Yield( + key: null + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_BinaryOp_LogicalOr( + left: Expr_Yield( + key: null + value: Scalar_String( + value: a + ) + ) + right: Expr_Exit( + expr: null + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Yield( + key: Scalar_String( + value: k + ) + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_BinaryOp_LogicalOr( + left: Expr_Yield( + key: Scalar_String( + value: k + ) + value: Scalar_String( + value: a + ) + ) + right: Expr_Exit( + expr: null + ) + ) + ) + 4: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: var_dump + ) + ) + args: array( + 0: Arg( + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Yield( + key: Scalar_String( + value: k + ) + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) + ) + ) + byRef: false + ) + ) + ) + byRef: false + unpack: false + ) + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_Yield( + key: null + value: Expr_Yield( + key: Scalar_String( + value: k1 + ) + value: Expr_Yield( + key: Scalar_String( + value: k2 + ) + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) + ) + ) + ) + ) + ) + 6: Stmt_Expression( + expr: Expr_Yield( + key: Expr_Yield( + key: Scalar_String( + value: k1 + ) + value: Expr_Yield( + key: null + value: Scalar_String( + value: k2 + ) + ) + ) + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: var_dump + ) + ) + args: array( + 0: Arg( + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Yield( + key: Scalar_String( + value: k1 + ) + value: Expr_Yield( + key: Scalar_String( + value: k2 + ) + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) + ) + ) + ) + byRef: false + ) + ) + ) + byRef: false + unpack: false + ) + ) + ) + ) + 8: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: var_dump + ) + ) + args: array( + 0: Arg( + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Expr_Yield( + key: Scalar_String( + value: k1 + ) + value: Expr_Yield( + key: null + value: Scalar_String( + value: k2 + ) + ) + ) + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) + ) + byRef: false + ) + ) + ) + byRef: false + unpack: false + ) + ) + ) + ) + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldUnaryPrecedence.test b/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldUnaryPrecedence.test new file mode 100644 index 00000000..6b77d335 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldUnaryPrecedence.test @@ -0,0 +1,56 @@ +Yield with unary operator argument +----- + +Hallo World! +----- +array( + 0: Stmt_Expression( + expr: Expr_Variable( + name: a + ) + ) + 1: Stmt_HaltCompiler( + remaining: Hallo World! + ) +) +----- + +#!/usr/bin/env php +----- +array( + 0: Stmt_InlineHTML( + value: #!/usr/bin/env php + + ) + 1: Stmt_Echo( + exprs: array( + 0: Scalar_String( + value: foobar + ) + ) + ) + 2: Stmt_InlineHTML( + value: #!/usr/bin/env php + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/stmt/if.test b/vendor/nikic/php-parser/test/code/parser/stmt/if.test new file mode 100644 index 00000000..e054c897 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/stmt/if.test @@ -0,0 +1,103 @@ +If/Elseif/Else +----- + +B + + $c) {} +foreach ($a as $b => &$c) {} +foreach ($a as list($a, $b)) {} +foreach ($a as $a => list($b, , $c)) {} + +// foreach on expression +foreach (array() as $b) {} + +// alternative syntax +foreach ($a as $b): +endforeach; +----- +array( + 0: Stmt_Foreach( + expr: Expr_Variable( + name: a + ) + keyVar: null + byRef: false + valueVar: Expr_Variable( + name: b + ) + stmts: array( + ) + comments: array( + 0: // foreach on variable + ) + ) + 1: Stmt_Foreach( + expr: Expr_Variable( + name: a + ) + keyVar: null + byRef: true + valueVar: Expr_Variable( + name: b + ) + stmts: array( + ) + ) + 2: Stmt_Foreach( + expr: Expr_Variable( + name: a + ) + keyVar: Expr_Variable( + name: b + ) + byRef: false + valueVar: Expr_Variable( + name: c + ) + stmts: array( + ) + ) + 3: Stmt_Foreach( + expr: Expr_Variable( + name: a + ) + keyVar: Expr_Variable( + name: b + ) + byRef: true + valueVar: Expr_Variable( + name: c + ) + stmts: array( + ) + ) + 4: Stmt_Foreach( + expr: Expr_Variable( + name: a + ) + keyVar: null + byRef: false + valueVar: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false + ) + ) + ) + stmts: array( + ) + ) + 5: Stmt_Foreach( + expr: Expr_Variable( + name: a + ) + keyVar: Expr_Variable( + name: a + ) + byRef: false + valueVar: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false + ) + 1: null + 2: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: c + ) + byRef: false + ) + ) + ) + stmts: array( + ) + ) + 6: Stmt_Foreach( + expr: Expr_Array( + items: array( + ) + ) + keyVar: null + byRef: false + valueVar: Expr_Variable( + name: b + ) + stmts: array( + ) + comments: array( + 0: // foreach on expression + ) + ) + 7: Stmt_Foreach( + expr: Expr_Variable( + name: a + ) + keyVar: null + byRef: false + valueVar: Expr_Variable( + name: b + ) + stmts: array( + ) + comments: array( + 0: // alternative syntax + ) + ) +) \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/parser/stmt/loop/while.test b/vendor/nikic/php-parser/test/code/parser/stmt/loop/while.test new file mode 100644 index 00000000..65f6b233 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/parser/stmt/loop/while.test @@ -0,0 +1,25 @@ +While loop +----- + +Hi! +----- +array( + 0: Stmt_Declare( + declares: array( + 0: Stmt_DeclareDeclare( + key: Identifier( + name: A + ) + value: Scalar_String( + value: B + ) + ) + ) + stmts: null + ) + 1: Stmt_Namespace( + name: Name( + parts: array( + 0: B + ) + ) + stmts: array( + ) + ) + 2: Stmt_HaltCompiler( + remaining: Hi! + ) +) +----- +a = $a; + } +}; +----- +new class +{ +}; +new class extends A implements B, C +{ +}; +new class($a) extends A +{ + private $a; + public function __construct($a) + { + $this->a = $a; + } +}; diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/expr/arrayDestructuring.test b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/arrayDestructuring.test new file mode 100644 index 00000000..bff1999e --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/arrayDestructuring.test @@ -0,0 +1,14 @@ +Array destructuring +----- + $b, 'b' => $a] = $baz; +----- +!!php7 +[$a, $b] = [$c, $d]; +[, $a, , , $b, ] = $foo; +[, [[$a]], $b] = $bar; +['a' => $b, 'b' => $a] = $baz; \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/expr/call.test b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/call.test new file mode 100644 index 00000000..0ec8925c --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/call.test @@ -0,0 +1,13 @@ +Calls +----- +d} +STR; + +call( + <<d} +STR; +call(<<> $b; +$a < $b; +$a <= $b; +$a > $b; +$a >= $b; +$a == $b; +$a != $b; +$a <> $b; +$a === $b; +$a !== $b; +$a <=> $b; +$a & $b; +$a ^ $b; +$a | $b; +$a && $b; +$a || $b; +$a ? $b : $c; +$a ?: $c; +$a ?? $c; +$a = $b; +$a **= $b; +$a ??= $c; +$a *= $b; +$a /= $b; +$a %= $b; +$a += $b; +$a -= $b; +$a .= $b; +$a <<= $b; +$a >>= $b; +$a &= $b; +$a ^= $b; +$a |= $b; +$a =& $b; + +$a and $b; +$a xor $b; +$a or $b; + +$a instanceof Foo; +$a instanceof $b; +----- +$a ** $b; +++$a; +--$a; +$a++; +$a--; +@$a; +~$a; +-$a; ++$a; +(int) $a; +(int) $a; +(float) $a; +(double) $a; +(real) $a; +(float) $a; +(double) $a; +(real) $a; +(string) $a; +(string) $a; +(array) $a; +(object) $a; +(bool) $a; +(bool) $a; +(unset) $a; +$a * $b; +$a / $b; +$a % $b; +$a + $b; +$a - $b; +$a . $b; +$a << $b; +$a >> $b; +$a < $b; +$a <= $b; +$a > $b; +$a >= $b; +$a == $b; +$a != $b; +$a != $b; +$a === $b; +$a !== $b; +$a <=> $b; +$a & $b; +$a ^ $b; +$a | $b; +$a && $b; +$a || $b; +$a ? $b : $c; +$a ?: $c; +$a ?? $c; +$a = $b; +$a **= $b; +$a ??= $c; +$a *= $b; +$a /= $b; +$a %= $b; +$a += $b; +$a -= $b; +$a .= $b; +$a <<= $b; +$a >>= $b; +$a &= $b; +$a ^= $b; +$a |= $b; +$a =& $b; +$a and $b; +$a xor $b; +$a or $b; +$a instanceof Foo; +$a instanceof $b; diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/expr/parentheses.test b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/parentheses.test new file mode 100644 index 00000000..a49c1108 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/parentheses.test @@ -0,0 +1,86 @@ +Pretty printer generates least-parentheses output +----- + 0) > (1 < 0); +++$a + $b; +$a + $b++; + +$a ** $b ** $c; +($a ** $b) ** $c; +-1 ** 2; + +yield from $a and yield from $b; +yield from ($a and yield from $b); + +print ($a and print $b); + +-(-$a); ++(+$a); +-(--$a); ++(++$a); + +// The following will currently add unnecessary parentheses, because the pretty printer is not aware that assignment +// and incdec only work on variables. +!$a = $b; +++$a ** $b; +$a ** $b++; +----- +echo 'abc' . 'cde' . 'fgh'; +echo 'abc' . ('cde' . 'fgh'); +echo 'abc' . 1 + 2 . 'fgh'; +echo 'abc' . (1 + 2) . 'fgh'; +echo 1 * 2 + 3 / 4 % 5 . 6; +echo 1 * (2 + 3) / (4 % (5 . 6)); +$a = $b = $c = $d = $f && true; +($a = $b = $c = $d = $f) && true; +$a = $b = $c = $d = $f and true; +$a = $b = $c = $d = ($f and true); +$a ? $b : $c ? $d : $e ? $f : $g; +$a ? $b : ($c ? $d : ($e ? $f : $g)); +$a ? $b ? $c : $d : $f; +$a ?? $b ?? $c; +($a ?? $b) ?? $c; +$a ?? ($b ? $c : $d); +$a || ($b ?? $c); +(1 > 0) > (1 < 0); +++$a + $b; +$a + $b++; +$a ** $b ** $c; +($a ** $b) ** $c; +-1 ** 2; +yield from $a and yield from $b; +yield from ($a and yield from $b); +print ($a and print $b); +-(-$a); ++(+$a); +-(--$a); ++(++$a); +// The following will currently add unnecessary parentheses, because the pretty printer is not aware that assignment +// and incdec only work on variables. +!($a = $b); +(++$a) ** $b; +$a ** ($b++); diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/expr/shortArraySyntax.test b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/shortArraySyntax.test new file mode 100644 index 00000000..082c2e04 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/shortArraySyntax.test @@ -0,0 +1,11 @@ +Short array syntax +----- + 'b', 'c' => 'd']; +----- +[]; +array(1, 2, 3); +['a' => 'b', 'c' => 'd']; \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/expr/stringEscaping.test b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/stringEscaping.test new file mode 100644 index 00000000..02877ad3 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/stringEscaping.test @@ -0,0 +1,23 @@ +Escape sequences in double-quoted strings +----- +b)(); +(A::$b)(); +----- +!!php7 +(function () { +})(); +array('a', 'b')()(); +A::$b::$c; +$A::$b[$c](); +$A::{$b[$c]}(); +A::${$b}[$c](); +($a->b)(); +(A::$b)(); diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/expr/variables.test b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/variables.test new file mode 100644 index 00000000..4e0fa2e1 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/variables.test @@ -0,0 +1,73 @@ +Variables +----- +b; +$a->b(); +$a->b($c); +$a->$b(); +$a->{$b}(); +$a->$b[$c](); +$$a->b; +$a[$b]; +$a[$b](); +$$a[$b]; +$a::B; +$a::$b; +$a::b(); +$a::b($c); +$a::$b(); +$a::$b[$c]; +$a::$b[$c]($d); +$a::{$b[$c]}($d); +$a::{$b->c}(); +A::$$b[$c](); +a(); +$a(); +$a()[$b]; +$a->b()[$c]; +$a::$b()[$c]; +(new A)->b; +(new A())->b(); +(new $$a)[$b]; +(new $a->b)->c; + +global $a, $$a, $$a[$b], $$a->b; +----- +!!php5 +$a; +${$a}; +${$a}; +$a->b; +$a->b(); +$a->b($c); +$a->{$b}(); +$a->{$b}(); +$a->{$b[$c]}(); +${$a}->b; +$a[$b]; +$a[$b](); +${$a[$b]}; +$a::B; +$a::$b; +$a::b(); +$a::b($c); +$a::$b(); +$a::$b[$c]; +$a::{$b[$c]}($d); +$a::{$b[$c]}($d); +$a::{$b->c}(); +A::${$b[$c]}(); +a(); +$a(); +$a()[$b]; +$a->b()[$c]; +$a::$b()[$c]; +(new A())->b; +(new A())->b(); +(new ${$a}())[$b]; +(new $a->b())->c; +global $a, ${$a}, ${$a[$b]}, ${$a->b}; diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/expr/yield.test b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/yield.test new file mode 100644 index 00000000..12ab7dec --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/expr/yield.test @@ -0,0 +1,46 @@ +Yield +----- + $b; + $a = yield; + $a = (yield $b); + $a = (yield $b => $c); +} +// TODO Get rid of parens for cases 2 and 3 +----- +function gen() +{ + yield; + (yield $a); + (yield $a => $b); + $a = yield; + $a = (yield $b); + $a = (yield $b => $c); +} +// TODO Get rid of parens for cases 2 and 3 +----- + $c; + yield from $a; + $a = yield from $b; +} +// TODO Get rid of parens for last case +----- +!!php7 +function gen() +{ + $a = (yield $b); + $a = (yield $b => $c); + yield from $a; + $a = (yield from $b); +} +// TODO Get rid of parens for last case \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/inlineHTMLandPHPtest.file-test b/vendor/nikic/php-parser/test/code/prettyPrinter/inlineHTMLandPHPtest.file-test new file mode 100644 index 00000000..b33eb527 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/inlineHTMLandPHPtest.file-test @@ -0,0 +1,58 @@ +File containing both inline HTML and PHP +----- +HTML + +HTML +----- + +HTML +----- +HTML + +HTML +----- +HTML + +HTML +----- +HTML + +HTML + +HTML +----- +HTML + +HTML + +HTML +----- +HTMLHTML +----- +HTMLHTML \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/nestedInlineHTML.test b/vendor/nikic/php-parser/test/code/prettyPrinter/nestedInlineHTML.test new file mode 100644 index 00000000..bc611f7b --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/nestedInlineHTML.test @@ -0,0 +1,16 @@ +InlineHTML node nested inside other code +----- + +Test + +Test + a = 'bar'; + echo 'test'; + } + + protected function baz() {} + public function foo() {} + abstract static function bar() {} +} + +trait Bar +{ + function test() + { + } +} +----- +class Foo extends Bar implements ABC, \DEF, namespace\GHI +{ + var $a = 'foo'; + private $b = 'bar'; + static $c = 'baz'; + function test() + { + $this->a = 'bar'; + echo 'test'; + } + protected function baz() + { + } + public function foo() + { + } + static abstract function bar() + { + } +} +trait Bar +{ + function test() + { + } +} \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/stmt/class_const.test b/vendor/nikic/php-parser/test/code/prettyPrinter/stmt/class_const.test new file mode 100644 index 00000000..e73ad430 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/stmt/class_const.test @@ -0,0 +1,20 @@ +Class constants +----- + $val) { + +} + +foreach ($arr as $key => &$val) { + +} +----- +foreach ($arr as $val) { +} +foreach ($arr as &$val) { +} +foreach ($arr as $key => $val) { +} +foreach ($arr as $key => &$val) { +} \ No newline at end of file diff --git a/vendor/nikic/php-parser/test/code/prettyPrinter/stmt/function_signatures.test b/vendor/nikic/php-parser/test/code/prettyPrinter/stmt/function_signatures.test new file mode 100644 index 00000000..af1088a0 --- /dev/null +++ b/vendor/nikic/php-parser/test/code/prettyPrinter/stmt/function_signatures.test @@ -0,0 +1,43 @@ +Function signatures +----- + $code) { + if (false !== strpos($code, '@@{')) { + // Skip tests with evaluate segments + continue; + } + + list($name, $tests) = $testParser->parseTest($code, 2); + $newTests = []; + foreach ($tests as list($modeLine, list($input, $expected))) { + $modes = null !== $modeLine ? array_fill_keys(explode(',', $modeLine), true) : []; + list($parser5, $parser7) = $codeParsingTest->createParsers($modes); + list(, $output) = isset($modes['php5']) + ? $codeParsingTest->getParseOutput($parser5, $input, $modes) + : $codeParsingTest->getParseOutput($parser7, $input, $modes); + $newTests[] = [$modeLine, [$input, $output]]; + } + + $newCode = $testParser->reconstructTest($name, $newTests); + file_put_contents($fileName, $newCode); +} diff --git a/vendor/nikic/php-parser/test_old/run-php-src.sh b/vendor/nikic/php-parser/test_old/run-php-src.sh new file mode 100755 index 00000000..944cfffa --- /dev/null +++ b/vendor/nikic/php-parser/test_old/run-php-src.sh @@ -0,0 +1,4 @@ +wget -q https://github.com/php/php-src/archive/php-7.3.0RC1.tar.gz +mkdir -p ./data/php-src +tar -xzf ./php-7.3.0RC1.tar.gz -C ./data/php-src --strip-components=1 +php -n test_old/run.php --verbose --no-progress PHP7 ./data/php-src diff --git a/vendor/nikic/php-parser/test_old/run.php b/vendor/nikic/php-parser/test_old/run.php new file mode 100644 index 00000000..8b74ab47 --- /dev/null +++ b/vendor/nikic/php-parser/test_old/run.php @@ -0,0 +1,271 @@ + [ + 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', +]]); +$parserName = 'PhpParser\Parser\\' . $version; +/** @var PhpParser\Parser $parser */ +$parser = new $parserName($lexer); +$prettyPrinter = new PhpParser\PrettyPrinter\Standard; +$nodeDumper = new PhpParser\NodeDumper; + +$cloningTraverser = new PhpParser\NodeTraverser; +$cloningTraverser->addVisitor(new PhpParser\NodeVisitor\CloningVisitor); + +$parseFail = $fpppFail = $ppFail = $compareFail = $count = 0; + +$readTime = $parseTime = $cloneTime = 0; +$fpppTime = $ppTime = $reparseTime = $compareTime = 0; +$totalStartTime = microtime(true); + +foreach (new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($dir), + RecursiveIteratorIterator::LEAVES_ONLY) + as $file) { + if (!$fileFilter($file)) { + continue; + } + + $startTime = microtime(true); + $origCode = file_get_contents($file); + $readTime += microtime(true) - $startTime; + + if (null === $origCode = $codeExtractor($file, $origCode)) { + continue; + } + + set_time_limit(10); + + ++$count; + + if ($showProgress) { + echo substr(str_pad('Testing file ' . $count . ': ' . substr($file, strlen($dir)), 79), 0, 79), "\r"; + } + + try { + $startTime = microtime(true); + $origStmts = $parser->parse($origCode); + $parseTime += microtime(true) - $startTime; + + $origTokens = $lexer->getTokens(); + + $startTime = microtime(true); + $stmts = $cloningTraverser->traverse($origStmts); + $cloneTime += microtime(true) - $startTime; + + $startTime = microtime(true); + $code = $prettyPrinter->printFormatPreserving($stmts, $origStmts, $origTokens); + $fpppTime += microtime(true) - $startTime; + + if ($code !== $origCode) { + echo $file, ":\n Result of format-preserving pretty-print differs\n"; + if ($verbose) { + echo "FPPP output:\n=====\n$code\n=====\n\n"; + } + + ++$fpppFail; + } + + $startTime = microtime(true); + $code = "prettyPrint($stmts); + $ppTime += microtime(true) - $startTime; + + try { + $startTime = microtime(true); + $ppStmts = $parser->parse($code); + $reparseTime += microtime(true) - $startTime; + + $startTime = microtime(true); + $same = $nodeDumper->dump($stmts) == $nodeDumper->dump($ppStmts); + $compareTime += microtime(true) - $startTime; + + if (!$same) { + echo $file, ":\n Result of initial parse and parse after pretty print differ\n"; + if ($verbose) { + echo "Pretty printer output:\n=====\n$code\n=====\n\n"; + } + + ++$compareFail; + } + } catch (PhpParser\Error $e) { + echo $file, ":\n Parse of pretty print failed with message: {$e->getMessage()}\n"; + if ($verbose) { + echo "Pretty printer output:\n=====\n$code\n=====\n\n"; + } + + ++$ppFail; + } + } catch (PhpParser\Error $e) { + echo $file, ":\n Parse failed with message: {$e->getMessage()}\n"; + + ++$parseFail; + } +} + +if (0 === $parseFail && 0 === $ppFail && 0 === $compareFail) { + $exit = 0; + echo "\n\n", 'All tests passed.', "\n"; +} else { + $exit = 1; + echo "\n\n", '==========', "\n\n", 'There were: ', "\n"; + if (0 !== $parseFail) { + echo ' ', $parseFail, ' parse failures.', "\n"; + } + if (0 !== $ppFail) { + echo ' ', $ppFail, ' pretty print failures.', "\n"; + } + if (0 !== $fpppFail) { + echo ' ', $fpppFail, ' FPPP failures.', "\n"; + } + if (0 !== $compareFail) { + echo ' ', $compareFail, ' compare failures.', "\n"; + } +} + +echo "\n", + 'Tested files: ', $count, "\n", + "\n", + 'Reading files took: ', $readTime, "\n", + 'Parsing took: ', $parseTime, "\n", + 'Cloning took: ', $cloneTime, "\n", + 'FPPP took: ', $fpppTime, "\n", + 'Pretty printing took: ', $ppTime, "\n", + 'Reparsing took: ', $reparseTime, "\n", + 'Comparing took: ', $compareTime, "\n", + "\n", + 'Total time: ', microtime(true) - $totalStartTime, "\n", + 'Maximum memory usage: ', memory_get_peak_usage(true), "\n"; + +exit($exit); diff --git a/vendor/ocramius/package-versions/CHANGELOG.md b/vendor/ocramius/package-versions/CHANGELOG.md new file mode 100644 index 00000000..a838c56a --- /dev/null +++ b/vendor/ocramius/package-versions/CHANGELOG.md @@ -0,0 +1,120 @@ +# CHANGELOG + +## 1.1.3 - 2017-09-06 + +This release fixes a bug that caused PackageVersions to prevent +the `composer remove` and `composer update` commands to fail when +this package is removed. + +In addition to that, mutation testing has been added to the suite, +ensuring that the package is accurately and extensively tested. + +Total issues resolved: **3** + +- [40: Mutation testing, PHP 7.1 testing](https://github.com/Ocramius/PackageVersions/pull/40) thanks to @Ocramius +- [41: Removing this package on install results in file access error](https://github.com/Ocramius/PackageVersions/issues/41) thanks to @Xerkus +- [46: #41 Avoid issues when the package is scheduled for removal](https://github.com/Ocramius/PackageVersions/pull/46) thanks to @Jean85 + +## 1.1.2 - 2016-12-30 + +This release fixes a bug that caused PackageVersions to be enabled +even when it was part of a globally installed package. + +Total issues resolved: **3** + +- [35: remove all temp directories](https://github.com/Ocramius/PackageVersions/pull/35) +- [38: Interferes with other projects when installed globally](https://github.com/Ocramius/PackageVersions/issues/38) +- [39: Ignore the global plugin when updating local projects](https://github.com/Ocramius/PackageVersions/pull/39) + +## 1.1.1 - 2016-07-25 + +This release removes the [`"files"`](https://getcomposer.org/doc/04-schema.md#files) directive from +[`composer.json`](https://github.com/Ocramius/PackageVersions/commit/86f2636f7c5e7b56fa035fa3826d5fcf80b6dc72), +as it is no longer needed for `composer install --classmap-authoritative`. +Also, that directive was causing issues with HHVM installations, since +PackageVersions is not compatible with it. + +Total issues resolved: **1** + +- [34: Fatal error during travis build after update to 1.1.0](https://github.com/Ocramius/PackageVersions/issues/34) + +## 1.1.0 - 2016-07-22 + +This release introduces support for running `composer install --classmap-authoritative` +and `composer install --no-scripts`. Please note that performance +while using these modes may be degraded, but the package will +still work. + +Additionally, the package was tuned to prevent the plugin from +running twice at installation. + +Total issues resolved: **10** + +- [18: Fails when using composer install --no-scripts](https://github.com/Ocramius/PackageVersions/issues/18) +- [20: CS (spacing)](https://github.com/Ocramius/PackageVersions/pull/20) +- [22: Document the way the require-dev section is treated](https://github.com/Ocramius/PackageVersions/issues/22) +- [23: Underline that composer.lock is used as source of information](https://github.com/Ocramius/PackageVersions/pull/23) +- [27: Fix incompatibility with --classmap-authoritative](https://github.com/Ocramius/PackageVersions/pull/27) +- [29: mention optimize-autoloader composer.json config option in README](https://github.com/Ocramius/PackageVersions/pull/29) +- [30: The version class is generated twice during composer update](https://github.com/Ocramius/PackageVersions/issues/30) +- [31: Remove double registration of the event listeners](https://github.com/Ocramius/PackageVersions/pull/31) +- [32: Update the usage of mock APIs to use the new API](https://github.com/Ocramius/PackageVersions/pull/32) +- [33: Fix for #18 - support running with --no-scripts flag](https://github.com/Ocramius/PackageVersions/pull/33) + +## 1.0.4 - 2016-04-23 + +This release includes a fix/workaround for composer/composer#5237, +which causes `ocramius/package-versions` to sometimes generate a +`Versions` class with malformed name (something like +`Versions_composer_tmp0`) when running `composer require `. + +Total issues resolved: **2** + +- [16: Workaround for composer/composer#5237 - class parsing](https://github.com/Ocramius/PackageVersions/pull/16) +- [17: Weird Class name being generated](https://github.com/Ocramius/PackageVersions/issues/17) + +## 1.0.3 - 2016-02-26 + +This release fixes an issue related to concurrent autoloader +re-generation caused by multiple composer plugins being installed. +The issue was solved by removing autoloader re-generation from this +package, but it may still affect other packages. + +It is now recommended that you run `composer dump-autoload --optimize` +after installation when using this particular package. +Please note that `composer (install|update) -o` is not sufficient +to avoid autoload overhead when using this particular package. + +Total issues resolved: **1** + +- [15: Remove autoload re-dump optimization](https://github.com/Ocramius/PackageVersions/pull/15) + +## 1.0.2 - 2016-02-24 + +This release fixes issues related to installing the component without +any dev dependencies or with packages that don't have a source or dist +reference, which is usual with packages defined directly in the +`composer.json`. + +Total issues resolved: **3** + +- [11: fix composer install --no-dev PHP7](https://github.com/Ocramius/PackageVersions/pull/11) +- [12: Packages don't always have a source/reference](https://github.com/Ocramius/PackageVersions/issues/12) +- [13: Fix #12 - support dist and missing package version references](https://github.com/Ocramius/PackageVersions/pull/13) + +## 1.0.1 - 2016-02-01 + +This release fixes an issue related with composer updates to +already installed versions. +Using `composer require` within a package that already used +`ocramius/package-versions` caused the installation to be unable +to write the `PackageVersions\Versions` class to a file. + +Total issues resolved: **6** + +- [2: remove unused use statement](https://github.com/Ocramius/PackageVersions/pull/2) +- [3: Remove useless files from dist package](https://github.com/Ocramius/PackageVersions/pull/3) +- [5: failed to open stream: phar error: write operations disabled by the php.ini setting phar.readonly](https://github.com/Ocramius/PackageVersions/issues/5) +- [6: Fix/#5 use composer vendor dir](https://github.com/Ocramius/PackageVersions/pull/6) +- [7: Hotfix - #5 generate package versions also when in phar context](https://github.com/Ocramius/PackageVersions/pull/7) +- [8: Versions class should be ignored by VCS, as it is an install-time artifact](https://github.com/Ocramius/PackageVersions/pull/8) diff --git a/vendor/ocramius/package-versions/CONTRIBUTING.md b/vendor/ocramius/package-versions/CONTRIBUTING.md new file mode 100644 index 00000000..71806175 --- /dev/null +++ b/vendor/ocramius/package-versions/CONTRIBUTING.md @@ -0,0 +1,39 @@ +--- +title: Contributing +--- + +# Contributing + + * Coding standard for the project is [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) + * The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php) + * Any contribution must provide tests for additional introduced conditions + * Any un-confirmed issue needs a failing test case before being accepted + * Pull requests must be sent from a new hotfix/feature branch, not from `master`. + +## Installation + +To install the project and run the tests, you need to clone it first: + +```sh +$ git clone git://github.com/Ocramius/PackageVersions.git +``` + +You will then need to run a composer installation: + +```sh +$ cd PackageVersions +$ curl -s https://getcomposer.org/installer | php +$ php composer.phar update +``` + +## Testing + +The PHPUnit version to be used is the one installed as a dev- dependency via composer: + +```sh +$ ./vendor/bin/phpunit +``` + +Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement +won't be merged. + diff --git a/vendor/ocramius/package-versions/LICENSE b/vendor/ocramius/package-versions/LICENSE new file mode 100644 index 00000000..a90b0792 --- /dev/null +++ b/vendor/ocramius/package-versions/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2016 Marco Pivetta + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/ocramius/package-versions/README.md b/vendor/ocramius/package-versions/README.md new file mode 100644 index 00000000..c9b6103a --- /dev/null +++ b/vendor/ocramius/package-versions/README.md @@ -0,0 +1,60 @@ +# Package Versions + +This utility provides quick and easy access to version information of composer dependencies. + +This information is derived from the ```composer.lock``` file which is (re)generated during ```composer install``` or ```composer update```. + +```php +$version = \PackageVersions\Versions::getVersion('ocramius/package-versions'); + +var_dump($version); // 1.0.0@0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33 +``` + +[![Build Status](https://travis-ci.org/Ocramius/PackageVersions.svg?branch=master)](https://travis-ci.org/Ocramius/PackageVersions) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Ocramius/PackageVersions/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Ocramius/PackageVersions/?branch=master) +[![Code Coverage](https://scrutinizer-ci.com/g/Ocramius/PackageVersions/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Ocramius/PackageVersions/?branch=master) +[![Downloads](https://img.shields.io/packagist/dt/ocramius/package-versions.svg)](https://packagist.org/packages/ocramius/package-versions) +[![Packagist](https://img.shields.io/packagist/v/ocramius/package-versions.svg)](https://packagist.org/packages/ocramius/package-versions) +[![Dependencies](https://tidelift.com/badges/github/packagist/ocramius%2Fpackage-versions)](https://tidelift.com/subscription/pkg/packagist-ocramius%2Fpackage-versions?utm_source=packagist-ocramius%2Fpackage-versions&utm_medium=readme) + +### Installation + +```sh +composer require ocramius/package-versions +``` + +It is suggested that you use a optimized composer autoloader in order to prevent +autoload I/O when accessing the `PackageVersions\Versions` API: + +Therefore you should use `optimize-autoloader: true` in your composer.json: +``` +... + "config": { + "optimize-autoloader": true + }, +... +``` +see https://getcomposer.org/doc/06-config.md#optimize-autoloader + +In case you manually generate your autoloader via the CLI use the `--optimize` flag: + +```sh +composer dump-autoload --optimize +``` + +### Use-cases + +This repository implements `PackageVersions\Versions::getVersion()` in such a way that no IO +happens when calling it, because the list of package versions is compiled during composer +installation. + +This is especially useful when you want to generate assets/code/artifacts that are computed from +the current version of a certain dependency. Doing so at runtime by checking the installed +version of a package would be too expensive, and this package mitigates that. + +## Professional Support + +[Professionally supported `ocramius/package-versions` is available through Tidelift](https://tidelift.com/subscription/pkg/packagist-ocramius-package-versions?utm_source=packagist-ocramius-package-versions&utm_medium=referral&utm_campaign=readme). + +You can also contact the maintainer at ocramius@gmail.com for looking into issues related to this package +in your private projects. diff --git a/vendor/ocramius/package-versions/composer.json b/vendor/ocramius/package-versions/composer.json new file mode 100644 index 00000000..c1a75cdf --- /dev/null +++ b/vendor/ocramius/package-versions/composer.json @@ -0,0 +1,43 @@ +{ + "name": "ocramius/package-versions", + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "type": "composer-plugin", + "license": "MIT", + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "require": { + "php": "^7.1.0", + "composer-plugin-api": "^1.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0.0", + "infection/infection": "^0.7.1", + "composer/composer": "^1.6.3", + "ext-zip": "*", + "doctrine/coding-standard": "^5.0.1" + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "autoload-dev": { + "psr-4": { + "PackageVersionsTest\\": "test/PackageVersionsTest" + } + }, + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "scripts": { + "post-update-cmd": "PackageVersions\\Installer::dumpVersionsClass", + "post-install-cmd": "PackageVersions\\Installer::dumpVersionsClass" + } +} diff --git a/vendor/ocramius/package-versions/composer.lock b/vendor/ocramius/package-versions/composer.lock new file mode 100644 index 00000000..f161dc10 --- /dev/null +++ b/vendor/ocramius/package-versions/composer.lock @@ -0,0 +1,2869 @@ +{ + "_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#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "8193d241c36d581f93f05282ea504ec5", + "packages": [], + "packages-dev": [ + { + "name": "composer/ca-bundle", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/d2c0a83b7533d6912e8d516756ebd34f893e9169", + "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2018-03-29T19:57:20+00:00" + }, + { + "name": "composer/composer", + "version": "1.6.4", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "86ad51e8a3c64c9782446aae740a61fc6faa2522" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/86ad51e8a3c64c9782446aae740a61fc6faa2522", + "reference": "86ad51e8a3c64c9782446aae740a61fc6faa2522", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.2", + "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/cli-prompt": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7", + "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "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" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2018-04-13T10:04:24+00:00" + }, + { + "name": "composer/semver", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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" + ], + "time": "2016-08-30T16:08:34+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "7e111c50db92fa2ced140f5ba23b4e261bc77a30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7e111c50db92fa2ced140f5ba23b4e261bc77a30", + "reference": "7e111c50db92fa2ced140f5ba23b4e261bc77a30", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "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": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2018-01-31T13:17:27+00:00" + }, + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.5.0", + "source": { + "type": "git", + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "e749410375ff6fb7a040a68878c656c2e610b132" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/e749410375ff6fb7a040a68878c656c2e610b132", + "reference": "e749410375ff6fb7a040a68878c656c2e610b132", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0", + "php": "^5.3|^7", + "squizlabs/php_codesniffer": "^2|^3" + }, + "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" + ], + "time": "2018-10-26T13:21:45+00:00" + }, + { + "name": "doctrine/coding-standard", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/coding-standard.git", + "reference": "9017efe98b47329cbd895d43f596747c8ef27307" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/9017efe98b47329cbd895d43f596747c8ef27307", + "reference": "9017efe98b47329cbd895d43f596747c8ef27307", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5.0", + "php": "^7.1", + "slevomat/coding-standard": "^4.8.0", + "squizlabs/php_codesniffer": "^3.3.2" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Sniffs\\": "lib/Doctrine/Sniffs" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Steve Müller", + "email": "st.mueller@dzh-online.de" + } + ], + "description": "The Doctrine Coding Standard is a set of PHPCS rules applied to all Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/coding-standard.html", + "keywords": [ + "checks", + "code", + "coding", + "cs", + "doctrine", + "rules", + "sniffer", + "sniffs", + "standard", + "style" + ], + "time": "2019-01-31T13:22:30+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "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": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, + { + "name": "infection/infection", + "version": "0.7.1", + "source": { + "type": "git", + "url": "https://github.com/infection/infection.git", + "reference": "44751a5835ec44e7f2754ddcf21a2012f8219c23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/infection/infection/zipball/44751a5835ec44e7f2754ddcf21a2012f8219c23", + "reference": "44751a5835ec44e7f2754ddcf21a2012f8219c23", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^3.0", + "padraic/phar-updater": "^1.0.4", + "php": "^7.0", + "pimple/pimple": "^3.2", + "sebastian/diff": "^1.4 || ^2.0 || ^3.0", + "symfony/console": "^3.2 || ^4.0", + "symfony/finder": "^3.2 || ^4.0", + "symfony/process": "^3.2 || ^4.0", + "symfony/yaml": "^3.2 || ^4.0" + }, + "conflict": { + "symfony/process": "3.4.2" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.1" + }, + "bin": [ + "bin/infection" + ], + "type": "library", + "autoload": { + "psr-4": { + "Infection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Maks Rafalko", + "email": "maks.rafalko@gmail.com", + "homepage": "https://twitter.com/maks_rafalko" + } + ], + "description": "Infection is a Mutation Testing framework for PHP. The mutation adequacy score can be used to measure the effectiveness of a test set in terms of its ability to detect faults.", + "keywords": [ + "coverage", + "mutant", + "mutation framework", + "mutation testing", + "testing", + "unit testing" + ], + "time": "2018-02-02T11:25:42+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.7", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "8560d4314577199ba51bf2032f02cd1315587c23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/8560d4314577199ba51bf2032f02cd1315587c23", + "reference": "8560d4314577199ba51bf2032f02cd1315587c23", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2018-02-14T22:26:30+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.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" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v3.1.5", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-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" + ], + "time": "2018-02-28T20:30:58+00:00" + }, + { + "name": "padraic/humbug_get_contents", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/humbug/file_get_contents.git", + "reference": "dcb086060c9dd6b2f51d8f7a895500307110b7a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/humbug/file_get_contents/zipball/dcb086060c9dd6b2f51d8f7a895500307110b7a7", + "reference": "dcb086060c9dd6b2f51d8f7a895500307110b7a7", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "ext-openssl": "*", + "php": "^5.3 || ^7.0 || ^7.1 || ^7.2" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.1", + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false + }, + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Humbug\\": "src/" + }, + "files": [ + "src/function.php", + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Padraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Théo Fidry", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Secure wrapper for accessing HTTPS resources with file_get_contents for PHP 5.3+", + "homepage": "https://github.com/padraic/file_get_contents", + "keywords": [ + "download", + "file_get_contents", + "http", + "https", + "ssl", + "tls" + ], + "time": "2018-02-12T18:47:17+00:00" + }, + { + "name": "padraic/phar-updater", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/humbug/phar-updater.git", + "reference": "d01d3b8f26e541ac9b9eeba1e18d005d852f7ff1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/humbug/phar-updater/zipball/d01d3b8f26e541ac9b9eeba1e18d005d852f7ff1", + "reference": "d01d3b8f26e541ac9b9eeba1e18d005d852f7ff1", + "shasum": "" + }, + "require": { + "padraic/humbug_get_contents": "^1.0", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Humbug\\SelfUpdate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + } + ], + "description": "A thing to make PHAR self-updating easy and secure.", + "keywords": [ + "humbug", + "phar", + "self-update", + "update" + ], + "time": "2018-03-30T12:52:15+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.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", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.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" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.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": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-30T07:14:17+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.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" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.7.6", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "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" + ], + "time": "2018-04-18T13:57:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "52187754b0eed0b8159f62a6fa30073327e8c2ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/52187754b0eed0b8159f62a6fa30073327e8c2ca", + "reference": "52187754b0eed0b8159f62a6fa30073327e8c2ca", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.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 provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-04-29T14:59:09+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.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" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "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" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "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": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2018-02-01T13:07:23+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.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": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2018-02-01T13:16:43+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "ca64dba53b88aba6af32aebc6b388068db95c435" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ca64dba53b88aba6af32aebc6b388068db95c435", + "reference": "ca64dba53b88aba6af32aebc6b388068db95c435", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.1", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "phpunit/phpunit-mock-objects": "^6.1.1", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.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": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-04-29T15:09:19+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "6.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/70c740bde8fd9ea9ea295be1cd875dd7b267e157", + "reference": "70c740bde8fd9ea9ea295be1cd875dd7b267e157", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.5", + "php": "^7.1", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.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": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2018-04-11T04:50:36+00:00" + }, + { + "name": "pimple/pimple", + "version": "v3.2.3", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32", + "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/container": "^1.0" + }, + "require-dev": { + "symfony/phpunit-bridge": "^3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "http://pimple.sensiolabs.org", + "keywords": [ + "container", + "dependency injection" + ], + "time": "2018-01-21T07:42:36+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://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" + ], + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-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/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "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": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-04-18T13:33:00+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "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": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2018-02-01T13:45:15+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-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" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "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": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-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/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-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/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-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", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "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": "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", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "seld/cli-prompt", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "time": "2017-03-18T11:32:45+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/d15f59a67ff805a44c50ea0516d2341740f81a38", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2018-01-24T12:46:19+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13T18:44:15+00:00" + }, + { + "name": "slevomat/coding-standard", + "version": "4.8.7", + "source": { + "type": "git", + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "bff96313d8c7c2ba57a4edb13c1c141df8988c58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/bff96313d8c7c2ba57a4edb13c1c141df8988c58", + "reference": "bff96313d8c7c2ba57a4edb13c1c141df8988c58", + "shasum": "" + }, + "require": { + "php": "^7.1", + "squizlabs/php_codesniffer": "^3.4.0" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "1.0.0", + "phing/phing": "2.16.1", + "phpstan/phpstan": "0.9.2", + "phpstan/phpstan-phpunit": "0.9.4", + "phpstan/phpstan-strict-rules": "0.9", + "phpunit/phpunit": "7.5.1" + }, + "type": "phpcodesniffer-standard", + "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.", + "time": "2019-01-03T13:15:50+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "379deb987e26c7cd103a7b387aea178baec96e48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48", + "reference": "379deb987e26c7cd103a7b387aea178baec96e48", + "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": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2018-12-19T23:57:18+00:00" + }, + { + "name": "symfony/console", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", + "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "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": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-04-30T01:23:47+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", + "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "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": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2018-02-22T10:50:29+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", + "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "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": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2018-04-04T05:10:37+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "3296adf6a6454a050679cde90f95350ad604b171" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171", + "reference": "3296adf6a6454a050679cde90f95350ad604b171", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "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" + ], + "time": "2018-04-26T10:06:28+00:00" + }, + { + "name": "symfony/process", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25", + "reference": "d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "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": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2018-04-03T05:24:00+00:00" + }, + { + "name": "symfony/yaml", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "275ad099e4cbe612a2acbca14a16dd1c5311324d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/275ad099e4cbe612a2acbca14a16dd1c5311324d", + "reference": "275ad099e4cbe612a2acbca14a16dd1c5311324d", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2018-04-08T08:49:08+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.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", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-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" + ], + "time": "2018-01-29T19:49:41+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^7.1.0" + }, + "platform-dev": { + "ext-zip": "*" + } +} diff --git a/vendor/ocramius/package-versions/infection.json.dist b/vendor/ocramius/package-versions/infection.json.dist new file mode 100644 index 00000000..b883a216 --- /dev/null +++ b/vendor/ocramius/package-versions/infection.json.dist @@ -0,0 +1,11 @@ +{ + "timeout": 10, + "source": { + "directories": [ + "src" + ] + }, + "logs": { + "text": "infection-log.txt" + } +} \ No newline at end of file diff --git a/vendor/ocramius/package-versions/phpcs.xml.dist b/vendor/ocramius/package-versions/phpcs.xml.dist new file mode 100644 index 00000000..e169c616 --- /dev/null +++ b/vendor/ocramius/package-versions/phpcs.xml.dist @@ -0,0 +1,21 @@ + + + + + + + + + + + src + test + + + src/PackageVersions/Versions.php + + + + src/PackageVersions/Installer.php + + diff --git a/vendor/ocramius/package-versions/src/PackageVersions/FallbackVersions.php b/vendor/ocramius/package-versions/src/PackageVersions/FallbackVersions.php new file mode 100644 index 00000000..a99b5f07 --- /dev/null +++ b/vendor/ocramius/package-versions/src/PackageVersions/FallbackVersions.php @@ -0,0 +1,88 @@ + $package['version'] . '@' . ( + $package['source']['reference']?? $package['dist']['reference'] ?? '' + ); + } + + yield self::ROOT_PACKAGE_NAME; + } +} diff --git a/vendor/ocramius/package-versions/src/PackageVersions/Installer.php b/vendor/ocramius/package-versions/src/PackageVersions/Installer.php new file mode 100644 index 00000000..18f1d906 --- /dev/null +++ b/vendor/ocramius/package-versions/src/PackageVersions/Installer.php @@ -0,0 +1,201 @@ + 'dumpVersionsClass', + ScriptEvents::POST_UPDATE_CMD => 'dumpVersionsClass', + ]; + } + + /** + * @throws RuntimeException + */ + public static function dumpVersionsClass(Event $composerEvent) : void + { + $composer = $composerEvent->getComposer(); + $rootPackage = $composer->getPackage(); + $versions = iterator_to_array(self::getVersions($composer->getLocker(), $rootPackage)); + + if (! array_key_exists('ocramius/package-versions', $versions)) { + //plugin must be globally installed - we only want to generate versions for projects which specifically + //require ocramius/package-versions + return; + } + + $versionClass = self::generateVersionsClass($rootPackage->getName(), $versions); + + self::writeVersionClassToFile($versionClass, $composer, $composerEvent->getIO()); + } + + /** + * @param string[] $versions + */ + private static function generateVersionsClass(string $rootPackageName, array $versions) : string + { + return sprintf( + self::$generatedClassTemplate, + 'fin' . 'al ' . 'cla' . 'ss ' . 'Versions', // note: workaround for regex-based code parsers :-( + $rootPackageName, + var_export($versions, true) + ); + } + + /** + * @throws RuntimeException + */ + private static function writeVersionClassToFile(string $versionClassSource, Composer $composer, IOInterface $io) : void + { + $installPath = self::locateRootPackageInstallPath($composer->getConfig(), $composer->getPackage()) + . '/src/PackageVersions/Versions.php'; + + if (! file_exists(dirname($installPath))) { + $io->write('ocramius/package-versions: Package not found (probably scheduled for removal); generation of version class skipped.'); + + return; + } + + $io->write('ocramius/package-versions: Generating version class...'); + + $installPathTmp = $installPath . '_' . uniqid('tmp', true); + file_put_contents($installPathTmp, $versionClassSource); + chmod($installPathTmp, 0664); + rename($installPathTmp, $installPath); + + $io->write('ocramius/package-versions: ...done generating version class'); + } + + /** + * @throws RuntimeException + */ + private static function locateRootPackageInstallPath( + Config $composerConfig, + RootPackageInterface $rootPackage + ) : string { + if (self::getRootPackageAlias($rootPackage)->getName() === 'ocramius/package-versions') { + return dirname($composerConfig->get('vendor-dir')); + } + + return $composerConfig->get('vendor-dir') . '/ocramius/package-versions'; + } + + private static function getRootPackageAlias(RootPackageInterface $rootPackage) : PackageInterface + { + $package = $rootPackage; + + while ($package instanceof AliasPackage) { + $package = $package->getAliasOf(); + } + + return $package; + } + + /** + * @return Generator|string[] + */ + private static function getVersions(Locker $locker, RootPackageInterface $rootPackage) : Generator + { + $lockData = $locker->getLockData(); + + $lockData['packages-dev'] = $lockData['packages-dev'] ?? []; + + foreach (array_merge($lockData['packages'], $lockData['packages-dev']) as $package) { + yield $package['name'] => $package['version'] . '@' . ( + $package['source']['reference']?? $package['dist']['reference'] ?? '' + ); + } + + foreach ($rootPackage->getReplaces() as $replace) { + $version = $replace->getPrettyConstraint(); + if ($version === 'self.version') { + $version = $rootPackage->getPrettyVersion(); + } + + yield $replace->getTarget() => $version . '@' . $rootPackage->getSourceReference(); + } + + yield $rootPackage->getName() => $rootPackage->getPrettyVersion() . '@' . $rootPackage->getSourceReference(); + } +} diff --git a/vendor/ocramius/package-versions/src/PackageVersions/Versions.php b/vendor/ocramius/package-versions/src/PackageVersions/Versions.php new file mode 100644 index 00000000..f3d3af92 --- /dev/null +++ b/vendor/ocramius/package-versions/src/PackageVersions/Versions.php @@ -0,0 +1,55 @@ + '1.3.2@d17708133b6c276d6e42ef887a877866b909d892', + 'jean85/pretty-package-versions' => '1.2@75c7effcf3f77501d0e0caa75111aff4daa0dd48', + 'nette/bootstrap' => 'v2.4.6@268816e3f1bb7426c3a4ceec2bd38a036b532543', + 'nette/di' => 'v2.4.15@d0561b8f77e8ef2ed6d83328860e16c81a5a8649', + 'nette/finder' => 'v2.4.2@ee951a656cb8ac622e5dd33474a01fd2470505a0', + 'nette/neon' => 'v3.0.0@cbff32059cbdd8720deccf9e9eace6ee516f02eb', + 'nette/php-generator' => 'v3.2.1@9de4e093a130f7a1bd175198799ebc0efbac6924', + 'nette/robot-loader' => 'v3.1.0@fc76c70e740b10f091e502b2e393d0be912f38d4', + 'nette/utils' => 'v2.5.3@17b9f76f2abd0c943adfb556e56f2165460b15ce', + 'nikic/php-parser' => 'v4.2.1@5221f49a608808c1e4d436df32884cbc1b821ac0', + 'ocramius/package-versions' => '1.4.0@a4d4b60d0e60da2487bd21a2c6ac089f85570dbb', + 'phpstan/phpdoc-parser' => '0.3.1@2cc49f47c69b023eaf05b48e6529389893b13d74', + 'phpstan/phpstan' => '0.11.2@8e185a74004920419ee97bf9dc62e6a175e8dca5', + 'psr/log' => '1.1.0@6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd', + 'symfony/console' => 'v4.2.3@1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4', + 'symfony/contracts' => 'v1.0.2@1aa7ab2429c3d594dd70689604b5cf7421254cdf', + 'symfony/finder' => 'v4.2.3@ef71816cbb264988bb57fe6a73f610888b9aa70c', + 'symfony/polyfill-mbstring' => 'v1.10.0@c79c051f5b3a46be09205c73b80b346e4153e494', + '__root__' => 'dev-master@e198c4db65320cce173bdde14ef08da5beb5d6d8', +); + + private function __construct() + { + } + + /** + * @throws \OutOfBoundsException If a version cannot be located. + */ + public static function getVersion(string $packageName) : string + { + if (isset(self::VERSIONS[$packageName])) { + return self::VERSIONS[$packageName]; + } + + throw new \OutOfBoundsException( + 'Required package "' . $packageName . '" is not installed: cannot detect its version' + ); + } +} diff --git a/vendor/phpstan/phpdoc-parser/build-abnfgen.sh b/vendor/phpstan/phpdoc-parser/build-abnfgen.sh new file mode 100755 index 00000000..a2911aa2 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/build-abnfgen.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +set -euo pipefail +IFS=$'\n\t' +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +ROOT_DIR="$DIR" + +if [[ ! -d "$ROOT_DIR/tools/abnfgen" ]]; then + rm -rf "$ROOT_DIR/temp/abnfgen" + mkdir -p "$ROOT_DIR/temp/abnfgen" + + wget http://www.quut.com/abnfgen/abnfgen-0.20.tar.gz \ + --output-document "$ROOT_DIR/temp/abnfgen.tar.gz" + + tar xf "$ROOT_DIR/temp/abnfgen.tar.gz" \ + --directory "$ROOT_DIR/temp/abnfgen" \ + --strip-components 1 + + cd "$ROOT_DIR/temp/abnfgen" + ./configure + make + + mkdir -p "$ROOT_DIR/tools/abnfgen" + mv abnfgen "$ROOT_DIR/tools/abnfgen" + rm -rf "$ROOT_DIR/temp/abnfgen" "$ROOT_DIR/temp/abnfgen.tar.gz" +fi diff --git a/vendor/phpstan/phpdoc-parser/composer.json b/vendor/phpstan/phpdoc-parser/composer.json new file mode 100644 index 00000000..9fbf15af --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/composer.json @@ -0,0 +1,28 @@ +{ + "name": "phpstan/phpdoc-parser", + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "license": "MIT", + "require": { + "php": "~7.1" + }, + "require-dev": { + "consistence/coding-standard": "^2.0.0", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/phpstan": "^0.10", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^3.3.0", + "symfony/process": "^3.4 || ^4.0" + }, + "autoload": { + "psr-4": {"PHPStan\\PhpDocParser\\": ["src/"]} + }, + "autoload-dev": { + "psr-4": {"PHPStan\\PhpDocParser\\": ["tests/PHPStan"]} + }, + "extra": { + "branch-alias": { + "dev-master": "0.3-dev" + } + } +} diff --git a/vendor/phpstan/phpdoc-parser/doc/grammars/phpdoc-method.peg b/vendor/phpstan/phpdoc-parser/doc/grammars/phpdoc-method.peg new file mode 100644 index 00000000..f022779a --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/doc/grammars/phpdoc-method.peg @@ -0,0 +1,41 @@ +PhpDocMethod + = AnnotationName IsStatic? MethodReturnType? MethodName MethodParameters? Description? + +AnnotationName + = '@method' + +IsStatic + = 'static' + +MethodReturnType + = Type + +MethodName + = [a-zA-Z_\127-\255][a-zA-Z0-9_\127-\255]* + +MethodParameters + = '(' MethodParametersInner? ')' + +MethodParametersInner + = MethodParameter (',' MethodParameter)* + +MethodParameter + = MethodParameterType? IsReference? IsVariaric? MethodParameterName MethodParameterDefaultValue? + +MethodParameterType + = Type + +IsReference + = '&' + +IsVariaric + = '...' + +MethodParameterName + = '$' [a-zA-Z_\127-\255][a-zA-Z0-9_\127-\255]* + +MethodParameterDefaultValue + = '=' PhpConstantExpr + +Description + = .+ # TODO: exclude EOL or another PhpDocTag start diff --git a/vendor/phpstan/phpdoc-parser/doc/grammars/phpdoc-param.peg b/vendor/phpstan/phpdoc-parser/doc/grammars/phpdoc-param.peg new file mode 100644 index 00000000..5a5c1b34 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/doc/grammars/phpdoc-param.peg @@ -0,0 +1,14 @@ +PhpDocParam + = AnnotationName Type IsVariadic? ParameterName Description? + +AnnotationName + = '@param' + +IsVariaric + = '...' + +ParameterName + = '$' [a-zA-Z_\127-\255][a-zA-Z0-9_\127-\255]* + +Description + = .+ # TODO: exclude EOL or another PhpDocTag start diff --git a/vendor/phpstan/phpdoc-parser/doc/grammars/type.abnf b/vendor/phpstan/phpdoc-parser/doc/grammars/type.abnf new file mode 100644 index 00000000..166f819a --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/doc/grammars/type.abnf @@ -0,0 +1,231 @@ +; ---------------------------------------------------------------------------- ; +; Type ; +; ---------------------------------------------------------------------------- ; + +Type + = Atomic [Union / Intersection] + / Nullable + +Union + = 1*(TokenUnion Atomic) + +Intersection + = 1*(TokenIntersection Atomic) + +Nullable + = TokenNullable TokenIdentifier [Generic] + +Atomic + = TokenIdentifier [Generic / Callable / Array] + / TokenThisVariable + / TokenParenthesesOpen Type TokenParenthesesClose [Array] + +Generic + = TokenAngleBracketOpen Type *(TokenComma Type) TokenAngleBracketClose + +Callable + = TokenParenthesesOpen [CallableParameters] TokenParenthesesClose TokenColon CallableReturnType + +CallableParameters + = CallableParameter *(TokenComma CallableParameter) + +CallableParameter + = Type [CallableParameterIsReference] [CallableParameterIsVariadic] [CallableParameterName] [CallableParameterIsOptional] + +CallableParameterIsReference + = TokenIntersection + +CallableParameterIsVariadic + = TokenVariadic + +CallableParameterName + = TokenVariable + +CallableParameterIsOptional + = TokenEqualSign + +CallableReturnType + = TokenIdentifier [Generic] + / Nullable + / TokenParenthesesOpen Type TokenParenthesesClose + +Array + = 1*(TokenSquareBracketOpen TokenSquareBracketClose) + + +; ---------------------------------------------------------------------------- ; +; ConstantExpr ; +; ---------------------------------------------------------------------------- ; + +ConstantExpr + = ConstantFloat *ByteHorizontalWs + / ConstantInt *ByteHorizontalWs + / ConstantTrue *ByteHorizontalWs + / ConstantFalse *ByteHorizontalWs + / ConstantNull *ByteHorizontalWs + / ConstantString *ByteHorizontalWs + / ConstantArray *ByteHorizontalWs + / ConstantFetch *ByteHorizontalWs + +ConstantFloat + = ["-"] 1*ByteDecDigit "." *ByteDecDigit [ConstantFloatExp] + / ["-"] 1*ByteDecDigit ConstantFloatExp + / ["-"] "." 1*ByteDecDigit [ConstantFloatExp] + +ConstantFloatExp + = "e" ["-"] 1*ByteDecDigit + +ConstantInt + = ["-"] "0b" 1*ByteBinDigit + / ["-"] "0o" 1*ByteOctDigit + / ["-"] "0x" 1*ByteHexDigit + / ["-"] 1*ByteDecDigit + +ConstantTrue + = "true" + +ConstantFalse + = "false" + +ConstantNull + = "null" + +ConstantString + = ByteSingleQuote *(ByteBackslash ByteNotEol / ByteNotEolAndNotBackslashAndNotSingleQuote) ByteSingleQuote + / ByteDoubleQuote *(ByteBackslash ByteNotEol / ByteNotEolAndNotBackslashAndNotDoubleQuote) ByteDoubleQuote + +ConstantArray + = TokenSquareBracketOpen [ConstantArrayItems] TokenSquareBracketClose + / "array" TokenParenthesesOpen [ConstantArrayItems] TokenParenthesesClose + +ConstantArrayItems + = ConstantArrayItem *(TokenComma ConstantArrayItem) [TokenComma] + +ConstantArrayItem + = ConstantExpr [TokenDoubleArrow ConstantExpr] + +ConstantFetch + = TokenIdentifier [TokenDoubleColon ByteIdentifierFirst *ByteIdentifierSecond *ByteHorizontalWs] + + +; ---------------------------------------------------------------------------- ; +; Tokens ; +; ---------------------------------------------------------------------------- ; + +TokenUnion + = "|" *ByteHorizontalWs + +TokenIntersection + = "&" *ByteHorizontalWs + +TokenNullable + = "?" *ByteHorizontalWs + +TokenParenthesesOpen + = "(" *ByteHorizontalWs + +TokenParenthesesClose + = ")" *ByteHorizontalWs + +TokenAngleBracketOpen + = "<" *ByteHorizontalWs + +TokenAngleBracketClose + = ">" *ByteHorizontalWs + +TokenSquareBracketOpen + = "[" *ByteHorizontalWs + +TokenSquareBracketClose + = "]" *ByteHorizontalWs + +TokenComma + = "," *ByteHorizontalWs + +TokenColon + = ":" *ByteHorizontalWs + +TokenVariadic + = "..." *ByteHorizontalWs + +TokenEqualSign + = "=" *ByteHorizontalWs + +TokenVariable + = "$" ByteIdentifierFirst *ByteIdentifierSecond *ByteHorizontalWs + +TokenDoubleArrow + = "=>" *ByteHorizontalWs + +TokenDoubleColon + = "::" *ByteHorizontalWs + +TokenThisVariable + = %x24.74.68.69.73 *ByteHorizontalWs + +TokenIdentifier + = [ByteBackslash] ByteIdentifierFirst *ByteIdentifierSecond *(ByteBackslash ByteIdentifierFirst *ByteIdentifierSecond) *ByteHorizontalWs + + +; ---------------------------------------------------------------------------- ; +; Bytes ; +; ---------------------------------------------------------------------------- ; + +ByteHorizontalWs + = %x09 ; horizontal tab + / %x20 ; space + +ByteBinDigit + = %x30-31 ; 0-1 + +ByteOctDigit + = %x30-37 ; 0-7 + +ByteDecDigit + = %x30-39 ; 0-9 + +ByteHexDigit + = %x30-39 ; 0-9 + / %x41-46 ; A-F + / %x61-66 ; a-f + +ByteIdentifierFirst + = %x41-5A ; A-Z + / %x5F ; _ + / %x61-7A ; a-z + / %x80-FF + +ByteIdentifierSecond + = %x30-39 ; 0-9 + / %x41-5A ; A-Z + / %x5F ; _ + / %x61-7A ; a-z + / %x80-FF + +ByteSingleQuote + = %x27 ; ' + +ByteDoubleQuote + = %x22 ; " + +ByteBackslash + = %x5C ; \ + +ByteNotEol + = %x00-09 ; skip LF + / %x0B-0C ; skip CR + / %x0E-FF + +ByteNotEolAndNotBackslashAndNotSingleQuote + = %x00-09 ; skip LF + / %x0B-0C ; skip CR + / %x0E-26 ; skip single quote + / %x28-5B ; skip backslash + / %x5D-FF + +ByteNotEolAndNotBackslashAndNotDoubleQuote + = %x00-09 ; skip LF + / %x0B-0C ; skip CR + / %x0E-21 ; skip double quote + / %x23-5B ; skip backslash + / %x5D-FF diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayItemNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayItemNode.php new file mode 100644 index 00000000..61bdd75a --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayItemNode.php @@ -0,0 +1,31 @@ +key = $key; + $this->value = $value; + } + + + public function __toString(): string + { + if ($this->key !== null) { + return "{$this->key} => {$this->value}"; + + } else { + return "{$this->value}"; + } + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayNode.php new file mode 100644 index 00000000..215c5a37 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprArrayNode.php @@ -0,0 +1,25 @@ +items = $items; + } + + + public function __toString(): string + { + return '[' . implode(', ', $this->items) . ']'; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFalseNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFalseNode.php new file mode 100644 index 00000000..fae8af1b --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprFalseNode.php @@ -0,0 +1,13 @@ +value = $value; + } + + + public function __toString(): string + { + return $this->value; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprIntegerNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprIntegerNode.php new file mode 100644 index 00000000..949ba5cb --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprIntegerNode.php @@ -0,0 +1,22 @@ +value = $value; + } + + + public function __toString(): string + { + return $this->value; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNode.php new file mode 100644 index 00000000..1859f03e --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprNode.php @@ -0,0 +1,10 @@ +value = $value; + } + + + public function __toString(): string + { + return $this->value; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprTrueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprTrueNode.php new file mode 100644 index 00000000..b0e3c003 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/ConstExpr/ConstExprTrueNode.php @@ -0,0 +1,13 @@ +className = $className; + $this->name = $name; + } + + + public function __toString(): string + { + if ($this->className === '') { + return $this->name; + + } else { + return "{$this->className}::{$this->name}"; + } + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Node.php b/vendor/phpstan/phpdoc-parser/src/Ast/Node.php new file mode 100644 index 00000000..8c4ccb57 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Node.php @@ -0,0 +1,10 @@ +value = $value; + } + + + public function __toString(): string + { + return $this->value; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/InvalidTagValueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/InvalidTagValueNode.php new file mode 100644 index 00000000..150acae5 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/InvalidTagValueNode.php @@ -0,0 +1,26 @@ +value = $value; + $this->exception = $exception; + } + + + public function __toString(): string + { + return $this->value; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php new file mode 100644 index 00000000..ec86e507 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueNode.php @@ -0,0 +1,44 @@ +isStatic = $isStatic; + $this->returnType = $returnType; + $this->methodName = $methodName; + $this->parameters = $parameters; + $this->description = $description; + } + + + public function __toString(): string + { + $static = $this->isStatic ? 'static ' : ''; + $returnType = $this->returnType ? "{$this->returnType} " : ''; + $parameters = implode(', ', $this->parameters); + $description = $this->description !== '' ? " {$this->description}" : ''; + return "{$static}{$returnType}{$this->methodName}({$parameters}){$description}"; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php new file mode 100644 index 00000000..6bcadd77 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/MethodTagValueParameterNode.php @@ -0,0 +1,46 @@ +type = $type; + $this->isReference = $isReference; + $this->isVariadic = $isVariadic; + $this->parameterName = $parameterName; + $this->defaultValue = $defaultValue; + } + + + public function __toString(): string + { + $type = $this->type ? "{$this->type} " : ''; + $isReference = $this->isReference ? '&' : ''; + $isVariadic = $this->isVariadic ? '...' : ''; + $default = $this->defaultValue ? " = {$this->defaultValue}" : ''; + return "{$type}{$isReference}{$isVariadic}{$this->parameterName}{$default}"; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php new file mode 100644 index 00000000..c11cc857 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamTagValueNode.php @@ -0,0 +1,37 @@ +type = $type; + $this->isVariadic = $isVariadic; + $this->parameterName = $parameterName; + $this->description = $description; + } + + + public function __toString(): string + { + $variadic = $this->isVariadic ? '...' : ''; + return trim("{$this->type} {$variadic}{$this->parameterName} {$this->description}"); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php new file mode 100644 index 00000000..6162f92d --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocChildNode.php @@ -0,0 +1,10 @@ +children = $children; + } + + + /** + * @return PhpDocTagNode[] + */ + public function getTags(): array + { + return array_filter($this->children, function (PhpDocChildNode $child): bool { + return $child instanceof PhpDocTagNode; + }); + } + + + /** + * @param string $tagName + * @return PhpDocTagNode[] + */ + public function getTagsByName(string $tagName): array + { + return array_filter($this->getTags(), function (PhpDocTagNode $tag) use ($tagName): bool { + return $tag->name === $tagName; + }); + } + + + /** + * @return VarTagValueNode[] + */ + public function getVarTagValues(): array + { + return array_column( + array_filter($this->getTagsByName('@var'), function (PhpDocTagNode $tag): bool { + return $tag->value instanceof VarTagValueNode; + }), + 'value' + ); + } + + + /** + * @return ParamTagValueNode[] + */ + public function getParamTagValues(): array + { + return array_column( + array_filter($this->getTagsByName('@param'), function (PhpDocTagNode $tag): bool { + return $tag->value instanceof ParamTagValueNode; + }), + 'value' + ); + } + + + /** + * @return ReturnTagValueNode[] + */ + public function getReturnTagValues(): array + { + return array_column( + array_filter($this->getTagsByName('@return'), function (PhpDocTagNode $tag): bool { + return $tag->value instanceof ReturnTagValueNode; + }), + 'value' + ); + } + + + /** + * @return ThrowsTagValueNode[] + */ + public function getThrowsTagValues(): array + { + return array_column( + array_filter($this->getTagsByName('@throws'), function (PhpDocTagNode $tag): bool { + return $tag->value instanceof ThrowsTagValueNode; + }), + 'value' + ); + } + + + /** + * @return PropertyTagValueNode[] + */ + public function getPropertyTagValues(): array + { + return array_column( + array_filter($this->getTagsByName('@property'), function (PhpDocTagNode $tag): bool { + return $tag->value instanceof PropertyTagValueNode; + }), + 'value' + ); + } + + + /** + * @return PropertyTagValueNode[] + */ + public function getPropertyReadTagValues(): array + { + return array_column( + array_filter($this->getTagsByName('@property-read'), function (PhpDocTagNode $tag): bool { + return $tag->value instanceof PropertyTagValueNode; + }), + 'value' + ); + } + + + /** + * @return PropertyTagValueNode[] + */ + public function getPropertyWriteTagValues(): array + { + return array_column( + array_filter($this->getTagsByName('@property-write'), function (PhpDocTagNode $tag): bool { + return $tag->value instanceof PropertyTagValueNode; + }), + 'value' + ); + } + + + /** + * @return MethodTagValueNode[] + */ + public function getMethodTagValues(): array + { + return array_column( + array_filter($this->getTagsByName('@method'), function (PhpDocTagNode $tag): bool { + return $tag->value instanceof MethodTagValueNode; + }), + 'value' + ); + } + + + public function __toString(): string + { + return "/**\n * " . implode("\n * ", $this->children) . '*/'; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagNode.php new file mode 100644 index 00000000..be3043bf --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagNode.php @@ -0,0 +1,26 @@ +name = $name; + $this->value = $value; + } + + + public function __toString(): string + { + return trim("{$this->name} {$this->value}"); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php new file mode 100644 index 00000000..7723fa0c --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PhpDocTagValueNode.php @@ -0,0 +1,10 @@ +text = $text; + } + + + public function __toString(): string + { + return $this->text; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php new file mode 100644 index 00000000..bca55a7e --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/PropertyTagValueNode.php @@ -0,0 +1,32 @@ +type = $type; + $this->propertyName = $propertyName; + $this->description = $description; + } + + + public function __toString(): string + { + return trim("{$this->type} {$this->propertyName} {$this->description}"); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php new file mode 100644 index 00000000..254d3f87 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ReturnTagValueNode.php @@ -0,0 +1,28 @@ +type = $type; + $this->description = $description; + } + + + public function __toString(): string + { + return trim("{$this->type} {$this->description}"); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ThrowsTagValueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ThrowsTagValueNode.php new file mode 100644 index 00000000..32ae12d2 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ThrowsTagValueNode.php @@ -0,0 +1,28 @@ +type = $type; + $this->description = $description; + } + + + public function __toString(): string + { + return trim("{$this->type} {$this->description}"); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/VarTagValueNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/VarTagValueNode.php new file mode 100644 index 00000000..2965ce7c --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/VarTagValueNode.php @@ -0,0 +1,32 @@ +type = $type; + $this->variableName = $variableName; + $this->description = $description; + } + + + public function __toString(): string + { + return trim("$this->type " . trim("{$this->variableName} {$this->description}")); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayTypeNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayTypeNode.php new file mode 100644 index 00000000..b01d083c --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Type/ArrayTypeNode.php @@ -0,0 +1,22 @@ +type = $type; + } + + + public function __toString(): string + { + return $this->type . '[]'; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeNode.php new file mode 100644 index 00000000..2f4bf7c5 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeNode.php @@ -0,0 +1,31 @@ +identifier = $identifier; + $this->parameters = $parameters; + $this->returnType = $returnType; + } + + + public function __toString(): string + { + $parameters = implode(', ', $this->parameters); + return "{$this->identifier}({$parameters}): {$this->returnType}"; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeParameterNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeParameterNode.php new file mode 100644 index 00000000..3503318d --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Type/CallableTypeParameterNode.php @@ -0,0 +1,44 @@ +type = $type; + $this->isReference = $isReference; + $this->isVariadic = $isVariadic; + $this->parameterName = $parameterName; + $this->isOptional = $isOptional; + } + + + public function __toString(): string + { + $type = "{$this->type} "; + $isReference = $this->isReference ? '&' : ''; + $isVariadic = $this->isVariadic ? '...' : ''; + $default = $this->isOptional ? ' = default' : ''; + return "{$type}{$isReference}{$isVariadic}{$this->parameterName}{$default}"; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Type/GenericTypeNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/Type/GenericTypeNode.php new file mode 100644 index 00000000..4dcc9c8f --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Type/GenericTypeNode.php @@ -0,0 +1,26 @@ +type = $type; + $this->genericTypes = $genericTypes; + } + + + public function __toString(): string + { + return $this->type . '<' . implode(', ', $this->genericTypes) . '>'; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Type/IdentifierTypeNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/Type/IdentifierTypeNode.php new file mode 100644 index 00000000..9ca389cc --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Type/IdentifierTypeNode.php @@ -0,0 +1,22 @@ +name = $name; + } + + + public function __toString(): string + { + return $this->name; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Type/IntersectionTypeNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/Type/IntersectionTypeNode.php new file mode 100644 index 00000000..60341187 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Type/IntersectionTypeNode.php @@ -0,0 +1,22 @@ +types = $types; + } + + + public function __toString(): string + { + return '(' . implode(' & ', $this->types) . ')'; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Type/NullableTypeNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/Type/NullableTypeNode.php new file mode 100644 index 00000000..98c73647 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Type/NullableTypeNode.php @@ -0,0 +1,22 @@ +type = $type; + } + + + public function __toString(): string + { + return '?' . $this->type; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Ast/Type/ThisTypeNode.php b/vendor/phpstan/phpdoc-parser/src/Ast/Type/ThisTypeNode.php new file mode 100644 index 00000000..06a3537e --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Ast/Type/ThisTypeNode.php @@ -0,0 +1,13 @@ +types = $types; + } + + + public function __toString(): string + { + return '(' . implode(' | ', $this->types) . ')'; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.php b/vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.php new file mode 100644 index 00000000..f31dbb04 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Lexer/Lexer.php @@ -0,0 +1,158 @@ + '\'&\'', + self::TOKEN_UNION => '\'|\'', + self::TOKEN_INTERSECTION => '\'&\'', + self::TOKEN_NULLABLE => '\'?\'', + self::TOKEN_OPEN_PARENTHESES => '\'(\'', + self::TOKEN_CLOSE_PARENTHESES => '\')\'', + self::TOKEN_OPEN_ANGLE_BRACKET => '\'<\'', + self::TOKEN_CLOSE_ANGLE_BRACKET => '\'>\'', + self::TOKEN_OPEN_SQUARE_BRACKET => '\'[\'', + self::TOKEN_CLOSE_SQUARE_BRACKET => '\']\'', + self::TOKEN_COMMA => '\',\'', + self::TOKEN_COLON => '\':\'', + self::TOKEN_VARIADIC => '\'...\'', + self::TOKEN_DOUBLE_COLON => '\'::\'', + self::TOKEN_DOUBLE_ARROW => '\'=>\'', + self::TOKEN_EQUAL => '\'=\'', + self::TOKEN_OPEN_PHPDOC => '\'/**\'', + self::TOKEN_CLOSE_PHPDOC => '\'*/\'', + self::TOKEN_PHPDOC_TAG => 'TOKEN_PHPDOC_TAG', + self::TOKEN_PHPDOC_EOL => 'TOKEN_PHPDOC_EOL', + self::TOKEN_FLOAT => 'TOKEN_FLOAT', + self::TOKEN_INTEGER => 'TOKEN_INTEGER', + self::TOKEN_SINGLE_QUOTED_STRING => 'TOKEN_SINGLE_QUOTED_STRING', + self::TOKEN_DOUBLE_QUOTED_STRING => 'TOKEN_DOUBLE_QUOTED_STRING', + self::TOKEN_IDENTIFIER => 'TOKEN_IDENTIFIER', + self::TOKEN_THIS_VARIABLE => '\'$this\'', + self::TOKEN_VARIABLE => 'TOKEN_VARIABLE', + self::TOKEN_HORIZONTAL_WS => 'TOKEN_HORIZONTAL_WS', + self::TOKEN_OTHER => 'TOKEN_OTHER', + self::TOKEN_END => 'TOKEN_END', + ]; + + public const VALUE_OFFSET = 0; + public const TYPE_OFFSET = 1; + + /** @var null|string */ + private $regexp; + + /** @var null|int[] */ + private $types; + + public function tokenize(string $s): array + { + if ($this->regexp === null || $this->types === null) { + $this->initialize(); + } + + assert($this->regexp !== null); + assert($this->types !== null); + + preg_match_all($this->regexp, $s, $tokens, PREG_SET_ORDER); + + $count = count($this->types); + foreach ($tokens as &$match) { + for ($i = 1; $i <= $count; $i++) { + if ($match[$i] !== null && $match[$i] !== '') { + $match = [$match[0], $this->types[$i - 1]]; + break; + } + } + } + + $tokens[] = ['', self::TOKEN_END]; + + return $tokens; + } + + + private function initialize() + { + $patterns = [ + // '&' followed by TOKEN_VARIADIC, TOKEN_VARIABLE, TOKEN_EQUAL, TOKEN_EQUAL or TOKEN_CLOSE_PARENTHESES + self::TOKEN_REFERENCE => '&(?=\\s*+(?:[.,=)]|(?:\\$(?!this(?![0-9a-z_\\x80-\\xFF])))))', + self::TOKEN_UNION => '\\|', + self::TOKEN_INTERSECTION => '&', + self::TOKEN_NULLABLE => '\\?', + + self::TOKEN_OPEN_PARENTHESES => '\\(', + self::TOKEN_CLOSE_PARENTHESES => '\\)', + self::TOKEN_OPEN_ANGLE_BRACKET => '<', + self::TOKEN_CLOSE_ANGLE_BRACKET => '>', + self::TOKEN_OPEN_SQUARE_BRACKET => '\\[', + self::TOKEN_CLOSE_SQUARE_BRACKET => '\\]', + + self::TOKEN_COMMA => ',', + self::TOKEN_VARIADIC => '\\.\\.\\.', + self::TOKEN_DOUBLE_COLON => '::', + self::TOKEN_DOUBLE_ARROW => '=>', + self::TOKEN_EQUAL => '=', + self::TOKEN_COLON => ':', + + self::TOKEN_OPEN_PHPDOC => '/\\*\\*(?=\\s)', + self::TOKEN_CLOSE_PHPDOC => '\\*/', + self::TOKEN_PHPDOC_TAG => '@[a-z-]++', + self::TOKEN_PHPDOC_EOL => '\\r?+\\n[\\x09\\x20]*+(?:\\*(?!/))?', + + self::TOKEN_FLOAT => '(?:-?[0-9]++\\.[0-9]*+(?:e-?[0-9]++)?)|(?:-?[0-9]*+\\.[0-9]++(?:e-?[0-9]++)?)|(?:-?[0-9]++e-?[0-9]++)', + self::TOKEN_INTEGER => '-?(?:(?:0b[0-1]++)|(?:0o[0-7]++)|(?:0x[0-9a-f]++)|(?:[0-9]++))', + self::TOKEN_SINGLE_QUOTED_STRING => '\'(?:\\\\[^\\r\\n]|[^\'\\r\\n\\\\])*+\'', + self::TOKEN_DOUBLE_QUOTED_STRING => '"(?:\\\\[^\\r\\n]|[^"\\r\\n\\\\])*+"', + + self::TOKEN_IDENTIFIER => '(?:[\\\\]?+[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF]*+)++', + self::TOKEN_THIS_VARIABLE => '\\$this(?![0-9a-z_\\x80-\\xFF])', + self::TOKEN_VARIABLE => '\\$[a-z_\\x80-\\xFF][0-9a-z_\\x80-\\xFF]*+', + + self::TOKEN_HORIZONTAL_WS => '[\\x09\\x20]++', + + // anything but TOKEN_CLOSE_PHPDOC or TOKEN_HORIZONTAL_WS or TOKEN_EOL + self::TOKEN_OTHER => '(?:(?!\\*/)[^\\s])++', + ]; + + $this->regexp = '~(' . implode(')|(', $patterns) . ')~Asi'; + $this->types = array_keys($patterns); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Parser/ConstExprParser.php b/vendor/phpstan/phpdoc-parser/src/Parser/ConstExprParser.php new file mode 100644 index 00000000..a9dcdbba --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Parser/ConstExprParser.php @@ -0,0 +1,97 @@ +isCurrentTokenType(Lexer::TOKEN_FLOAT)) { + $value = $tokens->currentTokenValue(); + $tokens->next(); + return new Ast\ConstExpr\ConstExprFloatNode($value); + + } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_INTEGER)) { + $value = $tokens->currentTokenValue(); + $tokens->next(); + return new Ast\ConstExpr\ConstExprIntegerNode($value); + + } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_SINGLE_QUOTED_STRING)) { + $value = $tokens->currentTokenValue(); + $tokens->next(); + return new Ast\ConstExpr\ConstExprStringNode($value); + + } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_DOUBLE_QUOTED_STRING)) { + $value = $tokens->currentTokenValue(); + $tokens->next(); + return new Ast\ConstExpr\ConstExprStringNode($value); + + } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) { + $identifier = $tokens->currentTokenValue(); + $tokens->next(); + + switch (strtolower($identifier)) { + case 'true': + return new Ast\ConstExpr\ConstExprTrueNode(); + case 'false': + return new Ast\ConstExpr\ConstExprFalseNode(); + case 'null': + return new Ast\ConstExpr\ConstExprNullNode(); + case 'array': + $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES); + return $this->parseArray($tokens, Lexer::TOKEN_CLOSE_PARENTHESES); + } + + if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_COLON)) { + $classConstantName = $tokens->currentTokenValue(); + $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); + return new Ast\ConstExpr\ConstFetchNode($identifier, $classConstantName); + + } else { + return new Ast\ConstExpr\ConstFetchNode('', $identifier); + } + + } elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { + return $this->parseArray($tokens, Lexer::TOKEN_CLOSE_SQUARE_BRACKET); + } + + throw new \LogicException($tokens->currentTokenValue()); + } + + + private function parseArray(TokenIterator $tokens, int $endToken): Ast\ConstExpr\ConstExprArrayNode + { + $items = []; + + if (!$tokens->tryConsumeTokenType($endToken)) { + do { + $items[] = $this->parseArrayItem($tokens); + } while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA) && !$tokens->isCurrentTokenType($endToken)); + $tokens->consumeTokenType($endToken); + } + + return new Ast\ConstExpr\ConstExprArrayNode($items); + } + + + private function parseArrayItem(TokenIterator $tokens): Ast\ConstExpr\ConstExprArrayItemNode + { + $expr = $this->parse($tokens); + + if ($tokens->tryConsumeTokenType(Lexer::TOKEN_DOUBLE_ARROW)) { + $key = $expr; + $value = $this->parse($tokens); + + } else { + $key = null; + $value = $expr; + } + + return new Ast\ConstExpr\ConstExprArrayItemNode($key, $value); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Parser/ParserException.php b/vendor/phpstan/phpdoc-parser/src/Parser/ParserException.php new file mode 100644 index 00000000..d6fd6feb --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Parser/ParserException.php @@ -0,0 +1,69 @@ +currentTokenValue = $currentTokenValue; + $this->currentTokenType = $currentTokenType; + $this->currentOffset = $currentOffset; + $this->expectedTokenType = $expectedTokenType; + + $json = json_encode($currentTokenValue, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + assert($json !== false); + + parent::__construct(sprintf( + 'Unexpected token %s, expected %s at offset %d', + $json, + Lexer::TOKEN_LABELS[$expectedTokenType], + $currentOffset + )); + } + + + public function getCurrentTokenValue(): string + { + return $this->currentTokenValue; + } + + + public function getCurrentTokenType(): int + { + return $this->currentTokenType; + } + + + public function getCurrentOffset(): int + { + return $this->currentOffset; + } + + + public function getExpectedTokenType(): int + { + return $this->expectedTokenType; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Parser/PhpDocParser.php b/vendor/phpstan/phpdoc-parser/src/Parser/PhpDocParser.php new file mode 100644 index 00000000..e5370a5a --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Parser/PhpDocParser.php @@ -0,0 +1,273 @@ +typeParser = $typeParser; + $this->constantExprParser = $constantExprParser; + } + + + public function parse(TokenIterator $tokens): Ast\PhpDoc\PhpDocNode + { + $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PHPDOC); + $tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL); + + $children = []; + + if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) { + $children[] = $this->parseChild($tokens); + while ($tokens->tryConsumeTokenType(Lexer::TOKEN_PHPDOC_EOL) && !$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PHPDOC)) { + $children[] = $this->parseChild($tokens); + } + } + + $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PHPDOC); + + return new Ast\PhpDoc\PhpDocNode(array_values($children)); + } + + + private function parseChild(TokenIterator $tokens): Ast\PhpDoc\PhpDocChildNode + { + if ($tokens->isCurrentTokenType(Lexer::TOKEN_PHPDOC_TAG)) { + return $this->parseTag($tokens); + + } else { + return $this->parseText($tokens); + } + } + + + private function parseText(TokenIterator $tokens): Ast\PhpDoc\PhpDocTextNode + { + $text = $tokens->joinUntil(Lexer::TOKEN_PHPDOC_EOL, Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END); + $text = rtrim($text, " \t"); // the trimmed characters MUST match Lexer::TOKEN_HORIZONTAL_WS + + return new Ast\PhpDoc\PhpDocTextNode($text); + } + + + public function parseTag(TokenIterator $tokens): Ast\PhpDoc\PhpDocTagNode + { + $tag = $tokens->currentTokenValue(); + $tokens->next(); + $value = $this->parseTagValue($tokens, $tag); + + return new Ast\PhpDoc\PhpDocTagNode($tag, $value); + } + + + public function parseTagValue(TokenIterator $tokens, string $tag): Ast\PhpDoc\PhpDocTagValueNode + { + try { + $tokens->pushSavePoint(); + + switch ($tag) { + case '@param': + $tagValue = $this->parseParamTagValue($tokens); + break; + + case '@var': + $tagValue = $this->parseVarTagValue($tokens); + break; + + case '@return': + $tagValue = $this->parseReturnTagValue($tokens); + break; + + case '@throws': + $tagValue = $this->parseThrowsTagValue($tokens); + break; + + case '@property': + case '@property-read': + case '@property-write': + $tagValue = $this->parsePropertyTagValue($tokens); + break; + + case '@method': + $tagValue = $this->parseMethodTagValue($tokens); + break; + + default: + $tagValue = new Ast\PhpDoc\GenericTagValueNode($this->parseOptionalDescription($tokens)); + break; + } + + $tokens->dropSavePoint(); + + } catch (\PHPStan\PhpDocParser\Parser\ParserException $e) { + $tokens->rollback(); + $tagValue = new Ast\PhpDoc\InvalidTagValueNode($this->parseOptionalDescription($tokens), $e); + } + + return $tagValue; + } + + + private function parseParamTagValue(TokenIterator $tokens): Ast\PhpDoc\ParamTagValueNode + { + $type = $this->typeParser->parse($tokens); + $isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC); + $parameterName = $this->parseRequiredVariableName($tokens); + $description = $this->parseOptionalDescription($tokens); + return new Ast\PhpDoc\ParamTagValueNode($type, $isVariadic, $parameterName, $description); + } + + + private function parseVarTagValue(TokenIterator $tokens): Ast\PhpDoc\VarTagValueNode + { + $type = $this->typeParser->parse($tokens); + $variableName = $this->parseOptionalVariableName($tokens); + $description = $this->parseOptionalDescription($tokens, $variableName === ''); + return new Ast\PhpDoc\VarTagValueNode($type, $variableName, $description); + } + + + private function parseReturnTagValue(TokenIterator $tokens): Ast\PhpDoc\ReturnTagValueNode + { + $type = $this->typeParser->parse($tokens); + $description = $this->parseOptionalDescription($tokens, true); + return new Ast\PhpDoc\ReturnTagValueNode($type, $description); + } + + + private function parseThrowsTagValue(TokenIterator $tokens): Ast\PhpDoc\ThrowsTagValueNode + { + $type = $this->typeParser->parse($tokens); + $description = $this->parseOptionalDescription($tokens, true); + return new Ast\PhpDoc\ThrowsTagValueNode($type, $description); + } + + + private function parsePropertyTagValue(TokenIterator $tokens): Ast\PhpDoc\PropertyTagValueNode + { + $type = $this->typeParser->parse($tokens); + $parameterName = $this->parseRequiredVariableName($tokens); + $description = $this->parseOptionalDescription($tokens); + return new Ast\PhpDoc\PropertyTagValueNode($type, $parameterName, $description); + } + + + private function parseMethodTagValue(TokenIterator $tokens): Ast\PhpDoc\MethodTagValueNode + { + $isStatic = $tokens->tryConsumeTokenValue('static'); + $returnTypeOrMethodName = $this->typeParser->parse($tokens); + + if ($tokens->isCurrentTokenType(Lexer::TOKEN_IDENTIFIER)) { + $returnType = $returnTypeOrMethodName; + $methodName = $tokens->currentTokenValue(); + $tokens->next(); + + } elseif ($returnTypeOrMethodName instanceof Ast\Type\IdentifierTypeNode) { + $returnType = $isStatic ? new Ast\Type\IdentifierTypeNode('static') : null; + $methodName = $returnTypeOrMethodName->name; + $isStatic = false; + + } else { + $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); // will throw exception + exit; + } + + $parameters = []; + $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES); + if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) { + $parameters[] = $this->parseMethodTagValueParameter($tokens); + while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { + $parameters[] = $this->parseMethodTagValueParameter($tokens); + } + } + $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); + + $description = $this->parseOptionalDescription($tokens); + return new Ast\PhpDoc\MethodTagValueNode($isStatic, $returnType, $methodName, $parameters, $description); + } + + + private function parseMethodTagValueParameter(TokenIterator $tokens): Ast\PhpDoc\MethodTagValueParameterNode + { + switch ($tokens->currentTokenType()) { + case Lexer::TOKEN_IDENTIFIER: + case Lexer::TOKEN_OPEN_PARENTHESES: + case Lexer::TOKEN_NULLABLE: + $parameterType = $this->typeParser->parse($tokens); + break; + + default: + $parameterType = null; + } + + $isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE); + $isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC); + + $parameterName = $tokens->currentTokenValue(); + $tokens->consumeTokenType(Lexer::TOKEN_VARIABLE); + + if ($tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL)) { + $defaultValue = $this->constantExprParser->parse($tokens); + + } else { + $defaultValue = null; + } + + return new Ast\PhpDoc\MethodTagValueParameterNode($parameterType, $isReference, $isVariadic, $parameterName, $defaultValue); + } + + + private function parseOptionalVariableName(TokenIterator $tokens): string + { + if ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) { + $parameterName = $tokens->currentTokenValue(); + $tokens->next(); + + } else { + $parameterName = ''; + } + + return $parameterName; + } + + + private function parseRequiredVariableName(TokenIterator $tokens): string + { + $parameterName = $tokens->currentTokenValue(); + $tokens->consumeTokenType(Lexer::TOKEN_VARIABLE); + + return $parameterName; + } + + + private function parseOptionalDescription(TokenIterator $tokens, bool $limitStartToken = false): string + { + if ($limitStartToken) { + foreach (self::DISALLOWED_DESCRIPTION_START_TOKENS as $disallowedStartToken) { + if ($tokens->isCurrentTokenType($disallowedStartToken)) { + $tokens->consumeTokenType(Lexer::TOKEN_OTHER); // will throw exception + } + } + } + + return $this->parseText($tokens)->text; + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Parser/TokenIterator.php b/vendor/phpstan/phpdoc-parser/src/Parser/TokenIterator.php new file mode 100644 index 00000000..5b3bfbd5 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Parser/TokenIterator.php @@ -0,0 +1,179 @@ +tokens = $tokens; + $this->index = $index; + + if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) { + $this->index++; + } + } + + + public function currentTokenValue(): string + { + return $this->tokens[$this->index][Lexer::VALUE_OFFSET]; + } + + + public function currentTokenType(): int + { + return $this->tokens[$this->index][Lexer::TYPE_OFFSET]; + } + + + public function currentTokenOffset(): int + { + $offset = 0; + for ($i = 0; $i < $this->index; $i++) { + $offset += strlen($this->tokens[$i][Lexer::VALUE_OFFSET]); + } + + return $offset; + } + + + public function isCurrentTokenValue(string $tokenValue): bool + { + return $this->tokens[$this->index][Lexer::VALUE_OFFSET] === $tokenValue; + } + + + public function isCurrentTokenType(int $tokenType): bool + { + return $this->tokens[$this->index][Lexer::TYPE_OFFSET] === $tokenType; + } + + + /** + * @param int $tokenType + * @throws \PHPStan\PhpDocParser\Parser\ParserException + */ + public function consumeTokenType(int $tokenType) + { + if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== $tokenType) { + $this->throwError($tokenType); + } + + $this->index++; + + if (($this->tokens[$this->index][Lexer::TYPE_OFFSET] ?? -1) === Lexer::TOKEN_HORIZONTAL_WS) { + $this->index++; + } + } + + + public function tryConsumeTokenValue(string $tokenValue): bool + { + if ($this->tokens[$this->index][Lexer::VALUE_OFFSET] !== $tokenValue) { + return false; + } + + $this->index++; + + if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) { + $this->index++; + } + + return true; + } + + + public function tryConsumeTokenType(int $tokenType): bool + { + if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] !== $tokenType) { + return false; + } + + $this->index++; + + if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) { + $this->index++; + } + + return true; + } + + + public function getSkippedHorizontalWhiteSpaceIfAny(): string + { + if ($this->tokens[$this->index - 1][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) { + return $this->tokens[$this->index - 1][Lexer::VALUE_OFFSET]; + } + + return ''; + } + + + public function joinUntil(int ...$tokenType): string + { + $s = ''; + while (!in_array($this->tokens[$this->index][Lexer::TYPE_OFFSET], $tokenType, true)) { + $s .= $this->tokens[$this->index++][Lexer::VALUE_OFFSET]; + } + return $s; + } + + + public function next() + { + $this->index++; + + if ($this->tokens[$this->index][Lexer::TYPE_OFFSET] === Lexer::TOKEN_HORIZONTAL_WS) { + $this->index++; + } + } + + + public function pushSavePoint() + { + $this->savePoints[] = $this->index; + } + + + public function dropSavePoint() + { + array_pop($this->savePoints); + } + + + public function rollback() + { + $index = array_pop($this->savePoints); + assert($index !== null); + $this->index = $index; + } + + + /** + * @param int $expectedTokenType + * @throws \PHPStan\PhpDocParser\Parser\ParserException + */ + private function throwError(int $expectedTokenType) + { + throw new \PHPStan\PhpDocParser\Parser\ParserException( + $this->currentTokenValue(), + $this->currentTokenType(), + $this->currentTokenOffset(), + $expectedTokenType + ); + } + +} diff --git a/vendor/phpstan/phpdoc-parser/src/Parser/TypeParser.php b/vendor/phpstan/phpdoc-parser/src/Parser/TypeParser.php new file mode 100644 index 00000000..596a0d52 --- /dev/null +++ b/vendor/phpstan/phpdoc-parser/src/Parser/TypeParser.php @@ -0,0 +1,211 @@ +isCurrentTokenType(Lexer::TOKEN_NULLABLE)) { + $type = $this->parseNullable($tokens); + + } else { + $type = $this->parseAtomic($tokens); + + if ($tokens->isCurrentTokenType(Lexer::TOKEN_UNION)) { + $type = $this->parseUnion($tokens, $type); + + } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_INTERSECTION)) { + $type = $this->parseIntersection($tokens, $type); + } + } + + return $type; + } + + + private function parseAtomic(TokenIterator $tokens): Ast\Type\TypeNode + { + if ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { + $type = $this->parse($tokens); + $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); + + if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { + $type = $this->tryParseArray($tokens, $type); + } + + } elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_THIS_VARIABLE)) { + return new Ast\Type\ThisTypeNode(); + + } else { + $type = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue()); + $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); + + if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) { + $type = $this->parseGeneric($tokens, $type); + + } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { + $type = $this->tryParseCallable($tokens, $type); + + } elseif ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { + $type = $this->tryParseArray($tokens, $type); + } + } + + return $type; + } + + + private function parseUnion(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode + { + $types = [$type]; + + while ($tokens->tryConsumeTokenType(Lexer::TOKEN_UNION)) { + $types[] = $this->parseAtomic($tokens); + } + + return new Ast\Type\UnionTypeNode($types); + } + + + private function parseIntersection(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode + { + $types = [$type]; + + while ($tokens->tryConsumeTokenType(Lexer::TOKEN_INTERSECTION)) { + $types[] = $this->parseAtomic($tokens); + } + + return new Ast\Type\IntersectionTypeNode($types); + } + + + private function parseNullable(TokenIterator $tokens): Ast\Type\TypeNode + { + $tokens->consumeTokenType(Lexer::TOKEN_NULLABLE); + + $type = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue()); + $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); + + if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) { + $type = $this->parseGeneric($tokens, $type); + } + + return new Ast\Type\NullableTypeNode($type); + } + + + private function parseGeneric(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $baseType): Ast\Type\TypeNode + { + $tokens->consumeTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET); + $genericTypes[] = $this->parse($tokens); + + while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { + $genericTypes[] = $this->parse($tokens); + } + + $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_ANGLE_BRACKET); + return new Ast\Type\GenericTypeNode($baseType, $genericTypes); + } + + + private function parseCallable(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $identifier): Ast\Type\TypeNode + { + $tokens->consumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES); + + $parameters = []; + if (!$tokens->isCurrentTokenType(Lexer::TOKEN_CLOSE_PARENTHESES)) { + $parameters[] = $this->parseCallableParameter($tokens); + while ($tokens->tryConsumeTokenType(Lexer::TOKEN_COMMA)) { + $parameters[] = $this->parseCallableParameter($tokens); + } + } + + $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); + $tokens->consumeTokenType(Lexer::TOKEN_COLON); + $returnType = $this->parseCallableReturnType($tokens); + + return new Ast\Type\CallableTypeNode($identifier, $parameters, $returnType); + } + + + private function parseCallableParameter(TokenIterator $tokens): Ast\Type\CallableTypeParameterNode + { + $type = $this->parse($tokens); + $isReference = $tokens->tryConsumeTokenType(Lexer::TOKEN_REFERENCE); + $isVariadic = $tokens->tryConsumeTokenType(Lexer::TOKEN_VARIADIC); + + if ($tokens->isCurrentTokenType(Lexer::TOKEN_VARIABLE)) { + $parameterName = $tokens->currentTokenValue(); + $tokens->consumeTokenType(Lexer::TOKEN_VARIABLE); + + } else { + $parameterName = ''; + } + + $isOptional = $tokens->tryConsumeTokenType(Lexer::TOKEN_EQUAL); + return new Ast\Type\CallableTypeParameterNode($type, $isReference, $isVariadic, $parameterName, $isOptional); + } + + + private function parseCallableReturnType(TokenIterator $tokens): Ast\Type\TypeNode + { + if ($tokens->isCurrentTokenType(Lexer::TOKEN_NULLABLE)) { + $type = $this->parseNullable($tokens); + + } elseif ($tokens->tryConsumeTokenType(Lexer::TOKEN_OPEN_PARENTHESES)) { + $type = $this->parse($tokens); + $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_PARENTHESES); + + } else { + $type = new Ast\Type\IdentifierTypeNode($tokens->currentTokenValue()); + $tokens->consumeTokenType(Lexer::TOKEN_IDENTIFIER); + + if ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_ANGLE_BRACKET)) { + $type = $this->parseGeneric($tokens, $type); + } + } + + return $type; + } + + + private function tryParseCallable(TokenIterator $tokens, Ast\Type\IdentifierTypeNode $identifier): Ast\Type\TypeNode + { + try { + $tokens->pushSavePoint(); + $type = $this->parseCallable($tokens, $identifier); + $tokens->dropSavePoint(); + + } catch (\PHPStan\PhpDocParser\Parser\ParserException $e) { + $tokens->rollback(); + $type = $identifier; + } + + return $type; + } + + + private function tryParseArray(TokenIterator $tokens, Ast\Type\TypeNode $type): Ast\Type\TypeNode + { + try { + while ($tokens->isCurrentTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET)) { + $tokens->pushSavePoint(); + $tokens->consumeTokenType(Lexer::TOKEN_OPEN_SQUARE_BRACKET); + $tokens->consumeTokenType(Lexer::TOKEN_CLOSE_SQUARE_BRACKET); + $tokens->dropSavePoint(); + $type = new Ast\Type\ArrayTypeNode($type); + } + + } catch (\PHPStan\PhpDocParser\Parser\ParserException $e) { + $tokens->rollback(); + } + + return $type; + } + +} diff --git a/vendor/phpstan/phpstan/.editorconfig b/vendor/phpstan/phpstan/.editorconfig new file mode 100644 index 00000000..5d66bc42 --- /dev/null +++ b/vendor/phpstan/phpstan/.editorconfig @@ -0,0 +1,27 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +trim_trailing_whitespace = true + +[*.{php,phpt}] +indent_style = tab +indent_size = 4 + +[*.xml] +indent_style = tab +indent_size = 4 + +[*.neon] +indent_style = tab +indent_size = 4 + +[*.{yaml,yml}] +indent_style = space +indent_size = 2 + +[composer.json] +indent_style = tab +indent_size = 4 diff --git a/vendor/phpstan/phpstan/.gitattributes b/vendor/phpstan/phpstan/.gitattributes new file mode 100644 index 00000000..0c772b6f --- /dev/null +++ b/vendor/phpstan/phpstan/.gitattributes @@ -0,0 +1,2 @@ +/build export-ignore +/tests export-ignore diff --git a/vendor/phpstan/phpstan/.github/ISSUE_TEMPLATE.md b/vendor/phpstan/phpstan/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..eae05601 --- /dev/null +++ b/vendor/phpstan/phpstan/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,15 @@ + + +### Summary of a problem or a feature request + + + + +### Code snippet that reproduces the problem + + + + +### Expected output + + diff --git a/vendor/phpstan/phpstan/.travis.yml b/vendor/phpstan/phpstan/.travis.yml new file mode 100644 index 00000000..b348a0f4 --- /dev/null +++ b/vendor/phpstan/phpstan/.travis.yml @@ -0,0 +1,61 @@ +dist: xenial +language: php + +stages: + - test + - name: phar-test + if: branch = master && type = push + - name: phar-push + if: branch = master && type = push + +php: + - 7.1 + - 7.2 + - 7.3 + - master + +env: + matrix: + - dependencies=lowest + - dependencies=highest + global: + secure: Wxs9IuFkyacKk/Cu4qxFkkSldob6AhJtx3MDS6Nehz/VF4M88awmI/GcVzfcXjFIA2+EJlkA+X0ymxP9xY5sp+vvmF4mkBIOvSvQdIOLsy73Ixpji3nqc8+epuvtBUGA4Y2xlLmBxSPYZlpVc/DRR2mIlzqDfOQc+gUmJ1aOZPUvs533cl4k0V23hU7L3LxgAnNY7j5vfNgYUhLqBHnqZ0yHt+m0x56wTOBHIBXH+LVNdgsl07fZnuC9HBb3lZKhtCtJiMyC0SsFQLljESaedTHRzptcOuvO+3dmt9R+AP/WxbdmleBaozCrwpdCK3Lqwrt9DXkxtn9ERjtVg0uT2KV5Mm5y4W0w9EXzX/8iUexlJaYOP7OYBtaV0R65w+oiC9dupKiFFvQtJkWcMg+4FCqEjNVM/smXin7+4dLgXiioLtqbjyQQqVwy/U+UmkQ5KIcWjJZGWkL79j1z1e29esNudieXqrX/yvGUW7Ng+4U3G2IHdWH3nMmjwx5/oBuOlc+6vu5aXdDRZVE12CJZ2X/uyJW2Ls5YLJsThAJ9roxsZ29MNZRihUOGk2lLDy/Q5TS6VcsaUmRaZHngM7Xt7v7pJLLbPIomgqGshPKxEXFO3vowZ7nXT1gJX0/FaBBqOahW0scGnxfZlJRZPWbvTg8gxhIGRxhNNYaX5Bb2hw8= +matrix: + allow_failures: + - php: master + +before_script: + - if php --ri xdebug >/dev/null; then phpenv config-rm xdebug.ini; fi + +install: + - if [ "$dependencies" = "lowest" ]; then composer update --prefer-lowest --no-interaction; fi + - if [ "$dependencies" = "highest" ]; then composer update --no-interaction; fi + +script: + - vendor/bin/phing + +jobs: + include: + - stage: phar-test + script: + - git clone https://github.com/phpstan/phpstan-compiler && cd phpstan-compiler && ./run-e2e-tests.sh $TRAVIS_COMMIT + - stage: phar-push + script: + - | + git clone https://github.com/phpstan/phpstan-compiler && \ + composer install --working-dir=phpstan-compiler && \ + php phpstan-compiler/bin/compile $TRAVIS_COMMIT && \ + git clone https://${GITHUB_TOKEN}@github.com/phpstan/phpstan-shim.git > /dev/null 2>&1 && \ + cp phpstan-compiler/tmp/phpstan.phar phpstan-shim/phpstan.phar && \ + cp phpstan-compiler/tmp/phpstan.phar phpstan-shim/phpstan && \ + cd phpstan-shim && \ + git config user.email "travis@travis-ci.org" && \ + git config user.name "Travis CI" && \ + git add phpstan phpstan.phar && \ + git commit -m "Updated PHPStan to commit ${TRAVIS_COMMIT}" && \ + git push --quiet origin master + +cache: + directories: + - $HOME/.composer/cache + - tmp diff --git a/vendor/phpstan/phpstan/BACKERS.md b/vendor/phpstan/phpstan/BACKERS.md new file mode 100644 index 00000000..af769e2d --- /dev/null +++ b/vendor/phpstan/phpstan/BACKERS.md @@ -0,0 +1,65 @@ +# Backers + +Development of PHPStan is made possible thanks to these awesome backers! +You can become one of them by [pledging on Patreon](https://www.patreon.com/phpstan). + +Check out all the tiers - higher ones include additional goodies like placing +the logo of your company in PHPStan's README. + +# $50+ + +* MessageBird + +# $10+ + +* Adam Lundrigan +* Scott Arciszewski + +# $5+ + +* Adam Žurek +* Bart Reunes +* Carlos C Soto +* Craig Mayhew +* David Šolc +* Dennis Haarbrink +* Haralan Dobrev +* Ilija Tovilo +* Jake B +* Jakub Chábek +* Jakub Červený +* Jan Endel +* Jan Kuchař +* Lars Roettig +* Lukas Unger +* Masaru Yamagishi +* Michael Moll +* Pavel Vondrášek +* René Kliment +* Rudolph Gottesheim +* seagoj +* Stefan Zielke +* Thomas Daugaard +* Tomasz +* Tommy Muehle +* Vašek Brychta +* Woda Digital + +# $1+ + +* Andrew Barlow +* Broken Bialek +* Christian Sjöström +* Craig Duncan +* Honza Cerny +* Ian Den Hartog +* Ivan Kvasnica +* korchasa +* Lucas Dos Santos Abreu +* Martin Lukeš +* Matej Drame +* Michal Mleczko +* Michał Włodarczyk +* Oliver Klee +* Ondrej Vodacek +* Wouter Admiraal diff --git a/vendor/phpstan/phpstan/CODE_OF_CONDUCT.md b/vendor/phpstan/phpstan/CODE_OF_CONDUCT.md new file mode 100644 index 00000000..162e250c --- /dev/null +++ b/vendor/phpstan/phpstan/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project maintainer at . All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/vendor/phpstan/phpstan/LICENSE b/vendor/phpstan/phpstan/LICENSE new file mode 100644 index 00000000..7c0f2b7b --- /dev/null +++ b/vendor/phpstan/phpstan/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Ondřej Mirtes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/phpstan/phpstan/README.md b/vendor/phpstan/phpstan/README.md new file mode 100644 index 00000000..6de8f5e7 --- /dev/null +++ b/vendor/phpstan/phpstan/README.md @@ -0,0 +1,714 @@ +

PHPStan - PHP Static Analysis Tool

+ +

+ PHPStan +

+ +

+ Build Status + Latest Stable Version + Total Downloads + License + PHPStan Enabled +

+ +------ + +PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs +even before you write tests for the code. It moves PHP closer to compiled languages in the sense that the correctness of each line of the code +can be checked before you run the actual line. + +**[Read more about PHPStan on Medium.com »](https://medium.com/@ondrejmirtes/phpstan-2939cd0ad0e3)** + +**[Try out PHPStan on the on-line playground! »](https://phpstan.org/)** + +## Sponsors + +Mike Pretzlaw +    +TheCodingMachine +    + + +Check out [PHPStan's Patreon](https://www.patreon.com/phpstan) for sponsoring options. One-time donations [through PayPal](https://paypal.me/phpstan) are also accepted. To request an invoice, [contact me](mailto:ondrej@mirtes.cz) through e-mail. + +## Prerequisites + +PHPStan requires PHP >= 7.1. You have to run it in environment with PHP 7.x but the actual code does not have to use +PHP 7.x features. (Code written for PHP 5.6 and earlier can run on 7.x mostly unmodified.) + +PHPStan works best with modern object-oriented code. The more strongly-typed your code is, the more information +you give PHPStan to work with. + +Properly annotated and typehinted code (class properties, function and method arguments, return types) helps +not only static analysis tools but also other people that work with the code to understand it. + +## Installation + +To start performing analysis on your code, require PHPStan in [Composer](https://getcomposer.org/): + +``` +composer require --dev phpstan/phpstan +``` + +Composer will install PHPStan's executable in its `bin-dir` which defaults to `vendor/bin`. + +If you have conflicting dependencies or you want to install PHPStan globally, the best way is via a PHAR archive. You will always find the latest stable PHAR archive below the [release notes](https://github.com/phpstan/phpstan/releases). You can also use the [phpstan/phpstan-shim](https://packagist.org/packages/phpstan/phpstan-shim) package to install PHPStan via Composer without the risk of conflicting dependencies. + +You can also use [PHPStan via Docker](https://github.com/phpstan/docker-image). + +## First run + +To let PHPStan analyse your codebase, you have to use the `analyse` command and point it to the right directories. + +So, for example if you have your classes in directories `src` and `tests`, you can run PHPStan like this: + +```bash +vendor/bin/phpstan analyse src tests +``` + +PHPStan will probably find some errors, but don't worry, your code might be just fine. Errors found +on the first run tend to be: + +* Extra arguments passed to functions (e. g. function requires two arguments, the code passes three) +* Extra arguments passed to print/sprintf functions (e. g. format string contains one placeholder, the code passes two values to replace) +* Obvious errors in dead code +* Magic behaviour that needs to be defined. See [Extensibility](#extensibility). + +After fixing the obvious mistakes in the code, look to the following section +for all the configuration options that will bring the number of reported errors to zero +making PHPStan suitable to run as part of your continuous integration script. + +## Rule levels + +If you want to use PHPStan but your codebase isn't up to speed with strong typing +and PHPStan's strict checks, you can choose from currently 8 levels +(0 is the loosest and 7 is the strictest) by passing `--level` to `analyse` command. Default level is `0`. + +This feature enables incremental adoption of PHPStan checks. You can start using PHPStan +with a lower rule level and increase it when you feel like it. + +You can also use `--level max` as an alias for the highest level. This will ensure that you will always use the highest level when upgrading to new versions of PHPStan. Please note that this can create a significant obstacle when upgrading to a newer version because you might have to fix a lot of code to bring the number of errors down to zero. + +## Extensibility + +Unique feature of PHPStan is the ability to define and statically check "magic" behaviour of classes - +accessing properties that are not defined in the class but are created in `__get` and `__set` +and invoking methods using `__call`. + +See [Class reflection extensions](#class-reflection-extensions), [Dynamic return type extensions](#dynamic-return-type-extensions) and [Type-specifying extensions](#type-specifying-extensions). + +You can also install official framework-specific extensions: + +* [Doctrine](https://github.com/phpstan/phpstan-doctrine) +* [PHPUnit](https://github.com/phpstan/phpstan-phpunit) +* [Nette Framework](https://github.com/phpstan/phpstan-nette) +* [Dibi - Database Abstraction Library](https://github.com/phpstan/phpstan-dibi) +* [PHP-Parser](https://github.com/phpstan/phpstan-php-parser) +* [beberlei/assert](https://github.com/phpstan/phpstan-beberlei-assert) +* [webmozart/assert](https://github.com/phpstan/phpstan-webmozart-assert) +* [Symfony Framework](https://github.com/phpstan/phpstan-symfony) +* [Mockery](https://github.com/phpstan/phpstan-mockery) + +Unofficial extensions for other frameworks and libraries are also available: + +* [Phony](https://github.com/eloquent/phpstan-phony) +* [Prophecy](https://github.com/Jan0707/phpstan-prophecy) +* [Laravel](https://github.com/nunomaduro/larastan) +* [myclabs/php-enum](https://github.com/timeweb/phpstan-enum) +* [Yii2](https://github.com/proget-hq/phpstan-yii2) +* [PhpSpec](https://github.com/proget-hq/phpstan-phpspec) +* [TYPO3](https://github.com/sascha-egerer/phpstan-typo3) + +New extensions are becoming available on a regular basis! + +## Configuration + +Config file is passed to the `phpstan` executable with `-c` option: + +```bash +vendor/bin/phpstan analyse -l 4 -c phpstan.neon src tests +``` + +When using a custom project config file, you have to pass the `--level` (`-l`) +option to `analyse` command (default value does not apply here). + +If you do not provide config file explicitly, PHPStan will look for +files named `phpstan.neon` or `phpstan.neon.dist` in current directory. + +The resolution priority is as such: +1. If config file is provided on command line, it is used. +2. If config file `phpstan.neon` exists in current directory, it will be used. +3. If config file `phpstan.neon.dist` exists in current directory, it will be used. +4. If none of the above is true, no config will be used. + +[NEON file format](https://ne-on.org/) is very similar to YAML. +All the following options are part of the `parameters` section. + +#### Configuration variables + - `%rootDir%` - root directory where PHPStan resides (i.e. `vendor/phpstan/phpstan` in Composer installation) + - `%currentWorkingDirectory%` - current working directory where PHPStan was executed + +#### Configuration options + + - `tmpDir` - specifies the temporary directory used by PHPStan cache (defaults to `sys_get_temp_dir() . '/phpstan'`) + - `level` - specifies analysis level - if specified, `-l` option is not required + - `paths` - specifies analysed paths - if specified, paths are not required to be passed as arguments + +### Autoloading + +PHPStan uses Composer autoloader so the easiest way how to autoload classes +is through the `autoload`/`autoload-dev` sections in composer.json. + +#### Specify paths to scan + +If PHPStan complains about some non-existent classes and you're sure the classes +exist in the codebase AND you don't want to use Composer autoloader for some reason, +you can specify directories to scan and concrete files to include using +`autoload_directories` and `autoload_files` array parameters: + +``` +parameters: + autoload_directories: + - %rootDir%/../../../build + autoload_files: + - %rootDir%/../../../generated/routes/GeneratedRouteList.php +``` + +`%rootDir%` is expanded to the root directory where PHPStan resides. + +#### Autoloading for global installation + +PHPStan supports global installation using [`composer global`](https://getcomposer.org/doc/03-cli.md#global) or via a [PHAR archive](#installation). +In this case, it's not part of the project autoloader, but it supports autodiscovery of the Composer autoloader +from current working directory residing in `vendor/`: + +```bash +cd /path/to/project +phpstan analyse src tests # looks for autoloader at /path/to/project/vendor/autoload.php +``` + +If you have your dependencies installed at a different path +or you're running PHPStan from a different directory, +you can specify the path to the autoloader with the `--autoload-file|-a` option: + +```bash +phpstan analyse --autoload-file=/path/to/autoload.php src tests +``` + +### Exclude files from analysis + +If your codebase contains some files that are broken on purpose +(e. g. to test behaviour of your application on files with invalid PHP code), +you can exclude them using the `excludes_analyse` array parameter. String at each line +is used as a pattern for the [`fnmatch`](https://secure.php.net/manual/en/function.fnmatch.php) function. + +``` +parameters: + excludes_analyse: + - %rootDir%/../../../tests/*/data/* +``` + +### Include custom extensions + +If your codebase contains php files with extensions other than the standard .php extension then you can add them +to the `fileExtensions` array parameter: + +``` +parameters: + fileExtensions: + - php + - module + - inc +``` + +### Universal object crates + +Classes without predefined structure are common in PHP applications. +They are used as universal holders of data - any property can be set and read on them. Notable examples +include `stdClass`, `SimpleXMLElement` (these are enabled by default), objects with results of database queries etc. +Use `universalObjectCratesClasses` array parameter to let PHPStan know which classes +with these characteristics are used in your codebase: + +``` +parameters: + universalObjectCratesClasses: + - Dibi\Row + - Ratchet\ConnectionInterface +``` + +### Add non-obviously assigned variables to scope + +If you use some variables from a try block in your catch blocks, set `polluteCatchScopeWithTryAssignments` boolean parameter to `true`. + +```php +try { + $author = $this->getLoggedInUser(); + $post = $this->postRepository->getById($id); +} catch (PostNotFoundException $e) { + // $author is probably defined here + throw new ArticleByAuthorCannotBePublished($author); +} +``` + +If you are enumerating over all possible situations in if-elseif branches +and PHPStan complains about undefined variables after the conditions, you can write +an else branch with throwing an exception: + +```php +if (somethingIsTrue()) { + $foo = true; +} elseif (orSomethingElseIsTrue()) { + $foo = false; +} else { + throw new ShouldNotHappenException(); +} + +doFoo($foo); +``` + +I recommend leaving `polluteCatchScopeWithTryAssignments` set to `false` because it leads to a clearer and more maintainable code. + +### Custom early terminating method calls + +Previous example showed that if a condition branches end with throwing an exception, that branch does not have +to define a variable used after the condition branches end. + +But exceptions are not the only way how to terminate execution of a method early. Some specific method calls +can be perceived by project developers also as early terminating - like a `redirect()` that stops execution +by throwing an internal exception. + +```php +if (somethingIsTrue()) { + $foo = true; +} elseif (orSomethingElseIsTrue()) { + $foo = false; +} else { + $this->redirect('homepage'); +} + +doFoo($foo); +``` + +These methods can be configured by specifying a class on whose instance they are called like this: + +``` +parameters: + earlyTerminatingMethodCalls: + Nette\Application\UI\Presenter: + - redirect + - redirectUrl + - sendJson + - sendResponse +``` + +### Ignore error messages with regular expressions + +If some issue in your code base is not easy to fix or just simply want to deal with it later, +you can exclude error messages from the analysis result with regular expressions: + +``` +parameters: + ignoreErrors: + - '#Call to an undefined method [a-zA-Z0-9\\_]+::method\(\)#' + - '#Call to an undefined method [a-zA-Z0-9\\_]+::expects\(\)#' + - '#Access to an undefined property PHPUnit_Framework_MockObject_MockObject::\$[a-zA-Z0-9_]+#' + - '#Call to an undefined method PHPUnit_Framework_MockObject_MockObject::[a-zA-Z0-9_]+\(\)#' +``` + +To exclude an error in a specific directory or file, specify a `path` along with the `message`: + +``` +parameters: + ignoreErrors: + - + message: '#Call to an undefined method [a-zA-Z0-9\\_]+::method\(\)#' + path: %currentWorkingDirectory%/some/dir/SomeFile.php + - + message: '#Call to an undefined method [a-zA-Z0-9\\_]+::method\(\)#' + path: %currentWorkingDirectory%/other/dir/* + - '#Other error to catch anywhere#' +``` + +If some of the patterns do not occur in the result anymore, PHPStan will let you know +and you will have to remove the pattern from the configuration. You can turn off +this behaviour by setting `reportUnmatchedIgnoredErrors` to `false` in PHPStan configuration. + +### Bootstrap file + +If you need to initialize something in PHP runtime before PHPStan runs (like your own autoloader), +you can provide your own bootstrap file: + +``` +parameters: + bootstrap: %rootDir%/../../../phpstan-bootstrap.php +``` + +### Custom rules + +PHPStan allows writing custom rules to check for specific situations in your own codebase. Your rule class +needs to implement the `PHPStan\Rules\Rule` interface and registered as a service in the configuration file: + +``` +services: + - + class: MyApp\PHPStan\Rules\DefaultValueTypesAssignedToPropertiesRule + tags: + - phpstan.rules.rule +``` + +For inspiration on how to implement a rule turn to [src/Rules](https://github.com/phpstan/phpstan/tree/master/src/Rules) +to see a lot of built-in rules. + +Check out also [phpstan-strict-rules](https://github.com/phpstan/phpstan-strict-rules) repository for extra strict and opinionated rules for PHPStan! + +### Custom error formatters + +PHPStan outputs errors via formatters. You can customize the output by implementing the `ErrorFormatter` interface in a new class and add it to the configuration. For existing formatters, see next chapter. + +```php +interface ErrorFormatter +{ + + /** + * Formats the errors and outputs them to the console. + * + * @param \PHPStan\Command\AnalysisResult $analysisResult + * @param \Symfony\Component\Console\Style\OutputStyle $style + * @return int Error code. + */ + public function formatErrors( + AnalysisResult $analysisResult, + \Symfony\Component\Console\Style\OutputStyle $style + ): int; + +} +``` + +Register the formatter in your `phpstan.neon`: + +``` +services: + errorFormatter.awesome: + class: App\PHPStan\AwesomeErrorFormatter +``` + +Use the name part after `errorFormatter.` as the CLI option value: + +```bash +vendor/bin/phpstan analyse -c phpstan.neon -l 4 --error-format awesome src tests +``` + +### Existing error formatters to be used + +You can pass the following keywords to the `--error-format=X` parameter in order to affect the output: + +- `table`: Default. Grouped errors by file, colorized. For human consumption. +- `raw`: Contains one error per line, with path to file, line number, and error description +- `checkstyle`: Creates a checkstyle.xml compatible output. Note that you'd have to redirect output into a file in order to capture the results for later processing. + +## Class reflection extensions + +Classes in PHP can expose "magical" properties and methods decided in run-time using +class methods like `__get`, `__set` and `__call`. Because PHPStan is all about static analysis +(testing code for errors without running it), it has to know about those properties and methods beforehand. + +When PHPStan stumbles upon a property or a method that is unknown to built-in class reflection, it iterates +over all registered class reflection extensions until it finds one that defines the property or method. + +Class reflection extension cannot have `PHPStan\Broker\Broker` (service for obtaining class reflections) injected in the constructor due to circular reference issue, but the extensions can implement `PHPStan\Reflection\BrokerAwareExtension` interface to obtain Broker via a setter. + +### Properties class reflection extensions + +This extension type must implement the following interface: + +```php +namespace PHPStan\Reflection; + +interface PropertiesClassReflectionExtension +{ + + public function hasProperty(ClassReflection $classReflection, string $propertyName): bool; + + public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection; + +} +``` + +Most likely you will also have to implement a new `PropertyReflection` class: + +```php +namespace PHPStan\Reflection; + +interface PropertyReflection +{ + + public function getType(): Type; + + public function getDeclaringClass(): ClassReflection; + + public function isStatic(): bool; + + public function isPrivate(): bool; + + public function isPublic(): bool; + +} +``` + +This is how you register the extension in project's PHPStan config file: + +``` +services: + - + class: App\PHPStan\PropertiesFromAnnotationsClassReflectionExtension + tags: + - phpstan.broker.propertiesClassReflectionExtension +``` + +### Methods class reflection extensions + +This extension type must implement the following interface: + +```php +namespace PHPStan\Reflection; + +interface MethodsClassReflectionExtension +{ + + public function hasMethod(ClassReflection $classReflection, string $methodName): bool; + + public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection; + +} +``` + +Most likely you will also have to implement a new `MethodReflection` class: + +```php +namespace PHPStan\Reflection; + +interface MethodReflection +{ + + public function getDeclaringClass(): ClassReflection; + + public function getPrototype(): self; + + public function isStatic(): bool; + + public function isPrivate(): bool; + + public function isPublic(): bool; + + public function getName(): string; + + /** + * @return \PHPStan\Reflection\ParameterReflection[] + */ + public function getParameters(): array; + + public function isVariadic(): bool; + + public function getReturnType(): Type; + +} +``` + +This is how you register the extension in project's PHPStan config file: + +``` +services: + - + class: App\PHPStan\EnumMethodsClassReflectionExtension + tags: + - phpstan.broker.methodsClassReflectionExtension +``` + +## Dynamic return type extensions + +If the return type of a method is not always the same, but depends on an argument passed to the method, +you can specify the return type by writing and registering an extension. + +Because you have to write the code with the type-resolving logic, it can be as complex as you want. + +After writing the sample extension, the variable `$mergedArticle` will have the correct type: + +```php +$mergedArticle = $this->entityManager->merge($article); +// $mergedArticle will have the same type as $article +``` + +This is the interface for dynamic return type extension: + +```php +namespace PHPStan\Type; + +use PhpParser\Node\Expr\MethodCall; +use PHPStan\Analyser\Scope; +use PHPStan\Reflection\MethodReflection; + +interface DynamicMethodReturnTypeExtension +{ + + public function getClass(): string; + + public function isMethodSupported(MethodReflection $methodReflection): bool; + + public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type; + +} +``` + +And this is how you'd write the extension that correctly resolves the EntityManager::merge() return type: + +```php +public function getClass(): string +{ + return \Doctrine\ORM\EntityManager::class; +} + +public function isMethodSupported(MethodReflection $methodReflection): bool +{ + return $methodReflection->getName() === 'merge'; +} + +public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type +{ + if (count($methodCall->args) === 0) { + return \PHPStan\Reflection\ParametersAcceptorSelector::selectFromArgs( + $scope, + $methodCall->args, + $methodReflection->getVariants() + )->getReturnType(); + } + $arg = $methodCall->args[0]->value; + + return $scope->getType($arg); +} +``` + +And finally, register the extension to PHPStan in the project's config file: + +``` +services: + - + class: App\PHPStan\EntityManagerDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicMethodReturnTypeExtension +``` + +There's also an analogous functionality for: + +* **static methods** using `DynamicStaticMethodReturnTypeExtension` interface +and `phpstan.broker.dynamicStaticMethodReturnTypeExtension` service tag. +* **functions** using `DynamicFunctionReturnTypeExtension` interface and `phpstan.broker.dynamicFunctionReturnTypeExtension` service tag. + +## Type-specifying extensions + +These extensions allow you to specify types of expressions based on certain pre-existing conditions. This is best illustrated with couple examples: + +```php +if (is_int($variable)) { + // here we can be sure that $variable is integer +} +``` + +```php +// using PHPUnit's asserts + +self::assertNotNull($variable); +// here we can be sure that $variable is not null +``` + +Type-specifying extension cannot have `PHPStan\Analyser\TypeSpecifier` injected in the constructor due to circular reference issue, but the extensions can implement `PHPStan\Analyser\TypeSpecifierAwareExtension` interface to obtain TypeSpecifier via a setter. + +This is the interface for type-specifying extension: + +```php +namespace PHPStan\Type; + +use PhpParser\Node\Expr\StaticCall; +use PHPStan\Analyser\Scope; +use PHPStan\Analyser\SpecifiedTypes; +use PHPStan\Analyser\TypeSpecifierContext; +use PHPStan\Reflection\MethodReflection; + +interface StaticMethodTypeSpecifyingExtension +{ + + public function getClass(): string; + + public function isStaticMethodSupported(MethodReflection $staticMethodReflection, StaticCall $node, TypeSpecifierContext $context): bool; + + public function specifyTypes(MethodReflection $staticMethodReflection, StaticCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes; + +} +``` + +And this is how you'd write the extension for the second example above: + +```php +public function getClass(): string +{ + return \PHPUnit\Framework\Assert::class; +} + +public function isStaticMethodSupported(MethodReflection $staticMethodReflection, StaticCall $node, TypeSpecifierContext $context): bool; +{ + // The $context argument tells us if we're in an if condition or not (as in this case). + return $staticMethodReflection->getName() === 'assertNotNull' && $context->null(); +} + +public function specifyTypes(MethodReflection $staticMethodReflection, StaticCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes +{ + // Assuming extension implements \PHPStan\Analyser\TypeSpecifierAwareExtension. + return $this->typeSpecifier->create($node->var, \PHPStan\Type\TypeCombinator::removeNull($scope->getType($node->var)), $context); +} +``` + +And finally, register the extension to PHPStan in the project's config file: + +``` +services: + - + class: App\PHPStan\AssertNotNullTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.staticMethodTypeSpecifyingExtension +``` + +There's also an analogous functionality for: + +* **dynamic methods** using `MethodTypeSpecifyingExtension` interface +and `phpstan.typeSpecifier.methodTypeSpecifyingExtension` service tag. +* **functions** using `FunctionTypeSpecifyingExtension` interface and `phpstan.typeSpecifier.functionTypeSpecifyingExtension` service tag. + +## Known issues + +* If `include` or `require` are used in the analysed code (instead of `include_once` or `require_once`), +PHPStan will throw `Cannot redeclare class` error. Use the `_once` variants to avoid this error. +* If PHPStan crashes without outputting any error, it's quite possible that it's +because of a low memory limit set on your system. **Run PHPStan again** to read a couple of hints +what you can do to prevent the crashes. + +## Code of Conduct + +This project adheres to a [Contributor Code of Conduct](https://github.com/phpstan/phpstan/blob/master/CODE_OF_CONDUCT.md). By participating in this project and its community, you are expected to uphold this code. + +## Contributing + +Any contributions are welcome. + +### Building + +You can either run the whole build including linting and coding standards using + +```bash +vendor/bin/phing +``` + +or run only tests using + +```bash +vendor/bin/phing tests +``` diff --git a/vendor/phpstan/phpstan/appveyor.yml b/vendor/phpstan/phpstan/appveyor.yml new file mode 100644 index 00000000..8ed43750 --- /dev/null +++ b/vendor/phpstan/phpstan/appveyor.yml @@ -0,0 +1,70 @@ +build: false +clone_folder: c:\projects\phpstan +clone_depth: 1 +platform: + - x64 +environment: + matrix: + - dependencies: lowest + php_version: 7.1 + - dependencies: highest + php_version: 7.1 + - dependencies: lowest + php_version: 7.2 + - dependencies: highest + php_version: 7.2 + - dependencies: lowest + php_version: 7.3 + - dependencies: highest + php_version: 7.3 + + project_directory: c:\projects\phpstan + composer_directory: c:\tools\composer + composer_executable: c:\tools\composer\composer.phar + composer_installer: c:\tools\composer\installer.php + php_root_directory: c:\tools\php +cache: + - c:\ProgramData\chocolatey\bin -> appveyor.yml + - c:\ProgramData\chocolatey\lib -> appveyor.yml + - c:\tools\composer -> appveyor.yml + - '%LOCALAPPDATA%\Composer -> appveyor.yml' + - c:\tools\php -> appveyor.yml +init: + - ps: $Env:php_directory = $Env:php_root_directory + '\' + $Env:php_version + - ps: $Env:exact_php_version = (((choco search php --exact --all-versions --limit-output | Select-String -pattern $Env:php_version) -replace '[php|]', '') | %{ New-Object System.Version $_ } | Sort-Object | Select-Object -Last 1).ToString() + - ps: $Env:PATH = $Env:php_directory + ';' + $Env:composer_directory + ';' + $Env:PATH + - ps: $Env:COMPOSER_NO_INTERACTION = 1 + - ps: $Env:ANSICON = '121x90 (121x90)' +install: + # Install PHP + - ps: If ((Test-Path $Env:php_directory) -eq $False) { New-Item -Path $Env:php_directory -ItemType 'directory' } + - ps: $php_install_parameters = '"/DontAddToPath /InstallDir:' + $Env:php_directory + '"' + - ps: appveyor-retry choco upgrade php --yes --version=$Env:exact_php_version --params=$php_install_parameters + + # Prepare PHP + - ps: cd $Env:php_directory + - ps: Copy-Item php.ini-production -Destination php.ini + - ps: Add-Content -Path php.ini -Value 'memory_limit=1G' + - ps: Add-Content -Path php.ini -Value 'date.timezone="UTC"' + - ps: Add-Content -Path php.ini -Value 'extension_dir=ext' + - ps: Add-Content -Path php.ini -Value 'extension=php_curl.dll' + - ps: Add-Content -Path php.ini -Value 'extension=php_mbstring.dll' + - ps: Add-Content -Path php.ini -Value 'extension=php_openssl.dll' + - ps: Add-Content -Path php.ini -Value 'extension=php_soap.dll' + - ps: Add-Content -Path php.ini -Value 'extension=php_mysqli.dll' + - ps: Add-Content -Path php.ini -Value 'extension=php_intl.dll' + - ps: php --version + + # Prepare composer + - ps: If ((Test-Path $Env:composer_directory) -eq $False) { New-Item -Path $Env:composer_directory -ItemType 'directory' } + - ps: If ((Test-Path $Env:composer_installer) -eq $False) { appveyor-retry appveyor DownloadFile https://getcomposer.org/installer -FileName $Env:composer_installer } + - ps: If ((Test-Path $Env:composer_executable) -eq $False) { php $Env:composer_installer --install-dir=$Env:composer_directory } + - ps: Set-Content -Path ($Env:composer_directory + '\composer.bat') -Value ('@php ' + $Env:composer_executable + ' %*') + + # Install dependencies + - ps: cd $Env:project_directory + - IF %dependencies%==lowest composer update --prefer-dist --prefer-lowest --prefer-stable --no-progress + - IF %dependencies%==highest composer update --prefer-dist --no-progress +test_script: + - ps: cd $Env:project_directory + - vendor\bin\phing diff --git a/vendor/phpstan/phpstan/bin/phpstan b/vendor/phpstan/phpstan/bin/phpstan new file mode 100755 index 00000000..a2fdf65e --- /dev/null +++ b/vendor/phpstan/phpstan/bin/phpstan @@ -0,0 +1,41 @@ +#!/usr/bin/env php +check(); +unset($xdebug); + +$version = 'Version unknown'; +try { + $version = \Jean85\PrettyVersions::getVersion('phpstan/phpstan')->getPrettyVersion(); +} catch (\OutOfBoundsException $e) { + +} + +$application = new \Symfony\Component\Console\Application( + 'PHPStan - PHP Static Analysis Tool', + $version +); +$application->add(new AnalyseCommand()); +$application->add(new DumpDependenciesCommand()); +$application->run(); diff --git a/vendor/phpstan/phpstan/build.xml b/vendor/phpstan/phpstan/build.xml new file mode 100644 index 00000000..57dd3eea --- /dev/null +++ b/vendor/phpstan/phpstan/build.xml @@ -0,0 +1,244 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpstan/phpstan/composer.json b/vendor/phpstan/phpstan/composer.json new file mode 100644 index 00000000..ddaf23f7 --- /dev/null +++ b/vendor/phpstan/phpstan/composer.json @@ -0,0 +1,68 @@ +{ + "name": "phpstan/phpstan", + "description": "PHPStan - PHP Static Analysis Tool", + "license": [ + "MIT" + ], + "require": { + "php": "~7.1", + "composer/xdebug-handler": "^1.3.0", + "jean85/pretty-package-versions": "^1.0.3", + "nette/bootstrap": "^2.4 || ^3.0", + "nette/di": "^2.4.7 || ^3.0", + "nette/robot-loader": "^3.0.1", + "nette/utils": "^2.4.5 || ^3.0", + "nikic/php-parser": "^4.0.2", + "phpstan/phpdoc-parser": "^0.3", + "symfony/console": "~3.2 || ~4.0", + "symfony/finder": "~3.2 || ~4.0" + }, + "conflict": { + "symfony/console": "3.4.16 || 4.1.5" + }, + "require-dev": { + "ext-intl": "*", + "ext-mysqli": "*", + "ext-soap": "*", + "ext-zip": "*", + "brianium/paratest": "^2.0", + "consistence/coding-standard": "^3.5", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "jakub-onderka/php-parallel-lint": "^1.0", + "localheinz/composer-normalize": "^1.1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-deprecation-rules": "^0.11", + "phpstan/phpstan-php-parser": "^0.11", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-strict-rules": "^0.11", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.7.2", + "squizlabs/php_codesniffer": "^3.3.2" + }, + "config": { + "sort-packages": true + }, + "extra": { + "branch-alias": { + "dev-master": "0.11-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": [ + "src/", + "build/PHPStan" + ] + } + }, + "autoload-dev": { + "classmap": [ + "tests/PHPStan" + ] + }, + "minimum-stability": "dev", + "prefer-stable": true, + "bin": [ + "bin/phpstan" + ] +} diff --git a/vendor/phpstan/phpstan/conf/config.level0.neon b/vendor/phpstan/phpstan/conf/config.level0.neon new file mode 100644 index 00000000..d5f8608e --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.level0.neon @@ -0,0 +1,132 @@ +parameters: + customRulesetUsed: false + +rules: + - PHPStan\Rules\Arrays\DuplicateKeysInLiteralArraysRule + - PHPStan\Rules\Arrays\OffsetAccessWithoutDimForReadingRule + - PHPStan\Rules\Classes\ClassConstantDeclarationRule + - PHPStan\Rules\Classes\ClassConstantRule + - PHPStan\Rules\Classes\ExistingClassesInClassImplementsRule + - PHPStan\Rules\Classes\ExistingClassesInInterfaceExtendsRule + - PHPStan\Rules\Classes\ExistingClassInClassExtendsRule + - PHPStan\Rules\Classes\ExistingClassInTraitUseRule + - PHPStan\Rules\Classes\InstantiationRule + - PHPStan\Rules\Classes\RequireParentConstructCallRule + - PHPStan\Rules\Classes\UnusedConstructorParametersRule + - PHPStan\Rules\Functions\CallToFunctionParametersRule + - PHPStan\Rules\Functions\ExistingClassesInClosureTypehintsRule + - PHPStan\Rules\Functions\ExistingClassesInTypehintsRule + - PHPStan\Rules\Functions\InnerFunctionRule + - PHPStan\Rules\Functions\NonExistentDefinedFunctionRule + - PHPStan\Rules\Functions\PrintfParametersRule + - PHPStan\Rules\Functions\UnusedClosureUsesRule + - PHPStan\Rules\Methods\ExistingClassesInTypehintsRule + - PHPStan\Rules\Properties\AccessStaticPropertiesRule + - PHPStan\Rules\Variables\ThisVariableRule + +services: + - + class: PHPStan\Rules\Classes\ExistingClassInInstanceOfRule + tags: + - phpstan.rules.rule + arguments: + checkClassCaseSensitivity: %checkClassCaseSensitivity% + + - + class: PHPStan\Rules\Exceptions\CaughtExceptionExistenceRule + tags: + - phpstan.rules.rule + arguments: + checkClassCaseSensitivity: %checkClassCaseSensitivity% + + - + class: PHPStan\Rules\Functions\CallToNonExistentFunctionRule + tags: + - phpstan.rules.rule + arguments: + checkFunctionNameCase: %checkFunctionNameCase% + + - + class: PHPStan\Rules\Methods\CallMethodsRule + tags: + - phpstan.rules.rule + arguments: + checkFunctionNameCase: %checkFunctionNameCase% + reportMagicMethods: %reportMagicMethods% + + - + class: PHPStan\Rules\Methods\CallStaticMethodsRule + tags: + - phpstan.rules.rule + arguments: + checkFunctionNameCase: %checkFunctionNameCase% + reportMagicMethods: %reportMagicMethods% + + - + class: PHPStan\Rules\Namespaces\ExistingNamesInGroupUseRule + tags: + - phpstan.rules.rule + arguments: + checkFunctionNameCase: %checkFunctionNameCase% + + - + class: PHPStan\Rules\Namespaces\ExistingNamesInUseRule + tags: + - phpstan.rules.rule + arguments: + checkFunctionNameCase: %checkFunctionNameCase% + + - + class: PHPStan\Rules\Operators\InvalidIncDecOperationRule + tags: + - phpstan.rules.rule + arguments: + checkThisOnly: %checkThisOnly% + + - + class: PHPStan\Rules\Properties\AccessPropertiesRule + tags: + - phpstan.rules.rule + arguments: + reportMagicProperties: %reportMagicProperties% + + - + class: PHPStan\Rules\Properties\ExistingClassesInPropertiesRule + tags: + - phpstan.rules.rule + arguments: + checkClassCaseSensitivity: %checkClassCaseSensitivity% + + - + class: PHPStan\Rules\Properties\WritingToReadOnlyPropertiesRule + arguments: + checkThisOnly: %checkThisOnly% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Properties\ReadingWriteOnlyPropertiesRule + arguments: + checkThisOnly: %checkThisOnly% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Variables\DefinedVariableRule + arguments: + cliArgumentsVariablesRegistered: %cliArgumentsVariablesRegistered% + checkMaybeUndefinedVariables: %checkMaybeUndefinedVariables% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Variables\DefinedVariableInAnonymousFunctionUseRule + arguments: + checkMaybeUndefinedVariables: %checkMaybeUndefinedVariables% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Regexp\RegularExpressionPatternRule + tags: + - phpstan.rules.rule diff --git a/vendor/phpstan/phpstan/conf/config.level1.neon b/vendor/phpstan/phpstan/conf/config.level1.neon new file mode 100644 index 00000000..df5b4d3e --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.level1.neon @@ -0,0 +1,11 @@ +includes: + - config.level0.neon + +parameters: + checkMaybeUndefinedVariables: true + reportMagicMethods: true + reportMagicProperties: true + +rules: + - PHPStan\Rules\Constants\ConstantRule + - PHPStan\Rules\Variables\VariableCertaintyInIssetRule diff --git a/vendor/phpstan/phpstan/conf/config.level2.neon b/vendor/phpstan/phpstan/conf/config.level2.neon new file mode 100644 index 00000000..7666fdff --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.level2.neon @@ -0,0 +1,29 @@ +includes: + - config.level1.neon + +parameters: + checkClassCaseSensitivity: true + checkThisOnly: false + +rules: + - PHPStan\Rules\Cast\EchoRule + - PHPStan\Rules\Cast\InvalidCastRule + - PHPStan\Rules\Cast\InvalidPartOfEncapsedStringRule + - PHPStan\Rules\Cast\PrintRule + - PHPStan\Rules\Functions\IncompatibleDefaultParameterTypeRule + - PHPStan\Rules\Methods\IncompatibleDefaultParameterTypeRule + - PHPStan\Rules\Operators\InvalidBinaryOperationRule + - PHPStan\Rules\Operators\InvalidUnaryOperationRule + - PHPStan\Rules\Operators\InvalidComparisonOperationRule + - PHPStan\Rules\PhpDoc\IncompatiblePhpDocTypeRule + - PHPStan\Rules\PhpDoc\IncompatiblePropertyPhpDocTypeRule + - PHPStan\Rules\PhpDoc\InvalidPhpDocTagValueRule + - PHPStan\Rules\PhpDoc\InvalidThrowsPhpDocValueRule + +services: + - + class: PHPStan\Rules\Functions\CallCallablesRule + arguments: + reportMaybes: %reportMaybes% + tags: + - phpstan.rules.rule diff --git a/vendor/phpstan/phpstan/conf/config.level3.neon b/vendor/phpstan/phpstan/conf/config.level3.neon new file mode 100644 index 00000000..deb49ff5 --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.level3.neon @@ -0,0 +1,52 @@ +includes: + - config.level2.neon + +rules: + - PHPStan\Rules\Arrays\AppendedArrayItemTypeRule + - PHPStan\Rules\Arrays\IterableInForeachRule + - PHPStan\Rules\Arrays\OffsetAccessAssignmentRule + - PHPStan\Rules\Arrays\OffsetAccessAssignOpRule + - PHPStan\Rules\Functions\ClosureReturnTypeRule + - PHPStan\Rules\Functions\ReturnTypeRule + - PHPStan\Rules\Methods\ReturnTypeRule + - PHPStan\Rules\Properties\DefaultValueTypesAssignedToPropertiesRule + - PHPStan\Rules\Properties\TypesAssignedToPropertiesRule + - PHPStan\Rules\Variables\ThrowTypeRule + - PHPStan\Rules\Variables\VariableCloningRule + +services: + - + class: PHPStan\Rules\Arrays\AppendedArrayKeyTypeRule + arguments: + checkUnionTypes: %checkUnionTypes% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Arrays\InvalidKeyInArrayDimFetchRule + arguments: + reportMaybes: %reportMaybes% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Arrays\InvalidKeyInArrayItemRule + arguments: + reportMaybes: %reportMaybes% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Arrays\NonexistentOffsetInArrayDimFetchRule + arguments: + reportMaybes: %reportMaybes% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Methods\MethodSignatureRule + arguments: + reportMaybes: %reportMaybesInMethodSignatures% + reportStatic: %reportStaticMethodSignatures% + tags: + - phpstan.rules.rule diff --git a/vendor/phpstan/phpstan/conf/config.level4.neon b/vendor/phpstan/phpstan/conf/config.level4.neon new file mode 100644 index 00000000..32d04441 --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.level4.neon @@ -0,0 +1,49 @@ +includes: + - config.level3.neon + +rules: + - PHPStan\Rules\Arrays\DeadForeachRule + - PHPStan\Rules\Comparison\BooleanAndConstantConditionRule + - PHPStan\Rules\Comparison\BooleanNotConstantConditionRule + - PHPStan\Rules\Comparison\BooleanOrConstantConditionRule + - PHPStan\Rules\Comparison\ElseIfConstantConditionRule + - PHPStan\Rules\Comparison\IfConstantConditionRule + - PHPStan\Rules\Comparison\TernaryOperatorConstantConditionRule + - PHPStan\Rules\Comparison\UnreachableIfBranchesRule + - PHPStan\Rules\Comparison\UnreachableTernaryElseBranchRule + +services: + - + class: PHPStan\Rules\Classes\ImpossibleInstanceOfRule + arguments: + checkAlwaysTrueInstanceof: %checkAlwaysTrueInstanceof% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Comparison\ImpossibleCheckTypeFunctionCallRule + arguments: + checkAlwaysTrueCheckTypeFunctionCall: %checkAlwaysTrueCheckTypeFunctionCall% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Comparison\ImpossibleCheckTypeMethodCallRule + arguments: + checkAlwaysTrueCheckTypeFunctionCall: %checkAlwaysTrueCheckTypeFunctionCall% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Comparison\ImpossibleCheckTypeStaticMethodCallRule + arguments: + checkAlwaysTrueCheckTypeFunctionCall: %checkAlwaysTrueCheckTypeFunctionCall% + tags: + - phpstan.rules.rule + + - + class: PHPStan\Rules\Comparison\StrictComparisonOfDifferentTypesRule + arguments: + checkAlwaysTrueStrictComparison: %checkAlwaysTrueStrictComparison% + tags: + - phpstan.rules.rule diff --git a/vendor/phpstan/phpstan/conf/config.level5.neon b/vendor/phpstan/phpstan/conf/config.level5.neon new file mode 100644 index 00000000..8ebba4d1 --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.level5.neon @@ -0,0 +1,6 @@ +includes: + - config.level4.neon + +parameters: + checkFunctionArgumentTypes: true + checkArgumentsPassedByReference: true diff --git a/vendor/phpstan/phpstan/conf/config.level6.neon b/vendor/phpstan/phpstan/conf/config.level6.neon new file mode 100644 index 00000000..aee6ed32 --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.level6.neon @@ -0,0 +1,6 @@ +includes: + - config.level5.neon + +parameters: + checkUnionTypes: true + reportMaybes: true diff --git a/vendor/phpstan/phpstan/conf/config.level7.neon b/vendor/phpstan/phpstan/conf/config.level7.neon new file mode 100644 index 00000000..a124f8e5 --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.level7.neon @@ -0,0 +1,5 @@ +includes: + - config.level6.neon + +parameters: + checkNullables: true diff --git a/vendor/phpstan/phpstan/conf/config.levelmax.neon b/vendor/phpstan/phpstan/conf/config.levelmax.neon new file mode 100644 index 00000000..e5064025 --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.levelmax.neon @@ -0,0 +1,2 @@ +includes: + - config.level7.neon diff --git a/vendor/phpstan/phpstan/conf/config.neon b/vendor/phpstan/phpstan/conf/config.neon new file mode 100644 index 00000000..a25a32b3 --- /dev/null +++ b/vendor/phpstan/phpstan/conf/config.neon @@ -0,0 +1,630 @@ +parameters: + bootstrap: null + excludes_analyse: [] + autoload_directories: [] + autoload_files: [] + fileExtensions: + - php + checkAlwaysTrueCheckTypeFunctionCall: false + checkAlwaysTrueInstanceof: false + checkAlwaysTrueStrictComparison: false + checkClassCaseSensitivity: false + checkFunctionArgumentTypes: false + checkFunctionNameCase: false + checkArgumentsPassedByReference: false + checkMaybeUndefinedVariables: false + checkNullables: false + checkThisOnly: true + checkUnionTypes: false + reportMaybes: false + reportMaybesInMethodSignatures: false + reportStaticMethodSignatures: false + polluteScopeWithLoopInitialAssignments: true + polluteScopeWithAlwaysIterableForeach: true + polluteCatchScopeWithTryAssignments: false + reportMagicMethods: false + reportMagicProperties: false + ignoreErrors: [] + internalErrorsCountLimit: 50 + cache: + nodesByFileCountMax: 512 + nodesByStringCountMax: 512 + reportUnmatchedIgnoredErrors: true + scopeClass: PHPStan\Analyser\Scope + universalObjectCratesClasses: + - stdClass + - SimpleXMLElement + earlyTerminatingMethodCalls: [] + memoryLimitFile: %tmpDir%/.memory_limit + benchmarkFile: null + dynamicConstantNames: + - ICONV_IMPL + - PHP_VERSION + - PHP_MAJOR_VERSION + - PHP_MINOR_VERSION + - PHP_RELEASE_VERSION + - PHP_VERSION_ID + - PHP_EXTRA_VERSION + - PHP_ZTS + - PHP_DEBUG + - PHP_MAXPATHLEN + - PHP_OS + - PHP_OS_FAMILY + - PHP_SAPI + - PHP_EOL + - PHP_INT_MAX + - PHP_INT_MIN + - PHP_INT_SIZE + - PHP_FLOAT_DIG + - PHP_FLOAT_EPSILON + - PHP_FLOAT_MIN + - PHP_FLOAT_MAX + - DEFAULT_INCLUDE_PATH + - PEAR_INSTALL_DIR + - PEAR_EXTENSION_DIR + - PHP_EXTENSION_DIR + - PHP_PREFIX + - PHP_BINDIR + - PHP_BINARY + - PHP_MANDIR + - PHP_LIBDIR + - PHP_DATADIR + - PHP_SYSCONFDIR + - PHP_LOCALSTATEDIR + - PHP_CONFIG_FILE_PATH + - PHP_CONFIG_FILE_SCAN_DIR + - PHP_SHLIB_SUFFIX + - PHP_FD_SETSIZE + +extensions: + rules: PHPStan\DependencyInjection\RulesExtension + conditionalTags: PHPStan\DependencyInjection\ConditionalTagsExtension + +services: + - + class: PhpParser\BuilderFactory + + - + class: PhpParser\Lexer + + - + class: PhpParser\NodeTraverser + setup: + - addVisitor(@PhpParser\NodeVisitor\NameResolver) + + - + class: PhpParser\NodeVisitor\NameResolver + + - + class: PhpParser\Parser\Php7 + + - + class: PhpParser\PrettyPrinter\Standard + + - + class: PHPStan\Broker\AnonymousClassNameHelper + + - + class: PHPStan\PhpDocParser\Lexer\Lexer + + - + class: PHPStan\PhpDocParser\Parser\TypeParser + + - + class: PHPStan\PhpDocParser\Parser\ConstExprParser + + - + class: PHPStan\PhpDocParser\Parser\PhpDocParser + + - + class: PHPStan\PhpDoc\PhpDocNodeResolver + + - + class: PHPStan\PhpDoc\PhpDocStringResolver + + - + class: PHPStan\PhpDoc\TypeNodeResolver + factory: @typeNodeResolverFactory::create + + - + class: PHPStan\PhpDoc\TypeStringResolver + + - + class: PHPStan\Analyser\Analyser + arguments: + ignoreErrors: %ignoreErrors% + reportUnmatchedIgnoredErrors: %reportUnmatchedIgnoredErrors% + internalErrorsCountLimit: %internalErrorsCountLimit% + benchmarkFile: %benchmarkFile% + + - + class: PHPStan\Analyser\ScopeFactory + arguments: + scopeClass: %scopeClass% + + - + class: PHPStan\Analyser\NodeScopeResolver + arguments: + polluteScopeWithLoopInitialAssignments: %polluteScopeWithLoopInitialAssignments% + polluteCatchScopeWithTryAssignments: %polluteCatchScopeWithTryAssignments% + polluteScopeWithAlwaysIterableForeach: %polluteScopeWithAlwaysIterableForeach% + earlyTerminatingMethodCalls: %earlyTerminatingMethodCalls% + + - + class: PHPStan\Cache\Cache + arguments: + storage: @cacheStorage + + - + class: PHPStan\Command\AnalyseApplication + arguments: + memoryLimitFile: %memoryLimitFile% + currentWorkingDirectory: %currentWorkingDirectory% + + - + class: PHPStan\Dependency\DependencyDumper + + - + class: PHPStan\Dependency\DependencyResolver + + - + class: PHPStan\File\FileHelper + arguments: + workingDirectory: %currentWorkingDirectory% + + - + class: PHPStan\File\FileExcluder + arguments: + analyseExcludes: %excludes_analyse% + + - + class: PHPStan\File\FileFinder + arguments: + fileExtensions: %fileExtensions% + + - + class: PHPStan\Parser\CachedParser + arguments: + originalParser: @directParser + cachedNodesByFileCountMax: %cache.nodesByFileCountMax% + cachedNodesByStringCountMax: %cache.nodesByStringCountMax% + + - + class: PHPStan\Parser\FunctionCallStatementFinder + + - + implement: PHPStan\Reflection\FunctionReflectionFactory + + - + class: PHPStan\Reflection\Annotations\AnnotationsMethodsClassReflectionExtension + + - + class: PHPStan\Reflection\Annotations\AnnotationsPropertiesClassReflectionExtension + + - + class: PHPStan\Reflection\Php\PhpClassReflectionExtension + + - + class: PHPStan\Reflection\PhpDefect\PhpDefectClassReflectionExtension + + - + implement: PHPStan\Reflection\Php\PhpMethodReflectionFactory + + - + class: PHPStan\Reflection\Php\UniversalObjectCratesClassReflectionExtension + tags: + - phpstan.broker.propertiesClassReflectionExtension + arguments: + classes: %universalObjectCratesClasses% + + - + class: PHPStan\Reflection\SignatureMap\SignatureMapParser + + - + class: PHPStan\Reflection\SignatureMap\SignatureMapProvider + + - + class: PHPStan\Rules\ClassCaseSensitivityCheck + + - + class: PHPStan\Rules\Comparison\ConstantConditionRuleHelper + + - + class: PHPStan\Rules\Comparison\ImpossibleCheckTypeHelper + + - + class: PHPStan\Rules\FunctionCallParametersCheck + arguments: + checkArgumentTypes: %checkFunctionArgumentTypes% + checkArgumentsPassedByReference: %checkArgumentsPassedByReference% + + - + class: PHPStan\Rules\FunctionDefinitionCheck + arguments: + checkClassCaseSensitivity: %checkClassCaseSensitivity% + checkThisOnly: %checkThisOnly% + + - + class: PHPStan\Rules\FunctionReturnTypeCheck + + - + class: PHPStan\Rules\Properties\PropertyDescriptor + + - + class: PHPStan\Rules\Properties\PropertyReflectionFinder + + - + class: PHPStan\Rules\RegistryFactory + + - + class: PHPStan\Rules\RuleLevelHelper + arguments: + checkNullables: %checkNullables% + checkThisOnly: %checkThisOnly% + checkUnionTypes: %checkUnionTypes% + + - + class: PHPStan\Rules\UnusedFunctionParametersCheck + + - + class: PHPStan\Type\FileTypeMapper + + - + class: PHPStan\Type\Php\ArgumentBasedFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayFillFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayFillKeysFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayFilterFunctionReturnTypeReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayKeyDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayKeyExistsFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\ArrayKeyFirstDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayKeyLastDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayKeysFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayMapFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayMergeFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayPopFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayReduceFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayShiftFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArraySliceFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArraySearchFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayValuesFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\CountFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\CountFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\CurlInitReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\DioStatDynamicFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ExplodeFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\GetParentClassDynamicFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\GettimeofdayDynamicFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\StatDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + - phpstan.broker.dynamicMethodReturnTypeExtension + + - + class: PHPStan\Type\Php\MethodExistsTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\PropertyExistsTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\MinMaxFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\PathinfoFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ReplaceFunctionsDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ArrayPointerFunctionsDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\VarExportFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\MbFunctionsReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\MicrotimeFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\HrtimeFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\ParseUrlFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\VersionCompareFunctionDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\StrtotimeFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\RangeFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\AssertFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\DefineConstantTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\DefinedConstantTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\InArrayFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsIntFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsFloatFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsNullFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsArrayFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsBoolFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsCallableFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsCountableFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsResourceFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsIterableFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsStringFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsSubclassOfFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsObjectFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsNumericFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsScalarFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\IsAFunctionTypeSpecifyingExtension + tags: + - phpstan.typeSpecifier.functionTypeSpecifyingExtension + + - + class: PHPStan\Type\Php\JsonThrowOnErrorDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\TypeSpecifyingFunctionsDynamicReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + - + class: PHPStan\Type\Php\StrSplitFunctionReturnTypeExtension + tags: + - phpstan.broker.dynamicFunctionReturnTypeExtension + + typeSpecifier: + class: PHPStan\Analyser\TypeSpecifier + factory: @typeSpecifierFactory::create + + typeSpecifierFactory: + class: PHPStan\Analyser\TypeSpecifierFactory + + relativePathHelper: + class: PHPStan\File\RelativePathHelper + dynamic: true + + broker: + class: PHPStan\Broker\Broker + factory: @brokerFactory::create + + brokerFactory: + class: PHPStan\Broker\BrokerFactory + + cacheStorage: + class: PHPStan\Cache\FileCacheStorage + arguments: + directory: %tmpDir%/cache/PHPStan + autowired: no + + directParser: + class: PHPStan\Parser\DirectParser + autowired: no + + registry: + class: PHPStan\Rules\Registry + factory: @PHPStan\Rules\RegistryFactory::create + + typeNodeResolverFactory: + class: PHPStan\PhpDoc\TypeNodeResolverFactory + + errorFormatter.raw: + class: PHPStan\Command\ErrorFormatter\RawErrorFormatter + + errorFormatter.table: + class: PHPStan\Command\ErrorFormatter\TableErrorFormatter + + errorFormatter.checkstyle: + class: PHPStan\Command\ErrorFormatter\CheckstyleErrorFormatter + + errorFormatter.json: + class: PHPStan\Command\ErrorFormatter\JsonErrorFormatter + arguments: + pretty: false + + errorFormatter.prettyJson: + class: PHPStan\Command\ErrorFormatter\JsonErrorFormatter + arguments: + pretty: true diff --git a/vendor/phpstan/phpstan/phpcs.xml b/vendor/phpstan/phpstan/phpcs.xml new file mode 100644 index 00000000..cbc89ee6 --- /dev/null +++ b/vendor/phpstan/phpstan/phpcs.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tests/*/data + tests/*/traits + tests/notAutoloaded + src/Reflection/SignatureMap/functionMap.php + diff --git a/vendor/phpstan/phpstan/src/AnalysedCodeException.php b/vendor/phpstan/phpstan/src/AnalysedCodeException.php new file mode 100644 index 00000000..4aa4fb54 --- /dev/null +++ b/vendor/phpstan/phpstan/src/AnalysedCodeException.php @@ -0,0 +1,8 @@ +)[] */ + private $ignoreErrors; + + /** @var bool */ + private $reportUnmatchedIgnoredErrors; + + /** @var int */ + private $internalErrorsCountLimit; + + /** @var string|null */ + private $benchmarkFile; + + /** @var float[] */ + private $benchmarkData = []; + + /** + * @param \PHPStan\Analyser\ScopeFactory $scopeFactory + * @param \PHPStan\Parser\Parser $parser + * @param \PHPStan\Rules\Registry $registry + * @param \PHPStan\Analyser\NodeScopeResolver $nodeScopeResolver + * @param \PHPStan\File\FileHelper $fileHelper + * @param (string|array)[] $ignoreErrors + * @param bool $reportUnmatchedIgnoredErrors + * @param int $internalErrorsCountLimit + * @param string|null $benchmarkFile + */ + public function __construct( + ScopeFactory $scopeFactory, + Parser $parser, + Registry $registry, + NodeScopeResolver $nodeScopeResolver, + FileHelper $fileHelper, + array $ignoreErrors, + bool $reportUnmatchedIgnoredErrors, + int $internalErrorsCountLimit, + ?string $benchmarkFile = null + ) + { + $this->scopeFactory = $scopeFactory; + $this->parser = $parser; + $this->registry = $registry; + $this->nodeScopeResolver = $nodeScopeResolver; + $this->fileHelper = $fileHelper; + $this->ignoreErrors = $ignoreErrors; + $this->reportUnmatchedIgnoredErrors = $reportUnmatchedIgnoredErrors; + $this->internalErrorsCountLimit = $internalErrorsCountLimit; + $this->benchmarkFile = $benchmarkFile; + } + + /** + * @param string[] $files + * @param bool $onlyFiles + * @param \Closure(string $file): void|null $preFileCallback + * @param \Closure(string $file): void|null $postFileCallback + * @param bool $debug + * @return string[]|\PHPStan\Analyser\Error[] errors + */ + public function analyse( + array $files, + bool $onlyFiles, + ?\Closure $preFileCallback = null, + ?\Closure $postFileCallback = null, + bool $debug = false + ): array + { + $errors = []; + + foreach ($this->ignoreErrors as $ignoreError) { + try { + if (is_array($ignoreError)) { + if (!isset($ignoreError['message'])) { + $errors[] = sprintf( + 'Ignored error %s is missing a message.', + Json::encode($ignoreError) + ); + continue; + } + if (!isset($ignoreError['path'])) { + $errors[] = sprintf( + 'Ignored error %s is missing a path.', + Json::encode($ignoreError) + ); + } + + $ignoreMessage = $ignoreError['message']; + } else { + $ignoreMessage = $ignoreError; + } + + \Nette\Utils\Strings::match('', $ignoreMessage); + } catch (\Nette\Utils\RegexpException $e) { + $errors[] = $e->getMessage(); + } + } + + if (count($errors) > 0) { + return $errors; + } + + $this->nodeScopeResolver->setAnalysedFiles($files); + $internalErrorsCount = 0; + $reachedInternalErrorsCountLimit = false; + foreach ($files as $file) { + try { + $fileErrors = []; + if ($preFileCallback !== null) { + $preFileCallback($file); + } + + if (is_file($file)) { + $parserBenchmarkTime = $this->benchmarkStart(); + $parserNodes = $this->parser->parseFile($file); + $this->benchmarkEnd($parserBenchmarkTime, 'parser'); + + $scopeBenchmarkTime = $this->benchmarkStart(); + $this->nodeScopeResolver->processNodes( + $parserNodes, + $this->scopeFactory->create(ScopeContext::create($file)), + function (\PhpParser\Node $node, Scope $scope) use (&$fileErrors, $file, &$scopeBenchmarkTime): void { + $this->benchmarkEnd($scopeBenchmarkTime, 'scope'); + $uniquedAnalysedCodeExceptionMessages = []; + foreach ($this->registry->getRules(get_class($node)) as $rule) { + try { + $ruleBenchmarkTime = $this->benchmarkStart(); + $ruleErrors = $rule->processNode($node, $scope); + $this->benchmarkEnd($ruleBenchmarkTime, sprintf('rule-%s', get_class($rule))); + } catch (\PHPStan\AnalysedCodeException $e) { + if (isset($uniquedAnalysedCodeExceptionMessages[$e->getMessage()])) { + continue; + } + + $uniquedAnalysedCodeExceptionMessages[$e->getMessage()] = true; + $fileErrors[] = new Error($e->getMessage(), $file, $node->getLine(), false); + continue; + } + + foreach ($ruleErrors as $ruleError) { + $line = $node->getLine(); + $fileName = $scope->getFileDescription(); + if (is_string($ruleError)) { + $message = $ruleError; + } else { + $message = $ruleError->getMessage(); + if ( + $ruleError instanceof LineRuleError + && $ruleError->getLine() !== -1 + ) { + $line = $ruleError->getLine(); + } + if ( + $ruleError instanceof FileRuleError + && $ruleError->getFile() !== '' + ) { + $fileName = $ruleError->getFile(); + } + } + $fileErrors[] = new Error($message, $fileName, $line); + } + } + + $scopeBenchmarkTime = $this->benchmarkStart(); + } + ); + } elseif (is_dir($file)) { + $fileErrors[] = new Error(sprintf('File %s is a directory.', $file), $file, null, false); + } else { + $fileErrors[] = new Error(sprintf('File %s does not exist.', $file), $file, null, false); + } + if ($postFileCallback !== null) { + $postFileCallback($file); + } + + $errors = array_merge($errors, $fileErrors); + } catch (\PhpParser\Error $e) { + $errors[] = new Error($e->getMessage(), $file, $e->getStartLine() !== -1 ? $e->getStartLine() : null, false); + } catch (\PHPStan\Parser\ParserErrorsException $e) { + foreach ($e->getErrors() as $error) { + $errors[] = new Error($error->getMessage(), $file, $error->getStartLine() !== -1 ? $error->getStartLine() : null, false); + } + } catch (\PHPStan\AnalysedCodeException $e) { + $errors[] = new Error($e->getMessage(), $file, null, false); + } catch (\Throwable $t) { + if ($debug) { + throw $t; + } + $internalErrorsCount++; + $internalErrorMessage = sprintf('Internal error: %s', $t->getMessage()); + $internalErrorMessage .= sprintf( + '%sRun PHPStan with --debug option and post the stack trace to:%s%s', + "\n", + "\n", + 'https://github.com/phpstan/phpstan/issues/new' + ); + $errors[] = new Error($internalErrorMessage, $file); + if ($internalErrorsCount >= $this->internalErrorsCountLimit) { + $reachedInternalErrorsCountLimit = true; + break; + } + } + } + + if ($this->benchmarkFile !== null) { + uasort($this->benchmarkData, static function (float $a, float $b): int { + return $b <=> $a; + }); + file_put_contents($this->benchmarkFile, Json::encode($this->benchmarkData, Json::PRETTY)); + } + + $unmatchedIgnoredErrors = $this->ignoreErrors; + $addErrors = []; + $errors = array_values(array_filter($errors, function (Error $error) use (&$unmatchedIgnoredErrors, &$addErrors): bool { + foreach ($this->ignoreErrors as $i => $ignore) { + if (IgnoredError::shouldIgnore($this->fileHelper, $error, $ignore)) { + unset($unmatchedIgnoredErrors[$i]); + if (!$error->canBeIgnored()) { + $addErrors[] = sprintf( + 'Error message "%s" cannot be ignored, use excludes_analyse instead.', + $error->getMessage() + ); + return true; + } + return false; + } + } + + return true; + })); + + $errors = array_merge($errors, $addErrors); + + if (!$onlyFiles && $this->reportUnmatchedIgnoredErrors && !$reachedInternalErrorsCountLimit) { + foreach ($unmatchedIgnoredErrors as $unmatchedIgnoredError) { + $errors[] = sprintf( + 'Ignored error pattern %s was not matched in reported errors.', + IgnoredError::stringifyPattern($unmatchedIgnoredError) + ); + } + } + + if ($reachedInternalErrorsCountLimit) { + $errors[] = sprintf('Reached internal errors count limit of %d, exiting...', $this->internalErrorsCountLimit); + } + + return $errors; + } + + private function benchmarkStart(): ?float + { + if ($this->benchmarkFile === null) { + return null; + } + + return microtime(true); + } + + private function benchmarkEnd(?float $startTime, string $description): void + { + if ($this->benchmarkFile === null) { + return; + } + if ($startTime === null) { + return; + } + $elapsedTime = microtime(true) - $startTime; + if (!isset($this->benchmarkData[$description])) { + $this->benchmarkData[$description] = $elapsedTime; + return; + } + + $this->benchmarkData[$description] += $elapsedTime; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/Error.php b/vendor/phpstan/phpstan/src/Analyser/Error.php new file mode 100644 index 00000000..6e419c9c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/Error.php @@ -0,0 +1,48 @@ +message = $message; + $this->file = $file; + $this->line = $line; + $this->canBeIgnored = $canBeIgnored; + } + + public function getMessage(): string + { + return $this->message; + } + + public function getFile(): string + { + return $this->file; + } + + public function getLine(): ?int + { + return $this->line; + } + + public function canBeIgnored(): bool + { + return $this->canBeIgnored; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/IgnoredError.php b/vendor/phpstan/phpstan/src/Analyser/IgnoredError.php new file mode 100644 index 00000000..4d920a4f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/IgnoredError.php @@ -0,0 +1,58 @@ +|string $ignoredError + * @return string Representation of the ignored error + */ + public static function stringifyPattern($ignoredError): string + { + if (!is_array($ignoredError)) { + return $ignoredError; + } + + // ignore by path + if (isset($ignoredError['path'])) { + return sprintf('%s in path %s', $ignoredError['message'], $ignoredError['path']); + } + + return $ignoredError['message']; + } + + /** + * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint + * @param FileHelper $fileHelper + * @param Error $error + * @param array|string $ignoredError + * @return bool To ignore or not to ignore? + */ + public static function shouldIgnore( + FileHelper $fileHelper, + Error $error, + $ignoredError + ): bool + { + if (is_array($ignoredError)) { + // ignore by path + if (isset($ignoredError['path'])) { + $fileExcluder = new FileExcluder($fileHelper, [$ignoredError['path']]); + + return \Nette\Utils\Strings::match($error->getMessage(), $ignoredError['message']) !== null + && $fileExcluder->isExcludedFromAnalysing($error->getFile()); + } + + throw new \PHPStan\ShouldNotHappenException(); + } + + return \Nette\Utils\Strings::match($error->getMessage(), $ignoredError) !== null; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/LookForAssignsSettings.php b/vendor/phpstan/phpstan/src/Analyser/LookForAssignsSettings.php new file mode 100644 index 00000000..488b6d4a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/LookForAssignsSettings.php @@ -0,0 +1,119 @@ +respectEarlyTermination = $respectEarlyTermination; + } + + public static function default(): self + { + return self::create(self::EARLY_TERMINATION_ALL); + } + + public static function insideLoop(): self + { + return self::create(self::EARLY_TERMINATION_STOP + self::EARLY_TERMINATION_BREAK + self::REPEAT_ANALYSIS); + } + + public static function afterLoop(): self + { + return self::create(self::EARLY_TERMINATION_STOP + self::REPEAT_ANALYSIS); + } + + public static function afterSwitch(): self + { + return self::create(self::EARLY_TERMINATION_STOP); + } + + public static function insideFinally(): self + { + return self::create(0); + } + + public static function insideClosure(): self + { + return self::create(self::EARLY_TERMINATION_CLOSURE); + } + + private static function create(int $value): self + { + self::$registry[$value] = self::$registry[$value] ?? new self($value); + return self::$registry[$value]; + } + + public function shouldRepeatAnalysis(): bool + { + return ($this->respectEarlyTermination & self::REPEAT_ANALYSIS) === self::REPEAT_ANALYSIS; + } + + public function shouldSkipBranch(\PhpParser\Node $earlyTerminationStatement): bool + { + return $this->isRespected($earlyTerminationStatement); + } + + private function isRespected(\PhpParser\Node $earlyTerminationStatement): bool + { + if ( + $earlyTerminationStatement instanceof Break_ + ) { + return ($this->respectEarlyTermination & self::EARLY_TERMINATION_BREAK) === self::EARLY_TERMINATION_BREAK; + } + + if ( + $earlyTerminationStatement instanceof Continue_ + ) { + return ($this->respectEarlyTermination & self::EARLY_TERMINATION_CONTINUE) === self::EARLY_TERMINATION_CONTINUE; + } + + return ($this->respectEarlyTermination & self::EARLY_TERMINATION_STOP) === self::EARLY_TERMINATION_STOP; + } + + public function shouldIntersectVariables(?\PhpParser\Node $earlyTerminationStatement): bool + { + if ($earlyTerminationStatement === null) { + return true; + } + + if ($this->shouldSkipBranch($earlyTerminationStatement)) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $earlyTerminationStatement instanceof Break_ + || $earlyTerminationStatement instanceof Continue_ + || ($this->respectEarlyTermination & self::EARLY_TERMINATION_STOP) === 0; + } + + public function shouldGeneralizeConstantTypesOfNonIdempotentOperations(): bool + { + return ( + ($this->respectEarlyTermination & self::EARLY_TERMINATION_STOP) === self::EARLY_TERMINATION_STOP + && $this->respectEarlyTermination !== self::EARLY_TERMINATION_ALL + ) || $this->respectEarlyTermination === self::EARLY_TERMINATION_CLOSURE; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/NameScope.php b/vendor/phpstan/phpstan/src/Analyser/NameScope.php new file mode 100644 index 00000000..ec23a060 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/NameScope.php @@ -0,0 +1,57 @@ + fullName(string) */ + private $uses; + + /** @var string|null */ + private $className; + + /** + * @param string|null $namespace + * @param string[] $uses alias(string) => fullName(string) + * @param string|null $className + */ + public function __construct(?string $namespace, array $uses, ?string $className = null) + { + $this->namespace = $namespace; + $this->uses = $uses; + $this->className = $className; + } + + public function getClassName(): ?string + { + return $this->className; + } + + public function resolveStringName(string $name): string + { + if (strpos($name, '\\') === 0) { + return ltrim($name, '\\'); + } + + $nameParts = explode('\\', $name); + $firstNamePart = strtolower($nameParts[0]); + if (isset($this->uses[$firstNamePart])) { + if (count($nameParts) === 1) { + return $this->uses[$firstNamePart]; + } + array_shift($nameParts); + return sprintf('%s\\%s', $this->uses[$firstNamePart], implode('\\', $nameParts)); + } + + if ($this->namespace !== null) { + return sprintf('%s\\%s', $this->namespace, $name); + } + + return $name; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/NodeScopeResolver.php b/vendor/phpstan/phpstan/src/Analyser/NodeScopeResolver.php new file mode 100644 index 00000000..29f509ee --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/NodeScopeResolver.php @@ -0,0 +1,2064 @@ + methods(string[]) */ + private $earlyTerminatingMethodCalls; + + /** @var \PHPStan\Reflection\ClassReflection|null */ + private $anonymousClassReflection; + + /** @var bool[] filePath(string) => bool(true) */ + private $analysedFiles; + + /** + * @param Broker $broker + * @param Parser $parser + * @param FileTypeMapper $fileTypeMapper + * @param FileHelper $fileHelper + * @param TypeSpecifier $typeSpecifier + * @param bool $polluteScopeWithLoopInitialAssignments + * @param bool $polluteCatchScopeWithTryAssignments + * @param bool $polluteScopeWithAlwaysIterableForeach + * @param string[][] $earlyTerminatingMethodCalls className(string) => methods(string[]) + */ + public function __construct( + Broker $broker, + Parser $parser, + FileTypeMapper $fileTypeMapper, + FileHelper $fileHelper, + TypeSpecifier $typeSpecifier, + bool $polluteScopeWithLoopInitialAssignments, + bool $polluteCatchScopeWithTryAssignments, + bool $polluteScopeWithAlwaysIterableForeach, + array $earlyTerminatingMethodCalls + ) + { + $this->broker = $broker; + $this->parser = $parser; + $this->fileTypeMapper = $fileTypeMapper; + $this->fileHelper = $fileHelper; + $this->typeSpecifier = $typeSpecifier; + $this->polluteScopeWithLoopInitialAssignments = $polluteScopeWithLoopInitialAssignments; + $this->polluteCatchScopeWithTryAssignments = $polluteCatchScopeWithTryAssignments; + $this->polluteScopeWithAlwaysIterableForeach = $polluteScopeWithAlwaysIterableForeach; + $this->earlyTerminatingMethodCalls = $earlyTerminatingMethodCalls; + } + + /** + * @param string[] $files + */ + public function setAnalysedFiles(array $files): void + { + $this->analysedFiles = array_fill_keys($files, true); + } + + /** + * @param \PhpParser\Node[] $nodes + * @param \PHPStan\Analyser\Scope $scope + * @param \Closure(\PhpParser\Node $node, Scope $scope): void $nodeCallback + * @param \PHPStan\Analyser\Scope $closureBindScope + */ + public function processNodes( + array $nodes, + Scope $scope, + \Closure $nodeCallback, + ?Scope $closureBindScope = null + ): void + { + $nodesCount = count($nodes); + /** @var \PhpParser\Node|string $node */ + foreach ($nodes as $i => $node) { + if (!($node instanceof \PhpParser\Node)) { + continue; + } + if ($scope->getInFunctionCall() !== null && $node instanceof Arg) { + $functionCall = $scope->getInFunctionCall(); + $value = $node->value; + + $parametersAcceptor = $this->findParametersAcceptorInFunctionCall($functionCall, $scope); + + if ($parametersAcceptor !== null) { + $parameters = $parametersAcceptor->getParameters(); + $assignByReference = false; + if (isset($parameters[$i])) { + $assignByReference = $parameters[$i]->passedByReference()->createsNewVariable(); + } elseif (count($parameters) > 0 && $parametersAcceptor->isVariadic()) { + $lastParameter = $parameters[count($parameters) - 1]; + $assignByReference = $lastParameter->passedByReference()->createsNewVariable(); + } + if ($assignByReference && $value instanceof Variable && is_string($value->name)) { + $scope = $scope->assignVariable($value->name, new MixedType(), TrinaryLogic::createYes()); + } + } + } + + $nodeScope = $scope; + if ($i === 0 && $closureBindScope !== null) { + $nodeScope = $closureBindScope; + } + + $this->processNode($node, $nodeScope, $nodeCallback); + + if ($i === $nodesCount - 1) { + break; + } + $scope = $this->lookForAssigns( + $scope, + $node, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + ); + + if ($node instanceof If_) { + if ($this->findEarlyTermination($node->stmts, $scope) !== null) { + $scope = $scope->filterByFalseyValue($node->cond); + $this->processNode($node->cond, $scope, function (Node $node, Scope $inScope) use (&$scope): void { + $this->specifyFetchedPropertyForInnerScope($node, $inScope, true, $scope); + }); + } + } elseif ($node instanceof Node\Stmt\Declare_) { + foreach ($node->declares as $declare) { + if ( + $declare->key->name === 'strict_types' + && $declare->value instanceof Node\Scalar\LNumber + && $declare->value->value === 1 + ) { + $scope = $scope->enterDeclareStrictTypes(); + break; + } + } + } elseif ($node instanceof Node\Stmt\Expression) { + $scope = $scope->filterBySpecifiedTypes($this->typeSpecifier->specifyTypesInCondition( + $scope, + $node->expr, + TypeSpecifierContext::createNull() + )); + } + } + } + + private function specifyProperty(Scope $scope, Expr $expr): Scope + { + if ( + $expr instanceof PropertyFetch + && $expr->name instanceof Node\Identifier + ) { + return $scope->filterByTruthyValue( + new FuncCall( + new Node\Name('property_exists'), + [ + new Arg($expr->var), + new Arg(new Node\Scalar\String_($expr->name->name)), + ] + ) + ); + } elseif ( + $expr instanceof Expr\StaticPropertyFetch + ) { + if ( + $expr->class instanceof Name + ) { + if ((string) $expr->class === 'static') { + return $scope->specifyFetchedStaticPropertyFromIsset($expr); + } + } elseif ($expr->name instanceof Node\VarLikeIdentifier) { + return $scope->filterByTruthyValue( + new FuncCall( + new Node\Name('property_exists'), + [ + new Arg($expr->class), + new Arg(new Node\Scalar\String_($expr->name->name)), + ] + ) + ); + } + } + + return $scope; + } + + private function specifyFetchedPropertyForInnerScope(Node $node, Scope $inScope, bool $inEarlyTermination, Scope &$scope): void + { + if ($inEarlyTermination === $inScope->isNegated()) { + if ($node instanceof Isset_) { + foreach ($node->vars as $var) { + $scope = $this->specifyProperty($scope, $var); + } + } + } else { + if ($node instanceof Expr\Empty_) { + $scope = $this->specifyProperty($scope, $node->expr); + } + } + } + + private function lookForArrayDestructuringArray(Scope $scope, Node $node, Type $valueType): Scope + { + if ($node instanceof Array_ || $node instanceof List_) { + foreach ($node->items as $key => $item) { + /** @var \PhpParser\Node\Expr\ArrayItem|null $itemValue */ + $itemValue = $item; + if ($itemValue === null) { + continue; + } + + $keyType = $itemValue->key === null ? new ConstantIntegerType($key) : $scope->getType($itemValue->key); + $scope = $this->specifyItemFromArrayDestructuring($scope, $itemValue, $valueType, $keyType); + } + } elseif ($node instanceof Variable && is_string($node->name)) { + $scope = $scope->assignVariable($node->name, new MixedType(), TrinaryLogic::createYes()); + } elseif ($node instanceof ArrayDimFetch && $node->var instanceof Variable && is_string($node->var->name)) { + $scope = $scope->assignVariable( + $node->var->name, + new MixedType(), + TrinaryLogic::createYes() + ); + } + + return $scope; + } + + private function specifyItemFromArrayDestructuring(Scope $scope, ArrayItem $arrayItem, Type $valueType, Type $keyType): Scope + { + $type = $valueType->getOffsetValueType($keyType); + + $itemNode = $arrayItem->value; + if ($itemNode instanceof Variable && is_string($itemNode->name)) { + $scope = $scope->assignVariable($itemNode->name, $type, TrinaryLogic::createYes()); + } elseif ($itemNode instanceof ArrayDimFetch && $itemNode->var instanceof Variable && is_string($itemNode->var->name)) { + $currentType = $scope->hasVariableType($itemNode->var->name)->no() + ? new ConstantArrayType([], []) + : $scope->getVariableType($itemNode->var->name); + $dimType = null; + if ($itemNode->dim !== null) { + $dimType = $scope->getType($itemNode->dim); + } + $scope = $scope->assignVariable( + $itemNode->var->name, + $currentType->setOffsetValueType($dimType, $type), + TrinaryLogic::createYes() + ); + } else { + $scope = $this->lookForArrayDestructuringArray($scope, $itemNode, $type); + } + + return $scope; + } + + private function enterForeach(Scope $scope, Foreach_ $node): Scope + { + if ($node->keyVar !== null && $node->keyVar instanceof Variable && is_string($node->keyVar->name)) { + $scope = $scope->assignVariable($node->keyVar->name, new MixedType(), TrinaryLogic::createYes()); + } + + $comment = CommentHelper::getDocComment($node); + if ($node->valueVar instanceof Variable && is_string($node->valueVar->name)) { + $scope = $scope->enterForeach( + $node->expr, + $node->valueVar->name, + $node->keyVar !== null + && $node->keyVar instanceof Variable + && is_string($node->keyVar->name) + ? $node->keyVar->name + : null + ); + if ($comment !== null) { + $scope = $this->processVarAnnotation($scope, $node->valueVar->name, $comment, true); + } + } + + if ( + $node->keyVar instanceof Variable && is_string($node->keyVar->name) + && $comment !== null + ) { + $scope = $this->processVarAnnotation($scope, $node->keyVar->name, $comment, true); + } + + if ($node->valueVar instanceof List_ || $node->valueVar instanceof Array_) { + $itemTypes = []; + $exprType = $scope->getType($node->expr); + $arrayTypes = TypeUtils::getArrays($exprType); + foreach ($arrayTypes as $arrayType) { + $itemTypes[] = $arrayType->getItemType(); + } + + $itemType = count($itemTypes) > 0 ? TypeCombinator::union(...$itemTypes) : new MixedType(); + $scope = $this->lookForArrayDestructuringArray($scope, $node->valueVar, $itemType); + } + + return $this->lookForAssigns($scope, $node->valueVar, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + } + + /** + * @param \PhpParser\Node $node + * @param Scope $scope + * @param \Closure(\PhpParser\Node $node, Scope $scope): void $nodeCallback + * @param bool $stopImmediately + */ + private function processNode(\PhpParser\Node $node, Scope $scope, \Closure $nodeCallback, bool $stopImmediately = false): void + { + $nodeCallback($node, $scope); + if ($stopImmediately) { + return; + } + + if ( + $node instanceof \PhpParser\Node\Stmt\ClassLike + ) { + if ($node instanceof Node\Stmt\Trait_) { + return; + } + if (isset($node->namespacedName)) { + $scope = $scope->enterClass($this->broker->getClass((string) $node->namespacedName)); + } elseif ($this->anonymousClassReflection !== null) { + $scope = $scope->enterAnonymousClass($this->anonymousClassReflection); + } else { + throw new \PHPStan\ShouldNotHappenException(); + } + } elseif ($node instanceof Node\Stmt\TraitUse) { + $this->processTraitUse($node, $scope, $nodeCallback); + } elseif ($node instanceof \PhpParser\Node\Stmt\Function_) { + $scope = $this->enterFunction($scope, $node); + } elseif ($node instanceof \PhpParser\Node\Stmt\ClassMethod) { + $scope = $this->enterClassMethod($scope, $node); + $nodeCallback(new InClassMethodNode($node), $scope); + } elseif ($node instanceof \PhpParser\Node\Stmt\Namespace_) { + $scope = $scope->enterNamespace((string) $node->name); + } elseif ( + $node instanceof \PhpParser\Node\Expr\StaticCall + && $node->class instanceof \PhpParser\Node\Name + && $node->name instanceof Node\Identifier + && (string) $node->class === 'Closure' + && $node->name->name === 'bind' + ) { + $thisType = null; + if (isset($node->args[1])) { + $argValue = $node->args[1]->value; + if ($argValue instanceof Expr\ConstFetch && ((string) $argValue->name === 'null')) { + $thisType = null; + } else { + $thisType = $scope->getType($argValue); + } + } + $scopeClass = 'static'; + if (isset($node->args[2])) { + $argValue = $node->args[2]->value; + $argValueType = $scope->getType($argValue); + + $directClassNames = TypeUtils::getDirectClassNames($argValueType); + if (count($directClassNames) === 1) { + $scopeClass = $directClassNames[0]; + } elseif ( + $argValue instanceof Expr\ClassConstFetch + && $argValue->name instanceof Node\Identifier + && strtolower($argValue->name->name) === 'class' + && $argValue->class instanceof Name + ) { + $scopeClass = $scope->resolveName($argValue->class); + } elseif ($argValueType instanceof ConstantStringType) { + $scopeClass = $argValueType->getValue(); + } + } + $closureBindScope = $scope->enterClosureBind($thisType, $scopeClass); + } elseif ($node instanceof Foreach_) { + $scope = $scope->exitFirstLevelStatements(); + $this->processNode($node->expr, $scope, $nodeCallback); + $scope = $this->lookForAssigns($scope, $node->expr, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + if ($node->keyVar !== null) { + $this->processNode($node->keyVar, $scope->enterExpressionAssign($node->keyVar), $nodeCallback); + } + $this->processNode( + $node->valueVar, + $this->lookForEnterVariableAssign($scope, $node->valueVar), + $nodeCallback + ); + + $scope = $this->lookForAssignsInBranches($scope, [ + new StatementList($scope, $node->stmts, false, function (Scope $scope) use ($node): Scope { + return $this->enterForeach($scope, $node); + }), + new StatementList($scope, []), + ], LookForAssignsSettings::insideLoop()); + $scope = $this->enterForeach($scope, $node); + + $this->processNodes($node->stmts, $scope->enterFirstLevelStatements(), $nodeCallback); + + return; + } elseif ($node instanceof For_) { + $this->processNodes($node->init, $scope, $nodeCallback); + + foreach ($node->init as $initExpr) { + $scope = $this->lookForAssigns($scope, $initExpr, TrinaryLogic::createYes(), LookForAssignsSettings::insideLoop()); + } + $scopeLoopMightHaveRun = $this->lookForAssignsInBranches($scope, [ + new StatementList($scope, $node->cond), + new StatementList($scope, $node->stmts), + new StatementList($scope, $node->loop), + new StatementList($scope, []), + ], LookForAssignsSettings::insideLoop()); + + $this->processNodes($node->cond, $scopeLoopMightHaveRun, $nodeCallback); + + $scopeLoopDefinitelyRan = $this->lookForAssignsInBranches($scope, [ + new StatementList($scope, $node->stmts, false, static function (Scope $scope) use ($node): Scope { + foreach ($node->cond as $condExpr) { + $scope = $scope->filterByTruthyValue($condExpr); + } + + return $scope; + }), + ], LookForAssignsSettings::insideLoop()); + + $this->processNodes($node->loop, $scopeLoopDefinitelyRan, $nodeCallback); + + foreach ($node->cond as $condExpr) { + $scopeLoopMightHaveRun = $this->lookForAssigns($scopeLoopMightHaveRun, $condExpr, TrinaryLogic::createYes(), LookForAssignsSettings::insideLoop()); + } + + foreach ($node->cond as $condExpr) { + $scopeLoopMightHaveRun = $scopeLoopMightHaveRun->filterByTruthyValue($condExpr); + } + $this->processNodes($node->stmts, $scopeLoopMightHaveRun, $nodeCallback); + + return; + } elseif ($node instanceof While_) { + $bodyScope = $this->lookForAssigns( + $scope, + $node->cond, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + ); + $condScope = $this->lookForAssignsInBranches($scope, [ + new StatementList($bodyScope, $node->stmts, false, static function (Scope $scope) use ($node): Scope { + return $scope->filterByTruthyValue($node->cond); + }), + new StatementList($scope, []), + ], LookForAssignsSettings::insideLoop()); + $this->processNode($node->cond, $condScope, $nodeCallback); + + $bodyScope = $this->lookForAssignsInBranches($bodyScope, [ + new StatementList($bodyScope, $node->stmts, false, static function (Scope $scope) use ($node): Scope { + return $scope->filterByTruthyValue($node->cond); + }), + new StatementList($bodyScope, []), + ], LookForAssignsSettings::insideLoop()); + $bodyScope = $this->lookForAssigns($bodyScope, $node->cond, TrinaryLogic::createYes(), LookForAssignsSettings::insideLoop()); + $bodyScope = $bodyScope->filterByTruthyValue($node->cond); + $this->processNodes($node->stmts, $bodyScope, $nodeCallback); + return; + } elseif ($node instanceof Catch_) { + if (!is_string($node->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $scope = $scope->enterCatch( + $node->types, + $node->var->name + ); + } elseif ($node instanceof Array_) { + $scope = $scope->exitFirstLevelStatements(); + foreach ($node->items as $item) { + if ($item === null) { + continue; + } + $this->processNode($item, $scope, $nodeCallback); + if ($item->key !== null) { + $scope = $this->lookForAssigns($scope, $item->key, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + } + $scope = $this->lookForAssigns($scope, $item->value, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + } + + return; + } elseif ($node instanceof Expr\Closure) { + $this->processNodes($node->uses, $scope, $nodeCallback); + $usesByRef = []; + foreach ($node->uses as $closureUse) { + if (!$closureUse->byRef) { + continue; + } + + $usesByRef[] = $closureUse; + } + + if (count($usesByRef) > 0) { + $closureScope = $this->lookForAssignsInBranches($scope, [ + new StatementList($scope, $node->stmts), + new StatementList($scope, []), + ], LookForAssignsSettings::insideClosure()); + /** @var Expr\ClosureUse $closureUse */ + foreach ($usesByRef as $closureUse) { + if (!is_string($closureUse->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $variableCertainty = $closureScope->hasVariableType($closureUse->var->name); + if ($variableCertainty->no()) { + continue; + } + $scope = $scope->assignVariable( + $closureUse->var->name, + $closureScope->getVariableType($closureUse->var->name), + $variableCertainty + ); + } + } + + $scope = $scope->enterAnonymousFunction($node); + $this->processNodes($node->stmts, $scope, $nodeCallback); + + return; + } elseif ($node instanceof If_) { + $this->processNode($node->cond, $scope->exitFirstLevelStatements(), $nodeCallback); + $scope = $this->lookForAssigns( + $scope, + $node->cond, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + ); + $ifScope = $scope; + $scope = $scope->filterByTruthyValue($node->cond); + + $specifyFetchedProperty = function (Node $node, Scope $inScope) use (&$scope): void { + $this->specifyFetchedPropertyForInnerScope($node, $inScope, false, $scope); + }; + $this->processNode($node->cond, $scope, $specifyFetchedProperty); + $this->processNodes($node->stmts, $scope->enterFirstLevelStatements(), $nodeCallback); + + if (count($node->elseifs) > 0 || $node->else !== null) { + $elseifScope = $ifScope->filterByFalseyValue($node->cond); + foreach ($node->elseifs as $elseif) { + $scope = $elseifScope; + $this->processNode($elseif, $scope, $nodeCallback, true); + $this->processNode($elseif->cond, $scope->exitFirstLevelStatements(), $nodeCallback); + $scope = $this->lookForAssigns( + $scope, + $elseif->cond, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + ); + $scope = $scope->filterByTruthyValue($elseif->cond); + $this->processNode($elseif->cond, $scope, $specifyFetchedProperty); + $this->processNodes($elseif->stmts, $scope->enterFirstLevelStatements(), $nodeCallback); + $elseifScope = $this->lookForAssigns( + $elseifScope, + $elseif->cond, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + )->filterByFalseyValue($elseif->cond); + } + if ($node->else !== null) { + $this->processNode($node->else, $elseifScope, $nodeCallback); + } + } + + return; + } elseif ($node instanceof Switch_) { + $scope = $scope->exitFirstLevelStatements(); + $this->processNode($node->cond, $scope, $nodeCallback); + $scope = $this->lookForAssigns( + $scope, + $node->cond, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + ); + $switchScope = $scope; + $switchConditionType = $scope->getType($node->cond)->toBoolean(); + $switchConditionIsTrue = $switchConditionType instanceof ConstantBooleanType && $switchConditionType->getValue(); + $switchConditionGetClassExpression = null; + if ( + $node->cond instanceof FuncCall + && $node->cond->name instanceof Name + && strtolower((string) $node->cond->name) === 'get_class' + && isset($node->cond->args[0]) + ) { + $switchConditionGetClassExpression = $node->cond->args[0]->value; + } + foreach ($node->cases as $caseNode) { + $this->processNode($caseNode, $scope, $nodeCallback, true); + if ($caseNode->cond !== null) { + $this->processNode($caseNode->cond, $switchScope, $nodeCallback); + $switchScope = $this->lookForAssigns( + $switchScope, + $caseNode->cond, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + ); + $scope = $this->lookForAssigns( + $scope, + $caseNode->cond, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + ); + + $caseScope = $switchScope; + if ($switchConditionIsTrue) { + $caseScope = $caseScope->filterByTruthyValue($caseNode->cond); + } elseif ( + $switchConditionGetClassExpression !== null + && $caseNode->cond instanceof Expr\ClassConstFetch + && $caseNode->cond->class instanceof Name + && $caseNode->cond->name instanceof Node\Identifier + && strtolower($caseNode->cond->name->name) === 'class' + ) { + $caseScope = $caseScope->specifyExpressionType( + $switchConditionGetClassExpression, + new ObjectType($scope->resolveName($caseNode->cond->class)) + ); + } + } else { + $caseScope = $switchScope; + } + $this->processNodes( + $caseNode->stmts, + $caseScope->enterFirstLevelStatements(), + $nodeCallback + ); + if ($this->findEarlyTermination($caseNode->stmts, $switchScope) === null) { + foreach ($caseNode->stmts as $statement) { + $switchScope = $this->lookForAssigns($switchScope, $statement, TrinaryLogic::createMaybe(), LookForAssignsSettings::default()); + } + } else { + $switchScope = $scope; + } + } + return; + } elseif ($node instanceof TryCatch) { + $statements = []; + $this->processNodes($node->stmts, $scope->enterFirstLevelStatements(), $nodeCallback); + + $scopeForLookForAssignsInBranches = $scope; + $tryAssignmentsCertainty = $this->polluteCatchScopeWithTryAssignments ? TrinaryLogic::createYes() : TrinaryLogic::createMaybe(); + foreach ($node->stmts as $statement) { + $scope = $this->lookForAssigns($scope, $statement, $tryAssignmentsCertainty, LookForAssignsSettings::default()); + } + + if ($node->finally !== null) { + $statements[] = new StatementList($scopeForLookForAssignsInBranches, $node->stmts); + $statements[] = new StatementList($scopeForLookForAssignsInBranches, []); + } + + foreach ($node->catches as $catch) { + $this->processNode($catch, $scope, $nodeCallback); + if ($node->finally === null) { + continue; + } + + if (!is_string($catch->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $statements[] = new StatementList($scope->enterCatch( + $catch->types, + $catch->var->name + ), $catch->stmts); + } + + if ($node->finally !== null) { + $finallyScope = $this->lookForAssignsInBranches($scopeForLookForAssignsInBranches, $statements, LookForAssignsSettings::insideFinally()); + + $this->processNode($node->finally, $finallyScope, $nodeCallback); + } + + return; + } elseif ($node instanceof FuncCall) { + $scope = $scope->enterFunctionCall($node); + } elseif ($node instanceof Expr\StaticCall) { + $scope = $scope->enterFunctionCall($node); + } elseif ($node instanceof MethodCall) { + if ( + $node->var instanceof Expr\Closure + && $node->name instanceof Node\Identifier + && $node->name->name === 'call' + && isset($node->args[0]) + ) { + $closureCallScope = $scope->enterClosureCall($scope->getType($node->args[0]->value)); + } + $scope = $scope->enterFunctionCall($node); + } elseif ($node instanceof New_ && $node->class instanceof Class_) { + $this->anonymousClassReflection = $this->broker->getAnonymousClassReflection($node, $scope); + } elseif ($node instanceof BooleanNot) { + $scope = $scope->enterNegation(); + } elseif ($node instanceof Unset_ || $node instanceof Isset_) { + foreach ($node->vars as $unsetVar) { + if ($unsetVar instanceof ArrayDimFetch && $unsetVar->dim === null) { + continue; + } + + while ( + $unsetVar instanceof ArrayDimFetch + || $unsetVar instanceof PropertyFetch + || ( + $unsetVar instanceof StaticPropertyFetch + && $unsetVar->class instanceof Expr + ) + ) { + $scope = $scope->enterExpressionAssign($unsetVar); + if ($unsetVar instanceof StaticPropertyFetch) { + /** @var Expr $unsetVar */ + $unsetVar = $unsetVar->class; + } else { + $unsetVar = $unsetVar->var; + } + } + + $scope = $scope->enterExpressionAssign($unsetVar); + } + } elseif ($node instanceof Node\Stmt\Global_) { + foreach ($node->vars as $var) { + $scope = $scope->enterExpressionAssign($var); + } + } + + $originalScope = $scope; + foreach ($node->getSubNodeNames() as $subNodeName) { + $scope = $originalScope; + $subNode = $node->{$subNodeName}; + + if (is_array($subNode)) { + $argClosureBindScope = null; + if (isset($closureBindScope) && $subNodeName === 'args') { + $argClosureBindScope = $closureBindScope; + } + if ($subNodeName === 'stmts') { + $scope = $scope->enterFirstLevelStatements(); + } else { + $scope = $scope->exitFirstLevelStatements(); + } + + if ($node instanceof Isset_ && $subNodeName === 'vars') { + foreach ($node->vars as $issetVar) { + $scope = $this->specifyProperty($scope, $issetVar); + $scope = $this->ensureNonNullability($scope, $issetVar, true); + } + } + + if ($node instanceof MethodCall && $subNodeName === 'args') { + $scope = $this->lookForAssigns($scope, $node->var, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + } + + if ($node instanceof Do_ && $subNodeName === 'stmts') { + $scope = $this->lookForAssignsInBranches($scope, [ + new StatementList($scope, $node->stmts), + new StatementList($scope, [$node->cond], true), + new StatementList($scope, []), + ], LookForAssignsSettings::insideLoop()); + } + + $this->processNodes($subNode, $scope, $nodeCallback, $argClosureBindScope); + } elseif ($subNode instanceof \PhpParser\Node) { + if ($node instanceof Coalesce && $subNodeName === 'left') { + $scope = $this->ensureNonNullability($scope, $subNode, false); + + if (!($node->left instanceof ArrayDimFetch) || $node->left->dim !== null) { + $scope = $this->lookForEnterVariableAssign($scope, $node->left); + } + } + + if ( + ($node instanceof BooleanAnd || $node instanceof BinaryOp\LogicalAnd) + && $subNodeName === 'right') { + $scope = $scope->filterByTruthyValue($node->left); + } + if ( + ($node instanceof BooleanOr || $node instanceof BinaryOp\LogicalOr) + && $subNodeName === 'right') { + $scope = $scope->filterByFalseyValue($node->left); + } + + if ($node instanceof Assign || $node instanceof AssignRef) { + if ($subNodeName === 'var') { + $scope = $this->lookForEnterVariableAssign($scope, $node->var); + } elseif ($subNodeName === 'expr') { + $scope = $this->lookForEnterVariableAssign($scope, $node); + } + } + + if ($node instanceof BinaryOp && $subNodeName === 'right') { + $scope = $this->lookForAssigns($scope, $node->left, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + } + + if ($node instanceof Expr\Empty_ && $subNodeName === 'expr') { + $scope = $this->specifyProperty($scope, $node->expr); + + if (!($node->expr instanceof ArrayDimFetch) || $node->expr->dim !== null) { + $scope = $this->lookForEnterVariableAssign($scope, $node->expr); + } + } + + if ( + $node instanceof ArrayItem + && $subNodeName === 'value' + && $node->key !== null + ) { + $scope = $this->lookForAssigns($scope, $node->key, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + } + + if ( + $node instanceof Ternary + && $subNodeName !== 'cond' + ) { + $scope = $this->lookForAssigns($scope, $node->cond, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + if ($subNodeName === 'if') { + $scope = $scope->filterByTruthyValue($node->cond); + $this->processNode($node->cond, $scope, function (Node $node, Scope $inScope) use (&$scope): void { + $this->specifyFetchedPropertyForInnerScope($node, $inScope, false, $scope); + }); + } elseif ($subNodeName === 'else') { + $scope = $scope->filterByFalseyValue($node->cond); + $this->processNode($node->cond, $scope, function (Node $node, Scope $inScope) use (&$scope): void { + $this->specifyFetchedPropertyForInnerScope($node, $inScope, true, $scope); + }); + } + } + + if ($node instanceof Do_ && $subNodeName === 'cond') { + foreach ($node->stmts as $statement) { + $scope = $this->lookForAssigns($scope, $statement, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + } + } + + if ($node instanceof Expr\Empty_ && $subNodeName === 'expr') { + $scope = $this->ensureNonNullability($scope, $subNode, true); + } + + if ($node instanceof StaticVar && $subNodeName === 'var') { + $scope = $scope->enterExpressionAssign($node->var); + } elseif ($node instanceof Expr\ClosureUse && $subNodeName === 'var') { + $scope = $scope->enterExpressionAssign($node->var); + } + + $nodeScope = $scope; + if (!$node instanceof ErrorSuppress && !$node instanceof Node\Stmt\Expression) { + $nodeScope = $nodeScope->exitFirstLevelStatements(); + } + if ($scope->isInFirstLevelStatement()) { + if ($node instanceof Ternary && $subNodeName !== 'cond') { + $nodeScope = $scope->enterFirstLevelStatements(); + } elseif ( + ($node instanceof BooleanAnd || $node instanceof BinaryOp\BooleanOr) + && $subNodeName === 'right' + ) { + $nodeScope = $scope->enterFirstLevelStatements(); + } + } + + if ($node instanceof MethodCall && $subNodeName === 'var' && isset($closureCallScope)) { + $nodeScope = $closureCallScope->exitFirstLevelStatements(); + } + + $this->processNode($subNode, $nodeScope, $nodeCallback); + } + } + } + + private function ensureNonNullability( + Scope $scope, + Node $node, + bool $findMethods + ): Scope + { + $nodeToSpecify = $node; + while ( + $nodeToSpecify instanceof PropertyFetch + || $nodeToSpecify instanceof StaticPropertyFetch + || ( + $findMethods && ( + $nodeToSpecify instanceof MethodCall + || $nodeToSpecify instanceof StaticCall + ) + ) + ) { + if ( + $nodeToSpecify instanceof PropertyFetch + || $nodeToSpecify instanceof MethodCall + ) { + $nodeToSpecify = $nodeToSpecify->var; + } elseif ($nodeToSpecify->class instanceof Expr) { + $nodeToSpecify = $nodeToSpecify->class; + } else { + break; + } + + $scope = $scope->specifyExpressionType( + $nodeToSpecify, + TypeCombinator::removeNull($scope->getType($nodeToSpecify)) + ); + } + + return $scope; + } + + private function lookForEnterVariableAssign(Scope $scope, Expr $node): Scope + { + if ($node instanceof Variable) { + $scope = $scope->enterExpressionAssign($node); + } elseif ($node instanceof ArrayDimFetch) { + while ($node instanceof ArrayDimFetch) { + $scope = $scope->enterExpressionAssign($node); + $node = $node->var; + } + + if ($node instanceof Variable) { + $scope = $scope->enterExpressionAssign($node); + } + } elseif ($node instanceof List_ || $node instanceof Array_) { + foreach ($node->items as $listItem) { + if ($listItem === null) { + continue; + } + + $scope = $this->lookForEnterVariableAssign($scope, $listItem->value); + } + } elseif ($node instanceof AssignRef) { + $scope = $scope->enterExpressionAssign($node->expr); + } elseif ($node instanceof Assign && $node->expr instanceof Expr\Closure) { + foreach ($node->expr->uses as $closureUse) { + if ( + !$closureUse->byRef + || !$node->var instanceof Variable + || !is_string($closureUse->var->name) + || $node->var->name !== $closureUse->var->name + ) { + continue; + } + + $scope = $scope->enterExpressionAssign(new Variable($closureUse->var->name)); + } + } else { + $scope = $scope->enterExpressionAssign($node); + } + + return $scope; + } + + private function lookForAssigns( + Scope $scope, + \PhpParser\Node $node, + TrinaryLogic $certainty, + LookForAssignsSettings $lookForAssignsSettings + ): Scope + { + if ($node instanceof Node\Stmt\Expression) { + $node = $node->expr; + } + + if ($node instanceof StaticVar) { + if (!is_string($node->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $scope = $scope->assignVariable( + $node->var->name, + new MixedType(), + $certainty + ); + } elseif ($node instanceof Static_) { + foreach ($node->vars as $var) { + $scope = $this->lookForAssigns($scope, $var, $certainty, $lookForAssignsSettings); + } + } elseif ($node instanceof If_) { + $conditionType = $scope->getType($node->cond)->toBoolean(); + $scope = $this->lookForAssigns($scope, $node->cond, $certainty, $lookForAssignsSettings); + $statements = []; + + if (!$conditionType instanceof ConstantBooleanType || $conditionType->getValue()) { + $statements[] = new StatementList( + $scope, + array_merge([$node->cond], $node->stmts), + false, + static function (Scope $scope) use ($node): Scope { + return $scope->filterByTruthyValue($node->cond); + } + ); + } + + if (!$conditionType instanceof ConstantBooleanType || !$conditionType->getValue()) { + $lastElseIfConditionIsTrue = false; + $elseIfScope = $scope; + $lastCond = $node->cond; + foreach ($node->elseifs as $elseIf) { + $elseIfScope = $elseIfScope->filterByFalseyValue($lastCond); + $lastCond = $elseIf->cond; + $elseIfConditionType = $elseIfScope->getType($elseIf->cond)->toBoolean(); + if ( + $elseIfConditionType instanceof ConstantBooleanType + && !$elseIfConditionType->getValue() + ) { + continue; + } + $statements[] = new StatementList( + $elseIfScope, + array_merge([$elseIf->cond], $elseIf->stmts), + false, + static function (Scope $scope) use ($elseIf): Scope { + return $scope->filterByTruthyValue($elseIf->cond); + } + ); + if ( + $elseIfConditionType instanceof ConstantBooleanType + && $elseIfConditionType->getValue() + ) { + $lastElseIfConditionIsTrue = true; + break; + } + } + + if (!$lastElseIfConditionIsTrue) { + $statements[] = new StatementList( + $elseIfScope, + $node->else !== null ? $node->else->stmts : [], + false, + static function (Scope $scope) use ($lastCond): Scope { + return $scope->filterByFalseyValue($lastCond); + } + ); + } + } + + $scope = $this->lookForAssignsInBranches($scope, $statements, $lookForAssignsSettings); + } elseif ($node instanceof TryCatch) { + $statements = [ + new StatementList($scope, $node->stmts), + ]; + foreach ($node->catches as $catch) { + if (!is_string($catch->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $statements[] = new StatementList($scope->enterCatch( + $catch->types, + $catch->var->name + ), array_merge([new Node\Stmt\Nop()], $catch->stmts)); + } + + $scope = $this->lookForAssignsInBranches($scope, $statements, $lookForAssignsSettings); + if ($node->finally !== null) { + foreach ($node->finally->stmts as $statement) { + $scope = $this->lookForAssigns($scope, $statement, $certainty, $lookForAssignsSettings); + } + } + } elseif ($node instanceof MethodCall || $node instanceof FuncCall || $node instanceof Expr\StaticCall) { + if ($node instanceof MethodCall) { + $scope = $this->lookForAssigns($scope, $node->var, $certainty, $lookForAssignsSettings); + } + foreach ($node->args as $argument) { + $scope = $this->lookForAssigns($scope, $argument, $certainty, $lookForAssignsSettings); + } + + $parametersAcceptor = $this->findParametersAcceptorInFunctionCall($node, $scope); + + if ($parametersAcceptor !== null) { + $parameters = $parametersAcceptor->getParameters(); + foreach ($node->args as $i => $arg) { + $assignByReference = false; + if (isset($parameters[$i])) { + $assignByReference = $parameters[$i]->passedByReference()->createsNewVariable(); + } elseif (count($parameters) > 0 && $parametersAcceptor->isVariadic()) { + $lastParameter = $parameters[count($parameters) - 1]; + $assignByReference = $lastParameter->passedByReference()->createsNewVariable(); + } + + if (!$assignByReference) { + continue; + } + + $arg = $node->args[$i]->value; + if (!($arg instanceof Variable) || !is_string($arg->name)) { + continue; + } + + $scope = $scope->assignVariable($arg->name, new MixedType(), $certainty); + } + } + if ( + $node instanceof FuncCall + && $node->name instanceof Name + && in_array((string) $node->name, [ + 'fopen', + 'file_get_contents', + ], true) + ) { + $scope = $scope->assignVariable('http_response_header', new ArrayType(new IntegerType(), new StringType()), $certainty); + } + + if ( + $node instanceof FuncCall + && $node->name instanceof Name + && in_array(strtolower((string) $node->name), [ + 'array_push', + 'array_unshift', + ], true) + && count($node->args) >= 2 + ) { + $argumentTypes = []; + foreach (array_slice($node->args, 1) as $callArg) { + $callArgType = $scope->getType($callArg->value); + if ($callArg->unpack) { + $iterableValueType = $callArgType->getIterableValueType(); + if ($iterableValueType instanceof UnionType) { + foreach ($iterableValueType->getTypes() as $innerType) { + $argumentTypes[] = $innerType; + } + } else { + $argumentTypes[] = $iterableValueType; + } + continue; + } + + $argumentTypes[] = $callArgType; + } + + $arrayArg = $node->args[0]->value; + $originalArrayType = $scope->getType($arrayArg); + $functionName = strtolower((string) $node->name); + $constantArrays = TypeUtils::getConstantArrays($originalArrayType); + if ( + $functionName === 'array_push' + || ($originalArrayType instanceof ArrayType && count($constantArrays) === 0) + ) { + $arrayType = $originalArrayType; + foreach ($argumentTypes as $argType) { + $arrayType = $arrayType->setOffsetValueType(null, $argType); + } + + $scope = $scope->specifyExpressionType($arrayArg, $arrayType); + } elseif (count($constantArrays) > 0) { + $defaultArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); + foreach ($argumentTypes as $argType) { + $defaultArrayBuilder->setOffsetValueType(null, $argType); + } + + $defaultArrayType = $defaultArrayBuilder->getArray(); + + $arrayTypes = []; + foreach ($constantArrays as $constantArray) { + $arrayType = $defaultArrayType; + foreach ($constantArray->getKeyTypes() as $i => $keyType) { + $valueType = $constantArray->getValueTypes()[$i]; + if ($keyType instanceof ConstantIntegerType) { + $keyType = null; + } + $arrayType = $arrayType->setOffsetValueType($keyType, $valueType); + } + $arrayTypes[] = $arrayType; + } + + $scope = $scope->specifyExpressionType( + $arrayArg, + TypeCombinator::union(...$arrayTypes) + ); + } + } + if ( + $node instanceof FuncCall + && $node->name instanceof Name + && in_array(strtolower((string) $node->name), [ + 'array_pop', + 'array_shift', + ], true) + && count($node->args) >= 1 + ) { + $arrayArg = $node->args[0]->value; + $constantArrays = TypeUtils::getConstantArrays($scope->getType($arrayArg)); + $functionName = strtolower((string) $node->name); + if (count($constantArrays) > 0) { + $resultArrayTypes = []; + + foreach ($constantArrays as $constantArray) { + if ($functionName === 'array_pop') { + $resultArrayTypes[] = $constantArray->removeLast(); + } else { + $resultArrayTypes[] = $constantArray->removeFirst(); + } + } + + $scope = $scope->specifyExpressionType( + $arrayArg, + TypeCombinator::union(...$resultArrayTypes) + ); + } + } + } elseif ($node instanceof BinaryOp) { + $scope = $this->lookForAssigns($scope, $node->left, $certainty, $lookForAssignsSettings); + $scope = $this->lookForAssigns($scope, $node->right, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof Arg) { + $scope = $this->lookForAssigns($scope, $node->value, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof BooleanNot) { + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof Ternary) { + $scope = $this->lookForAssigns($scope, $node->cond, $certainty, $lookForAssignsSettings); + $statements = []; + if ($node->if !== null) { + $statements[] = new StatementList( + $scope->filterByTruthyValue($node->cond), + [$node->if] + ); + } else { + $statements[] = new StatementList( + $scope->filterByTruthyValue($node->cond), + [$node->cond] + ); + } + + $statements[] = new StatementList( + $scope->filterByFalseyValue($node->cond), + [$node->else] + ); + $scope = $this->lookForAssignsInBranches($scope, $statements, $lookForAssignsSettings); + } elseif ($node instanceof Array_) { + foreach ($node->items as $item) { + if ($item === null) { + continue; + } + if ($item->key !== null) { + $scope = $this->lookForAssigns($scope, $item->key, $certainty, $lookForAssignsSettings); + } + $scope = $this->lookForAssigns($scope, $item->value, $certainty, $lookForAssignsSettings); + } + } elseif ($node instanceof New_) { + foreach ($node->args as $arg) { + $scope = $this->lookForAssigns($scope, $arg, $certainty, $lookForAssignsSettings); + } + } elseif ($node instanceof Do_) { + $scope = $this->lookForAssignsInBranches($scope, [ + new StatementList($scope, $node->stmts), + ], LookForAssignsSettings::afterLoop()); + $scope = $this->lookForAssigns($scope, $node->cond, TrinaryLogic::createYes(), LookForAssignsSettings::afterLoop()); + $scope = $scope->filterByFalseyValue($node->cond); + } elseif ($node instanceof Switch_) { + $scope = $this->lookForAssigns( + $scope, + $node->cond, + TrinaryLogic::createYes(), + LookForAssignsSettings::default() + ); + $statementLists = []; + $tmpStatements = []; + $hasDefault = false; + foreach ($node->cases as $case) { + if ($case->cond === null) { + $hasDefault = true; + } + + foreach ($case->stmts as $statement) { + $tmpStatements[] = $statement; + if ($this->findStatementEarlyTermination($statement, $scope) !== null) { + $statementLists[] = new StatementList($scope, $tmpStatements); + $tmpStatements = []; + break; + } + } + } + + if (count($tmpStatements) > 0) { + $statementLists[] = new StatementList($scope, $tmpStatements); + } + + if (!$hasDefault) { + $statementLists[] = new StatementList($scope, []); + } + + $scope = $this->lookForAssignsInBranches($scope, $statementLists, LookForAssignsSettings::afterSwitch()); + } elseif ($node instanceof Cast) { + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof For_) { + $forAssignmentsCertainty = $this->polluteScopeWithLoopInitialAssignments ? TrinaryLogic::createYes() : TrinaryLogic::createMaybe(); + foreach ($node->init as $initExpr) { + $scope = $this->lookForAssigns($scope, $initExpr, $forAssignmentsCertainty, LookForAssignsSettings::afterLoop()); + } + + foreach ($node->cond as $condExpr) { + $scope = $this->lookForAssigns($scope, $condExpr, $forAssignmentsCertainty, LookForAssignsSettings::afterLoop()); + } + + $statements = [ + new StatementList($scope, $node->stmts), + new StatementList($scope, []), // in order not to add variables existing only inside the for loop + ]; + $scope = $this->lookForAssignsInBranches($scope, $statements, LookForAssignsSettings::afterLoop()); + foreach ($node->loop as $loopExpr) { + $scope = $this->lookForAssigns($scope, $loopExpr, TrinaryLogic::createMaybe(), LookForAssignsSettings::afterLoop()); + } + } elseif ($node instanceof While_) { + $whileAssignmentsCertainty = $this->polluteScopeWithLoopInitialAssignments ? TrinaryLogic::createYes() : TrinaryLogic::createMaybe(); + $scope = $this->lookForAssigns($scope, $node->cond, $whileAssignmentsCertainty, LookForAssignsSettings::afterLoop()); + + $statements = [ + new StatementList($scope, $node->stmts, false, static function (Scope $scope) use ($node): Scope { + return $scope->filterByTruthyValue($node->cond); + }), + new StatementList($scope, []), // in order not to add variables existing only inside the for loop + ]; + $scope = $this->lookForAssignsInBranches($scope, $statements, LookForAssignsSettings::afterLoop()); + } elseif ($node instanceof ErrorSuppress) { + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof \PhpParser\Node\Stmt\Unset_) { + foreach ($node->vars as $var) { + $scope = $scope->unsetExpression($var); + } + } elseif ($node instanceof Echo_) { + foreach ($node->exprs as $echoedExpr) { + $scope = $this->lookForAssigns($scope, $echoedExpr, $certainty, $lookForAssignsSettings); + } + } elseif ($node instanceof Print_) { + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof Foreach_) { + $iterableAtLeastOnce = $scope->getType($node->expr)->isIterableAtLeastOnce(); + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + if (!$iterableAtLeastOnce->no()) { + $statements = [ + new StatementList($scope, array_merge( + [new Node\Stmt\Nop()], + $node->stmts + ), false, function (Scope $scope) use ($node): Scope { + return $this->enterForeach($scope, $node); + }), + ]; + + if (!$iterableAtLeastOnce->yes() || !$this->polluteScopeWithAlwaysIterableForeach) { + $statements[] = new StatementList($scope, []); + } + + $scope = $this->lookForAssignsInBranches($scope, $statements, LookForAssignsSettings::afterLoop()); + } + } elseif ($node instanceof Isset_) { + foreach ($node->vars as $var) { + $scope = $this->lookForAssigns($scope, $var, $certainty, $lookForAssignsSettings); + } + } elseif ($node instanceof Expr\Empty_ && (!($node->expr instanceof ArrayDimFetch) || $node->expr->dim !== null)) { + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof ArrayDimFetch && $node->dim !== null) { + $scope = $this->lookForAssigns($scope, $node->dim, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof Expr\Closure) { + $closureScope = $scope->enterAnonymousFunction($node); + $statements = [ + new StatementList($closureScope, array_merge( + [new Node\Stmt\Nop()], + $node->stmts + )), + new StatementList($closureScope, []), + ]; + $closureScope = $this->lookForAssignsInBranches($scope, $statements, LookForAssignsSettings::insideClosure()); + foreach ($node->uses as $closureUse) { + if (!$closureUse->byRef) { + continue; + } + + if (!is_string($closureUse->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $variableCertainty = $closureScope->hasVariableType($closureUse->var->name); + if ($variableCertainty->no()) { + continue; + } + + $scope = $scope->assignVariable( + $closureUse->var->name, + $closureScope->getVariableType($closureUse->var->name), + $variableCertainty + ); + } + } elseif ($node instanceof Instanceof_) { + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + } elseif ($node instanceof Expr\Include_) { + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + } elseif ( + ( + $node instanceof Expr\PostInc + || $node instanceof Expr\PostDec + || $node instanceof Expr\PreInc + || $node instanceof Expr\PreDec + ) && ( + $node->var instanceof Variable + || $node->var instanceof ArrayDimFetch + || $node->var instanceof PropertyFetch + || $node->var instanceof StaticPropertyFetch + ) + ) { + $expressionType = $scope->getType($node); + if ($expressionType instanceof ConstantScalarType) { + $afterValue = $expressionType->getValue(); + if ($node instanceof Expr\PostInc) { + $afterValue++; + } elseif ($node instanceof Expr\PostDec) { + $afterValue--; + } + + $newExpressionType = $scope->getTypeFromValue($afterValue); + if ($lookForAssignsSettings->shouldGeneralizeConstantTypesOfNonIdempotentOperations()) { + $newExpressionType = TypeUtils::generalizeType($newExpressionType); + } + + $scope = $this->assignVariable( + $scope, + $node->var, + $certainty, + $newExpressionType + ); + } + } elseif ($node instanceof Expr\Yield_) { + if ($node->key !== null) { + $scope = $this->lookForAssigns($scope, $node->key, $certainty, $lookForAssignsSettings); + } + if ($node->value !== null) { + $scope = $this->lookForAssigns($scope, $node->value, $certainty, $lookForAssignsSettings); + } + } elseif ($node instanceof Expr\YieldFrom) { + $scope = $this->lookForAssigns($scope, $node->expr, $certainty, $lookForAssignsSettings); + } + + $scope = $this->updateScopeForVariableAssign($scope, $node, $certainty, $lookForAssignsSettings); + + return $scope; + } + + private function updateScopeForVariableAssign( + Scope $scope, + \PhpParser\Node $node, + TrinaryLogic $certainty, + LookForAssignsSettings $lookForAssignsSettings + ): Scope + { + if ($node instanceof Assign || $node instanceof AssignRef || $node instanceof Expr\AssignOp || $node instanceof Node\Stmt\Global_) { + if ($node instanceof Assign || $node instanceof AssignRef || $node instanceof Expr\AssignOp) { + $scope = $this->lookForAssigns($scope, $node->var, TrinaryLogic::createYes(), $lookForAssignsSettings); + $vars = [$node->var]; + } else { + $vars = $node->vars; + } + + foreach ($vars as $var) { + if ( + !$var instanceof Variable + && !$var instanceof ArrayDimFetch + && !$var instanceof PropertyFetch + && !$var instanceof StaticPropertyFetch + ) { + continue; + } + + $type = null; + if ($node instanceof Assign || $node instanceof AssignRef) { + $type = $scope->getType($node->expr); + } elseif ($node instanceof Expr\AssignOp) { + $type = $scope->getType($node); + if ($lookForAssignsSettings->shouldGeneralizeConstantTypesOfNonIdempotentOperations()) { + $type = TypeUtils::generalizeType($type); + } + } + + $scope = $this->assignVariable($scope, $var, $certainty, $type); + if ( + (!$node instanceof Assign && !$node instanceof AssignRef) + || !$lookForAssignsSettings->shouldGeneralizeConstantTypesOfNonIdempotentOperations() + || !($var instanceof ArrayDimFetch) + || $var->dim !== null + ) { + continue; + } + + $type = $scope->getType($var->var); + $scope = $this->assignVariable($scope, $var->var, $certainty, TypeUtils::generalizeType($type)); + } + + if ($node instanceof Assign || $node instanceof AssignRef) { + if ($node->var instanceof Array_ || $node->var instanceof List_) { + $scope = $this->lookForArrayDestructuringArray($scope, $node->var, $scope->getType($node->expr)); + } + } + + if (!$node instanceof Node\Stmt\Global_) { + $scope = $this->lookForAssigns($scope, $node->expr, TrinaryLogic::createYes(), $lookForAssignsSettings); + } + + if ($node instanceof Assign || $node instanceof AssignRef) { + if ($node->var instanceof Variable && is_string($node->var->name)) { + $comment = CommentHelper::getDocComment($node); + if ($comment !== null) { + $scope = $this->processVarAnnotation($scope, $node->var->name, $comment, false); + } + } + } + } + + return $scope; + } + + private function processVarAnnotation(Scope $scope, string $variableName, string $comment, bool $strict): Scope + { + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc( + $scope->getFile(), + $scope->isInClass() ? $scope->getClassReflection()->getName() : null, + $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, + $comment + ); + $varTags = $resolvedPhpDoc->getVarTags(); + + if (isset($varTags[$variableName])) { + $variableType = $varTags[$variableName]->getType(); + return $scope->assignVariable($variableName, $variableType, TrinaryLogic::createYes()); + + } + + if (!$strict && count($varTags) === 1 && isset($varTags[0])) { + $variableType = $varTags[0]->getType(); + return $scope->assignVariable($variableName, $variableType, TrinaryLogic::createYes()); + + } + + return $scope; + } + + private function assignVariable( + Scope $scope, + Node $var, + TrinaryLogic $certainty, + ?Type $subNodeType = null + ): Scope + { + if ($var instanceof Variable && is_string($var->name)) { + $scope = $scope->assignVariable($var->name, $subNodeType ?? new MixedType(), $certainty); + } elseif ($var instanceof ArrayDimFetch) { + $subNodeType = $subNodeType ?? new MixedType(); + + $dimExprStack = []; + while ($var instanceof ArrayDimFetch) { + $dimExprStack[] = $var->dim; + $var = $var->var; + } + + // 1. eval root expr + $scope = $this->lookForAssigns($scope, $var, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + + // 2. eval dimensions + $offsetTypes = []; + foreach (array_reverse($dimExprStack) as $dimExpr) { + if ($dimExpr === null) { + $offsetTypes[] = null; + + } else { + if ($dimExpr instanceof Expr\PreInc || $dimExpr instanceof Expr\PreDec) { + $dimExpr = $dimExpr->var; + } + $scope = $this->lookForAssigns($scope, $dimExpr, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + $offsetTypes[] = $scope->getType($dimExpr); + } + } + + // 3. eval assigned expr, unfortunately this was already done + + // 4. compose types + $varType = $scope->getType($var); + if ($varType instanceof ErrorType) { + $varType = new ConstantArrayType([], []); + } + $offsetValueType = $varType; + $offsetValueTypeStack = [$offsetValueType]; + foreach (array_slice($offsetTypes, 0, -1) as $offsetType) { + if ($offsetType === null) { + $offsetValueType = new ConstantArrayType([], []); + + } else { + $offsetValueType = $offsetValueType->getOffsetValueType($offsetType); + if ($offsetValueType instanceof ErrorType) { + $offsetValueType = new ConstantArrayType([], []); + } + } + + $offsetValueTypeStack[] = $offsetValueType; + } + + $valueToWrite = $subNodeType; + foreach (array_reverse($offsetTypes) as $offsetType) { + /** @var Type $offsetValueType */ + $offsetValueType = array_pop($offsetValueTypeStack); + $valueToWrite = $offsetValueType->setOffsetValueType($offsetType, $valueToWrite); + } + + if ($valueToWrite instanceof ErrorType) { + $valueToWrite = new ArrayType(new MixedType(), new MixedType()); + } + + if ($var instanceof Variable && is_string($var->name)) { + $scope = $scope->assignVariable( + $var->name, + $valueToWrite, + $certainty + ); + } else { + $scope = $scope->specifyExpressionType( + $var, + $valueToWrite + ); + } + } elseif ($var instanceof PropertyFetch && $subNodeType !== null) { + $scope = $scope->specifyExpressionType($var, $subNodeType); + } elseif ($var instanceof Expr\StaticPropertyFetch && $subNodeType !== null) { + $scope = $scope->specifyExpressionType($var, $subNodeType); + } else { + $scope = $this->lookForAssigns($scope, $var, TrinaryLogic::createYes(), LookForAssignsSettings::default()); + } + + return $scope; + } + + /** + * @param \PHPStan\Analyser\Scope $initialScope + * @param \PHPStan\Analyser\StatementList[] $statementsLists + * @param \PHPStan\Analyser\LookForAssignsSettings $lookForAssignsSettings + * @param int $counter + * @return Scope + */ + private function lookForAssignsInBranches( + Scope $initialScope, + array $statementsLists, + LookForAssignsSettings $lookForAssignsSettings, + int $counter = 0 + ): Scope + { + /** @var \PHPStan\Analyser\Scope|null $intersectedScope */ + $intersectedScope = null; + foreach ($statementsLists as $statementList) { + $statements = $statementList->getStatements(); + $branchScope = $statementList->getScope(); + $branchScopeWithInitialScopeRemoved = $branchScope->removeVariables($initialScope, true); + + $earlyTerminationStatement = null; + foreach ($statements as $statement) { + $branchScope = $this->lookForAssigns($branchScope, $statement, TrinaryLogic::createYes(), $lookForAssignsSettings); + $branchScopeWithInitialScopeRemoved = $branchScope->removeVariables($initialScope, false); + $earlyTerminationStatement = $this->findStatementEarlyTermination($statement, $branchScope); + if ($earlyTerminationStatement !== null) { + if ($lookForAssignsSettings->shouldSkipBranch($earlyTerminationStatement)) { + continue 2; + } + $branchScopeWithInitialScopeRemoved = $branchScopeWithInitialScopeRemoved->removeSpecified($initialScope); + break; + } + } + + if (!$lookForAssignsSettings->shouldIntersectVariables($earlyTerminationStatement)) { + continue; + } + + if ($intersectedScope === null) { + $intersectedScope = $initialScope->createIntersectedScope($branchScopeWithInitialScopeRemoved); + } else { + $intersectedScope = $intersectedScope->intersectVariables($branchScopeWithInitialScopeRemoved); + } + + if (!$statementList->shouldFilterByTruthyValue()) { + continue; + } + + /** @var \PhpParser\Node\Expr $statement */ + foreach ($statements as $statement) { + $intersectedScope = $intersectedScope->filterByTruthyValue($statement); + } + } + + if ($intersectedScope !== null) { + $scope = $initialScope->mergeWithIntersectedScope($intersectedScope); + if ($counter === 0 && $lookForAssignsSettings->shouldRepeatAnalysis()) { + $newStatementLists = []; + foreach ($statementsLists as $statementList) { + $newStatementLists[] = StatementList::fromList( + $scope, + $statementList + ); + } + return $this->lookForAssignsInBranches( + $scope, + $newStatementLists, + $lookForAssignsSettings, + $counter + 1 + ); + } + + return $scope; + } + + return $initialScope; + } + + /** + * @param \PhpParser\Node[] $statements + * @param \PHPStan\Analyser\Scope $scope + * @return \PhpParser\Node|null + */ + private function findEarlyTermination(array $statements, Scope $scope): ?\PhpParser\Node + { + foreach ($statements as $statement) { + $statement = $this->findStatementEarlyTermination($statement, $scope); + if ($statement !== null) { + return $statement; + } + } + + return null; + } + + private function findStatementEarlyTermination(Node $statement, Scope $scope): ?\PhpParser\Node + { + if ($statement instanceof Node\Stmt\Expression) { + $statement = $statement->expr; + } + + if ( + $statement instanceof Throw_ + || $statement instanceof Return_ + || $statement instanceof Continue_ + || $statement instanceof Break_ + || $statement instanceof Exit_ + ) { + return $statement; + } elseif (($statement instanceof MethodCall || $statement instanceof Expr\StaticCall) && count($this->earlyTerminatingMethodCalls) > 0) { + if ($statement->name instanceof Expr) { + return null; + } + + if ($statement instanceof MethodCall) { + $methodCalledOnType = $scope->getType($statement->var); + } else { + if ($statement->class instanceof Name) { + $methodCalledOnType = $scope->getFunctionType($statement->class, false, false); + } else { + $methodCalledOnType = $scope->getType($statement->class); + } + } + + $directClassNames = TypeUtils::getDirectClassNames($methodCalledOnType); + foreach ($directClassNames as $referencedClass) { + if (!$this->broker->hasClass($referencedClass)) { + continue; + } + + $classReflection = $this->broker->getClass($referencedClass); + foreach (array_merge([$referencedClass], $classReflection->getParentClassesNames()) as $className) { + if (!isset($this->earlyTerminatingMethodCalls[$className])) { + continue; + } + + if (in_array((string) $statement->name, $this->earlyTerminatingMethodCalls[$className], true)) { + return $statement; + } + } + } + + return null; + } elseif ($statement instanceof If_) { + if ($statement->else === null) { + return null; + } + + if ($this->findEarlyTermination($statement->stmts, $scope) === null) { + return null; + } + + foreach ($statement->elseifs as $elseIfStatement) { + if ($this->findEarlyTermination($elseIfStatement->stmts, $scope) === null) { + return null; + } + } + + if ($this->findEarlyTermination($statement->else->stmts, $scope) === null) { + return null; + } + + return $statement; + } + + return null; + } + + private function findParametersAcceptorInFunctionCall(Expr $functionCall, Scope $scope): ?\PHPStan\Reflection\ParametersAcceptor + { + if ($functionCall instanceof FuncCall && $functionCall->name instanceof Name) { + if ($this->broker->hasFunction($functionCall->name, $scope)) { + return ParametersAcceptorSelector::selectFromArgs( + $scope, + $functionCall->args, + $this->broker->getFunction($functionCall->name, $scope)->getVariants() + ); + } + } elseif ($functionCall instanceof MethodCall && $functionCall->name instanceof Node\Identifier) { + $type = $scope->getType($functionCall->var); + $methodName = $functionCall->name->name; + if ($type->hasMethod($methodName)->yes()) { + return ParametersAcceptorSelector::selectFromArgs( + $scope, + $functionCall->args, + $type->getMethod($methodName, $scope)->getVariants() + ); + } + } elseif ( + $functionCall instanceof Expr\StaticCall + && $functionCall->class instanceof Name + && $functionCall->name instanceof Node\Identifier + ) { + $className = $scope->resolveName($functionCall->class); + if ($this->broker->hasClass($className)) { + $classReflection = $this->broker->getClass($className); + if ($classReflection->hasMethod($functionCall->name->name)) { + return ParametersAcceptorSelector::selectFromArgs( + $scope, + $functionCall->args, + $classReflection->getMethod($functionCall->name->name, $scope)->getVariants() + ); + } + } + } + + return null; + } + + private function processTraitUse(Node\Stmt\TraitUse $node, Scope $classScope, \Closure $nodeCallback): void + { + foreach ($node->traits as $trait) { + $traitName = (string) $trait; + if (!$this->broker->hasClass($traitName)) { + continue; + } + $traitReflection = $this->broker->getClass($traitName); + $traitFileName = $traitReflection->getFileName(); + if ($traitFileName === false) { + throw new \PHPStan\ShouldNotHappenException(); + } + $fileName = $this->fileHelper->normalizePath($traitFileName); + if (!isset($this->analysedFiles[$fileName])) { + return; + } + $parserNodes = $this->parser->parseFile($fileName); + $classScope = $classScope->enterTrait($traitReflection); + + $this->processNodesForTraitUse($parserNodes, $traitName, $classScope, $nodeCallback); + } + } + + /** + * @param \PhpParser\Node[]|\PhpParser\Node|scalar $node + * @param string $traitName + * @param \PHPStan\Analyser\Scope $classScope + * @param \Closure(\PhpParser\Node $node): void $nodeCallback + */ + private function processNodesForTraitUse($node, string $traitName, Scope $classScope, \Closure $nodeCallback): void + { + if ($node instanceof Node) { + if ($node instanceof Node\Stmt\Trait_ && $traitName === (string) $node->namespacedName) { + $this->processNodes($node->stmts, $classScope->enterFirstLevelStatements(), $nodeCallback); + return; + } + if ($node instanceof Node\Stmt\ClassLike) { + return; + } + foreach ($node->getSubNodeNames() as $subNodeName) { + $subNode = $node->{$subNodeName}; + $this->processNodesForTraitUse($subNode, $traitName, $classScope, $nodeCallback); + } + } elseif (is_array($node)) { + foreach ($node as $subNode) { + $this->processNodesForTraitUse($subNode, $traitName, $classScope, $nodeCallback); + } + } + } + + private function enterClassMethod(Scope $scope, Node\Stmt\ClassMethod $classMethod): Scope + { + [$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal, $isFinal] = $this->getPhpDocs($scope, $classMethod); + + return $scope->enterClassMethod( + $classMethod, + $phpDocParameterTypes, + $phpDocReturnType, + $phpDocThrowType, + $isDeprecated, + $isInternal, + $isFinal + ); + } + + /** + * @param Scope $scope + * @param Node\FunctionLike $functionLike + * @return mixed[] + */ + private function getPhpDocs(Scope $scope, Node\FunctionLike $functionLike): array + { + $phpDocParameterTypes = []; + $phpDocReturnType = null; + $phpDocThrowType = null; + $isDeprecated = false; + $isInternal = false; + $isFinal = false; + $docComment = $functionLike->getDocComment() !== null + ? $functionLike->getDocComment()->getText() + : null; + + $file = $scope->getFile(); + $class = $scope->isInClass() ? $scope->getClassReflection()->getName() : null; + $trait = $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null; + $isExplicitPhpDoc = true; + if ($functionLike instanceof Node\Stmt\ClassMethod) { + if (!$scope->isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + $phpDocBlock = PhpDocBlock::resolvePhpDocBlockForMethod( + $this->broker, + $docComment, + $scope->getClassReflection()->getName(), + $trait, + $functionLike->name->name, + $file + ); + + if ($phpDocBlock !== null) { + $docComment = $phpDocBlock->getDocComment(); + $file = $phpDocBlock->getFile(); + $class = $phpDocBlock->getClass(); + $trait = $phpDocBlock->getTrait(); + $isExplicitPhpDoc = $phpDocBlock->isExplicit(); + } + } + + if ($docComment !== null) { + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc( + $file, + $class, + $trait, + $docComment + ); + $phpDocParameterTypes = array_map(static function (ParamTag $tag): Type { + return $tag->getType(); + }, $resolvedPhpDoc->getParamTags()); + $nativeReturnType = $scope->getFunctionType($functionLike->getReturnType(), false, false); + $phpDocReturnType = null; + if ( + $resolvedPhpDoc->getReturnTag() !== null + && ( + $isExplicitPhpDoc + || $nativeReturnType->isSuperTypeOf($resolvedPhpDoc->getReturnTag()->getType())->yes() + ) + ) { + $phpDocReturnType = $resolvedPhpDoc->getReturnTag()->getType(); + } + $phpDocThrowType = $resolvedPhpDoc->getThrowsTag() !== null ? $resolvedPhpDoc->getThrowsTag()->getType() : null; + $isDeprecated = $resolvedPhpDoc->isDeprecated(); + $isInternal = $resolvedPhpDoc->isInternal(); + $isFinal = $resolvedPhpDoc->isFinal(); + } + + return [$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal, $isFinal]; + } + + private function enterFunction(Scope $scope, Node\Stmt\Function_ $function): Scope + { + [$phpDocParameterTypes, $phpDocReturnType, $phpDocThrowType, $isDeprecated, $isInternal, $isFinal] = $this->getPhpDocs($scope, $function); + + return $scope->enterFunction( + $function, + $phpDocParameterTypes, + $phpDocReturnType, + $phpDocThrowType, + $isDeprecated, + $isInternal, + $isFinal + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/OutOfClassScope.php b/vendor/phpstan/phpstan/src/Analyser/OutOfClassScope.php new file mode 100644 index 00000000..538c9ba9 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/OutOfClassScope.php @@ -0,0 +1,39 @@ +isPublic(); + } + + public function canCallMethod(MethodReflection $methodReflection): bool + { + return $methodReflection->isPublic(); + } + + public function canAccessConstant(ConstantReflection $constantReflection): bool + { + return $constantReflection->isPublic(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/Scope.php b/vendor/phpstan/phpstan/src/Analyser/Scope.php new file mode 100644 index 00000000..9ca404cf --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/Scope.php @@ -0,0 +1,2806 @@ +scopeFactory = $scopeFactory; + $this->broker = $broker; + $this->printer = $printer; + $this->typeSpecifier = $typeSpecifier; + $this->context = $context; + $this->declareStrictTypes = $declareStrictTypes; + $this->function = $function; + $this->namespace = $namespace; + $this->variableTypes = $variablesTypes; + $this->moreSpecificTypes = $moreSpecificTypes; + $this->inClosureBindScopeClass = $inClosureBindScopeClass; + $this->inAnonymousFunctionReturnType = $inAnonymousFunctionReturnType; + $this->inFunctionCall = $inFunctionCall; + $this->negated = $negated; + $this->inFirstLevelStatement = $inFirstLevelStatement; + $this->currentlyAssignedExpressions = $currentlyAssignedExpressions; + $this->dynamicConstantNames = $dynamicConstantNames; + } + + public function getFile(): string + { + return $this->context->getFile(); + } + + public function getFileDescription(): string + { + if ($this->context->getTraitReflection() === null) { + return $this->getFile(); + } + + /** @var ClassReflection $classReflection */ + $classReflection = $this->context->getClassReflection(); + + $className = sprintf('class %s', $classReflection->getDisplayName()); + if ($classReflection->isAnonymous()) { + $className = 'anonymous class'; + } + + $traitReflection = $this->context->getTraitReflection(); + if ($traitReflection->getFileName() === false) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return sprintf( + '%s (in context of %s)', + $traitReflection->getFileName(), + $className + ); + } + + public function isDeclareStrictTypes(): bool + { + return $this->declareStrictTypes; + } + + public function enterDeclareStrictTypes(): self + { + return $this->scopeFactory->create( + $this->context, + true + ); + } + + public function isInClass(): bool + { + return $this->context->getClassReflection() !== null; + } + + public function isInTrait(): bool + { + return $this->context->getTraitReflection() !== null; + } + + public function getClassReflection(): ?ClassReflection + { + return $this->context->getClassReflection(); + } + + public function getTraitReflection(): ?ClassReflection + { + return $this->context->getTraitReflection(); + } + + /** + * @return \PHPStan\Reflection\FunctionReflection|\PHPStan\Reflection\MethodReflection|null + */ + public function getFunction() + { + return $this->function; + } + + public function getFunctionName(): ?string + { + return $this->function !== null ? $this->function->getName() : null; + } + + public function getNamespace(): ?string + { + return $this->namespace; + } + + /** + * @return array + */ + private function getVariableTypes(): array + { + return $this->variableTypes; + } + + public function hasVariableType(string $variableName): TrinaryLogic + { + if ($this->isGlobalVariable($variableName)) { + return TrinaryLogic::createYes(); + } + + if (!isset($this->variableTypes[$variableName])) { + return TrinaryLogic::createNo(); + } + + return $this->variableTypes[$variableName]->getCertainty(); + } + + public function getVariableType(string $variableName): Type + { + if ($this->isGlobalVariable($variableName)) { + return new ArrayType(new StringType(), new MixedType()); + } + + if ($this->hasVariableType($variableName)->no()) { + throw new \PHPStan\Analyser\UndefinedVariableException($this, $variableName); + } + + return $this->variableTypes[$variableName]->getType(); + } + + private function isGlobalVariable(string $variableName): bool + { + return in_array($variableName, [ + 'GLOBALS', + '_SERVER', + '_GET', + '_POST', + '_FILES', + '_COOKIE', + '_SESSION', + '_REQUEST', + '_ENV', + ], true); + } + + public function hasConstant(Name $name): bool + { + $node = new ConstFetch(new Name\FullyQualified($name->toString())); + if ($this->isSpecified($node)) { + return true; + } + return $this->broker->hasConstant($name, $this); + } + + public function isInAnonymousFunction(): bool + { + return $this->inAnonymousFunctionReturnType !== null; + } + + public function getAnonymousFunctionReturnType(): ?\PHPStan\Type\Type + { + return $this->inAnonymousFunctionReturnType; + } + + /** + * @return \PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|null + */ + public function getInFunctionCall() + { + return $this->inFunctionCall; + } + + public function getType(Expr $node): Type + { + $key = $this->printer->prettyPrintExpr($node); + if (!array_key_exists($key, $this->resolvedTypes)) { + $this->resolvedTypes[$key] = $this->resolveType($node); + } + return $this->resolvedTypes[$key]; + } + + private function resolveType(Expr $node): Type + { + if ( + $node instanceof Expr\BinaryOp\Greater + || $node instanceof Expr\BinaryOp\GreaterOrEqual + || $node instanceof Expr\BinaryOp\Smaller + || $node instanceof Expr\BinaryOp\SmallerOrEqual + || $node instanceof Expr\BinaryOp\Equal + || $node instanceof Expr\BinaryOp\NotEqual + || $node instanceof Expr\Empty_ + ) { + return new BooleanType(); + } + + if ($node instanceof Expr\Isset_) { + $result = new ConstantBooleanType(true); + foreach ($node->vars as $var) { + if ($var instanceof Expr\ArrayDimFetch && $var->dim !== null) { + $hasOffset = $this->getType($var->var)->hasOffsetValueType( + $this->getType($var->dim) + )->toBooleanType(); + if ($hasOffset instanceof ConstantBooleanType) { + if (!$hasOffset->getValue()) { + return $hasOffset; + } + + continue; + } + + $result = $hasOffset; + continue; + } + + if ($var instanceof Expr\Variable && is_string($var->name)) { + $variableType = $this->resolveType($var); + $isNullSuperType = (new NullType())->isSuperTypeOf($variableType); + if ($this->hasVariableType($var->name)->no() || $isNullSuperType->yes()) { + return new ConstantBooleanType(false); + } + + if (!$isNullSuperType->no()) { + $result = new BooleanType(); + } + continue; + } + + return new BooleanType(); + } + + return $result; + } + + if ($node instanceof \PhpParser\Node\Expr\BooleanNot) { + $exprBooleanType = $this->getType($node->expr)->toBoolean(); + if ($exprBooleanType instanceof ConstantBooleanType) { + return new ConstantBooleanType(!$exprBooleanType->getValue()); + } + + return new BooleanType(); + } + + if ( + $node instanceof \PhpParser\Node\Expr\BinaryOp\BooleanAnd + || $node instanceof \PhpParser\Node\Expr\BinaryOp\LogicalAnd + ) { + $leftBooleanType = $this->getType($node->left)->toBoolean(); + if ( + $leftBooleanType instanceof ConstantBooleanType + && !$leftBooleanType->getValue() + ) { + return new ConstantBooleanType(false); + } + + $rightBooleanType = $this->filterByTruthyValue($node->left)->getType($node->right)->toBoolean(); + if ( + $rightBooleanType instanceof ConstantBooleanType + && !$rightBooleanType->getValue() + ) { + return new ConstantBooleanType(false); + } + + if ( + $leftBooleanType instanceof ConstantBooleanType + && $leftBooleanType->getValue() + && $rightBooleanType instanceof ConstantBooleanType + && $rightBooleanType->getValue() + ) { + return new ConstantBooleanType(true); + } + + return new BooleanType(); + } + + if ( + $node instanceof \PhpParser\Node\Expr\BinaryOp\BooleanOr + || $node instanceof \PhpParser\Node\Expr\BinaryOp\LogicalOr + ) { + $leftBooleanType = $this->getType($node->left)->toBoolean(); + if ( + $leftBooleanType instanceof ConstantBooleanType + && $leftBooleanType->getValue() + ) { + return new ConstantBooleanType(true); + } + + $rightBooleanType = $this->filterByFalseyValue($node->left)->getType($node->right)->toBoolean(); + if ( + $rightBooleanType instanceof ConstantBooleanType + && $rightBooleanType->getValue() + ) { + return new ConstantBooleanType(true); + } + + if ( + $leftBooleanType instanceof ConstantBooleanType + && !$leftBooleanType->getValue() + && $rightBooleanType instanceof ConstantBooleanType + && !$rightBooleanType->getValue() + ) { + return new ConstantBooleanType(false); + } + + return new BooleanType(); + } + + if ($node instanceof \PhpParser\Node\Expr\BinaryOp\LogicalXor) { + $leftBooleanType = $this->getType($node->left)->toBoolean(); + $rightBooleanType = $this->filterByFalseyValue($node->left)->getType($node->right)->toBoolean(); + if ( + $leftBooleanType instanceof ConstantBooleanType + && $rightBooleanType instanceof ConstantBooleanType + ) { + return new ConstantBooleanType( + $leftBooleanType->getValue() xor $rightBooleanType->getValue() + ); + } + + return new BooleanType(); + } + + if ($node instanceof Expr\BinaryOp\Identical) { + $leftType = $this->getType($node->left); + $rightType = $this->getType($node->right); + + if ( + ( + $node->left instanceof Node\Expr\PropertyFetch + || $node->left instanceof Node\Expr\StaticPropertyFetch + ) + && $rightType instanceof NullType + ) { + return new BooleanType(); + } + + if ( + ( + $node->right instanceof Node\Expr\PropertyFetch + || $node->right instanceof Node\Expr\StaticPropertyFetch + ) + && $leftType instanceof NullType + ) { + return new BooleanType(); + } + + $isSuperset = $leftType->isSuperTypeOf($rightType); + if ($isSuperset->no()) { + return new ConstantBooleanType(false); + } elseif ( + $isSuperset->yes() + && $leftType instanceof ConstantScalarType + && $rightType instanceof ConstantScalarType + && $leftType->getValue() === $rightType->getValue() + ) { + return new ConstantBooleanType(true); + } + + return new BooleanType(); + } + + if ($node instanceof Expr\BinaryOp\NotIdentical) { + $leftType = $this->getType($node->left); + $rightType = $this->getType($node->right); + + if ( + ( + $node->left instanceof Node\Expr\PropertyFetch + || $node->left instanceof Node\Expr\StaticPropertyFetch + ) + && $rightType instanceof NullType + ) { + return new BooleanType(); + } + + if ( + ( + $node->right instanceof Node\Expr\PropertyFetch + || $node->right instanceof Node\Expr\StaticPropertyFetch + ) + && $leftType instanceof NullType + ) { + return new BooleanType(); + } + + $isSuperset = $leftType->isSuperTypeOf($rightType); + if ($isSuperset->no()) { + return new ConstantBooleanType(true); + } elseif ( + $isSuperset->yes() + && $leftType instanceof ConstantScalarType + && $rightType instanceof ConstantScalarType + && $leftType->getValue() === $rightType->getValue() + ) { + return new ConstantBooleanType(false); + } + + return new BooleanType(); + } + + if ($node instanceof Expr\Instanceof_) { + if ($node->class instanceof Node\Name) { + $className = $this->resolveName($node->class); + $type = new ObjectType($className); + } else { + $type = $this->getType($node->class); + } + + $expressionType = $this->getType($node->expr); + if ( + $this->isInTrait() + && TypeUtils::findThisType($expressionType) !== null + ) { + return new BooleanType(); + } + if ($expressionType instanceof NeverType) { + return new ConstantBooleanType(false); + } + $isExpressionObject = (new ObjectWithoutClassType())->isSuperTypeOf($expressionType); + if (!$isExpressionObject->no() && !(new StringType())->isSuperTypeOf($type)->no()) { + return new BooleanType(); + } + + $isSuperType = $type->isSuperTypeOf($expressionType) + ->and($isExpressionObject); + if ($isSuperType->no()) { + return new ConstantBooleanType(false); + } elseif ($isSuperType->yes()) { + return new ConstantBooleanType(true); + } + + return new BooleanType(); + } + + if ($node instanceof Node\Expr\UnaryPlus) { + return $this->getType($node->expr)->toNumber(); + } + + if ($node instanceof Expr\ErrorSuppress + || $node instanceof Expr\Assign + ) { + return $this->getType($node->expr); + } + + if ($node instanceof Node\Expr\UnaryMinus) { + $type = $this->getType($node->expr)->toNumber(); + $scalarValues = TypeUtils::getConstantScalars($type); + if (count($scalarValues) > 0) { + $newTypes = []; + foreach ($scalarValues as $scalarValue) { + if ($scalarValue instanceof ConstantIntegerType) { + $newTypes[] = new ConstantIntegerType(-$scalarValue->getValue()); + } elseif ($scalarValue instanceof ConstantFloatType) { + $newTypes[] = new ConstantFloatType(-$scalarValue->getValue()); + } + } + + return TypeCombinator::union(...$newTypes); + } + + return $type; + } + + if ($node instanceof Expr\BinaryOp\Concat || $node instanceof Expr\AssignOp\Concat) { + if ($node instanceof Node\Expr\AssignOp) { + $left = $node->var; + $right = $node->expr; + } else { + $left = $node->left; + $right = $node->right; + } + + $leftStringType = $this->getType($left)->toString(); + $rightStringType = $this->getType($right)->toString(); + if (TypeCombinator::union( + $leftStringType, + $rightStringType + ) instanceof ErrorType) { + return new ErrorType(); + } + + if ($leftStringType instanceof ConstantStringType && $rightStringType instanceof ConstantStringType) { + return $leftStringType->append($rightStringType); + } + + return new StringType(); + } + + if ( + $node instanceof Node\Expr\BinaryOp\Div + || $node instanceof Node\Expr\AssignOp\Div + || $node instanceof Node\Expr\BinaryOp\Mod + || $node instanceof Node\Expr\AssignOp\Mod + ) { + if ($node instanceof Node\Expr\AssignOp) { + $right = $node->expr; + } else { + $right = $node->right; + } + + $rightTypes = TypeUtils::getConstantScalars($this->getType($right)->toNumber()); + foreach ($rightTypes as $rightType) { + if ( + $rightType->getValue() === 0 + || $rightType->getValue() === 0.0 + ) { + return new ErrorType(); + } + } + } + + if ( + ( + $node instanceof Node\Expr\BinaryOp + || $node instanceof Node\Expr\AssignOp + ) && !$node instanceof Expr\BinaryOp\Coalesce + ) { + if ($node instanceof Node\Expr\AssignOp) { + $left = $node->var; + $right = $node->expr; + } else { + $left = $node->left; + $right = $node->right; + } + + $leftTypes = TypeUtils::getConstantScalars($this->getType($left)); + $rightTypes = TypeUtils::getConstantScalars($this->getType($right)); + + if (count($leftTypes) > 0 && count($rightTypes) > 0) { + $resultTypes = []; + foreach ($leftTypes as $leftType) { + foreach ($rightTypes as $rightType) { + $resultTypes[] = $this->calculateFromScalars($node, $leftType, $rightType); + } + } + return TypeCombinator::union(...$resultTypes); + } + } + + if ($node instanceof Node\Expr\BinaryOp\Mod || $node instanceof Expr\AssignOp\Mod) { + return new IntegerType(); + } + + if ($node instanceof Expr\BinaryOp\Spaceship) { + return new IntegerType(); + } + + if ($node instanceof Expr\BinaryOp\Coalesce) { + if ($node->left instanceof Expr\ArrayDimFetch && $node->left->dim !== null) { + $dimType = $this->getType($node->left->dim); + $varType = $this->getType($node->left->var); + $hasOffset = $varType->hasOffsetValueType($dimType); + $leftType = $this->getType($node->left); + $rightType = $this->getType($node->right); + if ($hasOffset->no()) { + return $rightType; + } elseif ($hasOffset->yes()) { + $offsetValueType = $varType->getOffsetValueType($dimType); + if ($offsetValueType->isSuperTypeOf(new NullType())->no()) { + return TypeCombinator::removeNull($leftType); + } + } + + return TypeCombinator::union( + TypeCombinator::removeNull($leftType), + $rightType + ); + } + + $leftType = $this->getType($node->left); + $rightType = $this->getType($node->right); + if ($leftType instanceof ErrorType || $leftType instanceof NullType) { + return $rightType; + } + + if (TypeCombinator::containsNull($leftType) || $node->left instanceof PropertyFetch) { + return TypeCombinator::union( + TypeCombinator::removeNull($leftType), + $rightType + ); + } + + return TypeCombinator::removeNull($leftType); + } + + if ($node instanceof Expr\Clone_) { + return $this->getType($node->expr); + } + + if ( + $node instanceof Expr\AssignOp\ShiftLeft + || $node instanceof Expr\BinaryOp\ShiftLeft + || $node instanceof Expr\AssignOp\ShiftRight + || $node instanceof Expr\BinaryOp\ShiftRight + ) { + if ($node instanceof Node\Expr\AssignOp) { + $left = $node->var; + $right = $node->expr; + } else { + $left = $node->left; + $right = $node->right; + } + + if (TypeCombinator::union( + $this->getType($left)->toNumber(), + $this->getType($right)->toNumber() + ) instanceof ErrorType) { + return new ErrorType(); + } + + return new IntegerType(); + } + + if ( + $node instanceof Expr\AssignOp\BitwiseAnd + || $node instanceof Expr\BinaryOp\BitwiseAnd + || $node instanceof Expr\AssignOp\BitwiseOr + || $node instanceof Expr\BinaryOp\BitwiseOr + || $node instanceof Expr\AssignOp\BitwiseXor + || $node instanceof Expr\BinaryOp\BitwiseXor + ) { + if ($node instanceof Node\Expr\AssignOp) { + $left = $node->var; + $right = $node->expr; + } else { + $left = $node->left; + $right = $node->right; + } + + $leftType = $this->getType($left); + $rightType = $this->getType($right); + $stringType = new StringType(); + + if ($stringType->isSuperTypeOf($leftType)->yes() && $stringType->isSuperTypeOf($rightType)->yes()) { + return $stringType; + } + + if (TypeCombinator::union($leftType->toNumber(), $rightType->toNumber()) instanceof ErrorType) { + return new ErrorType(); + } + + return new IntegerType(); + } + + if ( + $node instanceof Node\Expr\BinaryOp\Plus + || $node instanceof Node\Expr\BinaryOp\Minus + || $node instanceof Node\Expr\BinaryOp\Mul + || $node instanceof Node\Expr\BinaryOp\Pow + || $node instanceof Node\Expr\BinaryOp\Div + || $node instanceof Node\Expr\AssignOp\Plus + || $node instanceof Node\Expr\AssignOp\Minus + || $node instanceof Node\Expr\AssignOp\Mul + || $node instanceof Node\Expr\AssignOp\Pow + || $node instanceof Node\Expr\AssignOp\Div + ) { + if ($node instanceof Node\Expr\AssignOp) { + $left = $node->var; + $right = $node->expr; + } else { + $left = $node->left; + $right = $node->right; + } + + $leftType = $this->getType($left); + $rightType = $this->getType($right); + + if ($node instanceof Expr\AssignOp\Plus || $node instanceof Expr\BinaryOp\Plus) { + $leftConstantArrays = TypeUtils::getConstantArrays($leftType); + $rightConstantArrays = TypeUtils::getConstantArrays($rightType); + + if (count($leftConstantArrays) > 0 && count($rightConstantArrays) > 0) { + $resultTypes = []; + foreach ($rightConstantArrays as $rightConstantArray) { + foreach ($leftConstantArrays as $leftConstantArray) { + $newArrayBuilder = ConstantArrayTypeBuilder::createFromConstantArray($rightConstantArray); + foreach ($leftConstantArray->getKeyTypes() as $leftKeyType) { + $newArrayBuilder->setOffsetValueType( + $leftKeyType, + $leftConstantArray->getOffsetValueType($leftKeyType) + ); + } + $resultTypes[] = $newArrayBuilder->getArray(); + } + } + + return TypeCombinator::union(...$resultTypes); + } + + $leftArrays = TypeUtils::getArrays($leftType); + $rightArrays = TypeUtils::getArrays($rightType); + + if (count($leftArrays) > 0 && count($rightArrays) > 0) { + $resultTypes = []; + foreach ($rightArrays as $rightArray) { + foreach ($leftArrays as $leftArray) { + $resultTypes[] = new ArrayType( + TypeCombinator::union($leftArray->getKeyType(), $rightArray->getKeyType()), + TypeCombinator::union($leftArray->getItemType(), $rightArray->getItemType()) + ); + } + } + + return TypeCombinator::union(...$resultTypes); + } + + if ($leftType instanceof MixedType && $rightType instanceof MixedType) { + return new BenevolentUnionType([ + new FloatType(), + new IntegerType(), + new ArrayType(new MixedType(), new MixedType()), + ]); + } + } + + $types = TypeCombinator::union($leftType, $rightType); + if ( + $leftType instanceof ArrayType + || $rightType instanceof ArrayType + || $types instanceof ArrayType + ) { + return new ErrorType(); + } + + $leftNumberType = $leftType->toNumber(); + $rightNumberType = $rightType->toNumber(); + + if ( + (new FloatType())->isSuperTypeOf($leftNumberType)->yes() + || (new FloatType())->isSuperTypeOf($rightNumberType)->yes() + ) { + return new FloatType(); + } + + if ($node instanceof Expr\AssignOp\Pow || $node instanceof Expr\BinaryOp\Pow) { + return new BenevolentUnionType([ + new FloatType(), + new IntegerType(), + ]); + } + + $resultType = TypeCombinator::union($leftNumberType, $rightNumberType); + if ($node instanceof Expr\AssignOp\Div || $node instanceof Expr\BinaryOp\Div) { + if ($types instanceof MixedType || $resultType instanceof IntegerType) { + return new BenevolentUnionType([new IntegerType(), new FloatType()]); + } + + return new UnionType([new IntegerType(), new FloatType()]); + } + + if ($types instanceof MixedType) { + return TypeUtils::toBenevolentUnion($resultType); + } + + return $resultType; + } + + if ($node instanceof LNumber) { + return new ConstantIntegerType($node->value); + } elseif ($node instanceof String_) { + return new ConstantStringType($node->value); + } elseif ($node instanceof Node\Scalar\Encapsed) { + $constantString = new ConstantStringType(''); + foreach ($node->parts as $part) { + if ($part instanceof EncapsedStringPart) { + $partStringType = new ConstantStringType($part->value); + } else { + $partStringType = $this->getType($part)->toString(); + if ($partStringType instanceof ErrorType) { + return new ErrorType(); + } + if (!$partStringType instanceof ConstantStringType) { + return new StringType(); + } + } + + $constantString = $constantString->append($partStringType); + } + return $constantString; + } elseif ($node instanceof DNumber) { + return new ConstantFloatType($node->value); + } elseif ($node instanceof Expr\Closure) { + $parameters = []; + $isVariadic = false; + $firstOptionalParameterIndex = null; + foreach ($node->params as $i => $param) { + $isOptionalCandidate = $param->default !== null || $param->variadic; + + if ($isOptionalCandidate) { + if ($firstOptionalParameterIndex === null) { + $firstOptionalParameterIndex = $i; + } + } else { + $firstOptionalParameterIndex = null; + } + } + + foreach ($node->params as $i => $param) { + if ($param->variadic) { + $isVariadic = true; + } + if (!$param->var instanceof Variable || !is_string($param->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $parameters[] = new NativeParameterReflection( + $param->var->name, + $firstOptionalParameterIndex !== null && $i >= $firstOptionalParameterIndex, + $this->getFunctionType($param->type, $param->type === null, false), + $param->byRef + ? PassedByReference::createCreatesNewVariable() + : PassedByReference::createNo(), + $param->variadic + ); + } + + return new ClosureType( + $parameters, + $this->getFunctionType($node->returnType, $node->returnType === null, false), + $isVariadic + ); + } elseif ($node instanceof New_) { + if ($node->class instanceof Name) { + if ( + count($node->class->parts) === 1 + ) { + $lowercasedClassName = strtolower($node->class->parts[0]); + if (in_array($lowercasedClassName, [ + 'self', + 'static', + 'parent', + ], true)) { + if (!$this->isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + if ($lowercasedClassName === 'static') { + return new StaticType($this->getClassReflection()->getName()); + } + + if ($lowercasedClassName === 'self') { + return new ObjectType($this->getClassReflection()->getName()); + } + + if ($this->getClassReflection()->getParentClass() !== false) { + return new ObjectType($this->getClassReflection()->getParentClass()->getName()); + } + + return new NonexistentParentClassType(); + } + } + + return new ObjectType((string) $node->class); + } + if ($node->class instanceof Node\Stmt\Class_) { + $anonymousClassReflection = $this->broker->getAnonymousClassReflection($node, $this); + + return new ObjectType($anonymousClassReflection->getName()); + } + } elseif ($node instanceof Array_) { + $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); + foreach ($node->items as $arrayItem) { + if ($arrayItem === null) { + continue; + } + $arrayBuilder->setOffsetValueType( + $arrayItem->key !== null ? $this->getType($arrayItem->key) : null, + $this->getType($arrayItem->value) + ); + } + return $arrayBuilder->getArray(); + + } elseif ($node instanceof Int_) { + return $this->getType($node->expr)->toInteger(); + } elseif ($node instanceof Bool_) { + return $this->getType($node->expr)->toBoolean(); + } elseif ($node instanceof Double) { + return $this->getType($node->expr)->toFloat(); + } elseif ($node instanceof \PhpParser\Node\Expr\Cast\String_) { + return $this->getType($node->expr)->toString(); + } elseif ($node instanceof \PhpParser\Node\Expr\Cast\Array_) { + return $this->getType($node->expr)->toArray(); + } elseif ($node instanceof Node\Scalar\MagicConst\Line) { + return new ConstantIntegerType($node->getLine()); + } elseif ($node instanceof Node\Scalar\MagicConst\Class_) { + if (!$this->isInClass()) { + return new ConstantStringType(''); + } + + return new ConstantStringType($this->getClassReflection()->getName()); + } elseif ($node instanceof Node\Scalar\MagicConst\Dir) { + return new ConstantStringType(dirname($this->getFile())); + } elseif ($node instanceof Node\Scalar\MagicConst\File) { + return new ConstantStringType($this->getFile()); + } elseif ($node instanceof Node\Scalar\MagicConst\Namespace_) { + if (!$this->isInClass()) { + return new ConstantStringType(''); + } + + $className = $this->getClassReflection()->getName(); + $parts = explode('\\', $className); + if (count($parts) <= 1) { + return new ConstantStringType(''); + } + + return new ConstantStringType($parts[0]); + } elseif ($node instanceof Node\Scalar\MagicConst\Method) { + if ($this->isInAnonymousFunction()) { + return new ConstantStringType('{closure}'); + } + + $function = $this->getFunction(); + if ($function === null) { + return new ConstantStringType(''); + } + if ($function instanceof MethodReflection) { + return new ConstantStringType( + sprintf('%s::%s', $function->getDeclaringClass()->getName(), $function->getName()) + ); + } + + return new ConstantStringType($function->getName()); + } elseif ($node instanceof Node\Scalar\MagicConst\Function_) { + if ($this->isInAnonymousFunction()) { + return new ConstantStringType('{closure}'); + } + $function = $this->getFunction(); + if ($function === null) { + return new ConstantStringType(''); + } + + return new ConstantStringType($function->getName()); + } elseif ($node instanceof Node\Scalar\MagicConst\Trait_) { + if (!$this->isInTrait()) { + return new ConstantStringType(''); + } + return new ConstantStringType($this->getTraitReflection()->getName()); + } elseif ($node instanceof Object_) { + $castToObject = static function (Type $type): Type { + if ((new ObjectWithoutClassType())->isSuperTypeOf($type)->yes()) { + return $type; + } + + return new ObjectType('stdClass'); + }; + + $exprType = $this->getType($node->expr); + if ($exprType instanceof UnionType) { + return TypeCombinator::union(...array_map($castToObject, $exprType->getTypes())); + } + + return $castToObject($exprType); + } elseif ($node instanceof Unset_) { + return new NullType(); + } elseif ($node instanceof Expr\PostInc || $node instanceof Expr\PostDec) { + return $this->getType($node->var); + } elseif ($node instanceof Expr\PreInc || $node instanceof Expr\PreDec) { + $varType = $this->getType($node->var); + if ($varType instanceof ConstantScalarType) { + $varValue = $varType->getValue(); + if ($node instanceof Expr\PreInc) { + ++$varValue; + } else { + --$varValue; + } + return $this->getTypeFromValue($varValue); + } + + $stringType = new StringType(); + if ($stringType->isSuperTypeOf($varType)->yes()) { + return $stringType; + } + + return $varType->toNumber(); + } + + $exprString = $this->printer->prettyPrintExpr($node); + if (isset($this->moreSpecificTypes[$exprString])) { + return $this->moreSpecificTypes[$exprString]->getType(); + } + + if ($node instanceof ConstFetch) { + $constName = strtolower((string) $node->name); + if ($constName === 'true') { + return new \PHPStan\Type\Constant\ConstantBooleanType(true); + } elseif ($constName === 'false') { + return new \PHPStan\Type\Constant\ConstantBooleanType(false); + } elseif ($constName === 'null') { + return new NullType(); + } + + if ($this->broker->hasConstant($node->name, $this)) { + /** @var string $resolvedConstantName */ + $resolvedConstantName = $this->broker->resolveConstantName($node->name, $this); + if ($resolvedConstantName === 'DIRECTORY_SEPARATOR') { + return new UnionType([ + new ConstantStringType('/'), + new ConstantStringType('\\'), + ]); + } + if ($resolvedConstantName === 'PATH_SEPARATOR') { + return new UnionType([ + new ConstantStringType(':'), + new ConstantStringType(';'), + ]); + } + if ($resolvedConstantName === 'PHP_EOL') { + return new UnionType([ + new ConstantStringType("\n"), + new ConstantStringType("\r\n"), + ]); + } + + $constantType = $this->getTypeFromValue(constant($resolvedConstantName)); + if ($constantType instanceof ConstantType && in_array($resolvedConstantName, $this->dynamicConstantNames, true)) { + return $constantType->generalize(); + } + return $constantType; + } + + return new ErrorType(); + } elseif ($node instanceof Node\Expr\ClassConstFetch && $node->name instanceof Node\Identifier) { + $constantName = $node->name->name; + if ($node->class instanceof Name) { + $constantClass = (string) $node->class; + $constantClassType = new ObjectType($constantClass); + $namesToResolve = [ + 'self', + 'parent', + ]; + if ($this->isInClass()) { + if ($this->getClassReflection()->isFinal()) { + $namesToResolve[] = 'static'; + } elseif (strtolower($constantClass) === 'static') { + if (strtolower($constantName) === 'class') { + return new StringType(); + } + return new MixedType(); + } + } + if (in_array(strtolower($constantClass), $namesToResolve, true)) { + $resolvedName = $this->resolveName($node->class); + if ($resolvedName === 'parent' && strtolower($constantName) === 'class') { + return new StringType(); + } + $constantClassType = new ObjectType($resolvedName); + } + } else { + $constantClassType = $this->getType($node->class); + } + + if (strtolower($constantName) === 'class' && $constantClassType instanceof TypeWithClassName) { + return new ConstantStringType($constantClassType->getClassName()); + } + + $referencedClasses = TypeUtils::getDirectClassNames($constantClassType); + $types = []; + foreach ($referencedClasses as $referencedClass) { + if (!$this->broker->hasClass($referencedClass)) { + continue; + } + + $propertyClassReflection = $this->broker->getClass($referencedClass); + if (!$propertyClassReflection->hasConstant($constantName)) { + continue; + } + + $constantType = $this->getTypeFromValue($propertyClassReflection->getConstant($constantName)->getValue()); + if ( + $constantType instanceof ConstantType + && in_array(sprintf('%s::%s', $propertyClassReflection->getName(), $constantName), $this->dynamicConstantNames, true) + ) { + $constantType = $constantType->generalize(); + } + $types[] = $constantType; + } + + if (count($types) > 0) { + return TypeCombinator::union(...$types); + } + + if (!$constantClassType->hasConstant($constantName)->yes()) { + return new ErrorType(); + } + + return $this->getTypeFromValue($constantClassType->getConstant($constantName)->getValue()); + } + + if ($node instanceof Expr\Ternary) { + if ($node->if === null) { + $conditionType = $this->getType($node->cond); + $booleanConditionType = $conditionType->toBoolean(); + if ($booleanConditionType instanceof ConstantBooleanType) { + if ($booleanConditionType->getValue()) { + return $this->filterByTruthyValue($node->cond, true)->getType($node->cond); + } + + return $this->filterByFalseyValue($node->cond, true)->getType($node->else); + } + return TypeCombinator::union( + $this->filterByTruthyValue($node->cond, true)->getType($node->cond), + $this->filterByFalseyValue($node->cond, true)->getType($node->else) + ); + } + + $booleanConditionType = $this->getType($node->cond)->toBoolean(); + if ($booleanConditionType instanceof ConstantBooleanType) { + if ($booleanConditionType->getValue()) { + return $this->filterByTruthyValue($node->cond)->getType($node->if); + } + + return $this->filterByFalseyValue($node->cond)->getType($node->else); + } + + return TypeCombinator::union( + $this->filterByTruthyValue($node->cond)->getType($node->if), + $this->filterByFalseyValue($node->cond)->getType($node->else) + ); + } + + if ($node instanceof Variable && is_string($node->name)) { + if ($this->hasVariableType($node->name)->no()) { + return new ErrorType(); + } + + return $this->getVariableType($node->name); + } + + if ($node instanceof Expr\ArrayDimFetch && $node->dim !== null) { + return $this->getTypeFromArrayDimFetch( + $node, + $this->getType($node->dim), + $this->getType($node->var) + ); + } + + if ($node instanceof MethodCall && $node->name instanceof Node\Identifier) { + $methodCalledOnType = $this->getType($node->var); + $referencedClasses = TypeUtils::getDirectClassNames($methodCalledOnType); + $resolvedTypes = []; + foreach ($referencedClasses as $referencedClass) { + if (!$this->broker->hasClass($referencedClass)) { + continue; + } + + $methodClassReflection = $this->broker->getClass($referencedClass); + if (!$methodClassReflection->hasMethod($node->name->name)) { + continue; + } + + $methodReflection = $methodClassReflection->getMethod($node->name->name, $this); + $foundDynamicReturnTypeExtension = false; + foreach ($this->broker->getDynamicMethodReturnTypeExtensionsForClass($methodClassReflection->getName()) as $dynamicMethodReturnTypeExtension) { + if (!$dynamicMethodReturnTypeExtension->isMethodSupported($methodReflection)) { + continue; + } + + $resolvedTypes[] = $dynamicMethodReturnTypeExtension->getTypeFromMethodCall($methodReflection, $node, $this); + $foundDynamicReturnTypeExtension = true; + } + + if ($foundDynamicReturnTypeExtension) { + continue; + } + + $methodReturnType = ParametersAcceptorSelector::selectFromArgs( + $this, + $node->args, + $methodReflection->getVariants() + )->getReturnType(); + if ($methodReturnType instanceof StaticResolvableType) { + $calledOnThis = $this->getType($node->var) instanceof ThisType; + if ($calledOnThis && $this->isInClass()) { + $resolvedTypes[] = $methodReturnType->changeBaseClass($this->getClassReflection()->getName()); + } else { + $resolvedTypes[] = $methodReturnType->resolveStatic($referencedClass); + } + } else { + $resolvedTypes[] = $methodReturnType; + } + } + if (count($resolvedTypes) > 0) { + return TypeCombinator::union(...$resolvedTypes); + } + + if ($methodCalledOnType->hasMethod($node->name->name)->yes()) { + $methodReflection = $methodCalledOnType->getMethod($node->name->name, $this); + return ParametersAcceptorSelector::selectFromArgs( + $this, + $node->args, + $methodReflection->getVariants() + )->getReturnType(); + } + + return new ErrorType(); + } + + if ($node instanceof Expr\StaticCall && $node->name instanceof Node\Identifier) { + if ($node->class instanceof Name) { + $calleeType = new ObjectType($this->resolveName($node->class)); + } else { + $calleeType = $this->getType($node->class); + } + + $referencedClasses = TypeUtils::getDirectClassNames($calleeType); + $resolvedTypes = []; + foreach ($referencedClasses as $referencedClass) { + if (!$this->broker->hasClass($referencedClass)) { + continue; + } + + $staticMethodClassReflection = $this->broker->getClass($referencedClass); + if (!$staticMethodClassReflection->hasMethod($node->name->name)) { + continue; + } + + $staticMethodReflection = $staticMethodClassReflection->getMethod($node->name->name, $this); + $foundDynamicReturnTypeExtension = false; + foreach ($this->broker->getDynamicStaticMethodReturnTypeExtensionsForClass($staticMethodClassReflection->getName()) as $dynamicStaticMethodReturnTypeExtension) { + if (!$dynamicStaticMethodReturnTypeExtension->isStaticMethodSupported($staticMethodReflection)) { + continue; + } + + $resolvedTypes[] = $dynamicStaticMethodReturnTypeExtension->getTypeFromStaticMethodCall($staticMethodReflection, $node, $this); + $foundDynamicReturnTypeExtension = true; + } + + if ($foundDynamicReturnTypeExtension) { + continue; + } + + $staticMethodReturnType = ParametersAcceptorSelector::selectFromArgs( + $this, + $node->args, + $staticMethodReflection->getVariants() + )->getReturnType(); + if ($staticMethodReturnType instanceof StaticResolvableType) { + if ($node->class instanceof Name) { + $nameNodeClassName = (string) $node->class; + $lowercasedNameNodeClassName = strtolower($nameNodeClassName); + if (in_array($lowercasedNameNodeClassName, [ + 'self', + 'static', + 'parent', + ], true) && $this->isInClass()) { + $resolvedTypes[] = $staticMethodReturnType->changeBaseClass($this->getClassReflection()->getName()); + } elseif ($this->broker->hasClass($nameNodeClassName)) { + $classReflection = $this->broker->getClass($nameNodeClassName); + $resolvedTypes[] = $staticMethodReturnType->resolveStatic($classReflection->getName()); + } else { + $resolvedTypes[] = $staticMethodReturnType; + } + } else { + $resolvedTypes[] = $staticMethodReturnType->resolveStatic($referencedClass); + } + } else { + $resolvedTypes[] = $staticMethodReturnType; + } + } + if (count($resolvedTypes) > 0) { + return TypeCombinator::union(...$resolvedTypes); + } + + if ($calleeType->hasMethod($node->name->name)->yes()) { + $staticMethodReflection = $calleeType->getMethod($node->name->name, $this); + return ParametersAcceptorSelector::selectFromArgs( + $this, + $node->args, + $staticMethodReflection->getVariants() + )->getReturnType(); + } + + return new ErrorType(); + } + + if ($node instanceof PropertyFetch && $node->name instanceof Node\Identifier) { + $propertyFetchedOnType = $this->getType($node->var); + $referencedClasses = TypeUtils::getDirectClassNames($propertyFetchedOnType); + $propertyName = $node->name->toString(); + $types = []; + foreach ($referencedClasses as $referencedClass) { + if (!$this->broker->hasClass($referencedClass)) { + continue; + } + + $propertyClassReflection = $this->broker->getClass($referencedClass); + if (!$propertyClassReflection->hasProperty($propertyName)) { + continue; + } + + $types[] = $propertyClassReflection->getProperty($propertyName, $this)->getType(); + } + + if (count($types) > 0) { + return TypeCombinator::union(...$types); + } + + if (!$propertyFetchedOnType->hasProperty($node->name->name)->yes()) { + return new ErrorType(); + } + + return $propertyFetchedOnType->getProperty($node->name->name, $this)->getType(); + } + + if ( + $node instanceof Expr\StaticPropertyFetch + && $node->name instanceof Node\VarLikeIdentifier + ) { + if ($node->class instanceof Name) { + $calleeType = new ObjectType($this->resolveName($node->class)); + } else { + $calleeType = $this->getType($node->class); + } + + $referencedClasses = TypeUtils::getDirectClassNames($calleeType); + $propertyName = $node->name->toString(); + $types = []; + foreach ($referencedClasses as $referencedClass) { + if (!$this->broker->hasClass($referencedClass)) { + continue; + } + + $propertyClassReflection = $this->broker->getClass($referencedClass); + if (!$propertyClassReflection->hasProperty($propertyName)) { + continue; + } + + $types[] = $propertyClassReflection->getProperty($propertyName, $this)->getType(); + } + + if (count($types) > 0) { + return TypeCombinator::union(...$types); + } + + if (!$calleeType->hasProperty($node->name->name)->yes()) { + return new ErrorType(); + } + + return $calleeType->getProperty($node->name->name, $this)->getType(); + } + + if ($node instanceof FuncCall) { + if ($node->name instanceof Expr) { + $calledOnType = $this->getType($node->name); + if ($calledOnType->isCallable()->no()) { + return new ErrorType(); + } + + return ParametersAcceptorSelector::selectFromArgs( + $this, + $node->args, + $calledOnType->getCallableParametersAcceptors($this) + )->getReturnType(); + } + + if (!$this->broker->hasFunction($node->name, $this)) { + return new ErrorType(); + } + + $functionReflection = $this->broker->getFunction($node->name, $this); + foreach ($this->broker->getDynamicFunctionReturnTypeExtensions() as $dynamicFunctionReturnTypeExtension) { + if (!$dynamicFunctionReturnTypeExtension->isFunctionSupported($functionReflection)) { + continue; + } + + return $dynamicFunctionReturnTypeExtension->getTypeFromFunctionCall($functionReflection, $node, $this); + } + + return ParametersAcceptorSelector::selectFromArgs( + $this, + $node->args, + $functionReflection->getVariants() + )->getReturnType(); + } + + return new MixedType(); + } + + protected function getTypeFromArrayDimFetch( + Expr\ArrayDimFetch $arrayDimFetch, + Type $offsetType, + Type $offsetAccessibleType + ): Type + { + if ($arrayDimFetch->dim === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ((new ObjectType(\ArrayAccess::class))->isSuperTypeOf($offsetAccessibleType)->yes()) { + return $this->getType( + new MethodCall( + $arrayDimFetch->var, + new Node\Identifier('offsetGet'), + [ + new Node\Arg($arrayDimFetch->dim), + ] + ) + ); + } + + return $offsetAccessibleType->getOffsetValueType($offsetType); + } + + private function calculateFromScalars(Expr $node, ConstantScalarType $leftType, ConstantScalarType $rightType): Type + { + if ($leftType instanceof StringType && $rightType instanceof StringType) { + /** @var string $leftValue */ + $leftValue = $leftType->getValue(); + /** @var string $rightValue */ + $rightValue = $rightType->getValue(); + + if ($node instanceof Expr\BinaryOp\BitwiseAnd || $node instanceof Expr\AssignOp\BitwiseAnd) { + return $this->getTypeFromValue($leftValue & $rightValue); + } + + if ($node instanceof Expr\BinaryOp\BitwiseOr || $node instanceof Expr\AssignOp\BitwiseOr) { + return $this->getTypeFromValue($leftValue | $rightValue); + } + + if ($node instanceof Expr\BinaryOp\BitwiseXor || $node instanceof Expr\AssignOp\BitwiseXor) { + return $this->getTypeFromValue($leftValue ^ $rightValue); + } + } + + $leftValue = $leftType->getValue(); + $rightValue = $rightType->getValue(); + + if ($node instanceof Node\Expr\BinaryOp\Spaceship) { + return $this->getTypeFromValue($leftValue <=> $rightValue); + } + + $leftNumberType = $leftType->toNumber(); + $rightNumberType = $rightType->toNumber(); + if (TypeCombinator::union($leftNumberType, $rightNumberType) instanceof ErrorType) { + return new ErrorType(); + } + + if (!$leftNumberType instanceof ConstantScalarType || !$rightNumberType instanceof ConstantScalarType) { + throw new \PHPStan\ShouldNotHappenException(); + } + + /** @var float|int $leftNumberValue */ + $leftNumberValue = $leftNumberType->getValue(); + + /** @var float|int $rightNumberValue */ + $rightNumberValue = $rightNumberType->getValue(); + + if ($node instanceof Node\Expr\BinaryOp\Plus || $node instanceof Node\Expr\AssignOp\Plus) { + return $this->getTypeFromValue($leftNumberValue + $rightNumberValue); + } + + if ($node instanceof Node\Expr\BinaryOp\Minus || $node instanceof Node\Expr\AssignOp\Minus) { + return $this->getTypeFromValue($leftNumberValue - $rightNumberValue); + } + + if ($node instanceof Node\Expr\BinaryOp\Mul || $node instanceof Node\Expr\AssignOp\Mul) { + return $this->getTypeFromValue($leftNumberValue * $rightNumberValue); + } + + if ($node instanceof Node\Expr\BinaryOp\Pow || $node instanceof Node\Expr\AssignOp\Pow) { + return $this->getTypeFromValue($leftNumberValue ** $rightNumberValue); + } + + if ($node instanceof Node\Expr\BinaryOp\Div || $node instanceof Node\Expr\AssignOp\Div) { + return $this->getTypeFromValue($leftNumberValue / $rightNumberValue); + } + + if ($node instanceof Node\Expr\BinaryOp\Mod || $node instanceof Node\Expr\AssignOp\Mod) { + return $this->getTypeFromValue($leftNumberValue % $rightNumberValue); + } + + if ($node instanceof Expr\BinaryOp\ShiftLeft || $node instanceof Expr\AssignOp\ShiftLeft) { + return $this->getTypeFromValue($leftNumberValue << $rightNumberValue); + } + + if ($node instanceof Expr\BinaryOp\ShiftRight || $node instanceof Expr\AssignOp\ShiftRight) { + return $this->getTypeFromValue($leftNumberValue >> $rightNumberValue); + } + + if ($node instanceof Expr\BinaryOp\BitwiseAnd || $node instanceof Expr\AssignOp\BitwiseAnd) { + return $this->getTypeFromValue($leftNumberValue & $rightNumberValue); + } + + if ($node instanceof Expr\BinaryOp\BitwiseOr || $node instanceof Expr\AssignOp\BitwiseOr) { + return $this->getTypeFromValue($leftNumberValue | $rightNumberValue); + } + + if ($node instanceof Expr\BinaryOp\BitwiseXor || $node instanceof Expr\AssignOp\BitwiseXor) { + return $this->getTypeFromValue($leftNumberValue ^ $rightNumberValue); + } + + return new MixedType(); + } + + public function resolveName(Name $name): string + { + $originalClass = (string) $name; + if ($this->isInClass()) { + if (in_array(strtolower($originalClass), [ + 'self', + 'static', + ], true)) { + return $this->getClassReflection()->getName(); + } elseif ($originalClass === 'parent') { + $currentClassReflection = $this->getClassReflection(); + if ($currentClassReflection->getParentClass() !== false) { + return $currentClassReflection->getParentClass()->getName(); + } + } + } + + return $originalClass; + } + + /** + * @param mixed $value + */ + public function getTypeFromValue($value): Type + { + if (is_int($value)) { + return new ConstantIntegerType($value); + } elseif (is_float($value)) { + return new ConstantFloatType($value); + } elseif (is_bool($value)) { + return new ConstantBooleanType($value); + } elseif ($value === null) { + return new NullType(); + } elseif (is_string($value)) { + return new ConstantStringType($value); + } elseif (is_array($value)) { + $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); + foreach ($value as $k => $v) { + $arrayBuilder->setOffsetValueType($this->getTypeFromValue($k), $this->getTypeFromValue($v)); + } + return $arrayBuilder->getArray(); + } + + return new MixedType(); + } + + public function isSpecified(Expr $node): bool + { + $exprString = $this->printer->prettyPrintExpr($node); + + return isset($this->moreSpecificTypes[$exprString]); + } + + public function enterClass(ClassReflection $classReflection): self + { + return $this->scopeFactory->create( + $this->context->enterClass($classReflection), + $this->isDeclareStrictTypes(), + null, + $this->getNamespace(), + [ + 'this' => VariableTypeHolder::createYes(new ThisType($classReflection->getName())), + ] + ); + } + + public function enterTrait(ClassReflection $traitReflection): self + { + return $this->scopeFactory->create( + $this->context->enterTrait($traitReflection), + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $this->getVariableTypes(), + $this->moreSpecificTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated() + ); + } + + /** + * @param Node\Stmt\ClassMethod $classMethod + * @param Type[] $phpDocParameterTypes + * @param Type|null $phpDocReturnType + * @param Type|null $throwType + * @param bool $isDeprecated + * @param bool $isInternal + * @param bool $isFinal + * @return self + */ + public function enterClassMethod( + Node\Stmt\ClassMethod $classMethod, + array $phpDocParameterTypes, + ?Type $phpDocReturnType, + ?Type $throwType, + bool $isDeprecated, + bool $isInternal, + bool $isFinal + ): self + { + if (!$this->isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->enterFunctionLike( + new PhpMethodFromParserNodeReflection( + $this->getClassReflection(), + $classMethod, + $this->getRealParameterTypes($classMethod), + $phpDocParameterTypes, + $classMethod->returnType !== null, + $this->getFunctionType($classMethod->returnType, $classMethod->returnType === null, false), + $phpDocReturnType, + $throwType, + $isDeprecated, + $isInternal, + $isFinal + ) + ); + } + + /** + * @param Node\FunctionLike $functionLike + * @return Type[] + */ + private function getRealParameterTypes(Node\FunctionLike $functionLike): array + { + $realParameterTypes = []; + foreach ($functionLike->getParams() as $parameter) { + if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $realParameterTypes[$parameter->var->name] = $this->getFunctionType( + $parameter->type, + $this->isParameterValueNullable($parameter), + $parameter->variadic + ); + } + + return $realParameterTypes; + } + + /** + * @param Node\Stmt\Function_ $function + * @param Type[] $phpDocParameterTypes + * @param Type|null $phpDocReturnType + * @param Type|null $throwType + * @param bool $isDeprecated + * @param bool $isInternal + * @param bool $isFinal + * @return self + */ + public function enterFunction( + Node\Stmt\Function_ $function, + array $phpDocParameterTypes, + ?Type $phpDocReturnType, + ?Type $throwType, + bool $isDeprecated, + bool $isInternal, + bool $isFinal + ): self + { + return $this->enterFunctionLike( + new PhpFunctionFromParserNodeReflection( + $function, + $this->getRealParameterTypes($function), + $phpDocParameterTypes, + $function->returnType !== null, + $this->getFunctionType($function->returnType, $function->returnType === null, false), + $phpDocReturnType, + $throwType, + $isDeprecated, + $isInternal, + $isFinal + ) + ); + } + + private function enterFunctionLike( + PhpFunctionFromParserNodeReflection $functionReflection + ): self + { + $variableTypes = $this->getVariableTypes(); + foreach (ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getParameters() as $parameter) { + $variableTypes[$parameter->getName()] = VariableTypeHolder::createYes($parameter->getType()); + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $functionReflection, + $this->getNamespace(), + $variableTypes, + [], + null, + null + ); + } + + public function enterNamespace(string $namespaceName): self + { + return $this->scopeFactory->create( + $this->context->beginFile(), + $this->isDeclareStrictTypes(), + null, + $namespaceName + ); + } + + public function enterClosureBind(?Type $thisType, string $scopeClass): self + { + $variableTypes = $this->getVariableTypes(); + + if ($thisType !== null) { + $variableTypes['this'] = VariableTypeHolder::createYes($thisType); + } else { + unset($variableTypes['this']); + } + + if ($scopeClass === 'static' && $this->isInClass()) { + $scopeClass = $this->getClassReflection()->getName(); + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypes, + $this->moreSpecificTypes, + $scopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated() + ); + } + + public function enterClosureCall(Type $thisType): self + { + $variableTypes = $this->getVariableTypes(); + $variableTypes['this'] = VariableTypeHolder::createYes($thisType); + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypes, + $this->moreSpecificTypes, + $thisType instanceof TypeWithClassName ? $thisType->getClassName() : null, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated() + ); + } + + public function isInClosureBind(): bool + { + return $this->inClosureBindScopeClass !== null; + } + + public function enterAnonymousClass(ClassReflection $anonymousClass): self + { + return $this->enterClass($anonymousClass); + } + + public function enterAnonymousFunction( + Expr\Closure $closure + ): self + { + $variableTypes = []; + foreach ($closure->params as $parameter) { + $isNullable = $this->isParameterValueNullable($parameter); + + if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $variableTypes[$parameter->var->name] = VariableTypeHolder::createYes( + $this->getFunctionType($parameter->type, $isNullable, $parameter->variadic) + ); + } + + foreach ($closure->uses as $use) { + if (!is_string($use->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + if ($this->hasVariableType($use->var->name)->no()) { + if ($use->byRef) { + if ($this->isInExpressionAssign(new Variable($use->var->name))) { + $variableTypes[$use->var->name] = VariableTypeHolder::createYes( + $this->getType($closure) + ); + continue; + } + $variableTypes[$use->var->name] = VariableTypeHolder::createYes(new NullType()); + } + continue; + } + $variableTypes[$use->var->name] = VariableTypeHolder::createYes($this->getVariableType($use->var->name)); + } + + if ($this->hasVariableType('this')->yes()) { + $variableTypes['this'] = VariableTypeHolder::createYes($this->getVariableType('this')); + } + + $returnType = $this->getFunctionType($closure->returnType, $closure->returnType === null, false); + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypes, + [], + $this->inClosureBindScopeClass, + $returnType, + $this->getInFunctionCall() + ); + } + + public function isParameterValueNullable(Node\Param $parameter): bool + { + if ($parameter->default instanceof ConstFetch) { + return strtolower((string) $parameter->default->name) === 'null'; + } + + return false; + } + + /** + * @param \PhpParser\Node\Name|\PhpParser\Node\Identifier|\PhpParser\Node\NullableType|null $type + * @param bool $isNullable + * @param bool $isVariadic + * @return Type + */ + public function getFunctionType($type, bool $isNullable, bool $isVariadic): Type + { + if ($isNullable) { + return TypeCombinator::addNull( + $this->getFunctionType($type, false, $isVariadic) + ); + } + if ($isVariadic) { + return new ArrayType(new IntegerType(), $this->getFunctionType( + $type, + false, + false + )); + } + if ($type === null) { + return new MixedType(); + } elseif ($type instanceof Name) { + $className = (string) $type; + $lowercasedClassName = strtolower($className); + if ($this->isInClass() && in_array($lowercasedClassName, ['self', 'static'], true)) { + $className = $this->getClassReflection()->getName(); + } elseif ( + $lowercasedClassName === 'parent' + ) { + if ($this->isInClass() && $this->getClassReflection()->getParentClass() !== false) { + return new ObjectType($this->getClassReflection()->getParentClass()->getName()); + } + + return new NonexistentParentClassType(); + } + return new ObjectType($className); + } elseif ($type instanceof Node\NullableType) { + return $this->getFunctionType($type->type, true, $isVariadic); + } + + $type = $type->name; + if ($type === 'string') { + return new StringType(); + } elseif ($type === 'int') { + return new IntegerType(); + } elseif ($type === 'bool') { + return new BooleanType(); + } elseif ($type === 'float') { + return new FloatType(); + } elseif ($type === 'callable') { + return new CallableType(); + } elseif ($type === 'array') { + return new ArrayType(new MixedType(), new MixedType()); + } elseif ($type === 'iterable') { + return new IterableType(new MixedType(), new MixedType()); + } elseif ($type === 'void') { + return new VoidType(); + } elseif ($type === 'object') { + return new ObjectWithoutClassType(); + } + + return new MixedType(); + } + + public function enterForeach(Expr $iteratee, string $valueName, ?string $keyName): self + { + $iterateeType = $this->getType($iteratee); + $scope = $this->assignVariable($valueName, $iterateeType->getIterableValueType(), TrinaryLogic::createYes()); + + if ($keyName !== null) { + $scope = $scope->assignVariable($keyName, $iterateeType->getIterableKeyType(), TrinaryLogic::createYes()); + } + + return $scope; + } + + /** + * @param \PhpParser\Node\Name[] $classes + * @param string $variableName + * @return Scope + */ + public function enterCatch(array $classes, string $variableName): self + { + $type = TypeCombinator::union(...array_map(static function (string $class): ObjectType { + return new ObjectType($class); + }, $classes)); + + return $this->assignVariable( + $variableName, + TypeCombinator::intersect($type, new ObjectType(\Throwable::class)), + TrinaryLogic::createYes() + ); + } + + /** + * @param \PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall $functionCall + * @return self + */ + public function enterFunctionCall($functionCall): self + { + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $this->getVariableTypes(), + $this->moreSpecificTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $functionCall, + $this->isNegated(), + $this->inFirstLevelStatement + ); + } + + public function enterExpressionAssign(Expr $expr): self + { + $currentlyAssignedExpressions = $this->currentlyAssignedExpressions; + $currentlyAssignedExpressions[] = $this->printer->prettyPrintExpr($expr); + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $this->getVariableTypes(), + $this->moreSpecificTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->isInFirstLevelStatement(), + $currentlyAssignedExpressions + ); + } + + public function isInExpressionAssign(Expr $expr): bool + { + $exprString = $this->printer->prettyPrintExpr($expr); + return in_array($exprString, $this->currentlyAssignedExpressions, true); + } + + public function assignVariable( + string $variableName, + Type $type, + TrinaryLogic $certainty + ): self + { + if ($certainty->no()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $existingCertainty = $this->hasVariableType($variableName); + if (!$existingCertainty->no()) { + $certainty = $certainty->or($existingCertainty); + } + + $variableTypes = $this->getVariableTypes(); + $variableTypes[$variableName] = new VariableTypeHolder($type, $certainty); + + $variableString = $this->printer->prettyPrintExpr(new Variable($variableName)); + $moreSpecificTypeHolders = $this->moreSpecificTypes; + foreach (array_keys($moreSpecificTypeHolders) as $key) { + $matches = \Nette\Utils\Strings::match((string) $key, '#(\$[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*)#'); + if ($matches === null) { + continue; + } + + if ($matches[1] !== $variableString) { + continue; + } + + unset($moreSpecificTypeHolders[$key]); + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypes, + $moreSpecificTypeHolders, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement, + $this->currentlyAssignedExpressions + ); + } + + public function unsetExpression(Expr $expr): self + { + if ($expr instanceof Variable && is_string($expr->name)) { + if ($this->hasVariableType($expr->name)->no()) { + return $this; + } + $variableTypes = $this->getVariableTypes(); + unset($variableTypes[$expr->name]); + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypes, + $this->moreSpecificTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } elseif ($expr instanceof Expr\ArrayDimFetch && $expr->dim !== null) { + $constantArrays = TypeUtils::getConstantArrays($this->getType($expr->var)); + if (count($constantArrays) > 0) { + $unsetArrays = []; + $dimType = $this->getType($expr->dim); + foreach ($constantArrays as $constantArray) { + $unsetArrays[] = $constantArray->unsetOffset($dimType); + } + return $this->specifyExpressionType( + $expr->var, + TypeCombinator::union(...$unsetArrays) + ); + } + } + + return $this; + } + + public function intersectVariables(Scope $otherScope): self + { + $ourVariableTypeHolders = $this->getVariableTypes(); + $theirVariableTypeHolders = $otherScope->getVariableTypes(); + $intersectedVariableTypeHolders = []; + foreach ($theirVariableTypeHolders as $name => $variableTypeHolder) { + if (isset($ourVariableTypeHolders[$name])) { + $intersectedVariableTypeHolders[$name] = $ourVariableTypeHolders[$name]->and($variableTypeHolder); + } else { + $intersectedVariableTypeHolders[$name] = VariableTypeHolder::createMaybe($variableTypeHolder->getType()); + } + } + + foreach ($ourVariableTypeHolders as $name => $variableTypeHolder) { + $variableNode = new Variable($name); + if ($otherScope->isSpecified($variableNode)) { + $intersectedVariableTypeHolders[$name] = VariableTypeHolder::createYes( + TypeCombinator::union( + $otherScope->getType($variableNode), + $variableTypeHolder->getType() + ) + ); + continue; + } + if (isset($theirVariableTypeHolders[$name])) { + continue; + } + + $intersectedVariableTypeHolders[$name] = VariableTypeHolder::createMaybe($variableTypeHolder->getType()); + } + + $ourSpecifiedTypeHolders = $this->moreSpecificTypes; + $theirSpecifiedTypeHolders = $otherScope->moreSpecificTypes; + $intersectedSpecifiedTypes = []; + + foreach ($theirSpecifiedTypeHolders as $exprString => $theirSpecifiedTypeHolder) { + $matches = \Nette\Utils\Strings::match((string) $exprString, '#^\$([a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*)$#'); + if ($matches !== null) { + continue; + } + if (isset($ourSpecifiedTypeHolders[$exprString])) { + $intersectedSpecifiedTypes[$exprString] = $ourSpecifiedTypeHolders[$exprString]->and($theirSpecifiedTypeHolder); + } else { + $intersectedSpecifiedTypes[$exprString] = VariableTypeHolder::createMaybe($theirSpecifiedTypeHolder->getType()); + } + } + + foreach ($this->moreSpecificTypes as $exprString => $specificTypeHolder) { + $matches = \Nette\Utils\Strings::match((string) $exprString, '#^\$([a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*)$#'); + if ($matches !== null) { + continue; + } + if (isset($otherScope->moreSpecificTypes[$exprString])) { + $intersectedSpecifiedTypes[$exprString] = VariableTypeHolder::createYes( + TypeCombinator::union( + $otherScope->moreSpecificTypes[$exprString]->getType(), + $specificTypeHolder->getType() + ) + ); + continue; + } + if (isset($theirVariableTypeHolders[$exprString])) { + continue; + } + + $intersectedSpecifiedTypes[$exprString] = VariableTypeHolder::createMaybe($specificTypeHolder->getType()); + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $intersectedVariableTypeHolders, + $intersectedSpecifiedTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } + + public function createIntersectedScope(self $otherScope): self + { + $variableTypes = []; + foreach ($otherScope->getVariableTypes() as $name => $variableTypeHolder) { + $variableTypes[$name] = $variableTypeHolder; + } + + $specifiedTypes = []; + foreach ($otherScope->moreSpecificTypes as $exprString => $specificTypeHolder) { + $matches = \Nette\Utils\Strings::match((string) $exprString, '#^\$([a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*)$#'); + if ($matches !== null) { + $variableTypes[$matches[1]] = $specificTypeHolder; + continue; + } + $specifiedTypes[$exprString] = $specificTypeHolder; + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypes, + $specifiedTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } + + public function mergeWithIntersectedScope(self $intersectedScope): self + { + $variableTypeHolders = $this->variableTypes; + $specifiedTypeHolders = $this->moreSpecificTypes; + foreach ($intersectedScope->getVariableTypes() as $name => $theirVariableTypeHolder) { + if (isset($variableTypeHolders[$name])) { + $type = $theirVariableTypeHolder->getType(); + if ($theirVariableTypeHolder->getCertainty()->maybe()) { + $type = TypeCombinator::union($type, $variableTypeHolders[$name]->getType()); + } + $theirVariableTypeHolder = new VariableTypeHolder( + $type, + $theirVariableTypeHolder->getCertainty()->or($variableTypeHolders[$name]->getCertainty()) + ); + } + + $variableTypeHolders[$name] = $theirVariableTypeHolder; + + $exprString = $this->printer->prettyPrintExpr(new Variable($name)); + unset($specifiedTypeHolders[$exprString]); + } + + foreach ($intersectedScope->moreSpecificTypes as $exprString => $theirTypeHolder) { + if (isset($specifiedTypeHolders[$exprString])) { + $type = $theirTypeHolder->getType(); + if ($theirTypeHolder->getCertainty()->maybe()) { + $type = TypeCombinator::union($type, $specifiedTypeHolders[$exprString]->getType()); + } + $theirTypeHolder = new VariableTypeHolder( + $type, + $theirTypeHolder->getCertainty()->or($specifiedTypeHolders[$exprString]->getCertainty()) + ); + } + + if (!$theirTypeHolder->getCertainty()->yes()) { + continue; + } + + $specifiedTypeHolders[$exprString] = $theirTypeHolder; + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypeHolders, + $specifiedTypeHolders, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } + + public function removeSpecified(self $initialScope): self + { + $variableTypeHolders = $this->variableTypes; + foreach ($variableTypeHolders as $name => $holder) { + if (!$holder->getCertainty()->yes()) { + continue; + } + $node = new Variable($name); + if ($this->isSpecified($node) && !$initialScope->hasVariableType($name)->no()) { + $variableTypeHolders[$name] = VariableTypeHolder::createYes(TypeCombinator::remove($initialScope->getVariableType($name), $this->getType($node))); + continue; + } + } + + $moreSpecificTypeHolders = $this->moreSpecificTypes; + foreach (array_keys($moreSpecificTypeHolders) as $exprString) { + if (isset($initialScope->moreSpecificTypes[$exprString])) { + continue; + } + + unset($moreSpecificTypeHolders[$exprString]); + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypeHolders, + $moreSpecificTypeHolders, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } + + public function removeVariables(self $otherScope, bool $all): self + { + $ourVariableTypeHolders = $this->getVariableTypes(); + foreach ($otherScope->getVariableTypes() as $name => $theirVariableTypeHolder) { + if ($all) { + if ( + isset($ourVariableTypeHolders[$name]) + && $ourVariableTypeHolders[$name]->getCertainty()->equals($theirVariableTypeHolder->getCertainty()) + ) { + unset($ourVariableTypeHolders[$name]); + } + } else { + if ( + isset($ourVariableTypeHolders[$name]) + && $theirVariableTypeHolder->getType()->equals($ourVariableTypeHolders[$name]->getType()) + && $ourVariableTypeHolders[$name]->getCertainty()->equals($theirVariableTypeHolder->getCertainty()) + ) { + unset($ourVariableTypeHolders[$name]); + } + } + } + + $ourTypeHolders = $this->moreSpecificTypes; + foreach ($otherScope->moreSpecificTypes as $exprString => $theirTypeHolder) { + if ($all) { + if ( + isset($ourTypeHolders[$exprString]) + && $ourTypeHolders[$exprString]->getCertainty()->equals($theirTypeHolder->getCertainty()) + ) { + unset($ourVariableTypeHolders[$exprString]); + } + } else { + if ( + isset($ourTypeHolders[$exprString]) + && $theirTypeHolder->getType()->equals($ourTypeHolders[$exprString]->getType()) + && $ourTypeHolders[$exprString]->getCertainty()->equals($theirTypeHolder->getCertainty()) + ) { + unset($ourVariableTypeHolders[$exprString]); + } + } + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $ourVariableTypeHolders, + $ourTypeHolders, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } + + public function specifyExpressionType(Expr $expr, Type $type): self + { + if ($expr instanceof Node\Scalar || $expr instanceof Array_) { + return $this; + } + + $exprString = $this->printer->prettyPrintExpr($expr); + + $scope = $this; + + if ($expr instanceof Variable && is_string($expr->name)) { + $variableName = $expr->name; + + $variableTypes = $this->getVariableTypes(); + $variableTypes[$variableName] = VariableTypeHolder::createYes($type); + + $moreSpecificTypes = $this->moreSpecificTypes; + $moreSpecificTypes[$exprString] = $variableTypes[$variableName]; + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $variableTypes, + $moreSpecificTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } elseif ($expr instanceof Expr\ArrayDimFetch && $expr->dim !== null) { + $constantArrays = TypeUtils::getConstantArrays($this->getType($expr->var)); + if (count($constantArrays) > 0) { + $setArrays = []; + $dimType = $this->getType($expr->dim); + foreach ($constantArrays as $constantArray) { + $setArrays[] = $constantArray->setOffsetValueType($dimType, $type); + } + $scope = $this->specifyExpressionType( + $expr->var, + TypeCombinator::union(...$setArrays) + ); + } + } + + return $scope->addMoreSpecificTypes([ + $exprString => $type, + ]); + } + + public function unspecifyExpressionType(Expr $expr): self + { + $exprString = $this->printer->prettyPrintExpr($expr); + $moreSpecificTypeHolders = $this->moreSpecificTypes; + if (isset($moreSpecificTypeHolders[$exprString]) && !$moreSpecificTypeHolders[$exprString]->getType() instanceof MixedType) { + unset($moreSpecificTypeHolders[$exprString]); + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $this->getVariableTypes(), + $moreSpecificTypeHolders, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } + + return $this; + } + + public function removeTypeFromExpression(Expr $expr, Type $type): self + { + return $this->specifyExpressionType( + $expr, + TypeCombinator::remove($this->getType($expr), $type) + ); + } + + public function filterByTruthyValue(Expr $expr, bool $defaultHandleFunctions = false): self + { + $specifiedTypes = $this->typeSpecifier->specifyTypesInCondition($this, $expr, TypeSpecifierContext::createTruthy(), $defaultHandleFunctions); + return $this->filterBySpecifiedTypes($specifiedTypes); + } + + public function filterByFalseyValue(Expr $expr, bool $defaultHandleFunctions = false): self + { + $specifiedTypes = $this->typeSpecifier->specifyTypesInCondition($this, $expr, TypeSpecifierContext::createFalsey(), $defaultHandleFunctions); + return $this->filterBySpecifiedTypes($specifiedTypes); + } + + public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self + { + $typeSpecifications = []; + foreach ($specifiedTypes->getSureTypes() as $exprString => [$expr, $type]) { + $typeSpecifications[] = [ + 'sure' => true, + 'exprString' => $exprString, + 'expr' => $expr, + 'type' => $type, + ]; + } + foreach ($specifiedTypes->getSureNotTypes() as $exprString => [$expr, $type]) { + $typeSpecifications[] = [ + 'sure' => false, + 'exprString' => $exprString, + 'expr' => $expr, + 'type' => $type, + ]; + } + + usort($typeSpecifications, static function (array $a, array $b): int { + $length = strlen((string) $a['exprString']) - strlen((string) $b['exprString']); + if ($length !== 0) { + return $length; + } + + return $b['sure'] - $a['sure']; + }); + + $scope = $this; + foreach ($typeSpecifications as $typeSpecification) { + $expr = $typeSpecification['expr']; + $type = $typeSpecification['type']; + if ($typeSpecification['sure']) { + $type = TypeCombinator::intersect($type, $this->getType($expr)); + $scope = $scope->specifyExpressionType($expr, $type); + } else { + $scope = $scope->removeTypeFromExpression($expr, $type); + } + } + + return $scope; + } + + public function specifyFetchedStaticPropertyFromIsset(Expr\StaticPropertyFetch $expr): self + { + $exprString = $this->printer->prettyPrintExpr($expr); + + return $this->addMoreSpecificTypes([ + $exprString => new MixedType(), + ]); + } + + public function enterNegation(): self + { + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $this->getVariableTypes(), + $this->moreSpecificTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + !$this->isNegated(), + $this->inFirstLevelStatement + ); + } + + public function enterFirstLevelStatements(): self + { + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $this->getVariableTypes(), + $this->moreSpecificTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + true, + $this->currentlyAssignedExpressions + ); + } + + public function exitFirstLevelStatements(): self + { + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $this->getVariableTypes(), + $this->moreSpecificTypes, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + false, + $this->currentlyAssignedExpressions + ); + } + + public function isInFirstLevelStatement(): bool + { + return $this->inFirstLevelStatement; + } + + public function isNegated(): bool + { + return $this->negated; + } + + /** + * @param Type[] $types + * @return self + */ + private function addMoreSpecificTypes(array $types): self + { + $moreSpecificTypeHolders = $this->moreSpecificTypes; + foreach ($types as $exprString => $type) { + $moreSpecificTypeHolders[$exprString] = VariableTypeHolder::createYes($type); + } + + return $this->scopeFactory->create( + $this->context, + $this->isDeclareStrictTypes(), + $this->getFunction(), + $this->getNamespace(), + $this->getVariableTypes(), + $moreSpecificTypeHolders, + $this->inClosureBindScopeClass, + $this->getAnonymousFunctionReturnType(), + $this->getInFunctionCall(), + $this->isNegated(), + $this->inFirstLevelStatement + ); + } + + public function canAccessProperty(PropertyReflection $propertyReflection): bool + { + return $this->canAccessClassMember($propertyReflection); + } + + public function canCallMethod(MethodReflection $methodReflection): bool + { + if ($this->canAccessClassMember($methodReflection)) { + return true; + } + + return $this->canAccessClassMember($methodReflection->getPrototype()); + } + + public function canAccessConstant(ConstantReflection $constantReflection): bool + { + return $this->canAccessClassMember($constantReflection); + } + + private function canAccessClassMember(ClassMemberReflection $classMemberReflection): bool + { + if ($classMemberReflection->isPublic()) { + return true; + } + + if ($this->inClosureBindScopeClass !== null && $this->broker->hasClass($this->inClosureBindScopeClass)) { + $currentClassReflection = $this->broker->getClass($this->inClosureBindScopeClass); + } elseif ($this->isInClass()) { + $currentClassReflection = $this->getClassReflection(); + } else { + return false; + } + + $classReflectionName = $classMemberReflection->getDeclaringClass()->getName(); + if ($classMemberReflection->isPrivate()) { + return $currentClassReflection->getName() === $classReflectionName; + } + + // protected + + if ( + $currentClassReflection->getName() === $classReflectionName + || $currentClassReflection->isSubclassOf($classReflectionName) + ) { + return true; + } + + return $classMemberReflection->getDeclaringClass()->isSubclassOf($currentClassReflection->getName()); + } + + /** + * @return string[] + */ + public function debug(): array + { + $descriptions = []; + foreach ($this->getVariableTypes() as $name => $variableTypeHolder) { + $key = sprintf('$%s (%s)', $name, $variableTypeHolder->getCertainty()->describe()); + $descriptions[$key] = $variableTypeHolder->getType()->describe(VerbosityLevel::value()); + } + foreach ($this->moreSpecificTypes as $exprString => $typeHolder) { + $key = sprintf( + '%s-specified (%s)', + $exprString, + $typeHolder->getCertainty()->describe() + ); + $descriptions[$key] = $typeHolder->getType()->describe(VerbosityLevel::value()); + } + + return $descriptions; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/ScopeContext.php b/vendor/phpstan/phpstan/src/Analyser/ScopeContext.php new file mode 100644 index 00000000..c2d35ebd --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/ScopeContext.php @@ -0,0 +1,78 @@ +file = $file; + $this->classReflection = $classReflection; + $this->traitReflection = $traitReflection; + } + + public static function create(string $file): self + { + return new self($file, null, null); + } + + public function beginFile(): self + { + return new self($this->file, null, null); + } + + public function enterClass(ClassReflection $classReflection): self + { + if ($this->classReflection !== null && !$classReflection->isAnonymous()) { + throw new \PHPStan\ShouldNotHappenException(); + } + if ($classReflection->isTrait()) { + throw new \PHPStan\ShouldNotHappenException(); + } + return new self($this->file, $classReflection, null); + } + + public function enterTrait(ClassReflection $traitReflection): self + { + if ($this->classReflection === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + if (!$traitReflection->isTrait()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return new self($this->file, $this->classReflection, $traitReflection); + } + + public function getFile(): string + { + return $this->file; + } + + public function getClassReflection(): ?ClassReflection + { + return $this->classReflection; + } + + public function getTraitReflection(): ?ClassReflection + { + return $this->traitReflection; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/ScopeFactory.php b/vendor/phpstan/phpstan/src/Analyser/ScopeFactory.php new file mode 100644 index 00000000..52826b0d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/ScopeFactory.php @@ -0,0 +1,99 @@ +scopeClass = $scopeClass; + $this->broker = $broker; + $this->printer = $printer; + $this->typeSpecifier = $typeSpecifier; + $this->dynamicConstantNames = $container->parameters['dynamicConstantNames']; + } + + /** + * @param \PHPStan\Analyser\ScopeContext $context + * @param bool $declareStrictTypes + * @param \PHPStan\Reflection\FunctionReflection|\PHPStan\Reflection\MethodReflection|null $function + * @param string|null $namespace + * @param \PHPStan\Analyser\VariableTypeHolder[] $variablesTypes + * @param \PHPStan\Analyser\VariableTypeHolder[] $moreSpecificTypes + * @param string|null $inClosureBindScopeClass + * @param \PHPStan\Type\Type|null $inAnonymousFunctionReturnType + * @param \PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|null $inFunctionCall + * @param bool $negated + * @param bool $inFirstLevelStatement + * @param string[] $currentlyAssignedExpressions + * + * @return Scope + */ + public function create( + ScopeContext $context, + bool $declareStrictTypes = false, + $function = null, + ?string $namespace = null, + array $variablesTypes = [], + array $moreSpecificTypes = [], + ?string $inClosureBindScopeClass = null, + ?Type $inAnonymousFunctionReturnType = null, + ?Expr $inFunctionCall = null, + bool $negated = false, + bool $inFirstLevelStatement = true, + array $currentlyAssignedExpressions = [] + ): Scope + { + $scopeClass = $this->scopeClass; + if (!is_a($scopeClass, Scope::class, true)) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return new $scopeClass( + $this, + $this->broker, + $this->printer, + $this->typeSpecifier, + $context, + $declareStrictTypes, + $function, + $namespace, + $variablesTypes, + $moreSpecificTypes, + $inClosureBindScopeClass, + $inAnonymousFunctionReturnType, + $inFunctionCall, + $negated, + $inFirstLevelStatement, + $currentlyAssignedExpressions, + $this->dynamicConstantNames + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/SpecifiedTypes.php b/vendor/phpstan/phpstan/src/Analyser/SpecifiedTypes.php new file mode 100644 index 00000000..b000cce5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/SpecifiedTypes.php @@ -0,0 +1,103 @@ +sureTypes = $sureTypes; + $this->sureNotTypes = $sureNotTypes; + } + + /** + * @return mixed[] + */ + public function getSureTypes(): array + { + return $this->sureTypes; + } + + /** + * @return mixed[] + */ + public function getSureNotTypes(): array + { + return $this->sureNotTypes; + } + + public function intersectWith(SpecifiedTypes $other): self + { + $sureTypeUnion = []; + $sureNotTypeUnion = []; + + foreach ($this->sureTypes as $exprString => [$exprNode, $type]) { + if (!isset($other->sureTypes[$exprString])) { + continue; + } + + $sureTypeUnion[$exprString] = [ + $exprNode, + TypeCombinator::union($type, $other->sureTypes[$exprString][1]), + ]; + } + + foreach ($this->sureNotTypes as $exprString => [$exprNode, $type]) { + if (!isset($other->sureNotTypes[$exprString])) { + continue; + } + + $sureNotTypeUnion[$exprString] = [ + $exprNode, + TypeCombinator::intersect($type, $other->sureNotTypes[$exprString][1]), + ]; + } + + return new self($sureTypeUnion, $sureNotTypeUnion); + } + + + public function unionWith(SpecifiedTypes $other): self + { + $sureTypeUnion = $this->sureTypes + $other->sureTypes; + $sureNotTypeUnion = $this->sureNotTypes + $other->sureNotTypes; + + foreach ($this->sureTypes as $exprString => [$exprNode, $type]) { + if (!isset($other->sureTypes[$exprString])) { + continue; + } + + $sureTypeUnion[$exprString] = [ + $exprNode, + TypeCombinator::intersect($type, $other->sureTypes[$exprString][1]), + ]; + } + + foreach ($this->sureNotTypes as $exprString => [$exprNode, $type]) { + if (!isset($other->sureNotTypes[$exprString])) { + continue; + } + + $sureNotTypeUnion[$exprString] = [ + $exprNode, + TypeCombinator::union($type, $other->sureNotTypes[$exprString][1]), + ]; + } + + return new self($sureTypeUnion, $sureNotTypeUnion); + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/StatementList.php b/vendor/phpstan/phpstan/src/Analyser/StatementList.php new file mode 100644 index 00000000..817f8481 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/StatementList.php @@ -0,0 +1,73 @@ +scope = $scope; + $this->statements = $statements; + $this->filterByTruthyValue = $filterByTruthyValue; + $this->processScope = $processScope; + } + + public static function fromList(Scope $scope, self $list): self + { + return new self( + $scope, + $list->statements, + $list->filterByTruthyValue, + $list->processScope + ); + } + + public function getScope(): Scope + { + $scope = $this->scope; + if ($this->processScope !== null) { + $callback = $this->processScope; + $scope = $callback($scope); + } + + return $scope; + } + + /** + * @return \PhpParser\Node[] + */ + public function getStatements(): array + { + return $this->statements; + } + + public function shouldFilterByTruthyValue(): bool + { + return $this->filterByTruthyValue; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/TypeSpecifier.php b/vendor/phpstan/phpstan/src/Analyser/TypeSpecifier.php new file mode 100644 index 00000000..e7ab8317 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/TypeSpecifier.php @@ -0,0 +1,562 @@ +printer = $printer; + $this->broker = $broker; + + foreach (array_merge($functionTypeSpecifyingExtensions, $methodTypeSpecifyingExtensions, $staticMethodTypeSpecifyingExtensions) as $extension) { + if (!($extension instanceof TypeSpecifierAwareExtension)) { + continue; + } + + $extension->setTypeSpecifier($this); + } + + $this->functionTypeSpecifyingExtensions = $functionTypeSpecifyingExtensions; + $this->methodTypeSpecifyingExtensions = $methodTypeSpecifyingExtensions; + $this->staticMethodTypeSpecifyingExtensions = $staticMethodTypeSpecifyingExtensions; + } + + public function specifyTypesInCondition( + Scope $scope, + Expr $expr, + TypeSpecifierContext $context, + bool $defaultHandleFunctions = false + ): SpecifiedTypes + { + if ($expr instanceof Instanceof_) { + if ($expr->class instanceof Name) { + $className = (string) $expr->class; + $lowercasedClassName = strtolower($className); + if ($lowercasedClassName === 'self' && $scope->isInClass()) { + $type = new ObjectType($scope->getClassReflection()->getName()); + } elseif ($lowercasedClassName === 'static' && $scope->isInClass()) { + $type = new StaticType($scope->getClassReflection()->getName()); + } elseif ($lowercasedClassName === 'parent') { + if ( + $scope->isInClass() + && $scope->getClassReflection()->getParentClass() !== false + ) { + $type = new ObjectType($scope->getClassReflection()->getParentClass()->getName()); + } else { + $type = new NonexistentParentClassType(); + } + } else { + $type = new ObjectType($className); + } + return $this->create($expr->expr, $type, $context); + } + + if ($context->true()) { + return $this->create($expr->expr, new ObjectWithoutClassType(), $context); + } + } elseif ($expr instanceof Node\Expr\BinaryOp\Identical) { + $expressions = $this->findTypeExpressionsFromBinaryOperation($scope, $expr); + if ($expressions !== null) { + /** @var Expr $exprNode */ + $exprNode = $expressions[0]; + /** @var \PHPStan\Type\ConstantScalarType $constantType */ + $constantType = $expressions[1]; + if ($constantType->getValue() === false) { + $types = $this->create($exprNode, $constantType, $context); + return $types->unionWith($this->specifyTypesInCondition( + $scope, + $exprNode, + $context->true() ? TypeSpecifierContext::createFalse() : TypeSpecifierContext::createFalse()->negate() + )); + } + + if ($constantType->getValue() === true) { + $types = $this->create($exprNode, $constantType, $context); + return $types->unionWith($this->specifyTypesInCondition( + $scope, + $exprNode, + $context->true() ? TypeSpecifierContext::createTrue() : TypeSpecifierContext::createTrue()->negate() + )); + } + + if ($constantType->getValue() === null) { + return $this->create($exprNode, $constantType, $context); + } + + if ( + !$context->null() + && $exprNode instanceof FuncCall + && count($exprNode->args) === 1 + && $exprNode->name instanceof Name + && strtolower((string) $exprNode->name) === 'count' + && $constantType instanceof ConstantIntegerType + ) { + if ($context->truthy() || $constantType->getValue() === 0) { + $newContext = $context; + if ($constantType->getValue() === 0) { + $newContext = $newContext->negate(); + } + $argType = $scope->getType($exprNode->args[0]->value); + if ((new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($argType)->yes()) { + return $this->create($exprNode->args[0]->value, new NonEmptyArrayType(), $newContext); + } + } + } + } + + if ($context->true()) { + $type = TypeCombinator::intersect($scope->getType($expr->right), $scope->getType($expr->left)); + $leftTypes = $this->create($expr->left, $type, $context); + $rightTypes = $this->create($expr->right, $type, $context); + return $leftTypes->unionWith($rightTypes); + + } elseif ($context->false()) { + $identicalType = $scope->getType($expr); + if ($identicalType instanceof ConstantBooleanType) { + $never = new NeverType(); + $contextForTypes = $identicalType->getValue() ? $context->negate() : $context; + $leftTypes = $this->create($expr->left, $never, $contextForTypes); + $rightTypes = $this->create($expr->right, $never, $contextForTypes); + return $leftTypes->unionWith($rightTypes); + } + + if ( + ( + $expr->left instanceof Node\Scalar + || $expr->left instanceof Expr\Array_ + ) + && !$expr->right instanceof Node\Scalar + ) { + return $this->create( + $expr->right, + $scope->getType($expr->left), + $context + ); + } + if ( + ( + $expr->right instanceof Node\Scalar + || $expr->right instanceof Expr\Array_ + ) + && !$expr->left instanceof Node\Scalar + ) { + return $this->create( + $expr->left, + $scope->getType($expr->right), + $context + ); + } + } + + } elseif ($expr instanceof Node\Expr\BinaryOp\NotIdentical) { + return $this->specifyTypesInCondition( + $scope, + new Node\Expr\BooleanNot(new Node\Expr\BinaryOp\Identical($expr->left, $expr->right)), + $context + ); + } elseif ($expr instanceof Node\Expr\BinaryOp\Equal) { + $expressions = $this->findTypeExpressionsFromBinaryOperation($scope, $expr); + if ($expressions !== null) { + /** @var Expr $exprNode */ + $exprNode = $expressions[0]; + /** @var \PHPStan\Type\ConstantScalarType $constantType */ + $constantType = $expressions[1]; + if ($constantType->getValue() === false || $constantType->getValue() === null) { + return $this->specifyTypesInCondition( + $scope, + $exprNode, + $context->true() ? TypeSpecifierContext::createFalsey() : TypeSpecifierContext::createFalsey()->negate() + ); + } + + if ($constantType->getValue() === true) { + return $this->specifyTypesInCondition( + $scope, + $exprNode, + $context->true() ? TypeSpecifierContext::createTruthy() : TypeSpecifierContext::createTruthy()->negate() + ); + } + } + } elseif ($expr instanceof Node\Expr\BinaryOp\NotEqual) { + return $this->specifyTypesInCondition( + $scope, + new Node\Expr\BooleanNot(new Node\Expr\BinaryOp\Equal($expr->left, $expr->right)), + $context + ); + } elseif ($expr instanceof FuncCall && $expr->name instanceof Name) { + if ($this->broker->hasFunction($expr->name, $scope)) { + $functionReflection = $this->broker->getFunction($expr->name, $scope); + foreach ($this->getFunctionTypeSpecifyingExtensions() as $extension) { + if (!$extension->isFunctionSupported($functionReflection, $expr, $context)) { + continue; + } + + return $extension->specifyTypes($functionReflection, $expr, $scope, $context); + } + } + + if ($defaultHandleFunctions) { + return $this->handleDefaultTruthyOrFalseyContext($context, $expr); + } + } elseif ($expr instanceof MethodCall && $expr->name instanceof Node\Identifier) { + $methodCalledOnType = $scope->getType($expr->var); + $referencedClasses = TypeUtils::getDirectClassNames($methodCalledOnType); + if ( + count($referencedClasses) === 1 + && $this->broker->hasClass($referencedClasses[0]) + ) { + $methodClassReflection = $this->broker->getClass($referencedClasses[0]); + if ($methodClassReflection->hasMethod($expr->name->name)) { + $methodReflection = $methodClassReflection->getMethod($expr->name->name, $scope); + foreach ($this->getMethodTypeSpecifyingExtensionsForClass($methodClassReflection->getName()) as $extension) { + if (!$extension->isMethodSupported($methodReflection, $expr, $context)) { + continue; + } + + return $extension->specifyTypes($methodReflection, $expr, $scope, $context); + } + } + } + + if ($defaultHandleFunctions) { + return $this->handleDefaultTruthyOrFalseyContext($context, $expr); + } + } elseif ($expr instanceof StaticCall && $expr->name instanceof Node\Identifier) { + if ($expr->class instanceof Name) { + $calleeType = new ObjectType($scope->resolveName($expr->class)); + } else { + $calleeType = $scope->getType($expr->class); + } + + if ($calleeType->hasMethod($expr->name->name)->yes()) { + $staticMethodReflection = $calleeType->getMethod($expr->name->name, $scope); + $referencedClasses = TypeUtils::getDirectClassNames($calleeType); + if ( + count($referencedClasses) === 1 + && $this->broker->hasClass($referencedClasses[0]) + ) { + $staticMethodClassReflection = $this->broker->getClass($referencedClasses[0]); + foreach ($this->getStaticMethodTypeSpecifyingExtensionsForClass($staticMethodClassReflection->getName()) as $extension) { + if (!$extension->isStaticMethodSupported($staticMethodReflection, $expr, $context)) { + continue; + } + + return $extension->specifyTypes($staticMethodReflection, $expr, $scope, $context); + } + } + } + + if ($defaultHandleFunctions) { + return $this->handleDefaultTruthyOrFalseyContext($context, $expr); + } + } elseif ($expr instanceof BooleanAnd || $expr instanceof LogicalAnd) { + $leftTypes = $this->specifyTypesInCondition($scope, $expr->left, $context); + $rightTypes = $this->specifyTypesInCondition($scope, $expr->right, $context); + return $context->true() ? $leftTypes->unionWith($rightTypes) : $leftTypes->intersectWith($rightTypes); + } elseif ($expr instanceof BooleanOr || $expr instanceof LogicalOr) { + $leftTypes = $this->specifyTypesInCondition($scope, $expr->left, $context); + $rightTypes = $this->specifyTypesInCondition($scope, $expr->right, $context); + return $context->true() ? $leftTypes->intersectWith($rightTypes) : $leftTypes->unionWith($rightTypes); + } elseif ($expr instanceof Node\Expr\BooleanNot && !$context->null()) { + return $this->specifyTypesInCondition($scope, $expr->expr, $context->negate()); + } elseif ($expr instanceof Node\Expr\Assign) { + if ($context->null()) { + return $this->specifyTypesInCondition($scope, $expr->expr, $context); + } + + return $this->specifyTypesInCondition($scope, $expr->var, $context); + } elseif ( + ( + $expr instanceof Expr\Isset_ + && count($expr->vars) > 0 + && $context->truthy() + ) + || ($expr instanceof Expr\Empty_ && $context->falsey()) + ) { + $vars = []; + if ($expr instanceof Expr\Isset_) { + $varsToIterate = $expr->vars; + } else { + $varsToIterate = [$expr->expr]; + } + foreach ($varsToIterate as $var) { + $vars[] = $var; + + while ( + $var instanceof ArrayDimFetch + || $var instanceof PropertyFetch + || ( + $var instanceof StaticPropertyFetch + && $var->class instanceof Expr + ) + ) { + if ($var instanceof StaticPropertyFetch) { + /** @var Expr $var */ + $var = $var->class; + } else { + $var = $var->var; + } + $vars[] = $var; + } + } + + $types = null; + foreach ($vars as $var) { + if ($expr instanceof Expr\Isset_) { + if ( + $var instanceof ArrayDimFetch + && $var->dim !== null + && !$scope->getType($var->var) instanceof MixedType + ) { + $type = $this->create( + $var->var, + new HasOffsetType($scope->getType($var->dim)), + $context + )->unionWith( + $this->create($var, new NullType(), TypeSpecifierContext::createFalse()) + ); + } else { + $type = $this->create($var, new NullType(), TypeSpecifierContext::createFalse()); + } + } else { + $type = $this->create( + $var, + new UnionType([ + new NullType(), + new ConstantBooleanType(false), + ]), + TypeSpecifierContext::createFalse() + ); + } + if ($types === null) { + $types = $type; + } else { + $types = $types->unionWith($type); + } + } + + /** @var SpecifiedTypes $types */ + $types = $types; + + if ( + $expr instanceof Expr\Empty_ + && (new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($scope->getType($expr->expr))->yes()) { + $types = $types->unionWith( + $this->create($expr->expr, new NonEmptyArrayType(), $context->negate()) + ); + } + + return $types; + } elseif ( + $expr instanceof Expr\Empty_ && $context->truthy() + && (new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($scope->getType($expr->expr))->yes() + ) { + return $this->create($expr->expr, new NonEmptyArrayType(), $context->negate()); + } elseif (!$context->null()) { + return $this->handleDefaultTruthyOrFalseyContext($context, $expr); + } + + return new SpecifiedTypes(); + } + + private function handleDefaultTruthyOrFalseyContext(TypeSpecifierContext $context, Expr $expr): SpecifiedTypes + { + if (!$context->truthy()) { + $type = new UnionType([new ObjectWithoutClassType(), new NonEmptyArrayType()]); + return $this->create($expr, $type, TypeSpecifierContext::createFalse()); + } elseif (!$context->falsey()) { + $type = new UnionType([ + new NullType(), + new ConstantBooleanType(false), + new ConstantIntegerType(0), + new ConstantFloatType(0.0), + new ConstantStringType(''), + new ConstantArrayType([], []), + ]); + return $this->create($expr, $type, TypeSpecifierContext::createFalse()); + } + + return new SpecifiedTypes(); + } + + /** + * @param \PHPStan\Analyser\Scope $scope + * @param \PhpParser\Node\Expr\BinaryOp $binaryOperation + * @return (Expr|\PHPStan\Type\ConstantScalarType)[]|null + */ + private function findTypeExpressionsFromBinaryOperation(Scope $scope, Node\Expr\BinaryOp $binaryOperation): ?array + { + $leftType = $scope->getType($binaryOperation->left); + $rightType = $scope->getType($binaryOperation->right); + if ( + $leftType instanceof \PHPStan\Type\ConstantScalarType + && !$binaryOperation->right instanceof ConstFetch + && !$binaryOperation->right instanceof Expr\ClassConstFetch + ) { + return [$binaryOperation->right, $leftType]; + } elseif ( + $rightType instanceof \PHPStan\Type\ConstantScalarType + && !$binaryOperation->left instanceof ConstFetch + && !$binaryOperation->left instanceof Expr\ClassConstFetch + ) { + return [$binaryOperation->left, $rightType]; + } + + return null; + } + + public function create(Expr $expr, Type $type, TypeSpecifierContext $context): SpecifiedTypes + { + if ($expr instanceof New_) { + return new SpecifiedTypes(); + } + + $sureTypes = []; + $sureNotTypes = []; + + $exprString = $this->printer->prettyPrintExpr($expr); + if ($context->false()) { + $sureNotTypes[$exprString] = [$expr, $type]; + } elseif ($context->true()) { + $sureTypes[$exprString] = [$expr, $type]; + } + + return new SpecifiedTypes($sureTypes, $sureNotTypes); + } + + /** + * @return \PHPStan\Type\FunctionTypeSpecifyingExtension[] + */ + public function getFunctionTypeSpecifyingExtensions(): array + { + return $this->functionTypeSpecifyingExtensions; + } + + /** + * @param string $className + * @return \PHPStan\Type\MethodTypeSpecifyingExtension[] + */ + public function getMethodTypeSpecifyingExtensionsForClass(string $className): array + { + if ($this->methodTypeSpecifyingExtensionsByClass === null) { + $byClass = []; + foreach ($this->methodTypeSpecifyingExtensions as $extension) { + $byClass[$extension->getClass()][] = $extension; + } + + $this->methodTypeSpecifyingExtensionsByClass = $byClass; + } + return $this->getTypeSpecifyingExtensionsForType($this->methodTypeSpecifyingExtensionsByClass, $className); + } + + /** + * @param string $className + * @return \PHPStan\Type\StaticMethodTypeSpecifyingExtension[] + */ + public function getStaticMethodTypeSpecifyingExtensionsForClass(string $className): array + { + if ($this->staticMethodTypeSpecifyingExtensionsByClass === null) { + $byClass = []; + foreach ($this->staticMethodTypeSpecifyingExtensions as $extension) { + $byClass[$extension->getClass()][] = $extension; + } + + $this->staticMethodTypeSpecifyingExtensionsByClass = $byClass; + } + return $this->getTypeSpecifyingExtensionsForType($this->staticMethodTypeSpecifyingExtensionsByClass, $className); + } + + /** + * @param \PHPStan\Type\MethodTypeSpecifyingExtension[][]|\PHPStan\Type\StaticMethodTypeSpecifyingExtension[][] $extensions + * @param string $className + * @return mixed[] + */ + private function getTypeSpecifyingExtensionsForType(array $extensions, string $className): array + { + $extensionsForClass = []; + $class = $this->broker->getClass($className); + foreach (array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()) as $extensionClassName) { + if (!isset($extensions[$extensionClassName])) { + continue; + } + + $extensionsForClass = array_merge($extensionsForClass, $extensions[$extensionClassName]); + } + + return $extensionsForClass; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/TypeSpecifierAwareExtension.php b/vendor/phpstan/phpstan/src/Analyser/TypeSpecifierAwareExtension.php new file mode 100644 index 00000000..88fc2e42 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/TypeSpecifierAwareExtension.php @@ -0,0 +1,10 @@ +value = $value; + } + + private static function create(?int $value): self + { + self::$registry[$value] = self::$registry[$value] ?? new self($value); + return self::$registry[$value]; + } + + public static function createTrue(): self + { + return self::create(self::CONTEXT_TRUE); + } + + public static function createTruthy(): self + { + return self::create(self::CONTEXT_TRUTHY); + } + + public static function createFalse(): self + { + return self::create(self::CONTEXT_FALSE); + } + + public static function createFalsey(): self + { + return self::create(self::CONTEXT_FALSEY); + } + + public static function createNull(): self + { + return self::create(null); + } + + public function negate(): self + { + if ($this->value === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + return self::create(~$this->value); + } + + public function true(): bool + { + return $this->value !== null && (bool) ($this->value & self::CONTEXT_TRUE); + } + + public function truthy(): bool + { + return $this->value !== null && (bool) ($this->value & self::CONTEXT_TRUTHY); + } + + public function false(): bool + { + return $this->value !== null && (bool) ($this->value & self::CONTEXT_FALSE); + } + + public function falsey(): bool + { + return $this->value !== null && (bool) ($this->value & self::CONTEXT_FALSEY); + } + + public function null(): bool + { + return $this->value === null; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/TypeSpecifierFactory.php b/vendor/phpstan/phpstan/src/Analyser/TypeSpecifierFactory.php new file mode 100644 index 00000000..2899e709 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/TypeSpecifierFactory.php @@ -0,0 +1,58 @@ +container = $container; + } + + public function create(): TypeSpecifier + { + $tagToService = function (array $tags) { + return array_map(function (string $serviceName) { + return $this->container->getService($serviceName); + }, array_keys($tags)); + }; + + $typeSpecifier = new TypeSpecifier( + $this->container->getByType(Standard::class), + $this->container->getByType(Broker::class), + $tagToService($this->container->findByTag(self::FUNCTION_TYPE_SPECIFYING_EXTENSION_TAG)), + $tagToService($this->container->findByTag(self::METHOD_TYPE_SPECIFYING_EXTENSION_TAG)), + $tagToService($this->container->findByTag(self::STATIC_METHOD_TYPE_SPECIFYING_EXTENSION_TAG)) + ); + + foreach (array_merge( + $tagToService($this->container->findByTag(BrokerFactory::PROPERTIES_CLASS_REFLECTION_EXTENSION_TAG)), + $tagToService($this->container->findByTag(BrokerFactory::METHODS_CLASS_REFLECTION_EXTENSION_TAG)), + $tagToService($this->container->findByTag(BrokerFactory::DYNAMIC_METHOD_RETURN_TYPE_EXTENSION_TAG)), + $tagToService($this->container->findByTag(BrokerFactory::DYNAMIC_STATIC_METHOD_RETURN_TYPE_EXTENSION_TAG)), + $tagToService($this->container->findByTag(BrokerFactory::DYNAMIC_FUNCTION_RETURN_TYPE_EXTENSION_TAG)) + ) as $extension) { + if (!($extension instanceof TypeSpecifierAwareExtension)) { + continue; + } + + $extension->setTypeSpecifier($typeSpecifier); + } + + return $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/UndefinedVariableException.php b/vendor/phpstan/phpstan/src/Analyser/UndefinedVariableException.php new file mode 100644 index 00000000..c9c8a51e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/UndefinedVariableException.php @@ -0,0 +1,31 @@ +scope = $scope; + $this->variableName = $variableName; + } + + public function getScope(): Scope + { + return $this->scope; + } + + public function getVariableName(): string + { + return $this->variableName; + } + +} diff --git a/vendor/phpstan/phpstan/src/Analyser/VariableTypeHolder.php b/vendor/phpstan/phpstan/src/Analyser/VariableTypeHolder.php new file mode 100644 index 00000000..3fe0869e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Analyser/VariableTypeHolder.php @@ -0,0 +1,55 @@ +no()) { + throw new \PHPStan\ShouldNotHappenException(); + } + $this->type = $type; + $this->certainty = $certainty; + } + + public static function createYes(Type $type): self + { + return new self($type, TrinaryLogic::createYes()); + } + + public static function createMaybe(Type $type): self + { + return new self($type, TrinaryLogic::createMaybe()); + } + + public function and(self $other): self + { + return new self( + TypeCombinator::union($this->getType(), $other->getType()), + $this->getCertainty()->and($other->getCertainty()) + ); + } + + public function getType(): Type + { + return $this->type; + } + + public function getCertainty(): TrinaryLogic + { + return $this->certainty; + } + +} diff --git a/vendor/phpstan/phpstan/src/Broker/AnonymousClassNameHelper.php b/vendor/phpstan/phpstan/src/Broker/AnonymousClassNameHelper.php new file mode 100644 index 00000000..f5dedc21 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Broker/AnonymousClassNameHelper.php @@ -0,0 +1,45 @@ +fileHelper = $fileHelper; + $this->relativePathHelper = $relativePathHelper; + } + + public function getAnonymousClassName( + \PhpParser\Node\Expr\New_ $node, + string $filename + ): string + { + if (!$node->class instanceof \PhpParser\Node\Stmt\Class_) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $filename = $this->relativePathHelper->getRelativePath( + $this->fileHelper->normalizePath($filename) + ); + + return sprintf( + 'AnonymousClass%s', + md5(sprintf('%s:%s', $filename, $node->class->getLine())) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Broker/Broker.php b/vendor/phpstan/phpstan/src/Broker/Broker.php new file mode 100644 index 00000000..b0e3f1ad --- /dev/null +++ b/vendor/phpstan/phpstan/src/Broker/Broker.php @@ -0,0 +1,592 @@ +propertiesClassReflectionExtensions = $propertiesClassReflectionExtensions; + $this->methodsClassReflectionExtensions = $methodsClassReflectionExtensions; + foreach (array_merge($propertiesClassReflectionExtensions, $methodsClassReflectionExtensions, $dynamicMethodReturnTypeExtensions, $dynamicStaticMethodReturnTypeExtensions, $dynamicFunctionReturnTypeExtensions) as $extension) { + if (!($extension instanceof BrokerAwareExtension)) { + continue; + } + + $extension->setBroker($this); + } + + $this->dynamicMethodReturnTypeExtensions = $dynamicMethodReturnTypeExtensions; + $this->dynamicStaticMethodReturnTypeExtensions = $dynamicStaticMethodReturnTypeExtensions; + + foreach ($dynamicFunctionReturnTypeExtensions as $functionReturnTypeExtension) { + $this->dynamicFunctionReturnTypeExtensions[] = $functionReturnTypeExtension; + } + + $this->functionReflectionFactory = $functionReflectionFactory; + $this->fileTypeMapper = $fileTypeMapper; + $this->signatureMapProvider = $signatureMapProvider; + $this->printer = $printer; + $this->anonymousClassNameHelper = $anonymousClassNameHelper; + $this->parser = $parser; + $this->relativePathHelper = $relativePathHelper; + $this->universalObjectCratesClasses = $universalObjectCratesClasses; + } + + public static function registerInstance(Broker $broker): void + { + self::$instance = $broker; + } + + public static function getInstance(): self + { + if (self::$instance === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + return self::$instance; + } + + /** + * @return string[] + */ + public function getUniversalObjectCratesClasses(): array + { + return $this->universalObjectCratesClasses; + } + + /** + * @param string $className + * @return \PHPStan\Type\DynamicMethodReturnTypeExtension[] + */ + public function getDynamicMethodReturnTypeExtensionsForClass(string $className): array + { + if ($this->dynamicMethodReturnTypeExtensionsByClass === null) { + $byClass = []; + foreach ($this->dynamicMethodReturnTypeExtensions as $extension) { + $byClass[$extension->getClass()][] = $extension; + } + + $this->dynamicMethodReturnTypeExtensionsByClass = $byClass; + } + return $this->getDynamicExtensionsForType($this->dynamicMethodReturnTypeExtensionsByClass, $className); + } + + /** + * @param string $className + * @return \PHPStan\Type\DynamicStaticMethodReturnTypeExtension[] + */ + public function getDynamicStaticMethodReturnTypeExtensionsForClass(string $className): array + { + if ($this->dynamicStaticMethodReturnTypeExtensionsByClass === null) { + $byClass = []; + foreach ($this->dynamicStaticMethodReturnTypeExtensions as $extension) { + $byClass[$extension->getClass()][] = $extension; + } + + $this->dynamicStaticMethodReturnTypeExtensionsByClass = $byClass; + } + return $this->getDynamicExtensionsForType($this->dynamicStaticMethodReturnTypeExtensionsByClass, $className); + } + + /** + * @return \PHPStan\Type\DynamicFunctionReturnTypeExtension[] + */ + public function getDynamicFunctionReturnTypeExtensions(): array + { + return $this->dynamicFunctionReturnTypeExtensions; + } + + /** + * @param \PHPStan\Type\DynamicMethodReturnTypeExtension[][]|\PHPStan\Type\DynamicStaticMethodReturnTypeExtension[][] $extensions + * @param string $className + * @return mixed[] + */ + private function getDynamicExtensionsForType(array $extensions, string $className): array + { + $extensionsForClass = []; + $class = $this->getClass($className); + foreach (array_merge([$className], $class->getParentClassesNames(), $class->getNativeReflection()->getInterfaceNames()) as $extensionClassName) { + if (!isset($extensions[$extensionClassName])) { + continue; + } + + $extensionsForClass = array_merge($extensionsForClass, $extensions[$extensionClassName]); + } + + return $extensionsForClass; + } + + public function getClass(string $className): \PHPStan\Reflection\ClassReflection + { + if (!$this->hasClass($className)) { + throw new \PHPStan\Broker\ClassNotFoundException($className); + } + + if (isset(self::$anonymousClasses[$className])) { + return self::$anonymousClasses[$className]; + } + + if (!isset($this->classReflections[$className])) { + $reflectionClass = new ReflectionClass($className); + $filename = null; + if ($reflectionClass->getFileName() !== false) { + $filename = $reflectionClass->getFileName(); + } + + $classReflection = $this->getClassFromReflection( + $reflectionClass, + $reflectionClass->getName(), + $reflectionClass->isAnonymous() ? $filename : null + ); + $this->classReflections[$className] = $classReflection; + if ($className !== $reflectionClass->getName()) { + // class alias optimization + $this->classReflections[$reflectionClass->getName()] = $classReflection; + } + } + + return $this->classReflections[$className]; + } + + public function getAnonymousClassReflection( + \PhpParser\Node\Expr\New_ $node, + Scope $scope + ): ClassReflection + { + if (!$node->class instanceof \PhpParser\Node\Stmt\Class_) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if (!$scope->isInTrait()) { + $scopeFile = $scope->getFile(); + } else { + $scopeFile = $scope->getTraitReflection()->getFileName(); + if ($scopeFile === false) { + $scopeFile = $scope->getFile(); + } + } + + $filename = $this->relativePathHelper->getRelativePath($scopeFile); + + $className = $this->anonymousClassNameHelper->getAnonymousClassName( + $node, + $filename + ); + + if (isset(self::$anonymousClasses[$className])) { + return self::$anonymousClasses[$className]; + } + + $classNode = $node->class; + $classNode->name = new \PhpParser\Node\Identifier($className); + eval($this->printer->prettyPrint([$classNode])); + unset($classNode); + + self::$anonymousClasses[$className] = $this->getClassFromReflection( + new \ReflectionClass('\\' . $className), + sprintf('class@anonymous/%s:%s', $filename, $node->getLine()), + $scopeFile + ); + $this->classReflections[$className] = self::$anonymousClasses[$className]; + + return self::$anonymousClasses[$className]; + } + + public function getClassFromReflection(\ReflectionClass $reflectionClass, string $displayName, ?string $anonymousFilename): ClassReflection + { + $className = $reflectionClass->getName(); + if (!isset($this->classReflections[$className])) { + $classReflection = new ClassReflection( + $this, + $this->fileTypeMapper, + $this->propertiesClassReflectionExtensions, + $this->methodsClassReflectionExtensions, + $displayName, + $reflectionClass, + $anonymousFilename + ); + $this->classReflections[$className] = $classReflection; + } + + return $this->classReflections[$className]; + } + + public function hasClass(string $className): bool + { + if (isset($this->hasClassCache[$className])) { + return $this->hasClassCache[$className]; + } + + spl_autoload_register($autoloader = function (string $autoloadedClassName) use ($className): void { + if ($autoloadedClassName !== $className && !$this->isExistsCheckCall()) { + throw new \PHPStan\Broker\ClassAutoloadingException($autoloadedClassName); + } + }); + + try { + return $this->hasClassCache[$className] = class_exists($className) || interface_exists($className) || trait_exists($className); + } catch (\PHPStan\Broker\ClassAutoloadingException $e) { + throw $e; + } catch (\Throwable $t) { + throw new \PHPStan\Broker\ClassAutoloadingException( + $className, + $t + ); + } finally { + spl_autoload_unregister($autoloader); + } + } + + public function getFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope): \PHPStan\Reflection\FunctionReflection + { + $functionName = $this->resolveFunctionName($nameNode, $scope); + if ($functionName === null) { + throw new \PHPStan\Broker\FunctionNotFoundException((string) $nameNode); + } + + $lowerCasedFunctionName = strtolower($functionName); + if (!isset($this->functionReflections[$lowerCasedFunctionName])) { + if (isset(self::$functionMap[$lowerCasedFunctionName])) { + return $this->functionReflections[$lowerCasedFunctionName] = self::$functionMap[$lowerCasedFunctionName]; + } + + if ($this->signatureMapProvider->hasFunctionSignature($lowerCasedFunctionName)) { + $variantName = $lowerCasedFunctionName; + $variants = []; + $i = 0; + while ($this->signatureMapProvider->hasFunctionSignature($variantName)) { + $functionSignature = $this->signatureMapProvider->getFunctionSignature($variantName, null); + $returnType = $functionSignature->getReturnType(); + if ($lowerCasedFunctionName === 'pow') { + $returnType = TypeUtils::toBenevolentUnion($returnType); + } + $variants[] = new FunctionVariant( + array_map(static function (ParameterSignature $parameterSignature) use ($lowerCasedFunctionName): NativeParameterReflection { + $type = $parameterSignature->getType(); + if ( + $parameterSignature->getName() === 'args' + && ( + $lowerCasedFunctionName === 'printf' + || $lowerCasedFunctionName === 'sprintf' + ) + ) { + $type = new UnionType([ + new StringAlwaysAcceptingObjectWithToStringType(), + new IntegerType(), + new FloatType(), + new NullType(), + new BooleanType(), + ]); + } + return new NativeParameterReflection( + $parameterSignature->getName(), + $parameterSignature->isOptional(), + $type, + $parameterSignature->passedByReference(), + $parameterSignature->isVariadic() + ); + }, $functionSignature->getParameters()), + $functionSignature->isVariadic(), + $returnType + ); + + $i++; + $variantName = sprintf($lowerCasedFunctionName . '\'' . $i); + } + $functionReflection = new NativeFunctionReflection( + $lowerCasedFunctionName, + $variants, + null + ); + self::$functionMap[$lowerCasedFunctionName] = $functionReflection; + $this->functionReflections[$lowerCasedFunctionName] = $functionReflection; + } else { + $this->functionReflections[$lowerCasedFunctionName] = $this->getCustomFunction($nameNode, $scope); + } + } + + return $this->functionReflections[$lowerCasedFunctionName]; + } + + public function hasFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope): bool + { + return $this->resolveFunctionName($nameNode, $scope) !== null; + } + + public function hasCustomFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope): bool + { + $functionName = $this->resolveFunctionName($nameNode, $scope); + if ($functionName === null) { + return false; + } + + $lowerCasedFunctionName = strtolower($functionName); + + return !$this->signatureMapProvider->hasFunctionSignature($lowerCasedFunctionName); + } + + public function getCustomFunction(\PhpParser\Node\Name $nameNode, ?Scope $scope): \PHPStan\Reflection\Php\PhpFunctionReflection + { + if (!$this->hasCustomFunction($nameNode, $scope)) { + throw new \PHPStan\Broker\FunctionNotFoundException((string) $nameNode); + } + + /** @var string $functionName */ + $functionName = $this->resolveFunctionName($nameNode, $scope); + if (!function_exists($functionName)) { + throw new \PHPStan\Broker\FunctionNotFoundException($functionName); + } + $lowerCasedFunctionName = strtolower($functionName); + if (isset($this->customFunctionReflections[$lowerCasedFunctionName])) { + return $this->customFunctionReflections[$lowerCasedFunctionName]; + } + + $reflectionFunction = new \ReflectionFunction($functionName); + $phpDocParameterTags = []; + $phpDocReturnTag = null; + $phpDocThrowsTag = null; + $isDeprecated = false; + $isInternal = false; + $isFinal = false; + if ($reflectionFunction->getFileName() !== false && $reflectionFunction->getDocComment() !== false) { + $fileName = $reflectionFunction->getFileName(); + $docComment = $reflectionFunction->getDocComment(); + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, null, null, $docComment); + $phpDocParameterTags = $resolvedPhpDoc->getParamTags(); + $phpDocReturnTag = $resolvedPhpDoc->getReturnTag(); + $phpDocThrowsTag = $resolvedPhpDoc->getThrowsTag(); + $isDeprecated = $resolvedPhpDoc->isDeprecated(); + $isInternal = $resolvedPhpDoc->isInternal(); + $isFinal = $resolvedPhpDoc->isFinal(); + } + + $functionReflection = $this->functionReflectionFactory->create( + $reflectionFunction, + array_map(static function (ParamTag $paramTag): Type { + return $paramTag->getType(); + }, $phpDocParameterTags), + $phpDocReturnTag !== null ? $phpDocReturnTag->getType() : null, + $phpDocThrowsTag !== null ? $phpDocThrowsTag->getType() : null, + $isDeprecated, + $isInternal, + $isFinal, + $reflectionFunction->getFileName() + ); + $this->customFunctionReflections[$lowerCasedFunctionName] = $functionReflection; + + return $functionReflection; + } + + public function resolveFunctionName(\PhpParser\Node\Name $nameNode, ?Scope $scope): ?string + { + return $this->resolveName($nameNode, function (string $name): bool { + $exists = function_exists($name); + if ($exists) { + return true; + } + + $lowercased = strtolower($name); + + return $this->signatureMapProvider->hasFunctionSignature($lowercased); + }, $scope); + } + + public function hasConstant(\PhpParser\Node\Name $nameNode, ?Scope $scope): bool + { + return $this->resolveConstantName($nameNode, $scope) !== null; + } + + public function resolveConstantName(\PhpParser\Node\Name $nameNode, ?Scope $scope): ?string + { + return $this->resolveName($nameNode, function (string $name) use ($scope): bool { + $isCompilerHaltOffset = $name === '__COMPILER_HALT_OFFSET__'; + if ($isCompilerHaltOffset && $scope !== null && $this->fileHasCompilerHaltStatementCalls($scope->getFile())) { + return true; + } + return defined($name); + }, $scope); + } + + private function fileHasCompilerHaltStatementCalls(string $pathToFile): bool + { + $nodes = $this->parser->parseFile($pathToFile); + foreach ($nodes as $node) { + if ($node instanceof Node\Stmt\HaltCompiler) { + return true; + } + } + + return false; + } + + /** + * @param Node\Name $nameNode + * @param \Closure(string $name): bool $existsCallback + * @param Scope|null $scope + * @return string|null + */ + private function resolveName( + \PhpParser\Node\Name $nameNode, + \Closure $existsCallback, + ?Scope $scope + ): ?string + { + $name = (string) $nameNode; + if ($scope !== null && $scope->getNamespace() !== null && !$nameNode->isFullyQualified()) { + $namespacedName = sprintf('%s\\%s', $scope->getNamespace(), $name); + if ($existsCallback($namespacedName)) { + return $namespacedName; + } + } + + if ($existsCallback($name)) { + return $name; + } + + return null; + } + + private function isExistsCheckCall(): bool + { + $debugBacktrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + $existsCallTypes = [ + 'class_exists' => true, + 'interface_exists' => true, + 'trait_exists' => true, + ]; + + foreach ($debugBacktrace as $traceStep) { + if ( + isset($traceStep['function']) + && isset($existsCallTypes[$traceStep['function']]) + // We must ignore the self::hasClass calls + && (!isset($traceStep['file']) || $traceStep['file'] !== __FILE__) + ) { + return true; + } + } + + return false; + } + +} diff --git a/vendor/phpstan/phpstan/src/Broker/BrokerFactory.php b/vendor/phpstan/phpstan/src/Broker/BrokerFactory.php new file mode 100644 index 00000000..c9f0d69e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Broker/BrokerFactory.php @@ -0,0 +1,65 @@ +container = $container; + } + + public function create(): Broker + { + $tagToService = function (array $tags) { + return array_map(function (string $serviceName) { + return $this->container->getService($serviceName); + }, array_keys($tags)); + }; + + $phpClassReflectionExtension = $this->container->getByType(PhpClassReflectionExtension::class); + $annotationsMethodsClassReflectionExtension = $this->container->getByType(AnnotationsMethodsClassReflectionExtension::class); + $annotationsPropertiesClassReflectionExtension = $this->container->getByType(AnnotationsPropertiesClassReflectionExtension::class); + $phpDefectClassReflectionExtension = $this->container->getByType(PhpDefectClassReflectionExtension::class); + + /** @var RelativePathHelper $relativePathHelper */ + $relativePathHelper = $this->container->getService('relativePathHelper'); + + return new Broker( + array_merge([$phpClassReflectionExtension, $phpDefectClassReflectionExtension], $tagToService($this->container->findByTag(self::PROPERTIES_CLASS_REFLECTION_EXTENSION_TAG)), [$annotationsPropertiesClassReflectionExtension]), + array_merge([$phpClassReflectionExtension], $tagToService($this->container->findByTag(self::METHODS_CLASS_REFLECTION_EXTENSION_TAG)), [$annotationsMethodsClassReflectionExtension]), + $tagToService($this->container->findByTag(self::DYNAMIC_METHOD_RETURN_TYPE_EXTENSION_TAG)), + $tagToService($this->container->findByTag(self::DYNAMIC_STATIC_METHOD_RETURN_TYPE_EXTENSION_TAG)), + $tagToService($this->container->findByTag(self::DYNAMIC_FUNCTION_RETURN_TYPE_EXTENSION_TAG)), + $this->container->getByType(FunctionReflectionFactory::class), + $this->container->getByType(FileTypeMapper::class), + $this->container->getByType(SignatureMapProvider::class), + $this->container->getByType(\PhpParser\PrettyPrinter\Standard::class), + $this->container->getByType(AnonymousClassNameHelper::class), + $this->container->getByType(Parser::class), + $relativePathHelper, + $this->container->parameters['universalObjectCratesClasses'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Broker/ClassAutoloadingException.php b/vendor/phpstan/phpstan/src/Broker/ClassAutoloadingException.php new file mode 100644 index 00000000..47b2f820 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Broker/ClassAutoloadingException.php @@ -0,0 +1,38 @@ +getMessage(), + $functionName + ), 0, $previous); + } else { + parent::__construct(sprintf( + 'Class %s not found and could not be autoloaded.', + $functionName + ), 0); + } + + $this->className = $functionName; + } + + public function getClassName(): string + { + return $this->className; + } + +} diff --git a/vendor/phpstan/phpstan/src/Broker/ClassNotFoundException.php b/vendor/phpstan/phpstan/src/Broker/ClassNotFoundException.php new file mode 100644 index 00000000..3e767a67 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Broker/ClassNotFoundException.php @@ -0,0 +1,22 @@ +className = $functionName; + } + + public function getClassName(): string + { + return $this->className; + } + +} diff --git a/vendor/phpstan/phpstan/src/Broker/FunctionNotFoundException.php b/vendor/phpstan/phpstan/src/Broker/FunctionNotFoundException.php new file mode 100644 index 00000000..bb7b4c26 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Broker/FunctionNotFoundException.php @@ -0,0 +1,22 @@ +functionName = $functionName; + } + + public function getFunctionName(): string + { + return $this->functionName; + } + +} diff --git a/vendor/phpstan/phpstan/src/Cache/Cache.php b/vendor/phpstan/phpstan/src/Cache/Cache.php new file mode 100644 index 00000000..09d01661 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Cache/Cache.php @@ -0,0 +1,35 @@ +storage = $storage; + } + + /** + * @param string $key + * @return mixed|null + */ + public function load(string $key) + { + return $this->storage->load($key); + } + + /** + * @param string $key + * @param mixed $data + * @return bool + */ + public function save(string $key, $data): bool + { + return $this->storage->save($key, $data); + } + +} diff --git a/vendor/phpstan/phpstan/src/Cache/CacheStorage.php b/vendor/phpstan/phpstan/src/Cache/CacheStorage.php new file mode 100644 index 00000000..db4b7226 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Cache/CacheStorage.php @@ -0,0 +1,21 @@ +directory = $directory; + + if (@mkdir($this->directory) && !is_dir($this->directory)) { + throw new \InvalidArgumentException(sprintf('Directory "%s" doesn\'t exist.', $this->directory)); + } + } + + /** + * @param string $key + * @return mixed|null + */ + public function load(string $key) + { + return (function (string $key) { + $filePath = $this->getFilePath($key); + return is_file($filePath) ? require $this->getFilePath($key) : null; + })($key); + } + + /** + * @param string $key + * @param mixed $data + * @return bool + */ + public function save(string $key, $data): bool + { + $writtenBytes = @file_put_contents( + $this->getFilePath($key), + sprintf("directory, preg_replace('~[^-\\w]~', '_', $key)); + } + +} diff --git a/vendor/phpstan/phpstan/src/Cache/MemoryCacheStorage.php b/vendor/phpstan/phpstan/src/Cache/MemoryCacheStorage.php new file mode 100644 index 00000000..8c725435 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Cache/MemoryCacheStorage.php @@ -0,0 +1,31 @@ +storage[$key] ?? null; + } + + /** + * @param string $key + * @param mixed $data + * @return bool + */ + public function save(string $key, $data): bool + { + $this->storage[$key] = $data; + return true; + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/AnalyseApplication.php b/vendor/phpstan/phpstan/src/Command/AnalyseApplication.php new file mode 100644 index 00000000..3fad4be4 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/AnalyseApplication.php @@ -0,0 +1,127 @@ +analyser = $analyser; + $this->memoryLimitFile = $memoryLimitFile; + $this->fileHelper = $fileHelper; + $this->currentWorkingDirectory = $currentWorkingDirectory; + } + + /** + * @param string[] $files + * @param bool $onlyFiles + * @param \Symfony\Component\Console\Style\OutputStyle $style + * @param \PHPStan\Command\ErrorFormatter\ErrorFormatter $errorFormatter + * @param bool $defaultLevelUsed + * @param bool $debug + * @return int Error code. + */ + public function analyse( + array $files, + bool $onlyFiles, + OutputStyle $style, + ErrorFormatter $errorFormatter, + bool $defaultLevelUsed, + bool $debug + ): int + { + $this->updateMemoryLimitFile(); + $errors = []; + + if (!$debug) { + $progressStarted = false; + $fileOrder = 0; + $preFileCallback = null; + $postFileCallback = function () use ($style, &$progressStarted, $files, &$fileOrder): void { + if (!$progressStarted) { + $style->progressStart(count($files)); + $progressStarted = true; + } + $style->progressAdvance(); + if ($fileOrder % 100 === 0) { + $this->updateMemoryLimitFile(); + } + $fileOrder++; + }; + } else { + $preFileCallback = static function (string $file) use ($style): void { + $style->writeln($file); + }; + $postFileCallback = null; + } + + $errors = array_merge($errors, $this->analyser->analyse( + $files, + $onlyFiles, + $preFileCallback, + $postFileCallback, + $debug + )); + + if (isset($progressStarted) && $progressStarted) { + $style->progressFinish(); + } + + $fileSpecificErrors = []; + $notFileSpecificErrors = []; + foreach ($errors as $error) { + if (is_string($error)) { + $notFileSpecificErrors[] = $error; + } else { + $fileSpecificErrors[] = $error; + } + } + + return $errorFormatter->formatErrors( + new AnalysisResult( + $fileSpecificErrors, + $notFileSpecificErrors, + $defaultLevelUsed, + $this->fileHelper->normalizePath($this->currentWorkingDirectory) + ), + $style + ); + } + + private function updateMemoryLimitFile(): void + { + $bytes = memory_get_peak_usage(true); + $megabytes = ceil($bytes / 1024 / 1024); + file_put_contents($this->memoryLimitFile, sprintf('%d MB', $megabytes)); + + if (!function_exists('pcntl_signal_dispatch')) { + return; + } + + pcntl_signal_dispatch(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php b/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php new file mode 100644 index 00000000..35dbdae6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/AnalyseCommand.php @@ -0,0 +1,131 @@ +setName(self::NAME) + ->setDescription('Analyses source code') + ->setDefinition([ + new InputArgument('paths', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Paths with source code to run analysis on'), + new InputOption('paths-file', null, InputOption::VALUE_REQUIRED, 'Path to a file with a list of paths to run analysis on'), + new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), + new InputOption(self::OPTION_LEVEL, 'l', InputOption::VALUE_REQUIRED, 'Level of rule options - the higher the stricter'), + new InputOption(ErrorsConsoleStyle::OPTION_NO_PROGRESS, null, InputOption::VALUE_NONE, 'Do not show progress bar, only results'), + new InputOption('debug', null, InputOption::VALUE_NONE, 'Show debug information - which file is analysed, do not catch internal errors'), + new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), + new InputOption('error-format', null, InputOption::VALUE_REQUIRED, 'Format in which to print the result of the analysis', 'table'), + new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for analysis'), + ]); + } + + /** + * @return string[] + */ + public function getAliases(): array + { + return ['analyze']; + } + + protected function initialize(InputInterface $input, OutputInterface $output): void + { + if ((bool) $input->getOption('debug')) { + $this->getApplication()->setCatchExceptions(false); + return; + } + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $paths = $input->getArgument('paths'); + $memoryLimit = $input->getOption('memory-limit'); + $autoloadFile = $input->getOption('autoload-file'); + $configuration = $input->getOption('configuration'); + $level = $input->getOption(self::OPTION_LEVEL); + $pathsFile = $input->getOption('paths-file'); + + if ( + !is_array($paths) + || (!is_string($memoryLimit) && $memoryLimit !== null) + || (!is_string($autoloadFile) && $autoloadFile !== null) + || (!is_string($configuration) && $configuration !== null) + || (!is_string($level) && $level !== null) + || (!is_string($pathsFile) && $pathsFile !== null) + ) { + throw new \PHPStan\ShouldNotHappenException(); + } + + try { + $inceptionResult = CommandHelper::begin( + $input, + $output, + $paths, + $pathsFile, + $memoryLimit, + $autoloadFile, + $configuration, + $level + ); + } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { + return 1; + } + + $errorOutput = $inceptionResult->getErrorOutput(); + $errorFormat = $input->getOption('error-format'); + + if (!is_string($errorFormat) && $errorFormat !== null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $container = $inceptionResult->getContainer(); + $errorFormatterServiceName = sprintf('errorFormatter.%s', $errorFormat); + if (!$container->hasService($errorFormatterServiceName)) { + $errorOutput->writeln(sprintf( + 'Error formatter "%s" not found. Available error formatters are: %s', + $errorFormat, + implode(', ', array_map(static function (string $name) { + return substr($name, strlen('errorFormatter.')); + }, $container->findByType(ErrorFormatter::class))) + )); + return 1; + } + + /** @var ErrorFormatter $errorFormatter */ + $errorFormatter = $container->getService($errorFormatterServiceName); + + /** @var AnalyseApplication $application */ + $application = $container->getByType(AnalyseApplication::class); + + $debug = $input->getOption('debug'); + if (!is_bool($debug)) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $inceptionResult->handleReturn( + $application->analyse( + $inceptionResult->getFiles(), + $inceptionResult->isOnlyFiles(), + $inceptionResult->getConsoleStyle(), + $errorFormatter, + $inceptionResult->isDefaultLevelUsed(), + $debug + ) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/AnalysisResult.php b/vendor/phpstan/phpstan/src/Command/AnalysisResult.php new file mode 100644 index 00000000..30ae1c52 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/AnalysisResult.php @@ -0,0 +1,96 @@ +getFile(), + $a->getLine(), + $a->getMessage(), + ] <=> [ + $b->getFile(), + $b->getLine(), + $b->getMessage(), + ]; + } + ); + + $this->fileSpecificErrors = $fileSpecificErrors; + $this->notFileSpecificErrors = $notFileSpecificErrors; + $this->defaultLevelUsed = $defaultLevelUsed; + $this->currentDirectory = $currentDirectory; + } + + public function hasErrors(): bool + { + return $this->getTotalErrorsCount() > 0; + } + + public function getTotalErrorsCount(): int + { + return count($this->fileSpecificErrors) + count($this->notFileSpecificErrors); + } + + /** + * @return \PHPStan\Analyser\Error[] sorted by their file name, line number and message + */ + public function getFileSpecificErrors(): array + { + return $this->fileSpecificErrors; + } + + /** + * @return string[] + */ + public function getNotFileSpecificErrors(): array + { + return $this->notFileSpecificErrors; + } + + public function isDefaultLevelUsed(): bool + { + return $this->defaultLevelUsed; + } + + /** + * @deprecated Use \PHPStan\File\RelativePathHelper instead + * @return string + */ + public function getCurrentDirectory(): string + { + return $this->currentDirectory; + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/CommandHelper.php b/vendor/phpstan/phpstan/src/Command/CommandHelper.php new file mode 100644 index 00000000..066e20fc --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/CommandHelper.php @@ -0,0 +1,253 @@ +getErrorOutput() : $output; + $consoleStyle = new ErrorsConsoleStyle($input, $output); + if ($memoryLimit !== null) { + if (\Nette\Utils\Strings::match($memoryLimit, '#^-?\d+[kMG]?$#i') === null) { + $errorOutput->writeln(sprintf('Invalid memory limit format "%s".', $memoryLimit)); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + if (ini_set('memory_limit', $memoryLimit) === false) { + $errorOutput->writeln(sprintf('Memory limit "%s" cannot be set.', $memoryLimit)); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + } + + $currentWorkingDirectory = getcwd(); + if ($currentWorkingDirectory === false) { + throw new \PHPStan\ShouldNotHappenException(); + } + $fileHelper = new FileHelper($currentWorkingDirectory); + if ($autoloadFile !== null && is_file($autoloadFile)) { + $autoloadFile = $fileHelper->absolutizePath($autoloadFile); + if (is_file($autoloadFile)) { + (static function (string $file): void { + require_once $file; + })($autoloadFile); + } + } + if ($projectConfigFile === null) { + foreach (['phpstan.neon', 'phpstan.neon.dist'] as $discoverableConfigName) { + $discoverableConfigFile = $currentWorkingDirectory . DIRECTORY_SEPARATOR . $discoverableConfigName; + if (is_file($discoverableConfigFile)) { + $projectConfigFile = $discoverableConfigFile; + $errorOutput->writeln(sprintf('Note: Using configuration file %s.', $projectConfigFile)); + break; + } + } + } + $defaultLevelUsed = false; + if ($projectConfigFile === null && $level === null) { + $level = self::DEFAULT_LEVEL; + $defaultLevelUsed = true; + } + + if (count($paths) === 0 && $pathsFile !== null) { + if (!file_exists($pathsFile)) { + $errorOutput->writeln(sprintf('Paths file %s does not exist.', $pathsFile)); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + + $pathsString = file_get_contents($pathsFile); + if ($pathsString === false) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $paths = array_values(array_filter(explode("\n", $pathsString), static function (string $path): bool { + return trim($path) !== ''; + })); + } + + $containerFactory = new ContainerFactory($currentWorkingDirectory); + if ($projectConfigFile !== null) { + if (!is_file($projectConfigFile)) { + $errorOutput->writeln(sprintf('Project config file at path %s does not exist.', $projectConfigFile)); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + + $loader = (new LoaderFactory())->createLoader(); + $projectConfig = $loader->load($projectConfigFile, null); + $defaultParameters = [ + 'rootDir' => $containerFactory->getRootDirectory(), + 'currentWorkingDirectory' => $containerFactory->getCurrentWorkingDirectory(), + ]; + + if (isset($projectConfig['parameters']['tmpDir'])) { + $tmpDir = Helpers::expand($projectConfig['parameters']['tmpDir'], $defaultParameters); + } + if ($level === null && isset($projectConfig['parameters']['level'])) { + $level = $projectConfig['parameters']['level']; + } + if (count($paths) === 0 && isset($projectConfig['parameters']['paths'])) { + $paths = Helpers::expand($projectConfig['parameters']['paths'], $defaultParameters); + } + } + + if (count($paths) === 0) { + $errorOutput->writeln('At least one path must be specified to analyse.'); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + + $additionalConfigFiles = []; + if ($level !== null) { + $levelConfigFile = sprintf('%s/config.level%s.neon', $containerFactory->getConfigDirectory(), $level); + if (!is_file($levelConfigFile)) { + $errorOutput->writeln(sprintf('Level config file %s was not found.', $levelConfigFile)); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + + $additionalConfigFiles[] = $levelConfigFile; + } + + if ($projectConfigFile !== null) { + $additionalConfigFiles[] = $projectConfigFile; + } + + if (!isset($tmpDir)) { + $tmpDir = sys_get_temp_dir() . '/phpstan'; + if (!@mkdir($tmpDir, 0777, true) && !is_dir($tmpDir)) { + $errorOutput->writeln(sprintf('Cannot create a temp directory %s', $tmpDir)); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + } + $paths = array_map(static function (string $path) use ($fileHelper): string { + return $fileHelper->absolutizePath($path); + }, $paths); + $container = $containerFactory->create($tmpDir, $additionalConfigFiles, $paths); + $memoryLimitFile = $container->parameters['memoryLimitFile']; + if (file_exists($memoryLimitFile)) { + $memoryLimitFileContents = file_get_contents($memoryLimitFile); + if ($memoryLimitFileContents === false) { + throw new \PHPStan\ShouldNotHappenException(); + } + $errorOutput->writeln('PHPStan crashed in the previous run probably because of excessive memory consumption.'); + $errorOutput->writeln(sprintf('It consumed around %s of memory.', $memoryLimitFileContents)); + $errorOutput->writeln(''); + $errorOutput->writeln(''); + $errorOutput->writeln('To avoid this issue, allow to use more memory with the --memory-limit option.'); + @unlink($memoryLimitFile); + } + + self::setUpSignalHandler($consoleStyle, $memoryLimitFile); + if (!isset($container->parameters['customRulesetUsed'])) { + $errorOutput->writeln(''); + $errorOutput->writeln('No rules detected'); + $errorOutput->writeln(''); + $errorOutput->writeln('You have the following choices:'); + $errorOutput->writeln(''); + $errorOutput->writeln('* while running the analyse option, use the --level option to adjust your rule level - the higher the stricter'); + $errorOutput->writeln(''); + $errorOutput->writeln(sprintf('* create your own custom ruleset by selecting which rules you want to check by copying the service definitions from the built-in config level files in %s.', $fileHelper->normalizePath(__DIR__ . '/../../conf'))); + $errorOutput->writeln(' * in this case, don\'t forget to define parameter customRulesetUsed in your config file.'); + $errorOutput->writeln(''); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } elseif ((bool) $container->parameters['customRulesetUsed']) { + $defaultLevelUsed = false; + } + + foreach ($container->parameters['autoload_files'] as $parameterAutoloadFile) { + (static function (string $file): void { + require_once $file; + })($fileHelper->normalizePath($parameterAutoloadFile)); + } + + if (count($container->parameters['autoload_directories']) > 0) { + $robotLoader = new \Nette\Loaders\RobotLoader(); + $robotLoader->acceptFiles = array_map(static function (string $extension): string { + return sprintf('*.%s', $extension); + }, $container->parameters['fileExtensions']); + + $robotLoader->setTempDirectory($tmpDir); + foreach ($container->parameters['autoload_directories'] as $directory) { + $robotLoader->addDirectory($fileHelper->normalizePath($directory)); + } + + foreach ($container->parameters['excludes_analyse'] as $directory) { + $robotLoader->excludeDirectory($fileHelper->normalizePath($directory)); + } + + $robotLoader->register(); + } + + $bootstrapFile = $container->parameters['bootstrap']; + if ($bootstrapFile !== null) { + $bootstrapFile = $fileHelper->normalizePath($bootstrapFile); + if (!is_file($bootstrapFile)) { + $errorOutput->writeln(sprintf('Bootstrap file %s does not exist.', $bootstrapFile)); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + try { + (static function (string $file): void { + require_once $file; + })($bootstrapFile); + } catch (\Throwable $e) { + $errorOutput->writeln($e->getMessage()); + throw new \PHPStan\Command\InceptionNotSuccessfulException(); + } + } + + /** @var FileFinder $fileFinder */ + $fileFinder = $container->getByType(FileFinder::class); + + try { + $fileFinderResult = $fileFinder->findFiles($paths); + } catch (\PHPStan\File\PathNotFoundException $e) { + $errorOutput->writeln(sprintf('%s', $e->getMessage())); + throw new \PHPStan\Command\InceptionNotSuccessfulException($e->getMessage(), 0, $e); + } + + return new InceptionResult( + $fileFinderResult->getFiles(), + $fileFinderResult->isOnlyFiles(), + $consoleStyle, + $errorOutput, + $container, + $defaultLevelUsed, + $memoryLimitFile + ); + } + + private static function setUpSignalHandler(OutputStyle $consoleStyle, string $memoryLimitFile): void + { + if (!function_exists('pcntl_signal')) { + return; + } + + pcntl_signal(SIGINT, static function () use ($consoleStyle, $memoryLimitFile): void { + if (file_exists($memoryLimitFile)) { + @unlink($memoryLimitFile); + } + $consoleStyle->newLine(); + exit(1); + }); + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/DumpDependenciesCommand.php b/vendor/phpstan/phpstan/src/Command/DumpDependenciesCommand.php new file mode 100644 index 00000000..d74b780c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/DumpDependenciesCommand.php @@ -0,0 +1,93 @@ +setName(self::NAME) + ->setDescription('Dumps files dependency tree') + ->setDefinition([ + new InputArgument('paths', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Paths with source code to run dump on'), + new InputOption('paths-file', null, InputOption::VALUE_REQUIRED, 'Path to a file with a list of paths to run analysis on'), + new InputOption('configuration', 'c', InputOption::VALUE_REQUIRED, 'Path to project configuration file'), + new InputOption(ErrorsConsoleStyle::OPTION_NO_PROGRESS, null, InputOption::VALUE_NONE, 'Do not show progress bar, only results'), + new InputOption('autoload-file', 'a', InputOption::VALUE_REQUIRED, 'Project\'s additional autoload file path'), + new InputOption('memory-limit', null, InputOption::VALUE_REQUIRED, 'Memory limit for the run'), + new InputOption('analysed-paths', null, InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED, 'Project-scope paths'), + ]); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + try { + /** @var string[] $paths */ + $paths = $input->getArgument('paths'); + + /** @var string|null $memoryLimit */ + $memoryLimit = $input->getOption('memory-limit'); + + /** @var string|null $autoloadFile */ + $autoloadFile = $input->getOption('autoload-file'); + + /** @var string|null $configurationFile */ + $configurationFile = $input->getOption('configuration'); + + /** @var string|null $pathsFile */ + $pathsFile = $input->getOption('paths-file'); + $inceptionResult = CommandHelper::begin( + $input, + $output, + $paths, + $pathsFile, + $memoryLimit, + $autoloadFile, + $configurationFile, + '0' // irrelevant but prevents an error when a config file is passed + ); + } catch (\PHPStan\Command\InceptionNotSuccessfulException $e) { + return 1; + } + + $consoleStyle = $inceptionResult->getConsoleStyle(); + + /** @var DependencyDumper $dependencyDumper */ + $dependencyDumper = $inceptionResult->getContainer()->getByType(DependencyDumper::class); + + /** @var FileHelper $fileHelper */ + $fileHelper = $inceptionResult->getContainer()->getByType(FileHelper::class); + + /** @var string[] $analysedPaths */ + $analysedPaths = $input->getOption('analysed-paths'); + $analysedPaths = array_map(static function (string $path) use ($fileHelper): string { + return $fileHelper->absolutizePath($path); + }, $analysedPaths); + $dependencies = $dependencyDumper->dumpDependencies( + $inceptionResult->getFiles(), + static function (int $count) use ($consoleStyle): void { + $consoleStyle->progressStart($count); + }, + static function () use ($consoleStyle): void { + $consoleStyle->progressAdvance(); + }, + count($analysedPaths) > 0 ? $analysedPaths : null + ); + $consoleStyle->progressFinish(); + $consoleStyle->writeln(Json::encode($dependencies, Json::PRETTY)); + + return $inceptionResult->handleReturn(0); + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/ErrorFormatter/CheckstyleErrorFormatter.php b/vendor/phpstan/phpstan/src/Command/ErrorFormatter/CheckstyleErrorFormatter.php new file mode 100644 index 00000000..ae256097 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/ErrorFormatter/CheckstyleErrorFormatter.php @@ -0,0 +1,102 @@ +relativePathHelper = $relativePathHelper; + } + + /** + * Formats the errors and outputs them to the console. + * + * @param \PHPStan\Command\AnalysisResult $analysisResult + * @param \Symfony\Component\Console\Style\OutputStyle $style + * @return int Error code. + */ + public function formatErrors( + AnalysisResult $analysisResult, + OutputStyle $style + ): int + { + $style->writeln(''); + $style->writeln(''); + + foreach ($this->groupByFile($analysisResult) as $relativeFilePath => $errors) { + $style->writeln(sprintf( + '', + $this->escape($relativeFilePath) + )); + + foreach ($errors as $error) { + $style->writeln(sprintf( + ' ', + $this->escape((string) $error->getLine()), + $this->escape((string) $error->getMessage()) + )); + } + $style->writeln(''); + } + + $notFileSpecificErrors = $analysisResult->getNotFileSpecificErrors(); + + if (count($notFileSpecificErrors) > 0) { + $style->writeln(''); + + foreach ($notFileSpecificErrors as $error) { + $style->writeln(sprintf(' ', $this->escape($error))); + } + + $style->writeln(''); + } + + $style->writeln(''); + + return $analysisResult->hasErrors() ? 1 : 0; + } + + /** + * Escapes values for using in XML + * + * @param string $string + * @return string + */ + protected function escape(string $string): string + { + return htmlspecialchars($string, ENT_XML1 | ENT_COMPAT, 'UTF-8'); + } + + /** + * Group errors by file + * + * @param AnalysisResult $analysisResult + * @return array Array that have as key the relative path of file + * and as value an array with occured errors. + */ + private function groupByFile(AnalysisResult $analysisResult): array + { + $files = []; + + /** @var \PHPStan\Analyser\Error $fileSpecificError */ + foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { + $relativeFilePath = $this->relativePathHelper->getRelativePath( + $fileSpecificError->getFile() + ); + + $files[$relativeFilePath][] = $fileSpecificError; + } + + return $files; + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/ErrorFormatter/ErrorFormatter.php b/vendor/phpstan/phpstan/src/Command/ErrorFormatter/ErrorFormatter.php new file mode 100644 index 00000000..6a675db1 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/ErrorFormatter/ErrorFormatter.php @@ -0,0 +1,22 @@ +pretty = $pretty; + } + + public function formatErrors(AnalysisResult $analysisResult, OutputStyle $style): int + { + $errorsArray = [ + 'totals' => [ + 'errors' => count($analysisResult->getNotFileSpecificErrors()), + 'file_errors' => count($analysisResult->getFileSpecificErrors()), + ], + 'files' => [], + 'errors' => [], + ]; + + foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { + $file = $fileSpecificError->getFile(); + if (!array_key_exists($file, $errorsArray['files'])) { + $errorsArray['files'][$file] = [ + 'errors' => 0, + 'messages' => [], + ]; + } + $errorsArray['files'][$file]['errors']++; + + $errorsArray['files'][$file]['messages'][] = [ + 'message' => $fileSpecificError->getMessage(), + 'line' => $fileSpecificError->getLine(), + 'ignorable' => $fileSpecificError->canBeIgnored(), + ]; + } + + foreach ($analysisResult->getNotFileSpecificErrors() as $notFileSpecificError) { + $errorsArray['errors'][] = $notFileSpecificError; + } + + $json = Json::encode($errorsArray, $this->pretty ? Json::PRETTY : 0); + + $style->write($json); + + return $analysisResult->hasErrors() ? 1 : 0; + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/ErrorFormatter/RawErrorFormatter.php b/vendor/phpstan/phpstan/src/Command/ErrorFormatter/RawErrorFormatter.php new file mode 100644 index 00000000..b5d69139 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/ErrorFormatter/RawErrorFormatter.php @@ -0,0 +1,38 @@ +hasErrors()) { + return 0; + } + + foreach ($analysisResult->getNotFileSpecificErrors() as $notFileSpecificError) { + $style->writeln(sprintf('?:?:%s', $notFileSpecificError)); + } + + foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { + $style->writeln( + sprintf( + '%s:%d:%s', + $fileSpecificError->getFile(), + $fileSpecificError->getLine() ?? '?', + $fileSpecificError->getMessage() + ) + ); + } + + return 1; + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/ErrorFormatter/TableErrorFormatter.php b/vendor/phpstan/phpstan/src/Command/ErrorFormatter/TableErrorFormatter.php new file mode 100644 index 00000000..9713818a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/ErrorFormatter/TableErrorFormatter.php @@ -0,0 +1,72 @@ +relativePathHelper = $relativePathHelper; + } + + public function formatErrors( + AnalysisResult $analysisResult, + OutputStyle $style + ): int + { + if (!$analysisResult->hasErrors()) { + $style->success('No errors'); + if ($analysisResult->isDefaultLevelUsed()) { + $style->note(sprintf( + 'PHPStan is performing only the most basic checks. You can pass a higher rule level through the --%s option (the default and current level is %d) to analyse code more thoroughly.', + AnalyseCommand::OPTION_LEVEL, + AnalyseCommand::DEFAULT_LEVEL + )); + } + return 0; + } + + /** @var array $fileErrors */ + $fileErrors = []; + foreach ($analysisResult->getFileSpecificErrors() as $fileSpecificError) { + if (!isset($fileErrors[$fileSpecificError->getFile()])) { + $fileErrors[$fileSpecificError->getFile()] = []; + } + + $fileErrors[$fileSpecificError->getFile()][] = $fileSpecificError; + } + + foreach ($fileErrors as $file => $errors) { + $rows = []; + foreach ($errors as $error) { + $rows[] = [ + (string) $error->getLine(), + $error->getMessage(), + ]; + } + + $relativeFilePath = $this->relativePathHelper->getRelativePath($file); + + $style->table(['Line', $relativeFilePath], $rows); + } + + if (count($analysisResult->getNotFileSpecificErrors()) > 0) { + $style->table(['Error'], array_map(static function (string $error): array { + return [$error]; + }, $analysisResult->getNotFileSpecificErrors())); + } + + $style->error(sprintf($analysisResult->getTotalErrorsCount() === 1 ? 'Found %d error' : 'Found %d errors', $analysisResult->getTotalErrorsCount())); + return 1; + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/ErrorsConsoleStyle.php b/vendor/phpstan/phpstan/src/Command/ErrorsConsoleStyle.php new file mode 100644 index 00000000..be387466 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/ErrorsConsoleStyle.php @@ -0,0 +1,116 @@ +showProgress = $input->hasOption(self::OPTION_NO_PROGRESS) && !(bool) $input->getOption(self::OPTION_NO_PROGRESS); + } + + /** + * @param string[] $headers + * @param string[][] $rows + */ + public function table(array $headers, array $rows): void + { + /** @var int $terminalWidth */ + $terminalWidth = (new \Symfony\Component\Console\Terminal())->getWidth(); + $maxHeaderWidth = strlen($headers[0]); + foreach ($rows as $row) { + $length = strlen($row[0]); + if ($maxHeaderWidth !== 0 && $length <= $maxHeaderWidth) { + continue; + } + + $maxHeaderWidth = $length; + } + + $wrap = static function ($rows) use ($terminalWidth, $maxHeaderWidth) { + return array_map(static function ($row) use ($terminalWidth, $maxHeaderWidth) { + return array_map(static function ($s) use ($terminalWidth, $maxHeaderWidth) { + if ($terminalWidth > $maxHeaderWidth + 5) { + return wordwrap( + $s, + $terminalWidth - $maxHeaderWidth - 5, + "\n", + true + ); + } + + return $s; + }, $row); + }, $rows); + }; + + parent::table($headers, $wrap($rows)); + } + + /** + * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint + * @param int $max + */ + public function createProgressBar($max = 0): ProgressBar + { + $this->progressBar = parent::createProgressBar($max); + $this->progressBar->setOverwrite(true); + return $this->progressBar; + } + + /** + * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint + * @param int $max + */ + public function progressStart($max = 0): void + { + if (!$this->showProgress) { + return; + } + parent::progressStart($max); + } + + /** + * @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint + * @param int $step + */ + public function progressAdvance($step = 1): void + { + if (!$this->showProgress) { + return; + } + if ($step > 0) { + $stepTime = (time() - $this->progressBar->getStartTime()) / $step; + if ($stepTime > 0 && $stepTime < 1) { + $this->progressBar->setRedrawFrequency((int) (1 / $stepTime)); + } else { + $this->progressBar->setRedrawFrequency(1); + } + } + + $this->progressBar->setProgress($this->progressBar->getProgress() + $step); + } + + public function progressFinish(): void + { + if (!$this->showProgress) { + return; + } + parent::progressFinish(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Command/InceptionNotSuccessfulException.php b/vendor/phpstan/phpstan/src/Command/InceptionNotSuccessfulException.php new file mode 100644 index 00000000..872b71cf --- /dev/null +++ b/vendor/phpstan/phpstan/src/Command/InceptionNotSuccessfulException.php @@ -0,0 +1,8 @@ +files = $files; + $this->onlyFiles = $onlyFiles; + $this->consoleStyle = $consoleStyle; + $this->errorOutput = $errorOutput; + $this->container = $container; + $this->isDefaultLevelUsed = $isDefaultLevelUsed; + $this->memoryLimitFile = $memoryLimitFile; + } + + /** + * @return string[] + */ + public function getFiles(): array + { + return $this->files; + } + + public function isOnlyFiles(): bool + { + return $this->onlyFiles; + } + + public function getConsoleStyle(): OutputStyle + { + return $this->consoleStyle; + } + + public function getErrorOutput(): OutputInterface + { + return $this->errorOutput; + } + + public function getContainer(): Container + { + return $this->container; + } + + public function isDefaultLevelUsed(): bool + { + return $this->isDefaultLevelUsed; + } + + public function handleReturn(int $exitCode): int + { + @unlink($this->memoryLimitFile); + return $exitCode; + } + +} diff --git a/vendor/phpstan/phpstan/src/Dependency/DependencyDumper.php b/vendor/phpstan/phpstan/src/Dependency/DependencyDumper.php new file mode 100644 index 00000000..710df8a9 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Dependency/DependencyDumper.php @@ -0,0 +1,143 @@ +dependencyResolver = $dependencyResolver; + $this->nodeScopeResolver = $nodeScopeResolver; + $this->fileHelper = $fileHelper; + $this->parser = $parser; + $this->scopeFactory = $scopeFactory; + $this->fileFinder = $fileFinder; + } + + /** + * @param string[] $files + * @param callable(int $count): void $countCallback + * @param callable(): void $progressCallback + * @param string[]|null $analysedPaths + * @return string[][] + */ + public function dumpDependencies( + array $files, + callable $countCallback, + callable $progressCallback, + ?array $analysedPaths + ): array + { + $analysedFiles = $files; + if ($analysedPaths !== null) { + $analysedFiles = $this->fileFinder->findFiles($analysedPaths)->getFiles(); + } + $this->nodeScopeResolver->setAnalysedFiles($analysedFiles); + $analysedFiles = array_fill_keys($analysedFiles, true); + + $dependencies = []; + $countCallback(count($files)); + foreach ($files as $file) { + try { + $parserNodes = $this->parser->parseFile($file); + } catch (\PHPStan\Parser\ParserErrorsException $e) { + continue; + } + + $fileDependencies = []; + try { + $this->nodeScopeResolver->processNodes( + $parserNodes, + $this->scopeFactory->create(ScopeContext::create($file)), + function (\PhpParser\Node $node, Scope $scope) use ($analysedFiles, &$fileDependencies): void { + $fileDependencies = array_merge( + $fileDependencies, + $this->resolveDependencies($node, $scope, $analysedFiles) + ); + } + ); + } catch (\PHPStan\AnalysedCodeException $e) { + // pass + } + + foreach (array_unique($fileDependencies) as $fileDependency) { + $relativeDependencyFile = $fileDependency; + $dependencies[$relativeDependencyFile][] = $file; + } + + $progressCallback(); + } + + return $dependencies; + } + + /** + * @param \PhpParser\Node $node + * @param Scope $scope + * @param array $analysedFiles + * @return string[] + */ + private function resolveDependencies( + \PhpParser\Node $node, + Scope $scope, + array $analysedFiles + ): array + { + $dependencies = []; + + foreach ($this->dependencyResolver->resolveDependencies($node, $scope) as $dependencyReflection) { + $dependencyFile = $dependencyReflection->getFileName(); + if ($dependencyFile === false) { + continue; + } + $dependencyFile = $this->fileHelper->normalizePath($dependencyFile); + + if ($scope->getFile() === $dependencyFile) { + continue; + } + + if (!isset($analysedFiles[$dependencyFile])) { + continue; + } + + $dependencies[$dependencyFile] = $dependencyFile; + } + + return array_values($dependencies); + } + +} diff --git a/vendor/phpstan/phpstan/src/Dependency/DependencyResolver.php b/vendor/phpstan/phpstan/src/Dependency/DependencyResolver.php new file mode 100644 index 00000000..8258dd87 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Dependency/DependencyResolver.php @@ -0,0 +1,256 @@ +broker = $broker; + } + + /** + * @param \PhpParser\Node $node + * @param Scope $scope + * @return ReflectionWithFilename[] + */ + public function resolveDependencies(\PhpParser\Node $node, Scope $scope): array + { + $dependenciesReflections = []; + + if ($node instanceof \PhpParser\Node\Stmt\Class_) { + if ($node->extends !== null) { + $this->addClassToDependencies($node->extends->toString(), $dependenciesReflections); + } + foreach ($node->implements as $className) { + $this->addClassToDependencies($className->toString(), $dependenciesReflections); + } + } elseif ($node instanceof \PhpParser\Node\Stmt\Interface_) { + if ($node->extends !== null) { + foreach ($node->extends as $className) { + $this->addClassToDependencies($className->toString(), $dependenciesReflections); + } + } + } elseif ($node instanceof ClassMethod) { + if (!$scope->isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + $nativeMethod = $scope->getClassReflection()->getNativeMethod($node->name->name); + if ($nativeMethod instanceof PhpMethodReflection) { + /** @var \PHPStan\Reflection\ParametersAcceptorWithPhpDocs $parametersAcceptor */ + $parametersAcceptor = ParametersAcceptorSelector::selectSingle($nativeMethod->getVariants()); + + $this->extractFromParametersAcceptor($parametersAcceptor, $dependenciesReflections); + } + } elseif ($node instanceof Function_) { + $functionName = $node->name->name; + if (isset($node->namespacedName)) { + $functionName = (string) $node->namespacedName; + } + $functionNameName = new Name($functionName); + if ($this->broker->hasCustomFunction($functionNameName, null)) { + $functionReflection = $this->broker->getCustomFunction($functionNameName, null); + + /** @var \PHPStan\Reflection\ParametersAcceptorWithPhpDocs $parametersAcceptor */ + $parametersAcceptor = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants()); + $this->extractFromParametersAcceptor($parametersAcceptor, $dependenciesReflections); + } + } elseif ($node instanceof Closure) { + /** @var ClosureType $closureType */ + $closureType = $scope->getType($node); + foreach ($closureType->getParameters() as $parameter) { + $referencedClasses = $parameter->getType()->getReferencedClasses(); + foreach ($referencedClasses as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } + + $returnTypeReferencedClasses = $closureType->getReturnType()->getReferencedClasses(); + foreach ($returnTypeReferencedClasses as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } elseif ($node instanceof \PhpParser\Node\Expr\FuncCall) { + $functionName = $node->name; + if ($functionName instanceof \PhpParser\Node\Name) { + try { + $dependenciesReflections[] = $this->getFunctionReflection($functionName, $scope); + } catch (\PHPStan\Broker\FunctionNotFoundException $e) { + // pass + } + } else { + $variants = $scope->getType($functionName)->getCallableParametersAcceptors($scope); + foreach ($variants as $variant) { + $referencedClasses = $variant->getReturnType()->getReferencedClasses(); + foreach ($referencedClasses as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } + } + + $returnType = $scope->getType($node); + foreach ($returnType->getReferencedClasses() as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } elseif ($node instanceof \PhpParser\Node\Expr\MethodCall || $node instanceof \PhpParser\Node\Expr\PropertyFetch) { + $classNames = $scope->getType($node->var)->getReferencedClasses(); + foreach ($classNames as $className) { + $this->addClassToDependencies($className, $dependenciesReflections); + } + + $returnType = $scope->getType($node); + foreach ($returnType->getReferencedClasses() as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } elseif ( + $node instanceof \PhpParser\Node\Expr\StaticCall + || $node instanceof \PhpParser\Node\Expr\ClassConstFetch + || $node instanceof \PhpParser\Node\Expr\StaticPropertyFetch + ) { + if ($node->class instanceof \PhpParser\Node\Name) { + $this->addClassToDependencies($scope->resolveName($node->class), $dependenciesReflections); + } else { + foreach ($scope->getType($node->class)->getReferencedClasses() as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } + + $returnType = $scope->getType($node); + foreach ($returnType->getReferencedClasses() as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } elseif ( + $node instanceof \PhpParser\Node\Expr\New_ + && $node->class instanceof \PhpParser\Node\Name + ) { + $this->addClassToDependencies($scope->resolveName($node->class), $dependenciesReflections); + } elseif ($node instanceof \PhpParser\Node\Stmt\TraitUse) { + foreach ($node->traits as $traitName) { + $this->addClassToDependencies($traitName->toString(), $dependenciesReflections); + } + } elseif ($node instanceof \PhpParser\Node\Expr\Instanceof_) { + if ($node->class instanceof Name) { + $this->addClassToDependencies($scope->resolveName($node->class), $dependenciesReflections); + } + } elseif ($node instanceof \PhpParser\Node\Stmt\Catch_) { + foreach ($node->types as $type) { + $this->addClassToDependencies($scope->resolveName($type), $dependenciesReflections); + } + } elseif ($node instanceof ArrayDimFetch && $node->dim !== null) { + $varType = $scope->getType($node->var); + $dimType = $scope->getType($node->dim); + + foreach ($varType->getOffsetValueType($dimType)->getReferencedClasses() as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } elseif ($node instanceof Foreach_) { + $exprType = $scope->getType($node->expr); + if ($node->keyVar !== null) { + foreach ($exprType->getIterableKeyType()->getReferencedClasses() as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } + + foreach ($exprType->getIterableValueType()->getReferencedClasses() as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } elseif ($node instanceof Array_) { + $arrayType = $scope->getType($node); + if (!$arrayType->isCallable()->no()) { + foreach ($arrayType->getCallableParametersAcceptors($scope) as $variant) { + $referencedClasses = $variant->getReturnType()->getReferencedClasses(); + foreach ($referencedClasses as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } + } + } + + return $dependenciesReflections; + } + + /** + * @param string $className + * @param ReflectionWithFilename[] $dependenciesReflections + */ + private function addClassToDependencies(string $className, array &$dependenciesReflections): void + { + try { + $classReflection = $this->broker->getClass($className); + } catch (\PHPStan\Broker\ClassNotFoundException $e) { + return; + } + + do { + $dependenciesReflections[] = $classReflection; + + foreach ($classReflection->getInterfaces() as $interface) { + $dependenciesReflections[] = $interface; + } + + foreach ($classReflection->getTraits() as $trait) { + $dependenciesReflections[] = $trait; + } + + $classReflection = $classReflection->getParentClass(); + } while ($classReflection !== false); + } + + private function getFunctionReflection(\PhpParser\Node\Name $nameNode, ?Scope $scope): ReflectionWithFilename + { + $reflection = $this->broker->getFunction($nameNode, $scope); + if (!$reflection instanceof ReflectionWithFilename) { + throw new \PHPStan\Broker\FunctionNotFoundException((string) $nameNode); + } + + return $reflection; + } + + /** + * @param ParametersAcceptorWithPhpDocs $parametersAcceptor + * @param ReflectionWithFilename[] $dependenciesReflections + */ + private function extractFromParametersAcceptor( + ParametersAcceptorWithPhpDocs $parametersAcceptor, + array &$dependenciesReflections + ): void + { + foreach ($parametersAcceptor->getParameters() as $parameter) { + $referencedClasses = array_merge( + $parameter->getNativeType()->getReferencedClasses(), + $parameter->getPhpDocType()->getReferencedClasses() + ); + + foreach ($referencedClasses as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } + + $returnTypeReferencedClasses = array_merge( + $parametersAcceptor->getNativeReturnType()->getReferencedClasses(), + $parametersAcceptor->getPhpDocReturnType()->getReferencedClasses() + ); + foreach ($returnTypeReferencedClasses as $referencedClass) { + $this->addClassToDependencies($referencedClass, $dependenciesReflections); + } + } + +} diff --git a/vendor/phpstan/phpstan/src/DependencyInjection/ConditionalTagsExtension.php b/vendor/phpstan/phpstan/src/DependencyInjection/ConditionalTagsExtension.php new file mode 100644 index 00000000..7cfb54e2 --- /dev/null +++ b/vendor/phpstan/phpstan/src/DependencyInjection/ConditionalTagsExtension.php @@ -0,0 +1,25 @@ +config; + $builder = $this->getContainerBuilder(); + + foreach ($config as $type => $tags) { + foreach ($builder->findByType($type) as $service) { + foreach ($tags as $tag => $parameter) { + if ((bool) $parameter) { + $service->addTag($tag); + continue; + } + } + } + } + } + +} diff --git a/vendor/phpstan/phpstan/src/DependencyInjection/Configurator.php b/vendor/phpstan/phpstan/src/DependencyInjection/Configurator.php new file mode 100644 index 00000000..b2bb0206 --- /dev/null +++ b/vendor/phpstan/phpstan/src/DependencyInjection/Configurator.php @@ -0,0 +1,25 @@ +loaderFactory = $loaderFactory; + + parent::__construct(); + } + + protected function createLoader(): Loader + { + return $this->loaderFactory->createLoader(); + } + +} diff --git a/vendor/phpstan/phpstan/src/DependencyInjection/ContainerFactory.php b/vendor/phpstan/phpstan/src/DependencyInjection/ContainerFactory.php new file mode 100644 index 00000000..c697543d --- /dev/null +++ b/vendor/phpstan/phpstan/src/DependencyInjection/ContainerFactory.php @@ -0,0 +1,89 @@ +currentWorkingDirectory = $currentWorkingDirectory; + $fileHelper = new FileHelper($currentWorkingDirectory); + $this->rootDirectory = $fileHelper->normalizePath(__DIR__ . '/../..'); + $this->configDirectory = $this->rootDirectory . '/conf'; + } + + /** + * @param string $tempDirectory + * @param string[] $additionalConfigFiles + * @param string[] $analysedPaths + * @return \Nette\DI\Container + */ + public function create( + string $tempDirectory, + array $additionalConfigFiles, + array $analysedPaths + ): \Nette\DI\Container + { + $configurator = new Configurator(new LoaderFactory()); + $configurator->defaultExtensions = [ + 'php' => PhpExtension::class, + 'extensions' => \Nette\DI\Extensions\ExtensionsExtension::class, + ]; + $configurator->setDebugMode(true); + $configurator->setTempDirectory($tempDirectory); + $configurator->addParameters([ + 'rootDir' => $this->rootDirectory, + 'currentWorkingDirectory' => $this->currentWorkingDirectory, + 'cliArgumentsVariablesRegistered' => ini_get('register_argc_argv') === '1', + 'tmpDir' => $tempDirectory, + ]); + $configurator->addConfig($this->configDirectory . '/config.neon'); + foreach ($additionalConfigFiles as $additionalConfigFile) { + $configurator->addConfig($additionalConfigFile); + } + + $configurator->addServices([ + 'relativePathHelper' => new RelativePathHelper($this->currentWorkingDirectory, DIRECTORY_SEPARATOR, $analysedPaths), + ]); + + $container = $configurator->createContainer(); + + /** @var Broker $broker */ + $broker = $container->getService('broker'); + Broker::registerInstance($broker); + $container->getService('typeSpecifier'); + + return $container; + } + + public function getCurrentWorkingDirectory(): string + { + return $this->currentWorkingDirectory; + } + + public function getRootDirectory(): string + { + return $this->rootDirectory; + } + + public function getConfigDirectory(): string + { + return $this->configDirectory; + } + +} diff --git a/vendor/phpstan/phpstan/src/DependencyInjection/LoaderFactory.php b/vendor/phpstan/phpstan/src/DependencyInjection/LoaderFactory.php new file mode 100644 index 00000000..44d1c9b8 --- /dev/null +++ b/vendor/phpstan/phpstan/src/DependencyInjection/LoaderFactory.php @@ -0,0 +1,19 @@ +addAdapter('dist', NeonAdapter::class); + + return $loader; + } + +} diff --git a/vendor/phpstan/phpstan/src/DependencyInjection/RulesExtension.php b/vendor/phpstan/phpstan/src/DependencyInjection/RulesExtension.php new file mode 100644 index 00000000..d63de5ee --- /dev/null +++ b/vendor/phpstan/phpstan/src/DependencyInjection/RulesExtension.php @@ -0,0 +1,23 @@ +config; + $builder = $this->getContainerBuilder(); + + foreach ($config as $key => $rule) { + $builder->addDefinition($this->prefix((string) $key)) + ->setFactory($rule) + ->setAutowired(false) + ->addTag(RegistryFactory::RULE_TAG); + } + } + +} diff --git a/vendor/phpstan/phpstan/src/File/FileExcluder.php b/vendor/phpstan/phpstan/src/File/FileExcluder.php new file mode 100644 index 00000000..e9f12b8b --- /dev/null +++ b/vendor/phpstan/phpstan/src/File/FileExcluder.php @@ -0,0 +1,62 @@ +analyseExcludes = array_map(function (string $exclude) use ($fileHelper): string { + $normalized = $fileHelper->normalizePath($exclude); + + if ($this->isFnmatchPattern($normalized)) { + return $normalized; + } + + return $fileHelper->absolutizePath($normalized); + }, $analyseExcludes); + } + + public function isExcludedFromAnalysing(string $file): bool + { + foreach ($this->analyseExcludes as $exclude) { + if (strpos($file, $exclude) === 0) { + return true; + } + + $isWindows = DIRECTORY_SEPARATOR === '\\'; + if ($isWindows) { + $fnmatchFlags = FNM_NOESCAPE | FNM_CASEFOLD; + } else { + $fnmatchFlags = 0; + } + + if ($this->isFnmatchPattern($exclude) && fnmatch($exclude, $file, $fnmatchFlags)) { + return true; + } + } + + return false; + } + + private function isFnmatchPattern(string $path): bool + { + return preg_match('~[*?[\]]~', $path) > 0; + } + +} diff --git a/vendor/phpstan/phpstan/src/File/FileFinder.php b/vendor/phpstan/phpstan/src/File/FileFinder.php new file mode 100644 index 00000000..85c9b3f8 --- /dev/null +++ b/vendor/phpstan/phpstan/src/File/FileFinder.php @@ -0,0 +1,65 @@ +fileExcluder = $fileExcluder; + $this->fileHelper = $fileHelper; + $this->fileExtensions = $fileExtensions; + } + + /** + * @param string[] $paths + * @return FileFinderResult + */ + public function findFiles(array $paths): FileFinderResult + { + $onlyFiles = true; + $files = []; + foreach ($paths as $path) { + if (!file_exists($path)) { + throw new \PHPStan\File\PathNotFoundException($path); + } elseif (is_file($path)) { + $files[] = $this->fileHelper->normalizePath($path); + } else { + $finder = new Finder(); + $finder->followLinks(); + foreach ($finder->files()->name('*.{' . implode(',', $this->fileExtensions) . '}')->in($path) as $fileInfo) { + $files[] = $this->fileHelper->normalizePath($fileInfo->getPathname()); + $onlyFiles = false; + } + } + } + + $files = array_values(array_filter($files, function (string $file): bool { + return !$this->fileExcluder->isExcludedFromAnalysing($file); + })); + + return new FileFinderResult($files, $onlyFiles); + } + +} diff --git a/vendor/phpstan/phpstan/src/File/FileFinderResult.php b/vendor/phpstan/phpstan/src/File/FileFinderResult.php new file mode 100644 index 00000000..37d8818f --- /dev/null +++ b/vendor/phpstan/phpstan/src/File/FileFinderResult.php @@ -0,0 +1,37 @@ +files = $files; + $this->onlyFiles = $onlyFiles; + } + + /** + * @return string[] + */ + public function getFiles(): array + { + return $this->files; + } + + public function isOnlyFiles(): bool + { + return $this->onlyFiles; + } + +} diff --git a/vendor/phpstan/phpstan/src/File/FileHelper.php b/vendor/phpstan/phpstan/src/File/FileHelper.php new file mode 100644 index 00000000..98863f72 --- /dev/null +++ b/vendor/phpstan/phpstan/src/File/FileHelper.php @@ -0,0 +1,74 @@ +workingDirectory = $this->normalizePath($workingDirectory); + } + + public function getWorkingDirectory(): string + { + return $this->workingDirectory; + } + + public function absolutizePath(string $path): string + { + if (DIRECTORY_SEPARATOR === '/') { + if (substr($path, 0, 1) === '/') { + return $path; + } + } else { + if (substr($path, 1, 1) === ':') { + return $path; + } + } + + return rtrim($this->getWorkingDirectory(), '/\\') . DIRECTORY_SEPARATOR . ltrim($path, '/\\'); + } + + public function normalizePath(string $originalPath): string + { + $matches = \Nette\Utils\Strings::match($originalPath, '~^([a-z]+)\\:\\/\\/(.+)~'); + if ($matches !== null) { + [, $scheme, $path] = $matches; + } else { + $scheme = null; + $path = $originalPath; + } + + $path = str_replace('\\', '/', $path); + $path = Strings::replace($path, '~/{2,}~', '/'); + + $pathRoot = strpos($path, '/') === 0 ? DIRECTORY_SEPARATOR : ''; + $pathParts = explode('/', trim($path, '/')); + + $normalizedPathParts = []; + foreach ($pathParts as $pathPart) { + if ($pathPart === '.') { + continue; + } + if ($pathPart === '..') { + /** @var string $removedPart */ + $removedPart = array_pop($normalizedPathParts); + if ($scheme === 'phar' && substr($removedPart, -5) === '.phar') { + $scheme = null; + } + + } else { + $normalizedPathParts[] = $pathPart; + } + } + + return ($scheme !== null ? $scheme . '://' : '') . $pathRoot . implode(DIRECTORY_SEPARATOR, $normalizedPathParts); + } + +} diff --git a/vendor/phpstan/phpstan/src/File/PathNotFoundException.php b/vendor/phpstan/phpstan/src/File/PathNotFoundException.php new file mode 100644 index 00000000..c03ae5f7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/File/PathNotFoundException.php @@ -0,0 +1,22 @@ +path = $path; + } + + public function getPath(): string + { + return $this->path; + } + +} diff --git a/vendor/phpstan/phpstan/src/File/RelativePathHelper.php b/vendor/phpstan/phpstan/src/File/RelativePathHelper.php new file mode 100644 index 00000000..477b17b5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/File/RelativePathHelper.php @@ -0,0 +1,105 @@ +directorySeparator = $directorySeparator; + $pathBeginning = null; + $pathToTrimArray = null; + $trimBeginning = static function (string $path): array { + if (substr($path, 0, 1) === '/') { + return [ + '/', + substr($path, 1), + ]; + } elseif (substr($path, 1, 1) === ':') { + return [ + substr($path, 0, 3), + substr($path, 3), + ]; + } + + return ['', $path]; + }; + + if ( + !in_array($currentWorkingDirectory, ['', '/'], true) + && !(strlen($currentWorkingDirectory) === 3 && substr($currentWorkingDirectory, 1, 1) === ':') + ) { + [$pathBeginning, $currentWorkingDirectory] = $trimBeginning($currentWorkingDirectory); + + /** @var string[] $pathToTrimArray */ + $pathToTrimArray = explode($directorySeparator, $currentWorkingDirectory); + } + foreach ($analysedPaths as $pathNumber => $path) { + [$tempPathBeginning, $path] = $trimBeginning($path); + + /** @var string[] $pathArray */ + $pathArray = explode($directorySeparator, $path); + $pathTempParts = []; + foreach ($pathArray as $i => $pathPart) { + if (\Nette\Utils\Strings::endsWith($pathPart, '.php')) { + continue; + } + if (!isset($pathToTrimArray[$i])) { + if ($pathNumber !== 0) { + $pathToTrimArray = $pathTempParts; + continue 2; + } + } elseif ($pathToTrimArray[$i] !== $pathPart) { + $pathToTrimArray = $pathTempParts; + continue 2; + } + + $pathTempParts[] = $pathPart; + } + + $pathBeginning = $tempPathBeginning; + $pathToTrimArray = $pathTempParts; + } + + if ($pathToTrimArray === null || count($pathToTrimArray) === 0) { + return; + } + + $pathToTrim = $pathBeginning . implode($directorySeparator, $pathToTrimArray); + $realPathToTrim = realpath($pathToTrim); + if ($realPathToTrim !== false) { + $pathToTrim = $realPathToTrim; + } + + $this->pathToTrim = $pathToTrim; + } + + public function getRelativePath(string $filename): string + { + if ( + $this->pathToTrim !== null + && strpos($filename, $this->pathToTrim) === 0 + ) { + return ltrim(substr($filename, strlen($this->pathToTrim)), $this->directorySeparator); + } + + return $filename; + } + +} diff --git a/vendor/phpstan/phpstan/src/Internal/ScopeIsInClassTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Internal/ScopeIsInClassTypeSpecifyingExtension.php new file mode 100644 index 00000000..6edb8676 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Internal/ScopeIsInClassTypeSpecifyingExtension.php @@ -0,0 +1,85 @@ +isInMethodName = $isInMethodName; + $this->removeNullMethodName = $removeNullMethodName; + $this->broker = $broker; + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + + public function getClass(): string + { + return ClassMemberAccessAnswerer::class; + } + + public function isMethodSupported( + MethodReflection $methodReflection, + MethodCall $node, + TypeSpecifierContext $context + ): bool + { + return $methodReflection->getName() === $this->isInMethodName + && !$context->null(); + } + + public function specifyTypes( + MethodReflection $methodReflection, + MethodCall $node, + Scope $scope, + TypeSpecifierContext $context + ): SpecifiedTypes + { + $scopeClass = $this->broker->getClass(Scope::class); + $methodVariants = $scopeClass + ->getMethod($this->removeNullMethodName, $scope) + ->getVariants(); + + return $this->typeSpecifier->create( + new MethodCall($node->var, $this->removeNullMethodName), + TypeCombinator::removeNull( + ParametersAcceptorSelector::selectSingle($methodVariants)->getReturnType() + ), + $context + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Internal/UnionTypeGetInternalDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Internal/UnionTypeGetInternalDynamicReturnTypeExtension.php new file mode 100644 index 00000000..fa06f30e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Internal/UnionTypeGetInternalDynamicReturnTypeExtension.php @@ -0,0 +1,40 @@ +getName() === 'getInternal'; + } + + public function getTypeFromMethodCall( + MethodReflection $methodReflection, + MethodCall $methodCall, + Scope $scope + ): Type + { + if (count($methodCall->args) < 2) { + return ParametersAcceptorSelector::selectSingle($methodReflection->getVariants())->getReturnType(); + } + + $getterClosureType = $scope->getType($methodCall->args[1]->value); + return ParametersAcceptorSelector::selectSingle($getterClosureType->getCallableParametersAcceptors($scope))->getReturnType(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Node/InClassMethodNode.php b/vendor/phpstan/phpstan/src/Node/InClassMethodNode.php new file mode 100644 index 00000000..654532ea --- /dev/null +++ b/vendor/phpstan/phpstan/src/Node/InClassMethodNode.php @@ -0,0 +1,32 @@ +getAttributes()); + $this->originalNode = $originalNode; + } + + public function getOriginalNode(): \PhpParser\Node\Stmt\ClassMethod + { + return $this->originalNode; + } + + public function getType(): string + { + return 'PHPStan_Stmt_InClassMethodNode'; + } + + public function getSubNodeNames(): array + { + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Node/VirtualNode.php b/vendor/phpstan/phpstan/src/Node/VirtualNode.php new file mode 100644 index 00000000..fcb07727 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Node/VirtualNode.php @@ -0,0 +1,10 @@ +originalParser = $originalParser; + $this->cachedNodesByFileCountMax = $cachedNodesByFileCountMax; + $this->cachedNodesByStringCountMax = $cachedNodesByStringCountMax; + } + + /** + * @param string $file path to a file to parse + * @return \PhpParser\Node[] + */ + public function parseFile(string $file): array + { + if ($this->cachedNodesByFileCountMax !== 0 && $this->cachedNodesByFileCount >= $this->cachedNodesByFileCountMax) { + $this->cachedNodesByFile = array_slice( + $this->cachedNodesByFile, + 1, + null, + true + ); + + --$this->cachedNodesByFileCount; + } + + if (!isset($this->cachedNodesByFile[$file])) { + $this->cachedNodesByFile[$file] = $this->originalParser->parseFile($file); + $this->cachedNodesByFileCount++; + } + + return $this->cachedNodesByFile[$file]; + } + + /** + * @param string $sourceCode + * @return \PhpParser\Node[] + */ + public function parseString(string $sourceCode): array + { + if ($this->cachedNodesByStringCountMax !== 0 && $this->cachedNodesByStringCount >= $this->cachedNodesByStringCountMax) { + $this->cachedNodesByString = array_slice( + $this->cachedNodesByString, + 1, + null, + true + ); + + --$this->cachedNodesByStringCount; + } + + if (!isset($this->cachedNodesByString[$sourceCode])) { + $this->cachedNodesByString[$sourceCode] = $this->originalParser->parseString($sourceCode); + $this->cachedNodesByStringCount++; + } + + return $this->cachedNodesByString[$sourceCode]; + } + + public function getCachedNodesByFileCount(): int + { + return $this->cachedNodesByFileCount; + } + + public function getCachedNodesByFileCountMax(): int + { + return $this->cachedNodesByFileCountMax; + } + + public function getCachedNodesByStringCount(): int + { + return $this->cachedNodesByStringCount; + } + + public function getCachedNodesByStingCountMax(): int + { + return $this->cachedNodesByStringCountMax; + } + + public function getCachedNodesByFile(): array + { + return $this->cachedNodesByFile; + } + + public function getCachedNodesByString(): array + { + return $this->cachedNodesByString; + } + +} diff --git a/vendor/phpstan/phpstan/src/Parser/DirectParser.php b/vendor/phpstan/phpstan/src/Parser/DirectParser.php new file mode 100644 index 00000000..a884d36b --- /dev/null +++ b/vendor/phpstan/phpstan/src/Parser/DirectParser.php @@ -0,0 +1,53 @@ +parser = $parser; + $this->traverser = $traverser; + } + + /** + * @param string $file path to a file to parse + * @return \PhpParser\Node[] + */ + public function parseFile(string $file): array + { + $contents = file_get_contents($file); + if ($contents === false) { + throw new \PHPStan\ShouldNotHappenException(); + } + return $this->parseString($contents); + } + + /** + * @param string $sourceCode + * @return \PhpParser\Node[] + */ + public function parseString(string $sourceCode): array + { + $errorHandler = new Collecting(); + $nodes = $this->parser->parse($sourceCode, $errorHandler); + if ($errorHandler->hasErrors()) { + throw new \PHPStan\Parser\ParserErrorsException($errorHandler->getErrors()); + } + if ($nodes === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + return $this->traverser->traverse($nodes); + } + +} diff --git a/vendor/phpstan/phpstan/src/Parser/FunctionCallStatementFinder.php b/vendor/phpstan/phpstan/src/Parser/FunctionCallStatementFinder.php new file mode 100644 index 00000000..7336d986 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Parser/FunctionCallStatementFinder.php @@ -0,0 +1,45 @@ +findFunctionCallInStatements($functionNames, $statement); + if ($result !== null) { + return $result; + } + } + + if (!($statement instanceof \PhpParser\Node)) { + continue; + } + + if ($statement instanceof FuncCall && $statement->name instanceof Name) { + if (in_array((string) $statement->name, $functionNames, true)) { + return $statement; + } + } + + $result = $this->findFunctionCallInStatements($functionNames, $statement); + if ($result !== null) { + return $result; + } + } + + return null; + } + +} diff --git a/vendor/phpstan/phpstan/src/Parser/Parser.php b/vendor/phpstan/phpstan/src/Parser/Parser.php new file mode 100644 index 00000000..cce06863 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Parser/Parser.php @@ -0,0 +1,20 @@ +getMessage(); + }, $errors))); + $this->errors = $errors; + } + + /** + * @return \PhpParser\Error[] + */ + public function getErrors(): array + { + return $this->errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/PhpDocBlock.php b/vendor/phpstan/phpstan/src/PhpDoc/PhpDocBlock.php new file mode 100644 index 00000000..7649b177 --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/PhpDocBlock.php @@ -0,0 +1,270 @@ +docComment = $docComment; + $this->file = $file; + $this->class = $class; + $this->trait = $trait; + $this->explicit = $explicit; + } + + public function getDocComment(): string + { + return $this->docComment; + } + + public function getFile(): string + { + return $this->file; + } + + public function getClass(): string + { + return $this->class; + } + + public function getTrait(): ?string + { + return $this->trait; + } + + public function isExplicit(): bool + { + return $this->explicit; + } + + public static function resolvePhpDocBlockForProperty( + Broker $broker, + ?string $docComment, + string $class, + ?string $trait, + string $propertyName, + string $file, + ?bool $explicit = null + ): ?self + { + return self::resolvePhpDocBlock( + $broker, + $docComment, + $class, + $trait, + $propertyName, + $file, + 'hasNativeProperty', + 'getNativeProperty', + __FUNCTION__, + $explicit + ); + } + + public static function resolvePhpDocBlockForMethod( + Broker $broker, + ?string $docComment, + string $class, + ?string $trait, + string $methodName, + string $file, + ?bool $explicit = null + ): ?self + { + return self::resolvePhpDocBlock( + $broker, + $docComment, + $class, + $trait, + $methodName, + $file, + 'hasNativeMethod', + 'getNativeMethod', + __FUNCTION__, + $explicit + ); + } + + private static function resolvePhpDocBlock( + Broker $broker, + ?string $docComment, + string $class, + ?string $trait, + string $name, + string $file, + string $hasMethodName, + string $getMethodName, + string $resolveMethodName, + ?bool $explicit + ): ?self + { + if ( + ( + $docComment === null + || preg_match('#\{@inheritdoc\}#i', $docComment) > 0 + ) + && $broker->hasClass($class) + ) { + $classReflection = $broker->getClass($class); + if ($classReflection->getParentClass() !== false) { + $parentClassReflection = $classReflection->getParentClass(); + $phpDocBlockFromClass = self::resolvePhpDocBlockRecursive( + $broker, + $parentClassReflection, + $trait, + $name, + $hasMethodName, + $getMethodName, + $resolveMethodName, + $explicit ?? $docComment !== null + ); + if ($phpDocBlockFromClass !== null) { + return $phpDocBlockFromClass; + } + } + + foreach ($classReflection->getInterfaces() as $interface) { + $phpDocBlockFromClass = self::resolvePhpDocBlockFromClass( + $broker, + $interface, + $name, + $hasMethodName, + $getMethodName, + $resolveMethodName, + $explicit ?? $docComment !== null + ); + if ($phpDocBlockFromClass !== null) { + return $phpDocBlockFromClass; + } + } + } + + return $docComment !== null + ? new self($docComment, $file, $class, $trait, $explicit ?? true) + : null; + } + + private static function resolvePhpDocBlockRecursive( + Broker $broker, + ClassReflection $classReflection, + ?string $trait, + string $name, + string $hasMethodName, + string $getMethodName, + string $resolveMethodName, + bool $explicit + ): ?self + { + $phpDocBlockFromClass = self::resolvePhpDocBlockFromClass( + $broker, + $classReflection, + $name, + $hasMethodName, + $getMethodName, + $resolveMethodName, + $explicit + ); + + if ($phpDocBlockFromClass !== null) { + return $phpDocBlockFromClass; + } + + $parentClassReflection = $classReflection->getParentClass(); + if ($parentClassReflection !== false) { + return self::resolvePhpDocBlockRecursive( + $broker, + $parentClassReflection, + $trait, + $name, + $hasMethodName, + $getMethodName, + $resolveMethodName, + $explicit + ); + } + + return null; + } + + private static function resolvePhpDocBlockFromClass( + Broker $broker, + ClassReflection $classReflection, + string $name, + string $hasMethodName, + string $getMethodName, + string $resolveMethodName, + bool $explicit + ): ?self + { + if ($classReflection->getFileName() !== false && $classReflection->$hasMethodName($name)) { + /** @var \PHPStan\Reflection\PropertyReflection|\PHPStan\Reflection\MethodReflection $parentReflection */ + $parentReflection = $classReflection->$getMethodName($name); + if ( + !$parentReflection instanceof PhpPropertyReflection + && !$parentReflection instanceof PhpMethodReflection + ) { + return null; + } + if ($parentReflection->isPrivate()) { + return null; + } + if ( + !$parentReflection->getDeclaringClass()->isTrait() + && $parentReflection->getDeclaringClass()->getName() !== $classReflection->getName() + ) { + return null; + } + + $traitReflection = $parentReflection instanceof PhpMethodReflection + ? $parentReflection->getDeclaringTrait() + : null; + + $trait = $traitReflection !== null + ? $traitReflection->getName() + : null; + + if ($parentReflection->getDocComment() !== false) { + return self::$resolveMethodName( + $broker, + $parentReflection->getDocComment(), + $classReflection->getName(), + $trait, + $name, + $classReflection->getFileName(), + $explicit + ); + } + } + + return null; + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/PhpDocNodeResolver.php b/vendor/phpstan/phpstan/src/PhpDoc/PhpDocNodeResolver.php new file mode 100644 index 00000000..d3929fb0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/PhpDocNodeResolver.php @@ -0,0 +1,236 @@ +typeNodeResolver = $typeNodeResolver; + } + + public function resolve(PhpDocNode $phpDocNode, NameScope $nameScope): ResolvedPhpDocBlock + { + return ResolvedPhpDocBlock::create( + $this->resolveVarTags($phpDocNode, $nameScope), + $this->resolveMethodTags($phpDocNode, $nameScope), + $this->resolvePropertyTags($phpDocNode, $nameScope), + $this->resolveParamTags($phpDocNode, $nameScope), + $this->resolveReturnTag($phpDocNode, $nameScope), + $this->resolveThrowsTags($phpDocNode, $nameScope), + $this->resolveIsDeprecated($phpDocNode), + $this->resolveIsInternal($phpDocNode), + $this->resolveIsFinal($phpDocNode) + ); + } + + /** + * @param PhpDocNode $phpDocNode + * @param NameScope $nameScope + * @return array + */ + private function resolveVarTags(PhpDocNode $phpDocNode, NameScope $nameScope): array + { + $resolved = []; + foreach ($phpDocNode->getVarTagValues() as $tagValue) { + if ($tagValue->variableName !== '') { + $variableName = substr($tagValue->variableName, 1); + $type = !isset($resolved[$variableName]) + ? $this->typeNodeResolver->resolve($tagValue->type, $nameScope) + : new MixedType(); + $resolved[$variableName] = new VarTag($type); + + } else { + $resolved[] = new VarTag($this->typeNodeResolver->resolve($tagValue->type, $nameScope)); + } + } + + return $resolved; + } + + /** + * @param PhpDocNode $phpDocNode + * @param NameScope $nameScope + * @return array + */ + private function resolvePropertyTags(PhpDocNode $phpDocNode, NameScope $nameScope): array + { + $resolved = []; + + foreach ($phpDocNode->getPropertyTagValues() as $tagValue) { + $propertyName = substr($tagValue->propertyName, 1); + $propertyType = !isset($resolved[$propertyName]) + ? $this->typeNodeResolver->resolve($tagValue->type, $nameScope) + : new MixedType(); + + $resolved[$propertyName] = new PropertyTag( + $propertyType, + true, + true + ); + } + + foreach ($phpDocNode->getPropertyReadTagValues() as $tagValue) { + $propertyName = substr($tagValue->propertyName, 1); + $propertyType = !isset($resolved[$propertyName]) + ? $this->typeNodeResolver->resolve($tagValue->type, $nameScope) + : new MixedType(); + + $resolved[$propertyName] = new PropertyTag( + $propertyType, + true, + false + ); + } + + foreach ($phpDocNode->getPropertyWriteTagValues() as $tagValue) { + $propertyName = substr($tagValue->propertyName, 1); + $propertyType = !isset($resolved[$propertyName]) + ? $this->typeNodeResolver->resolve($tagValue->type, $nameScope) + : new MixedType(); + + $resolved[$propertyName] = new PropertyTag( + $propertyType, + false, + true + ); + } + + return $resolved; + } + + /** + * @param PhpDocNode $phpDocNode + * @param NameScope $nameScope + * @return array + */ + private function resolveMethodTags(PhpDocNode $phpDocNode, NameScope $nameScope): array + { + $resolved = []; + + foreach ($phpDocNode->getMethodTagValues() as $tagValue) { + $parameters = []; + foreach ($tagValue->parameters as $parameterNode) { + $parameterName = substr($parameterNode->parameterName, 1); + $type = $parameterNode->type !== null ? $this->typeNodeResolver->resolve($parameterNode->type, $nameScope) : new MixedType(); + if ($parameterNode->defaultValue instanceof ConstExprNullNode) { + $type = TypeCombinator::addNull($type); + } + $parameters[$parameterName] = new MethodTagParameter( + $type, + $parameterNode->isReference + ? PassedByReference::createCreatesNewVariable() + : PassedByReference::createNo(), + $parameterNode->isVariadic || $parameterNode->defaultValue !== null, + $parameterNode->isVariadic + ); + } + + $resolved[$tagValue->methodName] = new MethodTag( + $tagValue->returnType !== null ? $this->typeNodeResolver->resolve($tagValue->returnType, $nameScope) : new MixedType(), + $tagValue->isStatic, + $parameters + ); + } + + return $resolved; + } + + /** + * @param PhpDocNode $phpDocNode + * @param NameScope $nameScope + * @return array + */ + private function resolveParamTags(PhpDocNode $phpDocNode, NameScope $nameScope): array + { + $resolved = []; + foreach ($phpDocNode->getParamTagValues() as $tagValue) { + $parameterName = substr($tagValue->parameterName, 1); + $parameterType = !isset($resolved[$parameterName]) + ? $this->typeNodeResolver->resolve($tagValue->type, $nameScope) + : new MixedType(); + + if ($tagValue->isVariadic) { + if (!$parameterType instanceof ArrayType) { + $parameterType = new ArrayType(new IntegerType(), $parameterType); + + } elseif ($parameterType->getKeyType() instanceof MixedType) { + $parameterType = new ArrayType(new IntegerType(), $parameterType->getItemType()); + } + } + + $resolved[$parameterName] = new ParamTag( + $parameterType, + $tagValue->isVariadic + ); + } + + return $resolved; + } + + private function resolveReturnTag(PhpDocNode $phpDocNode, NameScope $nameScope): ?\PHPStan\PhpDoc\Tag\ReturnTag + { + foreach ($phpDocNode->getReturnTagValues() as $tagValue) { + return new ReturnTag($this->typeNodeResolver->resolve($tagValue->type, $nameScope)); + } + + return null; + } + + private function resolveThrowsTags(PhpDocNode $phpDocNode, NameScope $nameScope): ?\PHPStan\PhpDoc\Tag\ThrowsTag + { + $types = array_map(function (ThrowsTagValueNode $throwsTagValue) use ($nameScope): Type { + return $this->typeNodeResolver->resolve($throwsTagValue->type, $nameScope); + }, $phpDocNode->getThrowsTagValues()); + + if (count($types) === 0) { + return null; + } + + return new ThrowsTag(TypeCombinator::union(...$types)); + } + + private function resolveIsDeprecated(PhpDocNode $phpDocNode): bool + { + $deprecatedTags = $phpDocNode->getTagsByName('@deprecated'); + + return count($deprecatedTags) > 0; + } + + private function resolveIsInternal(PhpDocNode $phpDocNode): bool + { + $internalTags = $phpDocNode->getTagsByName('@internal'); + + return count($internalTags) > 0; + } + + private function resolveIsFinal(PhpDocNode $phpDocNode): bool + { + $finalTags = $phpDocNode->getTagsByName('@final'); + + return count($finalTags) > 0; + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/PhpDocStringResolver.php b/vendor/phpstan/phpstan/src/PhpDoc/PhpDocStringResolver.php new file mode 100644 index 00000000..e688982e --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/PhpDocStringResolver.php @@ -0,0 +1,38 @@ +phpDocNodeResolver = $phpDocNodeResolver; + $this->phpDocLexer = $phpDocLexer; + $this->phpDocParser = $phpDocParser; + } + + public function resolve(string $phpDocString, NameScope $nameScope): ResolvedPhpDocBlock + { + $tokens = new TokenIterator($this->phpDocLexer->tokenize($phpDocString)); + $phpDocNode = $this->phpDocParser->parse($tokens); + $tokens->consumeTokenType(Lexer::TOKEN_END); + + return $this->phpDocNodeResolver->resolve($phpDocNode, $nameScope); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/ResolvedPhpDocBlock.php b/vendor/phpstan/phpstan/src/PhpDoc/ResolvedPhpDocBlock.php new file mode 100644 index 00000000..13c5ffd6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/ResolvedPhpDocBlock.php @@ -0,0 +1,191 @@ + */ + private $varTags; + + /** @var array */ + private $methodTags; + + /** @var array */ + private $propertyTags; + + /** @var array */ + private $paramTags; + + /** @var \PHPStan\PhpDoc\Tag\ReturnTag|null */ + private $returnTag; + + /** @var \PHPStan\PhpDoc\Tag\ThrowsTag|null */ + private $throwsTag; + + /** @var bool */ + private $isDeprecated; + + /** @var bool */ + private $isInternal; + + /** @var bool */ + private $isFinal; + + /** + * @param array $varTags + * @param array $methodTags + * @param array $propertyTags + * @param array $paramTags + * @param \PHPStan\PhpDoc\Tag\ReturnTag|null $returnTag + * @param \PHPStan\PhpDoc\Tag\ThrowsTag|null $throwsTags + * @param bool $isDeprecated + * @param bool $isInternal + * @param bool $isFinal + */ + private function __construct( + array $varTags, + array $methodTags, + array $propertyTags, + array $paramTags, + ?ReturnTag $returnTag, + ?ThrowsTag $throwsTags, + bool $isDeprecated, + bool $isInternal, + bool $isFinal + ) + { + $this->varTags = $varTags; + $this->methodTags = $methodTags; + $this->propertyTags = $propertyTags; + $this->paramTags = $paramTags; + $this->returnTag = $returnTag; + $this->throwsTag = $throwsTags; + $this->isDeprecated = $isDeprecated; + $this->isInternal = $isInternal; + $this->isFinal = $isFinal; + } + + /** + * @param array $varTags + * @param array $methodTags + * @param array $propertyTags + * @param array $paramTags + * @param \PHPStan\PhpDoc\Tag\ReturnTag|null $returnTag + * @param \PHPStan\PhpDoc\Tag\ThrowsTag|null $throwsTag + * @param bool $isDeprecated + * @param bool $isInternal + * @param bool $isFinal + * @return self + */ + public static function create( + array $varTags, + array $methodTags, + array $propertyTags, + array $paramTags, + ?ReturnTag $returnTag, + ?ThrowsTag $throwsTag, + bool $isDeprecated, + bool $isInternal, + bool $isFinal + ): self + { + return new self( + $varTags, + $methodTags, + $propertyTags, + $paramTags, + $returnTag, + $throwsTag, + $isDeprecated, + $isInternal, + $isFinal + ); + } + + public static function createEmpty(): self + { + return new self([], [], [], [], null, null, false, false, false); + } + + + /** + * @return array + */ + public function getVarTags(): array + { + return $this->varTags; + } + + /** + * @return array + */ + public function getMethodTags(): array + { + return $this->methodTags; + } + + /** + * @return array + */ + public function getPropertyTags(): array + { + return $this->propertyTags; + } + + /** + * @return array + */ + public function getParamTags(): array + { + return $this->paramTags; + } + + public function getReturnTag(): ?\PHPStan\PhpDoc\Tag\ReturnTag + { + return $this->returnTag; + } + + public function getThrowsTag(): ?\PHPStan\PhpDoc\Tag\ThrowsTag + { + return $this->throwsTag; + } + + public function isDeprecated(): bool + { + return $this->isDeprecated; + } + + public function isInternal(): bool + { + return $this->isInternal; + } + + public function isFinal(): bool + { + return $this->isFinal; + } + + /** + * @param mixed[] $properties + * @return self + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['varTags'], + $properties['methodTags'], + $properties['propertyTags'], + $properties['paramTags'], + $properties['returnTag'], + $properties['throwsTag'], + $properties['isDeprecated'], + $properties['isInternal'], + $properties['isFinal'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/Tag/MethodTag.php b/vendor/phpstan/phpstan/src/PhpDoc/Tag/MethodTag.php new file mode 100644 index 00000000..97e096df --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/Tag/MethodTag.php @@ -0,0 +1,66 @@ + */ + private $parameters; + + /** + * @param \PHPStan\Type\Type $returnType + * @param bool $isStatic + * @param array $parameters + */ + public function __construct( + Type $returnType, + bool $isStatic, + array $parameters + ) + { + $this->returnType = $returnType; + $this->isStatic = $isStatic; + $this->parameters = $parameters; + } + + public function getReturnType(): Type + { + return $this->returnType; + } + + public function isStatic(): bool + { + return $this->isStatic; + } + + /** + * @return array + */ + public function getParameters(): array + { + return $this->parameters; + } + + /** + * @param mixed[] $properties + * @return self + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['returnType'], + $properties['isStatic'], + $properties['parameters'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/Tag/MethodTagParameter.php b/vendor/phpstan/phpstan/src/PhpDoc/Tag/MethodTagParameter.php new file mode 100644 index 00000000..4f26c8ca --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/Tag/MethodTagParameter.php @@ -0,0 +1,70 @@ +type = $type; + $this->passedByReference = $passedByReference; + $this->isOptional = $isOptional; + $this->isVariadic = $isVariadic; + } + + public function getType(): Type + { + return $this->type; + } + + public function passedByReference(): PassedByReference + { + return $this->passedByReference; + } + + public function isOptional(): bool + { + return $this->isOptional; + } + + public function isVariadic(): bool + { + return $this->isVariadic; + } + + /** + * @param mixed[] $properties + * @return self + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['type'], + $properties['passedByReference'], + $properties['isOptional'], + $properties['isVariadic'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/Tag/ParamTag.php b/vendor/phpstan/phpstan/src/PhpDoc/Tag/ParamTag.php new file mode 100644 index 00000000..a4b9ce06 --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/Tag/ParamTag.php @@ -0,0 +1,44 @@ +type = $type; + $this->isVariadic = $isVariadic; + } + + public function getType(): Type + { + return $this->type; + } + + public function isVariadic(): bool + { + return $this->isVariadic; + } + + /** + * @param mixed[] $properties + * @return self + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['type'], + $properties['isVariadic'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/Tag/PropertyTag.php b/vendor/phpstan/phpstan/src/PhpDoc/Tag/PropertyTag.php new file mode 100644 index 00000000..0bbd76e6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/Tag/PropertyTag.php @@ -0,0 +1,58 @@ +type = $type; + $this->readable = $readable; + $this->writable = $writable; + } + + public function getType(): Type + { + return $this->type; + } + + public function isReadable(): bool + { + return $this->readable; + } + + public function isWritable(): bool + { + return $this->writable; + } + + /** + * @param mixed[] $properties + * @return PropertyTag + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['type'], + $properties['readable'], + $properties['writable'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/Tag/ReturnTag.php b/vendor/phpstan/phpstan/src/PhpDoc/Tag/ReturnTag.php new file mode 100644 index 00000000..99a1eea7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/Tag/ReturnTag.php @@ -0,0 +1,34 @@ +type = $type; + } + + public function getType(): Type + { + return $this->type; + } + + /** + * @param mixed[] $properties + * @return ReturnTag + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['type'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/Tag/ThrowsTag.php b/vendor/phpstan/phpstan/src/PhpDoc/Tag/ThrowsTag.php new file mode 100644 index 00000000..0ce1dbbb --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/Tag/ThrowsTag.php @@ -0,0 +1,34 @@ +type = $type; + } + + public function getType(): Type + { + return $this->type; + } + + /** + * @param mixed[] $properties + * @return ThrowsTag + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['type'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/Tag/VarTag.php b/vendor/phpstan/phpstan/src/PhpDoc/Tag/VarTag.php new file mode 100644 index 00000000..4be77f07 --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/Tag/VarTag.php @@ -0,0 +1,34 @@ +type = $type; + } + + public function getType(): Type + { + return $this->type; + } + + /** + * @param mixed[] $properties + * @return self + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['type'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/TypeNodeResolver.php b/vendor/phpstan/phpstan/src/PhpDoc/TypeNodeResolver.php new file mode 100644 index 00000000..da66754f --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/TypeNodeResolver.php @@ -0,0 +1,367 @@ +setTypeNodeResolver($this); + } + + $this->extensions = $extensions; + } + + public function getCacheKey(): string + { + $key = 'v50'; + foreach ($this->extensions as $extension) { + $key .= sprintf('-%s', $extension->getCacheKey()); + } + + return $key; + } + + public function resolve(TypeNode $typeNode, NameScope $nameScope): Type + { + foreach ($this->extensions as $extension) { + $type = $extension->resolve($typeNode, $nameScope); + if ($type !== null) { + return $type; + } + } + + if ($typeNode instanceof IdentifierTypeNode) { + return $this->resolveIdentifierTypeNode($typeNode, $nameScope); + + } elseif ($typeNode instanceof ThisTypeNode) { + return $this->resolveThisTypeNode($typeNode, $nameScope); + + } elseif ($typeNode instanceof NullableTypeNode) { + return $this->resolveNullableTypeNode($typeNode, $nameScope); + + } elseif ($typeNode instanceof UnionTypeNode) { + return $this->resolveUnionTypeNode($typeNode, $nameScope); + + } elseif ($typeNode instanceof IntersectionTypeNode) { + return $this->resolveIntersectionTypeNode($typeNode, $nameScope); + + } elseif ($typeNode instanceof ArrayTypeNode) { + return $this->resolveArrayTypeNode($typeNode, $nameScope); + + } elseif ($typeNode instanceof GenericTypeNode) { + return $this->resolveGenericTypeNode($typeNode, $nameScope); + + } elseif ($typeNode instanceof CallableTypeNode) { + return $this->resolveCallableTypeNode($typeNode, $nameScope); + } + + return new ErrorType(); + } + + private function resolveIdentifierTypeNode(IdentifierTypeNode $typeNode, NameScope $nameScope): Type + { + switch (strtolower($typeNode->name)) { + case 'int': + case 'integer': + return new IntegerType(); + + case 'string': + return new StringType(); + + case 'bool': + case 'boolean': + return new BooleanType(); + + case 'true': + return new ConstantBooleanType(true); + + case 'false': + return new ConstantBooleanType(false); + + case 'null': + return new NullType(); + + case 'float': + case 'double': + return new FloatType(); + + case 'array': + return new ArrayType(new MixedType(true), new MixedType(true)); + + case 'scalar': + return new UnionType([ + new IntegerType(), + new FloatType(), + new StringType(), + new BooleanType(), + ]); + + case 'number': + return new UnionType([ + new IntegerType(), + new FloatType(), + ]); + + case 'iterable': + return new IterableType(new MixedType(true), new MixedType(true)); + + case 'callable': + return new CallableType(); + + case 'resource': + return new ResourceType(); + + case 'mixed': + return new MixedType(true); + + case 'void': + return new VoidType(); + + case 'object': + return new ObjectWithoutClassType(); + + case 'never': + return new NeverType(); + } + + if ($nameScope->getClassName() !== null) { + switch (strtolower($typeNode->name)) { + case 'self': + return new ObjectType($nameScope->getClassName()); + + case 'static': + return new StaticType($nameScope->getClassName()); + + case 'parent': + $broker = Broker::getInstance(); + if ($broker->hasClass($nameScope->getClassName())) { + $classReflection = $broker->getClass($nameScope->getClassName()); + if ($classReflection->getParentClass() !== false) { + return new ObjectType($classReflection->getParentClass()->getName()); + } + } + + return new NonexistentParentClassType(); + } + } + + return new ObjectType($nameScope->resolveStringName($typeNode->name)); + } + + private function resolveThisTypeNode(ThisTypeNode $typeNode, NameScope $nameScope): Type + { + if ($nameScope->getClassName() !== null) { + return new ThisType($nameScope->getClassName()); + } + + return new ErrorType(); + } + + private function resolveNullableTypeNode(NullableTypeNode $typeNode, NameScope $nameScope): Type + { + return TypeCombinator::addNull($this->resolve($typeNode->type, $nameScope)); + } + + private function resolveUnionTypeNode(UnionTypeNode $typeNode, NameScope $nameScope): Type + { + $iterableTypeNodes = []; + $otherTypeNodes = []; + + foreach ($typeNode->types as $innerTypeNode) { + if ($innerTypeNode instanceof ArrayTypeNode) { + $iterableTypeNodes[] = $innerTypeNode->type; + } else { + $otherTypeNodes[] = $innerTypeNode; + } + } + + $otherTypeTypes = $this->resolveMultiple($otherTypeNodes, $nameScope); + if (count($iterableTypeNodes) > 0) { + $arrayTypeTypes = $this->resolveMultiple($iterableTypeNodes, $nameScope); + $arrayTypeType = TypeCombinator::union(...$arrayTypeTypes); + $addArray = true; + + foreach ($otherTypeTypes as &$type) { + if (!$type->isIterable()->yes() || !$type->getIterableValueType()->isSuperTypeOf($arrayTypeType)->yes()) { + continue; + } + + if ($type instanceof ObjectType) { + $type = new IntersectionType([$type, new IterableType(new MixedType(), $arrayTypeType)]); + } elseif ($type instanceof ArrayType) { + $type = new ArrayType(new MixedType(), $arrayTypeType); + } elseif ($type instanceof IterableType) { + $type = new IterableType(new MixedType(), $arrayTypeType); + } else { + continue; + } + + $addArray = false; + } + + if ($addArray) { + $otherTypeTypes[] = new ArrayType(new MixedType(), $arrayTypeType); + } + } + + return TypeCombinator::union(...$otherTypeTypes); + } + + private function resolveIntersectionTypeNode(IntersectionTypeNode $typeNode, NameScope $nameScope): Type + { + $types = $this->resolveMultiple($typeNode->types, $nameScope); + return TypeCombinator::intersect(...$types); + } + + private function resolveArrayTypeNode(ArrayTypeNode $typeNode, NameScope $nameScope): Type + { + $itemType = $this->resolve($typeNode->type, $nameScope); + return new ArrayType(new MixedType(), $itemType); + } + + private function resolveGenericTypeNode(GenericTypeNode $typeNode, NameScope $nameScope): Type + { + $mainTypeName = strtolower($typeNode->type->name); + $genericTypes = $this->resolveMultiple($typeNode->genericTypes, $nameScope); + + if ($mainTypeName === 'array') { + if (count($genericTypes) === 1) { // array + return new ArrayType(new MixedType(true), $genericTypes[0]); + + } + + if (count($genericTypes) === 2) { // array + return new ArrayType($genericTypes[0], $genericTypes[1]); + } + + } elseif ($mainTypeName === 'iterable') { + if (count($genericTypes) === 1) { // iterable + return new IterableType(new MixedType(true), $genericTypes[0]); + + } + + if (count($genericTypes) === 2) { // iterable + return new IterableType($genericTypes[0], $genericTypes[1]); + } + } + + $mainType = $this->resolveIdentifierTypeNode($typeNode->type, $nameScope); + if ($mainType->isIterable()->yes()) { + if (count($genericTypes) === 1) { // Foo + return TypeCombinator::intersect( + $mainType, + new IterableType(new MixedType(true), $genericTypes[0]) + ); + } + + if (count($genericTypes) === 2) { // Foo + return TypeCombinator::intersect( + $mainType, + new IterableType($genericTypes[0], $genericTypes[1]) + ); + } + } + + return new ErrorType(); + } + + private function resolveCallableTypeNode(CallableTypeNode $typeNode, NameScope $nameScope): Type + { + $mainType = $this->resolve($typeNode->identifier, $nameScope); + $isVariadic = false; + $parameters = array_map( + function (CallableTypeParameterNode $parameterNode) use ($nameScope, &$isVariadic): NativeParameterReflection { + $isVariadic = $isVariadic || $parameterNode->isVariadic; + return new NativeParameterReflection( + $parameterNode->parameterName, + $parameterNode->isOptional, + $this->resolve($parameterNode->type, $nameScope), + $parameterNode->isReference ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(), + $parameterNode->isVariadic + ); + }, + $typeNode->parameters + ); + $returnType = $this->resolve($typeNode->returnType, $nameScope); + + if ($mainType instanceof CallableType) { + return new CallableType($parameters, $returnType, $isVariadic); + + } elseif ( + $mainType instanceof ObjectType + && $mainType->getClassName() === \Closure::class + ) { + return new ClosureType($parameters, $returnType, $isVariadic); + } + + return new ErrorType(); + } + + /** + * @param TypeNode[] $typeNodes + * @param NameScope $nameScope + * @return Type[] + */ + public function resolveMultiple(array $typeNodes, NameScope $nameScope): array + { + $types = []; + foreach ($typeNodes as $typeNode) { + $types[] = $this->resolve($typeNode, $nameScope); + } + + return $types; + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/TypeNodeResolverAwareExtension.php b/vendor/phpstan/phpstan/src/PhpDoc/TypeNodeResolverAwareExtension.php new file mode 100644 index 00000000..38a65f17 --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/TypeNodeResolverAwareExtension.php @@ -0,0 +1,10 @@ +container = $container; + } + + public function create(): TypeNodeResolver + { + $tagToService = function (array $tags) { + return array_map(function (string $serviceName) { + return $this->container->getService($serviceName); + }, array_keys($tags)); + }; + + return new TypeNodeResolver( + $tagToService($this->container->findByTag(self::EXTENSION_TAG)) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/PhpDoc/TypeStringResolver.php b/vendor/phpstan/phpstan/src/PhpDoc/TypeStringResolver.php new file mode 100644 index 00000000..1d73049f --- /dev/null +++ b/vendor/phpstan/phpstan/src/PhpDoc/TypeStringResolver.php @@ -0,0 +1,39 @@ +typeLexer = $typeLexer; + $this->typeParser = $typeParser; + $this->typeNodeResolver = $typeNodeResolver; + } + + public function resolve(string $typeString, ?NameScope $nameScope = null): Type + { + $tokens = new TokenIterator($this->typeLexer->tokenize($typeString)); + $typeNode = $this->typeParser->parse($tokens); + $tokens->consumeTokenType(Lexer::TOKEN_END); + + return $this->typeNodeResolver->resolve($typeNode, $nameScope ?? new NameScope(null, [])); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationMethodReflection.php b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationMethodReflection.php new file mode 100644 index 00000000..aa3b6248 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationMethodReflection.php @@ -0,0 +1,107 @@ +name = $name; + $this->declaringClass = $declaringClass; + $this->returnType = $returnType; + $this->parameters = $parameters; + $this->isStatic = $isStatic; + $this->isVariadic = $isVariadic; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function getPrototype(): ClassMemberReflection + { + return $this; + } + + public function isStatic(): bool + { + return $this->isStatic; + } + + public function isPrivate(): bool + { + return false; + } + + public function isPublic(): bool + { + return true; + } + + public function getName(): string + { + return $this->name; + } + + /** + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getVariants(): array + { + if ($this->variants === null) { + $this->variants = [ + new FunctionVariant( + $this->parameters, + $this->isVariadic, + $this->returnType + ), + ]; + } + return $this->variants; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationPropertyReflection.php b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationPropertyReflection.php new file mode 100644 index 00000000..71109fe7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationPropertyReflection.php @@ -0,0 +1,72 @@ +declaringClass = $declaringClass; + $this->type = $type; + $this->readable = $readable; + $this->writable = $writable; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function isStatic(): bool + { + return false; + } + + public function isPrivate(): bool + { + return false; + } + + public function isPublic(): bool + { + return true; + } + + public function getType(): Type + { + return $this->type; + } + + public function isReadable(): bool + { + return $this->readable; + } + + public function isWritable(): bool + { + return $this->writable; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsMethodParameterReflection.php b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsMethodParameterReflection.php new file mode 100644 index 00000000..af10614e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsMethodParameterReflection.php @@ -0,0 +1,61 @@ +name = $name; + $this->type = $type; + $this->passedByReference = $passedByReference; + $this->isOptional = $isOptional; + $this->isVariadic = $isVariadic; + } + + public function getName(): string + { + return $this->name; + } + + public function isOptional(): bool + { + return $this->isOptional; + } + + public function getType(): Type + { + return $this->type; + } + + public function passedByReference(): PassedByReference + { + return $this->passedByReference; + } + + public function isVariadic(): bool + { + return $this->isVariadic; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsMethodsClassReflectionExtension.php b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsMethodsClassReflectionExtension.php new file mode 100644 index 00000000..ad38f2ef --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsMethodsClassReflectionExtension.php @@ -0,0 +1,113 @@ +fileTypeMapper = $fileTypeMapper; + } + + public function hasMethod(ClassReflection $classReflection, string $methodName): bool + { + if (!isset($this->methods[$classReflection->getName()])) { + $this->methods[$classReflection->getName()] = $this->createMethods($classReflection, $classReflection); + } + + return isset($this->methods[$classReflection->getName()][$methodName]); + } + + public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection + { + return $this->methods[$classReflection->getName()][$methodName]; + } + + /** + * @param ClassReflection $classReflection + * @param ClassReflection $declaringClass + * @return MethodReflection[] + */ + private function createMethods( + ClassReflection $classReflection, + ClassReflection $declaringClass + ): array + { + $methods = []; + foreach ($classReflection->getTraits() as $traitClass) { + $methods += $this->createMethods($traitClass, $classReflection); + } + foreach ($classReflection->getParents() as $parentClass) { + $methods += $this->createMethods($parentClass, $parentClass); + foreach ($parentClass->getTraits() as $traitClass) { + $methods += $this->createMethods($traitClass, $parentClass); + } + } + foreach ($classReflection->getInterfaces() as $interfaceClass) { + $methods += $this->createMethods($interfaceClass, $interfaceClass); + } + + $fileName = $classReflection->getFileName(); + if ($fileName === false) { + return $methods; + } + + $docComment = $classReflection->getNativeReflection()->getDocComment(); + if ($docComment === false) { + return $methods; + } + + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, $classReflection->getName(), null, $docComment); + foreach ($resolvedPhpDoc->getMethodTags() as $methodName => $methodTag) { + $parameters = []; + foreach ($methodTag->getParameters() as $parameterName => $parameterTag) { + $parameters[] = new AnnotationsMethodParameterReflection( + $parameterName, + $parameterTag->getType(), + $parameterTag->passedByReference(), + $parameterTag->isOptional(), + $parameterTag->isVariadic() + ); + } + + $methods[$methodName] = new AnnotationMethodReflection( + $methodName, + $declaringClass, + $methodTag->getReturnType(), + $parameters, + $methodTag->isStatic(), + $this->detectMethodVariadic($parameters) + ); + } + return $methods; + } + + /** + * @param AnnotationsMethodParameterReflection[] $parameters + * @return bool + */ + private function detectMethodVariadic(array $parameters): bool + { + if ($parameters === []) { + return false; + } + + $possibleVariadicParameterIndex = count($parameters) - 1; + $possibleVariadicParameter = $parameters[$possibleVariadicParameterIndex]; + + return $possibleVariadicParameter->isVariadic(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtension.php b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtension.php new file mode 100644 index 00000000..0b457da8 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Annotations/AnnotationsPropertiesClassReflectionExtension.php @@ -0,0 +1,86 @@ +fileTypeMapper = $fileTypeMapper; + } + + public function hasProperty(ClassReflection $classReflection, string $propertyName): bool + { + if (!isset($this->properties[$classReflection->getName()])) { + $this->properties[$classReflection->getName()] = $this->createProperties($classReflection, $classReflection); + } + + return isset($this->properties[$classReflection->getName()][$propertyName]); + } + + public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection + { + return $this->properties[$classReflection->getName()][$propertyName]; + } + + /** + * @param \PHPStan\Reflection\ClassReflection $classReflection + * @param \PHPStan\Reflection\ClassReflection $declaringClass + * @return \PHPStan\Reflection\PropertyReflection[] + */ + private function createProperties( + ClassReflection $classReflection, + ClassReflection $declaringClass + ): array + { + $properties = []; + foreach ($classReflection->getTraits() as $traitClass) { + $properties += $this->createProperties($traitClass, $classReflection); + } + foreach ($classReflection->getParents() as $parentClass) { + $properties += $this->createProperties($parentClass, $parentClass); + foreach ($parentClass->getTraits() as $traitClass) { + $properties += $this->createProperties($traitClass, $parentClass); + } + } + + foreach ($classReflection->getInterfaces() as $interfaceClass) { + $properties += $this->createProperties($interfaceClass, $interfaceClass); + } + + $fileName = $classReflection->getFileName(); + if ($fileName === false) { + return $properties; + } + + $docComment = $classReflection->getNativeReflection()->getDocComment(); + if ($docComment === false) { + return $properties; + } + + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, $classReflection->getName(), null, $docComment); + foreach ($resolvedPhpDoc->getPropertyTags() as $propertyName => $propertyTag) { + $properties[$propertyName] = new AnnotationPropertyReflection( + $declaringClass, + $propertyTag->getType(), + $propertyTag->isReadable(), + $propertyTag->isWritable() + ); + } + + return $properties; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/BrokerAwareClassReflectionExtension.php b/vendor/phpstan/phpstan/src/Reflection/BrokerAwareClassReflectionExtension.php new file mode 100644 index 00000000..9f6d69fb --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/BrokerAwareClassReflectionExtension.php @@ -0,0 +1,11 @@ +declaringClass = $declaringClass; + $this->reflection = $reflection; + $this->isDeprecated = $isDeprecated; + $this->isInternal = $isInternal; + } + + public function getName(): string + { + return $this->reflection->getName(); + } + + /** + * @return mixed + */ + public function getValue() + { + return $this->reflection->getValue(); + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function isStatic(): bool + { + return true; + } + + public function isPrivate(): bool + { + return $this->reflection->isPrivate(); + } + + public function isPublic(): bool + { + return $this->reflection->isPublic(); + } + + public function isDeprecated(): bool + { + return $this->isDeprecated; + } + + public function isInternal(): bool + { + return $this->isInternal; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/ClassMemberAccessAnswerer.php b/vendor/phpstan/phpstan/src/Reflection/ClassMemberAccessAnswerer.php new file mode 100644 index 00000000..b19f8021 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/ClassMemberAccessAnswerer.php @@ -0,0 +1,18 @@ +broker = $broker; + $this->fileTypeMapper = $fileTypeMapper; + $this->propertiesClassReflectionExtensions = $propertiesClassReflectionExtensions; + $this->methodsClassReflectionExtensions = $methodsClassReflectionExtensions; + $this->displayName = $displayName; + $this->reflection = $reflection; + $this->anonymousFilename = $anonymousFilename; + } + + public function getNativeReflection(): \ReflectionClass + { + return $this->reflection; + } + + /** + * @return string|false + */ + public function getFileName() + { + if ($this->anonymousFilename !== null) { + return $this->anonymousFilename; + } + $fileName = $this->reflection->getFileName(); + if ($fileName === false) { + return false; + } + + if (!file_exists($fileName)) { + return false; + } + + return $fileName; + } + + /** + * @return false|\PHPStan\Reflection\ClassReflection + */ + public function getParentClass() + { + if ($this->reflection->getParentClass() === false) { + return false; + } + + return $this->broker->getClass($this->reflection->getParentClass()->getName()); + } + + public function getName(): string + { + return $this->reflection->getName(); + } + + public function getDisplayName(): string + { + return $this->displayName; + } + + /** + * @return int[] + */ + public function getClassHierarchyDistances(): array + { + if ($this->classHierarchyDistances === null) { + $distance = 0; + $distances = [ + $this->getName() => $distance, + ]; + $currentClassReflection = $this->getNativeReflection(); + foreach ($this->getNativeReflection()->getTraits() as $trait) { + $distance++; + if (array_key_exists($trait->getName(), $distances)) { + continue; + } + + $distances[$trait->getName()] = $distance; + } + + while ($currentClassReflection->getParentClass() !== false) { + $distance++; + $parentClassName = $currentClassReflection->getParentClass()->getName(); + if (!array_key_exists($parentClassName, $distances)) { + $distances[$parentClassName] = $distance; + } + $currentClassReflection = $currentClassReflection->getParentClass(); + foreach ($currentClassReflection->getTraits() as $trait) { + $distance++; + if (array_key_exists($trait->getName(), $distances)) { + continue; + } + + $distances[$trait->getName()] = $distance; + } + } + foreach ($this->getNativeReflection()->getInterfaces() as $interface) { + $distance++; + if (array_key_exists($interface->getName(), $distances)) { + continue; + } + + $distances[$interface->getName()] = $distance; + } + + $this->classHierarchyDistances = $distances; + } + + return $this->classHierarchyDistances; + } + + public function hasProperty(string $propertyName): bool + { + foreach ($this->propertiesClassReflectionExtensions as $extension) { + if ($extension->hasProperty($this, $propertyName)) { + return true; + } + } + + return false; + } + + public function hasMethod(string $methodName): bool + { + foreach ($this->methodsClassReflectionExtensions as $extension) { + if ($extension->hasMethod($this, $methodName)) { + return true; + } + } + + return false; + } + + public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection + { + $key = $methodName; + if ($scope->isInClass()) { + $key = sprintf('%s-%s', $key, $scope->getClassReflection()->getName()); + } + if (!isset($this->methods[$key])) { + foreach ($this->methodsClassReflectionExtensions as $extension) { + if (!$extension->hasMethod($this, $methodName)) { + continue; + } + + $method = $extension->getMethod($this, $methodName); + if ($scope->canCallMethod($method)) { + return $this->methods[$key] = $method; + } + $this->methods[$key] = $method; + } + } + + if (!isset($this->methods[$key])) { + $filename = $this->getFileName(); + throw new \PHPStan\Reflection\MissingMethodFromReflectionException($this->getName(), $methodName, $filename !== false ? $filename : null); + } + + return $this->methods[$key]; + } + + public function hasNativeMethod(string $methodName): bool + { + return $this->getPhpExtension()->hasNativeMethod($this, $methodName); + } + + public function getNativeMethod(string $methodName): MethodReflection + { + if (!$this->hasNativeMethod($methodName)) { + $filename = $this->getFileName(); + throw new \PHPStan\Reflection\MissingMethodFromReflectionException($this->getName(), $methodName, $filename !== false ? $filename : null); + } + return $this->getPhpExtension()->getNativeMethod($this, $methodName); + } + + public function hasConstructor(): bool + { + return $this->reflection->getConstructor() !== null; + } + + public function getConstructor(): MethodReflection + { + $constructor = $this->reflection->getConstructor(); + if ($constructor === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + return $this->getNativeMethod($constructor->getName()); + } + + private function getPhpExtension(): PhpClassReflectionExtension + { + $extension = $this->methodsClassReflectionExtensions[0]; + if (!$extension instanceof PhpClassReflectionExtension) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $extension; + } + + public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection + { + $key = $propertyName; + if ($scope->isInClass()) { + $key = sprintf('%s-%s', $key, $scope->getClassReflection()->getName()); + } + if (!isset($this->properties[$key])) { + foreach ($this->propertiesClassReflectionExtensions as $extension) { + if (!$extension->hasProperty($this, $propertyName)) { + continue; + } + + $property = $extension->getProperty($this, $propertyName); + if ($scope->canAccessProperty($property)) { + return $this->properties[$key] = $property; + } + $this->properties[$key] = $property; + } + } + + if (!isset($this->properties[$key])) { + $filename = $this->getFileName(); + throw new \PHPStan\Reflection\MissingPropertyFromReflectionException($this->getName(), $propertyName, $filename !== false ? $filename : null); + } + + return $this->properties[$key]; + } + + public function hasNativeProperty(string $propertyName): bool + { + return $this->getPhpExtension()->hasProperty($this, $propertyName); + } + + public function getNativeProperty(string $propertyName): PhpPropertyReflection + { + if (!$this->hasNativeProperty($propertyName)) { + $filename = $this->getFileName(); + throw new \PHPStan\Reflection\MissingPropertyFromReflectionException($this->getName(), $propertyName, $filename !== false ? $filename : null); + } + return $this->getPhpExtension()->getNativeProperty($this, $propertyName); + } + + public function isAbstract(): bool + { + return $this->reflection->isAbstract(); + } + + public function isInterface(): bool + { + return $this->reflection->isInterface(); + } + + public function isTrait(): bool + { + return $this->reflection->isTrait(); + } + + public function isAnonymous(): bool + { + return $this->anonymousFilename !== null; + } + + public function isSubclassOf(string $className): bool + { + return $this->reflection->isSubclassOf($className); + } + + /** + * @return \PHPStan\Reflection\ClassReflection[] + */ + public function getParents(): array + { + $parents = []; + $parent = $this->getParentClass(); + while ($parent !== false) { + $parents[] = $parent; + $parent = $parent->getParentClass(); + } + + return $parents; + } + + /** + * @return \PHPStan\Reflection\ClassReflection[] + */ + public function getInterfaces(): array + { + return array_map(function (\ReflectionClass $interface) { + return $this->broker->getClass($interface->getName()); + }, $this->getNativeReflection()->getInterfaces()); + } + + /** + * @return \PHPStan\Reflection\ClassReflection[] + */ + public function getTraits(): array + { + return array_map(function (\ReflectionClass $trait) { + return $this->broker->getClass($trait->getName()); + }, $this->getNativeReflection()->getTraits()); + } + + /** + * @return string[] + */ + public function getParentClassesNames(): array + { + $parentNames = []; + $currentClassReflection = $this; + while ($currentClassReflection->getParentClass() !== false) { + $parentNames[] = $currentClassReflection->getParentClass()->getName(); + $currentClassReflection = $currentClassReflection->getParentClass(); + } + + return $parentNames; + } + + public function hasConstant(string $name): bool + { + return $this->getNativeReflection()->hasConstant($name); + } + + public function getConstant(string $name): ConstantReflection + { + if (!isset($this->constants[$name])) { + $reflectionConstant = $this->getNativeReflection()->getReflectionConstant($name); + if ($reflectionConstant === false) { + $fileName = $this->getFileName(); + throw new \PHPStan\Reflection\MissingConstantFromReflectionException($this->getName(), $name, $fileName !== false ? $fileName : null); + } + + $isDeprecated = false; + $isInternal = false; + if ($reflectionConstant->getDocComment() !== false && $this->getFileName() !== false) { + $docComment = $reflectionConstant->getDocComment(); + $fileName = $this->getFileName(); + $className = $reflectionConstant->getDeclaringClass()->getName(); + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc($fileName, $className, null, $docComment); + + $isDeprecated = $resolvedPhpDoc->isDeprecated(); + $isInternal = $resolvedPhpDoc->isInternal(); + } + + $this->constants[$name] = new ClassConstantReflection( + $this->broker->getClass($reflectionConstant->getDeclaringClass()->getName()), + $reflectionConstant, + $isDeprecated, + $isInternal + ); + } + return $this->constants[$name]; + } + + public function hasTraitUse(string $traitName): bool + { + return in_array($traitName, $this->getTraitNames(), true); + } + + /** + * @return string[] + */ + private function getTraitNames(): array + { + $class = $this->reflection; + $traitNames = $class->getTraitNames(); + while ($class->getParentClass() !== false) { + $traitNames = array_values(array_unique(array_merge($traitNames, $class->getParentClass()->getTraitNames()))); + $class = $class->getParentClass(); + } + + return $traitNames; + } + + public function isDeprecated(): bool + { + if ($this->isDeprecated === null) { + $resolvedPhpDoc = $this->getResolvedPhpDoc(); + $this->isDeprecated = $resolvedPhpDoc !== null && $resolvedPhpDoc->isDeprecated(); + } + + return $this->isDeprecated; + } + + public function isInternal(): bool + { + if ($this->isInternal === null) { + $resolvedPhpDoc = $this->getResolvedPhpDoc(); + $this->isInternal = $resolvedPhpDoc !== null && $resolvedPhpDoc->isInternal(); + } + + return $this->isInternal; + } + + public function isFinal(): bool + { + if ($this->isFinal === null) { + $resolvedPhpDoc = $this->getResolvedPhpDoc(); + $this->isFinal = $this->reflection->isFinal() + || ($resolvedPhpDoc !== null && $resolvedPhpDoc->isFinal()); + } + + return $this->isFinal; + } + + private function getResolvedPhpDoc(): ?ResolvedPhpDocBlock + { + $fileName = $this->reflection->getFileName(); + if ($fileName === false) { + return null; + } + + $docComment = $this->reflection->getDocComment(); + if ($docComment === false) { + return null; + } + + return $this->fileTypeMapper->getResolvedPhpDoc($fileName, $this->getName(), null, $docComment); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/ConstantReflection.php b/vendor/phpstan/phpstan/src/Reflection/ConstantReflection.php new file mode 100644 index 00000000..f3e66382 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/ConstantReflection.php @@ -0,0 +1,15 @@ +name = $name; + } + + public function getDeclaringClass(): ClassReflection + { + $broker = Broker::getInstance(); + + return $broker->getClass(\stdClass::class); + } + + public function isStatic(): bool + { + return true; + } + + public function isPrivate(): bool + { + return false; + } + + public function isPublic(): bool + { + return true; + } + + public function getName(): string + { + return $this->name; + } + + /** + * @return mixed + */ + public function getValue() + { + // so that Scope::getTypeFromValue() returns mixed + return new \stdClass(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Dummy/DummyMethodReflection.php b/vendor/phpstan/phpstan/src/Reflection/Dummy/DummyMethodReflection.php new file mode 100644 index 00000000..e386db1c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Dummy/DummyMethodReflection.php @@ -0,0 +1,64 @@ +name = $name; + } + + public function getDeclaringClass(): ClassReflection + { + $broker = Broker::getInstance(); + + return $broker->getClass(\stdClass::class); + } + + public function isStatic(): bool + { + return false; + } + + public function isPrivate(): bool + { + return false; + } + + public function isPublic(): bool + { + return true; + } + + public function getName(): string + { + return $this->name; + } + + public function getPrototype(): ClassMemberReflection + { + return $this; + } + + /** + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getVariants(): array + { + return [ + new TrivialParametersAcceptor(), + ]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Dummy/DummyPropertyReflection.php b/vendor/phpstan/phpstan/src/Reflection/Dummy/DummyPropertyReflection.php new file mode 100644 index 00000000..74e50e16 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Dummy/DummyPropertyReflection.php @@ -0,0 +1,51 @@ +getClass(\stdClass::class); + } + + public function isStatic(): bool + { + return false; + } + + public function isPrivate(): bool + { + return false; + } + + public function isPublic(): bool + { + return true; + } + + public function getType(): Type + { + return new MixedType(); + } + + public function isReadable(): bool + { + return true; + } + + public function isWritable(): bool + { + return true; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/FinalizableReflection.php b/vendor/phpstan/phpstan/src/Reflection/FinalizableReflection.php new file mode 100644 index 00000000..baaff6a6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/FinalizableReflection.php @@ -0,0 +1,10 @@ + */ + private $parameters; + + /** @var bool */ + private $isVariadic; + + /** @var Type */ + private $returnType; + + /** + * @param array $parameters + * @param bool $isVariadic + * @param Type $returnType + */ + public function __construct( + array $parameters, + bool $isVariadic, + Type $returnType + ) + { + $this->parameters = $parameters; + $this->isVariadic = $isVariadic; + $this->returnType = $returnType; + } + + /** + * @return array + */ + public function getParameters(): array + { + return $this->parameters; + } + + public function isVariadic(): bool + { + return $this->isVariadic; + } + + public function getReturnType(): Type + { + return $this->returnType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/FunctionVariantWithPhpDocs.php b/vendor/phpstan/phpstan/src/Reflection/FunctionVariantWithPhpDocs.php new file mode 100644 index 00000000..5b89b1a4 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/FunctionVariantWithPhpDocs.php @@ -0,0 +1,61 @@ + $parameters + * @param bool $isVariadic + * @param Type $returnType + * @param Type $phpDocReturnType + * @param Type $nativeReturnType + */ + public function __construct( + array $parameters, + bool $isVariadic, + Type $returnType, + Type $phpDocReturnType, + Type $nativeReturnType + ) + { + parent::__construct( + $parameters, + $isVariadic, + $returnType + ); + $this->phpDocReturnType = $phpDocReturnType; + $this->nativeReturnType = $nativeReturnType; + } + + /** + * @return array + */ + public function getParameters(): array + { + /** @var \PHPStan\Reflection\ParameterReflectionWithPhpDocs[] $parameters */ + $parameters = parent::getParameters(); + + return $parameters; + } + + public function getPhpDocReturnType(): Type + { + return $this->phpDocReturnType; + } + + public function getNativeReturnType(): Type + { + return $this->nativeReturnType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/InaccessibleMethod.php b/vendor/phpstan/phpstan/src/Reflection/InaccessibleMethod.php new file mode 100644 index 00000000..86f2f46d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/InaccessibleMethod.php @@ -0,0 +1,42 @@ +methodReflection = $methodReflection; + } + + public function getMethod(): MethodReflection + { + return $this->methodReflection; + } + + /** + * @return array + */ + public function getParameters(): array + { + return []; + } + + public function isVariadic(): bool + { + return true; + } + + public function getReturnType(): Type + { + return new MixedType(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/InternableReflection.php b/vendor/phpstan/phpstan/src/Reflection/InternableReflection.php new file mode 100644 index 00000000..58d1f94d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/InternableReflection.php @@ -0,0 +1,10 @@ +declaringClass = $declaringClass; + $this->isStatic = $isStatic; + $this->isPrivate = $isPrivate; + $this->isPublic = $isPublic; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function isStatic(): bool + { + return $this->isStatic; + } + + public function isPrivate(): bool + { + return $this->isPrivate; + } + + public function isPublic(): bool + { + return $this->isPublic; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/MethodReflection.php b/vendor/phpstan/phpstan/src/Reflection/MethodReflection.php new file mode 100644 index 00000000..19fa307c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/MethodReflection.php @@ -0,0 +1,17 @@ +name = $name; + $this->variants = $variants; + $this->throwType = $throwType; + } + + public function getName(): string + { + return $this->name; + } + + /** + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getVariants(): array + { + return $this->variants; + } + + public function getThrowType(): ?Type + { + return $this->throwType; + } + + public function isDeprecated(): bool + { + return false; + } + + public function isInternal(): bool + { + return false; + } + + public function isFinal(): bool + { + return false; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Native/NativeMethodReflection.php b/vendor/phpstan/phpstan/src/Reflection/Native/NativeMethodReflection.php new file mode 100644 index 00000000..73289cc2 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Native/NativeMethodReflection.php @@ -0,0 +1,114 @@ +broker = $broker; + $this->declaringClass = $declaringClass; + $this->reflection = $reflection; + $this->variants = $variants; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function isStatic(): bool + { + return $this->reflection->isStatic(); + } + + public function isPrivate(): bool + { + return $this->reflection->isPrivate(); + } + + public function isPublic(): bool + { + return $this->reflection->isPublic(); + } + + public function getPrototype(): ClassMemberReflection + { + try { + $prototypeMethod = $this->reflection->getPrototype(); + $prototypeDeclaringClass = $this->broker->getClass($prototypeMethod->getDeclaringClass()->getName()); + + return new MethodPrototypeReflection( + $prototypeDeclaringClass, + $prototypeMethod->isStatic(), + $prototypeMethod->isPrivate(), + $prototypeMethod->isPublic() + ); + } catch (\ReflectionException $e) { + return $this; + } + } + + public function getName(): string + { + return $this->reflection->getName(); + } + + /** + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getVariants(): array + { + return $this->variants; + } + + public function isDeprecated(): bool + { + return $this->reflection->isDeprecated(); + } + + public function isInternal(): bool + { + return false; + } + + public function isFinal(): bool + { + return false; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Native/NativeParameterReflection.php b/vendor/phpstan/phpstan/src/Reflection/Native/NativeParameterReflection.php new file mode 100644 index 00000000..d5cb4d36 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Native/NativeParameterReflection.php @@ -0,0 +1,89 @@ +name = $name; + $this->optional = $optional; + $this->type = $type; + $this->passedByReference = $passedByReference; + $this->variadic = $variadic; + } + + public function getName(): string + { + return $this->name; + } + + public function isOptional(): bool + { + return $this->optional; + } + + public function getType(): Type + { + $type = $this->type; + if ($this->variadic) { + $type = new ArrayType(new IntegerType(), $type); + } + + return $type; + } + + public function passedByReference(): PassedByReference + { + return $this->passedByReference; + } + + public function isVariadic(): bool + { + return $this->variadic; + } + + /** + * @param mixed[] $properties + * @return self + */ + public static function __set_state(array $properties): self + { + return new self( + $properties['name'], + $properties['optional'], + $properties['type'], + $properties['passedByReference'], + $properties['variadic'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/ParameterReflection.php b/vendor/phpstan/phpstan/src/Reflection/ParameterReflection.php new file mode 100644 index 00000000..9e6158e1 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/ParameterReflection.php @@ -0,0 +1,20 @@ + + */ + public function getParameters(): array; + + public function isVariadic(): bool; + + public function getReturnType(): Type; + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/ParametersAcceptorSelector.php b/vendor/phpstan/phpstan/src/Reflection/ParametersAcceptorSelector.php new file mode 100644 index 00000000..a0e0d409 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/ParametersAcceptorSelector.php @@ -0,0 +1,245 @@ +getType($arg->value); + if ($arg->unpack) { + $unpack = true; + $types[] = $type->getIterableValueType(); + } else { + $types[] = $type; + } + } + + return self::selectFromTypes($types, $parametersAcceptors, $unpack); + } + + /** + * @param \PHPStan\Type\Type[] $types + * @param ParametersAcceptor[] $parametersAcceptors + * @param bool $unpack + * @return ParametersAcceptor + */ + public static function selectFromTypes( + array $types, + array $parametersAcceptors, + bool $unpack + ): ParametersAcceptor + { + if (count($parametersAcceptors) === 1) { + return $parametersAcceptors[0]; + } + + if (count($parametersAcceptors) === 0) { + throw new \PHPStan\ShouldNotHappenException( + 'getVariants() must return at least one variant.' + ); + } + + $typesCount = count($types); + $acceptableAcceptors = []; + + foreach ($parametersAcceptors as $parametersAcceptor) { + if ($unpack) { + $acceptableAcceptors[] = $parametersAcceptor; + continue; + } + + $functionParametersMinCount = 0; + $functionParametersMaxCount = 0; + foreach ($parametersAcceptor->getParameters() as $parameter) { + if (!$parameter->isOptional()) { + $functionParametersMinCount++; + } + + $functionParametersMaxCount++; + } + + if ($typesCount < $functionParametersMinCount) { + continue; + } + + if ( + !$parametersAcceptor->isVariadic() + && $typesCount > $functionParametersMaxCount + ) { + continue; + } + + $acceptableAcceptors[] = $parametersAcceptor; + } + + if (count($acceptableAcceptors) === 0) { + return self::combineAcceptors($parametersAcceptors); + } + + if (count($acceptableAcceptors) === 1) { + return $acceptableAcceptors[0]; + } + + $winningAcceptors = []; + $winningCertainty = null; + foreach ($acceptableAcceptors as $acceptableAcceptor) { + $isSuperType = TrinaryLogic::createYes(); + foreach ($acceptableAcceptor->getParameters() as $i => $parameter) { + if (!isset($types[$i])) { + if (!$unpack || count($types) <= 0) { + break; + } + + $type = $types[count($types) - 1]; + } else { + $type = $types[$i]; + } + + if ($parameter->getType() instanceof MixedType) { + $isSuperType = $isSuperType->and(TrinaryLogic::createMaybe()); + } else { + $isSuperType = $isSuperType->and($parameter->getType()->isSuperTypeOf($type)); + } + } + + if ($isSuperType->no()) { + continue; + } + + if ($winningCertainty === null) { + $winningAcceptors[] = $acceptableAcceptor; + $winningCertainty = $isSuperType; + } else { + $comparison = $winningCertainty->compareTo($isSuperType); + if ($comparison === $isSuperType) { + $winningAcceptors = [$acceptableAcceptor]; + $winningCertainty = $isSuperType; + } elseif ($comparison === null) { + $winningAcceptors[] = $acceptableAcceptor; + } + } + } + + if (count($winningAcceptors) === 0) { + return self::combineAcceptors($acceptableAcceptors); + } + + return self::combineAcceptors($winningAcceptors); + } + + /** + * @param ParametersAcceptor[] $acceptors + * @return ParametersAcceptor + */ + public static function combineAcceptors(array $acceptors): ParametersAcceptor + { + if (count($acceptors) === 1) { + return $acceptors[0]; + } + + $minimumNumberOfParameters = null; + foreach ($acceptors as $acceptor) { + $acceptorParametersMinCount = 0; + foreach ($acceptor->getParameters() as $parameter) { + if ($parameter->isOptional()) { + continue; + } + + $acceptorParametersMinCount++; + } + + if ($minimumNumberOfParameters !== null && $minimumNumberOfParameters <= $acceptorParametersMinCount) { + continue; + } + + $minimumNumberOfParameters = $acceptorParametersMinCount; + } + + $parameters = []; + $isVariadic = false; + $returnType = null; + + foreach ($acceptors as $acceptor) { + if ($returnType === null) { + $returnType = $acceptor->getReturnType(); + } else { + $returnType = TypeCombinator::union($returnType, $acceptor->getReturnType()); + } + $isVariadic = $isVariadic || $acceptor->isVariadic(); + + foreach ($acceptor->getParameters() as $i => $parameter) { + if (!isset($parameters[$i])) { + $parameters[$i] = new NativeParameterReflection( + $parameter->getName(), + $i + 1 > $minimumNumberOfParameters, + $parameter->getType(), + $parameter->passedByReference(), + $parameter->isVariadic() + ); + continue; + } + + $isVariadic = $parameters[$i]->isVariadic() || $parameter->isVariadic(); + + $parameters[$i] = new NativeParameterReflection( + $parameters[$i]->getName() !== $parameter->getName() ? sprintf('%s|%s', $parameters[$i]->getName(), $parameter->getName()) : $parameter->getName(), + $i + 1 > $minimumNumberOfParameters, + TypeCombinator::union($parameters[$i]->getType(), $parameter->getType()), + $parameters[$i]->passedByReference()->combine($parameter->passedByReference()), + $isVariadic + ); + + if ($isVariadic) { + $parameters = array_slice($parameters, 0, $i + 1); + break; + } + } + } + + /** @var \PHPStan\Type\Type $returnType */ + $returnType = $returnType; + + return new FunctionVariant($parameters, $isVariadic, $returnType); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/ParametersAcceptorWithPhpDocs.php b/vendor/phpstan/phpstan/src/Reflection/ParametersAcceptorWithPhpDocs.php new file mode 100644 index 00000000..fbc22be4 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/ParametersAcceptorWithPhpDocs.php @@ -0,0 +1,19 @@ + + */ + public function getParameters(): array; + + public function getPhpDocReturnType(): Type; + + public function getNativeReturnType(): Type; + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/PassedByReference.php b/vendor/phpstan/phpstan/src/Reflection/PassedByReference.php new file mode 100644 index 00000000..41b41241 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/PassedByReference.php @@ -0,0 +1,87 @@ +value = $value; + } + + private static function create(int $value): self + { + if (!array_key_exists($value, self::$registry)) { + self::$registry[$value] = new self($value); + } + + return self::$registry[$value]; + } + + public static function createNo(): self + { + return self::create(self::NO); + } + + public static function createCreatesNewVariable(): self + { + return self::create(self::CREATES_NEW_VARIABLE); + } + + public static function createReadsArgument(): self + { + return self::create(self::READS_ARGUMENT); + } + + public function no(): bool + { + return $this->value === self::NO; + } + + public function yes(): bool + { + return !$this->no(); + } + + public function equals(self $other): bool + { + return $this->value === $other->value; + } + + public function createsNewVariable(): bool + { + return $this->value === self::CREATES_NEW_VARIABLE; + } + + public function combine(self $other): self + { + if ($this->value > $other->value) { + return $this; + } elseif ($this->value < $other->value) { + return $other; + } + + return $this; + } + + /** + * @param mixed[] $properties + * @return self + */ + public static function __set_state(array $properties): self + { + return new self($properties['value']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/BuiltinMethodReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/BuiltinMethodReflection.php new file mode 100644 index 00000000..2cc301d5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/BuiltinMethodReflection.php @@ -0,0 +1,51 @@ +name = $name; + $this->type = $type; + $this->optional = $optional; + $this->passedByReference = $passedByReference !== null + ? PassedByReference::createCreatesNewVariable() + : PassedByReference::createNo(); + $this->variadic = $variadic; + } + + public function getName(): string + { + return $this->name; + } + + public function isOptional(): bool + { + return $this->optional; + } + + public function getType(): Type + { + return $this->type; + } + + public function passedByReference(): PassedByReference + { + return $this->passedByReference; + } + + public function isVariadic(): bool + { + return $this->variadic; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/FakeBuiltinMethodReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/FakeBuiltinMethodReflection.php new file mode 100644 index 00000000..baba0392 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/FakeBuiltinMethodReflection.php @@ -0,0 +1,108 @@ +methodName = $methodName; + $this->declaringClass = $declaringClass; + } + + public function getName(): string + { + return $this->methodName; + } + + /** + * @return string|false + */ + public function getFileName() + { + return false; + } + + public function getDeclaringClass(): \ReflectionClass + { + return $this->declaringClass; + } + + /** + * @return int|false + */ + public function getStartLine() + { + return false; + } + + /** + * @return int|false + */ + public function getEndLine() + { + return false; + } + + /** + * @return string|false + */ + public function getDocComment() + { + return false; + } + + public function isStatic(): bool + { + return false; + } + + public function isPrivate(): bool + { + return false; + } + + public function isPublic(): bool + { + return true; + } + + public function getPrototype(): BuiltinMethodReflection + { + throw new \ReflectionException(); + } + + public function isDeprecated(): bool + { + return false; + } + + public function isVariadic(): bool + { + return false; + } + + public function getReturnType(): ?\ReflectionType + { + return null; + } + + /** + * @return \ReflectionParameter[] + */ + public function getParameters(): array + { + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/NativeBuiltinMethodReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/NativeBuiltinMethodReflection.php new file mode 100644 index 00000000..92b4684f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/NativeBuiltinMethodReflection.php @@ -0,0 +1,101 @@ +reflection = $reflection; + } + + public function getName(): string + { + return $this->reflection->getName(); + } + + /** + * @return string|false + */ + public function getFileName() + { + return $this->reflection->getFileName(); + } + + public function getDeclaringClass(): \ReflectionClass + { + return $this->reflection->getDeclaringClass(); + } + + /** + * @return int|false + */ + public function getStartLine() + { + return $this->reflection->getStartLine(); + } + + /** + * @return int|false + */ + public function getEndLine() + { + return $this->reflection->getEndLine(); + } + + /** + * @return string|false + */ + public function getDocComment() + { + return $this->reflection->getDocComment(); + } + + public function isStatic(): bool + { + return $this->reflection->isStatic(); + } + + public function isPrivate(): bool + { + return $this->reflection->isPrivate(); + } + + public function isPublic(): bool + { + return $this->reflection->isPublic(); + } + + public function getPrototype(): BuiltinMethodReflection + { + return new self($this->reflection->getPrototype()); + } + + public function isDeprecated(): bool + { + return $this->reflection->isDeprecated(); + } + + public function isVariadic(): bool + { + return $this->reflection->isVariadic(); + } + + public function getReturnType(): ?\ReflectionType + { + return $this->reflection->getReturnType(); + } + + /** + * @return \ReflectionParameter[] + */ + public function getParameters(): array + { + return $this->reflection->getParameters(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/PhpClassReflectionExtension.php b/vendor/phpstan/phpstan/src/Reflection/Php/PhpClassReflectionExtension.php new file mode 100644 index 00000000..09feef3e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/PhpClassReflectionExtension.php @@ -0,0 +1,497 @@ +methodReflectionFactory = $methodReflectionFactory; + $this->fileTypeMapper = $fileTypeMapper; + $this->annotationsMethodsClassReflectionExtension = $annotationsMethodsClassReflectionExtension; + $this->annotationsPropertiesClassReflectionExtension = $annotationsPropertiesClassReflectionExtension; + $this->signatureMapProvider = $signatureMapProvider; + } + + public function setBroker(Broker $broker): void + { + $this->broker = $broker; + } + + public function hasProperty(ClassReflection $classReflection, string $propertyName): bool + { + return $classReflection->getNativeReflection()->hasProperty($propertyName); + } + + public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection + { + if (!isset($this->propertiesIncludingAnnotations[$classReflection->getName()][$propertyName])) { + $this->propertiesIncludingAnnotations[$classReflection->getName()][$propertyName] = $this->createProperty($classReflection, $propertyName, true); + } + + return $this->propertiesIncludingAnnotations[$classReflection->getName()][$propertyName]; + } + + public function getNativeProperty(ClassReflection $classReflection, string $propertyName): PhpPropertyReflection + { + if (!isset($this->nativeProperties[$classReflection->getName()][$propertyName])) { + /** @var \PHPStan\Reflection\Php\PhpPropertyReflection $property */ + $property = $this->createProperty($classReflection, $propertyName, false); + $this->nativeProperties[$classReflection->getName()][$propertyName] = $property; + } + + return $this->nativeProperties[$classReflection->getName()][$propertyName]; + } + + private function createProperty( + ClassReflection $classReflection, + string $propertyName, + bool $includingAnnotations + ): PropertyReflection + { + $propertyReflection = $classReflection->getNativeReflection()->getProperty($propertyName); + $propertyName = $propertyReflection->getName(); + $declaringClassReflection = $this->broker->getClass($propertyReflection->getDeclaringClass()->getName()); + $isDeprecated = false; + $isInternal = false; + + if ($includingAnnotations && $this->annotationsPropertiesClassReflectionExtension->hasProperty($classReflection, $propertyName)) { + $hierarchyDistances = $classReflection->getClassHierarchyDistances(); + $annotationProperty = $this->annotationsPropertiesClassReflectionExtension->getProperty($classReflection, $propertyName); + if (!isset($hierarchyDistances[$annotationProperty->getDeclaringClass()->getName()])) { + throw new \PHPStan\ShouldNotHappenException(); + } + if (!isset($hierarchyDistances[$propertyReflection->getDeclaringClass()->getName()])) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ($hierarchyDistances[$annotationProperty->getDeclaringClass()->getName()] < $hierarchyDistances[$propertyReflection->getDeclaringClass()->getName()]) { + return $annotationProperty; + } + } + + $docComment = $propertyReflection->getDocComment() !== false + ? $propertyReflection->getDocComment() + : null; + + if ($declaringClassReflection->getFileName() !== false) { + $phpDocBlock = PhpDocBlock::resolvePhpDocBlockForProperty( + $this->broker, + $docComment, + $declaringClassReflection->getName(), + null, + $propertyName, + $declaringClassReflection->getFileName() + ); + + if ($phpDocBlock !== null) { + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc( + $phpDocBlock->getFile(), + $phpDocBlock->getClass(), + $this->findPropertyTrait($phpDocBlock, $propertyReflection), + $phpDocBlock->getDocComment() + ); + $varTags = $resolvedPhpDoc->getVarTags(); + if (isset($varTags[0]) && count($varTags) === 1) { + $type = $varTags[0]->getType(); + } elseif (isset($varTags[$propertyName])) { + $type = $varTags[$propertyName]->getType(); + } else { + $type = new MixedType(); + } + $isDeprecated = $resolvedPhpDoc->isDeprecated(); + $isInternal = $resolvedPhpDoc->isInternal(); + } else { + $type = new MixedType(); + } + } else { + $type = new MixedType(); + } + + return new PhpPropertyReflection( + $declaringClassReflection, + $type, + $propertyReflection, + $isDeprecated, + $isInternal + ); + } + + public function hasMethod(ClassReflection $classReflection, string $methodName): bool + { + if ( + $classReflection->getName() === \ReflectionType::class + ) { + $classReflection = $this->broker->getClass(\ReflectionNamedType::class); + } + + return $classReflection->getNativeReflection()->hasMethod($methodName); + } + + public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection + { + if ( + $classReflection->getName() === \ReflectionType::class + ) { + $classReflection = $this->broker->getClass(\ReflectionNamedType::class); + } + + if (isset($this->methodsIncludingAnnotations[$classReflection->getName()][$methodName])) { + return $this->methodsIncludingAnnotations[$classReflection->getName()][$methodName]; + } + + $nativeMethodReflection = new NativeBuiltinMethodReflection($classReflection->getNativeReflection()->getMethod($methodName)); + if (!isset($this->methodsIncludingAnnotations[$classReflection->getName()][$nativeMethodReflection->getName()])) { + $method = $this->createMethod($classReflection, $nativeMethodReflection, true); + $this->methodsIncludingAnnotations[$classReflection->getName()][$nativeMethodReflection->getName()] = $method; + if ($nativeMethodReflection->getName() !== $methodName) { + $this->methodsIncludingAnnotations[$classReflection->getName()][$methodName] = $method; + } + } + + return $this->methodsIncludingAnnotations[$classReflection->getName()][$nativeMethodReflection->getName()]; + } + + public function hasNativeMethod(ClassReflection $classReflection, string $methodName): bool + { + $hasMethod = $this->hasMethod($classReflection, $methodName); + if ($hasMethod) { + return true; + } + + if ($methodName === '__get' && UniversalObjectCratesClassReflectionExtension::isUniversalObjectCrate( + $this->broker, + $this->broker->getUniversalObjectCratesClasses(), + $classReflection + )) { + return true; + } + + return false; + } + + public function getNativeMethod(ClassReflection $classReflection, string $methodName): MethodReflection + { + if (isset($this->nativeMethods[$classReflection->getName()][$methodName])) { + return $this->nativeMethods[$classReflection->getName()][$methodName]; + } + + if ($classReflection->getNativeReflection()->hasMethod($methodName)) { + $nativeMethodReflection = new NativeBuiltinMethodReflection( + $classReflection->getNativeReflection()->getMethod($methodName) + ); + } else { + if ( + $methodName !== '__get' + || !UniversalObjectCratesClassReflectionExtension::isUniversalObjectCrate( + $this->broker, + $this->broker->getUniversalObjectCratesClasses(), + $classReflection + )) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $nativeMethodReflection = new FakeBuiltinMethodReflection( + $methodName, + $classReflection->getNativeReflection() + ); + } + + if (!isset($this->nativeMethods[$classReflection->getName()][$nativeMethodReflection->getName()])) { + $method = $this->createMethod($classReflection, $nativeMethodReflection, false); + $this->nativeMethods[$classReflection->getName()][$nativeMethodReflection->getName()] = $method; + } + + return $this->nativeMethods[$classReflection->getName()][$nativeMethodReflection->getName()]; + } + + private function createMethod( + ClassReflection $classReflection, + BuiltinMethodReflection $methodReflection, + bool $includingAnnotations + ): MethodReflection + { + if ($includingAnnotations && $this->annotationsMethodsClassReflectionExtension->hasMethod($classReflection, $methodReflection->getName())) { + $hierarchyDistances = $classReflection->getClassHierarchyDistances(); + $annotationMethod = $this->annotationsMethodsClassReflectionExtension->getMethod($classReflection, $methodReflection->getName()); + if (!isset($hierarchyDistances[$annotationMethod->getDeclaringClass()->getName()])) { + throw new \PHPStan\ShouldNotHappenException(); + } + if (!isset($hierarchyDistances[$methodReflection->getDeclaringClass()->getName()])) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ($hierarchyDistances[$annotationMethod->getDeclaringClass()->getName()] < $hierarchyDistances[$methodReflection->getDeclaringClass()->getName()]) { + return $annotationMethod; + } + } + $declaringClassName = $methodReflection->getDeclaringClass()->getName(); + $signatureMapMethodName = sprintf('%s::%s', $declaringClassName, $methodReflection->getName()); + $declaringClass = $this->broker->getClass($declaringClassName); + if ($this->signatureMapProvider->hasFunctionSignature($signatureMapMethodName)) { + $variantName = $signatureMapMethodName; + $variants = []; + $i = 0; + while ($this->signatureMapProvider->hasFunctionSignature($variantName)) { + $methodSignature = $this->signatureMapProvider->getFunctionSignature($variantName, $declaringClassName); + $variants[] = new FunctionVariant( + array_map(static function (ParameterSignature $parameterSignature): NativeParameterReflection { + return new NativeParameterReflection( + $parameterSignature->getName(), + $parameterSignature->isOptional(), + $parameterSignature->getType(), + $parameterSignature->passedByReference(), + $parameterSignature->isVariadic() + ); + }, $methodSignature->getParameters()), + $methodSignature->isVariadic(), + $methodSignature->getReturnType() + ); + $i++; + $variantName = sprintf($signatureMapMethodName . '\'' . $i); + } + return new NativeMethodReflection( + $this->broker, + $declaringClass, + $methodReflection, + $variants + ); + } + + $phpDocParameterTypes = []; + $phpDocReturnType = null; + $phpDocThrowType = null; + $isDeprecated = false; + $isInternal = false; + $isFinal = false; + $declaringTraitName = $this->findMethodTrait($methodReflection); + if ($declaringClass->getFileName() !== false) { + $docComment = $methodReflection->getDocComment() !== false + ? $methodReflection->getDocComment() + : null; + + $phpDocBlock = PhpDocBlock::resolvePhpDocBlockForMethod( + $this->broker, + $docComment, + $declaringClass->getName(), + $declaringTraitName, + $methodReflection->getName(), + $declaringClass->getFileName() + ); + + if ($phpDocBlock !== null) { + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc( + $phpDocBlock->getFile(), + $phpDocBlock->getClass(), + $phpDocBlock->getTrait(), + $phpDocBlock->getDocComment() + ); + $phpDocParameterTypes = array_map(static function (ParamTag $tag): Type { + return $tag->getType(); + }, $resolvedPhpDoc->getParamTags()); + $nativeReturnType = TypehintHelper::decideTypeFromReflection( + $methodReflection->getReturnType(), + null, + $declaringClass->getName() + ); + $phpDocReturnType = null; + if ( + $resolvedPhpDoc->getReturnTag() !== null + && ( + $phpDocBlock->isExplicit() + || $nativeReturnType->isSuperTypeOf($resolvedPhpDoc->getReturnTag()->getType())->yes() + ) + ) { + $phpDocReturnType = $resolvedPhpDoc->getReturnTag()->getType(); + } + $phpDocThrowType = $resolvedPhpDoc->getThrowsTag() !== null ? $resolvedPhpDoc->getThrowsTag()->getType() : null; + $isDeprecated = $resolvedPhpDoc->isDeprecated(); + $isInternal = $resolvedPhpDoc->isInternal(); + $isFinal = $resolvedPhpDoc->isFinal(); + } + } + + $declaringTrait = null; + if ( + $declaringTraitName !== null && $this->broker->hasClass($declaringTraitName) + ) { + $declaringTrait = $this->broker->getClass($declaringTraitName); + } + + return $this->methodReflectionFactory->create( + $declaringClass, + $declaringTrait, + $methodReflection, + $phpDocParameterTypes, + $phpDocReturnType, + $phpDocThrowType, + $isDeprecated, + $isInternal, + $isFinal + ); + } + + private function findPropertyTrait( + PhpDocBlock $phpDocBlock, + \ReflectionProperty $propertyReflection + ): ?string + { + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc( + $phpDocBlock->getFile(), + $phpDocBlock->getClass(), + null, + $phpDocBlock->getDocComment() + ); + if (count($resolvedPhpDoc->getVarTags()) > 0) { + return null; + } + + $declaringClass = $propertyReflection->getDeclaringClass(); + $traits = $declaringClass->getTraits(); + while (count($traits) > 0) { + /** @var \ReflectionClass $traitReflection */ + $traitReflection = array_pop($traits); + $traits = array_merge($traits, $traitReflection->getTraits()); + if (!$traitReflection->hasProperty($propertyReflection->getName())) { + continue; + } + + $traitResolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc( + $phpDocBlock->getFile(), + $phpDocBlock->getClass(), + $traitReflection->getName(), + $phpDocBlock->getDocComment() + ); + if ( + count($traitResolvedPhpDoc->getVarTags()) > 0 + ) { + return $traitReflection->getName(); + } + } + + return null; + } + + private function findMethodTrait( + BuiltinMethodReflection $methodReflection + ): ?string + { + $declaringClass = $methodReflection->getDeclaringClass(); + if ( + $methodReflection->getFileName() === $declaringClass->getFileName() + && $methodReflection->getStartLine() >= $declaringClass->getStartLine() + && $methodReflection->getEndLine() <= $declaringClass->getEndLine() + ) { + return null; + } + + $declaringClass = $methodReflection->getDeclaringClass(); + $traitAliases = $declaringClass->getTraitAliases(); + if (array_key_exists($methodReflection->getName(), $traitAliases)) { + return explode('::', $traitAliases[$methodReflection->getName()])[0]; + } + + foreach ($this->collectTraits($declaringClass) as $traitReflection) { + if (!$traitReflection->hasMethod($methodReflection->getName())) { + continue; + } + + if ( + $methodReflection->getFileName() === $traitReflection->getFileName() + && $methodReflection->getStartLine() >= $traitReflection->getStartLine() + && $methodReflection->getEndLine() <= $traitReflection->getEndLine() + ) { + return $traitReflection->getName(); + } + } + + return null; + } + + /** + * @param \ReflectionClass $class + * @return \ReflectionClass[] + */ + private function collectTraits(\ReflectionClass $class): array + { + $traits = []; + $traitsLeftToAnalyze = $class->getTraits(); + + while (count($traitsLeftToAnalyze) !== 0) { + $trait = reset($traitsLeftToAnalyze); + $traits[] = $trait; + + foreach ($trait->getTraits() as $subTrait) { + if (in_array($subTrait, $traits, true)) { + continue; + } + + $traitsLeftToAnalyze[] = $subTrait; + } + + array_shift($traitsLeftToAnalyze); + } + + return $traits; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/PhpFunctionFromParserNodeReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/PhpFunctionFromParserNodeReflection.php new file mode 100644 index 00000000..2c43522b --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/PhpFunctionFromParserNodeReflection.php @@ -0,0 +1,199 @@ +functionLike = $functionLike; + $this->realParameterTypes = $realParameterTypes; + $this->phpDocParameterTypes = $phpDocParameterTypes; + $this->realReturnTypePresent = $realReturnTypePresent; + $this->realReturnType = $realReturnType; + $this->phpDocReturnType = $phpDocReturnType; + $this->throwType = $throwType; + $this->isDeprecated = $isDeprecated; + $this->isInternal = $isInternal; + $this->isFinal = $isFinal; + } + + protected function getFunctionLike(): FunctionLike + { + return $this->functionLike; + } + + public function getName(): string + { + if ($this->functionLike instanceof ClassMethod) { + return $this->functionLike->name->name; + } + + return (string) $this->functionLike->namespacedName; + } + + /** + * @return \PHPStan\Reflection\ParametersAcceptorWithPhpDocs[] + */ + public function getVariants(): array + { + if ($this->variants === null) { + $this->variants = [ + new FunctionVariantWithPhpDocs( + $this->getParameters(), + $this->isVariadic(), + $this->getReturnType(), + $this->phpDocReturnType ?? new MixedType(), + $this->realReturnType ?? new MixedType() + ), + ]; + } + + return $this->variants; + } + + /** + * @return \PHPStan\Reflection\ParameterReflectionWithPhpDocs[] + */ + private function getParameters(): array + { + $parameters = []; + $isOptional = true; + + /** @var \PhpParser\Node\Param $parameter */ + foreach (array_reverse($this->functionLike->getParams()) as $parameter) { + if (!$isOptional || $parameter->default === null) { + $isOptional = false; + } + + if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $parameters[] = new PhpParameterFromParserNodeReflection( + $parameter->var->name, + $isOptional, + $this->realParameterTypes[$parameter->var->name], + $this->phpDocParameterTypes[$parameter->var->name] ?? null, + $parameter->byRef + ? PassedByReference::createCreatesNewVariable() + : PassedByReference::createNo(), + $parameter->default, + $parameter->variadic + ); + } + + return array_reverse($parameters); + } + + private function isVariadic(): bool + { + foreach ($this->functionLike->getParams() as $parameter) { + if ($parameter->variadic) { + return true; + } + } + + return false; + } + + protected function getReturnType(): Type + { + $phpDocReturnType = $this->phpDocReturnType; + if ( + $this->realReturnTypePresent + && $phpDocReturnType !== null + && TypeCombinator::containsNull($this->realReturnType) !== TypeCombinator::containsNull($phpDocReturnType) + ) { + $phpDocReturnType = null; + } + return TypehintHelper::decideType($this->realReturnType, $phpDocReturnType); + } + + public function isDeprecated(): bool + { + return $this->isDeprecated; + } + + public function isInternal(): bool + { + return $this->isInternal; + } + + public function isFinal(): bool + { + return $this->isFinal; + } + + public function getThrowType(): ?Type + { + return $this->throwType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/PhpFunctionReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/PhpFunctionReflection.php new file mode 100644 index 00000000..6de3a342 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/PhpFunctionReflection.php @@ -0,0 +1,253 @@ +reflection = $reflection; + $this->parser = $parser; + $this->functionCallStatementFinder = $functionCallStatementFinder; + $this->cache = $cache; + $this->phpDocParameterTypes = $phpDocParameterTypes; + $this->phpDocReturnType = $phpDocReturnType; + $this->phpDocThrowType = $phpDocThrowType; + $this->isDeprecated = $isDeprecated; + $this->isInternal = $isInternal; + $this->isFinal = $isFinal; + $this->filename = $filename; + } + + public function getName(): string + { + return $this->reflection->getName(); + } + + /** + * @return string|false + */ + public function getFileName() + { + return $this->filename; + } + + /** + * @return ParametersAcceptorWithPhpDocs[] + */ + public function getVariants(): array + { + if ($this->variants === null) { + $this->variants = [ + new FunctionVariantWithPhpDocs( + $this->getParameters(), + $this->isVariadic(), + $this->getReturnType(), + $this->getPhpDocReturnType(), + $this->getNativeReturnType() + ), + ]; + } + + return $this->variants; + } + + /** + * @return \PHPStan\Reflection\ParameterReflectionWithPhpDocs[] + */ + private function getParameters(): array + { + return array_map(function (\ReflectionParameter $reflection) { + return new PhpParameterReflection( + $reflection, + $this->phpDocParameterTypes[$reflection->getName()] ?? null + ); + }, $this->reflection->getParameters()); + } + + private function isVariadic(): bool + { + $isNativelyVariadic = $this->reflection->isVariadic(); + if (!$isNativelyVariadic && $this->reflection->getFileName() !== false) { + $key = sprintf('variadic-function-%s-v0', $this->reflection->getName()); + $cachedResult = $this->cache->load($key); + if ($cachedResult === null) { + $nodes = $this->parser->parseFile($this->reflection->getFileName()); + $result = $this->callsFuncGetArgs($nodes); + $this->cache->save($key, $result); + return $result; + } + + return $cachedResult; + } + + return $isNativelyVariadic; + } + + /** + * @param mixed $nodes + * @return bool + */ + private function callsFuncGetArgs($nodes): bool + { + foreach ($nodes as $node) { + if (is_array($node)) { + if ($this->callsFuncGetArgs($node)) { + return true; + } + } + + if (!($node instanceof \PhpParser\Node)) { + continue; + } + + if ($node instanceof Function_) { + $functionName = (string) $node->namespacedName; + + if ($functionName === $this->reflection->getName()) { + return $this->functionCallStatementFinder->findFunctionCallInStatements(ParametersAcceptor::VARIADIC_FUNCTIONS, $node->getStmts()) !== null; + } + + continue; + } + + if ($this->callsFuncGetArgs($node)) { + return true; + } + } + + return false; + } + + private function getReturnType(): Type + { + if ($this->reflection->getName() === 'count') { + return new IntegerType(); + } + $returnType = $this->reflection->getReturnType(); + $phpDocReturnType = $this->phpDocReturnType; + if ( + $returnType !== null + && $phpDocReturnType !== null + && $returnType->allowsNull() !== TypeCombinator::containsNull($phpDocReturnType) + ) { + $phpDocReturnType = null; + } + return TypehintHelper::decideTypeFromReflection( + $returnType, + $phpDocReturnType + ); + } + + private function getPhpDocReturnType(): Type + { + if ($this->phpDocReturnType !== null) { + return $this->phpDocReturnType; + } + + return new MixedType(); + } + + private function getNativeReturnType(): Type + { + return TypehintHelper::decideTypeFromReflection($this->reflection->getReturnType()); + } + + public function isDeprecated(): bool + { + return $this->isDeprecated || $this->reflection->isDeprecated(); + } + + public function isInternal(): bool + { + return $this->isInternal; + } + + public function isFinal(): bool + { + return $this->isFinal; + } + + public function getThrowType(): ?Type + { + return $this->phpDocThrowType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodFromParserNodeReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodFromParserNodeReflection.php new file mode 100644 index 00000000..a7433282 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodFromParserNodeReflection.php @@ -0,0 +1,125 @@ +declaringClass = $declaringClass; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function getPrototype(): ClassMemberReflection + { + return $this->declaringClass->getNativeMethod($this->getClassMethod()->name->name)->getPrototype(); + } + + private function getClassMethod(): ClassMethod + { + /** @var \PhpParser\Node\Stmt\ClassMethod $functionLike */ + $functionLike = $this->getFunctionLike(); + return $functionLike; + } + + public function isStatic(): bool + { + return $this->getClassMethod()->isStatic(); + } + + public function isPrivate(): bool + { + return $this->getClassMethod()->isPrivate(); + } + + public function isPublic(): bool + { + return $this->getClassMethod()->isPublic(); + } + + protected function getReturnType(): Type + { + $name = strtolower($this->getName()); + if ( + $name === '__construct' + || $name === '__destruct' + || $name === '__unset' + || $name === '__wakeup' + || $name === '__clone' + ) { + return new VoidType(); + } + if ($name === '__tostring') { + return new StringType(); + } + if ($name === '__isset') { + return new BooleanType(); + } + if ($name === '__sleep') { + return new ArrayType(new IntegerType(), new StringType()); + } + if ($name === '__set_state') { + return new ObjectWithoutClassType(); + } + + return parent::getReturnType(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodReflection.php new file mode 100644 index 00000000..017752e2 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodReflection.php @@ -0,0 +1,415 @@ +declaringClass = $declaringClass; + $this->declaringTrait = $declaringTrait; + $this->reflection = $reflection; + $this->broker = $broker; + $this->parser = $parser; + $this->functionCallStatementFinder = $functionCallStatementFinder; + $this->cache = $cache; + $this->phpDocParameterTypes = $phpDocParameterTypes; + $this->phpDocReturnType = $phpDocReturnType; + $this->phpDocThrowType = $phpDocThrowType; + $this->isDeprecated = $isDeprecated; + $this->isInternal = $isInternal; + $this->isFinal = $isFinal; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function getDeclaringTrait(): ?ClassReflection + { + return $this->declaringTrait; + } + + /** + * @return string|false + */ + public function getDocComment() + { + return $this->reflection->getDocComment(); + } + + public function getPrototype(): ClassMemberReflection + { + try { + $prototypeMethod = $this->reflection->getPrototype(); + $prototypeDeclaringClass = $this->broker->getClass($prototypeMethod->getDeclaringClass()->getName()); + + return new MethodPrototypeReflection( + $prototypeDeclaringClass, + $prototypeMethod->isStatic(), + $prototypeMethod->isPrivate(), + $prototypeMethod->isPublic() + ); + } catch (\ReflectionException $e) { + return $this; + } + } + + public function isStatic(): bool + { + return $this->reflection->isStatic(); + } + + public function getName(): string + { + $name = $this->reflection->getName(); + $lowercaseName = strtolower($name); + if ($lowercaseName === $name) { + // fix for https://bugs.php.net/bug.php?id=74939 + foreach ($this->getDeclaringClass()->getNativeReflection()->getTraitAliases() as $traitTarget) { + $correctName = $this->getMethodNameWithCorrectCase($name, $traitTarget); + if ($correctName !== null) { + $name = $correctName; + break; + } + } + } + + return $name; + } + + private function getMethodNameWithCorrectCase(string $lowercaseMethodName, string $traitTarget): ?string + { + $trait = explode('::', $traitTarget)[0]; + $traitReflection = $this->broker->getClass($trait)->getNativeReflection(); + foreach ($traitReflection->getTraitAliases() as $methodAlias => $aliasTraitTarget) { + if ($lowercaseMethodName === strtolower($methodAlias)) { + return $methodAlias; + } + + $correctName = $this->getMethodNameWithCorrectCase($lowercaseMethodName, $aliasTraitTarget); + if ($correctName !== null) { + return $correctName; + } + } + + return null; + } + + /** + * @return ParametersAcceptorWithPhpDocs[] + */ + public function getVariants(): array + { + if ($this->variants === null) { + $this->variants = [ + new FunctionVariantWithPhpDocs( + $this->getParameters(), + $this->isVariadic(), + $this->getReturnType(), + $this->getPhpDocReturnType(), + $this->getNativeReturnType() + ), + ]; + } + + return $this->variants; + } + + /** + * @return \PHPStan\Reflection\ParameterReflectionWithPhpDocs[] + */ + private function getParameters(): array + { + if ($this->parameters === null) { + $this->parameters = array_map(function (\ReflectionParameter $reflection) { + return new PhpParameterReflection( + $reflection, + $this->phpDocParameterTypes[$reflection->getName()] ?? null + ); + }, $this->reflection->getParameters()); + } + + return $this->parameters; + } + + private function isVariadic(): bool + { + $isNativelyVariadic = $this->reflection->isVariadic(); + $declaringClass = $this->declaringClass; + $filename = $this->declaringClass->getFileName(); + if ($this->declaringTrait !== null) { + $declaringClass = $this->declaringTrait; + $filename = $this->declaringTrait->getFileName(); + } + + if (!$isNativelyVariadic && $filename !== false) { + $key = sprintf('variadic-method-%s-%s-v1', $declaringClass->getName(), $this->reflection->getName()); + $cachedResult = $this->cache->load($key); + if ($cachedResult === null || !is_bool($cachedResult)) { + $nodes = $this->parser->parseFile($filename); + $result = $this->callsFuncGetArgs($declaringClass, $nodes); + $this->cache->save($key, $result); + return $result; + } + + return $cachedResult; + } + + return $isNativelyVariadic; + } + + /** + * @param ClassReflection $declaringClass + * @param mixed $nodes + * @return bool + */ + private function callsFuncGetArgs(ClassReflection $declaringClass, $nodes): bool + { + foreach ($nodes as $node) { + if (is_array($node)) { + if ($this->callsFuncGetArgs($declaringClass, $node)) { + return true; + } + } + + if (!($node instanceof \PhpParser\Node)) { + continue; + } + + if ( + $node instanceof \PhpParser\Node\Stmt\ClassLike + && isset($node->namespacedName) + && $declaringClass->getName() !== (string) $node->namespacedName + ) { + continue; + } + + if ($node instanceof ClassMethod) { + if ($node->getStmts() === null) { + continue; // interface + } + + $methodName = $node->name->name; + if ($methodName === $this->reflection->getName()) { + return $this->functionCallStatementFinder->findFunctionCallInStatements(ParametersAcceptor::VARIADIC_FUNCTIONS, $node->getStmts()) !== null; + } + + continue; + } + + if ($this->callsFuncGetArgs($declaringClass, $node)) { + return true; + } + } + + return false; + } + + public function isPrivate(): bool + { + return $this->reflection->isPrivate(); + } + + public function isPublic(): bool + { + return $this->reflection->isPublic(); + } + + private function getReturnType(): Type + { + if ($this->returnType === null) { + $name = strtolower($this->getName()); + if ( + $name === '__construct' + || $name === '__destruct' + || $name === '__unset' + || $name === '__wakeup' + || $name === '__clone' + ) { + return $this->returnType = new VoidType(); + } + if ($name === '__tostring') { + return $this->returnType = new StringType(); + } + if ($name === '__isset') { + return $this->returnType = new BooleanType(); + } + if ($name === '__sleep') { + return $this->returnType = new ArrayType(new IntegerType(), new StringType()); + } + if ($name === '__set_state') { + return $this->returnType = new ObjectWithoutClassType(); + } + + $returnType = $this->reflection->getReturnType(); + $phpDocReturnType = $this->phpDocReturnType; + if ( + $returnType !== null + && $phpDocReturnType !== null + && $returnType->allowsNull() !== TypeCombinator::containsNull($phpDocReturnType) + ) { + $phpDocReturnType = null; + } + $this->returnType = TypehintHelper::decideTypeFromReflection( + $returnType, + $phpDocReturnType, + $this->declaringClass->getName() + ); + } + + return $this->returnType; + } + + private function getPhpDocReturnType(): Type + { + if ($this->phpDocReturnType !== null) { + return $this->phpDocReturnType; + } + + return new MixedType(); + } + + private function getNativeReturnType(): Type + { + if ($this->nativeReturnType === null) { + $this->nativeReturnType = TypehintHelper::decideTypeFromReflection( + $this->reflection->getReturnType(), + null, + $this->declaringClass->getName() + ); + } + + return $this->nativeReturnType; + } + + public function isDeprecated(): bool + { + return $this->isDeprecated; + } + + public function isInternal(): bool + { + return $this->isInternal; + } + + public function isFinal(): bool + { + return $this->isFinal; + } + + public function getThrowType(): ?Type + { + return $this->phpDocThrowType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodReflectionFactory.php b/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodReflectionFactory.php new file mode 100644 index 00000000..7d3929b6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/PhpMethodReflectionFactory.php @@ -0,0 +1,35 @@ +name = $name; + $this->optional = $optional; + $this->realType = $realType; + $this->phpDocType = $phpDocType; + $this->passedByReference = $passedByReference; + $this->defaultValue = $defaultValue; + $this->variadic = $variadic; + } + + public function getName(): string + { + return $this->name; + } + + public function isOptional(): bool + { + return $this->optional; + } + + public function getType(): Type + { + if ($this->type === null) { + $phpDocType = $this->phpDocType; + if ($phpDocType !== null && $this->defaultValue !== null) { + if ( + $this->defaultValue instanceof ConstFetch + && strtolower((string) $this->defaultValue->name) === 'null' + ) { + $phpDocType = \PHPStan\Type\TypeCombinator::addNull($phpDocType); + } + } + $this->type = TypehintHelper::decideType($this->realType, $phpDocType); + } + + return $this->type; + } + + public function getPhpDocType(): Type + { + return $this->phpDocType ?? new MixedType(); + } + + public function getNativeType(): Type + { + return $this->realType ?? new MixedType(); + } + + public function passedByReference(): PassedByReference + { + return $this->passedByReference; + } + + public function isVariadic(): bool + { + return $this->variadic; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/PhpParameterReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/PhpParameterReflection.php new file mode 100644 index 00000000..0d8cb765 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/PhpParameterReflection.php @@ -0,0 +1,95 @@ +reflection = $reflection; + $this->phpDocType = $phpDocType; + } + + public function isOptional(): bool + { + return $this->reflection->isOptional(); + } + + public function getName(): string + { + return $this->reflection->getName(); + } + + public function getType(): Type + { + if ($this->type === null) { + $phpDocType = $this->phpDocType; + if ($phpDocType !== null && $this->reflection->isDefaultValueAvailable() && $this->reflection->getDefaultValue() === null) { + $phpDocType = \PHPStan\Type\TypeCombinator::addNull($phpDocType); + } + $this->type = TypehintHelper::decideTypeFromReflection( + $this->reflection->getType(), + $phpDocType, + $this->reflection->getDeclaringClass() !== null ? $this->reflection->getDeclaringClass()->getName() : null, + $this->isVariadic() + ); + } + + return $this->type; + } + + public function passedByReference(): PassedByReference + { + return $this->reflection->isPassedByReference() + ? PassedByReference::createCreatesNewVariable() + : PassedByReference::createNo(); + } + + public function isVariadic(): bool + { + return $this->reflection->isVariadic(); + } + + public function getPhpDocType(): Type + { + if ($this->phpDocType !== null) { + return $this->phpDocType; + } + + return new MixedType(); + } + + public function getNativeType(): Type + { + if ($this->nativeType === null) { + $this->nativeType = TypehintHelper::decideTypeFromReflection( + $this->reflection->getType(), + null, + $this->reflection->getDeclaringClass() !== null ? $this->reflection->getDeclaringClass()->getName() : null, + $this->isVariadic() + ); + } + + return $this->nativeType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/PhpPropertyReflection.php b/vendor/phpstan/phpstan/src/Reflection/Php/PhpPropertyReflection.php new file mode 100644 index 00000000..b5aa4c58 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/PhpPropertyReflection.php @@ -0,0 +1,97 @@ +declaringClass = $declaringClass; + $this->type = $type; + $this->reflection = $reflection; + $this->isDeprecated = $isDeprecated; + $this->isInternal = $isInternal; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + /** + * @return string|false + */ + public function getDocComment() + { + return $this->reflection->getDocComment(); + } + + public function isStatic(): bool + { + return $this->reflection->isStatic(); + } + + public function isPrivate(): bool + { + return $this->reflection->isPrivate(); + } + + public function isPublic(): bool + { + return $this->reflection->isPublic(); + } + + public function getType(): Type + { + return $this->type; + } + + public function isReadable(): bool + { + return true; + } + + public function isWritable(): bool + { + return true; + } + + public function isDeprecated(): bool + { + return $this->isDeprecated; + } + + public function isInternal(): bool + { + return $this->isInternal; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/UniversalObjectCrateProperty.php b/vendor/phpstan/phpstan/src/Reflection/Php/UniversalObjectCrateProperty.php new file mode 100644 index 00000000..70c89114 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/UniversalObjectCrateProperty.php @@ -0,0 +1,61 @@ +declaringClass = $declaringClass; + $this->type = $type; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function isStatic(): bool + { + return false; + } + + public function isPrivate(): bool + { + return false; + } + + public function isPublic(): bool + { + return true; + } + + public function getType(): Type + { + return $this->type; + } + + public function isReadable(): bool + { + return true; + } + + public function isWritable(): bool + { + return true; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/Php/UniversalObjectCratesClassReflectionExtension.php b/vendor/phpstan/phpstan/src/Reflection/Php/UniversalObjectCratesClassReflectionExtension.php new file mode 100644 index 00000000..09bb7c97 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/Php/UniversalObjectCratesClassReflectionExtension.php @@ -0,0 +1,81 @@ +classes = $classes; + } + + public function setBroker(Broker $broker): void + { + $this->broker = $broker; + } + + public function hasProperty(ClassReflection $classReflection, string $propertyName): bool + { + return self::isUniversalObjectCrate( + $this->broker, + $this->classes, + $classReflection + ); + } + + /** + * @param \PHPStan\Broker\Broker $broker + * @param string[] $classes + * @param \PHPStan\Reflection\ClassReflection $classReflection + * @return bool + */ + public static function isUniversalObjectCrate( + Broker $broker, + array $classes, + ClassReflection $classReflection + ): bool + { + foreach ($classes as $className) { + if (!$broker->hasClass($className)) { + continue; + } + + if ( + $classReflection->getName() === $className + || $classReflection->isSubclassOf($className) + ) { + return true; + } + } + + return false; + } + + public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection + { + if ($classReflection->hasNativeMethod('__get')) { + $type = ParametersAcceptorSelector::selectSingle($classReflection->getNativeMethod('__get')->getVariants())->getReturnType(); + } else { + $type = new MixedType(); + } + return new UniversalObjectCrateProperty($classReflection, $type); + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/PhpDefect/PhpDefectClassReflectionExtension.php b/vendor/phpstan/phpstan/src/Reflection/PhpDefect/PhpDefectClassReflectionExtension.php new file mode 100644 index 00000000..12ec7771 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/PhpDefect/PhpDefectClassReflectionExtension.php @@ -0,0 +1,241 @@ +> */ + private static $defaultProperties = [ + \DateInterval::class => [ + 'y' => 'int', + 'm' => 'int', + 'd' => 'int', + 'h' => 'int', + 'i' => 'int', + 's' => 'int', + 'invert' => 'int', + 'days' => 'mixed', + 'f' => 'float', + ], + \DatePeriod::class => [ + 'recurrences' => 'int', + 'include_start_date' => 'bool', + 'start' => \DateTimeInterface::class, + 'current' => \DateTimeInterface::class, + 'end' => \DateTimeInterface::class, + 'interval' => \DateInterval::class, + ], + 'Directory' => [ + 'handle' => 'resource', + 'path' => 'string', + ], + 'DOMAttr' => [ // extends DOMNode + 'name' => 'string', + 'ownerDocument' => 'DOMDocument', + 'ownerElement' => 'DOMElement', + 'schemaTypeInfo' => 'bool', + 'specified' => 'bool', + 'value' => 'string', + ], + 'DOMCharacterData' => [ // extends DOMNode + 'data' => 'string', + 'length' => 'int', + 'ownerDocument' => 'DOMDocument', + ], + 'DOMDocument' => [ + 'actualEncoding' => 'string', + 'config' => 'DOMConfiguration', + 'doctype' => 'DOMDocumentType', + 'documentElement' => 'DOMElement', + 'documentURI' => 'string', + 'encoding' => 'string', + 'formatOutput' => 'bool', + 'implementation' => 'DOMImplementation', + 'ownerDocument' => 'null', + 'preserveWhiteSpace' => 'bool', + 'recover' => 'bool', + 'resolveExternals' => 'bool', + 'standalone' => 'bool', + 'strictErrorChecking' => 'bool', + 'substituteEntities' => 'bool', + 'validateOnParse' => 'bool', + 'version' => 'string', + 'xmlEncoding' => 'string', + 'xmlStandalone' => 'bool', + 'xmlVersion' => 'string', + ], + 'DOMDocumentType' => [ // extends DOMNode + 'publicId' => 'string', + 'systemId' => 'string', + 'name' => 'string', + 'entities' => 'DOMNamedNodeMap', + 'notations' => 'DOMNamedNodeMap', + 'ownerDocument' => 'DOMDocument', + 'internalSubset' => 'string', + ], + 'DOMElement' => [ // extends DOMNode + 'ownerDocument' => 'DOMDocument', + 'schemaTypeInfo' => 'bool', + 'tagName' => 'string', + ], + 'DOMEntity' => [ // extends DOMNode + 'publicId' => 'string', + 'systemId' => 'string', + 'notationName' => 'string', + 'actualEncoding' => 'string', + 'encoding' => 'string', + 'ownerDocument' => 'DOMDocument', + 'version' => 'string', + ], + 'DOMNamedNodeMap' => [ + 'length' => 'int', + ], + 'DOMNode' => [ + 'nodeName' => 'string', + 'nodeValue' => 'string', + 'nodeType' => 'int', + 'parentNode' => 'DOMNode', + 'childNodes' => 'DOMNodeList', + 'firstChild' => 'DOMNode', + 'lastChild' => 'DOMNode', + 'previousSibling' => 'DOMNode', + 'nextSibling' => 'DOMNode', + 'attributes' => 'DOMNamedNodeMap', + 'ownerDocument' => 'DOMDocument|null', + 'namespaceURI' => 'string', + 'prefix' => 'string', + 'localName' => 'string', + 'baseURI' => 'string', + 'textContent' => 'string', + ], + 'DOMNodeList' => [ + 'length' => 'int', + ], + 'DOMNotation' => [ // extends DOMNode + 'ownerDocument' => 'DOMDocument', + 'publicId' => 'string', + 'systemId' => 'string', + ], + 'DOMProcessingInstruction' => [ // extends DOMNode + 'ownerDocument' => 'DOMDocument', + 'target' => 'string', + 'data' => 'string', + ], + 'DOMText' => [ // extends DOMCharacterData + 'wholeText' => 'string', + ], + 'DOMXPath' => [ // extends DOMCharacterData + 'document' => 'DOMDocument', + ], + 'Ds\\Pair' => [ + 'key' => 'mixed', + 'value' => 'mixed', + ], + 'XMLReader' => [ + 'attributeCount' => 'int', + 'baseURI' => 'string', + 'depth' => 'int', + 'hasAttributes' => 'bool', + 'hasValue' => 'bool', + 'isDefault' => 'bool', + 'isEmptyElement' => 'bool', + 'localName' => 'string', + 'name' => 'string', + 'namespaceURI' => 'string', + 'nodeType' => 'int', + 'prefix' => 'string', + 'value' => 'string', + 'xmlLang' => 'string', + ], + 'ZipArchive' => [ + 'status' => 'int', + 'statusSys' => 'int', + 'numFiles' => 'int', + 'filename' => 'string', + 'comment' => 'string', + ], + 'LibXMLError' => [ + 'level' => 'int', + 'code' => 'int', + 'column' => 'int', + 'message' => 'string', + 'file' => 'string', + 'line' => 'int', + ], + ]; + + /** @var \PHPStan\Reflection\Annotations\AnnotationsPropertiesClassReflectionExtension */ + private $annotationsPropertiesClassReflectionExtension; + + /** @var TypeStringResolver */ + private $typeStringResolver; + + /** @var string[][] */ + private $properties = []; + + public function __construct( + TypeStringResolver $typeStringResolver, + AnnotationsPropertiesClassReflectionExtension $annotationsPropertiesClassReflectionExtension + ) + { + $this->typeStringResolver = $typeStringResolver; + $this->properties = self::$defaultProperties; + $this->annotationsPropertiesClassReflectionExtension = $annotationsPropertiesClassReflectionExtension; + } + + public function hasProperty(ClassReflection $classReflection, string $propertyName): bool + { + $classWithProperties = $this->getClassWithProperties($classReflection, $propertyName); + return $classWithProperties !== null; + } + + public function getProperty(ClassReflection $classReflection, string $propertyName): PropertyReflection + { + /** @var \PHPStan\Reflection\ClassReflection $classWithProperties */ + $classWithProperties = $this->getClassWithProperties($classReflection, $propertyName); + + if ($this->annotationsPropertiesClassReflectionExtension->hasProperty($classReflection, $propertyName)) { + $hierarchyDistances = $classReflection->getClassHierarchyDistances(); + $annotationProperty = $this->annotationsPropertiesClassReflectionExtension->getProperty($classReflection, $propertyName); + if (!isset($hierarchyDistances[$annotationProperty->getDeclaringClass()->getName()])) { + throw new \PHPStan\ShouldNotHappenException(); + } + if (!isset($hierarchyDistances[$classWithProperties->getName()])) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ($hierarchyDistances[$annotationProperty->getDeclaringClass()->getName()] < $hierarchyDistances[$classWithProperties->getName()]) { + return $annotationProperty; + } + } + + $typeString = $this->properties[$classWithProperties->getName()][$propertyName]; + return new PhpDefectPropertyReflection( + $classWithProperties, + $this->typeStringResolver->resolve($typeString) + ); + } + + private function getClassWithProperties(ClassReflection $classReflection, string $propertyName): ?\PHPStan\Reflection\ClassReflection + { + if (isset($this->properties[$classReflection->getName()][$propertyName])) { + return $classReflection; + } + + foreach ($classReflection->getParents() as $parentClass) { + if (isset($this->properties[$parentClass->getName()][$propertyName])) { + return $parentClass; + } + } + + return null; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/PhpDefect/PhpDefectPropertyReflection.php b/vendor/phpstan/phpstan/src/Reflection/PhpDefect/PhpDefectPropertyReflection.php new file mode 100644 index 00000000..b1bff7db --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/PhpDefect/PhpDefectPropertyReflection.php @@ -0,0 +1,62 @@ +declaringClass = $declaringClass; + $this->type = $type; + } + + public function getDeclaringClass(): ClassReflection + { + return $this->declaringClass; + } + + public function isStatic(): bool + { + return false; + } + + public function isPrivate(): bool + { + return false; + } + + public function isPublic(): bool + { + return true; + } + + public function getType(): Type + { + return $this->type; + } + + public function isReadable(): bool + { + return true; + } + + public function isWritable(): bool + { + return true; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/PropertiesClassReflectionExtension.php b/vendor/phpstan/phpstan/src/Reflection/PropertiesClassReflectionExtension.php new file mode 100644 index 00000000..7b8b6fce --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/PropertiesClassReflectionExtension.php @@ -0,0 +1,12 @@ + $parameters + * @param \PHPStan\Type\Type $returnType + * @param bool $variadic + */ + public function __construct( + array $parameters, + Type $returnType, + bool $variadic + ) + { + $this->parameters = $parameters; + $this->returnType = $returnType; + $this->variadic = $variadic; + } + + /** + * @return array + */ + public function getParameters(): array + { + return $this->parameters; + } + + public function getReturnType(): Type + { + return $this->returnType; + } + + public function isVariadic(): bool + { + return $this->variadic; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/SignatureMap/ParameterSignature.php b/vendor/phpstan/phpstan/src/Reflection/SignatureMap/ParameterSignature.php new file mode 100644 index 00000000..ec6b694a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/SignatureMap/ParameterSignature.php @@ -0,0 +1,67 @@ +name = $name; + $this->optional = $optional; + $this->type = $type; + $this->passedByReference = $passedByReference; + $this->variadic = $variadic; + } + + + public function getName(): string + { + return $this->name; + } + + public function isOptional(): bool + { + return $this->optional; + } + + public function getType(): Type + { + return $this->type; + } + + public function passedByReference(): PassedByReference + { + return $this->passedByReference; + } + + public function isVariadic(): bool + { + return $this->variadic; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/SignatureMap/SignatureMapParser.php b/vendor/phpstan/phpstan/src/Reflection/SignatureMap/SignatureMapParser.php new file mode 100644 index 00000000..cb2c1820 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/SignatureMap/SignatureMapParser.php @@ -0,0 +1,134 @@ +typeStringResolver = $typeNodeResolver; + } + + /** + * @param mixed[] $map + * @param string|null $className + * @return \PHPStan\Reflection\SignatureMap\FunctionSignature + */ + public function getFunctionSignature(array $map, ?string $className): FunctionSignature + { + $parameterSignatures = $this->getParameters(array_slice($map, 1)); + $hasVariadic = false; + foreach ($parameterSignatures as $parameterSignature) { + if ($parameterSignature->isVariadic()) { + $hasVariadic = true; + break; + } + } + return new FunctionSignature( + $parameterSignatures, + $this->getTypeFromString($map[0], $className), + $hasVariadic + ); + } + + private function getTypeFromString(string $typeString, ?string $className): Type + { + if ($typeString === '') { + return new MixedType(true); + } + $parts = explode('|', $typeString); + $types = []; + foreach ($parts as $part) { + $isNullable = false; + if (substr($part, 0, 1) === '?') { + $isNullable = true; + $part = substr($part, 1); + } + + if ($part === 'OCI-Lob' || $part === 'OCI-Collection') { + $type = new ObjectType($part); + } else { + $type = $this->typeStringResolver->resolve($part, new NameScope(null, [], $className)); + } + if ($isNullable) { + $type = TypeCombinator::addNull($type); + } + + $types[] = $type; + } + + return TypeCombinator::union(...$types); + } + + /** + * @param array $parameterMap + * @return array + */ + private function getParameters(array $parameterMap): array + { + $parameterSignatures = []; + foreach ($parameterMap as $parameterName => $typeString) { + [$name, $isOptional, $passedByReference, $isVariadic] = $this->getParameterInfoFromName($parameterName); + $parameterSignatures[] = new ParameterSignature( + $name, + $isOptional, + $this->getTypeFromString($typeString, null), + $passedByReference, + $isVariadic + ); + } + + return $parameterSignatures; + } + + /** + * @param string $parameterNameString + * @return mixed[] + */ + private function getParameterInfoFromName(string $parameterNameString): array + { + $matches = \Nette\Utils\Strings::match( + $parameterNameString, + '#^(?P&(?:\.\.\.)?r?w?_?)?(?P\.\.\.)?(?P[^=]+)?(?P=)?($)#' + ); + if ($matches === null || !isset($matches['optional'])) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $isVariadic = $matches['variadic'] !== ''; + + $reference = $matches['reference']; + if (strpos($reference, '&...') === 0) { + $reference = '&' . substr($reference, 4); + $isVariadic = true; + } + if (strpos($reference, '&rw') === 0) { + $passedByReference = PassedByReference::createReadsArgument(); + } elseif (strpos($reference, '&w') === 0) { + $passedByReference = PassedByReference::createCreatesNewVariable(); + } else { + $passedByReference = PassedByReference::createNo(); + } + + $isOptional = $isVariadic || $matches['optional'] !== ''; + + $name = $matches['name'] !== '' ? $matches['name'] : '...'; + + return [$name, $isOptional, $passedByReference, $isVariadic]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/SignatureMap/SignatureMapProvider.php b/vendor/phpstan/phpstan/src/Reflection/SignatureMap/SignatureMapProvider.php new file mode 100644 index 00000000..0f75d762 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/SignatureMap/SignatureMapProvider.php @@ -0,0 +1,56 @@ +parser = $parser; + } + + public function hasFunctionSignature(string $name): bool + { + $signatureMap = self::getSignatureMap(); + return array_key_exists($name, $signatureMap); + } + + public function getFunctionSignature(string $functionName, ?string $className): FunctionSignature + { + if (!$this->hasFunctionSignature($functionName)) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $signatureMap = self::getSignatureMap(); + + return $this->parser->getFunctionSignature( + $signatureMap[$functionName], + $className + ); + } + + /** + * @return mixed[] + */ + private static function getSignatureMap(): array + { + if (self::$signatureMap === null) { + $signatureMap = require __DIR__ . '/functionMap.php'; + if (!is_array($signatureMap)) { + throw new \PHPStan\ShouldNotHappenException('Signature map could not be loaded.'); + } + + self::$signatureMap = $signatureMap; + } + + return self::$signatureMap; + } + +} diff --git a/vendor/phpstan/phpstan/src/Reflection/SignatureMap/functionMap.php b/vendor/phpstan/phpstan/src/Reflection/SignatureMap/functionMap.php new file mode 100644 index 00000000..fd76f879 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/SignatureMap/functionMap.php @@ -0,0 +1,13742 @@ +' => [', ''=>''] + * alternative signature for the same function + * '' => [', ''=>''] + * + * A '&' in front of the means the arg is always passed by reference. + * (i.e. ReflectionParameter->isPassedByReference()) + * This was previously only used in cases where the function actually created the + * variable in the local scope. + * Some reference arguments will have prefixes in to indicate the way the argument is used. + * Currently, the only prefixes with meaning are 'rw_' (read-write) and 'w_' (write). + * Those prefixes don't mean anything for non-references. + * Code using these signatures should remove those prefixes from messages rendered to the user. + * 1. '&rw_' indicates that a parameter with a value is expected to be passed in, and may be modified. + * Phan will warn if the variable has an incompatible type, or is undefined. + * 2. '&w_' indicates that a parameter is expected to be passed in, and the value will be ignored, and may be overwritten. + * 3. The absence of a prefix is treated by Phan the same way as having the prefix 'w_' (Some may be changed to 'rw_name'). These will have prefixes added later. + * + * So, for functions like sort() where technically the arg is by-ref, + * indicate the reference param's signature by-ref and read-write, + * as `'&rw_array'=>'array'` + * so that Phan won't create it in the local scope + * + * However, for a function like preg_match() where the 3rd arg is an array of sub-pattern matches (and optional), + * this arg needs to be marked as by-ref and write-only, as `'&w_matches='=>'array'`. + * + * A '=' following the indicates this arg is optional. + * + * The can begin with '...' to indicate the arg is variadic. + * '...args=' indicates it is both variadic and optional. + * + * Some reference arguments will have prefixes in to indicate the way the argument is used. + * Currently, the only prefixes with meaning are 'rw_' and 'w_'. + * Code using these signatures should remove those prefixes from messages rendered to the user. + * 1. '&rw_name' indicates that a parameter with a value is expected to be passed in, and may be modified. + * 2. '&w_name' indicates that a parameter is expected to be passed in, and the value will be ignored, and may be overwritten. + * + * Sources of stub info: + * + * 1. Reflection + * 2. docs.php.net's SVN repo or website, and examples (See internal/internalsignatures.php) + * 3. Various websites documenting individual extensions + * 4. PHPStorm stubs (For anything missing from the above sources) + * See internal/internalsignatures.php + */ + +return [ +'_' => ['string', 'message'=>'string'], +'__halt_compiler' => ['void'], +'abs' => ['int', 'number'=>'int'], +'abs\'1' => ['float', 'number'=>'float'], +'accelerator_get_configuration' => ['array'], +'accelerator_get_scripts' => ['array'], +'accelerator_get_status' => ['array', 'fetch_scripts'=>'bool'], +'accelerator_reset' => [''], +'accelerator_set_status' => ['void', 'status'=>''], +'acos' => ['float', 'number'=>'float'], +'acosh' => ['float', 'number'=>'float'], +'addcslashes' => ['string', 'str'=>'string', 'charlist'=>'string'], +'addslashes' => ['string', 'str'=>'string'], +'AMQPChannel::__construct' => ['void', 'amqp_connection'=>'AMQPConnection'], +'AMQPChannel::basicRecover' => ['', 'requeue='=>'bool|true'], +'AMQPChannel::commitTransaction' => ['bool'], +'AMQPChannel::getChannelId' => ['int'], +'AMQPChannel::getConnection' => ['AMQPConnection'], +'AMQPChannel::getPrefetchCount' => ['int'], +'AMQPChannel::getPrefetchSize' => ['int'], +'AMQPChannel::isConnected' => ['bool'], +'AMQPChannel::qos' => ['bool', 'size'=>'int', 'count'=>'int'], +'AMQPChannel::rollbackTransaction' => ['bool'], +'AMQPChannel::setPrefetchCount' => ['bool', 'count'=>'int'], +'AMQPChannel::setPrefetchSize' => ['bool', 'size'=>'int'], +'AMQPChannel::startTransaction' => ['bool'], +'AMQPConnection::__construct' => ['void', 'credentials='=>'array'], +'AMQPConnection::connect' => ['bool'], +'AMQPConnection::disconnect' => ['bool'], +'AMQPConnection::getHost' => ['string'], +'AMQPConnection::getLogin' => ['string'], +'AMQPConnection::getMaxChannels' => ['int|null'], +'AMQPConnection::getPassword' => ['string'], +'AMQPConnection::getPort' => ['int'], +'AMQPConnection::getReadTimeout' => ['float'], +'AMQPConnection::getTimeout' => ['float'], +'AMQPConnection::getUsedChannels' => ['int'], +'AMQPConnection::getVhost' => ['string'], +'AMQPConnection::getWriteTimeout' => ['float'], +'AMQPConnection::isConnected' => ['bool'], +'AMQPConnection::isPersistent' => ['bool|null'], +'AMQPConnection::pconnect' => ['bool'], +'AMQPConnection::pdisconnect' => ['bool'], +'AMQPConnection::preconnect' => ['bool'], +'AMQPConnection::reconnect' => ['bool'], +'AMQPConnection::setHost' => ['bool', 'host'=>'string'], +'AMQPConnection::setLogin' => ['bool', 'login'=>'string'], +'AMQPConnection::setPassword' => ['bool', 'password'=>'string'], +'AMQPConnection::setPort' => ['bool', 'port'=>'int'], +'AMQPConnection::setReadTimeout' => ['bool', 'timeout'=>'int'], +'AMQPConnection::setTimeout' => ['bool', 'timeout'=>'int'], +'AMQPConnection::setVhost' => ['bool', 'vhost'=>'string'], +'AMQPConnection::setWriteTimeout' => ['bool', 'timeout'=>'int'], +'AMQPEnvelope::getAppId' => ['string'], +'AMQPEnvelope::getBody' => ['string'], +'AMQPEnvelope::getContentEncoding' => ['string'], +'AMQPEnvelope::getContentType' => ['string'], +'AMQPEnvelope::getCorrelationId' => ['string'], +'AMQPEnvelope::getDeliveryMode' => ['int'], +'AMQPEnvelope::getDeliveryTag' => ['string'], +'AMQPEnvelope::getExchangeName' => ['string'], +'AMQPEnvelope::getExpiration' => ['string'], +'AMQPEnvelope::getHeader' => ['bool|string', 'header_key'=>'string'], +'AMQPEnvelope::getHeaders' => ['array'], +'AMQPEnvelope::getMessageId' => ['string'], +'AMQPEnvelope::getPriority' => ['int'], +'AMQPEnvelope::getReplyTo' => ['string'], +'AMQPEnvelope::getRoutingKey' => ['string'], +'AMQPEnvelope::getTimeStamp' => ['string'], +'AMQPEnvelope::getType' => ['string'], +'AMQPEnvelope::getUserId' => ['string'], +'AMQPEnvelope::isRedelivery' => ['bool'], +'AMQPExchange::__construct' => ['void', 'amqp_channel'=>'AMQPChannel'], +'AMQPExchange::bind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'], +'AMQPExchange::declareExchange' => ['bool'], +'AMQPExchange::delete' => ['bool', 'exchangeName='=>'string', 'flags='=>'int'], +'AMQPExchange::getArgument' => ['bool|int|string', 'key'=>'string'], +'AMQPExchange::getArguments' => ['array'], +'AMQPExchange::getChannel' => ['AMQPChannel'], +'AMQPExchange::getConnection' => ['AMQPConnection'], +'AMQPExchange::getFlags' => ['int'], +'AMQPExchange::getName' => ['string'], +'AMQPExchange::getType' => ['string'], +'AMQPExchange::publish' => ['bool', 'message'=>'string', 'routing_key='=>'string', 'flags='=>'int', 'attributes='=>'array'], +'AMQPExchange::setArgument' => ['bool', 'key'=>'string', 'value'=>'int|string'], +'AMQPExchange::setArguments' => ['bool', 'arguments'=>'array'], +'AMQPExchange::setFlags' => ['bool', 'flags'=>'int'], +'AMQPExchange::setName' => ['bool', 'exchange_name'=>'string'], +'AMQPExchange::setType' => ['bool', 'exchange_type'=>'string'], +'AMQPExchange::unbind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'], +'AMQPQueue::__construct' => ['void', 'amqp_channel'=>'AMQPChannel'], +'AMQPQueue::ack' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'], +'AMQPQueue::bind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'], +'AMQPQueue::cancel' => ['bool', 'consumer_tag='=>'string'], +'AMQPQueue::consume' => ['void', 'callback='=>'?callable', 'flags='=>'int', 'consumerTag='=>'string'], +'AMQPQueue::declareQueue' => ['int'], +'AMQPQueue::delete' => ['int', 'flags='=>'int'], +'AMQPQueue::get' => ['AMQPEnvelope|bool', 'flags='=>'int'], +'AMQPQueue::getArgument' => ['bool|int|string', 'key'=>'string'], +'AMQPQueue::getArguments' => ['array'], +'AMQPQueue::getChannel' => ['AMQPChannel'], +'AMQPQueue::getConnection' => ['AMQPConnection'], +'AMQPQueue::getFlags' => ['int'], +'AMQPQueue::getName' => ['string'], +'AMQPQueue::nack' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'], +'AMQPQueue::purge' => ['bool'], +'AMQPQueue::reject' => ['bool', 'delivery_tag'=>'string', 'flags='=>'int'], +'AMQPQueue::setArgument' => ['bool', 'key'=>'string', 'value'=>'mixed'], +'AMQPQueue::setArguments' => ['bool', 'arguments'=>'array'], +'AMQPQueue::setFlags' => ['bool', 'flags'=>'int'], +'AMQPQueue::setName' => ['bool', 'queue_name'=>'string'], +'AMQPQueue::unbind' => ['bool', 'exchange_name'=>'string', 'routing_key='=>'string', 'arguments='=>'array'], +'apache_child_terminate' => ['bool'], +'apache_get_modules' => ['array'], +'apache_get_version' => ['string|false'], +'apache_getenv' => ['string|false', 'variable'=>'string', 'walk_to_top='=>'bool'], +'apache_lookup_uri' => ['object', 'filename'=>'string'], +'apache_note' => ['string|false', 'note_name'=>'string', 'note_value='=>'string'], +'apache_request_headers' => ['array|false'], +'apache_reset_timeout' => ['bool'], +'apache_response_headers' => ['array|false'], +'apache_setenv' => ['bool', 'variable'=>'string', 'value'=>'string', 'walk_to_top='=>'bool'], +'apc_add' => ['bool', 'key'=>'string', 'ttl='=>'int'], +'apc_add\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], +'apc_bin_dump' => ['string', 'files='=>'array', 'user_vars='=>'array'], +'apc_bin_dumpfile' => ['int', 'files'=>'array', 'user_vars'=>'array', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'], +'apc_bin_load' => ['bool', 'data'=>'string', 'flags='=>'int'], +'apc_bin_loadfile' => ['bool', 'filename'=>'string', 'context='=>'resource', 'flags='=>'int'], +'apc_cache_info' => ['array', 'cache_type='=>'string', 'limited='=>'bool'], +'apc_cas' => ['bool', 'key'=>'string', 'old'=>'int', 'new'=>'int'], +'apc_clear_cache' => ['bool', 'cache_type='=>'string'], +'apc_compile_file' => ['mixed', 'filename'=>'string', 'atomic='=>'bool'], +'apc_dec' => ['int', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'], +'apc_define_constants' => ['bool', 'key'=>'string', 'constants'=>'array', 'case_sensitive='=>'bool'], +'apc_delete' => ['bool', 'key'=>'string|string[]|APCIterator'], +'apc_delete_file' => ['mixed', 'keys'=>'mixed'], +'apc_exists' => ['bool', 'keys'=>'string'], +'apc_exists\'1' => ['array', 'keys'=>'string[]'], +'apc_fetch' => ['mixed', 'key'=>'mixed', '&w_success='=>'bool'], +'apc_inc' => ['int', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'], +'apc_load_constants' => ['bool', 'key'=>'string', 'case_sensitive='=>'bool'], +'apc_sma_info' => ['array', 'limited='=>'bool'], +'apc_store' => ['bool', 'key'=>'string', 'var'=>'', 'ttl='=>'int'], +'apc_store\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], +'APCIterator::__construct' => ['void', 'cache'=>'string', 'search='=>'', 'format='=>'int', 'chunk_size='=>'int', 'list='=>'int'], +'APCIterator::current' => ['mixed'], +'APCIterator::getTotalCount' => ['int'], +'APCIterator::getTotalHits' => ['int'], +'APCIterator::getTotalSize' => ['int'], +'APCIterator::key' => ['string'], +'APCIterator::next' => ['void'], +'APCIterator::rewind' => ['void'], +'APCIterator::valid' => ['bool'], +'apcu_add' => ['bool', 'key'=>'string', 'var'=>'', 'ttl='=>'int'], +'apcu_add\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], +'apcu_cache_info' => ['array', 'limited='=>'bool'], +'apcu_cas' => ['bool', 'key'=>'string', 'old'=>'int', 'new'=>'int'], +'apcu_clear_cache' => ['bool'], +'apcu_dec' => ['int', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'], +'apcu_delete' => ['bool|array', 'key'=>'string|string[]|APCUIterator'], +'apcu_entry' => ['mixed', 'key'=>'string', 'generator'=>'callable', 'ttl='=>'int'], +'apcu_exists' => ['bool', 'keys'=>'string'], +'apcu_exists\'1' => ['array', 'keys'=>'string[]'], +'apcu_fetch' => ['mixed', 'key'=>'string|string[]', '&w_success='=>'bool'], +'apcu_inc' => ['int', 'key'=>'string', 'step='=>'int', '&w_success='=>'bool'], +'apcu_sma_info' => ['array', 'limited='=>'bool'], +'apcu_store' => ['bool', 'key'=>'string', 'var='=>'', 'ttl='=>'int'], +'apcu_store\'1' => ['array', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], +'APCUIterator::__construct' => ['void', 'search='=>'string|string[]|null', 'format='=>'int', 'chunk_size='=>'int', 'list='=>'int'], +'APCUIterator::current' => ['mixed'], +'APCUIterator::getTotalCount' => ['int'], +'APCUIterator::getTotalHits' => ['int'], +'APCUIterator::getTotalSize' => ['int'], +'APCUIterator::key' => ['string'], +'APCUIterator::next' => ['void'], +'APCUIterator::rewind' => ['void'], +'APCUIterator::valid' => ['bool'], +'apd_breakpoint' => ['bool', 'debug_level'=>'int'], +'apd_callstack' => ['array'], +'apd_clunk' => ['void', 'warning'=>'string', 'delimiter='=>'string'], +'apd_continue' => ['bool', 'debug_level'=>'int'], +'apd_croak' => ['void', 'warning'=>'string', 'delimiter='=>'string'], +'apd_dump_function_table' => ['void'], +'apd_dump_persistent_resources' => ['array'], +'apd_dump_regular_resources' => ['array'], +'apd_echo' => ['bool', 'output'=>'string'], +'apd_get_active_symbols' => ['array'], +'apd_set_pprof_trace' => ['string', 'dump_directory='=>'string', 'fragment='=>'string'], +'apd_set_session' => ['void', 'debug_level'=>'int'], +'apd_set_session_trace' => ['void', 'debug_level'=>'int', 'dump_directory='=>'string'], +'apd_set_session_trace_socket' => ['bool', 'tcp_server'=>'string', 'socket_type'=>'int', 'port'=>'int', 'debug_level'=>'int'], +'AppendIterator::__construct' => ['void'], +'AppendIterator::append' => ['void', 'it'=>'iterator'], +'AppendIterator::current' => ['mixed'], +'AppendIterator::getArrayIterator' => ['ArrayIterator'], +'AppendIterator::getInnerIterator' => ['iterator'], +'AppendIterator::getIteratorIndex' => ['int'], +'AppendIterator::key' => ['mixed'], +'AppendIterator::next' => ['void'], +'AppendIterator::rewind' => ['void'], +'AppendIterator::valid' => ['bool'], +'array_change_key_case' => ['array', 'input'=>'array', 'case='=>'int'], +'array_chunk' => ['array[]', 'input'=>'array', 'size'=>'int', 'preserve_keys='=>'bool'], +'array_column' => ['array', 'array'=>'array', 'column_key'=>'mixed', 'index_key='=>'mixed'], +'array_combine' => ['array|false', 'keys'=>'array', 'values'=>'array'], +'array_count_values' => ['int[]', 'input'=>'array'], +'array_diff' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], +'array_diff_assoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], +'array_diff_key' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], +'array_diff_uassoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_comp_func'=>'callable'], +'array_diff_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest='=>'array|callable'], +'array_diff_ukey' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_comp_func'=>'callable'], +'array_diff_ukey\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest='=>'array|callable'], +'array_fill' => ['array', 'start_key'=>'int', 'num'=>'int', 'val'=>'mixed'], +'array_fill_keys' => ['array', 'keys'=>'array', 'val'=>'mixed'], +'array_filter' => ['array', 'input'=>'array', 'callback='=>'callable', 'flag='=>'int'], +'array_flip' => ['array', 'input'=>'array'], +'array_intersect' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], +'array_intersect_assoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], +'array_intersect_key' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], +'array_intersect_uassoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_compare_func'=>'callable'], +'array_intersect_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest'=>'array|callable'], +'array_intersect_ukey' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_compare_func'=>'callable'], +'array_intersect_ukey\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest'=>'array|callable'], +'array_key_first' => ['int|string|null', 'array' => 'array'], +'array_key_last' => ['int|string|null', 'array' => 'array'], +'array_key_exists' => ['bool', 'key'=>'string|int', 'search'=>'array'], +'array_keys' => ['array', 'input'=>'array', 'search_value='=>'mixed', 'strict='=>'bool'], +'array_map' => ['array', 'callback'=>'?callable', 'input1'=>'array', '...args='=>'array'], +'array_merge' => ['array', 'arr1'=>'array', '...args='=>'array'], +'array_merge_recursive' => ['array', 'arr1'=>'array', '...args='=>'array'], +'array_multisort' => ['bool', '&rw_array1'=>'array', 'array1_sort_order='=>'array|int', 'array1_sort_flags='=>'array|int', '...args='=>'array|int'], +'array_pad' => ['array', 'input'=>'array', 'pad_size'=>'int', 'pad_value'=>'mixed'], +'array_pop' => ['mixed', '&rw_stack'=>'array'], +'array_product' => ['int|float', 'input'=>'array'], +'array_push' => ['int', '&rw_stack'=>'array', 'var'=>'mixed', '...vars='=>'mixed'], +'array_rand' => ['int|string|array|array', 'input'=>'array', 'num_req'=>'int'], +'array_rand\'1' => ['int|string', 'input'=>'array'], +'array_reduce' => ['mixed', 'input'=>'array', 'callback'=>'callable', 'initial='=>'mixed'], +'array_replace' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], +'array_replace_recursive' => ['array', 'arr1'=>'array', 'arr2'=>'array', '...args='=>'array'], +'array_reverse' => ['array', 'input'=>'array', 'preserve='=>'bool'], +'array_search' => ['int|string|false', 'needle'=>'mixed', 'haystack'=>'array', 'strict='=>'bool'], +'array_shift' => ['mixed', '&rw_stack'=>'array'], +'array_slice' => ['array', 'input'=>'array', 'offset'=>'int', 'length='=>'?int', 'preserve_keys='=>'bool'], +'array_splice' => ['array', '&rw_input'=>'array', 'offset'=>'int', 'length='=>'int', 'replacement='=>'array|string'], +'array_sum' => ['int|float', 'input'=>'array'], +'array_udiff' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_comp_func'=>'callable'], +'array_udiff\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest='=>'array|callable'], +'array_udiff_assoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'key_comp_func'=>'callable'], +'array_udiff_assoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest='=>'array|callable'], +'array_udiff_uassoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_comp_func'=>'callable', 'key_comp_func'=>'callable'], +'array_udiff_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', 'arg5'=>'array|callable', '...rest='=>'array|callable'], +'array_uintersect' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_compare_func'=>'callable'], +'array_uintersect\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest='=>'array|callable'], +'array_uintersect_assoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_compare_func'=>'callable'], +'array_uintersect_assoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', '...rest='=>'array|callable'], +'array_uintersect_uassoc' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'data_compare_func'=>'callable', 'key_compare_func'=>'callable'], +'array_uintersect_uassoc\'1' => ['array', 'arr1'=>'array', 'arr2'=>'array', 'arr3'=>'array', 'arg4'=>'array|callable', 'arg5'=>'array|callable', '...rest='=>'array|callable'], +'array_unique' => ['array', 'input'=>'array', 'sort_flags='=>'int'], +'array_unshift' => ['int', '&rw_stack'=>'array', 'var'=>'mixed', '...vars='=>'mixed'], +'array_values' => ['array', 'input'=>'array'], +'array_walk' => ['bool', '&rw_input'=>'array', 'callback'=>'callable', 'userdata='=>'mixed'], +'array_walk_recursive' => ['bool', '&rw_input'=>'array', 'callback'=>'callable', 'userdata='=>'mixed'], +'ArrayAccess::offsetExists' => ['bool', 'offset'=>'mixed'], +'ArrayAccess::offsetGet' => ['mixed', 'offset'=>'mixed'], +'ArrayAccess::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], +'ArrayAccess::offsetUnset' => ['void', 'offset'=>'mixed'], +'ArrayIterator::__construct' => ['void', 'array='=>'array|object', 'flags='=>'int'], +'ArrayIterator::append' => ['void', 'value'=>'mixed'], +'ArrayIterator::asort' => ['void'], +'ArrayIterator::count' => ['int'], +'ArrayIterator::current' => ['mixed'], +'ArrayIterator::getArrayCopy' => ['array'], +'ArrayIterator::getFlags' => ['void'], +'ArrayIterator::key' => ['int|string|false'], +'ArrayIterator::ksort' => ['void'], +'ArrayIterator::natcasesort' => ['void'], +'ArrayIterator::natsort' => ['void'], +'ArrayIterator::next' => ['void'], +'ArrayIterator::offsetExists' => ['bool', 'index'=>'string'], +'ArrayIterator::offsetGet' => ['mixed', 'index'=>'string'], +'ArrayIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'mixed'], +'ArrayIterator::offsetUnset' => ['void', 'index'=>'string'], +'ArrayIterator::rewind' => ['void'], +'ArrayIterator::seek' => ['void', 'position'=>'int'], +'ArrayIterator::serialize' => ['string'], +'ArrayIterator::setFlags' => ['void', 'flags'=>'string'], +'ArrayIterator::uasort' => ['void', 'cmp_function'=>'callable'], +'ArrayIterator::uksort' => ['void', 'cmp_function'=>'callable'], +'ArrayIterator::unserialize' => ['string', 'serialized'=>'string'], +'ArrayIterator::valid' => ['bool'], +'ArrayObject::__construct' => ['void', 'input='=>'array|object', 'flags='=>'int', 'iterator_class='=>'string'], +'ArrayObject::append' => ['void', 'value'=>'mixed'], +'ArrayObject::asort' => ['void'], +'ArrayObject::count' => ['int'], +'ArrayObject::exchangeArray' => ['array', 'ar'=>'mixed'], +'ArrayObject::getArrayCopy' => ['array'], +'ArrayObject::getFlags' => ['int'], +'ArrayObject::getIterator' => ['ArrayIterator'], +'ArrayObject::getIteratorClass' => ['string'], +'ArrayObject::ksort' => ['void'], +'ArrayObject::natcasesort' => ['void'], +'ArrayObject::natsort' => ['void'], +'ArrayObject::offsetExists' => ['bool', 'index'=>'mixed'], +'ArrayObject::offsetGet' => ['mixed', 'index'=>'mixed'], +'ArrayObject::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'], +'ArrayObject::offsetUnset' => ['void', 'index'=>'mixed'], +'ArrayObject::serialize' => ['string'], +'ArrayObject::setFlags' => ['void', 'flags'=>'int'], +'ArrayObject::setIteratorClass' => ['void', 'iterator_class'=>'string'], +'ArrayObject::uasort' => ['void', 'cmp_function'=>'callable'], +'ArrayObject::uksort' => ['void', 'cmp_function'=>'callable'], +'ArrayObject::unserialize' => ['void', 'serialized'=>'string'], +'arsort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], +'asin' => ['float', 'number'=>'float'], +'asinh' => ['float', 'number'=>'float'], +'asort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], +'assert' => ['int', 'assertion'=>'string|bool', 'description='=>'string|Throwable|null'], +'assert_options' => ['mixed', 'what'=>'int', 'value='=>'mixed'], +'ast\get_kind_name' => ['string', 'kind'=>'int'], +'ast\get_metadata' => ['array'], +'ast\get_supported_versions' => ['array', 'exclude_deprecated='=>'bool'], +'ast\kind_uses_flags' => ['bool', 'kind'=>'int'], +'ast\Node::__construct' => ['void', 'kind='=>'int', 'flags='=>'int', 'children='=>'ast\Node\Decl[]|ast\Node[]|array[]|int[]|string[]|float[]|bool[]|null[]', 'start_line='=>'int'], +'ast\parse_code' => ['ast\Node', 'code'=>'string', 'version'=>'int', 'filename='=>'string'], +'ast\parse_file' => ['ast\Node', 'filename'=>'string', 'version'=>'int'], +'atan' => ['float', 'number'=>'float'], +'atan2' => ['float', 'y'=>'float', 'x'=>'float'], +'atanh' => ['float', 'number'=>'float'], +'BadFunctionCallException::__clone' => ['void'], +'BadFunctionCallException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?BadFunctionCallException'], +'BadFunctionCallException::__toString' => ['string'], +'BadFunctionCallException::getCode' => ['int'], +'BadFunctionCallException::getFile' => ['string'], +'BadFunctionCallException::getLine' => ['int'], +'BadFunctionCallException::getMessage' => ['string'], +'BadFunctionCallException::getPrevious' => ['?Throwable|?BadFunctionCallException'], +'BadFunctionCallException::getTrace' => ['array'], +'BadFunctionCallException::getTraceAsString' => ['string'], +'BadMethodCallException::__clone' => ['void'], +'BadMethodCallException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?BadMethodCallException'], +'BadMethodCallException::__toString' => ['string'], +'BadMethodCallException::getCode' => ['int'], +'BadMethodCallException::getFile' => ['string'], +'BadMethodCallException::getLine' => ['int'], +'BadMethodCallException::getMessage' => ['string'], +'BadMethodCallException::getPrevious' => ['?Throwable|?BadMethodCallException'], +'BadMethodCallException::getTrace' => ['array'], +'BadMethodCallException::getTraceAsString' => ['string'], +'base64_decode' => ['string|false', 'str'=>'string', 'strict='=>'bool'], +'base64_encode' => ['string', 'str'=>'string'], +'base_convert' => ['string', 'number'=>'string', 'frombase'=>'int', 'tobase'=>'int'], +'basename' => ['string', 'path'=>'string', 'suffix='=>'string'], +'bbcode_add_element' => ['bool', 'bbcode_container'=>'resource', 'tag_name'=>'string', 'tag_rules'=>'array'], +'bbcode_add_smiley' => ['bool', 'bbcode_container'=>'resource', 'smiley'=>'string', 'replace_by'=>'string'], +'bbcode_create' => ['resource', 'bbcode_initial_tags='=>'array'], +'bbcode_destroy' => ['bool', 'bbcode_container'=>'resource'], +'bbcode_parse' => ['string', 'bbcode_container'=>'resource', 'to_parse'=>'string'], +'bbcode_set_arg_parser' => ['bool', 'bbcode_container'=>'resource', 'bbcode_arg_parser'=>'resource'], +'bbcode_set_flags' => ['bool', 'bbcode_container'=>'resource', 'flags'=>'int', 'mode='=>'int'], +'bcadd' => ['string', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], +'bccomp' => ['int', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], +'bcdiv' => ['string', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], +'bcmod' => ['string', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], +'bcmul' => ['string', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], +'bcompiler_load' => ['bool', 'filename'=>'string'], +'bcompiler_load_exe' => ['bool', 'filename'=>'string'], +'bcompiler_parse_class' => ['bool', 'class'=>'string', 'callback'=>'string'], +'bcompiler_read' => ['bool', 'filehandle'=>'resource'], +'bcompiler_write_class' => ['bool', 'filehandle'=>'resource', 'classname'=>'string', 'extends='=>'string'], +'bcompiler_write_constant' => ['bool', 'filehandle'=>'resource', 'constantname'=>'string'], +'bcompiler_write_exe_footer' => ['bool', 'filehandle'=>'resource', 'startpos'=>'int'], +'bcompiler_write_file' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'], +'bcompiler_write_footer' => ['bool', 'filehandle'=>'resource'], +'bcompiler_write_function' => ['bool', 'filehandle'=>'resource', 'functionname'=>'string'], +'bcompiler_write_functions_from_file' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'], +'bcompiler_write_header' => ['bool', 'filehandle'=>'resource', 'write_ver='=>'string'], +'bcompiler_write_included_filename' => ['bool', 'filehandle'=>'resource', 'filename'=>'string'], +'bcpow' => ['string', 'base'=>'string', 'exponent'=>'string', 'scale='=>'int'], +'bcpowmod' => ['string', 'base'=>'string', 'exponent'=>'string', 'modulus'=>'string', 'scale='=>'int'], +'bcscale' => ['bool', 'scale'=>'int'], +'bcsqrt' => ['string', 'operand'=>'string', 'scale='=>'int'], +'bcsub' => ['string', 'left_operand'=>'string', 'right_operand'=>'string', 'scale='=>'int'], +'bin2hex' => ['string', 'data'=>'string'], +'bind_textdomain_codeset' => ['string', 'domain'=>'string', 'codeset'=>'string'], +'bindec' => ['int', 'binary_number'=>'string'], +'bindtextdomain' => ['string', 'domain_name'=>'string', 'dir'=>'string'], +'birdstep_autocommit' => ['bool', 'index'=>'int'], +'birdstep_close' => ['bool', 'id'=>'int'], +'birdstep_commit' => ['bool', 'index'=>'int'], +'birdstep_connect' => ['int', 'server'=>'string', 'user'=>'string', 'pass'=>'string'], +'birdstep_exec' => ['int', 'index'=>'int', 'exec_str'=>'string'], +'birdstep_fetch' => ['bool', 'index'=>'int'], +'birdstep_fieldname' => ['string', 'index'=>'int', 'col'=>'int'], +'birdstep_fieldnum' => ['int', 'index'=>'int'], +'birdstep_freeresult' => ['bool', 'index'=>'int'], +'birdstep_off_autocommit' => ['bool', 'index'=>'int'], +'birdstep_result' => ['', 'index'=>'int', 'col'=>''], +'birdstep_rollback' => ['bool', 'index'=>'int'], +'blenc_encrypt' => ['string', 'plaintext'=>'string', 'encodedfile'=>'string', 'encryption_key='=>'string'], +'boolval' => ['bool', 'var'=>'mixed'], +'BSON\Binary::__construct' => ['void', 'data'=>'string', 'subtype'=>'string'], +'BSON\Binary::getSubType' => [''], +'BSON\fromArray' => ['string', 'array'=>'string'], +'BSON\fromJSON' => ['string', 'json'=>'string'], +'BSON\Javascript::__construct' => ['void', 'javascript'=>'string', 'scope='=>'string'], +'BSON\ObjectID::__construct' => ['void', 'id='=>'string'], +'BSON\ObjectID::__toString' => ['string'], +'BSON\Regex::__construct' => ['void', 'pattern'=>'string', 'flags'=>'string'], +'BSON\Regex::__toString' => ['string'], +'BSON\Regex::getFlags' => [''], +'BSON\Regex::getPattern' => [''], +'BSON\Serializable::bsonSerialize' => ['string'], +'BSON\Timestamp::__construct' => ['void', 'increment'=>'string', 'timestamp'=>'string'], +'BSON\Timestamp::__toString' => ['string'], +'BSON\toArray' => ['array', 'bson'=>'string'], +'BSON\toJSON' => ['string', 'bson'=>'string'], +'BSON\Unserializable::bsonUnserialize' => ['', 'data'=>'array'], +'BSON\UTCDatetime::__construct' => ['void', 'milliseconds'=>'string'], +'BSON\UTCDatetime::__toString' => ['string'], +'BSON\UTCDatetime::toDateTime' => [''], +'bson_decode' => ['array', 'bson'=>'string'], +'bson_encode' => ['string', 'anything'=>'mixed'], +'bzclose' => ['int', 'bz'=>'resource'], +'bzcompress' => ['string', 'source'=>'string', 'blocksize100k='=>'int', 'workfactor='=>'int'], +'bzdecompress' => ['string', 'source'=>'string', 'small='=>'int'], +'bzerrno' => ['int', 'bz'=>'resource'], +'bzerror' => ['array', 'bz'=>'resource'], +'bzerrstr' => ['string', 'bz'=>'resource'], +'bzflush' => ['int', 'bz'=>'resource'], +'bzopen' => ['resource', 'file'=>'string|resource', 'mode'=>'string'], +'bzread' => ['string', 'bz'=>'resource', 'length='=>'int'], +'bzwrite' => ['int', 'bz'=>'resource', 'data'=>'string', 'length='=>'int'], +'CachingIterator::__construct' => ['void', 'it'=>'iterator', 'flags='=>''], +'CachingIterator::__toString' => ['string'], +'CachingIterator::count' => ['int'], +'CachingIterator::current' => ['void'], +'CachingIterator::getCache' => ['array'], +'CachingIterator::getFlags' => ['int'], +'CachingIterator::getInnerIterator' => ['Iterator'], +'CachingIterator::hasNext' => ['bool'], +'CachingIterator::key' => ['mixed'], +'CachingIterator::next' => ['void'], +'CachingIterator::offsetExists' => ['bool', 'index'=>'string'], +'CachingIterator::offsetGet' => ['mixed', 'index'=>'string'], +'CachingIterator::offsetSet' => ['void', 'index'=>'string', 'newval'=>'mixed'], +'CachingIterator::offsetUnset' => ['void', 'index'=>'string'], +'CachingIterator::rewind' => ['void'], +'CachingIterator::setFlags' => ['void', 'flags'=>'int'], +'CachingIterator::valid' => ['bool'], +'Cairo::availableFonts' => ['array'], +'Cairo::availableSurfaces' => ['array'], +'Cairo::statusToString' => ['string', 'status'=>'int'], +'Cairo::version' => ['int'], +'Cairo::versionString' => ['string'], +'cairo_append_path' => ['', 'path'=>'cairopath', 'context'=>'cairocontext'], +'cairo_arc' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'], +'cairo_arc_negative' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'], +'cairo_available_fonts' => ['array'], +'cairo_available_surfaces' => ['array'], +'cairo_clip' => ['', 'context'=>'cairocontext'], +'cairo_clip_extents' => ['array', 'context'=>'cairocontext'], +'cairo_clip_preserve' => ['', 'context'=>'cairocontext'], +'cairo_clip_rectangle_list' => ['array', 'context'=>'cairocontext'], +'cairo_close_path' => ['', 'context'=>'cairocontext'], +'cairo_copy_page' => ['', 'context'=>'cairocontext'], +'cairo_copy_path' => ['CairoPath', 'context'=>'cairocontext'], +'cairo_copy_path_flat' => ['CairoPath', 'context'=>'cairocontext'], +'cairo_create' => ['CairoContext', 'surface'=>'cairosurface'], +'cairo_curve_to' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float', 'context'=>'cairocontext'], +'cairo_device_to_user' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'], +'cairo_device_to_user_distance' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'], +'cairo_fill' => ['', 'context'=>'cairocontext'], +'cairo_fill_extents' => ['array', 'context'=>'cairocontext'], +'cairo_fill_preserve' => ['', 'context'=>'cairocontext'], +'cairo_font_extents' => ['array', 'context'=>'cairocontext'], +'cairo_font_face_get_type' => ['int', 'fontface'=>'cairofontface'], +'cairo_font_face_status' => ['int', 'fontface'=>'cairofontface'], +'cairo_font_options_create' => ['CairoFontOptions'], +'cairo_font_options_equal' => ['bool', 'options'=>'cairofontoptions', 'other'=>'cairofontoptions'], +'cairo_font_options_get_antialias' => ['int', 'options'=>'cairofontoptions'], +'cairo_font_options_get_hint_metrics' => ['int', 'options'=>'cairofontoptions'], +'cairo_font_options_get_hint_style' => ['int', 'options'=>'cairofontoptions'], +'cairo_font_options_get_subpixel_order' => ['int', 'options'=>'cairofontoptions'], +'cairo_font_options_hash' => ['int', 'options'=>'cairofontoptions'], +'cairo_font_options_merge' => ['void', 'options'=>'cairofontoptions', 'other'=>'cairofontoptions'], +'cairo_font_options_set_antialias' => ['void', 'options'=>'cairofontoptions', 'antialias'=>'int'], +'cairo_font_options_set_hint_metrics' => ['void', 'options'=>'cairofontoptions', 'hint_metrics'=>'int'], +'cairo_font_options_set_hint_style' => ['void', 'options'=>'cairofontoptions', 'hint_style'=>'int'], +'cairo_font_options_set_subpixel_order' => ['void', 'options'=>'cairofontoptions', 'subpixel_order'=>'int'], +'cairo_font_options_status' => ['int', 'options'=>'cairofontoptions'], +'cairo_format_stride_for_width' => ['int', 'format'=>'int', 'width'=>'int'], +'cairo_get_antialias' => ['int', 'context'=>'cairocontext'], +'cairo_get_current_point' => ['array', 'context'=>'cairocontext'], +'cairo_get_dash' => ['array', 'context'=>'cairocontext'], +'cairo_get_dash_count' => ['int', 'context'=>'cairocontext'], +'cairo_get_fill_rule' => ['int', 'context'=>'cairocontext'], +'cairo_get_font_face' => ['', 'context'=>'cairocontext'], +'cairo_get_font_matrix' => ['', 'context'=>'cairocontext'], +'cairo_get_font_options' => ['', 'context'=>'cairocontext'], +'cairo_get_group_target' => ['', 'context'=>'cairocontext'], +'cairo_get_line_cap' => ['int', 'context'=>'cairocontext'], +'cairo_get_line_join' => ['int', 'context'=>'cairocontext'], +'cairo_get_line_width' => ['float', 'context'=>'cairocontext'], +'cairo_get_matrix' => ['', 'context'=>'cairocontext'], +'cairo_get_miter_limit' => ['float', 'context'=>'cairocontext'], +'cairo_get_operator' => ['int', 'context'=>'cairocontext'], +'cairo_get_scaled_font' => ['', 'context'=>'cairocontext'], +'cairo_get_source' => ['', 'context'=>'cairocontext'], +'cairo_get_target' => ['', 'context'=>'cairocontext'], +'cairo_get_tolerance' => ['float', 'context'=>'cairocontext'], +'cairo_glyph_path' => ['', 'glyphs'=>'array', 'context'=>'cairocontext'], +'cairo_has_current_point' => ['bool', 'context'=>'cairocontext'], +'cairo_identity_matrix' => ['', 'context'=>'cairocontext'], +'cairo_image_surface_create' => ['CairoImageSurface', 'format'=>'int', 'width'=>'int', 'height'=>'int'], +'cairo_image_surface_create_for_data' => ['CairoImageSurface', 'data'=>'string', 'format'=>'int', 'width'=>'int', 'height'=>'int', 'stride='=>'int'], +'cairo_image_surface_create_from_png' => ['CairoImageSurface', 'file'=>'string'], +'cairo_image_surface_get_data' => ['string', 'surface'=>'cairoimagesurface'], +'cairo_image_surface_get_format' => ['int', 'surface'=>'cairoimagesurface'], +'cairo_image_surface_get_height' => ['int', 'surface'=>'cairoimagesurface'], +'cairo_image_surface_get_stride' => ['int', 'surface'=>'cairoimagesurface'], +'cairo_image_surface_get_width' => ['int', 'surface'=>'cairoimagesurface'], +'cairo_in_fill' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_in_stroke' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_line_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_mask' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'], +'cairo_mask_surface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'], +'cairo_matrix_create_scale' => ['object', 'sx'=>'float', 'sy'=>'float'], +'cairo_matrix_init' => ['object', 'xx='=>'float', 'yx='=>'float', 'xy='=>'float', 'yy='=>'float', 'x0='=>'float', 'y0='=>'float'], +'cairo_matrix_init_identity' => ['object'], +'cairo_matrix_init_rotate' => ['object', 'radians'=>'float'], +'cairo_matrix_init_scale' => ['object', 'sx'=>'float', 'sy'=>'float'], +'cairo_matrix_init_translate' => ['object', 'tx'=>'float', 'ty'=>'float'], +'cairo_matrix_invert' => ['void', 'matrix'=>'cairomatrix'], +'cairo_matrix_multiply' => ['CairoMatrix', 'matrix1'=>'cairomatrix', 'matrix2'=>'cairomatrix'], +'cairo_matrix_rotate' => ['', 'matrix'=>'cairomatrix', 'radians'=>'float'], +'cairo_matrix_scale' => ['', 'sx'=>'float', 'sy'=>'float', 'context'=>'cairocontext'], +'cairo_matrix_transform_distance' => ['array', 'matrix'=>'cairomatrix', 'dx'=>'float', 'dy'=>'float'], +'cairo_matrix_transform_point' => ['array', 'matrix'=>'cairomatrix', 'dx'=>'float', 'dy'=>'float'], +'cairo_matrix_translate' => ['void', 'matrix'=>'cairomatrix', 'tx'=>'float', 'ty'=>'float'], +'cairo_move_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_new_path' => ['', 'context'=>'cairocontext'], +'cairo_new_sub_path' => ['', 'context'=>'cairocontext'], +'cairo_paint' => ['', 'context'=>'cairocontext'], +'cairo_paint_with_alpha' => ['', 'alpha'=>'string', 'context'=>'cairocontext'], +'cairo_path_extents' => ['array', 'context'=>'cairocontext'], +'cairo_pattern_add_color_stop_rgb' => ['void', 'pattern'=>'cairogradientpattern', 'offset'=>'float', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], +'cairo_pattern_add_color_stop_rgba' => ['void', 'pattern'=>'cairogradientpattern', 'offset'=>'float', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha'=>'float'], +'cairo_pattern_create_for_surface' => ['CairoPattern', 'surface'=>'cairosurface'], +'cairo_pattern_create_linear' => ['CairoPattern', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float'], +'cairo_pattern_create_radial' => ['CairoPattern', 'x0'=>'float', 'y0'=>'float', 'r0'=>'float', 'x1'=>'float', 'y1'=>'float', 'r1'=>'float'], +'cairo_pattern_create_rgb' => ['CairoPattern', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], +'cairo_pattern_create_rgba' => ['CairoPattern', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha'=>'float'], +'cairo_pattern_get_color_stop_count' => ['int', 'pattern'=>'cairogradientpattern'], +'cairo_pattern_get_color_stop_rgba' => ['array', 'pattern'=>'cairogradientpattern', 'index'=>'int'], +'cairo_pattern_get_extend' => ['int', 'pattern'=>'string'], +'cairo_pattern_get_filter' => ['int', 'pattern'=>'cairosurfacepattern'], +'cairo_pattern_get_linear_points' => ['array', 'pattern'=>'cairolineargradient'], +'cairo_pattern_get_matrix' => ['CairoMatrix', 'pattern'=>'cairopattern'], +'cairo_pattern_get_radial_circles' => ['array', 'pattern'=>'cairoradialgradient'], +'cairo_pattern_get_rgba' => ['array', 'pattern'=>'cairosolidpattern'], +'cairo_pattern_get_surface' => ['CairoSurface', 'pattern'=>'cairosurfacepattern'], +'cairo_pattern_get_type' => ['int', 'pattern'=>'cairopattern'], +'cairo_pattern_set_extend' => ['void', 'pattern'=>'string', 'extend'=>'string'], +'cairo_pattern_set_filter' => ['void', 'pattern'=>'cairosurfacepattern', 'filter'=>'int'], +'cairo_pattern_set_matrix' => ['void', 'pattern'=>'cairopattern', 'matrix'=>'cairomatrix'], +'cairo_pattern_status' => ['int', 'pattern'=>'cairopattern'], +'cairo_pdf_surface_create' => ['CairoPdfSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'], +'cairo_pdf_surface_set_size' => ['void', 'surface'=>'cairopdfsurface', 'width'=>'float', 'height'=>'float'], +'cairo_pop_group' => ['', 'context'=>'cairocontext'], +'cairo_pop_group_to_source' => ['', 'context'=>'cairocontext'], +'cairo_ps_get_levels' => ['array'], +'cairo_ps_level_to_string' => ['string', 'level'=>'int'], +'cairo_ps_surface_create' => ['CairoPsSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'], +'cairo_ps_surface_dsc_begin_page_setup' => ['void', 'surface'=>'cairopssurface'], +'cairo_ps_surface_dsc_begin_setup' => ['void', 'surface'=>'cairopssurface'], +'cairo_ps_surface_dsc_comment' => ['void', 'surface'=>'cairopssurface', 'comment'=>'string'], +'cairo_ps_surface_get_eps' => ['bool', 'surface'=>'cairopssurface'], +'cairo_ps_surface_restrict_to_level' => ['void', 'surface'=>'cairopssurface', 'level'=>'int'], +'cairo_ps_surface_set_eps' => ['void', 'surface'=>'cairopssurface', 'level'=>'bool'], +'cairo_ps_surface_set_size' => ['void', 'surface'=>'cairopssurface', 'width'=>'float', 'height'=>'float'], +'cairo_push_group' => ['', 'context'=>'cairocontext'], +'cairo_push_group_with_content' => ['', 'content'=>'string', 'context'=>'cairocontext'], +'cairo_rectangle' => ['', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string', 'context'=>'cairocontext'], +'cairo_rel_curve_to' => ['', 'x1'=>'string', 'y1'=>'string', 'x2'=>'string', 'y2'=>'string', 'x3'=>'string', 'y3'=>'string', 'context'=>'cairocontext'], +'cairo_rel_line_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_rel_move_to' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_reset_clip' => ['', 'context'=>'cairocontext'], +'cairo_restore' => ['', 'context'=>'cairocontext'], +'cairo_rotate' => ['', 'sx'=>'string', 'sy'=>'string', 'context'=>'cairocontext', 'angle'=>'string'], +'cairo_save' => ['', 'context'=>'cairocontext'], +'cairo_scale' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_scaled_font_create' => ['CairoScaledFont', 'fontface'=>'cairofontface', 'matrix'=>'cairomatrix', 'ctm'=>'cairomatrix', 'fontoptions'=>'cairofontoptions'], +'cairo_scaled_font_extents' => ['array', 'scaledfont'=>'cairoscaledfont'], +'cairo_scaled_font_get_ctm' => ['CairoMatrix', 'scaledfont'=>'cairoscaledfont'], +'cairo_scaled_font_get_font_face' => ['CairoFontFace', 'scaledfont'=>'cairoscaledfont'], +'cairo_scaled_font_get_font_matrix' => ['CairoFontOptions', 'scaledfont'=>'cairoscaledfont'], +'cairo_scaled_font_get_font_options' => ['CairoFontOptions', 'scaledfont'=>'cairoscaledfont'], +'cairo_scaled_font_get_scale_matrix' => ['CairoMatrix', 'scaledfont'=>'cairoscaledfont'], +'cairo_scaled_font_get_type' => ['int', 'scaledfont'=>'cairoscaledfont'], +'cairo_scaled_font_glyph_extents' => ['array', 'scaledfont'=>'cairoscaledfont', 'glyphs'=>'array'], +'cairo_scaled_font_status' => ['int', 'scaledfont'=>'cairoscaledfont'], +'cairo_scaled_font_text_extents' => ['array', 'scaledfont'=>'cairoscaledfont', 'text'=>'string'], +'cairo_select_font_face' => ['', 'family'=>'string', 'slant='=>'string', 'weight='=>'string', 'context='=>'cairocontext'], +'cairo_set_antialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'], +'cairo_set_dash' => ['', 'dashes'=>'array', 'offset='=>'string', 'context='=>'cairocontext'], +'cairo_set_fill_rule' => ['', 'setting'=>'string', 'context'=>'cairocontext'], +'cairo_set_font_face' => ['', 'fontface'=>'cairofontface', 'context'=>'cairocontext'], +'cairo_set_font_matrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], +'cairo_set_font_options' => ['', 'fontoptions'=>'cairofontoptions', 'context'=>'cairocontext'], +'cairo_set_font_size' => ['', 'size'=>'string', 'context'=>'cairocontext'], +'cairo_set_line_cap' => ['', 'setting'=>'string', 'context'=>'cairocontext'], +'cairo_set_line_join' => ['', 'setting'=>'string', 'context'=>'cairocontext'], +'cairo_set_line_width' => ['', 'width'=>'string', 'context'=>'cairocontext'], +'cairo_set_matrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], +'cairo_set_miter_limit' => ['', 'limit'=>'string', 'context'=>'cairocontext'], +'cairo_set_operator' => ['', 'setting'=>'string', 'context'=>'cairocontext'], +'cairo_set_scaled_font' => ['', 'scaledfont'=>'cairoscaledfont', 'context'=>'cairocontext'], +'cairo_set_source' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'], +'cairo_set_source_surface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'], +'cairo_set_tolerance' => ['', 'tolerance'=>'string', 'context'=>'cairocontext'], +'cairo_show_page' => ['', 'context'=>'cairocontext'], +'cairo_show_text' => ['', 'text'=>'string', 'context'=>'cairocontext'], +'cairo_status' => ['int', 'context'=>'cairocontext'], +'cairo_status_to_string' => ['string', 'status'=>'int'], +'cairo_stroke' => ['', 'context'=>'cairocontext'], +'cairo_stroke_extents' => ['array', 'context'=>'cairocontext'], +'cairo_stroke_preserve' => ['', 'context'=>'cairocontext'], +'cairo_surface_copy_page' => ['void', 'surface'=>'cairosurface'], +'cairo_surface_create_similar' => ['CairoSurface', 'surface'=>'cairosurface', 'content'=>'int', 'width'=>'float', 'height'=>'float'], +'cairo_surface_finish' => ['void', 'surface'=>'cairosurface'], +'cairo_surface_flush' => ['void', 'surface'=>'cairosurface'], +'cairo_surface_get_content' => ['int', 'surface'=>'cairosurface'], +'cairo_surface_get_device_offset' => ['array', 'surface'=>'cairosurface'], +'cairo_surface_get_font_options' => ['CairoFontOptions', 'surface'=>'cairosurface'], +'cairo_surface_get_type' => ['int', 'surface'=>'cairosurface'], +'cairo_surface_mark_dirty' => ['void', 'surface'=>'cairosurface'], +'cairo_surface_mark_dirty_rectangle' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], +'cairo_surface_set_device_offset' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float'], +'cairo_surface_set_fallback_resolution' => ['void', 'surface'=>'cairosurface', 'x'=>'float', 'y'=>'float'], +'cairo_surface_show_page' => ['void', 'surface'=>'cairosurface'], +'cairo_surface_status' => ['int', 'surface'=>'cairosurface'], +'cairo_surface_write_to_png' => ['void', 'surface'=>'cairosurface', 'stream'=>'resource'], +'cairo_svg_get_versions' => ['array'], +'cairo_svg_surface_create' => ['CairoSvgSurface', 'file'=>'string', 'width'=>'float', 'height'=>'float'], +'cairo_svg_surface_get_versions' => ['array'], +'cairo_svg_surface_restrict_to_version' => ['void', 'surface'=>'cairosvgsurface', 'version'=>'int'], +'cairo_svg_version_to_string' => ['string', 'version'=>'int'], +'cairo_text_extents' => ['array', 'text'=>'string', 'context'=>'cairocontext'], +'cairo_text_path' => ['', 'string'=>'string', 'context'=>'cairocontext', 'text'=>'string'], +'cairo_transform' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], +'cairo_translate' => ['', 'tx'=>'string', 'ty'=>'string', 'context'=>'cairocontext', 'x'=>'string', 'y'=>'string'], +'cairo_user_to_device' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_user_to_device_distance' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'cairo_version' => ['int'], +'cairo_version_string' => ['string'], +'CairoContext::__construct' => ['void', 'surface'=>'CairoSurface'], +'CairoContext::appendPath' => ['', 'path'=>'cairopath', 'context'=>'cairocontext'], +'CairoContext::arc' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'], +'CairoContext::arcNegative' => ['', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'angle1'=>'float', 'angle2'=>'float', 'context'=>'cairocontext'], +'CairoContext::clip' => ['', 'context'=>'cairocontext'], +'CairoContext::clipExtents' => ['array', 'context'=>'cairocontext'], +'CairoContext::clipPreserve' => ['', 'context'=>'cairocontext'], +'CairoContext::clipRectangleList' => ['array', 'context'=>'cairocontext'], +'CairoContext::closePath' => ['', 'context'=>'cairocontext'], +'CairoContext::copyPage' => ['', 'context'=>'cairocontext'], +'CairoContext::copyPath' => ['CairoPath', 'context'=>'cairocontext'], +'CairoContext::copyPathFlat' => ['CairoPath', 'context'=>'cairocontext'], +'CairoContext::curveTo' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float', 'context'=>'cairocontext'], +'CairoContext::deviceToUser' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'], +'CairoContext::deviceToUserDistance' => ['array', 'x'=>'float', 'y'=>'float', 'context'=>'cairocontext'], +'CairoContext::fill' => ['', 'context'=>'cairocontext'], +'CairoContext::fillExtents' => ['array', 'context'=>'cairocontext'], +'CairoContext::fillPreserve' => ['', 'context'=>'cairocontext'], +'CairoContext::fontExtents' => ['array', 'context'=>'cairocontext'], +'CairoContext::getAntialias' => ['int', 'context'=>'cairocontext'], +'CairoContext::getCurrentPoint' => ['array', 'context'=>'cairocontext'], +'CairoContext::getDash' => ['array', 'context'=>'cairocontext'], +'CairoContext::getDashCount' => ['int', 'context'=>'cairocontext'], +'CairoContext::getFillRule' => ['int', 'context'=>'cairocontext'], +'CairoContext::getFontFace' => ['', 'context'=>'cairocontext'], +'CairoContext::getFontMatrix' => ['', 'context'=>'cairocontext'], +'CairoContext::getFontOptions' => ['', 'context'=>'cairocontext'], +'CairoContext::getGroupTarget' => ['', 'context'=>'cairocontext'], +'CairoContext::getLineCap' => ['int', 'context'=>'cairocontext'], +'CairoContext::getLineJoin' => ['int', 'context'=>'cairocontext'], +'CairoContext::getLineWidth' => ['float', 'context'=>'cairocontext'], +'CairoContext::getMatrix' => ['', 'context'=>'cairocontext'], +'CairoContext::getMiterLimit' => ['float', 'context'=>'cairocontext'], +'CairoContext::getOperator' => ['int', 'context'=>'cairocontext'], +'CairoContext::getScaledFont' => ['', 'context'=>'cairocontext'], +'CairoContext::getSource' => ['', 'context'=>'cairocontext'], +'CairoContext::getTarget' => ['', 'context'=>'cairocontext'], +'CairoContext::getTolerance' => ['float', 'context'=>'cairocontext'], +'CairoContext::glyphPath' => ['', 'glyphs'=>'array', 'context'=>'cairocontext'], +'CairoContext::hasCurrentPoint' => ['bool', 'context'=>'cairocontext'], +'CairoContext::identityMatrix' => ['', 'context'=>'cairocontext'], +'CairoContext::inFill' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::inStroke' => ['bool', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::lineTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::mask' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'], +'CairoContext::maskSurface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'], +'CairoContext::moveTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::newPath' => ['', 'context'=>'cairocontext'], +'CairoContext::newSubPath' => ['', 'context'=>'cairocontext'], +'CairoContext::paint' => ['', 'context'=>'cairocontext'], +'CairoContext::paintWithAlpha' => ['', 'alpha'=>'string', 'context'=>'cairocontext'], +'CairoContext::pathExtents' => ['array', 'context'=>'cairocontext'], +'CairoContext::popGroup' => ['', 'context'=>'cairocontext'], +'CairoContext::popGroupToSource' => ['', 'context'=>'cairocontext'], +'CairoContext::pushGroup' => ['', 'context'=>'cairocontext'], +'CairoContext::pushGroupWithContent' => ['', 'content'=>'string', 'context'=>'cairocontext'], +'CairoContext::rectangle' => ['', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string', 'context'=>'cairocontext'], +'CairoContext::relCurveTo' => ['', 'x1'=>'string', 'y1'=>'string', 'x2'=>'string', 'y2'=>'string', 'x3'=>'string', 'y3'=>'string', 'context'=>'cairocontext'], +'CairoContext::relLineTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::relMoveTo' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::resetClip' => ['', 'context'=>'cairocontext'], +'CairoContext::restore' => ['', 'context'=>'cairocontext'], +'CairoContext::rotate' => ['', 'angle'=>'string', 'context'=>'cairocontext'], +'CairoContext::save' => ['', 'context'=>'cairocontext'], +'CairoContext::scale' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::selectFontFace' => ['', 'family'=>'string', 'slant='=>'string', 'weight='=>'string', 'context='=>'cairocontext'], +'CairoContext::setAntialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'], +'CairoContext::setDash' => ['', 'dashes'=>'array', 'offset='=>'string', 'context='=>'cairocontext'], +'CairoContext::setFillRule' => ['', 'setting'=>'string', 'context'=>'cairocontext'], +'CairoContext::setFontFace' => ['', 'fontface'=>'cairofontface', 'context'=>'cairocontext'], +'CairoContext::setFontMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], +'CairoContext::setFontOptions' => ['', 'fontoptions'=>'cairofontoptions', 'context'=>'cairocontext'], +'CairoContext::setFontSize' => ['', 'size'=>'string', 'context'=>'cairocontext'], +'CairoContext::setLineCap' => ['', 'setting'=>'string', 'context'=>'cairocontext'], +'CairoContext::setLineJoin' => ['', 'setting'=>'string', 'context'=>'cairocontext'], +'CairoContext::setLineWidth' => ['', 'width'=>'string', 'context'=>'cairocontext'], +'CairoContext::setMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], +'CairoContext::setMiterLimit' => ['', 'limit'=>'string', 'context'=>'cairocontext'], +'CairoContext::setOperator' => ['', 'setting'=>'string', 'context'=>'cairocontext'], +'CairoContext::setScaledFont' => ['', 'scaledfont'=>'cairoscaledfont', 'context'=>'cairocontext'], +'CairoContext::setSource' => ['', 'pattern'=>'cairopattern', 'context'=>'cairocontext'], +'CairoContext::setSourceRGB' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'], +'CairoContext::setSourceRGBA' => ['', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string', 'context'=>'cairocontext', 'pattern'=>'cairopattern'], +'CairoContext::setSourceSurface' => ['', 'surface'=>'cairosurface', 'x='=>'string', 'y='=>'string', 'context='=>'cairocontext'], +'CairoContext::setTolerance' => ['', 'tolerance'=>'string', 'context'=>'cairocontext'], +'CairoContext::showPage' => ['', 'context'=>'cairocontext'], +'CairoContext::showText' => ['', 'text'=>'string', 'context'=>'cairocontext'], +'CairoContext::status' => ['int', 'context'=>'cairocontext'], +'CairoContext::stroke' => ['', 'context'=>'cairocontext'], +'CairoContext::strokeExtents' => ['array', 'context'=>'cairocontext'], +'CairoContext::strokePreserve' => ['', 'context'=>'cairocontext'], +'CairoContext::textExtents' => ['array', 'text'=>'string', 'context'=>'cairocontext'], +'CairoContext::textPath' => ['', 'string'=>'string', 'context'=>'cairocontext', 'text'=>'string'], +'CairoContext::transform' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], +'CairoContext::translate' => ['', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::userToDevice' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoContext::userToDeviceDistance' => ['array', 'x'=>'string', 'y'=>'string', 'context'=>'cairocontext'], +'CairoFontFace::__construct' => ['void'], +'CairoFontFace::getType' => ['int'], +'CairoFontFace::status' => ['int', 'fontface'=>'cairofontface'], +'CairoFontOptions::__construct' => ['void'], +'CairoFontOptions::equal' => ['bool', 'other'=>'string'], +'CairoFontOptions::getAntialias' => ['int', 'context'=>'cairocontext'], +'CairoFontOptions::getHintMetrics' => ['int'], +'CairoFontOptions::getHintStyle' => ['int'], +'CairoFontOptions::getSubpixelOrder' => ['int'], +'CairoFontOptions::hash' => ['int'], +'CairoFontOptions::merge' => ['void', 'other'=>'string'], +'CairoFontOptions::setAntialias' => ['', 'antialias='=>'string', 'context='=>'cairocontext'], +'CairoFontOptions::setHintMetrics' => ['void', 'hint_metrics'=>'string'], +'CairoFontOptions::setHintStyle' => ['void', 'hint_style'=>'string'], +'CairoFontOptions::setSubpixelOrder' => ['void', 'subpixel_order'=>'string'], +'CairoFontOptions::status' => ['int', 'context'=>'cairocontext'], +'CairoFormat::strideForWidth' => ['int', 'format'=>'int', 'width'=>'int'], +'CairoGradientPattern::addColorStopRgb' => ['void', 'offset'=>'string', 'red'=>'string', 'green'=>'string', 'blue'=>'string'], +'CairoGradientPattern::addColorStopRgba' => ['void', 'offset'=>'string', 'red'=>'string', 'green'=>'string', 'blue'=>'string', 'alpha'=>'string'], +'CairoGradientPattern::getColorStopCount' => ['int'], +'CairoGradientPattern::getColorStopRgba' => ['array', 'index'=>'string'], +'CairoGradientPattern::getExtend' => ['int'], +'CairoGradientPattern::setExtend' => ['void', 'extend'=>'int'], +'CairoImageSurface::__construct' => ['void', 'format'=>'int', 'width'=>'int', 'height'=>'int'], +'CairoImageSurface::createForData' => ['void', 'data'=>'string', 'format'=>'int', 'width'=>'int', 'height'=>'int', 'stride='=>'int'], +'CairoImageSurface::createFromPng' => ['CairoImageSurface', 'file'=>'string'], +'CairoImageSurface::getData' => ['string'], +'CairoImageSurface::getFormat' => ['int'], +'CairoImageSurface::getHeight' => ['int'], +'CairoImageSurface::getStride' => ['int'], +'CairoImageSurface::getWidth' => ['int'], +'CairoLinearGradient::__construct' => ['void', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float'], +'CairoLinearGradient::getPoints' => ['array'], +'CairoMatrix::__construct' => ['void', 'xx='=>'float', 'yx='=>'float', 'xy='=>'float', 'yy='=>'float', 'x0='=>'float', 'y0='=>'float'], +'CairoMatrix::initIdentity' => ['object'], +'CairoMatrix::initRotate' => ['object', 'radians'=>'float'], +'CairoMatrix::initScale' => ['object', 'sx'=>'float', 'sy'=>'float'], +'CairoMatrix::initTranslate' => ['object', 'tx'=>'float', 'ty'=>'float'], +'CairoMatrix::invert' => ['void'], +'CairoMatrix::multiply' => ['CairoMatrix', 'matrix1'=>'cairomatrix', 'matrix2'=>'cairomatrix'], +'CairoMatrix::rotate' => ['', 'sx'=>'string', 'sy'=>'string', 'context'=>'cairocontext', 'angle'=>'string'], +'CairoMatrix::scale' => ['', 'sx'=>'float', 'sy'=>'float', 'context'=>'cairocontext'], +'CairoMatrix::transformDistance' => ['array', 'dx'=>'string', 'dy'=>'string'], +'CairoMatrix::transformPoint' => ['array', 'dx'=>'string', 'dy'=>'string'], +'CairoMatrix::translate' => ['', 'tx'=>'string', 'ty'=>'string', 'context'=>'cairocontext', 'x'=>'string', 'y'=>'string'], +'CairoPattern::__construct' => ['void'], +'CairoPattern::getMatrix' => ['', 'context'=>'cairocontext'], +'CairoPattern::getType' => ['int'], +'CairoPattern::setMatrix' => ['', 'matrix'=>'cairomatrix', 'context'=>'cairocontext'], +'CairoPattern::status' => ['int', 'context'=>'cairocontext'], +'CairoPdfSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'], +'CairoPdfSurface::setSize' => ['void', 'width'=>'string', 'height'=>'string'], +'CairoPsSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'], +'CairoPsSurface::dscBeginPageSetup' => ['void'], +'CairoPsSurface::dscBeginSetup' => ['void'], +'CairoPsSurface::dscComment' => ['void', 'comment'=>'string'], +'CairoPsSurface::getEps' => ['bool'], +'CairoPsSurface::getLevels' => ['array'], +'CairoPsSurface::levelToString' => ['string', 'level'=>'int'], +'CairoPsSurface::restrictToLevel' => ['void', 'level'=>'string'], +'CairoPsSurface::setEps' => ['void', 'level'=>'string'], +'CairoPsSurface::setSize' => ['void', 'width'=>'string', 'height'=>'string'], +'CairoRadialGradient::__construct' => ['void', 'x0'=>'float', 'y0'=>'float', 'r0'=>'float', 'x1'=>'float', 'y1'=>'float', 'r1'=>'float'], +'CairoRadialGradient::getCircles' => ['array'], +'CairoScaledFont::__construct' => ['void', 'font_face'=>'CairoFontFace', 'matrix'=>'CairoMatrix', 'ctm'=>'CairoMatrix', 'options'=>'CairoFontOptions'], +'CairoScaledFont::extents' => ['array'], +'CairoScaledFont::getCtm' => ['CairoMatrix'], +'CairoScaledFont::getFontFace' => ['', 'context'=>'cairocontext'], +'CairoScaledFont::getFontMatrix' => ['', 'context'=>'cairocontext'], +'CairoScaledFont::getFontOptions' => ['', 'context'=>'cairocontext'], +'CairoScaledFont::getScaleMatrix' => ['void'], +'CairoScaledFont::getType' => ['int'], +'CairoScaledFont::glyphExtents' => ['array', 'glyphs'=>'string'], +'CairoScaledFont::status' => ['int', 'context'=>'cairocontext'], +'CairoScaledFont::textExtents' => ['array', 'text'=>'string', 'context'=>'cairocontext'], +'CairoSolidPattern::__construct' => ['void', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'alpha='=>'float'], +'CairoSolidPattern::getRgba' => ['array'], +'CairoSurface::__construct' => ['void'], +'CairoSurface::copyPage' => ['', 'context'=>'cairocontext'], +'CairoSurface::createSimilar' => ['void', 'other'=>'cairosurface', 'content'=>'int', 'width'=>'string', 'height'=>'string'], +'CairoSurface::finish' => ['void'], +'CairoSurface::flush' => ['void'], +'CairoSurface::getContent' => ['int'], +'CairoSurface::getDeviceOffset' => ['array'], +'CairoSurface::getFontOptions' => ['', 'context'=>'cairocontext'], +'CairoSurface::getType' => ['int'], +'CairoSurface::markDirty' => ['void'], +'CairoSurface::markDirtyRectangle' => ['void', 'x'=>'string', 'y'=>'string', 'width'=>'string', 'height'=>'string'], +'CairoSurface::setDeviceOffset' => ['void', 'x'=>'string', 'y'=>'string'], +'CairoSurface::setFallbackResolution' => ['void', 'x'=>'string', 'y'=>'string'], +'CairoSurface::showPage' => ['', 'context'=>'cairocontext'], +'CairoSurface::status' => ['int', 'context'=>'cairocontext'], +'CairoSurface::writeToPng' => ['void', 'file'=>'string'], +'CairoSurfacePattern::__construct' => ['void', 'surface'=>'CairoSurface'], +'CairoSurfacePattern::getExtend' => ['int'], +'CairoSurfacePattern::getFilter' => ['int'], +'CairoSurfacePattern::getSurface' => ['void'], +'CairoSurfacePattern::setExtend' => ['void', 'extend'=>'int'], +'CairoSurfacePattern::setFilter' => ['void', 'filter'=>'string'], +'CairoSvgSurface::__construct' => ['void', 'file'=>'string', 'width'=>'float', 'height'=>'float'], +'CairoSvgSurface::getVersions' => ['array'], +'CairoSvgSurface::restrictToVersion' => ['void', 'version'=>'string'], +'CairoSvgSurface::versionToString' => ['string', 'version'=>'int'], +'cal_days_in_month' => ['int', 'calendar'=>'int', 'month'=>'int', 'year'=>'int'], +'cal_from_jd' => ['array', 'jd'=>'int', 'calendar'=>'int'], +'cal_info' => ['array', 'calendar='=>'int'], +'cal_to_jd' => ['int', 'calendar'=>'int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], +'calcul_hmac' => ['string', 'clent'=>'string', 'siretcode'=>'string', 'price'=>'string', 'reference'=>'string', 'validity'=>'string', 'taxation'=>'string', 'devise'=>'string', 'language'=>'string'], +'calculhmac' => ['string', 'clent'=>'string', 'data'=>'string'], +'call_user_func' => ['mixed', 'function'=>'callable', '...parameters='=>'mixed'], +'call_user_func_array' => ['mixed', 'function'=>'callable', 'parameters'=>'array'], +'call_user_method' => ['mixed', 'method_name'=>'string', 'obj'=>'object', 'parameter='=>'mixed', '...args='=>'mixed'], +'call_user_method_array' => ['mixed', 'method_name'=>'string', 'obj'=>'object', 'params'=>'array'], +'CallbackFilterIterator::__construct' => ['void', 'it'=>'iterator', 'func'=>'callable'], +'CallbackFilterIterator::accept' => ['bool'], +'CallbackFilterIterator::current' => ['mixed'], +'CallbackFilterIterator::getInnerIterator' => ['iterator'], +'CallbackFilterIterator::key' => ['mixed'], +'CallbackFilterIterator::next' => ['void'], +'CallbackFilterIterator::rewind' => ['void'], +'CallbackFilterIterator::valid' => ['bool'], +'ceil' => ['float|int', 'number'=>'float'], +'chdb::__construct' => ['void', 'pathname'=>'string'], +'chdb::get' => ['string', 'key'=>'string'], +'chdb_create' => ['bool', 'pathname'=>'string', 'data'=>'array'], +'chdir' => ['bool', 'directory'=>'string'], +'checkdate' => ['bool', 'month'=>'int', 'day'=>'int', 'year'=>'int'], +'checkdnsrr' => ['bool', 'host'=>'string', 'type='=>'string'], +'chgrp' => ['bool', 'filename'=>'string', 'group'=>'string|int'], +'chmod' => ['bool', 'filename'=>'string', 'mode'=>'int'], +'chop' => ['string', 'str'=>'string', 'character_mask='=>'string'], +'chown' => ['bool', 'filename'=>'string', 'user'=>'string|int'], +'chr' => ['string', 'ascii'=>'int'], +'chroot' => ['bool', 'directory'=>'string'], +'chunk_split' => ['string', 'str'=>'string', 'chunklen='=>'int', 'ending='=>'string'], +'class_alias' => ['bool', 'user_class_name'=>'string', 'alias_name'=>'string', 'autoload='=>'bool'], +'class_exists' => ['bool', 'classname'=>'string', 'autoload='=>'bool'], +'class_implements' => ['array', 'what'=>'object|string', 'autoload='=>'bool'], +'class_parents' => ['array', 'instance'=>'object|string', 'autoload='=>'bool'], +'class_uses' => ['array', 'what'=>'object|string', 'autoload='=>'bool'], +'classkit_import' => ['array', 'filename'=>'string'], +'classkit_method_add' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int'], +'classkit_method_copy' => ['bool', 'dclass'=>'string', 'dmethod'=>'string', 'sclass'=>'string', 'smethod='=>'string'], +'classkit_method_redefine' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int'], +'classkit_method_remove' => ['bool', 'classname'=>'string', 'methodname'=>'string'], +'classkit_method_rename' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'newname'=>'string'], +'classObj::__construct' => ['void', 'layer'=>'layerObj', 'class'=>'classObj'], +'classObj::addLabel' => ['int', 'label'=>'labelObj'], +'classObj::convertToString' => ['string'], +'classObj::createLegendIcon' => ['imageObj', 'width'=>'int', 'height'=>'int'], +'classObj::deletestyle' => ['int', 'index'=>'int'], +'classObj::drawLegendIcon' => ['int', 'width'=>'int', 'height'=>'int', 'im'=>'imageObj', 'dstX'=>'int', 'dstY'=>'int'], +'classObj::free' => ['void'], +'classObj::getExpressionString' => ['string'], +'classObj::getLabel' => ['labelObj', 'index'=>'int'], +'classObj::getMetaData' => ['int', 'name'=>'string'], +'classObj::getStyle' => ['styleObj', 'index'=>'int'], +'classObj::getTextString' => ['string'], +'classObj::movestyledown' => ['int', 'index'=>'int'], +'classObj::movestyleup' => ['int', 'index'=>'int'], +'classObj::ms_newClassObj' => ['classObj', 'layer'=>'layerObj', 'class'=>'classObj'], +'classObj::removeLabel' => ['labelObj', 'index'=>'int'], +'classObj::removeMetaData' => ['int', 'name'=>'string'], +'classObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'classObj::setExpression' => ['int', 'expression'=>'string'], +'classObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'], +'classObj::settext' => ['int', 'text'=>'string'], +'classObj::updateFromString' => ['int', 'snippet'=>'string'], +'clearstatcache' => ['void', 'clear_realpath_cache='=>'bool', 'filename='=>'string'], +'cli_get_process_title' => ['string'], +'cli_set_process_title' => ['bool', 'arg'=>'string'], +'ClosedGeneratorException::__clone' => ['void'], +'ClosedGeneratorException::__toString' => ['string'], +'ClosedGeneratorException::getCode' => ['int'], +'ClosedGeneratorException::getFile' => ['string'], +'ClosedGeneratorException::getLine' => ['int'], +'ClosedGeneratorException::getMessage' => ['string'], +'ClosedGeneratorException::getPrevious' => ['Throwable|ClosedGeneratorException|null'], +'ClosedGeneratorException::getTrace' => ['array'], +'ClosedGeneratorException::getTraceAsString' => ['string'], +'closedir' => ['void', 'dir_handle='=>'resource'], +'closelog' => ['bool'], +'Closure::__construct' => ['void'], +'Closure::__invoke' => ['', '...args='=>''], +'Closure::bind' => ['Closure', 'old'=>'Closure', 'to'=>'?object', 'scope='=>'object|string'], +'Closure::bindTo' => ['Closure', 'new'=>'?object', 'newscope='=>'object|string'], +'Closure::call' => ['', 'to'=>'object', '...parameters='=>''], +'Closure::fromCallable' => ['Closure', 'callable'=>'callable'], +'clusterObj::convertToString' => ['string'], +'clusterObj::getFilterString' => ['string'], +'clusterObj::getGroupString' => ['string'], +'clusterObj::setFilter' => ['int', 'expression'=>'string'], +'clusterObj::setGroup' => ['int', 'expression'=>'string'], +'Collator::__construct' => ['void', 'locale'=>'string'], +'Collator::asort' => ['bool', '&rw_arr'=>'array', 'sort_flag='=>'int'], +'Collator::compare' => ['int', 'str1'=>'string', 'str2'=>'string'], +'Collator::create' => ['Collator', 'locale'=>'string'], +'Collator::getAttribute' => ['int', 'attr'=>'int'], +'Collator::getErrorCode' => ['int'], +'Collator::getErrorMessage' => ['string'], +'Collator::getLocale' => ['string', 'type'=>'int'], +'Collator::getSortKey' => ['string', 'str'=>'string'], +'Collator::getStrength' => ['int'], +'Collator::setAttribute' => ['bool', 'attr'=>'int', 'val'=>'int'], +'Collator::setStrength' => ['bool', 'strength'=>'int'], +'Collator::sort' => ['bool', '&rw_arr'=>'array', 'sort_flags='=>'int'], +'Collator::sortWithSortKeys' => ['bool', '&rw_arr'=>'array'], +'collator_asort' => ['bool', 'coll'=>'collator', '&rw_arr'=>'array', 'sort_flag='=>'int'], +'collator_compare' => ['int', 'coll'=>'collator', 'str1'=>'string', 'str2'=>'string'], +'collator_create' => ['Collator', 'locale'=>'string'], +'collator_get_attribute' => ['int', 'coll'=>'collator', 'attr'=>'int'], +'collator_get_error_code' => ['int', 'coll'=>'collator'], +'collator_get_error_message' => ['string', 'coll'=>'collator'], +'collator_get_locale' => ['string', 'coll'=>'collator', 'type'=>'int'], +'collator_get_sort_key' => ['string', 'coll'=>'collator', 'str'=>'string'], +'collator_get_strength' => ['int', 'coll'=>'collator'], +'collator_set_attribute' => ['bool', 'coll'=>'collator', 'attr'=>'int', 'val'=>'int'], +'collator_set_strength' => ['bool', 'coll'=>'collator', 'strength'=>'int'], +'collator_sort' => ['bool', 'coll'=>'collator', '&rw_arr'=>'array', 'sort_flag='=>'int'], +'collator_sort_with_sort_keys' => ['bool', 'coll'=>'collator', '&rw_arr'=>'array'], +'Collectable::isGarbage' => ['bool'], +'Collectable::setGarbage' => ['void'], +'colorObj::setHex' => ['int', 'hex'=>'string'], +'colorObj::toHex' => ['string'], +'COM::__call' => ['', 'name'=>'', 'args'=>''], +'COM::__construct' => ['void', 'module_name'=>'string', 'server_name='=>'mixed', 'codepage='=>'int', 'typelib='=>'string'], +'COM::__get' => ['', 'name'=>''], +'COM::__set' => ['', 'name'=>'', 'value'=>''], +'com_addref' => [''], +'com_create_guid' => ['string'], +'com_event_sink' => ['bool', 'comobject'=>'object', 'sinkobject'=>'object', 'sinkinterface='=>'mixed'], +'com_get_active_object' => ['object', 'progid'=>'string', 'code_page='=>'int'], +'com_isenum' => ['bool', 'com_module'=>'variant'], +'com_load_typelib' => ['bool', 'typelib_name'=>'string', 'case_insensitive='=>'int'], +'com_message_pump' => ['bool', 'timeoutms='=>'int'], +'com_print_typeinfo' => ['bool', 'comobject_or_typelib'=>'object', 'dispinterface='=>'string', 'wantsink='=>'bool'], +'com_release' => [''], +'compact' => ['array', '...var_names='=>'string|array'], +'COMPersistHelper::__construct' => ['void', 'com_object'=>'object'], +'COMPersistHelper::GetCurFile' => ['string'], +'COMPersistHelper::GetMaxStreamSize' => ['int'], +'COMPersistHelper::InitNew' => ['int'], +'COMPersistHelper::LoadFromFile' => ['bool', 'filename'=>'string', 'flags'=>'int'], +'COMPersistHelper::LoadFromStream' => ['', 'stream'=>''], +'COMPersistHelper::SaveToFile' => ['bool', 'filename'=>'string', 'remember'=>'bool'], +'COMPersistHelper::SaveToStream' => ['int', 'stream'=>''], +'componere\cast' => ['Type', 'arg1'=>'', 'object'=>''], +'componere\cast_by_ref' => ['Type', 'arg1'=>'', 'object'=>''], +'Cond::broadcast' => ['bool', 'condition'=>'long'], +'Cond::create' => ['long'], +'Cond::destroy' => ['bool', 'condition'=>'long'], +'Cond::signal' => ['bool', 'condition'=>'long'], +'Cond::wait' => ['bool', 'condition'=>'long', 'mutex'=>'long', 'timeout='=>'long'], +'confirm_pdo_ibm_compiled' => [''], +'connection_aborted' => ['int'], +'connection_status' => ['int'], +'connection_timeout' => ['int'], +'constant' => ['mixed', 'const_name'=>'string'], +'convert_cyr_string' => ['string', 'str'=>'string', 'from'=>'string', 'to'=>'string'], +'convert_uudecode' => ['string', 'data'=>'string'], +'convert_uuencode' => ['string', 'data'=>'string'], +'copy' => ['bool', 'source_file'=>'string', 'destination_file'=>'string', 'context='=>'resource'], +'cos' => ['float', 'number'=>'float'], +'cosh' => ['float', 'number'=>'float'], +'Couchbase\AnalyticsQuery::__construct' => ['void'], +'Couchbase\AnalyticsQuery::fromString' => ['Couchbase\AnalyticsQuery', 'statement'=>'string'], +'Couchbase\basicDecoderV1' => ['mixed', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int', 'options'=>'array'], +'Couchbase\basicEncoderV1' => ['array', 'value'=>'mixed', 'options'=>'array'], +'Couchbase\BooleanFieldSearchQuery::__construct' => ['void'], +'Couchbase\BooleanFieldSearchQuery::boost' => ['Couchbase\BooleanFieldSearchQuery', 'boost'=>'float'], +'Couchbase\BooleanFieldSearchQuery::field' => ['Couchbase\BooleanFieldSearchQuery', 'field'=>'string'], +'Couchbase\BooleanFieldSearchQuery::jsonSerialize' => ['array'], +'Couchbase\BooleanSearchQuery::__construct' => ['void'], +'Couchbase\BooleanSearchQuery::boost' => ['Couchbase\BooleanSearchQuery', 'boost'=>'float'], +'Couchbase\BooleanSearchQuery::jsonSerialize' => ['array'], +'Couchbase\BooleanSearchQuery::must' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array'], +'Couchbase\BooleanSearchQuery::mustNot' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array'], +'Couchbase\BooleanSearchQuery::should' => ['Couchbase\BooleanSearchQuery', '...queries='=>'array'], +'Couchbase\Bucket::__construct' => ['void'], +'Couchbase\Bucket::__get' => ['int', 'name'=>'string'], +'Couchbase\Bucket::__set' => ['int', 'name'=>'string', 'value'=>'int'], +'Couchbase\Bucket::append' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], +'Couchbase\Bucket::counter' => ['Couchbase\Document|array', 'ids'=>'array|string', 'delta='=>'int', 'options='=>'array'], +'Couchbase\Bucket::diag' => ['array', 'reportId='=>'string'], +'Couchbase\Bucket::get' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'], +'Couchbase\Bucket::getAndLock' => ['Couchbase\Document|array', 'ids'=>'array|string', 'lockTime'=>'int', 'options='=>'array'], +'Couchbase\Bucket::getAndTouch' => ['Couchbase\Document|array', 'ids'=>'array|string', 'expiry'=>'int', 'options='=>'array'], +'Couchbase\Bucket::getFromReplica' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'], +'Couchbase\Bucket::insert' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], +'Couchbase\Bucket::listExists' => ['bool', 'id'=>'string', 'value'=>'mixed'], +'Couchbase\Bucket::listGet' => ['mixed', 'id'=>'string', 'index'=>'int'], +'Couchbase\Bucket::listPush' => ['', 'id'=>'string', 'value'=>'mixed'], +'Couchbase\Bucket::listRemove' => ['', 'id'=>'string', 'index'=>'int'], +'Couchbase\Bucket::listSet' => ['', 'id'=>'string', 'index'=>'int', 'value'=>'mixed'], +'Couchbase\Bucket::listShift' => ['', 'id'=>'string', 'value'=>'mixed'], +'Couchbase\Bucket::listSize' => ['int', 'id'=>'string'], +'Couchbase\Bucket::lookupIn' => ['Couchbase\LookupInBuilder', 'id'=>'string'], +'Couchbase\Bucket::manager' => ['Couchbase\BucketManager'], +'Couchbase\Bucket::mapAdd' => ['', 'id'=>'string', 'key'=>'string', 'value'=>'mixed'], +'Couchbase\Bucket::mapGet' => ['mixed', 'id'=>'string', 'key'=>'string'], +'Couchbase\Bucket::mapRemove' => ['', 'id'=>'string', 'key'=>'string'], +'Couchbase\Bucket::mapSize' => ['int', 'id'=>'string'], +'Couchbase\Bucket::mutateIn' => ['Couchbase\MutateInBuilder', 'id'=>'string', 'cas'=>'string'], +'Couchbase\Bucket::ping' => ['array', 'services='=>'int', 'reportId='=>'string'], +'Couchbase\Bucket::prepend' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], +'Couchbase\Bucket::query' => ['object', 'query'=>'Couchbase\AnalyticsQuery|Couchbase\N1qlQuery|Couchbase\SearchQuery|Couchbase\SpatialViewQuery|Couchbase\ViewQuery', 'jsonAsArray='=>'bool|false'], +'Couchbase\Bucket::queueAdd' => ['', 'id'=>'string', 'value'=>'mixed'], +'Couchbase\Bucket::queueExists' => ['bool', 'id'=>'string', 'value'=>'mixed'], +'Couchbase\Bucket::queueRemove' => ['mixed', 'id'=>'string'], +'Couchbase\Bucket::queueSize' => ['int', 'id'=>'string'], +'Couchbase\Bucket::remove' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'], +'Couchbase\Bucket::replace' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], +'Couchbase\Bucket::retrieveIn' => ['Couchbase\DocumentFragment', 'id'=>'string', '...paths='=>'array'], +'Couchbase\Bucket::setAdd' => ['', 'id'=>'string', 'value'=>'bool|float|int|string'], +'Couchbase\Bucket::setExists' => ['bool', 'id'=>'string', 'value'=>'bool|float|int|string'], +'Couchbase\Bucket::setRemove' => ['', 'id'=>'string', 'value'=>'bool|float|int|string'], +'Couchbase\Bucket::setSize' => ['int', 'id'=>'string'], +'Couchbase\Bucket::setTranscoder' => ['', 'encoder'=>'callable', 'decoder'=>'callable'], +'Couchbase\Bucket::touch' => ['Couchbase\Document|array', 'ids'=>'array|string', 'expiry'=>'int', 'options='=>'array'], +'Couchbase\Bucket::unlock' => ['Couchbase\Document|array', 'ids'=>'array|string', 'options='=>'array'], +'Couchbase\Bucket::upsert' => ['Couchbase\Document|array', 'ids'=>'array|string', 'value'=>'mixed', 'options='=>'array'], +'Couchbase\BucketManager::__construct' => ['void'], +'Couchbase\BucketManager::createN1qlIndex' => ['', 'name'=>'string', 'fields'=>'array', 'whereClause='=>'string', 'ignoreIfExist='=>'bool|false', 'defer='=>'bool|false'], +'Couchbase\BucketManager::createN1qlPrimaryIndex' => ['', 'customName='=>'string', 'ignoreIfExist='=>'bool|false', 'defer='=>'bool|false'], +'Couchbase\BucketManager::dropN1qlIndex' => ['', 'name'=>'string', 'ignoreIfNotExist='=>'bool|false'], +'Couchbase\BucketManager::dropN1qlPrimaryIndex' => ['', 'customName='=>'string', 'ignoreIfNotExist='=>'bool|false'], +'Couchbase\BucketManager::flush' => [''], +'Couchbase\BucketManager::getDesignDocument' => ['array', 'name'=>'string'], +'Couchbase\BucketManager::info' => ['array'], +'Couchbase\BucketManager::insertDesignDocument' => ['', 'name'=>'string', 'document'=>'array'], +'Couchbase\BucketManager::listDesignDocuments' => ['array'], +'Couchbase\BucketManager::listN1qlIndexes' => ['array'], +'Couchbase\BucketManager::removeDesignDocument' => ['', 'name'=>'string'], +'Couchbase\BucketManager::upsertDesignDocument' => ['', 'name'=>'string', 'document'=>'array'], +'Couchbase\ClassicAuthenticator::bucket' => ['', 'name'=>'string', 'password'=>'string'], +'Couchbase\ClassicAuthenticator::cluster' => ['', 'username'=>'string', 'password'=>'string'], +'Couchbase\Cluster::__construct' => ['void', 'connstr'=>'string'], +'Couchbase\Cluster::authenticate' => ['null', 'authenticator'=>'Couchbase\Authenticator'], +'Couchbase\Cluster::authenticateAs' => ['null', 'username'=>'string', 'password'=>'string'], +'Couchbase\Cluster::manager' => ['Couchbase\ClusterManager', 'username='=>'string', 'password='=>'string'], +'Couchbase\Cluster::openBucket' => ['Couchbase\Bucket', 'name='=>'string', 'password='=>'string'], +'Couchbase\ClusterManager::__construct' => ['void'], +'Couchbase\ClusterManager::createBucket' => ['', 'name'=>'string', 'options='=>'array'], +'Couchbase\ClusterManager::getUser' => ['array', 'username'=>'string', 'domain='=>'int'], +'Couchbase\ClusterManager::info' => ['array'], +'Couchbase\ClusterManager::listBuckets' => ['array'], +'Couchbase\ClusterManager::listUsers' => ['array', 'domain='=>'int'], +'Couchbase\ClusterManager::removeBucket' => ['', 'name'=>'string'], +'Couchbase\ClusterManager::removeUser' => ['', 'name'=>'string', 'domain='=>'int'], +'Couchbase\ClusterManager::upsertUser' => ['', 'name'=>'string', 'settings'=>'Couchbase\UserSettings', 'domain='=>'int'], +'Couchbase\ConjunctionSearchQuery::__construct' => ['void'], +'Couchbase\ConjunctionSearchQuery::boost' => ['Couchbase\ConjunctionSearchQuery', 'boost'=>'float'], +'Couchbase\ConjunctionSearchQuery::every' => ['Couchbase\ConjunctionSearchQuery', '...queries='=>'array'], +'Couchbase\ConjunctionSearchQuery::jsonSerialize' => ['array'], +'Couchbase\DateRangeSearchFacet::__construct' => ['void'], +'Couchbase\DateRangeSearchFacet::addRange' => ['Couchbase\DateSearchFacet', 'name'=>'string', 'start'=>'int|string', 'end'=>'int|string'], +'Couchbase\DateRangeSearchFacet::jsonSerialize' => ['array'], +'Couchbase\DateRangeSearchQuery::__construct' => ['void'], +'Couchbase\DateRangeSearchQuery::boost' => ['Couchbase\DateRangeSearchQuery', 'boost'=>'float'], +'Couchbase\DateRangeSearchQuery::dateTimeParser' => ['Couchbase\DateRangeSearchQuery', 'dateTimeParser'=>'string'], +'Couchbase\DateRangeSearchQuery::end' => ['Couchbase\DateRangeSearchQuery', 'end'=>'int|string', 'inclusive='=>'bool|false'], +'Couchbase\DateRangeSearchQuery::field' => ['Couchbase\DateRangeSearchQuery', 'field'=>'string'], +'Couchbase\DateRangeSearchQuery::jsonSerialize' => ['array'], +'Couchbase\DateRangeSearchQuery::start' => ['Couchbase\DateRangeSearchQuery', 'start'=>'int|string', 'inclusive='=>'bool|true'], +'Couchbase\defaultDecoder' => ['mixed', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int'], +'Couchbase\defaultEncoder' => ['array', 'value'=>'mixed'], +'Couchbase\DisjunctionSearchQuery::__construct' => ['void'], +'Couchbase\DisjunctionSearchQuery::boost' => ['Couchbase\DisjunctionSearchQuery', 'boost'=>'float'], +'Couchbase\DisjunctionSearchQuery::either' => ['Couchbase\DisjunctionSearchQuery', '...queries='=>'array'], +'Couchbase\DisjunctionSearchQuery::jsonSerialize' => ['array'], +'Couchbase\DisjunctionSearchQuery::min' => ['Couchbase\DisjunctionSearchQuery', 'min'=>'int'], +'Couchbase\DocIdSearchQuery::__construct' => ['void'], +'Couchbase\DocIdSearchQuery::boost' => ['Couchbase\DocIdSearchQuery', 'boost'=>'float'], +'Couchbase\DocIdSearchQuery::docIds' => ['Couchbase\DocIdSearchQuery', '...documentIds='=>'array'], +'Couchbase\DocIdSearchQuery::field' => ['Couchbase\DocIdSearchQuery', 'field'=>'string'], +'Couchbase\DocIdSearchQuery::jsonSerialize' => ['array'], +'Couchbase\fastlzCompress' => ['string', 'data'=>'string'], +'Couchbase\fastlzDecompress' => ['string', 'data'=>'string'], +'Couchbase\GeoBoundingBoxSearchQuery::__construct' => ['void'], +'Couchbase\GeoBoundingBoxSearchQuery::boost' => ['Couchbase\GeoBoundingBoxSearchQuery', 'boost'=>'float'], +'Couchbase\GeoBoundingBoxSearchQuery::field' => ['Couchbase\GeoBoundingBoxSearchQuery', 'field'=>'string'], +'Couchbase\GeoBoundingBoxSearchQuery::jsonSerialize' => ['array'], +'Couchbase\GeoDistanceSearchQuery::__construct' => ['void'], +'Couchbase\GeoDistanceSearchQuery::boost' => ['Couchbase\GeoDistanceSearchQuery', 'boost'=>'float'], +'Couchbase\GeoDistanceSearchQuery::field' => ['Couchbase\GeoDistanceSearchQuery', 'field'=>'string'], +'Couchbase\GeoDistanceSearchQuery::jsonSerialize' => ['array'], +'Couchbase\LookupInBuilder::__construct' => ['void'], +'Couchbase\LookupInBuilder::execute' => ['Couchbase\DocumentFragment'], +'Couchbase\LookupInBuilder::exists' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'], +'Couchbase\LookupInBuilder::get' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'], +'Couchbase\LookupInBuilder::getCount' => ['Couchbase\LookupInBuilder', 'path'=>'string', 'options='=>'array'], +'Couchbase\MatchAllSearchQuery::__construct' => ['void'], +'Couchbase\MatchAllSearchQuery::boost' => ['Couchbase\MatchAllSearchQuery', 'boost'=>'float'], +'Couchbase\MatchAllSearchQuery::jsonSerialize' => ['array'], +'Couchbase\MatchNoneSearchQuery::__construct' => ['void'], +'Couchbase\MatchNoneSearchQuery::boost' => ['Couchbase\MatchNoneSearchQuery', 'boost'=>'float'], +'Couchbase\MatchNoneSearchQuery::jsonSerialize' => ['array'], +'Couchbase\MatchPhraseSearchQuery::__construct' => ['void'], +'Couchbase\MatchPhraseSearchQuery::analyzer' => ['Couchbase\MatchPhraseSearchQuery', 'analyzer'=>'string'], +'Couchbase\MatchPhraseSearchQuery::boost' => ['Couchbase\MatchPhraseSearchQuery', 'boost'=>'float'], +'Couchbase\MatchPhraseSearchQuery::field' => ['Couchbase\MatchPhraseSearchQuery', 'field'=>'string'], +'Couchbase\MatchPhraseSearchQuery::jsonSerialize' => ['array'], +'Couchbase\MatchSearchQuery::__construct' => ['void'], +'Couchbase\MatchSearchQuery::analyzer' => ['Couchbase\MatchSearchQuery', 'analyzer'=>'string'], +'Couchbase\MatchSearchQuery::boost' => ['Couchbase\MatchSearchQuery', 'boost'=>'float'], +'Couchbase\MatchSearchQuery::field' => ['Couchbase\MatchSearchQuery', 'field'=>'string'], +'Couchbase\MatchSearchQuery::fuzziness' => ['Couchbase\MatchSearchQuery', 'fuzziness'=>'int'], +'Couchbase\MatchSearchQuery::jsonSerialize' => ['array'], +'Couchbase\MatchSearchQuery::prefixLength' => ['Couchbase\MatchSearchQuery', 'prefixLength'=>'int'], +'Couchbase\MutateInBuilder::__construct' => ['void'], +'Couchbase\MutateInBuilder::arrayAddUnique' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], +'Couchbase\MutateInBuilder::arrayAppend' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], +'Couchbase\MutateInBuilder::arrayAppendAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array|bool'], +'Couchbase\MutateInBuilder::arrayInsert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array'], +'Couchbase\MutateInBuilder::arrayInsertAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array'], +'Couchbase\MutateInBuilder::arrayPrepend' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], +'Couchbase\MutateInBuilder::arrayPrependAll' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'values'=>'array', 'options='=>'array|bool'], +'Couchbase\MutateInBuilder::counter' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'delta'=>'int', 'options='=>'array|bool'], +'Couchbase\MutateInBuilder::execute' => ['Couchbase\DocumentFragment'], +'Couchbase\MutateInBuilder::insert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], +'Couchbase\MutateInBuilder::modeDocument' => ['', 'mode'=>'int'], +'Couchbase\MutateInBuilder::remove' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'options='=>'array'], +'Couchbase\MutateInBuilder::replace' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array'], +'Couchbase\MutateInBuilder::upsert' => ['Couchbase\MutateInBuilder', 'path'=>'string', 'value'=>'mixed', 'options='=>'array|bool'], +'Couchbase\MutateInBuilder::withExpiry' => ['Couchbase\MutateInBuilder', 'expiry'=>'Couchbase\expiry'], +'Couchbase\MutationState::__construct' => ['void'], +'Couchbase\MutationState::add' => ['', 'source'=>'Couchbase\Document|Couchbase\DocumentFragment|array'], +'Couchbase\MutationState::from' => ['Couchbase\MutationState', 'source'=>'Couchbase\Document|Couchbase\DocumentFragment|array'], +'Couchbase\MutationToken::__construct' => ['void'], +'Couchbase\MutationToken::bucketName' => ['string'], +'Couchbase\MutationToken::from' => ['', 'bucketName'=>'string', 'vbucketId'=>'int', 'vbucketUuid'=>'string', 'sequenceNumber'=>'string'], +'Couchbase\MutationToken::sequenceNumber' => ['string'], +'Couchbase\MutationToken::vbucketId' => ['int'], +'Couchbase\MutationToken::vbucketUuid' => ['string'], +'Couchbase\N1qlIndex::__construct' => ['void'], +'Couchbase\N1qlQuery::__construct' => ['void'], +'Couchbase\N1qlQuery::adhoc' => ['Couchbase\N1qlQuery', 'adhoc'=>'bool'], +'Couchbase\N1qlQuery::consistency' => ['Couchbase\N1qlQuery', 'consistency'=>'int'], +'Couchbase\N1qlQuery::consistentWith' => ['Couchbase\N1qlQuery', 'state'=>'Couchbase\MutationState'], +'Couchbase\N1qlQuery::crossBucket' => ['Couchbase\N1qlQuery', 'crossBucket'=>'bool'], +'Couchbase\N1qlQuery::fromString' => ['Couchbase\N1qlQuery', 'statement'=>'string'], +'Couchbase\N1qlQuery::maxParallelism' => ['Couchbase\N1qlQuery', 'maxParallelism'=>'int'], +'Couchbase\N1qlQuery::namedParams' => ['Couchbase\N1qlQuery', 'params'=>'array'], +'Couchbase\N1qlQuery::pipelineBatch' => ['Couchbase\N1qlQuery', 'pipelineBatch'=>'int'], +'Couchbase\N1qlQuery::pipelineCap' => ['Couchbase\N1qlQuery', 'pipelineCap'=>'int'], +'Couchbase\N1qlQuery::positionalParams' => ['Couchbase\N1qlQuery', 'params'=>'array'], +'Couchbase\N1qlQuery::readonly' => ['Couchbase\N1qlQuery', 'readonly'=>'bool'], +'Couchbase\N1qlQuery::scanCap' => ['Couchbase\N1qlQuery', 'scanCap'=>'int'], +'Couchbase\NumericRangeSearchFacet::__construct' => ['void'], +'Couchbase\NumericRangeSearchFacet::addRange' => ['Couchbase\NumericSearchFacet', 'name'=>'string', 'min'=>'float', 'max'=>'float'], +'Couchbase\NumericRangeSearchFacet::jsonSerialize' => ['array'], +'Couchbase\NumericRangeSearchQuery::__construct' => ['void'], +'Couchbase\NumericRangeSearchQuery::boost' => ['Couchbase\NumericRangeSearchQuery', 'boost'=>'float'], +'Couchbase\NumericRangeSearchQuery::field' => ['Couchbase\NumericRangeSearchQuery', 'field'=>'string'], +'Couchbase\NumericRangeSearchQuery::jsonSerialize' => ['array'], +'Couchbase\NumericRangeSearchQuery::max' => ['Couchbase\NumericRangeSearchQuery', 'max'=>'float', 'inclusive='=>'bool|false'], +'Couchbase\NumericRangeSearchQuery::min' => ['Couchbase\NumericRangeSearchQuery', 'min'=>'float', 'inclusive='=>'bool|true'], +'Couchbase\passthruDecoder' => ['string', 'bytes'=>'string', 'flags'=>'int', 'datatype'=>'int'], +'Couchbase\passthruEncoder' => ['array', 'value'=>'string'], +'Couchbase\PasswordAuthenticator::password' => ['Couchbase\PasswordAuthenticator', 'password'=>'string'], +'Couchbase\PasswordAuthenticator::username' => ['Couchbase\PasswordAuthenticator', 'username'=>'string'], +'Couchbase\PhraseSearchQuery::__construct' => ['void'], +'Couchbase\PhraseSearchQuery::boost' => ['Couchbase\PhraseSearchQuery', 'boost'=>'float'], +'Couchbase\PhraseSearchQuery::field' => ['Couchbase\PhraseSearchQuery', 'field'=>'string'], +'Couchbase\PhraseSearchQuery::jsonSerialize' => ['array'], +'Couchbase\PrefixSearchQuery::__construct' => ['void'], +'Couchbase\PrefixSearchQuery::boost' => ['Couchbase\PrefixSearchQuery', 'boost'=>'float'], +'Couchbase\PrefixSearchQuery::field' => ['Couchbase\PrefixSearchQuery', 'field'=>'string'], +'Couchbase\PrefixSearchQuery::jsonSerialize' => ['array'], +'Couchbase\QueryStringSearchQuery::__construct' => ['void'], +'Couchbase\QueryStringSearchQuery::boost' => ['Couchbase\QueryStringSearchQuery', 'boost'=>'float'], +'Couchbase\QueryStringSearchQuery::jsonSerialize' => ['array'], +'Couchbase\RegexpSearchQuery::__construct' => ['void'], +'Couchbase\RegexpSearchQuery::boost' => ['Couchbase\RegexpSearchQuery', 'boost'=>'float'], +'Couchbase\RegexpSearchQuery::field' => ['Couchbase\RegexpSearchQuery', 'field'=>'string'], +'Couchbase\RegexpSearchQuery::jsonSerialize' => ['array'], +'Couchbase\SearchQuery::__construct' => ['void', 'indexName'=>'string', 'queryPart'=>'Couchbase\SearchQueryPart'], +'Couchbase\SearchQuery::addFacet' => ['Couchbase\SearchQuery', 'name'=>'string', 'facet'=>'Couchbase\SearchFacet'], +'Couchbase\SearchQuery::boolean' => ['Couchbase\BooleanSearchQuery'], +'Couchbase\SearchQuery::booleanField' => ['Couchbase\BooleanFieldSearchQuery', 'value'=>'bool'], +'Couchbase\SearchQuery::conjuncts' => ['Couchbase\ConjunctionSearchQuery', '...queries='=>'array'], +'Couchbase\SearchQuery::consistentWith' => ['Couchbase\SearchQuery', 'state'=>'Couchbase\MutationState'], +'Couchbase\SearchQuery::dateRange' => ['Couchbase\DateRangeSearchQuery'], +'Couchbase\SearchQuery::dateRangeFacet' => ['Couchbase\DateRangeSearchFacet', 'field'=>'string', 'limit'=>'int'], +'Couchbase\SearchQuery::disjuncts' => ['Couchbase\DisjunctionSearchQuery', '...queries='=>'array'], +'Couchbase\SearchQuery::docId' => ['Couchbase\DocIdSearchQuery', '...documentIds='=>'array'], +'Couchbase\SearchQuery::explain' => ['Couchbase\SearchQuery', 'explain'=>'bool'], +'Couchbase\SearchQuery::fields' => ['Couchbase\SearchQuery', '...fields='=>'array'], +'Couchbase\SearchQuery::geoBoundingBox' => ['Couchbase\GeoBoundingBoxSearchQuery', 'topLeftLongitude'=>'float', 'topLeftLatitude'=>'float', 'bottomRightLongitude'=>'float', 'bottomRightLatitude'=>'float'], +'Couchbase\SearchQuery::geoDistance' => ['Couchbase\GeoDistanceSearchQuery', 'longitude'=>'float', 'latitude'=>'float', 'distance'=>'string'], +'Couchbase\SearchQuery::highlight' => ['Couchbase\SearchQuery', 'style'=>'string', '...fields='=>'array'], +'Couchbase\SearchQuery::jsonSerialize' => ['array'], +'Couchbase\SearchQuery::limit' => ['Couchbase\SearchQuery', 'limit'=>'int'], +'Couchbase\SearchQuery::match' => ['Couchbase\MatchSearchQuery', 'match'=>'string'], +'Couchbase\SearchQuery::matchAll' => ['Couchbase\MatchAllSearchQuery'], +'Couchbase\SearchQuery::matchNone' => ['Couchbase\MatchNoneSearchQuery'], +'Couchbase\SearchQuery::matchPhrase' => ['Couchbase\MatchPhraseSearchQuery', '...terms='=>'array'], +'Couchbase\SearchQuery::numericRange' => ['Couchbase\NumericRangeSearchQuery'], +'Couchbase\SearchQuery::numericRangeFacet' => ['Couchbase\NumericRangeSearchFacet', 'field'=>'string', 'limit'=>'int'], +'Couchbase\SearchQuery::prefix' => ['Couchbase\PrefixSearchQuery', 'prefix'=>'string'], +'Couchbase\SearchQuery::queryString' => ['Couchbase\QueryStringSearchQuery', 'queryString'=>'string'], +'Couchbase\SearchQuery::regexp' => ['Couchbase\RegexpSearchQuery', 'regexp'=>'string'], +'Couchbase\SearchQuery::serverSideTimeout' => ['Couchbase\SearchQuery', 'serverSideTimeout'=>'int'], +'Couchbase\SearchQuery::skip' => ['Couchbase\SearchQuery', 'skip'=>'int'], +'Couchbase\SearchQuery::sort' => ['Couchbase\SearchQuery', '...sort='=>'array'], +'Couchbase\SearchQuery::term' => ['Couchbase\TermSearchQuery', 'term'=>'string'], +'Couchbase\SearchQuery::termFacet' => ['Couchbase\TermSearchFacet', 'field'=>'string', 'limit'=>'int'], +'Couchbase\SearchQuery::termRange' => ['Couchbase\TermRangeSearchQuery'], +'Couchbase\SearchQuery::wildcard' => ['Couchbase\WildcardSearchQuery', 'wildcard'=>'string'], +'Couchbase\SpatialViewQuery::__construct' => ['void'], +'Couchbase\SpatialViewQuery::bbox' => ['Couchbase\SpatialViewQuery', 'bbox'=>'array'], +'Couchbase\SpatialViewQuery::consistency' => ['Couchbase\SpatialViewQuery', 'consistency'=>'int'], +'Couchbase\SpatialViewQuery::custom' => ['', 'customParameters'=>'array'], +'Couchbase\SpatialViewQuery::encode' => ['array'], +'Couchbase\SpatialViewQuery::endRange' => ['Couchbase\SpatialViewQuery', 'range'=>'array'], +'Couchbase\SpatialViewQuery::limit' => ['Couchbase\SpatialViewQuery', 'limit'=>'int'], +'Couchbase\SpatialViewQuery::order' => ['Couchbase\SpatialViewQuery', 'order'=>'int'], +'Couchbase\SpatialViewQuery::skip' => ['Couchbase\SpatialViewQuery', 'skip'=>'int'], +'Couchbase\SpatialViewQuery::startRange' => ['Couchbase\SpatialViewQuery', 'range'=>'array'], +'Couchbase\TermRangeSearchQuery::__construct' => ['void'], +'Couchbase\TermRangeSearchQuery::boost' => ['Couchbase\TermRangeSearchQuery', 'boost'=>'float'], +'Couchbase\TermRangeSearchQuery::field' => ['Couchbase\TermRangeSearchQuery', 'field'=>'string'], +'Couchbase\TermRangeSearchQuery::jsonSerialize' => ['array'], +'Couchbase\TermRangeSearchQuery::max' => ['Couchbase\TermRangeSearchQuery', 'max'=>'string', 'inclusive='=>'bool|false'], +'Couchbase\TermRangeSearchQuery::min' => ['Couchbase\TermRangeSearchQuery', 'min'=>'string', 'inclusive='=>'bool|true'], +'Couchbase\TermSearchFacet::__construct' => ['void'], +'Couchbase\TermSearchFacet::jsonSerialize' => ['array'], +'Couchbase\TermSearchQuery::__construct' => ['void'], +'Couchbase\TermSearchQuery::boost' => ['Couchbase\TermSearchQuery', 'boost'=>'float'], +'Couchbase\TermSearchQuery::field' => ['Couchbase\TermSearchQuery', 'field'=>'string'], +'Couchbase\TermSearchQuery::fuzziness' => ['Couchbase\TermSearchQuery', 'fuzziness'=>'int'], +'Couchbase\TermSearchQuery::jsonSerialize' => ['array'], +'Couchbase\TermSearchQuery::prefixLength' => ['Couchbase\TermSearchQuery', 'prefixLength'=>'int'], +'Couchbase\UserSettings::fullName' => ['Couchbase\UserSettings', 'fullName'=>'string'], +'Couchbase\UserSettings::password' => ['Couchbase\UserSettings', 'password'=>'string'], +'Couchbase\UserSettings::role' => ['Couchbase\UserSettings', 'role'=>'string', 'bucket='=>'string'], +'Couchbase\ViewQuery::__construct' => ['void'], +'Couchbase\ViewQuery::consistency' => ['Couchbase\ViewQuery', 'consistency'=>'int'], +'Couchbase\ViewQuery::custom' => ['Couchbase\ViewQuery', 'customParameters'=>'array'], +'Couchbase\ViewQuery::encode' => ['array'], +'Couchbase\ViewQuery::from' => ['Couchbase\ViewQuery', 'designDocumentName'=>'string', 'viewName'=>'string'], +'Couchbase\ViewQuery::fromSpatial' => ['Couchbase\SpatialViewQuery', 'designDocumentName'=>'string', 'viewName'=>'string'], +'Couchbase\ViewQuery::group' => ['Couchbase\ViewQuery', 'group'=>'bool'], +'Couchbase\ViewQuery::groupLevel' => ['Couchbase\ViewQuery', 'groupLevel'=>'int'], +'Couchbase\ViewQuery::idRange' => ['Couchbase\ViewQuery', 'startKeyDocumentId'=>'string', 'endKeyDocumentId'=>'string'], +'Couchbase\ViewQuery::key' => ['Couchbase\ViewQuery', 'key'=>'mixed'], +'Couchbase\ViewQuery::keys' => ['Couchbase\ViewQuery', 'keys'=>'array'], +'Couchbase\ViewQuery::limit' => ['Couchbase\ViewQuery', 'limit'=>'int'], +'Couchbase\ViewQuery::order' => ['Couchbase\ViewQuery', 'order'=>'int'], +'Couchbase\ViewQuery::range' => ['Couchbase\ViewQuery', 'startKey'=>'mixed', 'endKey'=>'mixed', 'inclusiveEnd='=>'bool|false'], +'Couchbase\ViewQuery::reduce' => ['Couchbase\ViewQuery', 'reduce'=>'bool'], +'Couchbase\ViewQuery::skip' => ['Couchbase\ViewQuery', 'skip'=>'int'], +'Couchbase\ViewQueryEncodable::encode' => ['array'], +'Couchbase\WildcardSearchQuery::__construct' => ['void'], +'Couchbase\WildcardSearchQuery::boost' => ['Couchbase\WildcardSearchQuery', 'boost'=>'float'], +'Couchbase\WildcardSearchQuery::field' => ['Couchbase\WildcardSearchQuery', 'field'=>'string'], +'Couchbase\WildcardSearchQuery::jsonSerialize' => ['array'], +'Couchbase\zlibCompress' => ['string', 'data'=>'string'], +'Couchbase\zlibDecompress' => ['string', 'data'=>'string'], +'count' => ['int', 'var'=>'Countable|array', 'mode='=>'int'], +'count_chars' => ['mixed', 'input'=>'string', 'mode='=>'int'], +'Countable::count' => ['int'], +'crack_check' => ['bool', 'dictionary'=>'', 'password'=>'string'], +'crack_closedict' => ['bool', 'dictionary='=>'resource'], +'crack_getlastmessage' => ['string'], +'crack_opendict' => ['resource', 'dictionary'=>'string'], +'crash' => [''], +'crc32' => ['int', 'str'=>'string'], +'create_function' => ['string', 'args'=>'string', 'code'=>'string'], +'crypt' => ['string', 'str'=>'string', 'salt='=>'string'], +'ctype_alnum' => ['bool', 'c'=>'string|int'], +'ctype_alpha' => ['bool', 'c'=>'string|int'], +'ctype_cntrl' => ['bool', 'c'=>'string|int'], +'ctype_digit' => ['bool', 'c'=>'string|int'], +'ctype_graph' => ['bool', 'c'=>'string|int'], +'ctype_lower' => ['bool', 'c'=>'string|int'], +'ctype_print' => ['bool', 'c'=>'string|int'], +'ctype_punct' => ['bool', 'c'=>'string|int'], +'ctype_space' => ['bool', 'c'=>'string|int'], +'ctype_upper' => ['bool', 'c'=>'string|int'], +'ctype_xdigit' => ['bool', 'c'=>'string|int'], +'cubrid_affected_rows' => ['int', 'req_identifier='=>''], +'cubrid_bind' => ['bool', 'req_identifier'=>'resource', 'bind_param'=>'int', 'bind_value'=>'mixed', 'bind_value_type='=>'string'], +'cubrid_client_encoding' => ['string', 'conn_identifier='=>''], +'cubrid_close' => ['bool', 'conn_identifier='=>''], +'cubrid_close_prepare' => ['int', 'req_identifier'=>'resource'], +'cubrid_close_request' => ['bool', 'req_identifier'=>'resource'], +'cubrid_col_get' => ['array', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string'], +'cubrid_col_size' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string'], +'cubrid_column_names' => ['array', 'req_identifier'=>'resource'], +'cubrid_column_types' => ['array', 'req_identifier'=>'resource'], +'cubrid_commit' => ['bool', 'conn_identifier'=>'resource'], +'cubrid_connect' => ['resource', 'host'=>'string', 'port'=>'int', 'dbname'=>'string', 'userid='=>'string', 'passwd='=>'string'], +'cubrid_connect_with_url' => ['resource', 'conn_url'=>'string', 'userid='=>'string', 'passwd='=>'string'], +'cubrid_current_oid' => ['string', 'req_identifier'=>'resource'], +'cubrid_data_seek' => ['bool', 'req_identifier'=>'', 'row_number'=>'int'], +'cubrid_db_name' => ['string', 'result'=>'array', 'index'=>'int'], +'cubrid_db_parameter' => ['array', 'conn_identifier'=>'resource'], +'cubrid_disconnect' => ['bool', 'conn_identifier'=>'resource'], +'cubrid_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'], +'cubrid_errno' => ['int', 'conn_identifier='=>''], +'cubrid_error' => ['string', 'connection='=>''], +'cubrid_error_code' => ['int'], +'cubrid_error_code_facility' => ['int'], +'cubrid_error_msg' => ['string'], +'cubrid_execute' => ['bool', 'conn_identifier'=>'', 'sql'=>'string', 'option='=>'int', 'request_identifier='=>''], +'cubrid_fetch' => ['mixed', 'result'=>'resource', 'type='=>'int'], +'cubrid_fetch_array' => ['array', 'result'=>'', 'type='=>'int'], +'cubrid_fetch_assoc' => ['array', 'result'=>''], +'cubrid_fetch_field' => ['object', 'result'=>'', 'field_offset='=>'int'], +'cubrid_fetch_lengths' => ['array', 'result'=>''], +'cubrid_fetch_object' => ['object', 'result'=>'', 'class_name='=>'string', 'params='=>'array'], +'cubrid_fetch_row' => ['array', 'result'=>''], +'cubrid_field_flags' => ['string', 'result'=>'', 'field_offset'=>'int'], +'cubrid_field_len' => ['int', 'result'=>'', 'field_offset'=>'int'], +'cubrid_field_name' => ['string', 'result'=>'', 'field_offset'=>'int'], +'cubrid_field_seek' => ['bool', 'result'=>'', 'field_offset='=>'int'], +'cubrid_field_table' => ['string', 'result'=>'', 'field_offset'=>'int'], +'cubrid_field_type' => ['string', 'result'=>'', 'field_offset'=>'int'], +'cubrid_free_result' => ['bool', 'req_identifier'=>'resource'], +'cubrid_get' => ['mixed', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr='=>'mixed'], +'cubrid_get_autocommit' => ['bool', 'conn_identifier'=>'resource'], +'cubrid_get_charset' => ['string', 'conn_identifier'=>'resource'], +'cubrid_get_class_name' => ['string', 'conn_identifier'=>'resource', 'oid'=>'string'], +'cubrid_get_client_info' => ['string'], +'cubrid_get_db_parameter' => ['array', 'conn_identifier'=>'resource'], +'cubrid_get_query_timeout' => ['int', 'req_identifier'=>'resource'], +'cubrid_get_server_info' => ['string', 'conn_identifier'=>'resource'], +'cubrid_insert_id' => ['string', 'conn_identifier='=>'resource'], +'cubrid_is_instance' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string'], +'cubrid_list_dbs' => ['array', 'conn_identifier'=>''], +'cubrid_load_from_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string', 'file_name'=>'string'], +'cubrid_lob2_bind' => ['bool', 'req_identifier'=>'resource', 'bind_index'=>'int', 'bind_value'=>'mixed', 'bind_value_type='=>'string'], +'cubrid_lob2_close' => ['bool', 'lob_identifier'=>'resource'], +'cubrid_lob2_export' => ['bool', 'lob_identifier'=>'resource', 'file_name'=>'string'], +'cubrid_lob2_import' => ['bool', 'lob_identifier'=>'resource', 'file_name'=>'string'], +'cubrid_lob2_new' => ['resource', 'conn_identifier='=>'resource', 'type='=>'string'], +'cubrid_lob2_read' => ['string', 'lob_identifier'=>'resource', 'len'=>'int'], +'cubrid_lob2_seek' => ['bool', 'lob_identifier'=>'resource', 'offset'=>'int', 'origin='=>'int'], +'cubrid_lob2_seek64' => ['bool', 'lob_identifier'=>'resource', 'offset'=>'string', 'origin='=>'int'], +'cubrid_lob2_size' => ['int', 'lob_identifier'=>'resource'], +'cubrid_lob2_size64' => ['string', 'lob_identifier'=>'resource'], +'cubrid_lob2_tell' => ['int', 'lob_identifier'=>'resource'], +'cubrid_lob2_tell64' => ['string', 'lob_identifier'=>'resource'], +'cubrid_lob2_write' => ['bool', 'lob_identifier'=>'resource', 'buf'=>'string'], +'cubrid_lob_close' => ['bool', 'lob_identifier_array'=>'array'], +'cubrid_lob_export' => ['bool', 'conn_identifier'=>'resource', 'lob_identifier'=>'resource', 'path_name'=>'string'], +'cubrid_lob_get' => ['array', 'conn_identifier'=>'resource', 'sql'=>'string'], +'cubrid_lob_send' => ['bool', 'conn_identifier'=>'resource', 'lob_identifier'=>'resource'], +'cubrid_lob_size' => ['string', 'lob_identifier'=>'resource'], +'cubrid_lock_read' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'], +'cubrid_lock_write' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string'], +'cubrid_move_cursor' => ['int', 'req_identifier'=>'resource', 'offset'=>'int', 'origin='=>'int'], +'cubrid_new_glo' => ['string', 'conn_identifier'=>'', 'class_name'=>'string', 'file_name'=>'string'], +'cubrid_next_result' => ['bool', 'result'=>'resource'], +'cubrid_num_cols' => ['int', 'req_identifier'=>'resource'], +'cubrid_num_fields' => ['int', 'result'=>''], +'cubrid_num_rows' => ['int', 'req_identifier'=>'resource'], +'cubrid_pconnect' => ['resource', 'host'=>'string', 'port'=>'int', 'dbname'=>'string', 'userid='=>'string', 'passwd='=>'string'], +'cubrid_pconnect_with_url' => ['resource', 'conn_url'=>'string', 'userid='=>'string', 'passwd='=>'string'], +'cubrid_ping' => ['bool', 'conn_identifier='=>''], +'cubrid_prepare' => ['resource', 'conn_identifier'=>'resource', 'prepare_stmt'=>'string', 'option='=>'int'], +'cubrid_put' => ['int', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr='=>'string', 'value='=>'mixed'], +'cubrid_query' => ['resource', 'query'=>'string', 'conn_identifier='=>''], +'cubrid_real_escape_string' => ['string', 'unescaped_string'=>'string', 'conn_identifier='=>''], +'cubrid_result' => ['string', 'result'=>'', 'row'=>'int', 'field='=>''], +'cubrid_rollback' => ['bool', 'conn_identifier'=>'resource'], +'cubrid_save_to_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string', 'file_name'=>'string'], +'cubrid_schema' => ['array', 'conn_identifier'=>'resource', 'schema_type'=>'int', 'class_name='=>'string', 'attr_name='=>'string'], +'cubrid_send_glo' => ['int', 'conn_identifier'=>'', 'oid'=>'string'], +'cubrid_seq_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int'], +'cubrid_seq_insert' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int', 'seq_element'=>'string'], +'cubrid_seq_put' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'index'=>'int', 'seq_element'=>'string'], +'cubrid_set_add' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'set_element'=>'string'], +'cubrid_set_autocommit' => ['bool', 'conn_identifier'=>'resource', 'mode'=>'bool'], +'cubrid_set_db_parameter' => ['bool', 'conn_identifier'=>'resource', 'param_type'=>'int', 'param_value'=>'int'], +'cubrid_set_drop' => ['bool', 'conn_identifier'=>'resource', 'oid'=>'string', 'attr_name'=>'string', 'set_element'=>'string'], +'cubrid_set_query_timeout' => ['bool', 'req_identifier'=>'resource', 'timeout'=>'int'], +'cubrid_unbuffered_query' => ['resource', 'query'=>'string', 'conn_identifier='=>''], +'cubrid_version' => ['string'], +'curl_close' => ['void', 'ch'=>'resource'], +'curl_copy_handle' => ['resource', 'ch'=>'resource'], +'curl_errno' => ['int', 'ch'=>'resource'], +'curl_error' => ['string', 'ch'=>'resource'], +'curl_escape' => ['string', 'ch'=>'resource', 'str'=>'string'], +'curl_exec' => ['bool|string', 'ch'=>'resource'], +'curl_file_create' => ['CURLFile', 'filename'=>'string', 'mimetype='=>'string', 'postfilename='=>'string'], +'curl_getinfo' => ['mixed', 'ch'=>'resource', 'option='=>'int'], +'curl_init' => ['resource|false', 'url='=>'string'], +'curl_multi_add_handle' => ['int', 'mh'=>'resource', 'ch'=>'resource'], +'curl_multi_close' => ['void', 'mh'=>'resource'], +'curl_multi_errno' => ['int', 'mh'=>'resource'], +'curl_multi_exec' => ['int', 'mh'=>'resource', '&w_still_running'=>'int'], +'curl_multi_getcontent' => ['string', 'ch'=>'resource'], +'curl_multi_info_read' => ['array|false', 'mh'=>'resource', 'msgs_in_queue='=>'int'], +'curl_multi_init' => ['resource|false'], +'curl_multi_remove_handle' => ['int', 'mh'=>'resource', 'ch'=>'resource'], +'curl_multi_select' => ['int', 'mh'=>'resource', 'timeout='=>'float'], +'curl_multi_setopt' => ['bool', 'mh'=>'resource', 'option'=>'int', 'value'=>'mixed'], +'curl_multi_strerror' => ['string', 'code'=>'int'], +'curl_pause' => ['int', 'ch'=>'resource', 'bitmask'=>'int'], +'curl_reset' => ['void', 'ch'=>'resource'], +'curl_setopt' => ['bool', 'ch'=>'resource', 'option'=>'int', 'value'=>'mixed'], +'curl_setopt_array' => ['bool', 'ch'=>'resource', 'options'=>'array'], +'curl_share_close' => ['void', 'sh'=>'resource'], +'curl_share_errno' => ['int', 'sh'=>'resource'], +'curl_share_init' => ['resource'], +'curl_share_setopt' => ['bool', 'sh'=>'resource', 'option'=>'int', 'value'=>'string'], +'curl_share_strerror' => ['string', 'code'=>'int'], +'curl_strerror' => ['string', 'code'=>'int'], +'curl_unescape' => ['string', 'ch'=>'resource', 'str'=>'string'], +'curl_version' => ['array', 'version='=>'int'], +'CURLFile::__construct' => ['void', 'filename'=>'string', 'mimetype='=>'string', 'postfilename='=>'string'], +'CURLFile::__wakeup' => ['void'], +'CURLFile::getFilename' => ['string'], +'CURLFile::getMimeType' => ['string'], +'CURLFile::getPostFilename' => ['string'], +'CURLFile::setMimeType' => ['void', 'mime'=>'string'], +'CURLFile::setPostFilename' => ['void', 'name'=>'string'], +'current' => ['mixed', 'array_arg'=>'array|object'], +'cyrus_authenticate' => ['void', 'connection'=>'resource', 'mechlist='=>'string', 'service='=>'string', 'user='=>'string', 'minssf='=>'int', 'maxssf='=>'int', 'authname='=>'string', 'password='=>'string'], +'cyrus_bind' => ['bool', 'connection'=>'resource', 'callbacks'=>'array'], +'cyrus_close' => ['bool', 'connection'=>'resource'], +'cyrus_connect' => ['resource', 'host='=>'string', 'port='=>'string', 'flags='=>'int'], +'cyrus_query' => ['array', 'connection'=>'resource', 'query'=>'string'], +'cyrus_unbind' => ['bool', 'connection'=>'resource', 'trigger_name'=>'string'], +'date' => ['string', 'format'=>'string', 'timestamp='=>'int'], +'date_add' => ['DateTime|false', 'object'=>'', 'interval'=>''], +'date_create' => ['DateTime|false', 'time='=>'string|null', 'timezone='=>'?\DateTimeZone'], +'date_create_from_format' => ['DateTime|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'DateTimeZone'], +'date_create_immutable' => ['DateTimeImmutable|false', 'time='=>'string', 'timezone='=>'?\DateTimeZone'], +'date_create_immutable_from_format' => ['DateTimeImmutable', 'format'=>'string', 'time'=>'string', 'timezone='=>'?\DateTimeZone'], +'date_date_set' => ['DateTime|false', 'object'=>'', 'year'=>'', 'month'=>'', 'day'=>''], +'date_default_timezone_get' => ['string'], +'date_default_timezone_set' => ['bool', 'timezone_identifier'=>'string'], +'date_diff' => ['DateInterval', 'obj1'=>'DateTimeInterface', 'obj2'=>'DateTimeInterface', 'absolute='=>'bool'], +'date_format' => ['string', 'obj'=>'DateTimeInterface', 'format'=>'string'], +'date_get_last_errors' => ['array'], +'date_interval_create_from_date_string' => ['DateInterval', 'time'=>''], +'date_interval_format' => ['DateInterval', 'object'=>'', 'format'=>''], +'date_isodate_set' => ['DateTime|false', 'object'=>'DateTime', 'year'=>'int', 'week'=>'int', 'day='=>'int|mixed'], +'date_modify' => ['DateTime|false', 'object'=>'DateTime', 'modify'=>'string'], +'date_offset_get' => ['int', 'obj'=>'DateTimeInterface'], +'date_parse' => ['array', 'date'=>'string'], +'date_parse_from_format' => ['array', 'format'=>'string', 'date'=>'string'], +'date_sub' => ['DateTime|false', 'object'=>'DateTime', 'interval'=>'DateInterval'], +'date_sun_info' => ['array', 'time'=>'int', 'latitude'=>'float', 'longitude'=>'float'], +'date_sunrise' => ['mixed', 'time'=>'int', 'format='=>'int', 'latitude='=>'float', 'longitude='=>'float', 'zenith='=>'float', 'gmt_offset='=>'float'], +'date_sunset' => ['mixed', 'time'=>'int', 'format='=>'int', 'latitude='=>'float', 'longitude='=>'float', 'zenith='=>'float', 'gmt_offset='=>'float'], +'date_time_set' => ['DateTime|false', 'object'=>'', 'hour'=>'', 'minute'=>'', 'second'=>'', 'microseconds'=>''], +'date_timestamp_get' => ['int', 'obj'=>'DateTimeInterface'], +'date_timestamp_set' => ['DateTime|false', 'object'=>'DateTime', 'unixtimestamp'=>'int'], +'date_timezone_get' => ['DateTimeZone', 'obj'=>'DateTimeInterface'], +'date_timezone_set' => ['DateTime|false', 'object'=>'DateTime', 'timezone'=>'DateTimeZone'], +'datefmt_create' => ['IntlDateFormatter', 'locale'=>'string', 'datetype'=>'int', 'timetype'=>'int', 'timezone='=>'int', 'calendar='=>'int|IntlCalendar', 'pattern='=>'string'], +'datefmt_format' => ['string', 'fmt'=>'IntlDateFormatter', 'value'=>'DateTime|IntlCalendar|array|int'], +'datefmt_format_object' => ['string', 'object'=>'object', 'format='=>'mixed', 'locale='=>'string'], +'datefmt_get_calendar' => ['int', 'fmt'=>'IntlDateFormatter'], +'datefmt_get_calendar_object' => ['IntlCalendar', 'fmt'=>'IntlDateFormatter'], +'datefmt_get_datetype' => ['int', 'fmt'=>'IntlDateFormatter'], +'datefmt_get_error_code' => ['int', 'fmt'=>'IntlDateFormatter'], +'datefmt_get_error_message' => ['string', 'fmt'=>'IntlDateFormatter'], +'datefmt_get_locale' => ['string', 'fmt'=>'IntlDateFormatter', 'which='=>'int'], +'datefmt_get_pattern' => ['string', 'fmt'=>'IntlDateFormatter'], +'datefmt_get_timetype' => ['int', 'fmt'=>'IntlDateFormatter'], +'datefmt_get_timezone' => ['IntlTimeZone'], +'datefmt_get_timezone_id' => ['string', 'fmt'=>'IntlDateFormatter'], +'datefmt_is_lenient' => ['bool', 'fmt'=>'IntlDateFormatter'], +'datefmt_localtime' => ['array|bool', 'fmt'=>'IntlDateFormatter', 'text_to_parse='=>'string', '&rw_parse_pos='=>'int'], +'datefmt_parse' => ['int|false', 'fmt'=>'IntlDateFormatter', 'text_to_parse='=>'string', '&rw_parse_pos='=>'int'], +'datefmt_set_calendar' => ['bool', 'fmt'=>'IntlDateFormatter', 'which'=>'int'], +'datefmt_set_lenient' => ['?bool', 'fmt'=>'IntlDateFormatter', 'lenient'=>'bool'], +'datefmt_set_pattern' => ['bool', 'fmt'=>'IntlDateFormatter', 'pattern'=>'string'], +'datefmt_set_timezone' => ['bool', 'zone'=>'mixed'], +'datefmt_set_timezone_id' => ['bool', 'fmt'=>'IntlDateFormatter', 'zone'=>'string'], +'DateInterval::__construct' => ['void', 'spec'=>'string'], +'DateInterval::__set_state' => ['DateInterval', 'array'=>'array'], +'DateInterval::__wakeup' => ['void'], +'DateInterval::createFromDateString' => ['DateInterval', 'time'=>'string'], +'DateInterval::format' => ['string', 'format'=>'string'], +'DatePeriod::__construct' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'recur'=>'int', 'options='=>'int'], +'DatePeriod::__construct\'1' => ['void', 'start'=>'DateTimeInterface', 'interval'=>'DateInterval', 'end'=>'DateTimeInterface', 'options='=>'int'], +'DatePeriod::__construct\'2' => ['void', 'iso'=>'string', 'options='=>'int'], +'DatePeriod::__wakeup' => ['void'], +'DatePeriod::getDateInterval' => ['DateInterval'], +'DatePeriod::getEndDate' => ['DateTimeInterface'], +'DatePeriod::getStartDate' => ['DateTimeInterface'], +'DateTime::__construct' => ['void', 'time='=>'string|null', 'timezone='=>'?DateTimeZone'], +'DateTime::__set_state' => ['static', 'array'=>'array'], +'DateTime::__wakeup' => ['void'], +'DateTime::add' => ['static', 'interval'=>'DateInterval'], +'DateTime::createFromFormat' => ['static|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'DateTimeZone|null'], +'DateTime::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'], +'DateTime::format' => ['string', 'format'=>'string'], +'DateTime::getLastErrors' => ['array'], +'DateTime::getOffset' => ['int'], +'DateTime::getTimestamp' => ['int'], +'DateTime::getTimezone' => ['DateTimeZone'], +'DateTime::modify' => ['static', 'modify'=>'string'], +'DateTime::setDate' => ['static', 'year'=>'int', 'month'=>'int', 'day'=>'int'], +'DateTime::setISODate' => ['static', 'year'=>'int', 'week'=>'int', 'day='=>'int'], +'DateTime::setTime' => ['static', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'], +'DateTime::setTimestamp' => ['static', 'unixtimestamp'=>'int'], +'DateTime::setTimezone' => ['static', 'timezone'=>'DateTimeZone'], +'DateTime::sub' => ['static', 'interval'=>'DateInterval'], +'DateTimeImmutable::__construct' => ['void', 'time='=>'string|null', 'timezone='=>'?DateTimeZone'], +'DateTimeImmutable::__set_state' => ['static', 'array'=>'array'], +'DateTimeImmutable::__wakeup' => ['void'], +'DateTimeImmutable::add' => ['static', 'interval'=>'DateInterval'], +'DateTimeImmutable::createFromFormat' => ['static|false', 'format'=>'string', 'time'=>'string', 'timezone='=>'DateTimeZone|null'], +'DateTimeImmutable::createFromMutable' => ['static', 'datetime'=>'DateTime'], +'DateTimeImmutable::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'], +'DateTimeImmutable::format' => ['string', 'format'=>'string'], +'DateTimeImmutable::getLastErrors' => ['array'], +'DateTimeImmutable::getOffset' => ['int'], +'DateTimeImmutable::getTimestamp' => ['int'], +'DateTimeImmutable::getTimezone' => ['DateTimeZone'], +'DateTimeImmutable::modify' => ['static', 'modify'=>'string'], +'DateTimeImmutable::setDate' => ['static', 'year'=>'int', 'month'=>'int', 'day'=>'int'], +'DateTimeImmutable::setISODate' => ['static', 'year'=>'int', 'week'=>'int', 'day='=>'int'], +'DateTimeImmutable::setTime' => ['static', 'hour'=>'int', 'minute'=>'int', 'second='=>'int', 'microseconds='=>'int'], +'DateTimeImmutable::setTimestamp' => ['static', 'unixtimestamp'=>'int'], +'DateTimeImmutable::setTimezone' => ['static', 'timezone'=>'DateTimeZone'], +'DateTimeImmutable::sub' => ['static', 'interval'=>'DateInterval'], +'DateTimeInterface::diff' => ['DateInterval', 'datetime2'=>'DateTimeInterface', 'absolute='=>'bool'], +'DateTimeInterface::format' => ['string', 'format'=>'string'], +'DateTimeInterface::getOffset' => ['int'], +'DateTimeInterface::getTimestamp' => ['int'], +'DateTimeInterface::getTimezone' => ['DateTimeZone'], +'DateTimeZone::__construct' => ['void', 'timezone'=>'string'], +'DateTimeZone::__set_state' => ['DateTimeZone', 'array'=>'array'], +'DateTimeZone::__wakeup' => ['void'], +'DateTimeZone::getLocation' => ['array'], +'DateTimeZone::getName' => ['string'], +'DateTimeZone::getOffset' => ['int', 'datetime'=>'DateTimeInterface'], +'DateTimeZone::getTransitions' => ['array', 'timestamp_begin='=>'int', 'timestamp_end='=>'int'], +'DateTimeZone::listAbbreviations' => ['array'], +'DateTimeZone::listIdentifiers' => ['array', 'what='=>'int', 'country='=>'string'], +'db2_autocommit' => ['mixed', 'connection'=>'resource', 'value='=>'int'], +'db2_bind_param' => ['bool', 'stmt'=>'resource', 'parameter_number'=>'int', 'variable_name'=>'string', 'parameter_type='=>'int', 'data_type='=>'int', 'precision='=>'int', 'scale='=>'int'], +'db2_client_info' => ['object|false', 'connection'=>'resource'], +'db2_close' => ['bool', 'connection'=>'resource'], +'db2_column_privileges' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'column_name='=>'string'], +'db2_columns' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'column_name='=>'string'], +'db2_commit' => ['bool', 'connection'=>'resource'], +'db2_conn_error' => ['string', 'connection='=>'resource'], +'db2_conn_errormsg' => ['string', 'connection='=>'resource'], +'db2_connect' => ['resource|false', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'options='=>'array'], +'db2_cursor_type' => ['int', 'stmt'=>'resource'], +'db2_escape_string' => ['string', 'string_literal'=>'string'], +'db2_exec' => ['resource|false', 'connection'=>'resource', 'statement'=>'string', 'options='=>'array'], +'db2_execute' => ['bool', 'stmt'=>'resource', 'parameters='=>'array'], +'db2_fetch_array' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'], +'db2_fetch_assoc' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'], +'db2_fetch_both' => ['array|false', 'stmt'=>'resource', 'row_number='=>'int'], +'db2_fetch_object' => ['object|false', 'stmt'=>'resource', 'row_number='=>'int'], +'db2_fetch_row' => ['bool', 'stmt'=>'resource', 'row_number='=>'int'], +'db2_field_display_size' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], +'db2_field_name' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'], +'db2_field_num' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], +'db2_field_precision' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], +'db2_field_scale' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], +'db2_field_type' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'], +'db2_field_width' => ['int|false', 'stmt'=>'resource', 'column'=>'mixed'], +'db2_foreign_keys' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string'], +'db2_free_result' => ['bool', 'stmt'=>'resource'], +'db2_free_stmt' => ['bool', 'stmt'=>'resource'], +'db2_get_option' => ['string|false', 'resource'=>'resource', 'option'=>'string'], +'db2_last_insert_id' => ['string', 'resource'=>'resource'], +'db2_lob_read' => ['string|false', 'stmt'=>'resource', 'colnum'=>'int', 'length'=>'int'], +'db2_next_result' => ['resource|false', 'stmt'=>'resource'], +'db2_num_fields' => ['int|false', 'stmt'=>'resource'], +'db2_num_rows' => ['int', 'stmt'=>'resource'], +'db2_pclose' => ['bool', 'resource'=>'resource'], +'db2_pconnect' => ['resource|false', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'options='=>'array'], +'db2_prepare' => ['resource|false', 'connection'=>'resource', 'statement'=>'string', 'options='=>'array'], +'db2_primary_keys' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string'], +'db2_primarykeys' => [''], +'db2_procedure_columns' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'procedure'=>'string', 'parameter'=>'string'], +'db2_procedurecolumns' => [''], +'db2_procedures' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'procedure'=>'string'], +'db2_result' => ['mixed', 'stmt'=>'resource', 'column'=>'mixed'], +'db2_rollback' => ['bool', 'connection'=>'resource'], +'db2_server_info' => ['object|false', 'connection'=>'resource'], +'db2_set_option' => ['bool', 'resource'=>'resource', 'options'=>'array', 'type'=>'int'], +'db2_setoption' => [''], +'db2_special_columns' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string', 'scope'=>'int'], +'db2_specialcolumns' => [''], +'db2_statistics' => ['resource|false', 'connection'=>'resource', 'qualifier'=>'string', 'schema'=>'string', 'table_name'=>'string', 'unique'=>'bool'], +'db2_stmt_error' => ['string', 'stmt='=>'resource'], +'db2_stmt_errormsg' => ['string', 'stmt='=>'resource'], +'db2_table_privileges' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string'], +'db2_tableprivileges' => [''], +'db2_tables' => ['resource|false', 'connection'=>'resource', 'qualifier='=>'string', 'schema='=>'string', 'table_name='=>'string', 'table_type='=>'string'], +'dba_close' => ['void', 'handle'=>'resource'], +'dba_delete' => ['bool', 'key'=>'string', 'handle'=>'resource'], +'dba_exists' => ['bool', 'key'=>'string', 'handle'=>'resource'], +'dba_fetch' => ['string', 'key'=>'string', 'skip'=>'int', 'handle'=>'resource'], +'dba_fetch\'1' => ['string', 'key'=>'string', 'handle'=>'resource'], +'dba_firstkey' => ['string', 'handle'=>'resource'], +'dba_handlers' => ['array', 'full_info='=>'bool'], +'dba_insert' => ['bool', 'key'=>'string', 'value'=>'string', 'handle'=>'resource'], +'dba_key_split' => ['array|false', 'key'=>'string'], +'dba_list' => ['array'], +'dba_nextkey' => ['string', 'handle'=>'resource'], +'dba_open' => ['resource', 'path'=>'string', 'mode'=>'string', 'handlername='=>'string', '...args='=>'string'], +'dba_optimize' => ['bool', 'handle'=>'resource'], +'dba_popen' => ['resource', 'path'=>'string', 'mode'=>'string', 'handlername='=>'string', '...args='=>'string'], +'dba_replace' => ['bool', 'key'=>'string', 'value'=>'string', 'handle'=>'resource'], +'dba_sync' => ['bool', 'handle'=>'resource'], +'dbase_add_record' => ['bool', 'dbase_identifier'=>'int', 'record'=>'array'], +'dbase_close' => ['bool', 'dbase_identifier'=>'int'], +'dbase_create' => ['int', 'filename'=>'string', 'fields'=>'array'], +'dbase_delete_record' => ['bool', 'dbase_identifier'=>'int', 'record_number'=>'int'], +'dbase_get_header_info' => ['array', 'dbase_identifier'=>'int'], +'dbase_get_record' => ['array', 'dbase_identifier'=>'int', 'record_number'=>'int'], +'dbase_get_record_with_names' => ['array', 'dbase_identifier'=>'int', 'record_number'=>'int'], +'dbase_numfields' => ['int', 'dbase_identifier'=>'int'], +'dbase_numrecords' => ['int', 'dbase_identifier'=>'int'], +'dbase_open' => ['int', 'filename'=>'string', 'mode'=>'int'], +'dbase_pack' => ['bool', 'dbase_identifier'=>'int'], +'dbase_replace_record' => ['bool', 'dbase_identifier'=>'int', 'record'=>'array', 'record_number'=>'int'], +'dbplus_add' => ['int', 'relation'=>'resource', 'tuple'=>'array'], +'dbplus_aql' => ['resource', 'query'=>'string', 'server='=>'string', 'dbpath='=>'string'], +'dbplus_chdir' => ['string', 'newdir='=>'string'], +'dbplus_close' => ['mixed', 'relation'=>'resource'], +'dbplus_curr' => ['int', 'relation'=>'resource', 'tuple'=>'array'], +'dbplus_errcode' => ['string', 'errno='=>'int'], +'dbplus_errno' => ['int'], +'dbplus_find' => ['int', 'relation'=>'resource', 'constraints'=>'array', 'tuple'=>'mixed'], +'dbplus_first' => ['int', 'relation'=>'resource', 'tuple'=>'array'], +'dbplus_flush' => ['int', 'relation'=>'resource'], +'dbplus_freealllocks' => ['int'], +'dbplus_freelock' => ['int', 'relation'=>'resource', 'tuple'=>'string'], +'dbplus_freerlocks' => ['int', 'relation'=>'resource'], +'dbplus_getlock' => ['int', 'relation'=>'resource', 'tuple'=>'string'], +'dbplus_getunique' => ['int', 'relation'=>'resource', 'uniqueid'=>'int'], +'dbplus_info' => ['int', 'relation'=>'resource', 'key'=>'string', 'result'=>'array'], +'dbplus_last' => ['int', 'relation'=>'resource', 'tuple'=>'array'], +'dbplus_lockrel' => ['int', 'relation'=>'resource'], +'dbplus_next' => ['int', 'relation'=>'resource', 'tuple'=>'array'], +'dbplus_open' => ['resource', 'name'=>'string'], +'dbplus_prev' => ['int', 'relation'=>'resource', 'tuple'=>'array'], +'dbplus_rchperm' => ['int', 'relation'=>'resource', 'mask'=>'int', 'user'=>'string', 'group'=>'string'], +'dbplus_rcreate' => ['resource', 'name'=>'string', 'domlist'=>'mixed', 'overwrite='=>'bool'], +'dbplus_rcrtexact' => ['mixed', 'name'=>'string', 'relation'=>'resource', 'overwrite='=>'bool'], +'dbplus_rcrtlike' => ['mixed', 'name'=>'string', 'relation'=>'resource', 'overwrite='=>'int'], +'dbplus_resolve' => ['array', 'relation_name'=>'string'], +'dbplus_restorepos' => ['int', 'relation'=>'resource', 'tuple'=>'array'], +'dbplus_rkeys' => ['mixed', 'relation'=>'resource', 'domlist'=>'mixed'], +'dbplus_ropen' => ['resource', 'name'=>'string'], +'dbplus_rquery' => ['resource', 'query'=>'string', 'dbpath='=>'string'], +'dbplus_rrename' => ['int', 'relation'=>'resource', 'name'=>'string'], +'dbplus_rsecindex' => ['mixed', 'relation'=>'resource', 'domlist'=>'mixed', 'type'=>'int'], +'dbplus_runlink' => ['int', 'relation'=>'resource'], +'dbplus_rzap' => ['int', 'relation'=>'resource'], +'dbplus_savepos' => ['int', 'relation'=>'resource'], +'dbplus_setindex' => ['int', 'relation'=>'resource', 'idx_name'=>'string'], +'dbplus_setindexbynumber' => ['int', 'relation'=>'resource', 'idx_number'=>'int'], +'dbplus_sql' => ['resource', 'query'=>'string', 'server='=>'string', 'dbpath='=>'string'], +'dbplus_tcl' => ['string', 'sid'=>'int', 'script'=>'string'], +'dbplus_tremove' => ['int', 'relation'=>'resource', 'tuple'=>'array', 'current='=>'array'], +'dbplus_undo' => ['int', 'relation'=>'resource'], +'dbplus_undoprepare' => ['int', 'relation'=>'resource'], +'dbplus_unlockrel' => ['int', 'relation'=>'resource'], +'dbplus_unselect' => ['int', 'relation'=>'resource'], +'dbplus_update' => ['int', 'relation'=>'resource', 'old'=>'array', 'new'=>'array'], +'dbplus_xlockrel' => ['int', 'relation'=>'resource'], +'dbplus_xunlockrel' => ['int', 'relation'=>'resource'], +'dbx_close' => ['int', 'link_identifier'=>'object'], +'dbx_compare' => ['int', 'row_a'=>'array', 'row_b'=>'array', 'column_key'=>'string', 'flags='=>'int'], +'dbx_connect' => ['object', 'module'=>'mixed', 'host'=>'string', 'database'=>'string', 'username'=>'string', 'password'=>'string', 'persistent='=>'int'], +'dbx_error' => ['string', 'link_identifier'=>'object'], +'dbx_escape_string' => ['string', 'link_identifier'=>'object', 'text'=>'string'], +'dbx_fetch_row' => ['mixed', 'result_identifier'=>'object'], +'dbx_query' => ['mixed', 'link_identifier'=>'object', 'sql_statement'=>'string', 'flags='=>'int'], +'dbx_sort' => ['bool', 'result'=>'object', 'user_compare_function'=>'string'], +'dcgettext' => ['string', 'domain_name'=>'string', 'msgid'=>'string', 'category'=>'int'], +'dcngettext' => ['string', 'domain'=>'string', 'msgid1'=>'string', 'msgid2'=>'string', 'n'=>'int', 'category'=>'int'], +'deaggregate' => ['', 'object'=>'object', 'class_name='=>'string'], +'debug_backtrace' => ['array', 'options='=>'int|bool', 'limit='=>'int'], +'debug_print_backtrace' => ['void', 'options='=>'int|bool', 'limit='=>'int'], +'debug_zval_dump' => ['void', '...var'=>'mixed'], +'debugger_connect' => [''], +'debugger_connector_pid' => [''], +'debugger_get_server_start_time' => [''], +'debugger_print' => [''], +'debugger_start_debug' => [''], +'decbin' => ['string', 'decimal_number'=>'int'], +'dechex' => ['string', 'decimal_number'=>'int'], +'decoct' => ['string', 'decimal_number'=>'int'], +'define' => ['bool', 'constant_name'=>'string', 'value'=>'mixed', 'case_insensitive='=>'bool'], +'define_syslog_variables' => ['void'], +'defined' => ['bool', 'name'=>'string'], +'deflate_add' => ['string|false', 'context'=>'resource', 'data'=>'string', 'flush_mode='=>'int'], +'deflate_init' => ['resource|false', 'encoding'=>'int', 'options='=>'array'], +'deg2rad' => ['float', 'number'=>'float'], +'dgettext' => ['string', 'domain_name'=>'string', 'msgid'=>'string'], +'dio_close' => ['void', 'fd'=>'resource'], +'dio_fcntl' => ['mixed', 'fd'=>'resource', 'cmd'=>'int', 'args='=>'mixed'], +'dio_open' => ['resource', 'filename'=>'string', 'flags'=>'int', 'mode='=>'int'], +'dio_read' => ['string', 'fd'=>'resource', 'len='=>'int'], +'dio_seek' => ['int', 'fd'=>'resource', 'pos'=>'int', 'whence='=>'int'], +'dio_stat' => ['array|null', 'fd'=>'resource'], +'dio_tcsetattr' => ['bool', 'fd'=>'resource', 'options'=>'array'], +'dio_truncate' => ['bool', 'fd'=>'resource', 'offset'=>'int'], +'dio_write' => ['int', 'fd'=>'resource', 'data'=>'string', 'len='=>'int'], +'dir' => ['Directory|false', 'directory'=>'string', 'context='=>'resource'], +'Directory::close' => ['void', 'dir_handle='=>'resource'], +'Directory::read' => ['string|false', 'dir_handle='=>'resource'], +'Directory::rewind' => ['void', 'dir_handle='=>'resource'], +'DirectoryIterator::__construct' => ['void', 'path'=>'string'], +'DirectoryIterator::__toString' => ['string'], +'DirectoryIterator::current' => ['DirectoryIterator'], +'DirectoryIterator::getATime' => ['int'], +'DirectoryIterator::getBasename' => ['string', 'suffix='=>'string'], +'DirectoryIterator::getChildren' => ['RecursiveDirectoryIterator'], +'DirectoryIterator::getCTime' => ['int'], +'DirectoryIterator::getExtension' => ['string'], +'DirectoryIterator::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'], +'DirectoryIterator::getFilename' => ['string'], +'DirectoryIterator::getGroup' => ['int'], +'DirectoryIterator::getInode' => ['int'], +'DirectoryIterator::getLinkTarget' => ['string'], +'DirectoryIterator::getMTime' => ['int'], +'DirectoryIterator::getOwner' => ['int'], +'DirectoryIterator::getPath' => ['string'], +'DirectoryIterator::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'], +'DirectoryIterator::getPathname' => ['string'], +'DirectoryIterator::getPerms' => ['int'], +'DirectoryIterator::getRealPath' => ['string'], +'DirectoryIterator::getSize' => ['int'], +'DirectoryIterator::getType' => ['string'], +'DirectoryIterator::isDir' => ['bool'], +'DirectoryIterator::isDot' => ['bool'], +'DirectoryIterator::isExecutable' => ['bool'], +'DirectoryIterator::isFile' => ['bool'], +'DirectoryIterator::isLink' => ['bool'], +'DirectoryIterator::isReadable' => ['bool'], +'DirectoryIterator::isWritable' => ['bool'], +'DirectoryIterator::key' => ['string'], +'DirectoryIterator::next' => ['void'], +'DirectoryIterator::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'], +'DirectoryIterator::rewind' => ['void'], +'DirectoryIterator::seek' => ['void', 'position'=>'int'], +'DirectoryIterator::setFileClass' => ['void', 'class_name='=>'string'], +'DirectoryIterator::setInfoClass' => ['void', 'class_name='=>'string'], +'DirectoryIterator::valid' => ['bool'], +'dirname' => ['string', 'path'=>'string', 'levels='=>'int'], +'disk_free_space' => ['float|false', 'path'=>'string'], +'disk_total_space' => ['float', 'path'=>'string'], +'diskfreespace' => ['', 'path'=>''], +'display_disabled_function' => [''], +'dl' => ['int', 'extension_filename'=>'string'], +'dngettext' => ['string', 'domain'=>'string', 'msgid1'=>'string', 'msgid2'=>'string', 'count'=>'int'], +'dns_check_record' => ['bool', 'host'=>'string', 'type='=>'string'], +'dns_get_mx' => ['bool', 'hostname'=>'string', '&w_mxhosts'=>'array', '&w_weight'=>'array'], +'dns_get_record' => ['array|false', 'hostname'=>'string', 'type='=>'int', '&w_authns='=>'array', '&w_addtl='=>'array', 'raw='=>'bool'], +'dom_document_relaxNG_validate_file' => ['bool', 'filename'=>'string'], +'dom_document_relaxNG_validate_xml' => ['bool', 'source'=>'string'], +'dom_document_schema_validate' => ['bool', 'source'=>'string', 'flags'=>'int'], +'dom_document_schema_validate_file' => ['bool', 'filename'=>'string', 'flags'=>'int'], +'dom_document_xinclude' => ['int', 'options'=>'int'], +'dom_import_simplexml' => ['DOMElement|false', 'node'=>'SimpleXMLElement'], +'dom_xpath_evaluate' => ['', 'expr'=>'string', 'context'=>'DOMNode', 'registernodens'=>'bool'], +'dom_xpath_query' => ['DOMNodeList', 'expr'=>'string', 'context'=>'DOMNode', 'registernodens'=>'bool'], +'dom_xpath_register_ns' => ['bool', 'prefix'=>'string', 'uri'=>'string'], +'dom_xpath_register_php_functions' => [''], +'DomainException::__clone' => ['void'], +'DomainException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?DomainException'], +'DomainException::__toString' => ['string'], +'DomainException::__wakeup' => ['void'], +'DomainException::getCode' => ['int'], +'DomainException::getFile' => ['string'], +'DomainException::getLine' => ['int'], +'DomainException::getMessage' => ['string'], +'DomainException::getPrevious' => ['Throwable|DomainException|null'], +'DomainException::getTrace' => ['array'], +'DomainException::getTraceAsString' => ['string'], +'DOMAttr::__construct' => ['void', 'name'=>'string', 'value='=>'string'], +'DOMAttr::isId' => ['bool'], +'DomAttribute::name' => ['string'], +'DomAttribute::set_value' => ['bool', 'content'=>'string'], +'DomAttribute::specified' => ['bool'], +'DomAttribute::value' => ['string'], +'DOMCdataSection::__construct' => ['void', 'value'=>'string'], +'DOMCharacterData::appendData' => ['void', 'data'=>'string'], +'DOMCharacterData::deleteData' => ['void', 'offset'=>'int', 'count'=>'int'], +'DOMCharacterData::insertData' => ['void', 'offset'=>'int', 'data'=>'string'], +'DOMCharacterData::replaceData' => ['void', 'offset'=>'int', 'count'=>'int', 'data'=>'string'], +'DOMCharacterData::substringData' => ['string', 'offset'=>'int', 'count'=>'int'], +'DOMComment::__construct' => ['void', 'value='=>'string'], +'DOMDocument::__construct' => ['void', 'version='=>'string', 'encoding='=>'string'], +'DOMDocument::createAttribute' => ['DOMAttr', 'name'=>'string'], +'DOMDocument::createAttributeNS' => ['DOMAttr', 'namespaceuri'=>'string', 'qualifiedname'=>'string'], +'DOMDocument::createCDATASection' => ['DOMCDATASection', 'data'=>'string'], +'DOMDocument::createComment' => ['DOMComment', 'data'=>'string'], +'DOMDocument::createDocumentFragment' => ['DOMDocumentFragment'], +'DOMDocument::createElement' => ['DOMElement', 'name'=>'string', 'value='=>'string'], +'DOMDocument::createElementNS' => ['DOMElement', 'namespaceuri'=>'string', 'qualifiedname'=>'string', 'value='=>'string'], +'DOMDocument::createEntityReference' => ['DOMEntityReference', 'name'=>'string'], +'DOMDocument::createProcessingInstruction' => ['DOMProcessingInstruction', 'target'=>'string', 'data='=>'string'], +'DOMDocument::createTextNode' => ['DOMText', 'content'=>'string'], +'DOMDocument::getElementById' => ['DOMElement|null', 'elementid'=>'string'], +'DOMDocument::getElementsByTagName' => ['DOMNodeList', 'name'=>'string'], +'DOMDocument::getElementsByTagNameNS' => ['DOMNodeList', 'namespaceuri'=>'string', 'localname'=>'string'], +'DOMDocument::importNode' => ['DOMNode', 'importednode'=>'DOMNode', 'deep='=>'bool'], +'DOMDocument::load' => ['mixed', 'filename'=>'string', 'options='=>'int'], +'DOMDocument::loadHTML' => ['bool', 'source'=>'string', 'options='=>'int'], +'DOMDocument::loadHTMLFile' => ['bool', 'filename'=>'string', 'options='=>'int'], +'DOMDocument::loadXML' => ['mixed', 'source'=>'string', 'options='=>'int'], +'DOMDocument::normalizeDocument' => ['void'], +'DOMDocument::registerNodeClass' => ['bool', 'baseclass'=>'string', 'extendedclass'=>'string'], +'DOMDocument::relaxNGValidate' => ['bool', 'filename'=>'string'], +'DOMDocument::relaxNGValidateSource' => ['bool', 'source'=>'string'], +'DOMDocument::save' => ['int', 'filename'=>'string', 'options='=>'int'], +'DOMDocument::saveHTML' => ['string|false', 'node='=>'?DOMNode'], +'DOMDocument::saveHTMLFile' => ['int', 'filename'=>'string'], +'DOMDocument::saveXML' => ['string', 'node='=>'DOMNode', 'options='=>'int'], +'DOMDocument::schemaValidate' => ['bool', 'filename'=>'string', 'flags='=>'int'], +'DOMDocument::schemaValidateSource' => ['bool', 'source'=>'string', 'flags='=>'int'], +'DOMDocument::validate' => ['bool'], +'DOMDocument::xinclude' => ['int', 'options='=>'int'], +'DOMDocumentFragment::__construct' => ['void'], +'DOMDocumentFragment::appendXML' => ['bool', 'data'=>'string'], +'DomDocumentType::entities' => ['array'], +'DomDocumentType::internal_subset' => ['bool'], +'DomDocumentType::name' => ['string'], +'DomDocumentType::notations' => ['array'], +'DomDocumentType::public_id' => ['string'], +'DomDocumentType::system_id' => ['string'], +'DOMElement::__construct' => ['void', 'name'=>'string', 'value='=>'string', 'uri='=>'string'], +'DOMElement::get_attribute' => ['string', 'name'=>'string'], +'DOMElement::get_attribute_node' => ['DomAttribute', 'name'=>'string'], +'DOMElement::get_elements_by_tagname' => ['array', 'name'=>'string'], +'DOMElement::getAttribute' => ['string', 'name'=>'string'], +'DOMElement::getAttributeNode' => ['DOMAttr', 'name'=>'string'], +'DOMElement::getAttributeNodeNS' => ['DOMAttr', 'namespaceuri'=>'string', 'localname'=>'string'], +'DOMElement::getAttributeNS' => ['string', 'namespaceuri'=>'string', 'localname'=>'string'], +'DOMElement::getElementsByTagName' => ['DOMNodeList', 'name'=>'string'], +'DOMElement::getElementsByTagNameNS' => ['DOMNodeList', 'namespaceuri'=>'string', 'localname'=>'string'], +'DOMElement::has_attribute' => ['bool', 'name'=>'string'], +'DOMElement::hasAttribute' => ['bool', 'name'=>'string'], +'DOMElement::hasAttributeNS' => ['bool', 'namespaceuri'=>'string', 'localname'=>'string'], +'DOMElement::remove_attribute' => ['bool', 'name'=>'string'], +'DOMElement::removeAttribute' => ['bool', 'name'=>'string'], +'DOMElement::removeAttributeNode' => ['bool', 'oldnode'=>'DOMAttr'], +'DOMElement::removeAttributeNS' => ['bool', 'namespaceuri'=>'string', 'localname'=>'string'], +'DOMElement::set_attribute' => ['DomAttribute', 'name'=>'string', 'value'=>'string'], +'DOMElement::set_attribute_node' => ['DomNode', 'attr'=>'DOMNode'], +'DOMElement::setAttribute' => ['DOMAttr', 'name'=>'string', 'value'=>'string'], +'DOMElement::setAttributeNode' => ['DOMAttr', 'attr'=>'DOMAttr'], +'DOMElement::setAttributeNodeNS' => ['DOMAttr', 'attr'=>'DOMAttr'], +'DOMElement::setAttributeNS' => ['void', 'namespaceuri'=>'string', 'qualifiedname'=>'string', 'value'=>'string'], +'DOMElement::setIdAttribute' => ['void', 'name'=>'string', 'isid'=>'bool'], +'DOMElement::setIdAttributeNode' => ['void', 'attr'=>'DOMAttr', 'isid'=>'bool'], +'DOMElement::setIdAttributeNS' => ['void', 'namespaceuri'=>'string', 'localname'=>'string', 'isid'=>'bool'], +'DOMElement::tagname' => ['string'], +'DOMEntityReference::__construct' => ['void', 'name'=>'string'], +'DOMImplementation::__construct' => ['void'], +'DOMImplementation::createDocument' => ['DOMDocument', 'namespaceuri='=>'string', 'qualifiedname='=>'string', 'doctype='=>'DOMDocumentType'], +'DOMImplementation::createDocumentType' => ['DOMDocumentType', 'qualifiedname='=>'string', 'publicid='=>'string', 'systemid='=>'string'], +'DOMImplementation::hasFeature' => ['bool', 'feature'=>'string', 'version'=>'string'], +'DOMNamedNodeMap::getNamedItem' => ['?DOMNode', 'name'=>'string'], +'DOMNamedNodeMap::getNamedItemNS' => ['?DOMNode', 'namespaceuri'=>'string', 'localname'=>'string'], +'DOMNamedNodeMap::item' => ['?DOMNode', 'index'=>'int'], +'DomNode::add_namespace' => ['bool', 'uri'=>'string', 'prefix'=>'string'], +'DomNode::append_child' => ['DOMNode', 'newnode'=>'DOMNode'], +'DOMNode::appendChild' => ['DOMNode', 'newnode'=>'DOMNode'], +'DOMNode::C14N' => ['string', 'exclusive='=>'bool', 'with_comments='=>'bool', 'xpath='=>'array', 'ns_prefixes='=>'array'], +'DOMNode::C14NFile' => ['int', 'uri='=>'string', 'exclusive='=>'bool', 'with_comments='=>'bool', 'xpath='=>'array', 'ns_prefixes='=>'array'], +'DOMNode::cloneNode' => ['DOMNode', 'deep='=>'bool'], +'DOMNode::getLineNo' => ['int'], +'DOMNode::getNodePath' => ['?string'], +'DOMNode::hasAttributes' => ['bool'], +'DOMNode::hasChildNodes' => ['bool'], +'DOMNode::insertBefore' => ['DOMNode', 'newnode'=>'DOMNode', 'refnode='=>'DOMNode'], +'DOMNode::isDefaultNamespace' => ['bool', 'namespaceuri'=>'string'], +'DOMNode::isSameNode' => ['bool', 'node'=>'DOMNode'], +'DOMNode::isSupported' => ['bool', 'feature'=>'string', 'version'=>'string'], +'DOMNode::lookupNamespaceURI' => ['string', 'prefix'=>'string'], +'DOMNode::lookupPrefix' => ['string', 'namespaceuri'=>'string'], +'DOMNode::normalize' => ['void'], +'DOMNode::removeChild' => ['DOMNode', 'oldnode'=>'DOMNode'], +'DOMNode::replaceChild' => ['DOMNode', 'newnode'=>'DOMNode', 'oldnode'=>'DOMNode'], +'DOMNodeList::count' => ['int'], +'DOMNodeList::item' => ['?DOMNode', 'index'=>'int'], +'DOMProcessingInstruction::__construct' => ['void', 'name'=>'string', 'value'=>'string'], +'DomProcessingInstruction::data' => ['string'], +'DomProcessingInstruction::target' => ['string'], +'DOMText::__construct' => ['void', 'value='=>'string'], +'DOMText::isElementContentWhitespace' => ['bool'], +'DOMText::isWhitespaceInElementContent' => ['bool'], +'DOMText::splitText' => ['DOMText', 'offset'=>'int'], +'domxml_new_doc' => ['DomDocument', 'version'=>'string'], +'domxml_open_file' => ['DomDocument', 'filename'=>'string', 'mode='=>'int', 'error='=>'array'], +'domxml_open_mem' => ['DomDocument', 'str'=>'string', 'mode='=>'int', 'error='=>'array'], +'domxml_version' => ['string'], +'domxml_xmltree' => ['DomDocument', 'str'=>'string'], +'domxml_xslt_stylesheet' => ['DomXsltStylesheet', 'xsl_buf'=>'string'], +'domxml_xslt_stylesheet_doc' => ['DomXsltStylesheet', 'xsl_doc'=>'DOMDocument'], +'domxml_xslt_stylesheet_file' => ['DomXsltStylesheet', 'xsl_file'=>'string'], +'domxml_xslt_version' => ['int'], +'DOMXPath::__construct' => ['void', 'doc'=>'DOMDocument'], +'DOMXPath::evaluate' => ['mixed', 'expression'=>'string', 'contextnode='=>'DOMNode', 'registernodens='=>'bool'], +'DOMXPath::query' => ['DOMNodeList', 'expression'=>'string', 'contextnode='=>'DOMNode', 'registernodens='=>'bool'], +'DOMXPath::registerNamespace' => ['bool', 'prefix'=>'string', 'namespaceuri'=>'string'], +'DOMXPath::registerPhpFunctions' => ['void', 'restrict='=>'mixed'], +'DomXsltStylesheet::process' => ['DomDocument', 'xml_doc'=>'DOMDocument', 'xslt_params='=>'array', 'is_xpath_param='=>'bool', 'profile_filename='=>'string'], +'DomXsltStylesheet::result_dump_file' => ['string', 'xmldoc'=>'DOMDocument', 'filename'=>'string'], +'DomXsltStylesheet::result_dump_mem' => ['string', 'xmldoc'=>'DOMDocument'], +'DOTNET::__construct' => ['void', 'assembly_name'=>'string', 'class_name'=>'string', 'codepage='=>'int'], +'dotnet_load' => ['int', 'assembly_name'=>'string', 'datatype_name='=>'string', 'codepage='=>'int'], +'doubleval' => ['float', 'var'=>'mixed'], +'Ds\Collection::clear' => ['void'], +'Ds\Collection::copy' => ['Ds\Collection'], +'Ds\Collection::isEmpty' => ['bool'], +'Ds\Collection::toArray' => ['array'], +'Ds\Hashable::hash' => ['void'], +'Ds\Hashable::equals' => ['bool', 'obj'=>'mixed'], +'Ds\Sequence::allocate' => ['void', 'capacity'=>'int'], +'Ds\Sequence::apply' => ['void', 'callback'=>'callable'], +'Ds\Sequence::capacity' => ['int'], +'Ds\Sequence::contains' => ['bool', '...values='=>'mixed'], +'Ds\Sequence::filter' => ['Ds\Sequence', 'callback='=>'callable'], +'Ds\Sequence::find' => ['mixed', 'value'=>'mixed'], +'Ds\Sequence::first' => ['mixed'], +'Ds\Sequence::get' => ['mixed', 'index'=>'int'], +'Ds\Sequence::insert' => ['void', 'index'=>'int', '...values='=>'mixed'], +'Ds\Sequence::join' => ['string', 'glue='=>'string'], +'Ds\Sequence::last' => ['void'], +'Ds\Sequence::map' => ['Ds\Sequence', 'callback'=>'callable'], +'Ds\Sequence::merge' => ['Ds\Sequence', 'values'=>'mixed'], +'Ds\Sequence::pop' => ['mixed'], +'Ds\Sequence::push' => ['void', '...values='=>'mixed'], +'Ds\Sequence::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], +'Ds\Sequence::remove' => ['mixed', 'index'=>'int'], +'Ds\Sequence::reverse' => ['void'], +'Ds\Sequence::reversed' => ['Ds\Sequence'], +'Ds\Sequence::rotate' => ['void', 'rotations'=>'int'], +'Ds\Sequence::set' => ['void', 'index'=>'int', 'value'=>'mixed'], +'Ds\Sequence::shift' => ['mixed'], +'Ds\Sequence::slice' => ['Ds\Sequence', 'index'=>'int', 'length='=>'?int'], +'Ds\Sequence::sort' => ['void', 'comparator='=>'callable'], +'Ds\Sequence::sorted' => ['Ds\Sequence', 'comparator='=>'callable'], +'Ds\Sequence::sum' => ['int|float'], +'Ds\Sequence::unshift' => ['void', '...values='=>'mixed'], +'Ds\Vector::__construct' => ['void', 'values='=>'mixed'], +'Ds\Vector::allocate' => ['void', 'capacity'=>'int'], +'Ds\Vector::apply' => ['void', 'callback'=>'callable'], +'Ds\Vector::capacity' => ['int'], +'Ds\Vector::contains' => ['bool', '...values='=>'mixed'], +'Ds\Vector::filter' => ['Ds\Vector', 'callback='=>'callable'], +'Ds\Vector::find' => ['mixed', 'value'=>'mixed'], +'Ds\Vector::first' => ['mixed'], +'Ds\Vector::get' => ['mixed', 'index'=>'int'], +'Ds\Vector::insert' => ['void', 'index'=>'int', '...values='=>'mixed'], +'Ds\Vector::join' => ['string', 'glue='=>'string'], +'Ds\Vector::last' => ['mixed'], +'Ds\Vector::map' => ['Ds\Vector', 'callback'=>'callable'], +'Ds\Vector::merge' => ['Ds\Vector', 'values'=>'mixed'], +'Ds\Vector::pop' => ['mixed'], +'Ds\Vector::push' => ['void', '...values='=>'mixed'], +'Ds\Vector::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], +'Ds\Vector::remove' => ['mixed', 'index'=>'int'], +'Ds\Vector::reverse' => ['void'], +'Ds\Vector::reversed' => ['Ds\Vector'], +'Ds\Vector::rotate' => ['void', 'rotations'=>'int'], +'Ds\Vector::set' => ['void', 'index'=>'int', 'value'=>'mixed'], +'Ds\Vector::shift' => ['mixed'], +'Ds\Vector::slice' => ['Ds\Vector', 'index'=>'int', 'length='=>'?int'], +'Ds\Vector::sort' => ['void', 'comparator='=>'callable'], +'Ds\Vector::sorted' => ['Ds\Vector', 'comparator='=>'callable'], +'Ds\Vector::sum' => ['int|float'], +'Ds\Vector::unshift' => ['void', '...values='=>'mixed'], +'Ds\Vector::clear' => ['void'], +'Ds\Vector::copy' => ['Ds\Vector'], +'Ds\Vector::count' => ['int'], +'Ds\Vector::isEmpty' => ['bool'], +'Ds\Vector::jsonSerialize' => ['array'], +'Ds\Vector::toArray' => ['array'], +'Ds\Deque::__construct' => ['void', 'values='=>'mixed'], +'Ds\Deque::clear' => ['void'], +'Ds\Deque::copy' => ['Ds\Deque'], +'Ds\Deque::count' => ['int'], +'Ds\Deque::isEmpty' => ['bool'], +'Ds\Deque::jsonSerialize' => ['array'], +'Ds\Deque::toArray' => ['array'], +'Ds\Deque::allocate' => ['void', 'capacity'=>'int'], +'Ds\Deque::apply' => ['void', 'callback'=>'callable'], +'Ds\Deque::capacity' => ['int'], +'Ds\Deque::contains' => ['bool', '...values='=>'mixed'], +'Ds\Deque::filter' => ['Ds\Deque', 'callback='=>'callable'], +'Ds\Deque::find' => ['mixed', 'value'=>'mixed'], +'Ds\Deque::first' => ['mixed'], +'Ds\Deque::get' => ['void', 'index'=>'int'], +'Ds\Deque::insert' => ['void', 'index'=>'int', '...values='=>'mixed'], +'Ds\Deque::join' => ['string', 'glue='=>'string'], +'Ds\Deque::last' => ['mixed'], +'Ds\Deque::map' => ['Ds\Deque', 'callback'=>'callable'], +'Ds\Deque::merge' => ['Ds\Deque', 'values'=>'mixed'], +'Ds\Deque::pop' => ['mixed'], +'Ds\Deque::push' => ['void', '...values='=>'mixed'], +'Ds\Deque::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], +'Ds\Deque::remove' => ['mixed', 'index'=>'int'], +'Ds\Deque::reverse' => ['void'], +'Ds\Deque::reversed' => ['Ds\Deque'], +'Ds\Deque::rotate' => ['void', 'rotations'=>'int'], +'Ds\Deque::set' => ['void', 'index'=>'int', 'value'=>'mixed'], +'Ds\Deque::shift' => ['mixed'], +'Ds\Deque::slice' => ['Ds\Deque', 'index'=>'int', 'length='=>'?int'], +'Ds\Deque::sort' => ['void', 'comparator='=>'callable'], +'Ds\Deque::sorted' => ['Ds\Deque', 'comparator='=>'callable'], +'Ds\Deque::sum' => ['int|float'], +'Ds\Deque::unshift' => ['void', '...values='=>'mixed'], +'Ds\Map::__construct' => ['void', 'values='=>'mixed'], +'Ds\Map::allocate' => ['void', 'capacity'=>'int'], +'Ds\Map::apply' => ['void', 'callback'=>'callable'], +'Ds\Map::capacity' => ['int'], +'Ds\Map::diff' => ['Ds\Map', 'map'=>'Ds\Map'], +'Ds\Map::filter' => ['Ds\Map', 'callback='=>'callable'], +'Ds\Map::first' => ['Ds\Pair'], +'Ds\Map::get' => ['mixed', 'key'=>'mixed', 'default='=>'mixed'], +'Ds\Map::hasKey' => ['bool', 'key'=>'mixed'], +'Ds\Map::hasValue' => ['bool', 'value'=>'mixed'], +'Ds\Map::intersect' => ['Ds\Map', 'map'=>'Ds\Map'], +'Ds\Map::keys' => ['Ds\Set'], +'Ds\Map::ksort' => ['void', 'comparator='=>'callable'], +'Ds\Map::ksorted' => ['Ds\Map', 'comparator='=>'callable'], +'Ds\Map::last' => ['Ds\Pair'], +'Ds\Map::map' => ['Ds\Map', 'callback'=>'callable'], +'Ds\Map::merge' => ['Ds\Map', 'values'=>'mixed'], +'Ds\Map::pairs' => ['Ds\Sequence'], +'Ds\Map::put' => ['void', 'key'=>'mixed', 'value'=>'mixed'], +'Ds\Map::putAll' => ['void', 'values'=>'mixed'], +'Ds\Map::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], +'Ds\Map::remove' => ['mixed', 'key'=>'mixed', 'default='=>'mixed'], +'Ds\Map::reverse' => ['void'], +'Ds\Map::reversed' => ['Ds\Map'], +'Ds\Map::skip' => ['Ds\Pair', 'position'=>'int'], +'Ds\Map::slice' => ['Ds\Map', 'index'=>'int', 'length='=>'?int'], +'Ds\Map::sort' => ['void', 'comparator='=>'callable'], +'Ds\Map::sorted' => ['Ds\Map', 'comparator='=>'callable'], +'Ds\Map::sum' => ['int|float'], +'Ds\Map::union' => ['Ds\Map', 'map'=>'mixed'], +'Ds\Map::values' => ['Ds\Sequence'], +'Ds\Map::xor' => ['Ds\Map', 'map'=>'Ds\Map'], +'Ds\Map::clear' => ['void'], +'Ds\Map::copy' => ['Ds\Map'], +'Ds\Map::count' => ['int'], +'Ds\Map::isEmpty' => ['bool'], +'Ds\Map::jsonSerialize' => ['array'], +'Ds\Map::toArray' => ['array'], +'Ds\Pair::__construct' => ['void', 'key='=>'mixed', 'value='=>'mixed'], +'Ds\Pair::copy' => ['Ds\Pair'], +'Ds\Pair::jsonSerialize' => ['array'], +'Ds\Pair::toArray' => ['array'], +'Ds\Set::__construct' => ['void', 'values='=>'mixed'], +'Ds\Set::add' => ['void', '...values='=>'mixed'], +'Ds\Set::allocate' => ['void', 'capacity'=>'int'], +'Ds\Set::capacity' => ['int'], +'Ds\Set::contains' => ['bool', '...values='=>'mixed'], +'Ds\Set::diff' => ['Ds\Set', 'set'=>'Ds\Set'], +'Ds\Set::filter' => ['Ds\Set', 'callback='=>'callable'], +'Ds\Set::first' => ['void'], +'Ds\Set::get' => ['mixed', 'index'=>'int'], +'Ds\Set::intersect' => ['Ds\Set', 'set'=>'Ds\Set'], +'Ds\Set::join' => ['void', 'glue='=>'string'], +'Ds\Set::last' => ['void'], +'Ds\Set::merge' => ['Ds\Set', 'values'=>'mixed'], +'Ds\Set::reduce' => ['mixed', 'callback'=>'callable', 'initial='=>'mixed'], +'Ds\Set::remove' => ['void', '...values='=>'mixed'], +'Ds\Set::reverse' => ['void'], +'Ds\Set::reversed' => ['Ds\Set'], +'Ds\Set::slice' => ['Ds\Set', 'index'=>'int', 'length='=>'?int'], +'Ds\Set::sort' => ['void', 'comparator='=>'callable'], +'Ds\Set::sorted' => ['Ds\Set', 'comparator='=>'callable'], +'Ds\Set::sum' => ['int|float'], +'Ds\Set::union' => ['?Ds\Set', 'set'=>'Ds\Set'], +'Ds\Set::xor' => ['Ds\Set', 'set'=>'Ds\Set'], +'Ds\Set::clear' => ['void'], +'Ds\Set::copy' => ['Ds\Set'], +'Ds\Set::count' => ['int'], +'Ds\Set::isEmpty' => ['bool'], +'Ds\Set::jsonSerialize' => ['array'], +'Ds\Set::toArray' => ['array'], +'Ds\Stack::__construct' => ['void', 'values='=>'mixed'], +'Ds\Stack::allocate' => ['void', 'capacity'=>'int'], +'Ds\Stack::capacity' => ['int'], +'Ds\Stack::peek' => ['mixed'], +'Ds\Stack::pop' => ['mixed'], +'Ds\Stack::push' => ['void', '...values='=>'mixed'], +'Ds\Stack::clear' => ['void'], +'Ds\Stack::copy' => ['Ds\Stack'], +'Ds\Stack::count' => ['int'], +'Ds\Stack::isEmpty' => ['bool'], +'Ds\Stack::jsonSerialize' => ['array'], +'Ds\Stack::toArray' => ['array'], +'Ds\Queue::__construct' => ['void', 'values='=>'mixed'], +'Ds\Queue::allocate' => ['void', 'capacity'=>'int'], +'Ds\Queue::capacity' => ['int'], +'Ds\Queue::peek' => ['mixed'], +'Ds\Queue::pop' => ['mixed'], +'Ds\Queue::push' => ['void', '...values='=>'mixed'], +'Ds\Queue::clear' => ['void'], +'Ds\Queue::copy' => ['Ds\Queue'], +'Ds\Queue::count' => ['int'], +'Ds\Queue::isEmpty' => ['bool'], +'Ds\Queue::jsonSerialize' => ['array'], +'Ds\Queue::toArray' => ['array'], +'Ds\PriorityQueue::__construct' => ['void'], +'Ds\PriorityQueue::allocate' => ['void', 'capacity'=>'int'], +'Ds\PriorityQueue::capacity' => ['int'], +'Ds\PriorityQueue::peek' => ['mixed'], +'Ds\PriorityQueue::pop' => ['mixed'], +'Ds\PriorityQueue::push' => ['void', 'value'=>'mixed', 'priority'=>'int'], +'Ds\PriorityQueue::clear' => ['void'], +'Ds\PriorityQueue::copy' => ['Ds\PriorityQueue'], +'Ds\PriorityQueue::count' => ['int'], +'Ds\PriorityQueue::isEmpty' => ['bool'], +'Ds\PriorityQueue::jsonSerialize' => ['array'], +'Ds\PriorityQueue::toArray' => ['array'], +'each' => ['array', '&rw_arr'=>'array'], +'easter_date' => ['int', 'year='=>'int'], +'easter_days' => ['int', 'year='=>'int', 'method='=>'int'], +'echo' => ['void', 'arg1'=>'string', '...args='=>'string'], +'eio_busy' => ['resource', 'delay'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_cancel' => ['void', 'req'=>'resource'], +'eio_chmod' => ['resource', 'path'=>'string', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_chown' => ['resource', 'path'=>'string', 'uid'=>'int', 'gid='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_close' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_custom' => ['resource', 'execute'=>'callable', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], +'eio_dup2' => ['resource', 'fd'=>'mixed', 'fd2'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_event_loop' => ['bool'], +'eio_fallocate' => ['resource', 'fd'=>'mixed', 'mode'=>'int', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_fchmod' => ['resource', 'fd'=>'mixed', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_fchown' => ['resource', 'fd'=>'mixed', 'uid'=>'int', 'gid='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_fdatasync' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_fstat' => ['resource', 'fd'=>'mixed', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], +'eio_fstatvfs' => ['resource', 'fd'=>'mixed', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], +'eio_fsync' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_ftruncate' => ['resource', 'fd'=>'mixed', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_futime' => ['resource', 'fd'=>'mixed', 'atime'=>'float', 'mtime'=>'float', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_get_event_stream' => ['mixed'], +'eio_get_last_error' => ['string', 'req'=>'resource'], +'eio_grp' => ['resource', 'callback'=>'callable', 'data='=>'string'], +'eio_grp_add' => ['void', 'grp'=>'resource', 'req'=>'resource'], +'eio_grp_cancel' => ['void', 'grp'=>'resource'], +'eio_grp_limit' => ['void', 'grp'=>'resource', 'limit'=>'int'], +'eio_init' => ['void'], +'eio_link' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_lstat' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], +'eio_mkdir' => ['resource', 'path'=>'string', 'mode'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_mknod' => ['resource', 'path'=>'string', 'mode'=>'int', 'dev'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_nop' => ['resource', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_npending' => ['int'], +'eio_nready' => ['int'], +'eio_nreqs' => ['int'], +'eio_nthreads' => ['int'], +'eio_open' => ['resource', 'path'=>'string', 'flags'=>'int', 'mode'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], +'eio_poll' => ['int'], +'eio_read' => ['resource', 'fd'=>'mixed', 'length'=>'int', 'offset'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], +'eio_readahead' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_readdir' => ['resource', 'path'=>'string', 'flags'=>'int', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'], +'eio_readlink' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'], +'eio_realpath' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'string'], +'eio_rename' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_rmdir' => ['resource', 'path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_seek' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'whence'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_sendfile' => ['resource', 'out_fd'=>'mixed', 'in_fd'=>'mixed', 'offset'=>'int', 'length'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'string'], +'eio_set_max_idle' => ['void', 'nthreads'=>'int'], +'eio_set_max_parallel' => ['void', 'nthreads'=>'int'], +'eio_set_max_poll_reqs' => ['void', 'nreqs'=>'int'], +'eio_set_max_poll_time' => ['void', 'nseconds'=>'float'], +'eio_set_min_parallel' => ['void', 'nthreads'=>'string'], +'eio_stat' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], +'eio_statvfs' => ['resource', 'path'=>'string', 'pri'=>'int', 'callback'=>'callable', 'data='=>'mixed'], +'eio_symlink' => ['resource', 'path'=>'string', 'new_path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_sync' => ['resource', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_sync_file_range' => ['resource', 'fd'=>'mixed', 'offset'=>'int', 'nbytes'=>'int', 'flags'=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_syncfs' => ['resource', 'fd'=>'mixed', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_truncate' => ['resource', 'path'=>'string', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_unlink' => ['resource', 'path'=>'string', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_utime' => ['resource', 'path'=>'string', 'atime'=>'float', 'mtime'=>'float', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'eio_write' => ['resource', 'fd'=>'mixed', 'str'=>'string', 'length='=>'int', 'offset='=>'int', 'pri='=>'int', 'callback='=>'callable', 'data='=>'mixed'], +'empty' => ['bool', 'var'=>'mixed'], +'EmptyIterator::current' => ['mixed'], +'EmptyIterator::key' => ['mixed'], +'EmptyIterator::next' => ['void'], +'EmptyIterator::rewind' => ['void'], +'EmptyIterator::valid' => ['bool'], +'enchant_broker_describe' => ['array', 'broker'=>'resource'], +'enchant_broker_dict_exists' => ['bool', 'broker'=>'resource', 'tag'=>'string'], +'enchant_broker_free' => ['bool', 'broker'=>'resource'], +'enchant_broker_free_dict' => ['resource', 'dict'=>'resource'], +'enchant_broker_get_dict_path' => ['string', 'broker'=>'resource', 'dict_type'=>'int'], +'enchant_broker_get_error' => ['string', 'broker'=>'resource'], +'enchant_broker_init' => ['resource'], +'enchant_broker_list_dicts' => ['string', 'broker'=>'resource'], +'enchant_broker_request_dict' => ['resource', 'broker'=>'resource', 'tag'=>'string'], +'enchant_broker_request_pwl_dict' => ['resource', 'broker'=>'resource', 'filename'=>'string'], +'enchant_broker_set_dict_path' => ['bool', 'broker'=>'resource', 'dict_type'=>'int', 'value'=>'string'], +'enchant_broker_set_ordering' => ['bool', 'broker'=>'resource', 'tag'=>'string', 'ordering'=>'string'], +'enchant_dict_add_to_personal' => ['void', 'dict'=>'resource', 'word'=>'string'], +'enchant_dict_add_to_session' => ['void', 'dict'=>'resource', 'word'=>'string'], +'enchant_dict_check' => ['bool', 'dict'=>'resource', 'word'=>'string'], +'enchant_dict_describe' => ['array', 'dict'=>'resource'], +'enchant_dict_get_error' => ['string', 'dict'=>'resource'], +'enchant_dict_is_in_session' => ['bool', 'dict'=>'resource', 'word'=>'string'], +'enchant_dict_quick_check' => ['bool', 'dict'=>'resource', 'word'=>'string', 'suggestions='=>'array'], +'enchant_dict_store_replacement' => ['void', 'dict'=>'resource', 'mis'=>'string', 'cor'=>'string'], +'enchant_dict_suggest' => ['array', 'dict'=>'resource', 'word'=>'string'], +'end' => ['mixed', '&rw_array_arg'=>'array|object'], +'ereg' => ['int', 'pattern'=>'string', 'string'=>'string', 'regs='=>'array'], +'ereg_replace' => ['string', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string'], +'eregi' => ['int', 'pattern'=>'string', 'string'=>'string', 'regs='=>'array'], +'eregi_replace' => ['string', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string'], +'Error::__clone' => ['void'], +'Error::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?Error'], +'Error::__toString' => ['string'], +'Error::getCode' => ['int'], +'Error::getFile' => ['string'], +'Error::getLine' => ['int'], +'Error::getMessage' => ['string'], +'Error::getPrevious' => ['Throwable|Error|null'], +'Error::getTrace' => ['array'], +'Error::getTraceAsString' => ['string'], +'error_clear_last' => ['void'], +'error_get_last' => ['?array'], +'error_log' => ['bool', 'message'=>'string', 'message_type='=>'int', 'destination='=>'string', 'extra_headers='=>'string'], +'error_reporting' => ['int', 'new_error_level='=>'int'], +'ErrorException::__clone' => ['void'], +'ErrorException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'severity='=>'int', 'filename='=>'string', 'lineno='=>'int', 'previous='=>'?Throwable|?ErrorException'], +'ErrorException::__toString' => ['string'], +'ErrorException::getCode' => ['int'], +'ErrorException::getFile' => ['string'], +'ErrorException::getLine' => ['int'], +'ErrorException::getMessage' => ['string'], +'ErrorException::getPrevious' => ['Throwable|ErrorException|null'], +'ErrorException::getSeverity' => ['int'], +'ErrorException::getTrace' => ['array'], +'ErrorException::getTraceAsString' => ['string'], +'escapeshellarg' => ['string', 'arg'=>'string'], +'escapeshellcmd' => ['string', 'command'=>'string'], +'Ev::backend' => ['int'], +'Ev::depth' => ['int'], +'Ev::embeddableBackends' => ['void'], +'Ev::feedSignal' => ['void', 'signum'=>'int'], +'Ev::feedSignalEvent' => ['void', 'signum'=>'int'], +'Ev::iteration' => ['int'], +'Ev::now' => ['float'], +'Ev::nowUpdate' => ['void'], +'Ev::recommendedBackends' => ['void'], +'Ev::resume' => ['void'], +'Ev::run' => ['void', 'flags='=>'int'], +'Ev::sleep' => ['void', 'seconds'=>'float'], +'Ev::stop' => ['void', 'how='=>'int'], +'Ev::supportedBackends' => ['void'], +'Ev::suspend' => ['void'], +'Ev::time' => ['float'], +'Ev::verify' => ['void'], +'eval' => ['mixed', 'code_str'=>'string'], +'EvCheck::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvCheck::createStopped' => ['object', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], +'EvChild::__construct' => ['void', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvChild::createStopped' => ['object', 'pid'=>'int', 'trace'=>'bool', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvChild::set' => ['void', 'pid'=>'int', 'trace'=>'bool'], +'EvEmbed::__construct' => ['void', 'other'=>'object', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvEmbed::createStopped' => ['void', 'other'=>'object', 'callback='=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvEmbed::set' => ['void', 'other'=>'object'], +'EvEmbed::sweep' => ['void'], +'Event::__construct' => ['void', 'base'=>'EventBase', 'fd'=>'mixed', 'what'=>'int', 'cb'=>'callable', 'arg='=>'mixed'], +'Event::add' => ['bool', 'timeout='=>'float'], +'Event::addSignal' => ['bool', 'timeout='=>'float'], +'Event::addTimer' => ['bool', 'timeout='=>'float'], +'Event::del' => ['bool'], +'Event::delSignal' => ['bool'], +'Event::delTimer' => ['bool'], +'Event::free' => ['void'], +'Event::getSupportedMethods' => ['array'], +'Event::pending' => ['bool', 'flags'=>'int'], +'Event::set' => ['bool', 'base'=>'EventBase', 'fd'=>'mixed', 'what='=>'int', 'cb='=>'callable', 'arg='=>'mixed'], +'Event::setPriority' => ['bool', 'priority'=>'int'], +'Event::setTimer' => ['bool', 'base'=>'EventBase', 'cb'=>'callable', 'arg='=>'mixed'], +'Event::signal' => ['Event', 'base'=>'EventBase', 'signum'=>'int', 'cb'=>'callable', 'arg='=>'mixed'], +'Event::timer' => ['Event', 'base'=>'EventBase', 'cb'=>'callable', 'arg='=>'mixed'], +'event_add' => ['bool', 'event'=>'resource', 'timeout='=>'int'], +'event_base_free' => ['void', 'event_base'=>'resource'], +'event_base_loop' => ['int', 'event_base'=>'resource', 'flags='=>'int'], +'event_base_loopbreak' => ['bool', 'event_base'=>'resource'], +'event_base_loopexit' => ['bool', 'event_base'=>'resource', 'timeout='=>'int'], +'event_base_new' => ['resource'], +'event_base_priority_init' => ['bool', 'event_base'=>'resource', 'npriorities'=>'int'], +'event_base_reinit' => ['bool', 'event_base'=>'resource'], +'event_base_set' => ['bool', 'event'=>'resource', 'event_base'=>'resource'], +'event_buffer_base_set' => ['bool', 'bevent'=>'resource', 'event_base'=>'resource'], +'event_buffer_disable' => ['bool', 'bevent'=>'resource', 'events'=>'int'], +'event_buffer_enable' => ['bool', 'bevent'=>'resource', 'events'=>'int'], +'event_buffer_fd_set' => ['void', 'bevent'=>'resource', 'fd'=>'resource'], +'event_buffer_free' => ['void', 'bevent'=>'resource'], +'event_buffer_new' => ['resource', 'stream'=>'resource', 'readcb'=>'mixed', 'writecb'=>'mixed', 'errorcb'=>'mixed', 'arg='=>'mixed'], +'event_buffer_priority_set' => ['bool', 'bevent'=>'resource', 'priority'=>'int'], +'event_buffer_read' => ['string', 'bevent'=>'resource', 'data_size'=>'int'], +'event_buffer_set_callback' => ['bool', 'event'=>'resource', 'readcb'=>'mixed', 'writecb'=>'mixed', 'errorcb'=>'mixed', 'arg='=>'mixed'], +'event_buffer_timeout_set' => ['void', 'bevent'=>'resource', 'read_timeout'=>'int', 'write_timeout'=>'int'], +'event_buffer_watermark_set' => ['void', 'bevent'=>'resource', 'events'=>'int', 'lowmark'=>'int', 'highmark'=>'int'], +'event_buffer_write' => ['bool', 'bevent'=>'resource', 'data'=>'string', 'data_size='=>'int'], +'event_del' => ['bool', 'event'=>'resource'], +'event_free' => ['void', 'event'=>'resource'], +'event_new' => ['resource'], +'event_priority_set' => ['bool', 'event'=>'resource', 'priority'=>'int'], +'event_set' => ['bool', 'event'=>'resource', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], +'event_timer_add' => ['bool', 'event'=>'resource', 'timeout='=>'int'], +'event_timer_del' => ['bool', 'event'=>'resource'], +'event_timer_new' => ['bool|resource'], +'event_timer_pending' => ['bool', 'event'=>'resource', 'timeout='=>'int'], +'event_timer_set' => ['bool', 'event'=>'resource', 'callback'=>'callable', 'arg='=>'mixed'], +'EventBase::__construct' => ['void', 'cfg='=>'EventConfig'], +'EventBase::dispatch' => ['void'], +'EventBase::exit' => ['bool', 'timeout='=>'float'], +'EventBase::free' => ['void'], +'EventBase::getFeatures' => ['int'], +'EventBase::getMethod' => ['string', 'cfg='=>'EventConfig'], +'EventBase::getTimeOfDayCached' => ['float'], +'EventBase::gotExit' => ['bool'], +'EventBase::gotStop' => ['bool'], +'EventBase::loop' => ['bool', 'flags='=>'int'], +'EventBase::priorityInit' => ['bool', 'n_priorities'=>'int'], +'EventBase::reInit' => ['bool'], +'EventBase::stop' => ['bool'], +'EventBuffer::__construct' => ['void'], +'EventBuffer::add' => ['bool', 'data'=>'string'], +'EventBuffer::addBuffer' => ['bool', 'buf'=>'EventBuffer'], +'EventBuffer::appendFrom' => ['int', 'buf'=>'EventBuffer', 'len'=>'int'], +'EventBuffer::copyout' => ['int', '&w_data'=>'string', 'max_bytes'=>'int'], +'EventBuffer::drain' => ['bool', 'len'=>'int'], +'EventBuffer::enableLocking' => ['void'], +'EventBuffer::expand' => ['bool', 'len'=>'int'], +'EventBuffer::freeze' => ['bool', 'at_front'=>'bool'], +'EventBuffer::lock' => ['void'], +'EventBuffer::prepend' => ['bool', 'data'=>'string'], +'EventBuffer::prependBuffer' => ['bool', 'buf'=>'EventBuffer'], +'EventBuffer::pullup' => ['string', 'size'=>'int'], +'EventBuffer::read' => ['string', 'max_bytes'=>'int'], +'EventBuffer::readFrom' => ['int', 'fd'=>'mixed', 'howmuch'=>'int'], +'EventBuffer::readLine' => ['string', 'eol_style'=>'int'], +'EventBuffer::search' => ['mixed', 'what'=>'string', 'start='=>'int', 'end='=>'int'], +'EventBuffer::searchEol' => ['mixed', 'start='=>'int', 'eol_style='=>'int'], +'EventBuffer::substr' => ['string', 'start'=>'int', 'length='=>'int'], +'EventBuffer::unfreeze' => ['bool', 'at_front'=>'bool'], +'EventBuffer::unlock' => ['bool'], +'EventBuffer::write' => ['int', 'fd'=>'mixed', 'howmuch='=>'int'], +'EventBufferEvent::__construct' => ['void', 'base'=>'EventBase', 'socket='=>'mixed', 'options='=>'int', 'readcb='=>'callable', 'writecb='=>'callable', 'eventcb='=>'callable'], +'EventBufferEvent::close' => ['void'], +'EventBufferEvent::connect' => ['bool', 'addr'=>'string'], +'EventBufferEvent::connectHost' => ['bool', 'dns_base'=>'EventDnsBase', 'hostname'=>'string', 'port'=>'int', 'family='=>'int'], +'EventBufferEvent::createPair' => ['array', 'base'=>'EventBase', 'options='=>'int'], +'EventBufferEvent::disable' => ['bool', 'events'=>'int'], +'EventBufferEvent::enable' => ['bool', 'events'=>'int'], +'EventBufferEvent::free' => ['void'], +'EventBufferEvent::getDnsErrorString' => ['string'], +'EventBufferEvent::getEnabled' => ['int'], +'EventBufferEvent::getInput' => ['EventBuffer'], +'EventBufferEvent::getOutput' => ['EventBuffer'], +'EventBufferEvent::read' => ['string', 'size'=>'int'], +'EventBufferEvent::readBuffer' => ['bool', 'buf'=>'EventBuffer'], +'EventBufferEvent::setCallbacks' => ['void', 'readcb'=>'callable', 'writecb'=>'callable', 'eventcb'=>'callable', 'arg='=>'string'], +'EventBufferEvent::setPriority' => ['bool', 'priority'=>'int'], +'EventBufferEvent::setTimeouts' => ['bool', 'timeout_read'=>'float', 'timeout_write'=>'float'], +'EventBufferEvent::setWatermark' => ['void', 'events'=>'int', 'lowmark'=>'int', 'highmark'=>'int'], +'EventBufferEvent::sslError' => ['string'], +'EventBufferEvent::sslFilter' => ['EventBufferEvent', 'base'=>'EventBase', 'underlying'=>'EventBufferEvent', 'ctx'=>'EventSslContext', 'state'=>'int', 'options='=>'int'], +'EventBufferEvent::sslGetCipherInfo' => ['string'], +'EventBufferEvent::sslGetCipherName' => ['string'], +'EventBufferEvent::sslGetCipherVersion' => ['string'], +'EventBufferEvent::sslGetProtocol' => ['string'], +'EventBufferEvent::sslRenegotiate' => ['void'], +'EventBufferEvent::sslSocket' => ['EventBufferEvent', 'base'=>'EventBase', 'socket'=>'mixed', 'ctx'=>'EventSslContext', 'state'=>'int', 'options='=>'int'], +'EventBufferEvent::write' => ['bool', 'data'=>'string'], +'EventBufferEvent::writeBuffer' => ['bool', 'buf'=>'EventBuffer'], +'EventConfig::__construct' => ['void'], +'EventConfig::avoidMethod' => ['bool', 'method'=>'int'], +'EventConfig::requireFeatures' => ['bool', 'feature'=>'int'], +'EventConfig::setMaxDispatchInterval' => ['void', 'max_interval'=>'int', 'max_callbacks'=>'int', 'min_priority'=>'int'], +'EventDnsBase::__construct' => ['void', 'base'=>'EventBase', 'initialize'=>'bool'], +'EventDnsBase::addNameserverIp' => ['bool', 'ip'=>'string'], +'EventDnsBase::addSearch' => ['void', 'domain'=>'string'], +'EventDnsBase::clearSearch' => ['void'], +'EventDnsBase::countNameservers' => ['int'], +'EventDnsBase::loadHosts' => ['bool', 'hosts'=>'string'], +'EventDnsBase::parseResolvConf' => ['bool', 'flags'=>'int', 'filename'=>'string'], +'EventDnsBase::setOption' => ['bool', 'option'=>'string', 'value'=>'string'], +'EventDnsBase::setSearchNdots' => ['bool', 'ndots'=>'int'], +'EventHttp::__construct' => ['void', 'base'=>'EventBase', 'ctx='=>'EventSslContext'], +'EventHttp::accept' => ['bool', 'socket'=>'mixed'], +'EventHttp::addServerAlias' => ['bool', 'alias'=>'string'], +'EventHttp::bind' => ['void', 'address'=>'string', 'port'=>'int'], +'EventHttp::removeServerAlias' => ['bool', 'alias'=>'string'], +'EventHttp::setAllowedMethods' => ['void', 'methods'=>'int'], +'EventHttp::setCallback' => ['void', 'path'=>'string', 'cb'=>'string', 'arg='=>'string'], +'EventHttp::setDefaultCallback' => ['void', 'cb'=>'string', 'arg='=>'string'], +'EventHttp::setMaxBodySize' => ['void', 'value'=>'int'], +'EventHttp::setMaxHeadersSize' => ['void', 'value'=>'int'], +'EventHttp::setTimeout' => ['void', 'value'=>'int'], +'EventHttpConnection::__construct' => ['void', 'base'=>'EventBase', 'dns_base'=>'EventDnsBase', 'address'=>'string', 'port'=>'int', 'ctx='=>'EventSslContext'], +'EventHttpConnection::getBase' => ['EventBase'], +'EventHttpConnection::getPeer' => ['void', '&w_address'=>'string', '&w_port'=>'int'], +'EventHttpConnection::makeRequest' => ['bool', 'req'=>'EventHttpRequest', 'type'=>'int', 'uri'=>'string'], +'EventHttpConnection::setCloseCallback' => ['void', 'callback'=>'callable', 'data='=>'mixed'], +'EventHttpConnection::setLocalAddress' => ['void', 'address'=>'string'], +'EventHttpConnection::setLocalPort' => ['void', 'port'=>'int'], +'EventHttpConnection::setMaxBodySize' => ['void', 'max_size'=>'string'], +'EventHttpConnection::setMaxHeadersSize' => ['void', 'max_size'=>'string'], +'EventHttpConnection::setRetries' => ['void', 'retries'=>'int'], +'EventHttpConnection::setTimeout' => ['void', 'timeout'=>'int'], +'EventHttpRequest::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed'], +'EventHttpRequest::addHeader' => ['bool', 'key'=>'string', 'value'=>'string', 'type'=>'int'], +'EventHttpRequest::cancel' => ['void'], +'EventHttpRequest::clearHeaders' => ['void'], +'EventHttpRequest::closeConnection' => ['void'], +'EventHttpRequest::findHeader' => ['void', 'key'=>'string', 'type'=>'string'], +'EventHttpRequest::free' => ['void'], +'EventHttpRequest::getBufferEvent' => ['EventBufferEvent'], +'EventHttpRequest::getCommand' => ['void'], +'EventHttpRequest::getConnection' => ['EventHttpConnection'], +'EventHttpRequest::getHost' => ['string'], +'EventHttpRequest::getInputBuffer' => ['EventBuffer'], +'EventHttpRequest::getInputHeaders' => ['array'], +'EventHttpRequest::getOutputBuffer' => ['EventBuffer'], +'EventHttpRequest::getOutputHeaders' => ['void'], +'EventHttpRequest::getResponseCode' => ['int'], +'EventHttpRequest::getUri' => ['string'], +'EventHttpRequest::removeHeader' => ['void', 'key'=>'string', 'type'=>'string'], +'EventHttpRequest::sendError' => ['void', 'error'=>'int', 'reason='=>'string'], +'EventHttpRequest::sendReply' => ['void', 'code'=>'int', 'reason'=>'string', 'buf='=>'EventBuffer'], +'EventHttpRequest::sendReplyChunk' => ['void', 'buf'=>'EventBuffer'], +'EventHttpRequest::sendReplyEnd' => ['void'], +'EventHttpRequest::sendReplyStart' => ['void', 'code'=>'int', 'reason'=>'string'], +'EventListener::__construct' => ['void', 'base'=>'EventBase', 'cb'=>'callable', 'data'=>'mixed', 'flags'=>'int', 'backlog'=>'int', 'target'=>'mixed'], +'EventListener::disable' => ['bool'], +'EventListener::enable' => ['bool'], +'EventListener::getBase' => ['void'], +'EventListener::getSocketName' => ['bool', '&w_address'=>'string', '&w_port='=>'mixed'], +'EventListener::setCallback' => ['void', 'cb'=>'callable', 'arg='=>'mixed'], +'EventListener::setErrorCallback' => ['void', 'cb'=>'string'], +'EventSslContext::__construct' => ['void', 'method'=>'string', 'options'=>'string'], +'EventUtil::__construct' => ['void'], +'EventUtil::getLastSocketErrno' => ['int', 'socket='=>'mixed'], +'EventUtil::getLastSocketError' => ['string', 'socket='=>'mixed'], +'EventUtil::getSocketFd' => ['int', 'socket'=>'mixed'], +'EventUtil::getSocketName' => ['bool', 'socket'=>'mixed', '&w_address'=>'string', '&w_port='=>'mixed'], +'EventUtil::setSocketOption' => ['bool', 'socket'=>'mixed', 'level'=>'int', 'optname'=>'int', 'optval'=>'mixed'], +'EventUtil::sslRandPoll' => ['void'], +'EvFork::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvFork::createStopped' => ['object', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], +'EvIdle::__construct' => ['void', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvIdle::createStopped' => ['object', 'callback'=>'string', 'data='=>'mixed', 'priority='=>'int'], +'EvIo::__construct' => ['void', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvIo::createStopped' => ['EvIo', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvIo::set' => ['void', 'fd'=>'mixed', 'events'=>'int'], +'EvLoop::__construct' => ['void', 'flags='=>'int', 'data='=>'mixed', 'io_interval='=>'float', 'timeout_interval='=>'float'], +'EvLoop::backend' => ['int'], +'EvLoop::check' => ['EvCheck', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], +'EvLoop::child' => ['EvChild', 'pid'=>'string', 'trace'=>'string', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], +'EvLoop::defaultLoop' => ['EvLoop', 'flags='=>'int', 'data='=>'mixed', 'io_interval='=>'float', 'timeout_interval='=>'float'], +'EvLoop::embed' => ['EvEmbed', 'other'=>'string', 'callback='=>'string', 'data='=>'string', 'priority='=>'string'], +'EvLoop::fork' => ['EvFork', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvLoop::idle' => ['EvIdle', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvLoop::invokePending' => ['void'], +'EvLoop::io' => ['EvIo', 'fd'=>'mixed', 'events'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvLoop::loopFork' => ['void'], +'EvLoop::now' => ['float'], +'EvLoop::nowUpdate' => ['void'], +'EvLoop::periodic' => ['EvPeriodic', 'offset'=>'float', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvLoop::prepare' => ['EvPrepare', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvLoop::resume' => ['void'], +'EvLoop::run' => ['void', 'flags='=>'int'], +'EvLoop::signal' => ['EvSignal', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvLoop::stat' => ['EvStat', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvLoop::stop' => ['void', 'how='=>'int'], +'EvLoop::suspend' => ['void'], +'EvLoop::timer' => ['EvTimer', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvLoop::verify' => ['void'], +'EvPeriodic::__construct' => ['void', 'offset'=>'float', 'interval'=>'string', 'reschedule_cb'=>'callable', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvPeriodic::again' => ['void'], +'EvPeriodic::at' => ['float'], +'EvPeriodic::createStopped' => ['EvPeriodic', 'offset'=>'float', 'interval'=>'float', 'reschedule_cb'=>'callable', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvPeriodic::set' => ['void', 'offset'=>'float', 'interval'=>'float'], +'EvPrepare::__construct' => ['void', 'callback'=>'string', 'data='=>'string', 'priority='=>'string'], +'EvPrepare::createStopped' => ['EvPrepare', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvSignal::__construct' => ['void', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvSignal::createStopped' => ['EvSignal', 'signum'=>'int', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvSignal::set' => ['void', 'signum'=>'int'], +'EvStat::__construct' => ['void', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvStat::attr' => ['array'], +'EvStat::createStopped' => ['void', 'path'=>'string', 'interval'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvStat::prev' => ['void'], +'EvStat::set' => ['void', 'path'=>'string', 'interval'=>'float'], +'EvStat::stat' => ['bool'], +'EvTimer::__construct' => ['void', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvTimer::again' => ['void'], +'EvTimer::createStopped' => ['EvTimer', 'after'=>'float', 'repeat'=>'float', 'callback'=>'callable', 'data='=>'mixed', 'priority='=>'int'], +'EvTimer::set' => ['void', 'after'=>'float', 'repeat'=>'float'], +'EvWatcher::__construct' => ['void'], +'EvWatcher::clear' => ['int'], +'EvWatcher::feed' => ['void', 'revents'=>'int'], +'EvWatcher::getLoop' => ['EvLoop'], +'EvWatcher::invoke' => ['void', 'revents'=>'int'], +'EvWatcher::keepalive' => ['bool', 'value='=>'bool'], +'EvWatcher::setCallback' => ['void', 'callback'=>'callable'], +'EvWatcher::start' => ['void'], +'EvWatcher::stop' => ['void'], +'Exception::__clone' => ['void'], +'Exception::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?Exception'], +'Exception::__toString' => ['string'], +'Exception::getCode' => ['mixed'], +'Exception::getFile' => ['string'], +'Exception::getLine' => ['int'], +'Exception::getMessage' => ['string'], +'Exception::getPrevious' => ['?Throwable|?Exception'], +'Exception::getTrace' => ['array'], +'Exception::getTraceAsString' => ['string'], +'exec' => ['string', 'command'=>'string', '&w_output='=>'array', '&w_return_value='=>'int'], +'exif_imagetype' => ['int|false', 'imagefile'=>'string'], +'exif_read_data' => ['array|false', 'filename'=>'string', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'], +'exif_tagname' => ['string', 'index'=>'int'], +'exif_thumbnail' => ['string', 'filename'=>'string', '&w_width='=>'int', '&w_height='=>'int', '&w_imagetype='=>'int'], +'exit' => ['', 'status'=>'string|int'], +'exp' => ['float', 'number'=>'float'], +'expect_expectl' => ['int', 'expect'=>'resource', 'cases'=>'array', 'match='=>'array'], +'expect_popen' => ['resource', 'command'=>'string'], +'explode' => ['array|false', 'separator'=>'string', 'str'=>'string', 'limit='=>'int'], +'expm1' => ['float', 'number'=>'float'], +'extension_loaded' => ['bool', 'extension_name'=>'string'], +'extract' => ['int', '&rw_var_array'=>'array', 'extract_type='=>'int', 'prefix='=>'string|null'], +'ezmlm_hash' => ['int', 'addr'=>'string'], +'fam_cancel_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'], +'fam_close' => ['void', 'fam'=>'resource'], +'fam_monitor_collection' => ['resource', 'fam'=>'resource', 'dirname'=>'string', 'depth'=>'int', 'mask'=>'string'], +'fam_monitor_directory' => ['resource', 'fam'=>'resource', 'dirname'=>'string'], +'fam_monitor_file' => ['resource', 'fam'=>'resource', 'filename'=>'string'], +'fam_next_event' => ['array', 'fam'=>'resource'], +'fam_open' => ['resource', 'appname='=>'string'], +'fam_pending' => ['int', 'fam'=>'resource'], +'fam_resume_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'], +'fam_suspend_monitor' => ['bool', 'fam'=>'resource', 'fam_monitor'=>'resource'], +'fann_cascadetrain_on_data' => ['bool', 'ann'=>'resource', 'data'=>'resource', 'max_neurons'=>'int', 'neurons_between_reports'=>'int', 'desired_error'=>'float'], +'fann_cascadetrain_on_file' => ['bool', 'ann'=>'resource', 'filename'=>'string', 'max_neurons'=>'int', 'neurons_between_reports'=>'int', 'desired_error'=>'float'], +'fann_clear_scaling_params' => ['bool', 'ann'=>'resource'], +'fann_copy' => ['resource', 'ann'=>'resource'], +'fann_create_from_file' => ['resource', 'configuration_file'=>'string'], +'fann_create_shortcut' => ['reference', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'], +'fann_create_shortcut_array' => ['resource', 'num_layers'=>'int', 'layers'=>'array'], +'fann_create_sparse' => ['resource|false', 'connection_rate'=>'float', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'], +'fann_create_sparse_array' => ['resource|false', 'connection_rate'=>'float', 'num_layers'=>'int', 'layers'=>'array'], +'fann_create_standard' => ['resource', 'num_layers'=>'int', 'num_neurons1'=>'int', 'num_neurons2'=>'int', '...args='=>'int'], +'fann_create_standard_array' => ['resource', 'num_layers'=>'int', 'layers'=>'array'], +'fann_create_train' => ['resource', 'num_data'=>'int', 'num_input'=>'int', 'num_output'=>'int'], +'fann_create_train_from_callback' => ['resource', 'num_data'=>'int', 'num_input'=>'int', 'num_output'=>'int', 'user_function'=>'collable'], +'fann_descale_input' => ['bool', 'ann'=>'resource', 'input_vector'=>'array'], +'fann_descale_output' => ['bool', 'ann'=>'resource', 'output_vector'=>'array'], +'fann_descale_train' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'], +'fann_destroy' => ['bool', 'ann'=>'resource'], +'fann_destroy_train' => ['bool', 'train_data'=>'resource'], +'fann_duplicate_train_data' => ['resource', 'data'=>'resource'], +'fann_get_activation_function' => ['int', 'ann'=>'resource', 'layer'=>'int', 'neuron'=>'int'], +'fann_get_activation_steepness' => ['float', 'ann'=>'resource', 'layer'=>'int', 'neuron'=>'int'], +'fann_get_bias_array' => ['array', 'ann'=>'resource'], +'fann_get_bit_fail' => ['int', 'ann'=>'resource'], +'fann_get_bit_fail_limit' => ['float', 'ann'=>'resource'], +'fann_get_cascade_activation_functions' => ['array', 'ann'=>'resource'], +'fann_get_cascade_activation_functions_count' => ['int', 'ann'=>'resource'], +'fann_get_cascade_activation_steepnesses' => ['array', 'ann'=>'resource'], +'fann_get_cascade_activation_steepnesses_count' => ['int', 'ann'=>'resource'], +'fann_get_cascade_candidate_change_fraction' => ['float', 'ann'=>'resource'], +'fann_get_cascade_candidate_limit' => ['float', 'ann'=>'resource'], +'fann_get_cascade_candidate_stagnation_epochs' => ['float', 'ann'=>'resource'], +'fann_get_cascade_max_cand_epochs' => ['int', 'ann'=>'resource'], +'fann_get_cascade_max_out_epochs' => ['int', 'ann'=>'resource'], +'fann_get_cascade_min_cand_epochs' => ['int', 'ann'=>'resource'], +'fann_get_cascade_min_out_epochs' => ['int', 'ann'=>'resource'], +'fann_get_cascade_num_candidate_groups' => ['int', 'ann'=>'resource'], +'fann_get_cascade_num_candidates' => ['int', 'ann'=>'resource'], +'fann_get_cascade_output_change_fraction' => ['float', 'ann'=>'resource'], +'fann_get_cascade_output_stagnation_epochs' => ['int', 'ann'=>'resource'], +'fann_get_cascade_weight_multiplier' => ['float', 'ann'=>'resource'], +'fann_get_connection_array' => ['array', 'ann'=>'resource'], +'fann_get_connection_rate' => ['float', 'ann'=>'resource'], +'fann_get_errno' => ['int', 'errdat'=>'resource'], +'fann_get_errstr' => ['string', 'errdat'=>'resource'], +'fann_get_layer_array' => ['array', 'ann'=>'resource'], +'fann_get_learning_momentum' => ['float', 'ann'=>'resource'], +'fann_get_learning_rate' => ['float', 'ann'=>'resource'], +'fann_get_MSE' => ['float', 'ann'=>'resource'], +'fann_get_network_type' => ['int', 'ann'=>'resource'], +'fann_get_num_input' => ['int', 'ann'=>'resource'], +'fann_get_num_layers' => ['int', 'ann'=>'resource'], +'fann_get_num_output' => ['int', 'ann'=>'resource'], +'fann_get_quickprop_decay' => ['float', 'ann'=>'resource'], +'fann_get_quickprop_mu' => ['float', 'ann'=>'resource'], +'fann_get_rprop_decrease_factor' => ['float', 'ann'=>'resource'], +'fann_get_rprop_delta_max' => ['float', 'ann'=>'resource'], +'fann_get_rprop_delta_min' => ['float', 'ann'=>'resource'], +'fann_get_rprop_delta_zero' => ['float|false', 'ann'=>'resource'], +'fann_get_rprop_increase_factor' => ['float', 'ann'=>'resource'], +'fann_get_sarprop_step_error_shift' => ['float', 'ann'=>'resource'], +'fann_get_sarprop_step_error_threshold_factor' => ['float', 'ann'=>'resource'], +'fann_get_sarprop_temperature' => ['float', 'ann'=>'resource'], +'fann_get_sarprop_weight_decay_shift' => ['float', 'ann'=>'resource'], +'fann_get_total_connections' => ['int', 'ann'=>'resource'], +'fann_get_total_neurons' => ['int', 'ann'=>'resource'], +'fann_get_train_error_function' => ['int', 'ann'=>'resource'], +'fann_get_train_stop_function' => ['int', 'ann'=>'resource'], +'fann_get_training_algorithm' => ['int', 'ann'=>'resource'], +'fann_init_weights' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'], +'fann_length_train_data' => ['int', 'data'=>'resource'], +'fann_merge_train_data' => ['resource', 'data1'=>'resource', 'data2'=>'resource'], +'fann_num_input_train_data' => ['int', 'data'=>'resource'], +'fann_num_output_train_data' => ['int', 'data'=>'resource'], +'fann_print_error' => ['void', 'errdat'=>'string'], +'fann_randomize_weights' => ['bool', 'ann'=>'resource', 'min_weight'=>'float', 'max_weight'=>'float'], +'fann_read_train_from_file' => ['resource', 'filename'=>'string'], +'fann_reset_errno' => ['void', 'errdat'=>'resource'], +'fann_reset_errstr' => ['void', 'errdat'=>'resource'], +'fann_reset_MSE' => ['bool', 'ann'=>'string'], +'fann_run' => ['array', 'ann'=>'resource', 'input'=>'array'], +'fann_save' => ['bool', 'ann'=>'resource', 'configuration_file'=>'string'], +'fann_save_train' => ['bool', 'data'=>'resource', 'file_name'=>'string'], +'fann_scale_input' => ['bool', 'ann'=>'resource', 'input_vector'=>'array'], +'fann_scale_input_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'], +'fann_scale_output' => ['bool', 'ann'=>'resource', 'output_vector'=>'array'], +'fann_scale_output_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'], +'fann_scale_train' => ['bool', 'ann'=>'resource', 'train_data'=>'resource'], +'fann_scale_train_data' => ['bool', 'train_data'=>'resource', 'new_min'=>'float', 'new_max'=>'float'], +'fann_set_activation_function' => ['bool', 'ann'=>'resource', 'activation_function'=>'int', 'layer'=>'int', 'neuron'=>'int'], +'fann_set_activation_function_hidden' => ['bool', 'ann'=>'resource', 'activation_function'=>'int'], +'fann_set_activation_function_layer' => ['bool', 'ann'=>'resource', 'activation_function'=>'int', 'layer'=>'int'], +'fann_set_activation_function_output' => ['bool', 'ann'=>'resource', 'activation_function'=>'int'], +'fann_set_activation_steepness' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float', 'layer'=>'int', 'neuron'=>'int'], +'fann_set_activation_steepness_hidden' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float'], +'fann_set_activation_steepness_layer' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float', 'layer'=>'int'], +'fann_set_activation_steepness_output' => ['bool', 'ann'=>'resource', 'activation_steepness'=>'float'], +'fann_set_bit_fail_limit' => ['bool', 'ann'=>'resource', 'bit_fail_limit'=>'float'], +'fann_set_callback' => ['bool', 'ann'=>'resource', 'callback'=>'collable'], +'fann_set_cascade_activation_functions' => ['bool', 'ann'=>'resource', 'cascade_activation_functions'=>'array'], +'fann_set_cascade_activation_steepnesses' => ['bool', 'ann'=>'resource', 'cascade_activation_steepnesses_count'=>'array'], +'fann_set_cascade_candidate_change_fraction' => ['bool', 'ann'=>'resource', 'cascade_candidate_change_fraction'=>'float'], +'fann_set_cascade_candidate_limit' => ['bool', 'ann'=>'resource', 'cascade_candidate_limit'=>'float'], +'fann_set_cascade_candidate_stagnation_epochs' => ['bool', 'ann'=>'resource', 'cascade_candidate_stagnation_epochs'=>'int'], +'fann_set_cascade_max_cand_epochs' => ['bool', 'ann'=>'resource', 'cascade_max_cand_epochs'=>'int'], +'fann_set_cascade_max_out_epochs' => ['bool', 'ann'=>'resource', 'cascade_max_out_epochs'=>'int'], +'fann_set_cascade_min_cand_epochs' => ['bool', 'ann'=>'resource', 'cascade_min_cand_epochs'=>'int'], +'fann_set_cascade_min_out_epochs' => ['bool', 'ann'=>'resource', 'cascade_min_out_epochs'=>'int'], +'fann_set_cascade_num_candidate_groups' => ['bool', 'ann'=>'resource', 'cascade_num_candidate_groups'=>'int'], +'fann_set_cascade_output_change_fraction' => ['bool', 'ann'=>'resource', 'cascade_output_change_fraction'=>'float'], +'fann_set_cascade_output_stagnation_epochs' => ['bool', 'ann'=>'resource', 'cascade_output_stagnation_epochs'=>'int'], +'fann_set_cascade_weight_multiplier' => ['bool', 'ann'=>'resource', 'cascade_weight_multiplier'=>'float'], +'fann_set_error_log' => ['void', 'errdat'=>'resource', 'log_file'=>'string'], +'fann_set_input_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_input_min'=>'float', 'new_input_max'=>'float'], +'fann_set_learning_momentum' => ['bool', 'ann'=>'resource', 'learning_momentum'=>'float'], +'fann_set_learning_rate' => ['bool', 'ann'=>'resource', 'learning_rate'=>'float'], +'fann_set_output_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_output_min'=>'float', 'new_output_max'=>'float'], +'fann_set_quickprop_decay' => ['bool', 'ann'=>'resource', 'quickprop_decay'=>'float'], +'fann_set_quickprop_mu' => ['bool', 'ann'=>'resource', 'quickprop_mu'=>'float'], +'fann_set_rprop_decrease_factor' => ['bool', 'ann'=>'resource', 'rprop_decrease_factor'=>'float'], +'fann_set_rprop_delta_max' => ['bool', 'ann'=>'resource', 'rprop_delta_max'=>'float'], +'fann_set_rprop_delta_min' => ['bool', 'ann'=>'resource', 'rprop_delta_min'=>'float'], +'fann_set_rprop_delta_zero' => ['bool', 'ann'=>'resource', 'rprop_delta_zero'=>'float'], +'fann_set_rprop_increase_factor' => ['bool', 'ann'=>'resource', 'rprop_increase_factor'=>'float'], +'fann_set_sarprop_step_error_shift' => ['bool', 'ann'=>'resource', 'sarprop_step_error_shift'=>'float'], +'fann_set_sarprop_step_error_threshold_factor' => ['bool', 'ann'=>'resource', 'sarprop_step_error_threshold_factor'=>'float'], +'fann_set_sarprop_temperature' => ['bool', 'ann'=>'resource', 'sarprop_temperature'=>'float'], +'fann_set_sarprop_weight_decay_shift' => ['bool', 'ann'=>'resource', 'sarprop_weight_decay_shift'=>'float'], +'fann_set_scaling_params' => ['bool', 'ann'=>'resource', 'train_data'=>'resource', 'new_input_min'=>'float', 'new_input_max'=>'float', 'new_output_min'=>'float', 'new_output_max'=>'float'], +'fann_set_train_error_function' => ['bool', 'ann'=>'resource', 'error_function'=>'int'], +'fann_set_train_stop_function' => ['bool', 'ann'=>'resource', 'stop_function'=>'int'], +'fann_set_training_algorithm' => ['bool', 'ann'=>'resource', 'training_algorithm'=>'int'], +'fann_set_weight' => ['bool', 'ann'=>'resource', 'from_neuron'=>'int', 'to_neuron'=>'int', 'weight'=>'float'], +'fann_set_weight_array' => ['bool', 'ann'=>'resource', 'connections'=>'array'], +'fann_shuffle_train_data' => ['bool', 'train_data'=>'resource'], +'fann_subset_train_data' => ['resource', 'data'=>'resource', 'pos'=>'int', 'length'=>'int'], +'fann_test' => ['bool', 'ann'=>'resource', 'input'=>'array', 'desired_output'=>'array'], +'fann_test_data' => ['float', 'ann'=>'resource', 'data'=>'resource'], +'fann_train' => ['bool', 'ann'=>'resource', 'input'=>'array', 'desired_output'=>'array'], +'fann_train_epoch' => ['float', 'ann'=>'resource', 'data'=>'resource'], +'fann_train_on_data' => ['bool', 'ann'=>'resource', 'data'=>'resource', 'max_epochs'=>'int', 'epochs_between_reports'=>'int', 'desired_error'=>'float'], +'fann_train_on_file' => ['bool', 'ann'=>'resource', 'filename'=>'string', 'max_epochs'=>'int', 'epochs_between_reports'=>'int', 'desired_error'=>'float'], +'FANNConnection::__construct' => ['void', 'from_neuron'=>'int', 'to_neuron'=>'int', 'weight'=>'float'], +'FANNConnection::getFromNeuron' => ['int'], +'FANNConnection::getToNeuron' => ['int'], +'FANNConnection::getWeight' => ['void'], +'FANNConnection::setWeight' => ['bool', 'weight'=>'float'], +'fastcgi_finish_request' => ['bool'], +'fbsql_affected_rows' => ['int', 'link_identifier='=>'?resource'], +'fbsql_autocommit' => ['bool', 'link_identifier'=>'resource', 'onoff='=>'bool'], +'fbsql_blob_size' => ['int', 'blob_handle'=>'string', 'link_identifier='=>'?resource'], +'fbsql_change_user' => ['bool', 'user'=>'string', 'password'=>'string', 'database='=>'string', 'link_identifier='=>'?resource'], +'fbsql_clob_size' => ['int', 'clob_handle'=>'string', 'link_identifier='=>'?resource'], +'fbsql_close' => ['bool', 'link_identifier='=>'?resource'], +'fbsql_commit' => ['bool', 'link_identifier='=>'?resource'], +'fbsql_connect' => ['resource', 'hostname='=>'string', 'username='=>'string', 'password='=>'string'], +'fbsql_create_blob' => ['string', 'blob_data'=>'string', 'link_identifier='=>'?resource'], +'fbsql_create_clob' => ['string', 'clob_data'=>'string', 'link_identifier='=>'?resource'], +'fbsql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource', 'database_options='=>'string'], +'fbsql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'], +'fbsql_database' => ['string', 'link_identifier'=>'resource', 'database='=>'string'], +'fbsql_database_password' => ['string', 'link_identifier'=>'resource', 'database_password='=>'string'], +'fbsql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'?resource'], +'fbsql_db_status' => ['int', 'database_name'=>'string', 'link_identifier='=>'?resource'], +'fbsql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], +'fbsql_errno' => ['int', 'link_identifier='=>'?resource'], +'fbsql_error' => ['string', 'link_identifier='=>'?resource'], +'fbsql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], +'fbsql_fetch_assoc' => ['array', 'result'=>'resource'], +'fbsql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], +'fbsql_fetch_lengths' => ['array', 'result'=>'resource'], +'fbsql_fetch_object' => ['object', 'result'=>'resource'], +'fbsql_fetch_row' => ['array', 'result'=>'resource'], +'fbsql_field_flags' => ['string', 'result'=>'resource', 'field_offset='=>'int'], +'fbsql_field_len' => ['int', 'result'=>'resource', 'field_offset='=>'int'], +'fbsql_field_name' => ['string', 'result'=>'resource', 'field_index='=>'int'], +'fbsql_field_seek' => ['bool', 'result'=>'resource', 'field_offset='=>'int'], +'fbsql_field_table' => ['string', 'result'=>'resource', 'field_offset='=>'int'], +'fbsql_field_type' => ['string', 'result'=>'resource', 'field_offset='=>'int'], +'fbsql_free_result' => ['bool', 'result'=>'resource'], +'fbsql_get_autostart_info' => ['array', 'link_identifier='=>'?resource'], +'fbsql_hostname' => ['string', 'link_identifier'=>'resource', 'host_name='=>'string'], +'fbsql_insert_id' => ['int', 'link_identifier='=>'?resource'], +'fbsql_list_dbs' => ['resource', 'link_identifier='=>'?resource'], +'fbsql_list_fields' => ['resource', 'database_name'=>'string', 'table_name'=>'string', 'link_identifier='=>'?resource'], +'fbsql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'?resource'], +'fbsql_next_result' => ['bool', 'result'=>'resource'], +'fbsql_num_fields' => ['int', 'result'=>'resource'], +'fbsql_num_rows' => ['int', 'result'=>'resource'], +'fbsql_password' => ['string', 'link_identifier'=>'resource', 'password='=>'string'], +'fbsql_pconnect' => ['resource', 'hostname='=>'string', 'username='=>'string', 'password='=>'string'], +'fbsql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'?resource', 'batch_size='=>'int'], +'fbsql_read_blob' => ['string', 'blob_handle'=>'string', 'link_identifier='=>'?resource'], +'fbsql_read_clob' => ['string', 'clob_handle'=>'string', 'link_identifier='=>'?resource'], +'fbsql_result' => ['mixed', 'result'=>'resource', 'row='=>'int', 'field='=>'mixed'], +'fbsql_rollback' => ['bool', 'link_identifier='=>'?resource'], +'fbsql_rows_fetched' => ['int', 'result'=>'resource'], +'fbsql_select_db' => ['bool', 'database_name='=>'string', 'link_identifier='=>'?resource'], +'fbsql_set_characterset' => ['void', 'link_identifier'=>'resource', 'characterset'=>'int', 'in_out_both='=>'int'], +'fbsql_set_lob_mode' => ['bool', 'result'=>'resource', 'lob_mode'=>'int'], +'fbsql_set_password' => ['bool', 'link_identifier'=>'resource', 'user'=>'string', 'password'=>'string', 'old_password'=>'string'], +'fbsql_set_transaction' => ['void', 'link_identifier'=>'resource', 'locking'=>'int', 'isolation'=>'int'], +'fbsql_start_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource', 'database_options='=>'string'], +'fbsql_stop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], +'fbsql_table_name' => ['string', 'result'=>'resource', 'index'=>'int'], +'fbsql_username' => ['string', 'link_identifier'=>'resource', 'username='=>'string'], +'fbsql_warnings' => ['bool', 'onoff='=>'bool'], +'fclose' => ['bool', 'fp'=>'resource'], +'fdf_add_doc_javascript' => ['bool', 'fdf_document'=>'resource', 'script_name'=>'string', 'script_code'=>'string'], +'fdf_add_template' => ['bool', 'fdf_document'=>'resource', 'newpage'=>'int', 'filename'=>'string', 'template'=>'string', 'rename'=>'int'], +'fdf_close' => ['void', 'fdf_document'=>'resource'], +'fdf_create' => ['resource'], +'fdf_enum_values' => ['bool', 'fdf_document'=>'resource', 'function'=>'callable', 'userdata='=>'mixed'], +'fdf_errno' => ['int'], +'fdf_error' => ['string', 'error_code='=>'int'], +'fdf_get_ap' => ['bool', 'fdf_document'=>'resource', 'field'=>'string', 'face'=>'int', 'filename'=>'string'], +'fdf_get_attachment' => ['array', 'fdf_document'=>'resource', 'fieldname'=>'string', 'savepath'=>'string'], +'fdf_get_encoding' => ['string', 'fdf_document'=>'resource'], +'fdf_get_file' => ['string', 'fdf_document'=>'resource'], +'fdf_get_flags' => ['int', 'fdf_document'=>'resource', 'fieldname'=>'string', 'whichflags'=>'int'], +'fdf_get_opt' => ['mixed', 'fdf_document'=>'resource', 'fieldname'=>'string', 'element='=>'int'], +'fdf_get_status' => ['string', 'fdf_document'=>'resource'], +'fdf_get_value' => ['mixed', 'fdf_document'=>'resource', 'fieldname'=>'string', 'which='=>'int'], +'fdf_get_version' => ['string', 'fdf_document='=>'resource'], +'fdf_header' => ['void'], +'fdf_next_field_name' => ['string', 'fdf_document'=>'resource', 'fieldname='=>'string'], +'fdf_open' => ['resource', 'filename'=>'string'], +'fdf_open_string' => ['resource', 'fdf_data'=>'string'], +'fdf_remove_item' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'item'=>'int'], +'fdf_save' => ['bool', 'fdf_document'=>'resource', 'filename='=>'string'], +'fdf_save_string' => ['string', 'fdf_document'=>'resource'], +'fdf_set_ap' => ['bool', 'fdf_document'=>'resource', 'field_name'=>'string', 'face'=>'int', 'filename'=>'string', 'page_number'=>'int'], +'fdf_set_encoding' => ['bool', 'fdf_document'=>'resource', 'encoding'=>'string'], +'fdf_set_file' => ['bool', 'fdf_document'=>'resource', 'url'=>'string', 'target_frame='=>'string'], +'fdf_set_flags' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'whichflags'=>'int', 'newflags'=>'int'], +'fdf_set_javascript_action' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'trigger'=>'int', 'script'=>'string'], +'fdf_set_on_import_javascript' => ['bool', 'fdf_document'=>'resource', 'script'=>'string', 'before_data_import'=>'bool'], +'fdf_set_opt' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'element'=>'int', 'str1'=>'string', 'str2'=>'string'], +'fdf_set_status' => ['bool', 'fdf_document'=>'resource', 'status'=>'string'], +'fdf_set_submit_form_action' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'trigger'=>'int', 'script'=>'string', 'flags'=>'int'], +'fdf_set_target_frame' => ['bool', 'fdf_document'=>'resource', 'frame_name'=>'string'], +'fdf_set_value' => ['bool', 'fdf_document'=>'resource', 'fieldname'=>'string', 'value'=>'mixed', 'isname='=>'int'], +'fdf_set_version' => ['bool', 'fdf_document'=>'resource', 'version'=>'string'], +'feof' => ['bool', 'fp'=>'resource'], +'fflush' => ['bool', 'fp'=>'resource'], +'ffmpeg_animated_gif::__construct' => ['void', 'output_file_path'=>'string', 'width'=>'int', 'height'=>'int', 'frame_rate'=>'int', 'loop_count='=>'int'], +'ffmpeg_animated_gif::addFrame' => ['', 'frame_to_add'=>'ffmpeg_frame'], +'ffmpeg_frame::__construct' => ['void', 'gd_image'=>'resource'], +'ffmpeg_frame::crop' => ['', 'crop_top'=>'int', 'crop_bottom='=>'int', 'crop_left='=>'int', 'crop_right='=>'int'], +'ffmpeg_frame::getHeight' => ['int'], +'ffmpeg_frame::getPresentationTimestamp' => ['int'], +'ffmpeg_frame::getPTS' => ['int'], +'ffmpeg_frame::getWidth' => ['int'], +'ffmpeg_frame::resize' => ['', 'width'=>'int', 'height'=>'int', 'crop_top='=>'int', 'crop_bottom='=>'int', 'crop_left='=>'int', 'crop_right='=>'int'], +'ffmpeg_frame::toGDImage' => ['resource'], +'ffmpeg_movie::__construct' => ['void', 'path_to_media'=>'string', 'persistent'=>'bool'], +'ffmpeg_movie::getArtist' => ['string'], +'ffmpeg_movie::getAudioBitRate' => ['int'], +'ffmpeg_movie::getAudioChannels' => ['int'], +'ffmpeg_movie::getAudioCodec' => ['string'], +'ffmpeg_movie::getAudioSampleRate' => ['int'], +'ffmpeg_movie::getAuthor' => ['string'], +'ffmpeg_movie::getBitRate' => ['int'], +'ffmpeg_movie::getComment' => ['string'], +'ffmpeg_movie::getCopyright' => ['string'], +'ffmpeg_movie::getDuration' => ['int'], +'ffmpeg_movie::getFilename' => ['string'], +'ffmpeg_movie::getFrame' => ['ffmpeg_frame', 'framenumber'=>'int'], +'ffmpeg_movie::getFrameCount' => ['int'], +'ffmpeg_movie::getFrameHeight' => ['int'], +'ffmpeg_movie::getFrameNumber' => ['int'], +'ffmpeg_movie::getFrameRate' => ['int'], +'ffmpeg_movie::getFrameWidth' => ['int'], +'ffmpeg_movie::getGenre' => ['string'], +'ffmpeg_movie::getNextKeyFrame' => ['ffmpeg_frame'], +'ffmpeg_movie::getPixelFormat' => [''], +'ffmpeg_movie::getTitle' => ['string'], +'ffmpeg_movie::getTrackNumber' => ['int|string'], +'ffmpeg_movie::getVideoBitRate' => ['int'], +'ffmpeg_movie::getVideoCodec' => ['string'], +'ffmpeg_movie::getYear' => ['int|string'], +'ffmpeg_movie::hasAudio' => ['bool'], +'ffmpeg_movie::hasVideo' => ['bool'], +'fgetc' => ['string|false', 'fp'=>'resource'], +'fgetcsv' => ['?array|?false', 'fp'=>'resource', 'length='=>'int', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], +'fgets' => ['string|false', 'fp'=>'resource', 'length='=>'int'], +'fgetss' => ['string|false', 'fp'=>'resource', 'length='=>'int', 'allowable_tags='=>'string'], +'file' => ['array|false', 'filename'=>'string', 'flags='=>'int', 'context='=>'resource'], +'file_exists' => ['bool', 'filename'=>'string'], +'file_get_contents' => ['string|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'?resource', 'offset='=>'int', 'maxlen='=>'int'], +'file_put_contents' => ['int|false', 'file'=>'string', 'data'=>'mixed', 'flags='=>'int', 'context='=>'resource'], +'fileatime' => ['int|false', 'filename'=>'string'], +'filectime' => ['int|false', 'filename'=>'string'], +'filegroup' => ['int|false', 'filename'=>'string'], +'fileinode' => ['int|false', 'filename'=>'string'], +'filemtime' => ['int|false', 'filename'=>'string'], +'fileowner' => ['int|false', 'filename'=>'string'], +'fileperms' => ['int|false', 'filename'=>'string'], +'filepro' => ['bool', 'directory'=>'string'], +'filepro_fieldcount' => ['int'], +'filepro_fieldname' => ['string', 'field_number'=>'int'], +'filepro_fieldtype' => ['string', 'field_number'=>'int'], +'filepro_fieldwidth' => ['int', 'field_number'=>'int'], +'filepro_retrieve' => ['string', 'row_number'=>'int', 'field_number'=>'int'], +'filepro_rowcount' => ['int'], +'filesize' => ['int|false', 'filename'=>'string'], +'FilesystemIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'], +'FilesystemIterator::current' => ['string|SplFileInfo'], +'FilesystemIterator::getFlags' => ['int'], +'FilesystemIterator::key' => ['string'], +'FilesystemIterator::next' => ['void'], +'FilesystemIterator::rewind' => ['void'], +'FilesystemIterator::setFlags' => ['void', 'flags='=>'int'], +'filetype' => ['string|false', 'filename'=>'string'], +'filter_has_var' => ['bool', 'type'=>'int', 'variable_name'=>'string'], +'filter_id' => ['int|false', 'filtername'=>'string'], +'filter_input' => ['mixed', 'type'=>'int', 'variable_name'=>'string', 'filter='=>'int', 'options='=>'array|int'], +'filter_input_array' => ['mixed', 'type'=>'int', 'definition='=>'int|array', 'add_empty='=>'bool'], +'filter_list' => ['array'], +'filter_var' => ['mixed', 'variable'=>'mixed', 'filter='=>'int', 'options='=>'mixed'], +'filter_var_array' => ['mixed', 'data'=>'array', 'definition='=>'mixed', 'add_empty='=>'bool'], +'FilterIterator::__construct' => ['void', 'it'=>'iterator'], +'FilterIterator::accept' => ['bool'], +'FilterIterator::current' => ['mixed'], +'FilterIterator::getInnerIterator' => ['Iterator'], +'FilterIterator::key' => ['mixed'], +'FilterIterator::next' => ['void'], +'FilterIterator::rewind' => ['void'], +'FilterIterator::valid' => ['bool'], +'finfo::__construct' => ['void', 'options='=>'int', 'magic_file='=>'string'], +'finfo::buffer' => ['string', 'string'=>'string', 'options='=>'int', 'context='=>'resource'], +'finfo::file' => ['string', 'file_name'=>'string', 'options='=>'int', 'context='=>'resource'], +'finfo::set_flags' => ['bool', 'options'=>'int'], +'finfo_buffer' => ['string', 'finfo'=>'resource', 'string'=>'string', 'options='=>'int', 'context='=>'resource'], +'finfo_close' => ['bool', 'finfo'=>'resource'], +'finfo_file' => ['string', 'finfo'=>'resource', 'file_name'=>'string', 'options='=>'int', 'context='=>'resource'], +'finfo_open' => ['resource', 'options='=>'int', 'arg='=>'string'], +'finfo_set_flags' => ['bool', 'finfo'=>'resource', 'options'=>'int'], +'floatval' => ['float', 'var'=>'mixed'], +'flock' => ['bool', 'fp'=>'resource', 'operation'=>'int', '&w_wouldblock='=>'int'], +'floor' => ['float', 'number'=>'float'], +'flush' => ['void'], +'fmod' => ['float', 'x'=>'float', 'y'=>'float'], +'fnmatch' => ['bool', 'pattern'=>'string', 'filename'=>'string', 'flags='=>'int'], +'fopen' => ['resource|false', 'filename'=>'string', 'mode'=>'string', 'use_include_path='=>'bool', 'context='=>'resource'], +'forward_static_call' => ['mixed', 'function'=>'callable', '...parameters='=>'mixed'], +'forward_static_call_array' => ['mixed', 'function'=>'callable', 'parameters'=>'array'], +'fpassthru' => ['int', 'fp'=>'resource'], +'fprintf' => ['int', 'stream'=>'resource', 'format'=>'string', '...args='=>'string|int|float'], +'fputcsv' => ['int|false', 'fp'=>'resource', 'fields'=>'array', 'delimiter='=>'string', 'enclosure='=>'string', 'escape_char='=>'string'], +'fputs' => ['int|false', 'fp'=>'resource', 'str'=>'string', 'length='=>'int'], +'fread' => ['string|false', 'fp'=>'resource', 'length'=>'int'], +'frenchtojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], +'fribidi_log2vis' => ['string', 'str'=>'string', 'direction'=>'string', 'charset'=>'int'], +'fscanf' => ['array|int', 'stream'=>'resource', 'format'=>'string', '&...w_vars='=>'string|int|float|null'], +'fseek' => ['int', 'fp'=>'resource', 'offset'=>'int', 'whence='=>'int'], +'fsockopen' => ['resource|false', 'hostname'=>'string', 'port='=>'int', '&w_errno='=>'int', '&w_errstr='=>'string', 'timeout='=>'float'], +'fstat' => ['array|false', 'fp'=>'resource'], +'ftell' => ['int|false', 'fp'=>'resource'], +'ftok' => ['int', 'pathname'=>'string', 'proj'=>'string'], +'ftp_alloc' => ['bool', 'stream'=>'resource', 'size'=>'int', 'response='=>'string'], +'ftp_append' => ['bool', 'ftp'=>'resource', 'remote_file'=>'string', 'local_file'=>'string', 'mode='=>'int'], +'ftp_cdup' => ['bool', 'stream'=>'resource'], +'ftp_chdir' => ['bool', 'stream'=>'resource', 'directory'=>'string'], +'ftp_chmod' => ['int|false', 'stream'=>'resource', 'mode'=>'int', 'filename'=>'string'], +'ftp_close' => ['bool', 'stream'=>'resource'], +'ftp_connect' => ['resource|false', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'], +'ftp_delete' => ['bool', 'stream'=>'resource', 'file'=>'string'], +'ftp_exec' => ['bool', 'stream'=>'resource', 'command'=>'string'], +'ftp_fget' => ['bool', 'stream'=>'resource', 'fp'=>'resource', 'remote_file'=>'string', 'mode'=>'int', 'resumepos='=>'int'], +'ftp_fput' => ['bool', 'stream'=>'resource', 'remote_file'=>'string', 'fp'=>'resource', 'mode'=>'int', 'startpos='=>'int'], +'ftp_get' => ['bool', 'stream'=>'resource', 'local_file'=>'string', 'remote_file'=>'string', 'mode'=>'int', 'resume_pos='=>'int'], +'ftp_get_option' => ['mixed', 'stream'=>'resource', 'option'=>'int'], +'ftp_login' => ['bool', 'stream'=>'resource', 'username'=>'string', 'password'=>'string'], +'ftp_mdtm' => ['int', 'stream'=>'resource', 'filename'=>'string'], +'ftp_mkdir' => ['string|false', 'stream'=>'resource', 'directory'=>'string'], +'ftp_mlsd' => ['array', 'ftp_stream'=>'resource', 'directory'=>'string'], +'ftp_nb_continue' => ['int', 'stream'=>'resource'], +'ftp_nb_fget' => ['int', 'stream'=>'resource', 'fp'=>'resource', 'remote_file'=>'string', 'mode'=>'int', 'resumepos='=>'int'], +'ftp_nb_fput' => ['int', 'stream'=>'resource', 'remote_file'=>'string', 'fp'=>'resource', 'mode'=>'int', 'startpos='=>'int'], +'ftp_nb_get' => ['int', 'stream'=>'resource', 'local_file'=>'string', 'remote_file'=>'string', 'mode'=>'int', 'resume_pos='=>'int'], +'ftp_nb_put' => ['int', 'stream'=>'resource', 'remote_file'=>'string', 'local_file'=>'string', 'mode'=>'int', 'startpos='=>'int'], +'ftp_nlist' => ['array|false', 'stream'=>'resource', 'directory'=>'string'], +'ftp_pasv' => ['bool', 'stream'=>'resource', 'pasv'=>'bool'], +'ftp_put' => ['bool', 'stream'=>'resource', 'remote_file'=>'string', 'local_file'=>'string', 'mode'=>'int', 'startpos='=>'int'], +'ftp_pwd' => ['string|false', 'stream'=>'resource'], +'ftp_raw' => ['array', 'stream'=>'resource', 'command'=>'string'], +'ftp_rawlist' => ['array|false', 'stream'=>'resource', 'directory'=>'string', 'recursive='=>'bool'], +'ftp_rename' => ['bool', 'stream'=>'resource', 'src'=>'string', 'dest'=>'string'], +'ftp_rmdir' => ['bool', 'stream'=>'resource', 'directory'=>'string'], +'ftp_set_option' => ['bool', 'stream'=>'resource', 'option'=>'int', 'value'=>'mixed'], +'ftp_site' => ['bool', 'stream'=>'resource', 'cmd'=>'string'], +'ftp_size' => ['int', 'stream'=>'resource', 'filename'=>'string'], +'ftp_ssl_connect' => ['resource|false', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'], +'ftp_systype' => ['string|false', 'stream'=>'resource'], +'ftruncate' => ['bool', 'fp'=>'resource', 'size'=>'int'], +'func_get_arg' => ['mixed', 'arg_num'=>'int'], +'func_get_args' => ['array'], +'func_num_args' => ['int'], +'function_exists' => ['bool', 'function_name'=>'string'], +'fwrite' => ['int|false', 'fp'=>'resource', 'str'=>'string', 'length='=>'int'], +'gc_collect_cycles' => ['int'], +'gc_disable' => ['void'], +'gc_enable' => ['void'], +'gc_enabled' => ['bool'], +'gc_mem_caches' => ['int'], +'gd_info' => ['array'], +'gearman_bugreport' => [''], +'gearman_client_add_options' => ['', 'client_object'=>'', 'option'=>''], +'gearman_client_add_server' => ['', 'client_object'=>'', 'host'=>'', 'port'=>''], +'gearman_client_add_servers' => ['', 'client_object'=>'', 'servers'=>''], +'gearman_client_add_task' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], +'gearman_client_add_task_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], +'gearman_client_add_task_high' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], +'gearman_client_add_task_high_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], +'gearman_client_add_task_low' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], +'gearman_client_add_task_low_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'context'=>'', 'unique'=>''], +'gearman_client_add_task_status' => ['', 'client_object'=>'', 'job_handle'=>'', 'context'=>''], +'gearman_client_clear_fn' => ['', 'client_object'=>''], +'gearman_client_clone' => ['', 'client_object'=>''], +'gearman_client_context' => ['', 'client_object'=>''], +'gearman_client_create' => ['', 'client_object'=>''], +'gearman_client_do' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], +'gearman_client_do_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], +'gearman_client_do_high' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], +'gearman_client_do_high_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], +'gearman_client_do_job_handle' => ['', 'client_object'=>''], +'gearman_client_do_low' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], +'gearman_client_do_low_background' => ['', 'client_object'=>'', 'function_name'=>'', 'workload'=>'', 'unique'=>''], +'gearman_client_do_normal' => ['', 'client_object'=>'', 'function_name'=>'string', 'workload'=>'string', 'unique'=>'string'], +'gearman_client_do_status' => ['', 'client_object'=>''], +'gearman_client_echo' => ['', 'client_object'=>'', 'workload'=>''], +'gearman_client_errno' => ['', 'client_object'=>''], +'gearman_client_error' => ['', 'client_object'=>''], +'gearman_client_job_status' => ['', 'client_object'=>'', 'job_handle'=>''], +'gearman_client_options' => ['', 'client_object'=>''], +'gearman_client_remove_options' => ['', 'client_object'=>'', 'option'=>''], +'gearman_client_return_code' => ['', 'client_object'=>''], +'gearman_client_run_tasks' => ['', 'data'=>''], +'gearman_client_set_complete_fn' => ['', 'client_object'=>'', 'callback'=>''], +'gearman_client_set_context' => ['', 'client_object'=>'', 'context'=>''], +'gearman_client_set_created_fn' => ['', 'client_object'=>'', 'callback'=>''], +'gearman_client_set_data_fn' => ['', 'client_object'=>'', 'callback'=>''], +'gearman_client_set_exception_fn' => ['', 'client_object'=>'', 'callback'=>''], +'gearman_client_set_fail_fn' => ['', 'client_object'=>'', 'callback'=>''], +'gearman_client_set_options' => ['', 'client_object'=>'', 'option'=>''], +'gearman_client_set_status_fn' => ['', 'client_object'=>'', 'callback'=>''], +'gearman_client_set_timeout' => ['', 'client_object'=>'', 'timeout'=>''], +'gearman_client_set_warning_fn' => ['', 'client_object'=>'', 'callback'=>''], +'gearman_client_set_workload_fn' => ['', 'client_object'=>'', 'callback'=>''], +'gearman_client_timeout' => ['', 'client_object'=>''], +'gearman_client_wait' => ['', 'client_object'=>''], +'gearman_job_function_name' => ['', 'job_object'=>''], +'gearman_job_handle' => ['string'], +'gearman_job_return_code' => ['', 'job_object'=>''], +'gearman_job_send_complete' => ['', 'job_object'=>'', 'result'=>''], +'gearman_job_send_data' => ['', 'job_object'=>'', 'data'=>''], +'gearman_job_send_exception' => ['', 'job_object'=>'', 'exception'=>''], +'gearman_job_send_fail' => ['', 'job_object'=>''], +'gearman_job_send_status' => ['', 'job_object'=>'', 'numerator'=>'', 'denominator'=>''], +'gearman_job_send_warning' => ['', 'job_object'=>'', 'warning'=>''], +'gearman_job_status' => ['array', 'job_handle'=>'string'], +'gearman_job_unique' => ['', 'job_object'=>''], +'gearman_job_workload' => ['', 'job_object'=>''], +'gearman_job_workload_size' => ['', 'job_object'=>''], +'gearman_task_data' => ['', 'task_object'=>''], +'gearman_task_data_size' => ['', 'task_object'=>''], +'gearman_task_denominator' => ['', 'task_object'=>''], +'gearman_task_function_name' => ['', 'task_object'=>''], +'gearman_task_is_known' => ['', 'task_object'=>''], +'gearman_task_is_running' => ['', 'task_object'=>''], +'gearman_task_job_handle' => ['', 'task_object'=>''], +'gearman_task_numerator' => ['', 'task_object'=>''], +'gearman_task_recv_data' => ['', 'task_object'=>'', 'data_len'=>''], +'gearman_task_return_code' => ['', 'task_object'=>''], +'gearman_task_send_workload' => ['', 'task_object'=>'', 'data'=>''], +'gearman_task_unique' => ['', 'task_object'=>''], +'gearman_verbose_name' => ['', 'verbose'=>''], +'gearman_version' => [''], +'gearman_worker_add_function' => ['', 'worker_object'=>'', 'function_name'=>'', 'function'=>'', 'data'=>'', 'timeout'=>''], +'gearman_worker_add_options' => ['', 'worker_object'=>'', 'option'=>''], +'gearman_worker_add_server' => ['', 'worker_object'=>'', 'host'=>'', 'port'=>''], +'gearman_worker_add_servers' => ['', 'worker_object'=>'', 'servers'=>''], +'gearman_worker_clone' => ['', 'worker_object'=>''], +'gearman_worker_create' => [''], +'gearman_worker_echo' => ['', 'worker_object'=>'', 'workload'=>''], +'gearman_worker_errno' => ['', 'worker_object'=>''], +'gearman_worker_error' => ['', 'worker_object'=>''], +'gearman_worker_grab_job' => ['', 'worker_object'=>''], +'gearman_worker_options' => ['', 'worker_object'=>''], +'gearman_worker_register' => ['', 'worker_object'=>'', 'function_name'=>'', 'timeout'=>''], +'gearman_worker_remove_options' => ['', 'worker_object'=>'', 'option'=>''], +'gearman_worker_return_code' => ['', 'worker_object'=>''], +'gearman_worker_set_options' => ['', 'worker_object'=>'', 'option'=>''], +'gearman_worker_set_timeout' => ['', 'worker_object'=>'', 'timeout'=>''], +'gearman_worker_timeout' => ['', 'worker_object'=>''], +'gearman_worker_unregister' => ['', 'worker_object'=>'', 'function_name'=>''], +'gearman_worker_unregister_all' => ['', 'worker_object'=>''], +'gearman_worker_wait' => ['', 'worker_object'=>''], +'gearman_worker_work' => ['', 'worker_object'=>''], +'GearmanClient::__construct' => ['void'], +'GearmanClient::addOptions' => ['bool', 'options'=>'int'], +'GearmanClient::addServer' => ['bool', 'host='=>'string', 'port='=>'int'], +'GearmanClient::addServers' => ['bool', 'servers='=>'string'], +'GearmanClient::addTask' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], +'GearmanClient::addTaskBackground' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], +'GearmanClient::addTaskHigh' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], +'GearmanClient::addTaskHighBackground' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], +'GearmanClient::addTaskLow' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], +'GearmanClient::addTaskLowBackground' => ['GearmanTask', 'function_name'=>'string', 'workload'=>'string', 'context='=>'mixed', 'unique='=>'string'], +'GearmanClient::addTaskStatus' => ['GearmanTask', 'job_handle'=>'string', 'context='=>'string'], +'GearmanClient::clearCallbacks' => ['bool'], +'GearmanClient::clone' => ['GearmanClient'], +'GearmanClient::context' => ['string'], +'GearmanClient::data' => ['string'], +'GearmanClient::do' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], +'GearmanClient::doBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], +'GearmanClient::doHigh' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], +'GearmanClient::doHighBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], +'GearmanClient::doJobHandle' => ['string'], +'GearmanClient::doLow' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], +'GearmanClient::doLowBackground' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], +'GearmanClient::doNormal' => ['string', 'function_name'=>'string', 'workload'=>'string', 'unique='=>'string'], +'GearmanClient::doStatus' => ['array'], +'GearmanClient::echo' => ['bool', 'workload'=>'string'], +'GearmanClient::error' => ['string'], +'GearmanClient::getErrno' => ['int'], +'GearmanClient::jobStatus' => ['array', 'job_handle'=>'string'], +'GearmanClient::options' => [''], +'GearmanClient::ping' => ['bool', 'workload'=>'string'], +'GearmanClient::removeOptions' => ['bool', 'options'=>'int'], +'GearmanClient::returnCode' => ['int'], +'GearmanClient::runTasks' => ['bool'], +'GearmanClient::setClientCallback' => ['void', 'callback'=>'callable'], +'GearmanClient::setCompleteCallback' => ['bool', 'callback'=>'callable'], +'GearmanClient::setContext' => ['bool', 'context'=>'string'], +'GearmanClient::setCreatedCallback' => ['bool', 'callback'=>'string'], +'GearmanClient::setData' => ['bool', 'data'=>'string'], +'GearmanClient::setDataCallback' => ['bool', 'callback'=>'callable'], +'GearmanClient::setExceptionCallback' => ['bool', 'callback'=>'callable'], +'GearmanClient::setFailCallback' => ['bool', 'callback'=>'callable'], +'GearmanClient::setOptions' => ['bool', 'options'=>'int'], +'GearmanClient::setStatusCallback' => ['bool', 'callback'=>'callable'], +'GearmanClient::setTimeout' => ['bool', 'timeout'=>'int'], +'GearmanClient::setWarningCallback' => ['bool', 'callback'=>'callable'], +'GearmanClient::setWorkloadCallback' => ['bool', 'callback'=>'callable'], +'GearmanClient::timeout' => ['int'], +'GearmanClient::wait' => [''], +'GearmanJob::__construct' => ['void'], +'GearmanJob::complete' => ['bool', 'result'=>'string'], +'GearmanJob::data' => ['bool', 'data'=>'string'], +'GearmanJob::exception' => ['bool', 'exception'=>'string'], +'GearmanJob::fail' => ['bool'], +'GearmanJob::functionName' => ['string'], +'GearmanJob::handle' => ['string'], +'GearmanJob::returnCode' => ['int'], +'GearmanJob::sendComplete' => ['bool', 'result'=>'string'], +'GearmanJob::sendData' => ['bool', 'data'=>'string'], +'GearmanJob::sendException' => ['bool', 'exception'=>'string'], +'GearmanJob::sendFail' => ['bool'], +'GearmanJob::sendStatus' => ['bool', 'numerator'=>'int', 'denominator'=>'int'], +'GearmanJob::sendWarning' => ['bool', 'warning'=>'string'], +'GearmanJob::setReturn' => ['bool', 'gearman_return_t'=>'string'], +'GearmanJob::status' => ['bool', 'numerator'=>'int', 'denominator'=>'int'], +'GearmanJob::unique' => ['string'], +'GearmanJob::warning' => ['bool', 'warning'=>'string'], +'GearmanJob::workload' => ['string'], +'GearmanJob::workloadSize' => ['int'], +'GearmanTask::__construct' => ['void'], +'GearmanTask::create' => ['GearmanTask'], +'GearmanTask::data' => ['string'], +'GearmanTask::dataSize' => ['int'], +'GearmanTask::function' => ['string'], +'GearmanTask::functionName' => ['string'], +'GearmanTask::isKnown' => ['bool'], +'GearmanTask::isRunning' => ['bool'], +'GearmanTask::jobHandle' => ['string'], +'GearmanTask::recvData' => ['array', 'data_len'=>'int'], +'GearmanTask::returnCode' => ['int'], +'GearmanTask::sendData' => ['int', 'data'=>'string'], +'GearmanTask::sendWorkload' => ['int', 'data'=>'string'], +'GearmanTask::taskDenominator' => ['int'], +'GearmanTask::taskNumerator' => ['int'], +'GearmanTask::unique' => ['string'], +'GearmanTask::uuid' => ['string'], +'GearmanWorker::__construct' => ['void'], +'GearmanWorker::addFunction' => ['bool', 'function_name'=>'string', 'function'=>'callable', 'context='=>'mixed', 'timeout='=>'int'], +'GearmanWorker::addOptions' => ['bool', 'option'=>'int'], +'GearmanWorker::addServer' => ['bool', 'host='=>'string', 'port='=>'int'], +'GearmanWorker::addServers' => ['bool', 'servers'=>'string'], +'GearmanWorker::clone' => ['void'], +'GearmanWorker::echo' => ['bool', 'workload'=>'string'], +'GearmanWorker::error' => ['string'], +'GearmanWorker::getErrno' => ['int'], +'GearmanWorker::grabJob' => [''], +'GearmanWorker::options' => ['int'], +'GearmanWorker::register' => ['bool', 'function_name'=>'string', 'timeout='=>'int'], +'GearmanWorker::removeOptions' => ['bool', 'option'=>'int'], +'GearmanWorker::returnCode' => ['int'], +'GearmanWorker::setId' => ['bool', 'id'=>'string'], +'GearmanWorker::setOptions' => ['bool', 'option'=>'int'], +'GearmanWorker::setTimeout' => ['bool', 'timeout'=>'int'], +'GearmanWorker::timeout' => ['int'], +'GearmanWorker::unregister' => ['bool', 'function_name'=>'string'], +'GearmanWorker::unregisterAll' => ['bool'], +'GearmanWorker::wait' => ['bool'], +'GearmanWorker::work' => ['bool'], +'Gender\Gender::__construct' => ['void', 'dsn='=>'string'], +'Gender\Gender::connect' => ['bool', 'dsn'=>'string'], +'Gender\Gender::country' => ['array', 'country'=>'int'], +'Gender\Gender::get' => ['int', 'name'=>'string', 'country='=>'int'], +'Gender\Gender::isNick' => ['array', 'name0'=>'string', 'name1'=>'string', 'country='=>'int'], +'Gender\Gender::similarNames' => ['array', 'name'=>'string', 'country='=>'int'], +'Generator::__wakeup' => ['void'], +'Generator::current' => ['mixed'], +'Generator::getReturn' => ['mixed'], +'Generator::key' => ['mixed'], +'Generator::next' => ['void'], +'Generator::rewind' => ['void'], +'Generator::send' => ['mixed', 'value'=>'mixed'], +'Generator::throw' => ['mixed', 'exception'=>'Exception|Throwable'], +'Generator::valid' => ['bool'], +'geoip_asnum_by_name' => ['string', 'hostname'=>'string'], +'geoip_continent_code_by_name' => ['string', 'hostname'=>'string'], +'geoip_country_code3_by_name' => ['string', 'hostname'=>'string'], +'geoip_country_code_by_name' => ['string', 'hostname'=>'string'], +'geoip_country_name_by_name' => ['string', 'hostname'=>'string'], +'geoip_database_info' => ['string', 'database='=>'int'], +'geoip_db_avail' => ['bool', 'database'=>'int'], +'geoip_db_filename' => ['string', 'database'=>'int'], +'geoip_db_get_all_info' => ['array'], +'geoip_domain_by_name' => ['string', 'hostname'=>'string'], +'geoip_id_by_name' => ['int', 'hostname'=>'string'], +'geoip_isp_by_name' => ['string', 'hostname'=>'string'], +'geoip_netspeedcell_by_name' => ['string', 'hostname'=>'string'], +'geoip_org_by_name' => ['string', 'hostname'=>'string'], +'geoip_record_by_name' => ['array', 'hostname'=>'string'], +'geoip_region_by_name' => ['array', 'hostname'=>'string'], +'geoip_region_name_by_code' => ['string', 'country_code'=>'string', 'region_code'=>'string'], +'geoip_setup_custom_directory' => ['void', 'path'=>'string'], +'geoip_time_zone_by_country_and_region' => ['string|false', 'country_code'=>'string', 'region_code='=>'string'], +'get_browser' => ['mixed', 'browser_name='=>'string', 'return_array='=>'bool'], +'get_call_stack' => [''], +'get_called_class' => ['string'], +'get_cfg_var' => ['mixed', 'option_name'=>'string'], +'get_class' => ['string', 'object='=>'object'], +'get_class_methods' => ['array', 'class'=>'mixed'], +'get_class_vars' => ['array', 'class_name'=>'string'], +'get_current_user' => ['string'], +'get_declared_classes' => ['array'], +'get_declared_interfaces' => ['array'], +'get_declared_traits' => ['array'], +'get_defined_constants' => ['array', 'categorize='=>'bool'], +'get_defined_functions' => ['array>', 'exclude_disabled='=>'bool'], +'get_defined_vars' => ['array'], +'get_extension_funcs' => ['array', 'extension_name'=>'string'], +'get_headers' => ['array|false', 'url'=>'string', 'format='=>'int', 'context='=>'resource'], +'get_html_translation_table' => ['array', 'table='=>'int', 'flags='=>'int', 'encoding='=>'string'], +'get_include_path' => ['string'], +'get_included_files' => ['array'], +'get_loaded_extensions' => ['array', 'zend_extensions='=>'bool'], +'get_magic_quotes_gpc' => ['bool'], +'get_magic_quotes_runtime' => ['bool'], +'get_meta_tags' => ['array', 'filename'=>'string', 'use_include_path='=>'bool'], +'get_object_vars' => ['array', 'obj'=>'object'], +'get_parent_class' => ['string|false', 'object='=>'mixed'], +'get_required_files' => ['string[]'], +'get_resource_type' => ['string', 'res'=>'resource'], +'get_resources' => ['resource[]', 'resource_type'=>'string'], +'getallheaders' => ['array'], +'getcwd' => ['string|false'], +'getdate' => ['array', 'timestamp='=>'int'], +'getenv' => ['string|false', 'varname'=>'string', 'local_only='=>'bool'], +'getenv\'1' => ['string[]'], +'gethostbyaddr' => ['string|false', 'ip_address'=>'string'], +'gethostbyname' => ['string', 'hostname'=>'string'], +'gethostbynamel' => ['array|false', 'hostname'=>'string'], +'gethostname' => ['string|false'], +'getimagesize' => ['array|false', 'imagefile'=>'string', '&w_info='=>'array'], +'getimagesizefromstring' => ['array|false', 'data'=>'string', '&w_info='=>'array'], +'getlastmod' => ['int'], +'getmxrr' => ['bool', 'hostname'=>'string', '&w_mxhosts'=>'array', '&w_weight='=>'array'], +'getmygid' => ['int'], +'getmyinode' => ['int'], +'getmypid' => ['int'], +'getmyuid' => ['int'], +'getopt' => ['array|array|array>', 'options'=>'string', 'longopts='=>'array', '&w_optind='=>'int'], +'getprotobyname' => ['int|false', 'name'=>'string'], +'getprotobynumber' => ['string', 'proto'=>'int'], +'getrandmax' => ['int'], +'getrusage' => ['array', 'who='=>'int'], +'getservbyname' => ['int|false', 'service'=>'string', 'protocol'=>'string'], +'getservbyport' => ['string|false', 'port'=>'int', 'protocol'=>'string'], +'gettext' => ['string', 'msgid'=>'string'], +'gettimeofday' => ['array|float', 'get_as_float='=>'bool'], +'gettype' => ['string', 'var'=>'mixed'], +'glob' => ['array', 'pattern'=>'string', 'flags='=>'int'], +'GlobIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'], +'GlobIterator::cont' => ['int'], +'GlobIterator::count' => ['int'], +'Gmagick::__construct' => ['void', 'filename='=>'string'], +'Gmagick::addimage' => ['Gmagick', 'gmagick'=>'gmagick'], +'Gmagick::addnoiseimage' => ['Gmagick', 'noise'=>'int'], +'Gmagick::annotateimage' => ['Gmagick', 'gmagickdraw'=>'gmagickdraw', 'x'=>'float', 'y'=>'float', 'angle'=>'float', 'text'=>'string'], +'Gmagick::blurimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], +'Gmagick::borderimage' => ['Gmagick', 'color'=>'gmagickpixel', 'width'=>'int', 'height'=>'int'], +'Gmagick::charcoalimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float'], +'Gmagick::chopimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Gmagick::clear' => ['Gmagick'], +'Gmagick::commentimage' => ['Gmagick', 'comment'=>'string'], +'Gmagick::compositeimage' => ['Gmagick', 'source'=>'gmagick', 'compose'=>'int', 'x'=>'int', 'y'=>'int'], +'Gmagick::cropimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Gmagick::cropthumbnailimage' => ['Gmagick', 'width'=>'int', 'height'=>'int'], +'Gmagick::current' => ['Gmagick'], +'Gmagick::cyclecolormapimage' => ['Gmagick', 'displace'=>'int'], +'Gmagick::deconstructimages' => ['Gmagick'], +'Gmagick::despeckleimage' => ['Gmagick'], +'Gmagick::destroy' => ['Gmagick'], +'Gmagick::drawimage' => ['Gmagick', 'gmagickdraw'=>'gmagickdraw'], +'Gmagick::edgeimage' => ['Gmagick', 'radius'=>'float'], +'Gmagick::embossimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float'], +'Gmagick::enhanceimage' => ['Gmagick'], +'Gmagick::equalizeimage' => ['Gmagick'], +'Gmagick::flipimage' => ['Gmagick'], +'Gmagick::flopimage' => ['Gmagick'], +'Gmagick::frameimage' => ['Gmagick', 'color'=>'gmagickpixel', 'width'=>'int', 'height'=>'int', 'inner_bevel'=>'int', 'outer_bevel'=>'int'], +'Gmagick::gammaimage' => ['Gmagick', 'gamma'=>'float'], +'Gmagick::getcopyright' => ['string'], +'Gmagick::getfilename' => ['string'], +'Gmagick::getimagebackgroundcolor' => ['GmagickPixel'], +'Gmagick::getimageblueprimary' => ['array'], +'Gmagick::getimagebordercolor' => ['GmagickPixel'], +'Gmagick::getimagechanneldepth' => ['int', 'channel_type'=>'int'], +'Gmagick::getimagecolors' => ['int'], +'Gmagick::getimagecolorspace' => ['int'], +'Gmagick::getimagecompose' => ['int'], +'Gmagick::getimagedelay' => ['int'], +'Gmagick::getimagedepth' => ['int'], +'Gmagick::getimagedispose' => ['int'], +'Gmagick::getimageextrema' => ['array'], +'Gmagick::getimagefilename' => ['string'], +'Gmagick::getimageformat' => ['string'], +'Gmagick::getimagegamma' => ['float'], +'Gmagick::getimagegreenprimary' => ['array'], +'Gmagick::getimageheight' => ['int'], +'Gmagick::getimagehistogram' => ['array'], +'Gmagick::getimageindex' => ['int'], +'Gmagick::getimageinterlacescheme' => ['int'], +'Gmagick::getimageiterations' => ['int'], +'Gmagick::getimagematte' => ['int'], +'Gmagick::getimagemattecolor' => ['GmagickPixel'], +'Gmagick::getimageprofile' => ['string', 'name'=>'string'], +'Gmagick::getimageredprimary' => ['array'], +'Gmagick::getimagerenderingintent' => ['int'], +'Gmagick::getimageresolution' => ['array'], +'Gmagick::getimagescene' => ['int'], +'Gmagick::getimagesignature' => ['string'], +'Gmagick::getimagetype' => ['int'], +'Gmagick::getimageunits' => ['int'], +'Gmagick::getimagewhitepoint' => ['array'], +'Gmagick::getimagewidth' => ['int'], +'Gmagick::getpackagename' => ['string'], +'Gmagick::getquantumdepth' => ['array'], +'Gmagick::getreleasedate' => ['string'], +'Gmagick::getsamplingfactors' => ['array'], +'Gmagick::getsize' => ['array'], +'Gmagick::getversion' => ['array'], +'Gmagick::hasnextimage' => ['mixed'], +'Gmagick::haspreviousimage' => ['mixed'], +'Gmagick::implodeimage' => ['mixed', 'radius'=>'float'], +'Gmagick::labelimage' => ['mixed', 'label'=>'string'], +'Gmagick::levelimage' => ['mixed', 'blackpoint'=>'float', 'gamma'=>'float', 'whitepoint'=>'float', 'channel='=>'int'], +'Gmagick::magnifyimage' => ['mixed'], +'Gmagick::mapimage' => ['Gmagick', 'gmagick'=>'gmagick', 'dither'=>'bool'], +'Gmagick::medianfilterimage' => ['void', 'radius'=>'float'], +'Gmagick::minifyimage' => ['Gmagick'], +'Gmagick::modulateimage' => ['Gmagick', 'brightness'=>'float', 'saturation'=>'float', 'hue'=>'float'], +'Gmagick::motionblurimage' => ['Gmagick', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float'], +'Gmagick::newimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'background'=>'string', 'format='=>'string'], +'Gmagick::nextimage' => ['bool'], +'Gmagick::normalizeimage' => ['Gmagick', 'channel='=>'int'], +'Gmagick::oilpaintimage' => ['Gmagick', 'radius'=>'float'], +'Gmagick::previousimage' => ['bool'], +'Gmagick::profileimage' => ['Gmagick', 'name'=>'string', 'profile'=>'string'], +'Gmagick::quantizeimage' => ['Gmagick', 'numcolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'], +'Gmagick::quantizeimages' => ['Gmagick', 'numcolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'], +'Gmagick::queryfontmetrics' => ['array', 'draw'=>'gmagickdraw', 'text'=>'string'], +'Gmagick::queryfonts' => ['array', 'pattern='=>'string'], +'Gmagick::queryformats' => ['array', 'pattern='=>'string'], +'Gmagick::radialblurimage' => ['Gmagick', 'angle'=>'float', 'channel='=>'int'], +'Gmagick::raiseimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int', 'raise'=>'bool'], +'Gmagick::read' => ['Gmagick', 'filename'=>'string'], +'Gmagick::readimage' => ['Gmagick', 'filename'=>'string'], +'Gmagick::readimageblob' => ['Gmagick', 'imagecontents'=>'string', 'filename='=>'string'], +'Gmagick::readimagefile' => ['Gmagick', 'fp'=>'resource', 'filename='=>'string'], +'Gmagick::reducenoiseimage' => ['Gmagick', 'radius'=>'float'], +'Gmagick::removeimage' => ['Gmagick'], +'Gmagick::removeimageprofile' => ['string', 'name'=>'string'], +'Gmagick::resampleimage' => ['Gmagick', 'xresolution'=>'float', 'yresolution'=>'float', 'filter'=>'int', 'blur'=>'float'], +'Gmagick::resizeimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'filter'=>'int', 'blur'=>'float', 'fit='=>'bool'], +'Gmagick::rollimage' => ['Gmagick', 'x'=>'int', 'y'=>'int'], +'Gmagick::rotateimage' => ['Gmagick', 'color'=>'mixed', 'degrees'=>'float'], +'Gmagick::scaleimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'fit='=>'bool'], +'Gmagick::separateimagechannel' => ['Gmagick', 'channel'=>'int'], +'Gmagick::setCompressionQuality' => ['Gmagick', 'quality'=>'int'], +'Gmagick::setfilename' => ['Gmagick', 'filename'=>'string'], +'Gmagick::setimagebackgroundcolor' => ['Gmagick', 'color'=>'gmagickpixel'], +'Gmagick::setimageblueprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'], +'Gmagick::setimagebordercolor' => ['Gmagick', 'color'=>'gmagickpixel'], +'Gmagick::setimagechanneldepth' => ['Gmagick', 'channel'=>'int', 'depth'=>'int'], +'Gmagick::setimagecolorspace' => ['Gmagick', 'colorspace'=>'int'], +'Gmagick::setimagecompose' => ['Gmagick', 'composite'=>'int'], +'Gmagick::setimagedelay' => ['Gmagick', 'delay'=>'int'], +'Gmagick::setimagedepth' => ['Gmagick', 'depth'=>'int'], +'Gmagick::setimagedispose' => ['Gmagick', 'disposetype'=>'int'], +'Gmagick::setimagefilename' => ['Gmagick', 'filename'=>'string'], +'Gmagick::setimageformat' => ['Gmagick', 'imageformat'=>'string'], +'Gmagick::setimagegamma' => ['Gmagick', 'gamma'=>'float'], +'Gmagick::setimagegreenprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'], +'Gmagick::setimageindex' => ['Gmagick', 'index'=>'int'], +'Gmagick::setimageinterlacescheme' => ['Gmagick', 'interlace'=>'int'], +'Gmagick::setimageiterations' => ['Gmagick', 'iterations'=>'int'], +'Gmagick::setimageprofile' => ['Gmagick', 'name'=>'string', 'profile'=>'string'], +'Gmagick::setimageredprimary' => ['Gmagick', 'x'=>'float', 'y'=>'float'], +'Gmagick::setimagerenderingintent' => ['Gmagick', 'rendering_intent'=>'int'], +'Gmagick::setimageresolution' => ['Gmagick', 'xresolution'=>'float', 'yresolution'=>'float'], +'Gmagick::setimagescene' => ['Gmagick', 'scene'=>'int'], +'Gmagick::setimagetype' => ['Gmagick', 'imgtype'=>'int'], +'Gmagick::setimageunits' => ['Gmagick', 'resolution'=>'int'], +'Gmagick::setimagewhitepoint' => ['Gmagick', 'x'=>'float', 'y'=>'float'], +'Gmagick::setsamplingfactors' => ['Gmagick', 'factors'=>'array'], +'Gmagick::setsize' => ['Gmagick', 'columns'=>'int', 'rows'=>'int'], +'Gmagick::shearimage' => ['Gmagick', 'color'=>'mixed', 'xshear'=>'float', 'yshear'=>'float'], +'Gmagick::solarizeimage' => ['Gmagick', 'threshold'=>'int'], +'Gmagick::spreadimage' => ['Gmagick', 'radius'=>'float'], +'Gmagick::stripimage' => ['Gmagick'], +'Gmagick::swirlimage' => ['Gmagick', 'degrees'=>'float'], +'Gmagick::thumbnailimage' => ['Gmagick', 'width'=>'int', 'height'=>'int', 'fit='=>'bool'], +'Gmagick::trimimage' => ['Gmagick', 'fuzz'=>'float'], +'Gmagick::write' => ['', 'filename'=>'string'], +'Gmagick::writeimage' => ['Gmagick', 'filename'=>'string', 'all_frames='=>'bool'], +'GmagickDraw::annotate' => ['GmagickDraw', 'x'=>'float', 'y'=>'float', 'text'=>'string'], +'GmagickDraw::arc' => ['GmagickDraw', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float', 'sd'=>'float', 'ed'=>'float'], +'GmagickDraw::bezier' => ['GmagickDraw', 'coordinate_array'=>'array'], +'GmagickDraw::ellipse' => ['GmagickDraw', 'ox'=>'float', 'oy'=>'float', 'rx'=>'float', 'ry'=>'float', 'start'=>'float', 'end'=>'float'], +'GmagickDraw::getfillcolor' => ['GmagickPixel'], +'GmagickDraw::getfillopacity' => ['float'], +'GmagickDraw::getfont' => ['string'], +'GmagickDraw::getfontsize' => ['float'], +'GmagickDraw::getfontstyle' => ['int'], +'GmagickDraw::getfontweight' => ['int'], +'GmagickDraw::getstrokecolor' => ['GmagickPixel'], +'GmagickDraw::getstrokeopacity' => ['float'], +'GmagickDraw::getstrokewidth' => ['float'], +'GmagickDraw::gettextdecoration' => ['int'], +'GmagickDraw::gettextencoding' => ['string'], +'GmagickDraw::line' => ['GmagickDraw', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float'], +'GmagickDraw::point' => ['GmagickDraw', 'x'=>'float', 'y'=>'float'], +'GmagickDraw::polygon' => ['GmagickDraw', 'coordinates'=>'array'], +'GmagickDraw::polyline' => ['GmagickDraw', 'coordinate_array'=>'array'], +'GmagickDraw::rectangle' => ['GmagickDraw', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'], +'GmagickDraw::rotate' => ['GmagickDraw', 'degrees'=>'float'], +'GmagickDraw::roundrectangle' => ['GmagickDraw', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'rx'=>'float', 'ry'=>'float'], +'GmagickDraw::scale' => ['GmagickDraw', 'x'=>'float', 'y'=>'float'], +'GmagickDraw::setfillcolor' => ['GmagickDraw', 'color'=>'string'], +'GmagickDraw::setfillopacity' => ['GmagickDraw', 'fill_opacity'=>'float'], +'GmagickDraw::setfont' => ['GmagickDraw', 'font'=>'string'], +'GmagickDraw::setfontsize' => ['GmagickDraw', 'pointsize'=>'float'], +'GmagickDraw::setfontstyle' => ['GmagickDraw', 'style'=>'int'], +'GmagickDraw::setfontweight' => ['GmagickDraw', 'weight'=>'int'], +'GmagickDraw::setstrokecolor' => ['GmagickDraw', 'color'=>'gmagickpixel'], +'GmagickDraw::setstrokeopacity' => ['GmagickDraw', 'stroke_opacity'=>'float'], +'GmagickDraw::setstrokewidth' => ['GmagickDraw', 'width'=>'float'], +'GmagickDraw::settextdecoration' => ['GmagickDraw', 'decoration'=>'int'], +'GmagickDraw::settextencoding' => ['GmagickDraw', 'encoding'=>'string'], +'GmagickPixel::__construct' => ['void', 'color='=>'string'], +'GmagickPixel::getcolor' => ['mixed', 'as_array='=>'bool', 'normalize_array='=>'bool'], +'GmagickPixel::getcolorcount' => ['int'], +'GmagickPixel::getcolorvalue' => ['float', 'color'=>'int'], +'GmagickPixel::setcolor' => ['GmagickPixel', 'color'=>'string'], +'GmagickPixel::setcolorvalue' => ['GmagickPixel', 'color'=>'int', 'value'=>'float'], +'gmdate' => ['string', 'format'=>'string', 'timestamp='=>'int'], +'gmmktime' => ['int', 'hour='=>'int', 'min='=>'int', 'sec='=>'int', 'mon='=>'int', 'day='=>'int', 'year='=>'int'], +'GMP::__construct' => ['void'], +'GMP::serialize' => ['string'], +'GMP::__toString' => ['string'], +'GMP::unserialize' => ['void', 'serialized'=>'string'], +'gmp_abs' => ['GMP', 'a'=>'GMP|string|int'], +'gmp_add' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_and' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_clrbit' => ['void', 'a'=>'GMP|string|int', 'index'=>'int'], +'gmp_cmp' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_com' => ['GMP', 'a'=>'GMP|string|int'], +'gmp_div' => ['resource', 'a'=>'GMP|resource|string', 'b'=>'GMP|resource|string', 'round='=>'int'], +'gmp_div_q' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int', 'round='=>'int'], +'gmp_div_qr' => ['array', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int', 'round='=>'int'], +'gmp_div_r' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int', 'round='=>'int'], +'gmp_divexact' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_export' => ['string', 'gmpnumber'=>'GMP|string|int', 'word_size='=>'int', 'options='=>'int'], +'gmp_fact' => ['GMP', 'a'=>'int'], +'gmp_gcd' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_gcdext' => ['array', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_hamdist' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_import' => ['GMP', 'data'=>'string', 'word_size='=>'int', 'options='=>'int'], +'gmp_init' => ['GMP', 'number'=>'int|string', 'base='=>'int'], +'gmp_intval' => ['int', 'gmpnumber'=>'GMP|string|int'], +'gmp_invert' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_jacobi' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_legendre' => ['int', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_mod' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_mul' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_neg' => ['GMP', 'a'=>'GMP|string|int'], +'gmp_nextprime' => ['GMP', 'a'=>'GMP|string|int'], +'gmp_or' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_perfect_square' => ['bool', 'a'=>'GMP|string|int'], +'gmp_popcount' => ['int', 'a'=>'GMP|string|int'], +'gmp_pow' => ['GMP', 'base'=>'GMP|string|int', 'exp'=>'int'], +'gmp_powm' => ['GMP', 'base'=>'GMP|string|int', 'exp'=>'GMP|string|int', 'mod'=>'GMP|string|int'], +'gmp_prob_prime' => ['int', 'a'=>'GMP|string|int', 'reps='=>'int'], +'gmp_random' => ['GMP', 'limiter='=>'int'], +'gmp_random_bits' => ['GMP', 'bits'=>'int'], +'gmp_random_range' => ['GMP', 'min'=>'GMP|string|int', 'max'=>'GMP|string|int'], +'gmp_random_seed' => ['GMP', 'seed'=>'GMP|string|int'], +'gmp_root' => ['GMP', 'a'=>'GMP|string|int', 'nth'=>'int'], +'gmp_rootrem' => ['array', 'a'=>'GMP|string|int', 'nth'=>'int'], +'gmp_scan0' => ['int', 'a'=>'GMP|string|int', 'start'=>'int'], +'gmp_scan1' => ['int', 'a'=>'GMP|string|int', 'start'=>'int'], +'gmp_setbit' => ['void', 'a'=>'GMP|string|int', 'index'=>'int', 'set_clear='=>'bool'], +'gmp_sign' => ['int', 'a'=>'GMP|string|int'], +'gmp_sqrt' => ['GMP', 'a'=>'GMP|string|int'], +'gmp_sqrtrem' => ['array', 'a'=>'GMP|string|int'], +'gmp_strval' => ['string', 'gmpnumber'=>'GMP|string|int', 'base='=>'int'], +'gmp_sub' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmp_testbit' => ['bool', 'a'=>'GMP|string|int', 'index'=>'int'], +'gmp_xor' => ['GMP', 'a'=>'GMP|string|int', 'b'=>'GMP|string|int'], +'gmstrftime' => ['string', 'format'=>'string', 'timestamp='=>'int'], +'gnupg::adddecryptkey' => ['bool', 'fingerprint'=>'string', 'passphrase'=>'string'], +'gnupg::addencryptkey' => ['bool', 'fingerprint'=>'string'], +'gnupg::addsignkey' => ['bool', 'fingerprint'=>'string', 'passphrase='=>'string'], +'gnupg::cleardecryptkeys' => ['bool'], +'gnupg::clearencryptkeys' => ['bool'], +'gnupg::clearsignkeys' => ['bool'], +'gnupg::decrypt' => ['string', 'text'=>'string'], +'gnupg::decryptverify' => ['array', 'text'=>'string', '&plaintext'=>'string'], +'gnupg::encrypt' => ['string', 'plaintext'=>'string'], +'gnupg::encryptsign' => ['string', 'plaintext'=>'string'], +'gnupg::export' => ['string', 'fingerprint'=>'string'], +'gnupg::geterror' => ['string'], +'gnupg::getprotocol' => ['int'], +'gnupg::import' => ['array', 'keydata'=>'string'], +'gnupg::init' => ['resource'], +'gnupg::keyinfo' => ['array', 'pattern'=>'string'], +'gnupg::setarmor' => ['bool', 'armor'=>'int'], +'gnupg::seterrormode' => ['void', 'errormode'=>'int'], +'gnupg::setsignmode' => ['bool', 'signmode'=>'int'], +'gnupg::sign' => ['string', 'plaintext'=>'string'], +'gnupg::verify' => ['array', 'signed_text'=>'string', 'signature'=>'string', '&plaintext='=>'string'], +'gnupg_adddecryptkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string', 'passphrase'=>'string'], +'gnupg_addencryptkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string'], +'gnupg_addsignkey' => ['bool', 'identifier'=>'resource', 'fingerprint'=>'string', 'passphrase='=>'string'], +'gnupg_cleardecryptkeys' => ['bool', 'identifier'=>'resource'], +'gnupg_clearencryptkeys' => ['bool', 'identifier'=>'resource'], +'gnupg_clearsignkeys' => ['bool', 'identifier'=>'resource'], +'gnupg_decrypt' => ['string', 'identifier'=>'resource', 'text'=>'string'], +'gnupg_decryptverify' => ['array', 'identifier'=>'resource', 'text'=>'string', 'plaintext'=>'string'], +'gnupg_encrypt' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'], +'gnupg_encryptsign' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'], +'gnupg_export' => ['string', 'identifier'=>'resource', 'fingerprint'=>'string'], +'gnupg_geterror' => ['string', 'identifier'=>'resource'], +'gnupg_getprotocol' => ['int', 'identifier'=>'resource'], +'gnupg_import' => ['array', 'identifier'=>'resource', 'keydata'=>'string'], +'gnupg_init' => ['resource'], +'gnupg_keyinfo' => ['array', 'identifier'=>'resource', 'pattern'=>'string'], +'gnupg_setarmor' => ['bool', 'identifier'=>'resource', 'armor'=>'int'], +'gnupg_seterrormode' => ['void', 'identifier'=>'resource', 'errormode'=>'int'], +'gnupg_setsignmode' => ['bool', 'identifier'=>'resource', 'signmode'=>'int'], +'gnupg_sign' => ['string', 'identifier'=>'resource', 'plaintext'=>'string'], +'gnupg_verify' => ['array', 'identifier'=>'resource', 'signed_text'=>'string', 'signature'=>'string', 'plaintext='=>'string'], +'gopher_parsedir' => ['array', 'dirent'=>'string'], +'grapheme_extract' => ['string|false', 'str'=>'string', 'size'=>'int', 'extract_type='=>'int', 'start='=>'int', '&w_next='=>'int'], +'grapheme_stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], +'grapheme_stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool'], +'grapheme_strlen' => ['int|false', 'str'=>'string'], +'grapheme_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], +'grapheme_strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], +'grapheme_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int'], +'grapheme_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool'], +'grapheme_substr' => ['string|false', 'str'=>'string', 'start'=>'int', 'length='=>'int'], +'gregoriantojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], +'gridObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'Grpc\Call::__construct' => ['void', 'channel'=>'Grpc\Channel', 'method'=>'string', 'absolute_deadline'=>'Grpc\Timeval', 'host_override='=>'mixed'], +'Grpc\Call::cancel' => [''], +'Grpc\Call::getPeer' => ['string'], +'Grpc\Call::setCredentials' => ['int', 'creds_obj'=>'Grpc\CallCredentials'], +'Grpc\Call::startBatch' => ['object', 'batch'=>'array'], +'Grpc\CallCredentials::createComposite' => ['Grpc\CallCredentials', 'cred1'=>'Grpc\CallCredentials', 'cred2'=>'Grpc\CallCredentials'], +'Grpc\CallCredentials::createFromPlugin' => ['Grpc\CallCredentials', 'callback'=>'Closure'], +'Grpc\Channel::__construct' => ['void', 'target'=>'string', 'args='=>'array'], +'Grpc\Channel::close' => [''], +'Grpc\Channel::getConnectivityState' => ['int', 'try_to_connect='=>'bool|false'], +'Grpc\Channel::getTarget' => ['string'], +'Grpc\Channel::watchConnectivityState' => ['bool', 'last_state'=>'int', 'deadline_obj'=>'Grpc\Timeval'], +'Grpc\ChannelCredentials::createComposite' => ['Grpc\ChannelCredentials', 'cred1'=>'Grpc\ChannelCredentials', 'cred2'=>'Grpc\CallCredentials'], +'Grpc\ChannelCredentials::createDefault' => ['Grpc\ChannelCredentials'], +'Grpc\ChannelCredentials::createInsecure' => ['null'], +'Grpc\ChannelCredentials::createSsl' => ['Grpc\ChannelCredentials', 'pem_root_certs'=>'string', 'pem_private_key='=>'string', 'pem_cert_chain='=>'string'], +'Grpc\ChannelCredentials::setDefaultRootsPem' => ['', 'pem_roots'=>'string'], +'Grpc\Server::__construct' => ['void', 'args'=>'array'], +'Grpc\Server::addHttp2Port' => ['bool', 'addr'=>'string'], +'Grpc\Server::addSecureHttp2Port' => ['bool', 'addr'=>'string', 'creds_obj'=>'Grpc\ServerCredentials'], +'Grpc\Server::requestCall' => ['', 'tag_new'=>'int', 'tag_cancel'=>'int'], +'Grpc\Server::start' => [''], +'Grpc\ServerCredentials::createSsl' => ['object', 'pem_root_certs'=>'string', 'pem_private_key'=>'string', 'pem_cert_chain'=>'string'], +'Grpc\Timeval::__construct' => ['void', 'usec'=>'int'], +'Grpc\Timeval::add' => ['Grpc\Timeval', 'other'=>'Grpc\Timeval'], +'Grpc\Timeval::compare' => ['int', 'a'=>'Grpc\Timeval', 'b'=>'Grpc\Timeval'], +'Grpc\Timeval::infFuture' => ['Grpc\Timeval'], +'Grpc\Timeval::infPast' => ['Grpc\Timeval'], +'Grpc\Timeval::now' => ['Grpc\Timeval'], +'Grpc\Timeval::similar' => ['bool', 'a'=>'Grpc\Timeval', 'b'=>'Grpc\Timeval', 'threshold'=>'Grpc\Timeval'], +'Grpc\Timeval::sleepUntil' => [''], +'Grpc\Timeval::subtract' => ['Grpc\Timeval', 'other'=>'Grpc\Timeval'], +'Grpc\Timeval::zero' => ['Grpc\Timeval'], +'gupnp_context_get_host_ip' => ['string', 'context'=>'resource'], +'gupnp_context_get_port' => ['int', 'context'=>'resource'], +'gupnp_context_get_subscription_timeout' => ['int', 'context'=>'resource'], +'gupnp_context_host_path' => ['bool', 'context'=>'resource', 'local_path'=>'string', 'server_path'=>'string'], +'gupnp_context_new' => ['resource', 'host_ip='=>'string', 'port='=>'int'], +'gupnp_context_set_subscription_timeout' => ['void', 'context'=>'resource', 'timeout'=>'int'], +'gupnp_context_timeout_add' => ['bool', 'context'=>'resource', 'timeout'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], +'gupnp_context_unhost_path' => ['bool', 'context'=>'resource', 'server_path'=>'string'], +'gupnp_control_point_browse_start' => ['bool', 'cpoint'=>'resource'], +'gupnp_control_point_browse_stop' => ['bool', 'cpoint'=>'resource'], +'gupnp_control_point_callback_set' => ['bool', 'cpoint'=>'resource', 'signal'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], +'gupnp_control_point_new' => ['resource', 'context'=>'resource', 'target'=>'string'], +'gupnp_device_action_callback_set' => ['bool', 'root_device'=>'resource', 'signal'=>'int', 'action_name'=>'string', 'callback'=>'mixed', 'arg='=>'mixed'], +'gupnp_device_info_get' => ['array', 'root_device'=>'resource'], +'gupnp_device_info_get_service' => ['resource', 'root_device'=>'resource', 'type'=>'string'], +'gupnp_root_device_get_available' => ['bool', 'root_device'=>'resource'], +'gupnp_root_device_get_relative_location' => ['string', 'root_device'=>'resource'], +'gupnp_root_device_new' => ['resource', 'context'=>'resource', 'location'=>'string', 'description_dir'=>'string'], +'gupnp_root_device_set_available' => ['bool', 'root_device'=>'resource', 'available'=>'bool'], +'gupnp_root_device_start' => ['bool', 'root_device'=>'resource'], +'gupnp_root_device_stop' => ['bool', 'root_device'=>'resource'], +'gupnp_service_action_get' => ['mixed', 'action'=>'resource', 'name'=>'string', 'type'=>'int'], +'gupnp_service_action_return' => ['bool', 'action'=>'resource'], +'gupnp_service_action_return_error' => ['bool', 'action'=>'resource', 'error_code'=>'int', 'error_description='=>'string'], +'gupnp_service_action_set' => ['bool', 'action'=>'resource', 'name'=>'string', 'type'=>'int', 'value'=>'mixed'], +'gupnp_service_freeze_notify' => ['bool', 'service'=>'resource'], +'gupnp_service_info_get' => ['array', 'proxy'=>'resource'], +'gupnp_service_info_get_introspection' => ['mixed', 'proxy'=>'resource', 'callback='=>'mixed', 'arg='=>'mixed'], +'gupnp_service_introspection_get_state_variable' => ['array', 'introspection'=>'resource', 'variable_name'=>'string'], +'gupnp_service_notify' => ['bool', 'service'=>'resource', 'name'=>'string', 'type'=>'int', 'value'=>'mixed'], +'gupnp_service_proxy_action_get' => ['mixed', 'proxy'=>'resource', 'action'=>'string', 'name'=>'string', 'type'=>'int'], +'gupnp_service_proxy_action_set' => ['bool', 'proxy'=>'resource', 'action'=>'string', 'name'=>'string', 'value'=>'mixed', 'type'=>'int'], +'gupnp_service_proxy_add_notify' => ['bool', 'proxy'=>'resource', 'value'=>'string', 'type'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], +'gupnp_service_proxy_callback_set' => ['bool', 'proxy'=>'resource', 'signal'=>'int', 'callback'=>'mixed', 'arg='=>'mixed'], +'gupnp_service_proxy_get_subscribed' => ['bool', 'proxy'=>'resource'], +'gupnp_service_proxy_remove_notify' => ['bool', 'proxy'=>'resource', 'value'=>'string'], +'gupnp_service_proxy_send_action' => ['array', 'proxy'=>'resource', 'action'=>'string', 'in_params'=>'array', 'out_params'=>'array'], +'gupnp_service_proxy_set_subscribed' => ['bool', 'proxy'=>'resource', 'subscribed'=>'bool'], +'gupnp_service_thaw_notify' => ['bool', 'service'=>'resource'], +'gzclose' => ['bool', 'zp'=>'resource'], +'gzcompress' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'], +'gzdecode' => ['string|false', 'data'=>'string', 'length='=>'int'], +'gzdeflate' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding='=>'int'], +'gzencode' => ['string|false', 'data'=>'string', 'level='=>'int', 'encoding_mode='=>'int'], +'gzeof' => ['int', 'zp'=>'resource'], +'gzfile' => ['array', 'filename'=>'string', 'use_include_path='=>'int'], +'gzgetc' => ['string|false', 'zp'=>'resource'], +'gzgets' => ['string|false', 'zp'=>'resource', 'length='=>'int'], +'gzgetss' => ['string|false', 'zp'=>'resource', 'length'=>'int', 'allowable_tags='=>'string'], +'gzinflate' => ['string|false', 'data'=>'string', 'length='=>'int'], +'gzopen' => ['resource|false', 'filename'=>'string', 'mode'=>'string', 'use_include_path='=>'int'], +'gzpassthru' => ['int|false', 'zp'=>'resource'], +'gzputs' => ['int', 'zp'=>'resource', 'string'=>'string', 'length='=>'int'], +'gzread' => ['string', 'zp'=>'resource', 'length'=>'int'], +'gzrewind' => ['bool', 'zp'=>'resource'], +'gzseek' => ['int', 'zp'=>'resource', 'offset'=>'int', 'whence='=>'int'], +'gztell' => ['int|false', 'zp'=>'resource'], +'gzuncompress' => ['string|false', 'data'=>'string', 'length='=>'int'], +'gzwrite' => ['int', 'zp'=>'resource', 'string'=>'string', 'length='=>'int'], +'HaruAnnotation::setBorderStyle' => ['bool', 'width'=>'float', 'dash_on'=>'int', 'dash_off'=>'int'], +'HaruAnnotation::setHighlightMode' => ['bool', 'mode'=>'int'], +'HaruAnnotation::setIcon' => ['bool', 'icon'=>'int'], +'HaruAnnotation::setOpened' => ['bool', 'opened'=>'bool'], +'HaruDestination::setFit' => ['bool'], +'HaruDestination::setFitB' => ['bool'], +'HaruDestination::setFitBH' => ['bool', 'top'=>'float'], +'HaruDestination::setFitBV' => ['bool', 'left'=>'float'], +'HaruDestination::setFitH' => ['bool', 'top'=>'float'], +'HaruDestination::setFitR' => ['bool', 'left'=>'float', 'bottom'=>'float', 'right'=>'float', 'top'=>'float'], +'HaruDestination::setFitV' => ['bool', 'left'=>'float'], +'HaruDestination::setXYZ' => ['bool', 'left'=>'float', 'top'=>'float', 'zoom'=>'float'], +'HaruDoc::__construct' => ['void'], +'HaruDoc::addPage' => ['object'], +'HaruDoc::addPageLabel' => ['bool', 'first_page'=>'int', 'style'=>'int', 'first_num'=>'int', 'prefix='=>'string'], +'HaruDoc::createOutline' => ['object', 'title'=>'string', 'parent_outline='=>'object', 'encoder='=>'object'], +'HaruDoc::getCurrentEncoder' => ['object'], +'HaruDoc::getCurrentPage' => ['object'], +'HaruDoc::getEncoder' => ['object', 'encoding'=>'string'], +'HaruDoc::getFont' => ['object', 'fontname'=>'string', 'encoding='=>'string'], +'HaruDoc::getInfoAttr' => ['string', 'type'=>'int'], +'HaruDoc::getPageLayout' => ['int'], +'HaruDoc::getPageMode' => ['int'], +'HaruDoc::getStreamSize' => ['int'], +'HaruDoc::insertPage' => ['object', 'page'=>'object'], +'HaruDoc::loadJPEG' => ['object', 'filename'=>'string'], +'HaruDoc::loadPNG' => ['object', 'filename'=>'string', 'deferred='=>'bool'], +'HaruDoc::loadRaw' => ['object', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'color_space'=>'int'], +'HaruDoc::loadTTC' => ['string', 'fontfile'=>'string', 'index'=>'int', 'embed='=>'bool'], +'HaruDoc::loadTTF' => ['string', 'fontfile'=>'string', 'embed='=>'bool'], +'HaruDoc::loadType1' => ['string', 'afmfile'=>'string', 'pfmfile='=>'string'], +'HaruDoc::output' => ['bool'], +'HaruDoc::readFromStream' => ['string', 'bytes'=>'int'], +'HaruDoc::resetError' => ['bool'], +'HaruDoc::resetStream' => ['bool'], +'HaruDoc::save' => ['bool', 'file'=>'string'], +'HaruDoc::saveToStream' => ['bool'], +'HaruDoc::setCompressionMode' => ['bool', 'mode'=>'int'], +'HaruDoc::setCurrentEncoder' => ['bool', 'encoding'=>'string'], +'HaruDoc::setEncryptionMode' => ['bool', 'mode'=>'int', 'key_len='=>'int'], +'HaruDoc::setInfoAttr' => ['bool', 'type'=>'int', 'info'=>'string'], +'HaruDoc::setInfoDateAttr' => ['bool', 'type'=>'int', 'year'=>'int', 'month'=>'int', 'day'=>'int', 'hour'=>'int', 'min'=>'int', 'sec'=>'int', 'ind'=>'string', 'off_hour'=>'int', 'off_min'=>'int'], +'HaruDoc::setOpenAction' => ['bool', 'destination'=>'object'], +'HaruDoc::setPageLayout' => ['bool', 'layout'=>'int'], +'HaruDoc::setPageMode' => ['bool', 'mode'=>'int'], +'HaruDoc::setPagesConfiguration' => ['bool', 'page_per_pages'=>'int'], +'HaruDoc::setPassword' => ['bool', 'owner_password'=>'string', 'user_password'=>'string'], +'HaruDoc::setPermission' => ['bool', 'permission'=>'int'], +'HaruDoc::useCNSEncodings' => ['bool'], +'HaruDoc::useCNSFonts' => ['bool'], +'HaruDoc::useCNTEncodings' => ['bool'], +'HaruDoc::useCNTFonts' => ['bool'], +'HaruDoc::useJPEncodings' => ['bool'], +'HaruDoc::useJPFonts' => ['bool'], +'HaruDoc::useKREncodings' => ['bool'], +'HaruDoc::useKRFonts' => ['bool'], +'HaruEncoder::getByteType' => ['int', 'text'=>'string', 'index'=>'int'], +'HaruEncoder::getType' => ['int'], +'HaruEncoder::getUnicode' => ['int', 'character'=>'int'], +'HaruEncoder::getWritingMode' => ['int'], +'HaruFont::getAscent' => ['int'], +'HaruFont::getCapHeight' => ['int'], +'HaruFont::getDescent' => ['int'], +'HaruFont::getEncodingName' => ['string'], +'HaruFont::getFontName' => ['string'], +'HaruFont::getTextWidth' => ['array', 'text'=>'string'], +'HaruFont::getUnicodeWidth' => ['int', 'character'=>'int'], +'HaruFont::getXHeight' => ['int'], +'HaruFont::measureText' => ['int', 'text'=>'string', 'width'=>'float', 'font_size'=>'float', 'char_space'=>'float', 'word_space'=>'float', 'word_wrap='=>'bool'], +'HaruImage::getBitsPerComponent' => ['int'], +'HaruImage::getColorSpace' => ['string'], +'HaruImage::getHeight' => ['int'], +'HaruImage::getSize' => ['array'], +'HaruImage::getWidth' => ['int'], +'HaruImage::setColorMask' => ['bool', 'rmin'=>'int', 'rmax'=>'int', 'gmin'=>'int', 'gmax'=>'int', 'bmin'=>'int', 'bmax'=>'int'], +'HaruImage::setMaskImage' => ['bool', 'mask_image'=>'object'], +'HaruOutline::setDestination' => ['bool', 'destination'=>'object'], +'HaruOutline::setOpened' => ['bool', 'opened'=>'bool'], +'HaruPage::arc' => ['bool', 'x'=>'float', 'y'=>'float', 'ray'=>'float', 'ang1'=>'float', 'ang2'=>'float'], +'HaruPage::beginText' => ['bool'], +'HaruPage::circle' => ['bool', 'x'=>'float', 'y'=>'float', 'ray'=>'float'], +'HaruPage::closePath' => ['bool'], +'HaruPage::concat' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'], +'HaruPage::createDestination' => ['object'], +'HaruPage::createLinkAnnotation' => ['object', 'rectangle'=>'array', 'destination'=>'object'], +'HaruPage::createTextAnnotation' => ['object', 'rectangle'=>'array', 'text'=>'string', 'encoder='=>'object'], +'HaruPage::createURLAnnotation' => ['object', 'rectangle'=>'array', 'url'=>'string'], +'HaruPage::curveTo' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], +'HaruPage::curveTo2' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], +'HaruPage::curveTo3' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x3'=>'float', 'y3'=>'float'], +'HaruPage::drawImage' => ['bool', 'image'=>'object', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], +'HaruPage::ellipse' => ['bool', 'x'=>'float', 'y'=>'float', 'xray'=>'float', 'yray'=>'float'], +'HaruPage::endPath' => ['bool'], +'HaruPage::endText' => ['bool'], +'HaruPage::eofill' => ['bool'], +'HaruPage::eoFillStroke' => ['bool', 'close_path='=>'bool'], +'HaruPage::fill' => ['bool'], +'HaruPage::fillStroke' => ['bool', 'close_path='=>'bool'], +'HaruPage::getCharSpace' => ['float'], +'HaruPage::getCMYKFill' => ['array'], +'HaruPage::getCMYKStroke' => ['array'], +'HaruPage::getCurrentFont' => ['object'], +'HaruPage::getCurrentFontSize' => ['float'], +'HaruPage::getCurrentPos' => ['array'], +'HaruPage::getCurrentTextPos' => ['array'], +'HaruPage::getDash' => ['array'], +'HaruPage::getFillingColorSpace' => ['int'], +'HaruPage::getFlatness' => ['float'], +'HaruPage::getGMode' => ['int'], +'HaruPage::getGrayFill' => ['float'], +'HaruPage::getGrayStroke' => ['float'], +'HaruPage::getHeight' => ['float'], +'HaruPage::getHorizontalScaling' => ['float'], +'HaruPage::getLineCap' => ['int'], +'HaruPage::getLineJoin' => ['int'], +'HaruPage::getLineWidth' => ['float'], +'HaruPage::getMiterLimit' => ['float'], +'HaruPage::getRGBFill' => ['array'], +'HaruPage::getRGBStroke' => ['array'], +'HaruPage::getStrokingColorSpace' => ['int'], +'HaruPage::getTextLeading' => ['float'], +'HaruPage::getTextMatrix' => ['array'], +'HaruPage::getTextRenderingMode' => ['int'], +'HaruPage::getTextRise' => ['float'], +'HaruPage::getTextWidth' => ['float', 'text'=>'string'], +'HaruPage::getTransMatrix' => ['array'], +'HaruPage::getWidth' => ['float'], +'HaruPage::getWordSpace' => ['float'], +'HaruPage::lineTo' => ['bool', 'x'=>'float', 'y'=>'float'], +'HaruPage::measureText' => ['int', 'text'=>'string', 'width'=>'float', 'wordwrap='=>'bool'], +'HaruPage::moveTextPos' => ['bool', 'x'=>'float', 'y'=>'float', 'set_leading='=>'bool'], +'HaruPage::moveTo' => ['bool', 'x'=>'float', 'y'=>'float'], +'HaruPage::moveToNextLine' => ['bool'], +'HaruPage::rectangle' => ['bool', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], +'HaruPage::setCharSpace' => ['bool', 'char_space'=>'float'], +'HaruPage::setCMYKFill' => ['bool', 'c'=>'float', 'm'=>'float', 'y'=>'float', 'k'=>'float'], +'HaruPage::setCMYKStroke' => ['bool', 'c'=>'float', 'm'=>'float', 'y'=>'float', 'k'=>'float'], +'HaruPage::setDash' => ['bool', 'pattern'=>'array', 'phase'=>'int'], +'HaruPage::setFlatness' => ['bool', 'flatness'=>'float'], +'HaruPage::setFontAndSize' => ['bool', 'font'=>'object', 'size'=>'float'], +'HaruPage::setGrayFill' => ['bool', 'value'=>'float'], +'HaruPage::setGrayStroke' => ['bool', 'value'=>'float'], +'HaruPage::setHeight' => ['bool', 'height'=>'float'], +'HaruPage::setHorizontalScaling' => ['bool', 'scaling'=>'float'], +'HaruPage::setLineCap' => ['bool', 'cap'=>'int'], +'HaruPage::setLineJoin' => ['bool', 'join'=>'int'], +'HaruPage::setLineWidth' => ['bool', 'width'=>'float'], +'HaruPage::setMiterLimit' => ['bool', 'limit'=>'float'], +'HaruPage::setRGBFill' => ['bool', 'r'=>'float', 'g'=>'float', 'b'=>'float'], +'HaruPage::setRGBStroke' => ['bool', 'r'=>'float', 'g'=>'float', 'b'=>'float'], +'HaruPage::setRotate' => ['bool', 'angle'=>'int'], +'HaruPage::setSize' => ['bool', 'size'=>'int', 'direction'=>'int'], +'HaruPage::setSlideShow' => ['bool', 'type'=>'int', 'disp_time'=>'float', 'trans_time'=>'float'], +'HaruPage::setTextLeading' => ['bool', 'text_leading'=>'float'], +'HaruPage::setTextMatrix' => ['bool', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'], +'HaruPage::setTextRenderingMode' => ['bool', 'mode'=>'int'], +'HaruPage::setTextRise' => ['bool', 'rise'=>'float'], +'HaruPage::setWidth' => ['bool', 'width'=>'float'], +'HaruPage::setWordSpace' => ['bool', 'word_space'=>'float'], +'HaruPage::showText' => ['bool', 'text'=>'string'], +'HaruPage::showTextNextLine' => ['bool', 'text'=>'string', 'word_space='=>'float', 'char_space='=>'float'], +'HaruPage::stroke' => ['bool', 'close_path='=>'bool'], +'HaruPage::textOut' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'], +'HaruPage::textRect' => ['bool', 'left'=>'float', 'top'=>'float', 'right'=>'float', 'bottom'=>'float', 'text'=>'string', 'align='=>'int'], +'hash' => ['string', 'algo'=>'string', 'data'=>'string', 'raw_output='=>'bool'], +'hash_algos' => ['array'], +'hash_copy' => ['HashContext', 'context'=>'HashContext'], +'hash_equals' => ['bool', 'known_string'=>'string', 'user_string'=>'string'], +'hash_file' => ['string', 'algo'=>'string', 'filename'=>'string', 'raw_output='=>'bool'], +'hash_final' => ['string', 'context'=>'HashContext', 'raw_output='=>'bool'], +'hash_hkdf' => ['string', 'algo'=>'string', 'ikm'=>'string', 'length='=>'int', 'info='=>'string', 'salt='=>'string'], +'hash_hmac' => ['string', 'algo'=>'string', 'data'=>'string', 'key'=>'string', 'raw_output='=>'bool'], +'hash_hmac_algos' => ['array'], +'hash_hmac_file' => ['string', 'algo'=>'string', 'filename'=>'string', 'key'=>'string', 'raw_output='=>'bool'], +'hash_init' => ['HashContext', 'algo'=>'string', 'options='=>'int', 'key='=>'string'], +'hash_pbkdf2' => ['string', 'algo'=>'string', 'password'=>'string', 'salt'=>'string', 'iterations'=>'int', 'length='=>'int', 'raw_output='=>'bool'], +'hash_update' => ['bool', 'context'=>'HashContext', 'data'=>'string'], +'hash_update_file' => ['bool', 'context='=>'HashContext', 'filename'=>'string', 'scontext='=>'?HashContext'], +'hash_update_stream' => ['int', 'context'=>'HashContext', 'handle'=>'resource', 'length='=>'int'], +'hashTableObj::clear' => ['void'], +'hashTableObj::get' => ['string', 'key'=>'string'], +'hashTableObj::nextkey' => ['string', 'previousKey'=>'string'], +'hashTableObj::remove' => ['int', 'key'=>'string'], +'hashTableObj::set' => ['int', 'key'=>'string', 'value'=>'string'], +'header' => ['void', 'header'=>'string', 'replace='=>'bool', 'http_response_code='=>'int'], +'header_register_callback' => ['bool', 'callback'=>'callable'], +'header_remove' => ['void', 'name='=>'string'], +'headers_list' => ['array'], +'headers_sent' => ['bool', '&w_file='=>'string', '&w_line='=>'int'], +'hebrev' => ['string', 'str'=>'string', 'max_chars_per_line='=>'int'], +'hebrevc' => ['string', 'str'=>'string', 'max_chars_per_line='=>'int'], +'hex2bin' => ['string|false', 'data'=>'string'], +'hexdec' => ['int|float', 'hexadecimal_number'=>'string'], +'highlight_file' => ['string|bool', 'file_name'=>'string', 'return='=>'bool'], +'highlight_string' => ['string|bool', 'string'=>'string', 'return='=>'bool'], +'hrtime' => ['array|integer|float', 'get_as_number'=>'bool'], +'HRTime\PerformanceCounter::getElapsedTicks' => ['int'], +'HRTime\PerformanceCounter::getFrequency' => ['int'], +'HRTime\PerformanceCounter::getLastElapsedTicks' => ['int'], +'HRTime\PerformanceCounter::getTicks' => ['int'], +'HRTime\PerformanceCounter::getTicksSince' => ['int', 'start'=>'int'], +'HRTime\PerformanceCounter::isRunning' => ['bool'], +'HRTime\PerformanceCounter::start' => ['void'], +'HRTime\PerformanceCounter::stop' => ['void'], +'HRTime\StopWatch::getElapsedTicks' => ['int'], +'HRTime\StopWatch::getElapsedTime' => ['float', 'unit='=>'int'], +'HRTime\StopWatch::getLastElapsedTicks' => ['int'], +'HRTime\StopWatch::getLastElapsedTime' => ['float', 'unit='=>'int'], +'HRTime\StopWatch::isRunning' => ['bool'], +'HRTime\StopWatch::start' => ['void'], +'HRTime\StopWatch::stop' => ['void'], +'html_entity_decode' => ['string', 'string'=>'string', 'quote_style='=>'int', 'encoding='=>'string'], +'htmlentities' => ['string', 'string'=>'string', 'quote_style='=>'int', 'encoding='=>'string', 'double_encode='=>'bool'], +'htmlspecialchars' => ['string', 'string'=>'string', 'quote_style='=>'int', 'encoding='=>'string', 'double_encode='=>'bool'], +'htmlspecialchars_decode' => ['string', 'string'=>'string', 'quote_style='=>'int'], +'http\Env\Request::__construct' => ['void'], +'http\Env\Request::getCookie' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\Env\Request::getFiles' => ['array'], +'http\Env\Request::getForm' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\Env\Request::getQuery' => ['mixed', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\Env\Response::__construct' => ['void'], +'http\Env\Response::__invoke' => ['bool', 'data'=>'string', 'ob_flags='=>'int'], +'http\Env\Response::isCachedByETag' => ['int', 'header_name='=>'string'], +'http\Env\Response::isCachedByLastModified' => ['int', 'header_name='=>'string'], +'http\Env\Response::send' => ['bool', 'stream='=>'resource'], +'http\Env\Response::setCacheControl' => ['http\Env\Response', 'cache_control'=>'string'], +'http\Env\Response::setContentDisposition' => ['http\Env\Response', 'disposition_params'=>'array'], +'http\Env\Response::setContentEncoding' => ['http\Env\Response', 'content_encoding'=>'int'], +'http\Env\Response::setContentType' => ['http\Env\Response', 'content_type'=>'string'], +'http\Env\Response::setCookie' => ['http\Env\Response', 'cookie'=>'mixed'], +'http\Env\Response::setEnvRequest' => ['http\Env\Response', 'env_request'=>'http\Message'], +'http\Env\Response::setEtag' => ['http\Env\Response', 'etag'=>'string'], +'http\Env\Response::setLastModified' => ['http\Env\Response', 'last_modified'=>'int'], +'http\Env\Response::setThrottleRate' => ['http\Env\Response', 'chunk_size'=>'int', 'delay='=>'float|int'], +'http\QueryString::__construct' => ['void', 'querystring'=>'string'], +'http\QueryString::__toString' => ['string'], +'http\QueryString::get' => ['', 'name='=>'string', 'type='=>'mixed', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\QueryString::getArray' => ['array', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\QueryString::getBool' => ['bool', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\QueryString::getFloat' => ['float', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\QueryString::getGlobalInstance' => ['http\QueryString'], +'http\QueryString::getInt' => ['int', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\QueryString::getIterator' => ['IteratorAggregate'], +'http\QueryString::getObject' => ['', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\QueryString::getString' => ['string', 'name'=>'string', 'defval='=>'mixed', 'delete='=>'bool|false'], +'http\QueryString::mod' => ['http\QueryString', 'params='=>'mixed'], +'http\QueryString::offsetExists' => ['bool', 'offset'=>'mixed'], +'http\QueryString::offsetGet' => ['mixed', 'offset'=>'mixed'], +'http\QueryString::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], +'http\QueryString::offsetUnset' => ['void', 'offset'=>'mixed'], +'http\QueryString::serialize' => ['string'], +'http\QueryString::set' => ['http\QueryString', 'params'=>'mixed'], +'http\QueryString::toArray' => ['mixed[]'], +'http\QueryString::toString' => ['string'], +'http\QueryString::unserialize' => ['void', 'serialized'=>''], +'http\QueryString::xlate' => ['http\QueryString'], +'http\Url::__construct' => ['void', 'old_url='=>'mixed', 'new_url='=>'mixed', 'flags='=>'int'], +'http\Url::__toString' => [''], +'http\Url::mod' => ['http\Url', 'parts'=>'mixed', 'flags='=>'float|int|mixed'], +'http\Url::toArray' => ['string[]'], +'http\Url::toString' => ['string'], +'http_build_cookie' => ['string', 'cookie'=>'array'], +'http_build_query' => ['string', 'querydata'=>'array|object', 'prefix='=>'string', 'arg_separator='=>'string', 'enc_type='=>'int'], +'http_build_str' => ['string', 'query'=>'array', 'prefix='=>'?string', 'arg_separator='=>'string'], +'http_build_url' => ['string', 'url='=>'string|array', 'parts='=>'string|array', 'flags='=>'int', 'new_url='=>'array'], +'http_cache_etag' => ['bool', 'etag='=>'string'], +'http_cache_last_modified' => ['bool', 'timestamp_or_expires='=>'int'], +'http_chunked_decode' => ['string', 'encoded'=>'string'], +'http_date' => ['string', 'timestamp='=>'int'], +'http_deflate' => ['string', 'data'=>'string', 'flags='=>'int'], +'http_get' => ['string', 'url'=>'string', 'options='=>'array', 'info='=>'array'], +'http_get_request_body' => ['string'], +'http_get_request_body_stream' => ['resource'], +'http_get_request_headers' => ['array'], +'http_head' => ['string', 'url'=>'string', 'options='=>'array', 'info='=>'array'], +'http_inflate' => ['string', 'data'=>'string'], +'http_match_etag' => ['bool', 'etag'=>'string', 'for_range='=>'bool'], +'http_match_modified' => ['bool', 'timestamp='=>'int', 'for_range='=>'bool'], +'http_match_request_header' => ['bool', 'header'=>'string', 'value'=>'string', 'match_case='=>'bool'], +'http_negotiate_charset' => ['string', 'supported'=>'array', 'result='=>'array'], +'http_negotiate_content_type' => ['string', 'supported'=>'array', 'result='=>'array'], +'http_negotiate_language' => ['string', 'supported'=>'array', 'result='=>'array'], +'http_parse_cookie' => ['object', 'cookie'=>'string', 'flags='=>'int', 'allowed_extras='=>'array'], +'http_parse_headers' => ['array', 'header'=>'string'], +'http_parse_message' => ['object', 'message'=>'string'], +'http_parse_params' => ['object', 'param'=>'string', 'flags='=>'int'], +'http_persistent_handles_clean' => ['string', 'ident='=>'string'], +'http_persistent_handles_count' => ['object'], +'http_persistent_handles_ident' => ['string', 'ident='=>'string'], +'http_post_data' => ['string', 'url'=>'string', 'data'=>'string', 'options='=>'array', 'info='=>'array'], +'http_post_fields' => ['string', 'url'=>'string', 'data'=>'array', 'files='=>'array', 'options='=>'array', 'info='=>'array'], +'http_put_data' => ['string', 'url'=>'string', 'data'=>'string', 'options='=>'array', 'info='=>'array'], +'http_put_file' => ['string', 'url'=>'string', 'file'=>'string', 'options='=>'array', 'info='=>'array'], +'http_put_stream' => ['string', 'url'=>'string', 'stream'=>'', 'options='=>'array', 'info='=>'array'], +'http_redirect' => ['bool', 'url='=>'string', 'params='=>'array', 'session='=>'bool', 'status='=>'int'], +'http_request' => ['string', 'method'=>'int', 'url'=>'string', 'body='=>'string', 'options='=>'array', 'info='=>'array'], +'http_request_body_encode' => ['string', 'fields'=>'array', 'files'=>'array'], +'http_request_method_exists' => ['int', 'method'=>''], +'http_request_method_name' => ['string', 'method'=>'int'], +'http_request_method_register' => ['int', 'method'=>'string'], +'http_request_method_unregister' => ['bool', 'method'=>''], +'http_response_code' => ['int|bool', 'response_code='=>'int'], +'http_send_content_disposition' => ['bool', 'filename'=>'string', 'inline='=>'bool'], +'http_send_content_type' => ['bool', 'content_type='=>'string'], +'http_send_data' => ['bool', 'data'=>'string'], +'http_send_file' => ['bool', 'file'=>'string'], +'http_send_last_modified' => ['bool', 'timestamp='=>'int'], +'http_send_status' => ['bool', 'status'=>'int'], +'http_send_stream' => ['bool', 'stream'=>''], +'http_support' => ['int', 'feature='=>'int'], +'http_throttle' => ['', 'sec'=>'float', 'bytes='=>'int'], +'HttpDeflateStream::__construct' => ['void', 'flags='=>'int'], +'HttpDeflateStream::factory' => ['HttpDeflateStream', 'flags='=>'int', 'class_name='=>'string'], +'HttpDeflateStream::finish' => ['string', 'data='=>'string'], +'HttpDeflateStream::flush' => ['string', 'data='=>'string'], +'HttpDeflateStream::update' => ['string', 'data'=>'string'], +'HttpInflateStream::__construct' => ['void', 'flags='=>'int'], +'HttpInflateStream::factory' => ['HttpInflateStream', 'flags='=>'int', 'class_name='=>'string'], +'HttpInflateStream::finish' => ['string', 'data='=>'string'], +'HttpInflateStream::flush' => ['string', 'data='=>'string'], +'HttpInflateStream::update' => ['string', 'data'=>'string'], +'HttpMessage::__construct' => ['void', 'message='=>'string'], +'HttpMessage::__toString' => ['string'], +'HttpMessage::addHeaders' => ['', 'headers'=>'array', 'append='=>'bool'], +'HttpMessage::count' => ['int'], +'HttpMessage::current' => ['mixed'], +'HttpMessage::detach' => ['HttpMessage'], +'HttpMessage::factory' => ['HttpMessage', 'raw_message='=>'string', 'class_name='=>'string'], +'HttpMessage::fromEnv' => ['HttpMessage', 'message_type'=>'int', 'class_name='=>'string'], +'HttpMessage::fromString' => ['HttpMessage', 'raw_message='=>'string', 'class_name='=>'string'], +'HttpMessage::getBody' => ['string'], +'HttpMessage::getHeader' => ['string', 'header'=>'string'], +'HttpMessage::getHeaders' => ['array'], +'HttpMessage::getHttpVersion' => ['string'], +'HttpMessage::getInfo' => [''], +'HttpMessage::getParentMessage' => ['HttpMessage'], +'HttpMessage::getRequestMethod' => ['string'], +'HttpMessage::getRequestUrl' => ['string'], +'HttpMessage::getResponseCode' => ['int'], +'HttpMessage::getResponseStatus' => ['string'], +'HttpMessage::getType' => ['int'], +'HttpMessage::guessContentType' => ['string', 'magic_file'=>'string', 'magic_mode='=>'int'], +'HttpMessage::key' => ['int|string'], +'HttpMessage::next' => ['void'], +'HttpMessage::prepend' => ['', 'message'=>'httpmessage', 'top='=>'bool'], +'HttpMessage::reverse' => ['HttpMessage'], +'HttpMessage::rewind' => ['void'], +'HttpMessage::send' => ['bool'], +'HttpMessage::serialize' => ['string'], +'HttpMessage::setBody' => ['', 'body'=>'string'], +'HttpMessage::setHeaders' => ['', 'headers'=>'array'], +'HttpMessage::setHttpVersion' => ['bool', 'version'=>'string'], +'HttpMessage::setInfo' => ['', 'http_info'=>''], +'HttpMessage::setRequestMethod' => ['bool', 'method'=>'string'], +'HttpMessage::setRequestUrl' => ['bool', 'url'=>'string'], +'HttpMessage::setResponseCode' => ['bool', 'code'=>'int'], +'HttpMessage::setResponseStatus' => ['bool', 'status'=>'string'], +'HttpMessage::setType' => ['', 'type'=>'int'], +'HttpMessage::toMessageTypeObject' => ['HttpRequest|HttpResponse'], +'HttpMessage::toString' => ['string', 'include_parent='=>'bool'], +'HttpMessage::unserialize' => ['void', 'serialized'=>''], +'HttpMessage::valid' => ['bool'], +'HttpQueryString::__construct' => ['void', 'global='=>'bool', 'add='=>''], +'HttpQueryString::__toString' => ['string'], +'HttpQueryString::factory' => ['', 'global'=>'', 'params'=>'', 'class_name'=>''], +'HttpQueryString::get' => ['', 'key='=>'string', 'type='=>'', 'defval='=>'', 'delete='=>'bool'], +'HttpQueryString::getArray' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], +'HttpQueryString::getBool' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], +'HttpQueryString::getFloat' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], +'HttpQueryString::getInt' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], +'HttpQueryString::getObject' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], +'HttpQueryString::getString' => ['', 'name'=>'', 'defval'=>'', 'delete'=>''], +'HttpQueryString::mod' => ['HttpQueryString', 'params'=>''], +'HttpQueryString::offsetExists' => ['bool', 'offset'=>'mixed'], +'HttpQueryString::offsetGet' => ['mixed', 'offset'=>'mixed'], +'HttpQueryString::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], +'HttpQueryString::offsetUnset' => ['void', 'offset'=>'mixed'], +'HttpQueryString::serialize' => ['string'], +'HttpQueryString::set' => ['string', 'params'=>''], +'HttpQueryString::singleton' => ['HttpQueryString', 'global='=>'bool'], +'HttpQueryString::toArray' => ['array'], +'HttpQueryString::toString' => ['string'], +'HttpQueryString::unserialize' => ['void', 'serialized'=>'string'], +'HttpQueryString::xlate' => ['bool', 'ie'=>'string', 'oe'=>'string'], +'HttpRequest::__construct' => ['void', 'url='=>'string', 'request_method='=>'int', 'options='=>'array'], +'HttpRequest::addBody' => ['', 'request_body_data'=>''], +'HttpRequest::addCookies' => ['bool', 'cookies'=>'array'], +'HttpRequest::addHeaders' => ['bool', 'headers'=>'array'], +'HttpRequest::addPostFields' => ['bool', 'post_data'=>'array'], +'HttpRequest::addPostFile' => ['bool', 'name'=>'string', 'file'=>'string', 'content_type='=>'string'], +'HttpRequest::addPutData' => ['bool', 'put_data'=>'string'], +'HttpRequest::addQueryData' => ['bool', 'query_params'=>'array'], +'HttpRequest::addRawPostData' => ['bool', 'raw_post_data'=>'string'], +'HttpRequest::addSslOptions' => ['bool', 'options'=>'array'], +'HttpRequest::clearHistory' => [''], +'HttpRequest::enableCookies' => ['bool'], +'HttpRequest::encodeBody' => ['', 'fields'=>'', 'files'=>''], +'HttpRequest::factory' => ['', 'url'=>'', 'method'=>'', 'options'=>'', 'class_name'=>''], +'HttpRequest::flushCookies' => [''], +'HttpRequest::get' => ['', 'url'=>'', 'options'=>'', '&info'=>''], +'HttpRequest::getBody' => [''], +'HttpRequest::getContentType' => ['string'], +'HttpRequest::getCookies' => ['array'], +'HttpRequest::getHeaders' => ['array'], +'HttpRequest::getHistory' => ['HttpMessage'], +'HttpRequest::getMethod' => ['int'], +'HttpRequest::getOptions' => ['array'], +'HttpRequest::getPostFields' => ['array'], +'HttpRequest::getPostFiles' => ['array'], +'HttpRequest::getPutData' => ['string'], +'HttpRequest::getPutFile' => ['string'], +'HttpRequest::getQueryData' => ['string'], +'HttpRequest::getRawPostData' => ['string'], +'HttpRequest::getRawRequestMessage' => ['string'], +'HttpRequest::getRawResponseMessage' => ['string'], +'HttpRequest::getRequestMessage' => ['HttpMessage'], +'HttpRequest::getResponseBody' => ['string'], +'HttpRequest::getResponseCode' => ['int'], +'HttpRequest::getResponseCookies' => ['array', 'flags='=>'int', 'allowed_extras='=>'array'], +'HttpRequest::getResponseData' => ['array'], +'HttpRequest::getResponseHeader' => ['', 'name='=>'string'], +'HttpRequest::getResponseInfo' => ['', 'name='=>'string'], +'HttpRequest::getResponseMessage' => ['HttpMessage'], +'HttpRequest::getResponseStatus' => ['string'], +'HttpRequest::getSslOptions' => ['array'], +'HttpRequest::getUrl' => ['string'], +'HttpRequest::head' => ['', 'url'=>'', 'options'=>'', '&info'=>''], +'HttpRequest::methodExists' => ['', 'method'=>''], +'HttpRequest::methodName' => ['', 'method_id'=>''], +'HttpRequest::methodRegister' => ['', 'method_name'=>''], +'HttpRequest::methodUnregister' => ['', 'method'=>''], +'HttpRequest::postData' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''], +'HttpRequest::postFields' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''], +'HttpRequest::putData' => ['', 'url'=>'', 'data'=>'', 'options'=>'', '&info'=>''], +'HttpRequest::putFile' => ['', 'url'=>'', 'file'=>'', 'options'=>'', '&info'=>''], +'HttpRequest::putStream' => ['', 'url'=>'', 'stream'=>'', 'options'=>'', '&info'=>''], +'HttpRequest::resetCookies' => ['bool', 'session_only='=>'bool'], +'HttpRequest::send' => ['HttpMessage'], +'HttpRequest::setBody' => ['bool', 'request_body_data='=>'string'], +'HttpRequest::setContentType' => ['bool', 'content_type'=>'string'], +'HttpRequest::setCookies' => ['bool', 'cookies='=>'array'], +'HttpRequest::setHeaders' => ['bool', 'headers='=>'array'], +'HttpRequest::setMethod' => ['bool', 'request_method'=>'int'], +'HttpRequest::setOptions' => ['bool', 'options='=>'array'], +'HttpRequest::setPostFields' => ['bool', 'post_data'=>'array'], +'HttpRequest::setPostFiles' => ['bool', 'post_files'=>'array'], +'HttpRequest::setPutData' => ['bool', 'put_data='=>'string'], +'HttpRequest::setPutFile' => ['bool', 'file='=>'string'], +'HttpRequest::setQueryData' => ['bool', 'query_data'=>''], +'HttpRequest::setRawPostData' => ['bool', 'raw_post_data='=>'string'], +'HttpRequest::setSslOptions' => ['bool', 'options='=>'array'], +'HttpRequest::setUrl' => ['bool', 'url'=>'string'], +'HttpRequestDataShare::__construct' => ['void'], +'HttpRequestDataShare::__destruct' => [''], +'HttpRequestDataShare::attach' => ['', 'request'=>'HttpRequest'], +'HttpRequestDataShare::count' => ['int'], +'HttpRequestDataShare::detach' => ['', 'request'=>'HttpRequest'], +'HttpRequestDataShare::factory' => ['', 'global'=>'', 'class_name'=>''], +'HttpRequestDataShare::reset' => [''], +'HttpRequestDataShare::singleton' => ['', 'global'=>''], +'HttpRequestPool::__construct' => ['void', 'request='=>'httprequest'], +'HttpRequestPool::__destruct' => [''], +'HttpRequestPool::attach' => ['bool', 'request'=>'httprequest'], +'HttpRequestPool::count' => ['int'], +'HttpRequestPool::current' => ['mixed'], +'HttpRequestPool::detach' => ['bool', 'request'=>'httprequest'], +'HttpRequestPool::enableEvents' => ['', 'enable'=>''], +'HttpRequestPool::enablePipelining' => ['', 'enable'=>''], +'HttpRequestPool::getAttachedRequests' => ['array'], +'HttpRequestPool::getFinishedRequests' => ['array'], +'HttpRequestPool::key' => ['int|string'], +'HttpRequestPool::next' => ['void'], +'HttpRequestPool::reset' => [''], +'HttpRequestPool::rewind' => ['void'], +'HttpRequestPool::send' => ['bool'], +'HttpRequestPool::socketPerform' => ['bool'], +'HttpRequestPool::socketSelect' => ['bool', 'timeout='=>'float'], +'HttpRequestPool::valid' => ['bool'], +'HttpResponse::capture' => [''], +'HttpResponse::getBufferSize' => ['int'], +'HttpResponse::getCache' => ['bool'], +'HttpResponse::getCacheControl' => ['string'], +'HttpResponse::getContentDisposition' => ['string'], +'HttpResponse::getContentType' => ['string'], +'HttpResponse::getData' => ['string'], +'HttpResponse::getETag' => ['string'], +'HttpResponse::getFile' => ['string'], +'HttpResponse::getGzip' => ['bool'], +'HttpResponse::getHeader' => ['', 'name='=>'string'], +'HttpResponse::getLastModified' => ['int'], +'HttpResponse::getRequestBody' => ['string'], +'HttpResponse::getRequestBodyStream' => ['resource'], +'HttpResponse::getRequestHeaders' => ['array'], +'HttpResponse::getStream' => ['resource'], +'HttpResponse::getThrottleDelay' => ['float'], +'HttpResponse::guessContentType' => ['string', 'magic_file'=>'string', 'magic_mode='=>'int'], +'HttpResponse::redirect' => ['', 'url='=>'string', 'params='=>'array', 'session='=>'bool', 'status='=>'int'], +'HttpResponse::send' => ['bool', 'clean_ob='=>'bool'], +'HttpResponse::setBufferSize' => ['bool', 'bytes'=>'int'], +'HttpResponse::setCache' => ['bool', 'cache'=>'bool'], +'HttpResponse::setCacheControl' => ['bool', 'control'=>'string', 'max_age='=>'int', 'must_revalidate='=>'bool'], +'HttpResponse::setContentDisposition' => ['bool', 'filename'=>'string', 'inline='=>'bool'], +'HttpResponse::setContentType' => ['bool', 'content_type'=>'string'], +'HttpResponse::setData' => ['bool', 'data'=>''], +'HttpResponse::setETag' => ['bool', 'etag'=>'string'], +'HttpResponse::setFile' => ['bool', 'file'=>'string'], +'HttpResponse::setGzip' => ['bool', 'gzip'=>'bool'], +'HttpResponse::setHeader' => ['bool', 'name'=>'string', 'value='=>'', 'replace='=>'bool'], +'HttpResponse::setLastModified' => ['bool', 'timestamp'=>'int'], +'HttpResponse::setStream' => ['bool', 'stream'=>''], +'HttpResponse::setThrottleDelay' => ['bool', 'seconds'=>'float'], +'HttpResponse::status' => ['bool', 'status'=>'int'], +'HttpUtil::buildCookie' => ['', 'cookie_array'=>''], +'HttpUtil::buildStr' => ['', 'query'=>'', 'prefix'=>'', 'arg_sep'=>''], +'HttpUtil::buildUrl' => ['', 'url'=>'', 'parts'=>'', 'flags'=>'', '&composed'=>''], +'HttpUtil::chunkedDecode' => ['', 'encoded_string'=>''], +'HttpUtil::date' => ['', 'timestamp'=>''], +'HttpUtil::deflate' => ['', 'plain'=>'', 'flags'=>''], +'HttpUtil::inflate' => ['', 'encoded'=>''], +'HttpUtil::matchEtag' => ['', 'plain_etag'=>'', 'for_range'=>''], +'HttpUtil::matchModified' => ['', 'last_modified'=>'', 'for_range'=>''], +'HttpUtil::matchRequestHeader' => ['', 'header_name'=>'', 'header_value'=>'', 'case_sensitive'=>''], +'HttpUtil::negotiateCharset' => ['', 'supported'=>'', '&result'=>''], +'HttpUtil::negotiateContentType' => ['', 'supported'=>'', '&result'=>''], +'HttpUtil::negotiateLanguage' => ['', 'supported'=>'', '&result'=>''], +'HttpUtil::parseCookie' => ['', 'cookie_string'=>''], +'HttpUtil::parseHeaders' => ['', 'headers_string'=>''], +'HttpUtil::parseMessage' => ['', 'message_string'=>''], +'HttpUtil::parseParams' => ['', 'param_string'=>'', 'flags'=>''], +'HttpUtil::support' => ['', 'feature'=>''], +'hw_api::checkin' => ['bool', 'parameter'=>'array'], +'hw_api::checkout' => ['bool', 'parameter'=>'array'], +'hw_api::children' => ['array', 'parameter'=>'array'], +'hw_api::content' => ['HW_API_Content', 'parameter'=>'array'], +'hw_api::copy' => ['hw_api_content', 'parameter'=>'array'], +'hw_api::dbstat' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::dcstat' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::dstanchors' => ['array', 'parameter'=>'array'], +'hw_api::dstofsrcanchor' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::find' => ['array', 'parameter'=>'array'], +'hw_api::ftstat' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::hwstat' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::identify' => ['bool', 'parameter'=>'array'], +'hw_api::info' => ['array', 'parameter'=>'array'], +'hw_api::insert' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::insertanchor' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::insertcollection' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::insertdocument' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::link' => ['bool', 'parameter'=>'array'], +'hw_api::lock' => ['bool', 'parameter'=>'array'], +'hw_api::move' => ['bool', 'parameter'=>'array'], +'hw_api::object' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::objectbyanchor' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::parents' => ['array', 'parameter'=>'array'], +'hw_api::remove' => ['bool', 'parameter'=>'array'], +'hw_api::replace' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::setcommittedversion' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::srcanchors' => ['array', 'parameter'=>'array'], +'hw_api::srcsofdst' => ['array', 'parameter'=>'array'], +'hw_api::unlock' => ['bool', 'parameter'=>'array'], +'hw_api::user' => ['hw_api_object', 'parameter'=>'array'], +'hw_api::userlist' => ['array', 'parameter'=>'array'], +'hw_api_attribute' => ['HW_API_Attribute', 'name='=>'string', 'value='=>'string'], +'hw_api_attribute::key' => ['string'], +'hw_api_attribute::langdepvalue' => ['string', 'language'=>'string'], +'hw_api_attribute::value' => ['string'], +'hw_api_attribute::values' => ['array'], +'hw_api_content' => ['HW_API_Content', 'content'=>'string', 'mimetype'=>'string'], +'hw_api_content::mimetype' => ['string'], +'hw_api_content::read' => ['string', 'buffer'=>'string', 'len'=>'int'], +'hw_api_error::count' => ['int'], +'hw_api_error::reason' => ['HW_API_Reason'], +'hw_api_object' => ['hw_api_object', 'parameter'=>'array'], +'hw_api_object::assign' => ['bool', 'parameter'=>'array'], +'hw_api_object::attreditable' => ['bool', 'parameter'=>'array'], +'hw_api_object::count' => ['int', 'parameter'=>'array'], +'hw_api_object::insert' => ['bool', 'attribute'=>'hw_api_attribute'], +'hw_api_object::remove' => ['bool', 'name'=>'string'], +'hw_api_object::title' => ['string', 'parameter'=>'array'], +'hw_api_object::value' => ['string', 'name'=>'string'], +'hw_api_reason::description' => ['string'], +'hw_api_reason::type' => ['HW_API_Reason'], +'hw_Array2Objrec' => ['string', 'object_array'=>'array'], +'hw_changeobject' => ['bool', 'link'=>'int', 'objid'=>'int', 'attributes'=>'array'], +'hw_Children' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_ChildrenObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_Close' => ['bool', 'connection'=>'int'], +'hw_Connect' => ['int', 'host'=>'string', 'port'=>'int', 'username='=>'string', 'password='=>'string'], +'hw_connection_info' => ['', 'link'=>'int'], +'hw_cp' => ['int', 'connection'=>'int', 'object_id_array'=>'array', 'destination_id'=>'int'], +'hw_Deleteobject' => ['bool', 'connection'=>'int', 'object_to_delete'=>'int'], +'hw_DocByAnchor' => ['int', 'connection'=>'int', 'anchorid'=>'int'], +'hw_DocByAnchorObj' => ['string', 'connection'=>'int', 'anchorid'=>'int'], +'hw_Document_Attributes' => ['string', 'hw_document'=>'int'], +'hw_Document_BodyTag' => ['string', 'hw_document'=>'int', 'prefix='=>'string'], +'hw_Document_Content' => ['string', 'hw_document'=>'int'], +'hw_Document_SetContent' => ['bool', 'hw_document'=>'int', 'content'=>'string'], +'hw_Document_Size' => ['int', 'hw_document'=>'int'], +'hw_dummy' => ['string', 'link'=>'int', 'id'=>'int', 'msgid'=>'int'], +'hw_EditText' => ['bool', 'connection'=>'int', 'hw_document'=>'int'], +'hw_Error' => ['int', 'connection'=>'int'], +'hw_ErrorMsg' => ['string', 'connection'=>'int'], +'hw_Free_Document' => ['bool', 'hw_document'=>'int'], +'hw_GetAnchors' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetAnchorsObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetAndLock' => ['string', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetChildColl' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetChildCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetChildDocColl' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetChildDocCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetObject' => ['', 'connection'=>'int', 'objectid'=>'', 'query='=>'string'], +'hw_GetObjectByQuery' => ['array', 'connection'=>'int', 'query'=>'string', 'max_hits'=>'int'], +'hw_GetObjectByQueryColl' => ['array', 'connection'=>'int', 'objectid'=>'int', 'query'=>'string', 'max_hits'=>'int'], +'hw_GetObjectByQueryCollObj' => ['array', 'connection'=>'int', 'objectid'=>'int', 'query'=>'string', 'max_hits'=>'int'], +'hw_GetObjectByQueryObj' => ['array', 'connection'=>'int', 'query'=>'string', 'max_hits'=>'int'], +'hw_GetParents' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetParentsObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_getrellink' => ['string', 'link'=>'int', 'rootid'=>'int', 'sourceid'=>'int', 'destid'=>'int'], +'hw_GetRemote' => ['int', 'connection'=>'int', 'objectid'=>'int'], +'hw_getremotechildren' => ['', 'connection'=>'int', 'object_record'=>'string'], +'hw_GetSrcByDestObj' => ['array', 'connection'=>'int', 'objectid'=>'int'], +'hw_GetText' => ['int', 'connection'=>'int', 'objectid'=>'int', 'prefix='=>''], +'hw_getusername' => ['string', 'connection'=>'int'], +'hw_Identify' => ['string', 'link'=>'int', 'username'=>'string', 'password'=>'string'], +'hw_InCollections' => ['array', 'connection'=>'int', 'object_id_array'=>'array', 'collection_id_array'=>'array', 'return_collections'=>'int'], +'hw_Info' => ['string', 'connection'=>'int'], +'hw_InsColl' => ['int', 'connection'=>'int', 'objectid'=>'int', 'object_array'=>'array'], +'hw_InsDoc' => ['int', 'connection'=>'', 'parentid'=>'int', 'object_record'=>'string', 'text='=>'string'], +'hw_insertanchors' => ['bool', 'hwdoc'=>'int', 'anchorecs'=>'array', 'dest'=>'array', 'urlprefixes='=>'array'], +'hw_InsertDocument' => ['int', 'connection'=>'int', 'parent_id'=>'int', 'hw_document'=>'int'], +'hw_InsertObject' => ['int', 'connection'=>'int', 'object_rec'=>'string', 'parameter'=>'string'], +'hw_mapid' => ['int', 'connection'=>'int', 'server_id'=>'int', 'object_id'=>'int'], +'hw_Modifyobject' => ['bool', 'connection'=>'int', 'object_to_change'=>'int', 'remove'=>'array', 'add'=>'array', 'mode='=>'int'], +'hw_mv' => ['int', 'connection'=>'int', 'object_id_array'=>'array', 'source_id'=>'int', 'destination_id'=>'int'], +'hw_New_Document' => ['int', 'object_record'=>'string', 'document_data'=>'string', 'document_size'=>'int'], +'hw_objrec2array' => ['array', 'object_record'=>'string', 'format='=>'array'], +'hw_Output_Document' => ['bool', 'hw_document'=>'int'], +'hw_pConnect' => ['int', 'host'=>'string', 'port'=>'int', 'username='=>'string', 'password='=>'string'], +'hw_PipeDocument' => ['int', 'connection'=>'int', 'objectid'=>'int', 'url_prefixes='=>'array'], +'hw_Root' => ['int'], +'hw_setlinkroot' => ['int', 'link'=>'int', 'rootid'=>'int'], +'hw_stat' => ['string', 'link'=>'int'], +'hw_Unlock' => ['bool', 'connection'=>'int', 'objectid'=>'int'], +'hw_Who' => ['array', 'connection'=>'int'], +'hwapi_attribute_new' => ['HW_API_Attribute', 'name='=>'string', 'value='=>'string'], +'hwapi_content_new' => ['HW_API_Content', 'content'=>'string', 'mimetype'=>'string'], +'hwapi_hgcsp' => ['HW_API', 'hostname'=>'string', 'port='=>'int'], +'hwapi_object_new' => ['hw_api_object', 'parameter'=>'array'], +'hypot' => ['float', 'num1'=>'float', 'num2'=>'float'], +'ibase_add_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password'=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'], +'ibase_affected_rows' => ['int', 'link_identifier='=>'resource'], +'ibase_backup' => ['mixed', 'service_handle'=>'resource', 'source_db'=>'string', 'dest_file'=>'string', 'options='=>'int', 'verbose='=>'bool'], +'ibase_blob_add' => ['bool', 'blob_handle'=>'resource', 'data'=>'string'], +'ibase_blob_cancel' => ['bool', 'blob_handle'=>'resource'], +'ibase_blob_close' => ['string', 'blob_handle'=>'resource'], +'ibase_blob_create' => ['resource', 'link_identifier='=>'resource'], +'ibase_blob_echo' => ['bool', 'link_identifier'=>'', 'blob_id'=>'string'], +'ibase_blob_echo\'1' => ['bool', 'blob_id'=>'string'], +'ibase_blob_get' => ['string', 'blob_handle'=>'resource', 'len'=>'int'], +'ibase_blob_import' => ['string', 'link_identifier'=>'', 'file_handle'=>''], +'ibase_blob_info' => ['array', 'link_identifier'=>'', 'blob_id'=>'string'], +'ibase_blob_info\'1' => ['array', 'blob_id'=>'string'], +'ibase_blob_open' => ['resource', 'link_identifier'=>'', 'blob_id'=>'string'], +'ibase_blob_open\'1' => ['resource', 'blob_id'=>'string'], +'ibase_close' => ['bool', 'link_identifier='=>'resource'], +'ibase_commit' => ['bool', 'link_identifier='=>'resource'], +'ibase_commit_ret' => ['bool', 'link_identifier='=>'resource'], +'ibase_connect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'buffers='=>'int', 'dialect='=>'int', 'role='=>'string'], +'ibase_db_info' => ['string', 'service_handle'=>'resource', 'db'=>'string', 'action'=>'int', 'argument='=>'int'], +'ibase_delete_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password='=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'], +'ibase_drop_db' => ['bool', 'link_identifier='=>'resource'], +'ibase_errcode' => ['int'], +'ibase_errmsg' => ['string'], +'ibase_execute' => ['resource', 'query'=>'resource', 'bind_arg='=>'mixed', '...args='=>'mixed'], +'ibase_fetch_assoc' => ['array', 'result'=>'resource', 'fetch_flags='=>'int'], +'ibase_fetch_object' => ['object', 'result'=>'resource', 'fetch_flags='=>'int'], +'ibase_fetch_row' => ['array', 'result'=>'resource', 'fetch_flags='=>'int'], +'ibase_field_info' => ['array', 'query_result'=>'resource', 'field_number'=>'int'], +'ibase_free_event_handler' => ['bool', 'event'=>'resource'], +'ibase_free_query' => ['bool', 'query'=>'resource'], +'ibase_free_result' => ['bool', 'result'=>'resource'], +'ibase_gen_id' => ['int', 'generator'=>'string', 'increment='=>'int', 'link_identifier='=>'resource'], +'ibase_maintain_db' => ['bool', 'service_handle'=>'resource', 'db'=>'string', 'action'=>'int', 'argument='=>'int'], +'ibase_modify_user' => ['bool', 'service_handle'=>'resource', 'user_name'=>'string', 'password'=>'string', 'first_name='=>'string', 'middle_name='=>'string', 'last_name='=>'string'], +'ibase_name_result' => ['bool', 'result'=>'resource', 'name'=>'string'], +'ibase_num_fields' => ['int', 'query_result'=>'resource'], +'ibase_num_params' => ['int', 'query'=>'resource'], +'ibase_num_rows' => ['int', 'result_identifier'=>''], +'ibase_param_info' => ['array', 'query'=>'resource', 'field_number'=>'int'], +'ibase_pconnect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'buffers='=>'int', 'dialect='=>'int', 'role='=>'string'], +'ibase_prepare' => ['resource', 'link_identifier'=>'', 'query'=>'string', 'trans_identifier'=>''], +'ibase_query' => ['resource', 'link_identifier='=>'resource', 'string='=>'string', 'bind_arg='=>'int', '...args='=>''], +'ibase_restore' => ['mixed', 'service_handle'=>'resource', 'source_file'=>'string', 'dest_db'=>'string', 'options='=>'int', 'verbose='=>'bool'], +'ibase_rollback' => ['bool', 'link_identifier='=>'resource'], +'ibase_rollback_ret' => ['bool', 'link_identifier='=>'resource'], +'ibase_server_info' => ['string', 'service_handle'=>'resource', 'action'=>'int'], +'ibase_service_attach' => ['resource', 'host'=>'string', 'dba_username'=>'string', 'dba_password'=>'string'], +'ibase_service_detach' => ['bool', 'service_handle'=>'resource'], +'ibase_set_event_handler' => ['resource', 'link_identifier'=>'', 'callback'=>'callable', 'event='=>'string', '...args='=>''], +'ibase_set_event_handler\'1' => ['resource', 'callback'=>'callable', 'event'=>'string', '...args'=>''], +'ibase_timefmt' => ['bool', 'format'=>'string', 'columntype='=>'int'], +'ibase_trans' => ['resource', 'trans_args='=>'int', 'link_identifier='=>'', '...args='=>''], +'ibase_wait_event' => ['string', 'link_identifier'=>'', 'event='=>'string', '...args='=>''], +'ibase_wait_event\'1' => ['string', 'event'=>'string', '...args'=>''], +'iconv' => ['string|false', 'in_charset'=>'string', 'out_charset'=>'string', 'str'=>'string'], +'iconv_get_encoding' => ['mixed', 'type='=>'string'], +'iconv_mime_decode' => ['string|false', 'encoded_string'=>'string', 'mode='=>'int', 'charset='=>'string'], +'iconv_mime_decode_headers' => ['array|false', 'headers'=>'string', 'mode='=>'int', 'charset='=>'string'], +'iconv_mime_encode' => ['string|false', 'field_name'=>'string', 'field_value'=>'string', 'preference='=>'array'], +'iconv_set_encoding' => ['bool', 'type'=>'string', 'charset'=>'string'], +'iconv_strlen' => ['int', 'str'=>'string', 'charset='=>'string'], +'iconv_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'charset='=>'string'], +'iconv_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'charset='=>'string'], +'iconv_substr' => ['string|false', 'str'=>'string', 'offset'=>'int', 'length='=>'int', 'charset='=>'string'], +'id3_get_frame_long_name' => ['string', 'frameid'=>'string'], +'id3_get_frame_short_name' => ['string', 'frameid'=>'string'], +'id3_get_genre_id' => ['int', 'genre'=>'string'], +'id3_get_genre_list' => ['array'], +'id3_get_genre_name' => ['string', 'genre_id'=>'int'], +'id3_get_tag' => ['array', 'filename'=>'string', 'version='=>'int'], +'id3_get_version' => ['int', 'filename'=>'string'], +'id3_remove_tag' => ['bool', 'filename'=>'string', 'version='=>'int'], +'id3_set_tag' => ['bool', 'filename'=>'string', 'tag'=>'array', 'version='=>'int'], +'idate' => ['int', 'format'=>'string', 'timestamp='=>'int'], +'idn_strerror' => ['string', 'errorcode'=>'int'], +'idn_to_ascii' => ['string|false', 'domain'=>'string', 'options='=>'int', 'variant='=>'int', '&w_idna_info='=>'array'], +'idn_to_utf8' => ['string|false', 'domain'=>'string', 'options='=>'int', 'variant='=>'int', '&w_idna_info='=>'array'], +'ifx_affected_rows' => ['int', 'result_id'=>'resource'], +'ifx_blobinfile_mode' => ['bool', 'mode'=>'int'], +'ifx_byteasvarchar' => ['bool', 'mode'=>'int'], +'ifx_close' => ['bool', 'link_identifier='=>'resource'], +'ifx_connect' => ['resource', 'database='=>'string', 'userid='=>'string', 'password='=>'string'], +'ifx_copy_blob' => ['int', 'bid'=>'int'], +'ifx_create_blob' => ['int', 'type'=>'int', 'mode'=>'int', 'param'=>'string'], +'ifx_create_char' => ['int', 'param'=>'string'], +'ifx_do' => ['bool', 'result_id'=>'resource'], +'ifx_error' => ['string', 'link_identifier='=>'resource'], +'ifx_errormsg' => ['string', 'errorcode='=>'int'], +'ifx_fetch_row' => ['array', 'result_id'=>'resource', 'position='=>'mixed'], +'ifx_fieldproperties' => ['array', 'result_id'=>'resource'], +'ifx_fieldtypes' => ['array', 'result_id'=>'resource'], +'ifx_free_blob' => ['bool', 'bid'=>'int'], +'ifx_free_char' => ['bool', 'bid'=>'int'], +'ifx_free_result' => ['bool', 'result_id'=>'resource'], +'ifx_get_blob' => ['string', 'bid'=>'int'], +'ifx_get_char' => ['string', 'bid'=>'int'], +'ifx_getsqlca' => ['array', 'result_id'=>'resource'], +'ifx_htmltbl_result' => ['int', 'result_id'=>'resource', 'html_table_options='=>'string'], +'ifx_nullformat' => ['bool', 'mode'=>'int'], +'ifx_num_fields' => ['int', 'result_id'=>'resource'], +'ifx_num_rows' => ['int', 'result_id'=>'resource'], +'ifx_pconnect' => ['resource', 'database='=>'string', 'userid='=>'string', 'password='=>'string'], +'ifx_prepare' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'cursor_def='=>'int', 'blobidarray='=>'mixed'], +'ifx_query' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'cursor_type='=>'int', 'blobidarray='=>'mixed'], +'ifx_textasvarchar' => ['bool', 'mode'=>'int'], +'ifx_update_blob' => ['bool', 'bid'=>'int', 'content'=>'string'], +'ifx_update_char' => ['bool', 'bid'=>'int', 'content'=>'string'], +'ifxus_close_slob' => ['bool', 'bid'=>'int'], +'ifxus_create_slob' => ['int', 'mode'=>'int'], +'ifxus_free_slob' => ['bool', 'bid'=>'int'], +'ifxus_open_slob' => ['int', 'bid'=>'int', 'mode'=>'int'], +'ifxus_read_slob' => ['string', 'bid'=>'int', 'nbytes'=>'int'], +'ifxus_seek_slob' => ['int', 'bid'=>'int', 'mode'=>'int', 'offset'=>'int'], +'ifxus_tell_slob' => ['int', 'bid'=>'int'], +'ifxus_write_slob' => ['int', 'bid'=>'int', 'content'=>'string'], +'igbinary_serialize' => ['string|false', 'value'=>''], +'igbinary_unserialize' => ['', 'str'=>'string'], +'ignore_user_abort' => ['int', 'value='=>'bool'], +'iis_add_server' => ['int', 'path'=>'string', 'comment'=>'string', 'server_ip'=>'string', 'port'=>'int', 'host_name'=>'string', 'rights'=>'int', 'start_server'=>'int'], +'iis_get_dir_security' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string'], +'iis_get_script_map' => ['string', 'server_instance'=>'int', 'virtual_path'=>'string', 'script_extension'=>'string'], +'iis_get_server_by_comment' => ['int', 'comment'=>'string'], +'iis_get_server_by_path' => ['int', 'path'=>'string'], +'iis_get_server_rights' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string'], +'iis_get_service_state' => ['int', 'service_id'=>'string'], +'iis_remove_server' => ['int', 'server_instance'=>'int'], +'iis_set_app_settings' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'application_scope'=>'string'], +'iis_set_dir_security' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'directory_flags'=>'int'], +'iis_set_script_map' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'script_extension'=>'string', 'engine_path'=>'string', 'allow_scripting'=>'int'], +'iis_set_server_rights' => ['int', 'server_instance'=>'int', 'virtual_path'=>'string', 'directory_flags'=>'int'], +'iis_start_server' => ['int', 'server_instance'=>'int'], +'iis_start_service' => ['int', 'service_id'=>'string'], +'iis_stop_server' => ['int', 'server_instance'=>'int'], +'iis_stop_service' => ['int', 'service_id'=>'string'], +'image2wbmp' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'threshold='=>'int'], +'image_type_to_extension' => ['string', 'imagetype'=>'int', 'include_dot='=>'bool'], +'image_type_to_mime_type' => ['string', 'imagetype'=>'int'], +'imageaffine' => ['resource', 'src'=>'resource', 'affine'=>'array', 'clip='=>'array'], +'imageaffineconcat' => ['array', 'm1'=>'array', 'm2'=>'array'], +'imageaffinematrixconcat' => ['array', 'm1'=>'array', 'm2'=>'array'], +'imageaffinematrixget' => ['array', 'type'=>'int', 'options'=>'array'], +'imagealphablending' => ['bool', 'im'=>'resource', 'on'=>'bool'], +'imageantialias' => ['bool', 'im'=>'resource', 'on'=>'bool'], +'imagearc' => ['bool', 'im'=>'resource', 'cx'=>'int', 'cy'=>'int', 'w'=>'int', 'h'=>'int', 's'=>'int', 'e'=>'int', 'col'=>'int'], +'imagebmp' => ['bool', 'image'=>'resource', 'to='=>'mixed', 'compressed='=>'bool'], +'imagechar' => ['bool', 'im'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'c'=>'string', 'col'=>'int'], +'imagecharup' => ['bool', 'im'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'c'=>'string', 'col'=>'int'], +'imagecolorallocate' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], +'imagecolorallocatealpha' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'], +'imagecolorat' => ['int', 'im'=>'resource', 'x'=>'int', 'y'=>'int'], +'imagecolorclosest' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], +'imagecolorclosestalpha' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'], +'imagecolorclosesthwb' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], +'imagecolordeallocate' => ['bool', 'im'=>'resource', 'index'=>'int'], +'imagecolorexact' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], +'imagecolorexactalpha' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'], +'imagecolormatch' => ['bool', 'im1'=>'resource', 'im2'=>'resource'], +'imagecolorresolve' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], +'imagecolorresolvealpha' => ['int', 'im'=>'resource', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha'=>'int'], +'imagecolorset' => ['void', 'im'=>'resource', 'col'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'], +'imagecolorsforindex' => ['array', 'im'=>'resource', 'col'=>'int'], +'imagecolorstotal' => ['int', 'im'=>'resource'], +'imagecolortransparent' => ['int', 'im'=>'resource', 'col='=>'int'], +'imageconvolution' => ['resource', 'src_im'=>'resource', 'matrix3x3'=>'array', 'div'=>'float', 'offset'=>'float'], +'imagecopy' => ['bool', 'dst_im'=>'resource', 'src_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_w'=>'int', 'src_h'=>'int'], +'imagecopymerge' => ['bool', 'src_im'=>'resource', 'dst_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_w'=>'int', 'src_h'=>'int', 'pct'=>'int'], +'imagecopymergegray' => ['bool', 'src_im'=>'resource', 'dst_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'src_w'=>'int', 'src_h'=>'int', 'pct'=>'int'], +'imagecopyresampled' => ['bool', 'dst_im'=>'resource', 'src_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_w'=>'int', 'dst_h'=>'int', 'src_w'=>'int', 'src_h'=>'int'], +'imagecopyresized' => ['bool', 'dst_im'=>'resource', 'src_im'=>'resource', 'dst_x'=>'int', 'dst_y'=>'int', 'src_x'=>'int', 'src_y'=>'int', 'dst_w'=>'int', 'dst_h'=>'int', 'src_w'=>'int', 'src_h'=>'int'], +'imagecreate' => ['resource|false', 'x_size'=>'int', 'y_size'=>'int'], +'imagecreatefrombmp' => ['resource|false', 'filename'=>'string'], +'imagecreatefromgd' => ['resource|false', 'filename'=>'string'], +'imagecreatefromgd2' => ['resource|false', 'filename'=>'string'], +'imagecreatefromgd2part' => ['resource|false', 'filename'=>'string', 'srcx'=>'int', 'srcy'=>'int', 'width'=>'int', 'height'=>'int'], +'imagecreatefromgif' => ['resource|false', 'filename'=>'string'], +'imagecreatefromjpeg' => ['resource|false', 'filename'=>'string'], +'imagecreatefrompng' => ['resource|false', 'filename'=>'string'], +'imagecreatefromstring' => ['resource|false', 'image'=>'string'], +'imagecreatefromwbmp' => ['resource|false', 'filename'=>'string'], +'imagecreatefromwebp' => ['resource|false', 'filename'=>'string'], +'imagecreatefromxbm' => ['resource|false', 'filename'=>'string'], +'imagecreatefromxpm' => ['resource|false', 'filename'=>'string'], +'imagecreatetruecolor' => ['resource|false', 'x_size'=>'int', 'y_size'=>'int'], +'imagecrop' => ['resource', 'im'=>'resource', 'rect'=>'array'], +'imagecropauto' => ['resource', 'im'=>'resource', 'mode'=>'int', 'threshold'=>'float', 'color'=>'int'], +'imagedashedline' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'col'=>'int'], +'imagedestroy' => ['bool', 'im'=>'resource'], +'imageellipse' => ['bool', 'im'=>'resource', 'cx'=>'int', 'cy'=>'int', 'w'=>'int', 'h'=>'int', 'color'=>'int'], +'imagefill' => ['bool', 'im'=>'resource', 'x'=>'int', 'y'=>'int', 'col'=>'int'], +'imagefilledarc' => ['bool', 'im'=>'resource', 'cx'=>'int', 'cy'=>'int', 'w'=>'int', 'h'=>'int', 's'=>'int', 'e'=>'int', 'col'=>'int', 'style'=>'int'], +'imagefilledellipse' => ['bool', 'im'=>'resource', 'cx'=>'int', 'cy'=>'int', 'w'=>'int', 'h'=>'int', 'color'=>'int'], +'imagefilledpolygon' => ['bool', 'im'=>'resource', 'point'=>'array', 'num_points'=>'int', 'col'=>'int'], +'imagefilledrectangle' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'col'=>'int'], +'imagefilltoborder' => ['bool', 'im'=>'resource', 'x'=>'int', 'y'=>'int', 'border'=>'int', 'col'=>'int'], +'imagefilter' => ['bool', 'src_im'=>'resource', 'filtertype'=>'int', 'arg1='=>'int', 'arg2='=>'int', 'arg3='=>'int', 'arg4='=>'int'], +'imageflip' => ['bool', 'im'=>'resource', 'mode'=>'int'], +'imagefontheight' => ['int', 'font'=>'int'], +'imagefontwidth' => ['int', 'font'=>'int'], +'imageftbbox' => ['array', 'size'=>'float', 'angle'=>'float', 'font_file'=>'string', 'text'=>'string', 'extrainfo='=>'array'], +'imagefttext' => ['array', 'im'=>'resource', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'col'=>'int', 'font_file'=>'string', 'text'=>'string', 'extrainfo='=>'array'], +'imagegammacorrect' => ['bool', 'im'=>'resource', 'inputgamma'=>'float', 'outputgamma'=>'float'], +'imagegd' => ['bool', 'im'=>'resource', 'filename='=>'?string'], +'imagegd2' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'chunk_size='=>'int', 'type='=>'int'], +'imagegetclip' => ['array', 'im'=>'resource'], +'imagegif' => ['bool', 'im'=>'resource', 'filename='=>'?string'], +'imagegrabscreen' => ['resource'], +'imagegrabwindow' => ['resource', 'window_handle'=>'int', 'client_area='=>'int'], +'imageinterlace' => ['int', 'im'=>'resource', 'interlace='=>'int'], +'imageistruecolor' => ['bool', 'im'=>'resource'], +'imagejpeg' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'quality='=>'int'], +'imagelayereffect' => ['bool', 'im'=>'resource', 'effect'=>'int'], +'imageline' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'col'=>'int'], +'imageloadfont' => ['int', 'filename'=>'string'], +'imageObj::pasteImage' => ['void', 'srcImg'=>'imageObj', 'transparentColorHex'=>'int', 'dstX'=>'int', 'dstY'=>'int', 'angle'=>'int'], +'imageObj::saveImage' => ['int', 'filename'=>'string', 'oMap'=>'MapObj'], +'imageObj::saveWebImage' => ['string'], +'imageopenpolygon' => ['bool', 'image'=>'resource', 'points'=>'array', 'num_points'=>'int', 'color'=>'int'], +'imagepalettecopy' => ['void', 'dst'=>'resource', 'src'=>'resource'], +'imagepalettetotruecolor' => ['bool', 'src'=>'resource'], +'imagepng' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'quality='=>'int', 'filters='=>'int'], +'imagepolygon' => ['bool', 'im'=>'resource', 'point'=>'array', 'num_points'=>'int', 'col'=>'int'], +'imagepsbbox' => ['array', 'text'=>'string', 'font'=>'', 'size'=>'int', 'space'=>'int', 'tightness'=>'int', 'angle'=>'float'], +'imagepsencodefont' => ['bool', 'font_index'=>'resource', 'encodingfile'=>'string'], +'imagepsextendfont' => ['bool', 'font_index'=>'resource', 'extend'=>'float'], +'imagepsfreefont' => ['bool', 'font_index'=>'resource'], +'imagepsloadfont' => ['resource', 'filename'=>'string'], +'imagepsslantfont' => ['bool', 'font_index'=>'resource', 'slant'=>'float'], +'imagepstext' => ['array', 'image'=>'resource', 'text'=>'string', 'font_index'=>'resource', 'size'=>'int', 'foreground'=>'int', 'background'=>'int', 'x'=>'int', 'y'=>'int', 'space='=>'int', 'tightness='=>'int', 'angle='=>'float', 'antialias_steps='=>'int'], +'imagerectangle' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int', 'col'=>'int'], +'imageresolution' => ['mixed', 'image'=>'resource', 'res_x='=>'int', 'res_y='=>'int'], +'imagerotate' => ['resource', 'src_im'=>'resource', 'angle'=>'float', 'bgdcolor'=>'int', 'ignoretransparent='=>'int'], +'imagesavealpha' => ['bool', 'im'=>'resource', 'on'=>'bool'], +'imagescale' => ['resource', 'im'=>'resource', 'new_width'=>'int', 'new_height='=>'int', 'method='=>'int'], +'imagesetbrush' => ['bool', 'image'=>'resource', 'brush'=>'resource'], +'imagesetclip' => ['bool', 'im'=>'resource', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int'], +'imagesetinterpolation' => ['bool', 'im'=>'resource', 'method'=>'int'], +'imagesetpixel' => ['bool', 'im'=>'resource', 'x'=>'int', 'y'=>'int', 'col'=>'int'], +'imagesetstyle' => ['bool', 'im'=>'resource', 'styles'=>'array'], +'imagesetthickness' => ['bool', 'im'=>'resource', 'thickness'=>'int'], +'imagesettile' => ['bool', 'image'=>'resource', 'tile'=>'resource'], +'imagestring' => ['bool', 'im'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'str'=>'string', 'col'=>'int'], +'imagestringup' => ['bool', 'im'=>'resource', 'font'=>'int', 'x'=>'int', 'y'=>'int', 'str'=>'string', 'col'=>'int'], +'imagesx' => ['int', 'im'=>'resource'], +'imagesy' => ['int', 'im'=>'resource'], +'imagetruecolortopalette' => ['bool', 'im'=>'resource', 'ditherflag'=>'bool', 'colorswanted'=>'int'], +'imagettfbbox' => ['array', 'size'=>'float', 'angle'=>'float', 'font_file'=>'string', 'text'=>'string'], +'imagettftext' => ['array', 'im'=>'resource', 'size'=>'float', 'angle'=>'float', 'x'=>'int', 'y'=>'int', 'col'=>'int', 'font_file'=>'string', 'text'=>'string'], +'imagetypes' => ['int'], +'imagewbmp' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'foreground='=>'int'], +'imagewebp' => ['bool', 'im'=>'resource', 'filename='=>'?string', 'quality='=>'int'], +'imagexbm' => ['bool', 'im'=>'resource', 'filename'=>'?string', 'foreground='=>'int'], +'Imagick::__construct' => ['void', 'files='=>''], +'Imagick::__toString' => ['string'], +'Imagick::adaptiveBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], +'Imagick::adaptiveResizeImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'bestfit='=>'bool'], +'Imagick::adaptiveSharpenImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], +'Imagick::adaptiveThresholdImage' => ['bool', 'width'=>'int', 'height'=>'int', 'offset'=>'int'], +'Imagick::addImage' => ['bool', 'source'=>'imagick'], +'Imagick::addNoiseImage' => ['bool', 'noise_type'=>'int', 'channel='=>'int'], +'Imagick::affineTransformImage' => ['bool', 'matrix'=>'imagickdraw'], +'Imagick::animateImages' => ['bool', 'x_server'=>'string'], +'Imagick::annotateImage' => ['bool', 'draw_settings'=>'imagickdraw', 'x'=>'float', 'y'=>'float', 'angle'=>'float', 'text'=>'string'], +'Imagick::appendImages' => ['Imagick', 'stack'=>'bool'], +'Imagick::autoGammaImage' => ['bool', 'channel='=>'int'], +'Imagick::autoLevelImage' => ['void', 'CHANNEL='=>'string'], +'Imagick::autoOrient' => ['bool'], +'Imagick::averageImages' => ['Imagick'], +'Imagick::blackThresholdImage' => ['bool', 'threshold'=>'mixed'], +'Imagick::blueShiftImage' => ['void', 'factor='=>'float'], +'Imagick::blurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], +'Imagick::borderImage' => ['bool', 'bordercolor'=>'mixed', 'width'=>'int', 'height'=>'int'], +'Imagick::brightnessContrastImage' => ['void', 'brightness'=>'string', 'contrast'=>'string', 'CHANNEL='=>'string'], +'Imagick::charcoalImage' => ['bool', 'radius'=>'float', 'sigma'=>'float'], +'Imagick::chopImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Imagick::clampImage' => ['void', 'CHANNEL='=>'string'], +'Imagick::clear' => ['bool'], +'Imagick::clipImage' => ['bool'], +'Imagick::clipImagePath' => ['void', 'pathname'=>'string', 'inside'=>'string'], +'Imagick::clipPathImage' => ['bool', 'pathname'=>'string', 'inside'=>'bool'], +'Imagick::clone' => ['Imagick'], +'Imagick::clutImage' => ['bool', 'lookup_table'=>'imagick', 'channel='=>'float'], +'Imagick::coalesceImages' => ['Imagick'], +'Imagick::colorFloodfillImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int'], +'Imagick::colorizeImage' => ['bool', 'colorize'=>'mixed', 'opacity'=>'mixed'], +'Imagick::colorMatrixImage' => ['void', 'color_matrix'=>'string'], +'Imagick::combineImages' => ['Imagick', 'channeltype'=>'int'], +'Imagick::commentImage' => ['bool', 'comment'=>'string'], +'Imagick::compareImageChannels' => ['array', 'image'=>'imagick', 'channeltype'=>'int', 'metrictype'=>'int'], +'Imagick::compareImageLayers' => ['Imagick', 'method'=>'int'], +'Imagick::compareImages' => ['array', 'compare'=>'imagick', 'metric'=>'int'], +'Imagick::compositeImage' => ['bool', 'composite_object'=>'imagick', 'composite'=>'int', 'x'=>'int', 'y'=>'int', 'channel='=>'int'], +'Imagick::compositeImageGravity' => ['bool', 'imagick'=>'Imagick', 'COMPOSITE_CONSTANT'=>'int', 'GRAVITY_CONSTANT'=>'int'], +'Imagick::contrastImage' => ['bool', 'sharpen'=>'bool'], +'Imagick::contrastStretchImage' => ['bool', 'black_point'=>'float', 'white_point'=>'float', 'channel='=>'int'], +'Imagick::convolveImage' => ['bool', 'kernel'=>'array', 'channel='=>'int'], +'Imagick::count' => ['void', 'mode='=>'string'], +'Imagick::cropImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Imagick::cropThumbnailImage' => ['bool', 'width'=>'int', 'height'=>'int'], +'Imagick::current' => ['Imagick'], +'Imagick::cycleColormapImage' => ['bool', 'displace'=>'int'], +'Imagick::decipherImage' => ['bool', 'passphrase'=>'string'], +'Imagick::deconstructImages' => ['Imagick'], +'Imagick::deleteImageArtifact' => ['bool', 'artifact'=>'string'], +'Imagick::deleteImageProperty' => ['void', 'name'=>'string'], +'Imagick::deskewImage' => ['bool', 'threshold'=>'float'], +'Imagick::despeckleImage' => ['bool'], +'Imagick::destroy' => ['bool'], +'Imagick::displayImage' => ['bool', 'servername'=>'string'], +'Imagick::displayImages' => ['bool', 'servername'=>'string'], +'Imagick::distortImage' => ['bool', 'method'=>'int', 'arguments'=>'array', 'bestfit'=>'bool'], +'Imagick::drawImage' => ['bool', 'draw'=>'imagickdraw'], +'Imagick::edgeImage' => ['bool', 'radius'=>'float'], +'Imagick::embossImage' => ['bool', 'radius'=>'float', 'sigma'=>'float'], +'Imagick::encipherImage' => ['bool', 'passphrase'=>'string'], +'Imagick::enhanceImage' => ['bool'], +'Imagick::equalizeImage' => ['bool'], +'Imagick::evaluateImage' => ['bool', 'op'=>'int', 'constant'=>'float', 'channel='=>'int'], +'Imagick::evaluateImages' => ['bool', 'EVALUATE_CONSTANT'=>'int'], +'Imagick::exportImagePixels' => ['array', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int', 'map'=>'string', 'storage'=>'int'], +'Imagick::extentImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Imagick::filter' => ['void', 'ImagickKernel'=>'ImagickKernel', 'CHANNEL='=>'int'], +'Imagick::flattenImages' => ['Imagick'], +'Imagick::flipImage' => ['bool'], +'Imagick::floodFillPaintImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'target'=>'mixed', 'x'=>'int', 'y'=>'int', 'invert'=>'bool', 'channel='=>'int'], +'Imagick::flopImage' => ['bool'], +'Imagick::forwardFourierTransformimage' => ['void', 'magnitude'=>'bool'], +'Imagick::frameImage' => ['bool', 'matte_color'=>'mixed', 'width'=>'int', 'height'=>'int', 'inner_bevel'=>'int', 'outer_bevel'=>'int'], +'Imagick::functionImage' => ['bool', 'function'=>'int', 'arguments'=>'array', 'channel='=>'int'], +'Imagick::fxImage' => ['Imagick', 'expression'=>'string', 'channel='=>'int'], +'Imagick::gammaImage' => ['bool', 'gamma'=>'float', 'channel='=>'int'], +'Imagick::gaussianBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], +'Imagick::getColorspace' => ['int'], +'Imagick::getCompression' => ['int'], +'Imagick::getCompressionQuality' => ['int'], +'Imagick::getConfigureOptions' => ['string'], +'Imagick::getCopyright' => ['string'], +'Imagick::getFeatures' => ['string'], +'Imagick::getFilename' => ['string'], +'Imagick::getFont' => ['string'], +'Imagick::getFormat' => ['string'], +'Imagick::getGravity' => ['int'], +'Imagick::getHDRIEnabled' => ['int'], +'Imagick::getHomeURL' => ['string'], +'Imagick::getImage' => ['Imagick'], +'Imagick::getImageAlphaChannel' => ['int'], +'Imagick::getImageArtifact' => ['string', 'artifact'=>'string'], +'Imagick::getImageAttribute' => ['string', 'key'=>'string'], +'Imagick::getImageBackgroundColor' => ['ImagickPixel'], +'Imagick::getImageBlob' => ['string'], +'Imagick::getImageBluePrimary' => ['array'], +'Imagick::getImageBorderColor' => ['ImagickPixel'], +'Imagick::getImageChannelDepth' => ['int', 'channel'=>'int'], +'Imagick::getImageChannelDistortion' => ['float', 'reference'=>'imagick', 'channel'=>'int', 'metric'=>'int'], +'Imagick::getImageChannelDistortions' => ['float', 'reference'=>'imagick', 'metric'=>'int', 'channel='=>'int'], +'Imagick::getImageChannelExtrema' => ['array', 'channel'=>'int'], +'Imagick::getImageChannelKurtosis' => ['array', 'channel='=>'int'], +'Imagick::getImageChannelMean' => ['array', 'channel'=>'int'], +'Imagick::getImageChannelRange' => ['array', 'channel'=>'int'], +'Imagick::getImageChannelStatistics' => ['array'], +'Imagick::getImageClipMask' => ['Imagick'], +'Imagick::getImageColormapColor' => ['ImagickPixel', 'index'=>'int'], +'Imagick::getImageColors' => ['int'], +'Imagick::getImageColorspace' => ['int'], +'Imagick::getImageCompose' => ['int'], +'Imagick::getImageCompression' => ['int'], +'Imagick::getImageCompressionQuality' => ['int'], +'Imagick::getImageDelay' => ['int'], +'Imagick::getImageDepth' => ['int'], +'Imagick::getImageDispose' => ['int'], +'Imagick::getImageDistortion' => ['float', 'reference'=>'magickwand', 'metric'=>'int'], +'Imagick::getImageExtrema' => ['array'], +'Imagick::getImageFilename' => ['string'], +'Imagick::getImageFormat' => ['string'], +'Imagick::getImageGamma' => ['float'], +'Imagick::getImageGeometry' => ['array'], +'Imagick::getImageGravity' => ['int'], +'Imagick::getImageGreenPrimary' => ['array'], +'Imagick::getImageHeight' => ['int'], +'Imagick::getImageHistogram' => ['array'], +'Imagick::getImageIndex' => ['int'], +'Imagick::getImageInterlaceScheme' => ['int'], +'Imagick::getImageInterpolateMethod' => ['int'], +'Imagick::getImageIterations' => ['int'], +'Imagick::getImageLength' => ['int'], +'Imagick::getImageMagickLicense' => ['string'], +'Imagick::getImageMatte' => ['bool'], +'Imagick::getImageMatteColor' => ['ImagickPixel'], +'Imagick::getImageMimeType' => ['string'], +'Imagick::getImageOrientation' => ['int'], +'Imagick::getImagePage' => ['array'], +'Imagick::getImagePixelColor' => ['ImagickPixel', 'x'=>'int', 'y'=>'int'], +'Imagick::getImageProfile' => ['string', 'name'=>'string'], +'Imagick::getImageProfiles' => ['array', 'pattern='=>'string', 'only_names='=>'bool'], +'Imagick::getImageProperties' => ['array', 'pattern='=>'string', 'only_names='=>'bool'], +'Imagick::getImageProperty' => ['string', 'name'=>'string'], +'Imagick::getImageRedPrimary' => ['array'], +'Imagick::getImageRegion' => ['Imagick', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Imagick::getImageRenderingIntent' => ['int'], +'Imagick::getImageResolution' => ['array'], +'Imagick::getImagesBlob' => ['string'], +'Imagick::getImageScene' => ['int'], +'Imagick::getImageSignature' => ['string'], +'Imagick::getImageSize' => ['int'], +'Imagick::getImageTicksPerSecond' => ['int'], +'Imagick::getImageTotalInkDensity' => ['float'], +'Imagick::getImageType' => ['int'], +'Imagick::getImageUnits' => ['int'], +'Imagick::getImageVirtualPixelMethod' => ['int'], +'Imagick::getImageWhitePoint' => ['array'], +'Imagick::getImageWidth' => ['int'], +'Imagick::getInterlaceScheme' => ['int'], +'Imagick::getIteratorIndex' => ['int'], +'Imagick::getNumberImages' => ['int'], +'Imagick::getOption' => ['string', 'key'=>'string'], +'Imagick::getPackageName' => ['string'], +'Imagick::getPage' => ['array'], +'Imagick::getPixelIterator' => ['ImagickPixelIterator'], +'Imagick::getPixelRegionIterator' => ['ImagickPixelIterator', 'x'=>'int', 'y'=>'int', 'columns'=>'int', 'rows'=>'int'], +'Imagick::getPointSize' => ['float'], +'Imagick::getQuantum' => ['int'], +'Imagick::getQuantumDepth' => ['array'], +'Imagick::getQuantumRange' => ['array'], +'Imagick::getRegistry' => ['string', 'key'=>'string'], +'Imagick::getReleaseDate' => ['string'], +'Imagick::getResource' => ['int', 'type'=>'int'], +'Imagick::getResourceLimit' => ['int', 'type'=>'int'], +'Imagick::getSamplingFactors' => ['array'], +'Imagick::getSize' => ['array'], +'Imagick::getSizeOffset' => ['int'], +'Imagick::getVersion' => ['array'], +'Imagick::haldClutImage' => ['bool', 'clut'=>'imagick', 'channel='=>'int'], +'Imagick::hasNextImage' => ['bool'], +'Imagick::hasPreviousImage' => ['bool'], +'Imagick::identifyFormat' => ['string|false', 'embedText'=>'string'], +'Imagick::identifyImage' => ['array', 'appendrawoutput='=>'bool'], +'Imagick::identifyImageType' => ['int'], +'Imagick::implodeImage' => ['bool', 'radius'=>'float'], +'Imagick::importImagePixels' => ['bool', 'x'=>'int', 'y'=>'int', 'width'=>'int', 'height'=>'int', 'map'=>'string', 'storage'=>'int', 'pixels'=>'array'], +'Imagick::inverseFourierTransformImage' => ['void', 'complement'=>'string', 'magnitude'=>'string'], +'Imagick::key' => ['int|string'], +'Imagick::labelImage' => ['bool', 'label'=>'string'], +'Imagick::levelImage' => ['bool', 'blackpoint'=>'float', 'gamma'=>'float', 'whitepoint'=>'float', 'channel='=>'int'], +'Imagick::linearStretchImage' => ['bool', 'blackpoint'=>'float', 'whitepoint'=>'float'], +'Imagick::liquidRescaleImage' => ['bool', 'width'=>'int', 'height'=>'int', 'delta_x'=>'float', 'rigidity'=>'float'], +'Imagick::listRegistry' => ['array'], +'Imagick::localContrastImage' => ['bool', 'radius'=>'float', 'strength'=>'float'], +'Imagick::magnifyImage' => ['bool'], +'Imagick::mapImage' => ['bool', 'map'=>'imagick', 'dither'=>'bool'], +'Imagick::matteFloodfillImage' => ['bool', 'alpha'=>'float', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int'], +'Imagick::medianFilterImage' => ['bool', 'radius'=>'float'], +'Imagick::mergeImageLayers' => ['bool', 'layer_method'=>'int'], +'Imagick::minifyImage' => ['bool'], +'Imagick::modulateImage' => ['bool', 'brightness'=>'float', 'saturation'=>'float', 'hue'=>'float'], +'Imagick::montageImage' => ['Imagick', 'draw'=>'imagickdraw', 'tile_geometry'=>'string', 'thumbnail_geometry'=>'string', 'mode'=>'int', 'frame'=>'string'], +'Imagick::morphImages' => ['Imagick', 'number_frames'=>'int'], +'Imagick::morphology' => ['void', 'morphologyMethod'=>'int', 'iterations'=>'int', 'ImagickKernel'=>'ImagickKernel', 'CHANNEL='=>'string'], +'Imagick::mosaicImages' => ['Imagick'], +'Imagick::motionBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float', 'channel='=>'int'], +'Imagick::negateImage' => ['bool', 'gray'=>'bool', 'channel='=>'int'], +'Imagick::newImage' => ['bool', 'cols'=>'int', 'rows'=>'int', 'background'=>'mixed', 'format='=>'string'], +'Imagick::newPseudoImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'pseudostring'=>'string'], +'Imagick::next' => ['void'], +'Imagick::nextImage' => ['bool'], +'Imagick::normalizeImage' => ['bool', 'channel='=>'int'], +'Imagick::oilPaintImage' => ['bool', 'radius'=>'float'], +'Imagick::opaquePaintImage' => ['bool', 'target'=>'mixed', 'fill'=>'mixed', 'fuzz'=>'float', 'invert'=>'bool', 'channel='=>'int'], +'Imagick::optimizeImageLayers' => ['bool'], +'Imagick::orderedPosterizeImage' => ['bool', 'threshold_map'=>'string', 'channel='=>'int'], +'Imagick::paintFloodfillImage' => ['bool', 'fill'=>'mixed', 'fuzz'=>'float', 'bordercolor'=>'mixed', 'x'=>'int', 'y'=>'int', 'channel='=>'int'], +'Imagick::paintOpaqueImage' => ['bool', 'target'=>'mixed', 'fill'=>'mixed', 'fuzz'=>'float', 'channel='=>'int'], +'Imagick::paintTransparentImage' => ['bool', 'target'=>'mixed', 'alpha'=>'float', 'fuzz'=>'float'], +'Imagick::pingImage' => ['bool', 'filename'=>'string'], +'Imagick::pingImageBlob' => ['bool', 'image'=>'string'], +'Imagick::pingImageFile' => ['bool', 'filehandle'=>'resource', 'filename='=>'string'], +'Imagick::polaroidImage' => ['bool', 'properties'=>'imagickdraw', 'angle'=>'float'], +'Imagick::posterizeImage' => ['bool', 'levels'=>'int', 'dither'=>'bool'], +'Imagick::previewImages' => ['bool', 'preview'=>'int'], +'Imagick::previousImage' => ['bool'], +'Imagick::profileImage' => ['bool', 'name'=>'string', 'profile'=>'string'], +'Imagick::quantizeImage' => ['bool', 'numbercolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'], +'Imagick::quantizeImages' => ['bool', 'numbercolors'=>'int', 'colorspace'=>'int', 'treedepth'=>'int', 'dither'=>'bool', 'measureerror'=>'bool'], +'Imagick::queryFontMetrics' => ['array', 'properties'=>'imagickdraw', 'text'=>'string', 'multiline='=>'bool'], +'Imagick::queryFonts' => ['array', 'pattern='=>'string'], +'Imagick::queryFormats' => ['array', 'pattern='=>'string'], +'Imagick::radialBlurImage' => ['bool', 'angle'=>'float', 'channel='=>'int'], +'Imagick::raiseImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int', 'raise'=>'bool'], +'Imagick::randomThresholdImage' => ['bool', 'low'=>'float', 'high'=>'float', 'channel='=>'int'], +'Imagick::readImage' => ['bool', 'filename'=>'string'], +'Imagick::readImageBlob' => ['bool', 'image'=>'string', 'filename='=>'string'], +'Imagick::readImageFile' => ['bool', 'filehandle'=>'resource', 'filename='=>'string'], +'Imagick::readImages' => ['Imagick', 'filenames'=>'string'], +'Imagick::recolorImage' => ['bool', 'matrix'=>'array'], +'Imagick::reduceNoiseImage' => ['bool', 'radius'=>'float'], +'Imagick::remapImage' => ['bool', 'replacement'=>'imagick', 'dither'=>'int'], +'Imagick::removeImage' => ['bool'], +'Imagick::removeImageProfile' => ['string', 'name'=>'string'], +'Imagick::render' => ['bool'], +'Imagick::resampleImage' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float', 'filter'=>'int', 'blur'=>'float'], +'Imagick::resetImagePage' => ['bool', 'page'=>'string'], +'Imagick::resetIterator' => [''], +'Imagick::resizeImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'filter'=>'int', 'blur'=>'float', 'bestfit='=>'bool'], +'Imagick::rewind' => ['void'], +'Imagick::rollImage' => ['bool', 'x'=>'int', 'y'=>'int'], +'Imagick::rotateImage' => ['bool', 'background'=>'mixed', 'degrees'=>'float'], +'Imagick::rotationalBlurImage' => ['void', 'angle'=>'string', 'CHANNEL='=>'string'], +'Imagick::roundCorners' => ['bool', 'x_rounding'=>'float', 'y_rounding'=>'float', 'stroke_width='=>'float', 'displace='=>'float', 'size_correction='=>'float'], +'Imagick::roundCornersImage' => ['', 'xRounding'=>'', 'yRounding'=>'', 'strokeWidth'=>'', 'displace'=>'', 'sizeCorrection'=>''], +'Imagick::sampleImage' => ['bool', 'columns'=>'int', 'rows'=>'int'], +'Imagick::scaleImage' => ['bool', 'cols'=>'int', 'rows'=>'int', 'bestfit='=>'bool'], +'Imagick::segmentImage' => ['bool', 'colorspace'=>'int', 'cluster_threshold'=>'float', 'smooth_threshold'=>'float', 'verbose='=>'bool'], +'Imagick::selectiveBlurImage' => ['void', 'radius'=>'float', 'sigma'=>'float', 'threshold'=>'float', 'CHANNEL'=>'int'], +'Imagick::separateImageChannel' => ['bool', 'channel'=>'int'], +'Imagick::sepiaToneImage' => ['bool', 'threshold'=>'float'], +'Imagick::setAntiAlias' => ['int', 'antialias'=>'bool'], +'Imagick::setBackgroundColor' => ['bool', 'background'=>'mixed'], +'Imagick::setColorspace' => ['bool', 'colorspace'=>'int'], +'Imagick::setCompression' => ['bool', 'compression'=>'int'], +'Imagick::setCompressionQuality' => ['bool', 'quality'=>'int'], +'Imagick::setFilename' => ['bool', 'filename'=>'string'], +'Imagick::setFirstIterator' => ['bool'], +'Imagick::setFont' => ['bool', 'font'=>'string'], +'Imagick::setFormat' => ['bool', 'format'=>'string'], +'Imagick::setGravity' => ['bool', 'gravity'=>'int'], +'Imagick::setImage' => ['bool', 'replace'=>'imagick'], +'Imagick::setImageAlpha' => ['bool', 'alpha'=>'float'], +'Imagick::setImageAlphaChannel' => ['bool', 'mode'=>'int'], +'Imagick::setImageArtifact' => ['bool', 'artifact'=>'string', 'value'=>'string'], +'Imagick::setImageAttribute' => ['void', 'key'=>'string', 'value'=>'string'], +'Imagick::setImageBackgroundColor' => ['bool', 'background'=>'mixed'], +'Imagick::setImageBias' => ['bool', 'bias'=>'float'], +'Imagick::setImageBiasQuantum' => ['void', 'bias'=>'string'], +'Imagick::setImageBluePrimary' => ['bool', 'x'=>'float', 'y'=>'float'], +'Imagick::setImageBorderColor' => ['bool', 'border'=>'mixed'], +'Imagick::setImageChannelDepth' => ['bool', 'channel'=>'int', 'depth'=>'int'], +'Imagick::setImageChannelMask' => ['', 'channel'=>'int'], +'Imagick::setImageClipMask' => ['bool', 'clip_mask'=>'imagick'], +'Imagick::setImageColormapColor' => ['bool', 'index'=>'int', 'color'=>'imagickpixel'], +'Imagick::setImageColorspace' => ['bool', 'colorspace'=>'int'], +'Imagick::setImageCompose' => ['bool', 'compose'=>'int'], +'Imagick::setImageCompression' => ['bool', 'compression'=>'int'], +'Imagick::setImageCompressionQuality' => ['bool', 'quality'=>'int'], +'Imagick::setImageDelay' => ['bool', 'delay'=>'int'], +'Imagick::setImageDepth' => ['bool', 'depth'=>'int'], +'Imagick::setImageDispose' => ['bool', 'dispose'=>'int'], +'Imagick::setImageExtent' => ['bool', 'columns'=>'int', 'rows'=>'int'], +'Imagick::setImageFilename' => ['bool', 'filename'=>'string'], +'Imagick::setImageFormat' => ['bool', 'format'=>'string'], +'Imagick::setImageGamma' => ['bool', 'gamma'=>'float'], +'Imagick::setImageGravity' => ['bool', 'gravity'=>'int'], +'Imagick::setImageGreenPrimary' => ['bool', 'x'=>'float', 'y'=>'float'], +'Imagick::setImageIndex' => ['bool', 'index'=>'int'], +'Imagick::setImageInterlaceScheme' => ['bool', 'interlace_scheme'=>'int'], +'Imagick::setImageInterpolateMethod' => ['bool', 'method'=>'int'], +'Imagick::setImageIterations' => ['bool', 'iterations'=>'int'], +'Imagick::setImageMatte' => ['bool', 'matte'=>'bool'], +'Imagick::setImageMatteColor' => ['bool', 'matte'=>'mixed'], +'Imagick::setImageOpacity' => ['bool', 'opacity'=>'float'], +'Imagick::setImageOrientation' => ['bool', 'orientation'=>'int'], +'Imagick::setImagePage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Imagick::setImageProfile' => ['bool', 'name'=>'string', 'profile'=>'string'], +'Imagick::setImageProgressMonitor' => ['', 'filename'=>''], +'Imagick::setImageProperty' => ['bool', 'name'=>'string', 'value'=>'string'], +'Imagick::setImageRedPrimary' => ['bool', 'x'=>'float', 'y'=>'float'], +'Imagick::setImageRenderingIntent' => ['bool', 'rendering_intent'=>'int'], +'Imagick::setImageResolution' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float'], +'Imagick::setImageScene' => ['bool', 'scene'=>'int'], +'Imagick::setImageTicksPerSecond' => ['bool', 'ticks_per_second'=>'int'], +'Imagick::setImageType' => ['bool', 'image_type'=>'int'], +'Imagick::setImageUnits' => ['bool', 'units'=>'int'], +'Imagick::setImageVirtualPixelMethod' => ['bool', 'method'=>'int'], +'Imagick::setImageWhitePoint' => ['bool', 'x'=>'float', 'y'=>'float'], +'Imagick::setInterlaceScheme' => ['bool', 'interlace_scheme'=>'int'], +'Imagick::setIteratorIndex' => ['bool', 'index'=>'int'], +'Imagick::setLastIterator' => ['bool'], +'Imagick::setOption' => ['bool', 'key'=>'string', 'value'=>'string'], +'Imagick::setPage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Imagick::setPointSize' => ['bool', 'point_size'=>'float'], +'Imagick::setProgressMonitor' => ['void', 'callback'=>'callable'], +'Imagick::setRegistry' => ['void', 'key'=>'string', 'value'=>'string'], +'Imagick::setResolution' => ['bool', 'x_resolution'=>'float', 'y_resolution'=>'float'], +'Imagick::setResourceLimit' => ['bool', 'type'=>'int', 'limit'=>'int'], +'Imagick::setSamplingFactors' => ['bool', 'factors'=>'array'], +'Imagick::setSize' => ['bool', 'columns'=>'int', 'rows'=>'int'], +'Imagick::setSizeOffset' => ['bool', 'columns'=>'int', 'rows'=>'int', 'offset'=>'int'], +'Imagick::setType' => ['bool', 'image_type'=>'int'], +'Imagick::shadeImage' => ['bool', 'gray'=>'bool', 'azimuth'=>'float', 'elevation'=>'float'], +'Imagick::shadowImage' => ['bool', 'opacity'=>'float', 'sigma'=>'float', 'x'=>'int', 'y'=>'int'], +'Imagick::sharpenImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'int'], +'Imagick::shaveImage' => ['bool', 'columns'=>'int', 'rows'=>'int'], +'Imagick::shearImage' => ['bool', 'background'=>'mixed', 'x_shear'=>'float', 'y_shear'=>'float'], +'Imagick::sigmoidalContrastImage' => ['bool', 'sharpen'=>'bool', 'alpha'=>'float', 'beta'=>'float', 'channel='=>'int'], +'Imagick::similarityImage' => ['Imagick', 'imagick'=>'Imagick', '&bestMatch'=>'array', '&similarity'=>'float', 'similarity_threshold'=>'float', 'metric'=>'int'], +'Imagick::sketchImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'angle'=>'float'], +'Imagick::smushImages' => ['Imagick', 'stack'=>'string', 'offset'=>'string'], +'Imagick::solarizeImage' => ['bool', 'threshold'=>'int'], +'Imagick::sparseColorImage' => ['bool', 'sparse_method'=>'int', 'arguments'=>'array', 'channel='=>'int'], +'Imagick::spliceImage' => ['bool', 'width'=>'int', 'height'=>'int', 'x'=>'int', 'y'=>'int'], +'Imagick::spreadImage' => ['bool', 'radius'=>'float'], +'Imagick::statisticImage' => ['void', 'type'=>'int', 'width'=>'int', 'height'=>'int', 'CHANNEL='=>'string'], +'Imagick::steganoImage' => ['Imagick', 'watermark_wand'=>'imagick', 'offset'=>'int'], +'Imagick::stereoImage' => ['bool', 'offset_wand'=>'imagick'], +'Imagick::stripImage' => ['bool'], +'Imagick::subImageMatch' => ['Imagick', 'Imagick'=>'Imagick', '&w_offset='=>'array', '&w_similarity='=>'float'], +'Imagick::swirlImage' => ['bool', 'degrees'=>'float'], +'Imagick::textureImage' => ['bool', 'texture_wand'=>'imagick'], +'Imagick::thresholdImage' => ['bool', 'threshold'=>'float', 'channel='=>'int'], +'Imagick::thumbnailImage' => ['bool', 'columns'=>'int', 'rows'=>'int', 'bestfit='=>'bool', 'fill='=>'bool'], +'Imagick::tintImage' => ['bool', 'tint'=>'mixed', 'opacity'=>'mixed'], +'Imagick::transformImage' => ['Imagick', 'crop'=>'string', 'geometry'=>'string'], +'Imagick::transformImageColorspace' => ['bool', 'colorspace'=>'int'], +'Imagick::transparentPaintImage' => ['bool', 'target'=>'mixed', 'alpha'=>'float', 'fuzz'=>'float', 'invert'=>'bool'], +'Imagick::transposeImage' => ['bool'], +'Imagick::transverseImage' => ['bool'], +'Imagick::trimImage' => ['bool', 'fuzz'=>'float'], +'Imagick::uniqueImageColors' => ['bool'], +'Imagick::unsharpMaskImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'amount'=>'float', 'threshold'=>'float', 'channel='=>'int'], +'Imagick::valid' => ['bool'], +'Imagick::vignetteImage' => ['bool', 'blackpoint'=>'float', 'whitepoint'=>'float', 'x'=>'int', 'y'=>'int'], +'Imagick::waveImage' => ['bool', 'amplitude'=>'float', 'length'=>'float'], +'Imagick::whiteThresholdImage' => ['bool', 'threshold'=>'mixed'], +'Imagick::writeImage' => ['bool', 'filename='=>'string'], +'Imagick::writeImageFile' => ['bool', 'filehandle'=>'resource'], +'Imagick::writeImages' => ['bool', 'filename'=>'string', 'adjoin'=>'bool'], +'Imagick::writeImagesFile' => ['bool', 'filehandle'=>'resource'], +'ImagickDraw::__construct' => ['void'], +'ImagickDraw::affine' => ['bool', 'affine'=>'array'], +'ImagickDraw::annotation' => ['bool', 'x'=>'float', 'y'=>'float', 'text'=>'string'], +'ImagickDraw::arc' => ['bool', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float', 'sd'=>'float', 'ed'=>'float'], +'ImagickDraw::bezier' => ['bool', 'coordinates'=>'array'], +'ImagickDraw::circle' => ['bool', 'ox'=>'float', 'oy'=>'float', 'px'=>'float', 'py'=>'float'], +'ImagickDraw::clear' => ['bool'], +'ImagickDraw::clone' => ['ImagickDraw'], +'ImagickDraw::color' => ['bool', 'x'=>'float', 'y'=>'float', 'paintmethod'=>'int'], +'ImagickDraw::comment' => ['bool', 'comment'=>'string'], +'ImagickDraw::composite' => ['bool', 'compose'=>'int', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float', 'compositewand'=>'imagick'], +'ImagickDraw::destroy' => ['bool'], +'ImagickDraw::ellipse' => ['bool', 'ox'=>'float', 'oy'=>'float', 'rx'=>'float', 'ry'=>'float', 'start'=>'float', 'end'=>'float'], +'ImagickDraw::getBorderColor' => ['ImagickPixel'], +'ImagickDraw::getClipPath' => ['string'], +'ImagickDraw::getClipRule' => ['int'], +'ImagickDraw::getClipUnits' => ['int'], +'ImagickDraw::getDensity' => ['null|string'], +'ImagickDraw::getFillColor' => ['ImagickPixel'], +'ImagickDraw::getFillOpacity' => ['float'], +'ImagickDraw::getFillRule' => ['int'], +'ImagickDraw::getFont' => ['string'], +'ImagickDraw::getFontFamily' => ['string'], +'ImagickDraw::getFontResolution' => ['array'], +'ImagickDraw::getFontSize' => ['float'], +'ImagickDraw::getFontStretch' => ['int'], +'ImagickDraw::getFontStyle' => ['int'], +'ImagickDraw::getFontWeight' => ['int'], +'ImagickDraw::getGravity' => ['int'], +'ImagickDraw::getOpacity' => ['float'], +'ImagickDraw::getStrokeAntialias' => ['bool'], +'ImagickDraw::getStrokeColor' => ['ImagickPixel'], +'ImagickDraw::getStrokeDashArray' => ['array'], +'ImagickDraw::getStrokeDashOffset' => ['float'], +'ImagickDraw::getStrokeLineCap' => ['int'], +'ImagickDraw::getStrokeLineJoin' => ['int'], +'ImagickDraw::getStrokeMiterLimit' => ['int'], +'ImagickDraw::getStrokeOpacity' => ['float'], +'ImagickDraw::getStrokeWidth' => ['float'], +'ImagickDraw::getTextAlignment' => ['int'], +'ImagickDraw::getTextAntialias' => ['bool'], +'ImagickDraw::getTextDecoration' => ['int'], +'ImagickDraw::getTextDirection' => ['bool'], +'ImagickDraw::getTextEncoding' => ['string'], +'ImagickDraw::getTextInterlineSpacing' => ['float'], +'ImagickDraw::getTextInterwordSpacing' => ['float'], +'ImagickDraw::getTextKerning' => ['float'], +'ImagickDraw::getTextUnderColor' => ['ImagickPixel'], +'ImagickDraw::getVectorGraphics' => ['string'], +'ImagickDraw::line' => ['bool', 'sx'=>'float', 'sy'=>'float', 'ex'=>'float', 'ey'=>'float'], +'ImagickDraw::matte' => ['bool', 'x'=>'float', 'y'=>'float', 'paintmethod'=>'int'], +'ImagickDraw::pathClose' => ['bool'], +'ImagickDraw::pathCurveToAbsolute' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathCurveToQuadraticBezierAbsolute' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathCurveToQuadraticBezierRelative' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathCurveToQuadraticBezierSmoothAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathCurveToQuadraticBezierSmoothRelative' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathCurveToRelative' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathCurveToSmoothAbsolute' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathCurveToSmoothRelative' => ['bool', 'x2'=>'float', 'y2'=>'float', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathEllipticArcAbsolute' => ['bool', 'rx'=>'float', 'ry'=>'float', 'x_axis_rotation'=>'float', 'large_arc_flag'=>'bool', 'sweep_flag'=>'bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathEllipticArcRelative' => ['bool', 'rx'=>'float', 'ry'=>'float', 'x_axis_rotation'=>'float', 'large_arc_flag'=>'bool', 'sweep_flag'=>'bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathFinish' => ['bool'], +'ImagickDraw::pathLineToAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathLineToHorizontalAbsolute' => ['bool', 'x'=>'float'], +'ImagickDraw::pathLineToHorizontalRelative' => ['bool', 'x'=>'float'], +'ImagickDraw::pathLineToRelative' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathLineToVerticalAbsolute' => ['bool', 'y'=>'float'], +'ImagickDraw::pathLineToVerticalRelative' => ['bool', 'y'=>'float'], +'ImagickDraw::pathMoveToAbsolute' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathMoveToRelative' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::pathStart' => ['bool'], +'ImagickDraw::point' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::polygon' => ['bool', 'coordinates'=>'array'], +'ImagickDraw::polyline' => ['bool', 'coordinates'=>'array'], +'ImagickDraw::pop' => ['bool'], +'ImagickDraw::popClipPath' => ['bool'], +'ImagickDraw::popDefs' => ['bool'], +'ImagickDraw::popPattern' => ['bool'], +'ImagickDraw::push' => ['bool'], +'ImagickDraw::pushClipPath' => ['bool', 'clip_mask_id'=>'string'], +'ImagickDraw::pushDefs' => ['bool'], +'ImagickDraw::pushPattern' => ['bool', 'pattern_id'=>'string', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], +'ImagickDraw::rectangle' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'], +'ImagickDraw::render' => ['bool'], +'ImagickDraw::resetVectorGraphics' => ['void'], +'ImagickDraw::rotate' => ['bool', 'degrees'=>'float'], +'ImagickDraw::roundRectangle' => ['bool', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'rx'=>'float', 'ry'=>'float'], +'ImagickDraw::scale' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::setBorderColor' => ['bool', 'color'=>'ImagickPixel'], +'ImagickDraw::setClipPath' => ['bool', 'clip_mask'=>'string'], +'ImagickDraw::setClipRule' => ['bool', 'fill_rule'=>'int'], +'ImagickDraw::setClipUnits' => ['bool', 'clip_units'=>'int'], +'ImagickDraw::setDensity' => ['bool', 'density_string'=>'string'], +'ImagickDraw::setFillAlpha' => ['bool', 'opacity'=>'float'], +'ImagickDraw::setFillColor' => ['bool', 'fill_pixel'=>'imagickpixel'], +'ImagickDraw::setFillOpacity' => ['bool', 'fillopacity'=>'float'], +'ImagickDraw::setFillPatternURL' => ['bool', 'fill_url'=>'string'], +'ImagickDraw::setFillRule' => ['bool', 'fill_rule'=>'int'], +'ImagickDraw::setFont' => ['bool', 'font_name'=>'string'], +'ImagickDraw::setFontFamily' => ['bool', 'font_family'=>'string'], +'ImagickDraw::setFontResolution' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickDraw::setFontSize' => ['bool', 'pointsize'=>'float'], +'ImagickDraw::setFontStretch' => ['bool', 'fontstretch'=>'int'], +'ImagickDraw::setFontStyle' => ['bool', 'style'=>'int'], +'ImagickDraw::setFontWeight' => ['bool', 'font_weight'=>'int'], +'ImagickDraw::setGravity' => ['bool', 'gravity'=>'int'], +'ImagickDraw::setOpacity' => ['void', 'opacity'=>'float'], +'ImagickDraw::setResolution' => ['void', 'x_resolution'=>'string', 'y_resolution'=>'string'], +'ImagickDraw::setStrokeAlpha' => ['bool', 'opacity'=>'float'], +'ImagickDraw::setStrokeAntialias' => ['bool', 'stroke_antialias'=>'bool'], +'ImagickDraw::setStrokeColor' => ['bool', 'stroke_pixel'=>'imagickpixel'], +'ImagickDraw::setStrokeDashArray' => ['bool', 'dasharray'=>'array'], +'ImagickDraw::setStrokeDashOffset' => ['bool', 'dash_offset'=>'float'], +'ImagickDraw::setStrokeLineCap' => ['bool', 'linecap'=>'int'], +'ImagickDraw::setStrokeLineJoin' => ['bool', 'linejoin'=>'int'], +'ImagickDraw::setStrokeMiterLimit' => ['bool', 'miterlimit'=>'int'], +'ImagickDraw::setStrokeOpacity' => ['bool', 'stroke_opacity'=>'float'], +'ImagickDraw::setStrokePatternURL' => ['bool', 'stroke_url'=>'string'], +'ImagickDraw::setStrokeWidth' => ['bool', 'stroke_width'=>'float'], +'ImagickDraw::setTextAlignment' => ['bool', 'alignment'=>'int'], +'ImagickDraw::setTextAntialias' => ['bool', 'antialias'=>'bool'], +'ImagickDraw::setTextDecoration' => ['bool', 'decoration'=>'int'], +'ImagickDraw::setTextDirection' => ['bool', 'direction'=>'int'], +'ImagickDraw::setTextEncoding' => ['bool', 'encoding'=>'string'], +'ImagickDraw::setTextInterlineSpacing' => ['void', 'spacing'=>'float'], +'ImagickDraw::setTextInterwordSpacing' => ['void', 'spacing'=>'float'], +'ImagickDraw::setTextKerning' => ['void', 'kerning'=>'float'], +'ImagickDraw::setTextUnderColor' => ['bool', 'under_color'=>'imagickpixel'], +'ImagickDraw::setVectorGraphics' => ['bool', 'xml'=>'string'], +'ImagickDraw::setViewbox' => ['bool', 'x1'=>'int', 'y1'=>'int', 'x2'=>'int', 'y2'=>'int'], +'ImagickDraw::skewX' => ['bool', 'degrees'=>'float'], +'ImagickDraw::skewY' => ['bool', 'degrees'=>'float'], +'ImagickDraw::translate' => ['bool', 'x'=>'float', 'y'=>'float'], +'ImagickKernel::addKernel' => ['void', 'ImagickKernel'=>'ImagickKernel'], +'ImagickKernel::addUnityKernel' => ['void'], +'ImagickKernel::fromBuiltin' => ['ImagickKernel', 'kernelType'=>'string', 'kernelString'=>'string'], +'ImagickKernel::fromMatrix' => ['ImagickKernel', 'matrix'=>'array', 'origin='=>'array'], +'ImagickKernel::getMatrix' => ['array'], +'ImagickKernel::scale' => ['void'], +'ImagickKernel::separate' => ['array'], +'ImagickKernel::seperate' => ['void'], +'ImagickPixel::__construct' => ['void', 'color='=>'string'], +'ImagickPixel::clear' => ['bool'], +'ImagickPixel::clone' => ['void'], +'ImagickPixel::destroy' => ['bool'], +'ImagickPixel::getColor' => ['array', 'normalized='=>'bool'], +'ImagickPixel::getColorAsString' => ['string'], +'ImagickPixel::getColorCount' => ['int'], +'ImagickPixel::getColorQuantum' => ['mixed'], +'ImagickPixel::getColorValue' => ['float', 'color'=>'int'], +'ImagickPixel::getColorValueQuantum' => ['mixed'], +'ImagickPixel::getHSL' => ['array'], +'ImagickPixel::getIndex' => ['int'], +'ImagickPixel::isPixelSimilar' => ['bool', 'color'=>'ImagickPixel', 'fuzz'=>'float'], +'ImagickPixel::isPixelSimilarQuantum' => ['bool', 'color'=>'string', 'fuzz='=>'string'], +'ImagickPixel::isSimilar' => ['bool', 'color'=>'imagickpixel', 'fuzz'=>'float'], +'ImagickPixel::setColor' => ['bool', 'color'=>'string'], +'ImagickPixel::setcolorcount' => ['void', 'colorCount'=>'string'], +'ImagickPixel::setColorFromPixel' => ['bool', 'srcPixel'=>'ImagickPixel'], +'ImagickPixel::setColorValue' => ['bool', 'color'=>'int', 'value'=>'float'], +'ImagickPixel::setColorValueQuantum' => ['void', 'color'=>'int', 'value'=>'mixed'], +'ImagickPixel::setHSL' => ['bool', 'hue'=>'float', 'saturation'=>'float', 'luminosity'=>'float'], +'ImagickPixel::setIndex' => ['void', 'index'=>'int'], +'ImagickPixelIterator::__construct' => ['void', 'wand'=>'imagick'], +'ImagickPixelIterator::clear' => ['bool'], +'ImagickPixelIterator::current' => ['mixed'], +'ImagickPixelIterator::destroy' => ['bool'], +'ImagickPixelIterator::getCurrentIteratorRow' => ['array'], +'ImagickPixelIterator::getIteratorRow' => ['int'], +'ImagickPixelIterator::getNextIteratorRow' => ['array'], +'ImagickPixelIterator::getpixeliterator' => ['', 'Imagick'=>'Imagick'], +'ImagickPixelIterator::getpixelregioniterator' => ['', 'Imagick'=>'Imagick', 'x'=>'', 'y'=>'', 'columns'=>'', 'rows'=>''], +'ImagickPixelIterator::getPreviousIteratorRow' => ['array'], +'ImagickPixelIterator::key' => ['int|string'], +'ImagickPixelIterator::newPixelIterator' => ['bool', 'wand'=>'imagick'], +'ImagickPixelIterator::newPixelRegionIterator' => ['bool', 'wand'=>'imagick', 'x'=>'int', 'y'=>'int', 'columns'=>'int', 'rows'=>'int'], +'ImagickPixelIterator::next' => ['void'], +'ImagickPixelIterator::resetIterator' => ['bool'], +'ImagickPixelIterator::rewind' => ['void'], +'ImagickPixelIterator::setIteratorFirstRow' => ['bool'], +'ImagickPixelIterator::setIteratorLastRow' => ['bool'], +'ImagickPixelIterator::setIteratorRow' => ['bool', 'row'=>'int'], +'ImagickPixelIterator::syncIterator' => ['bool'], +'ImagickPixelIterator::valid' => ['bool'], +'imap_8bit' => ['string|false', 'text'=>'string'], +'imap_alerts' => ['array|false'], +'imap_append' => ['bool', 'stream_id'=>'resource', 'folder'=>'string', 'message'=>'string', 'options='=>'string', 'internal_date='=>'string'], +'imap_base64' => ['string|false', 'text'=>'string'], +'imap_binary' => ['string|false', 'text'=>'string'], +'imap_body' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], +'imap_bodystruct' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'section'=>'string'], +'imap_check' => ['stdClass|false', 'stream_id'=>'resource'], +'imap_clearflag_full' => ['bool', 'stream_id'=>'resource', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'], +'imap_close' => ['bool', 'stream_id'=>'resource', 'options='=>'int'], +'imap_create' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], +'imap_createmailbox' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], +'imap_delete' => ['bool', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], +'imap_deletemailbox' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], +'imap_errors' => ['array|false'], +'imap_expunge' => ['bool', 'stream_id'=>'resource'], +'imap_fetch_overview' => ['array|false', 'stream_id'=>'resource', 'sequence'=>'string', 'options='=>'int'], +'imap_fetchbody' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'section'=>'string', 'options='=>'int'], +'imap_fetchheader' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], +'imap_fetchmime' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'section'=>'string', 'options='=>'int'], +'imap_fetchstructure' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], +'imap_fetchtext' => ['string|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'options='=>'int'], +'imap_gc' => ['bool', 'stream_id'=>'resource', 'flags'=>'int'], +'imap_get_quota' => ['array|false', 'stream_id'=>'resource', 'qroot'=>'string'], +'imap_get_quotaroot' => ['array|false', 'stream_id'=>'resource', 'mbox'=>'string'], +'imap_getacl' => ['array|false', 'stream_id'=>'resource', 'mailbox'=>'string'], +'imap_getmailboxes' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], +'imap_getsubscribed' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], +'imap_header' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string'], +'imap_headerinfo' => ['stdClass|false', 'stream_id'=>'resource', 'msg_no'=>'int', 'from_length='=>'int', 'subject_length='=>'int', 'default_host='=>'string'], +'imap_headers' => ['array|false', 'stream_id'=>'resource'], +'imap_last_error' => ['string|false'], +'imap_list' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], +'imap_listmailbox' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], +'imap_listscan' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string', 'content'=>'string'], +'imap_listsubscribed' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], +'imap_lsub' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string'], +'imap_mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string', 'cc='=>'string', 'bcc='=>'string', 'rpath='=>'string'], +'imap_mail_compose' => ['string|false', 'envelope'=>'array', 'body'=>'array'], +'imap_mail_copy' => ['bool', 'stream_id'=>'resource', 'msglist'=>'string', 'mailbox'=>'string', 'options='=>'int'], +'imap_mail_move' => ['bool', 'stream_id'=>'resource', 'sequence'=>'string', 'mailbox'=>'string', 'options='=>'int'], +'imap_mailboxmsginfo' => ['stdClass|false', 'stream_id'=>'resource'], +'imap_mime_header_decode' => ['array|false', 'str'=>'string'], +'imap_msgno' => ['int|false', 'stream_id'=>'resource', 'unique_msg_id'=>'int'], +'imap_mutf7_to_utf8' => ['string|false', 'in'=>'string'], +'imap_num_msg' => ['int|false', 'stream_id'=>'resource'], +'imap_num_recent' => ['int|false', 'stream_id'=>'resource'], +'imap_open' => ['resource|false', 'mailbox'=>'string', 'user'=>'string', 'password'=>'string', 'options='=>'int', 'n_retries='=>'int', 'params=' => 'array|null'], +'imap_ping' => ['bool', 'stream_id'=>'resource'], +'imap_qprint' => ['string|false', 'text'=>'string'], +'imap_rename' => ['bool', 'stream_id'=>'resource', 'old_name'=>'string', 'new_name'=>'string'], +'imap_renamemailbox' => ['bool', 'stream_id'=>'resource', 'old_name'=>'string', 'new_name'=>'string'], +'imap_reopen' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string', 'options='=>'int', 'n_retries='=>'int'], +'imap_rfc822_parse_adrlist' => ['array', 'address_string'=>'string', 'default_host'=>'string'], +'imap_rfc822_parse_headers' => ['stdClass', 'headers'=>'string', 'default_host='=>'string'], +'imap_rfc822_write_address' => ['string|false', 'mailbox'=>'?string', 'host'=>'?string', 'personal'=>'?string'], +'imap_savebody' => ['bool', 'stream_id'=>'resource', 'file'=>'string|resource', 'msg_no'=>'int', 'section='=>'string', 'options='=>'int'], +'imap_scan' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string', 'content'=>'string'], +'imap_scanmailbox' => ['array|false', 'stream_id'=>'resource', 'ref'=>'string', 'pattern'=>'string', 'content'=>'string'], +'imap_search' => ['array|false', 'stream_id'=>'resource', 'criteria'=>'string', 'options='=>'int', 'charset='=>'string'], +'imap_set_quota' => ['bool', 'stream_id'=>'resource', 'qroot'=>'string', 'mailbox_size'=>'int'], +'imap_setacl' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string', 'id'=>'string', 'rights'=>'string'], +'imap_setflag_full' => ['bool', 'stream_id'=>'resource', 'sequence'=>'string', 'flag'=>'string', 'options='=>'int'], +'imap_sort' => ['array|false', 'stream_id'=>'resource', 'criteria'=>'int', 'reverse'=>'int', 'options='=>'int', 'search_criteria='=>'string', 'charset='=>'string'], +'imap_status' => ['stdClass|false', 'stream_id'=>'resource', 'mailbox'=>'string', 'options'=>'int'], +'imap_subscribe' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], +'imap_thread' => ['array', 'stream_id'=>'resource', 'options='=>'int'], +'imap_timeout' => ['mixed', 'timeout_type'=>'int', 'timeout='=>'int'], +'imap_uid' => ['int|false', 'stream_id'=>'resource', 'msg_no'=>'int'], +'imap_undelete' => ['bool', 'stream_id'=>'resource', 'msg_no'=>'int', 'flags='=>'int'], +'imap_unsubscribe' => ['bool', 'stream_id'=>'resource', 'mailbox'=>'string'], +'imap_utf7_decode' => ['string|false', 'buf'=>'string'], +'imap_utf7_encode' => ['string', 'buf'=>'string'], +'imap_utf8' => ['string', 'mime_encoded_text'=>'string'], +'imap_utf8_to_mutf7' => ['string|false', 'in'=>'string'], +'implode' => ['string', 'glue'=>'string', 'pieces'=>'array'], +'implode\'1' => ['string', 'pieces'=>'array', 'glue='=>'string'], +'import_request_variables' => ['bool', 'types'=>'string', 'prefix='=>'string'], +'in_array' => ['bool', 'needle'=>'mixed', 'haystack'=>'array', 'strict='=>'bool'], +'inclued_get_data' => ['array'], +'inet_ntop' => ['string|false', 'in_addr'=>'string'], +'inet_pton' => ['string|false', 'ip_address'=>'string'], +'InfiniteIterator::__construct' => ['void', 'it'=>'iterator'], +'InfiniteIterator::next' => ['void'], +'inflate_add' => ['string|false', 'context'=>'resource', 'encoded_data'=>'string', 'flush_mode='=>'int'], +'inflate_get_read_len' => ['int|false', 'resource'=>'resource'], +'inflate_get_status' => ['int|false', 'resource'=>'resource'], +'inflate_init' => ['resource|false', 'encoding'=>'int', 'options='=>'array'], +'ingres_autocommit' => ['bool', 'link'=>'resource'], +'ingres_autocommit_state' => ['bool', 'link'=>'resource'], +'ingres_charset' => ['string', 'link'=>'resource'], +'ingres_close' => ['bool', 'link'=>'resource'], +'ingres_commit' => ['bool', 'link'=>'resource'], +'ingres_connect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'options='=>'array'], +'ingres_cursor' => ['string', 'result'=>'resource'], +'ingres_errno' => ['int', 'link='=>'resource'], +'ingres_error' => ['string', 'link='=>'resource'], +'ingres_errsqlstate' => ['string', 'link='=>'resource'], +'ingres_escape_string' => ['string', 'link'=>'resource', 'source_string'=>'string'], +'ingres_execute' => ['bool', 'result'=>'resource', 'params='=>'array', 'types='=>'string'], +'ingres_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], +'ingres_fetch_assoc' => ['array', 'result'=>'resource'], +'ingres_fetch_object' => ['object', 'result'=>'resource', 'result_type='=>'int'], +'ingres_fetch_proc_return' => ['int', 'result'=>'resource'], +'ingres_fetch_row' => ['array', 'result'=>'resource'], +'ingres_field_length' => ['int', 'result'=>'resource', 'index'=>'int'], +'ingres_field_name' => ['string', 'result'=>'resource', 'index'=>'int'], +'ingres_field_nullable' => ['bool', 'result'=>'resource', 'index'=>'int'], +'ingres_field_precision' => ['int', 'result'=>'resource', 'index'=>'int'], +'ingres_field_scale' => ['int', 'result'=>'resource', 'index'=>'int'], +'ingres_field_type' => ['string', 'result'=>'resource', 'index'=>'int'], +'ingres_free_result' => ['bool', 'result'=>'resource'], +'ingres_next_error' => ['bool', 'link='=>'resource'], +'ingres_num_fields' => ['int', 'result'=>'resource'], +'ingres_num_rows' => ['int', 'result'=>'resource'], +'ingres_pconnect' => ['resource', 'database='=>'string', 'username='=>'string', 'password='=>'string', 'options='=>'array'], +'ingres_prepare' => ['mixed', 'link'=>'resource', 'query'=>'string'], +'ingres_query' => ['mixed', 'link'=>'resource', 'query'=>'string', 'params='=>'array', 'types='=>'string'], +'ingres_result_seek' => ['bool', 'result'=>'resource', 'position'=>'int'], +'ingres_rollback' => ['bool', 'link'=>'resource'], +'ingres_set_environment' => ['bool', 'link'=>'resource', 'options'=>'array'], +'ingres_unbuffered_query' => ['mixed', 'link'=>'resource', 'query'=>'string', 'params='=>'array', 'types='=>'string'], +'ini_alter' => ['string|false', 'varname'=>'string', 'newvalue'=>'string|int|float|bool'], +'ini_get' => ['string|false', 'varname'=>'string'], +'ini_get_all' => ['array', 'extension='=>'?string', 'details='=>'bool'], +'ini_restore' => ['void', 'varname'=>'string'], +'ini_set' => ['string|false', 'varname'=>'string', 'newvalue'=>'string|int|float|bool'], +'inotify_add_watch' => ['int', 'inotify_instance'=>'resource', 'pathname'=>'string', 'mask'=>'int'], +'inotify_init' => ['resource'], +'inotify_queue_len' => ['int', 'inotify_instance'=>'resource'], +'inotify_read' => ['array', 'inotify_instance'=>'resource'], +'inotify_rm_watch' => ['bool', 'inotify_instance'=>'resource', 'watch_descriptor'=>'int'], +'intdiv' => ['int', 'numerator'=>'int', 'divisor'=>'int'], +'interface_exists' => ['bool', 'classname'=>'string', 'autoload='=>'bool'], +'intl_error_name' => ['string', 'error_code'=>'int'], +'intl_get_error_code' => ['int'], +'intl_get_error_message' => ['string'], +'intl_is_failure' => ['bool', 'error_code'=>'int'], +'IntlBreakIterator::__construct' => ['void'], +'IntlBreakIterator::createCharacterInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], +'IntlBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'], +'IntlBreakIterator::createLineInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], +'IntlBreakIterator::createSentenceInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], +'IntlBreakIterator::createTitleInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], +'IntlBreakIterator::createWordInstance' => ['IntlRuleBasedBreakIterator', 'locale='=>'string'], +'IntlBreakIterator::current' => ['int'], +'IntlBreakIterator::first' => ['int'], +'IntlBreakIterator::following' => ['int', 'offset'=>'string'], +'IntlBreakIterator::getErrorCode' => ['int'], +'IntlBreakIterator::getErrorMessage' => ['string'], +'IntlBreakIterator::getLocale' => ['string', 'locale_type'=>'string'], +'IntlBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'string'], +'IntlBreakIterator::getText' => ['string'], +'IntlBreakIterator::isBoundary' => ['bool', 'offset'=>'string'], +'IntlBreakIterator::last' => ['int'], +'IntlBreakIterator::next' => ['int', 'offset='=>'int'], +'IntlBreakIterator::preceding' => ['int', 'offset'=>'int'], +'IntlBreakIterator::previous' => ['int'], +'IntlBreakIterator::setText' => ['bool', 'text'=>'string'], +'intlcal_add' => ['bool', 'cal'=>'IntlCalendar', 'field'=>'int', 'amount'=>'int'], +'intlcal_after' => ['bool', 'cal'=>'IntlCalendar', 'other'=>'IntlCalendar'], +'intlcal_before' => ['bool', 'cal'=>'IntlCalendar', 'other'=>'IntlCalendar'], +'intlcal_clear' => ['bool', 'cal'=>'IntlCalendar', 'field='=>'int'], +'intlcal_create_instance' => ['IntlCalendar', 'timeZone='=>'mixed', 'locale='=>'string'], +'intlcal_equals' => ['bool', 'cal'=>'IntlCalendar', 'other'=>'IntlCalendar'], +'intlcal_field_difference' => ['int', 'cal'=>'IntlCalendar', 'when'=>'float', 'field'=>'int'], +'intlcal_from_date_time' => ['IntlCalendar', 'dateTime'=>'DateTime|string'], +'intlcal_get' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], +'intlcal_get_actual_maximum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], +'intlcal_get_actual_minimum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], +'intlcal_get_available_locales' => ['array'], +'intlcal_get_day_of_week_type' => ['int', 'cal'=>'IntlCalendar', 'dayOfWeek'=>'int'], +'intlcal_get_first_day_of_week' => ['int', 'cal'=>'IntlCalendar'], +'intlcal_get_greatest_minimum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], +'intlcal_get_keyword_values_for_locale' => ['Iterator', 'key'=>'string', 'locale'=>'string', 'commonlyUsed'=>'bool'], +'intlcal_get_least_maximum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], +'intlcal_get_locale' => ['string', 'cal'=>'IntlCalendar', 'localeType'=>'int'], +'intlcal_get_maximum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], +'intlcal_get_minimal_days_in_first_week' => ['int', 'cal'=>'IntlCalendar'], +'intlcal_get_minimum' => ['int', 'cal'=>'IntlCalendar', 'field'=>'int'], +'intlcal_get_now' => ['float'], +'intlcal_get_repeated_wall_time_option' => ['int', 'cal'=>'IntlCalendar'], +'intlcal_get_skipped_wall_time_option' => ['int', 'cal'=>'IntlCalendar'], +'intlcal_get_time' => ['float', 'cal'=>'IntlCalendar'], +'intlcal_get_time_zone' => ['IntlTimeZone', 'cal'=>'IntlCalendar'], +'intlcal_get_type' => ['string', 'cal'=>'IntlCalendar'], +'intlcal_get_weekend_transition' => ['int', 'cal'=>'IntlCalendar', 'dayOfWeek'=>'string'], +'intlcal_in_daylight_time' => ['bool', 'cal'=>'IntlCalendar'], +'intlcal_is_equivalent_to' => ['bool', 'cal'=>'IntlCalendar', 'other'=>'IntlCalendar'], +'intlcal_is_lenient' => ['bool', 'cal'=>'IntlCalendar'], +'intlcal_is_set' => ['bool', 'cal'=>'IntlCalendar', 'field'=>'int'], +'intlcal_is_weekend' => ['bool', 'cal'=>'IntlCalendar', 'date='=>'float'], +'intlcal_roll' => ['bool', 'cal'=>'IntlCalendar', 'field'=>'int', 'amountOrUpOrDown'=>'mixed'], +'intlcal_set' => ['bool', 'cal'=>'IntlCalendar', 'field'=>'int', 'value'=>'int'], +'intlcal_set\'1' => ['bool', 'cal'=>'IntlCalendar', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'], +'intlcal_set_first_day_of_week' => ['bool', 'cal'=>'IntlCalendar', 'dayOfWeek'=>'int'], +'intlcal_set_lenient' => ['bool', 'cal'=>'IntlCalendar', 'isLenient'=>'bool'], +'intlcal_set_repeated_wall_time_option' => ['bool', 'cal'=>'IntlCalendar', 'wallTimeOption'=>'int'], +'intlcal_set_skipped_wall_time_option' => ['bool', 'cal'=>'IntlCalendar', 'wallTimeOption'=>'int'], +'intlcal_set_time' => ['bool', 'cal'=>'IntlCalendar', 'date'=>'float'], +'intlcal_set_time_zone' => ['bool', 'cal'=>'IntlCalendar', 'timeZone'=>'mixed'], +'intlcal_to_date_time' => ['DateTime', 'cal'=>'IntlCalendar'], +'IntlCalendar::__construct' => ['void'], +'IntlCalendar::add' => ['bool', 'field'=>'int', 'amount'=>'int'], +'IntlCalendar::after' => ['bool', 'other'=>'IntlCalendar'], +'IntlCalendar::before' => ['bool', 'other'=>'IntlCalendar'], +'IntlCalendar::clear' => ['bool', 'field='=>'int'], +'IntlCalendar::createInstance' => ['IntlCalendar', 'timeZone='=>'mixed', 'locale='=>'string'], +'IntlCalendar::equals' => ['bool', 'other'=>'IntlCalendar'], +'IntlCalendar::fieldDifference' => ['int', 'when'=>'float', 'field'=>'int'], +'IntlCalendar::fromDateTime' => ['IntlCalendar', 'dateTime'=>'DateTime|string'], +'IntlCalendar::get' => ['int', 'field'=>'int'], +'IntlCalendar::getActualMaximum' => ['int', 'field'=>'int'], +'IntlCalendar::getActualMinimum' => ['int', 'field'=>'int'], +'IntlCalendar::getAvailableLocales' => ['array'], +'IntlCalendar::getDayOfWeekType' => ['int', 'dayOfWeek'=>'int'], +'IntlCalendar::getErrorCode' => ['int'], +'IntlCalendar::getErrorMessage' => ['string'], +'IntlCalendar::getFirstDayOfWeek' => ['int'], +'IntlCalendar::getGreatestMinimum' => ['int', 'field'=>'int'], +'IntlCalendar::getKeywordValuesForLocale' => ['Iterator', 'key'=>'string', 'locale'=>'string', 'commonlyUsed'=>'bool'], +'IntlCalendar::getLeastMaximum' => ['int', 'field'=>'int'], +'IntlCalendar::getLocale' => ['string', 'localeType'=>'int'], +'IntlCalendar::getMaximum' => ['int', 'field'=>'int'], +'IntlCalendar::getMinimalDaysInFirstWeek' => ['int'], +'IntlCalendar::getMinimum' => ['int', 'field'=>'int'], +'IntlCalendar::getNow' => ['float'], +'IntlCalendar::getRepeatedWallTimeOption' => ['int'], +'IntlCalendar::getSkippedWallTimeOption' => ['int'], +'IntlCalendar::getTime' => ['float'], +'IntlCalendar::getTimeZone' => ['IntlTimeZone'], +'IntlCalendar::getType' => ['string'], +'IntlCalendar::getWeekendTransition' => ['int', 'dayOfWeek'=>'string'], +'IntlCalendar::inDaylightTime' => ['bool'], +'IntlCalendar::isEquivalentTo' => ['bool', 'other'=>'IntlCalendar'], +'IntlCalendar::isLenient' => ['bool'], +'IntlCalendar::isSet' => ['bool', 'field'=>'int'], +'IntlCalendar::isWeekend' => ['bool', 'date='=>'float'], +'IntlCalendar::roll' => ['bool', 'field'=>'int', 'amountOrUpOrDown'=>'mixed'], +'IntlCalendar::set' => ['bool', 'field'=>'int', 'value'=>'int'], +'IntlCalendar::set\'1' => ['bool', 'year'=>'int', 'month'=>'int', 'dayOfMonth='=>'int', 'hour='=>'int', 'minute='=>'int', 'second='=>'int'], +'IntlCalendar::setFirstDayOfWeek' => ['bool', 'dayOfWeek'=>'int'], +'IntlCalendar::setLenient' => ['bool', 'isLenient'=>'string'], +'IntlCalendar::setMinimalDaysInFirstWeek' => ['bool', 'minimalDays'=>'int'], +'IntlCalendar::setRepeatedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'], +'IntlCalendar::setSkippedWallTimeOption' => ['bool', 'wallTimeOption'=>'int'], +'IntlCalendar::setTime' => ['bool', 'date'=>'float'], +'IntlCalendar::setTimeZone' => ['bool', 'timeZone'=>'mixed'], +'IntlCalendar::toDateTime' => ['DateTime'], +'IntlChar::charAge' => ['array', 'char'=>'int|string'], +'IntlChar::charDigitValue' => ['int', 'codepoint'=>'mixed'], +'IntlChar::charDirection' => ['int', 'codepoint'=>'mixed'], +'IntlChar::charFromName' => ['int', 'name'=>'string', 'namechoice='=>'int'], +'IntlChar::charMirror' => ['mixed', 'codepoint'=>'mixed'], +'IntlChar::charName' => ['string', 'char'=>'int|string', 'namechoice='=>'int'], +'IntlChar::charType' => ['int', 'codepoint'=>'mixed'], +'IntlChar::chr' => ['string', 'codepoint'=>'mixed'], +'IntlChar::digit' => ['int', 'char'=>'int|string', 'radix='=>'int'], +'IntlChar::enumCharNames' => ['void', 'start'=>'mixed', 'limit'=>'mixed', 'callback'=>'callable', 'nameChoice='=>'int'], +'IntlChar::enumCharTypes' => ['void', 'cb='=>'callable'], +'IntlChar::foldCase' => ['int|string', 'char'=>'int|string', 'options='=>'int'], +'IntlChar::forDigit' => ['int', 'digit'=>'int', 'radix'=>'int'], +'IntlChar::getBidiPairedBracket' => ['mixed', 'codepoint'=>'mixed'], +'IntlChar::getBlockCode' => ['int', 'char'=>'int|string'], +'IntlChar::getCombiningClass' => ['int', 'codepoint'=>'mixed'], +'IntlChar::getFC_NFKC_Closure' => ['string', 'char'=>'int|string'], +'IntlChar::getIntPropertyMaxValue' => ['int', 'property'=>'int'], +'IntlChar::getIntPropertyMinValue' => ['int', 'property'=>'int'], +'IntlChar::getIntPropertyMxValue' => ['int', 'property'=>'int'], +'IntlChar::getIntPropertyValue' => ['int', 'char'=>'int|string', 'property'=>'int'], +'IntlChar::getNumericValue' => ['float', 'char'=>'int|string'], +'IntlChar::getPropertyEnum' => ['int', 'alias'=>'string'], +'IntlChar::getPropertyName' => ['string', 'property'=>'int', 'namechoice='=>'int'], +'IntlChar::getPropertyValueEnum' => ['int', 'property'=>'int', 'name'=>'string'], +'IntlChar::getPropertyValueName' => ['string', 'prop'=>'int', 'val'=>'int', 'namechoice='=>'int'], +'IntlChar::getUnicodeVersion' => ['array'], +'IntlChar::hasBinaryProperty' => ['bool', 'char'=>'int|string', 'property'=>'int'], +'IntlChar::isalnum' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isalpha' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isbase' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isblank' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::iscntrl' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isdefined' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isdigit' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isgraph' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isIDIgnorable' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isIDPart' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isIDStart' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isISOControl' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isJavaIDPart' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isJavaIDStart' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isJavaSpaceChar' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::islower' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isMirrored' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isprint' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::ispunct' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isspace' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::istitle' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isUAlphabetic' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isULowercase' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isupper' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isUUppercase' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isUWhiteSpace' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isWhitespace' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::isxdigit' => ['bool', 'codepoint'=>'mixed'], +'IntlChar::ord' => ['int', 'character'=>'mixed'], +'IntlChar::tolower' => ['mixed', 'codepoint'=>'mixed'], +'IntlChar::totitle' => ['mixed', 'codepoint'=>'mixed'], +'IntlChar::toupper' => ['mixed', 'codepoint'=>'mixed'], +'IntlCodePointBreakIterator::getLastCodePoint' => ['int'], +'IntlDateFormatter::__construct' => ['void', 'locale'=>'string', 'datetype'=>'?int', 'timetype'=>'?int', 'timezone='=>'null|string|IntlTimeZone|DateTimeZone', 'calendar='=>'null|int|IntlCalendar', 'pattern='=>'string'], +'IntlDateFormatter::create' => ['IntlDateFormatter', 'locale'=>'string', 'datetype'=>'int', 'timetype'=>'int', 'timezone='=>'null|string|IntlTimeZone|DateTimeZone', 'calendar='=>'int|IntlCalendar', 'pattern='=>'string'], +'IntlDateFormatter::format' => ['string', 'args'=>''], +'IntlDateFormatter::formatObject' => ['string', 'object'=>'object', 'format='=>'mixed', 'locale='=>'string'], +'IntlDateFormatter::getCalendar' => ['int'], +'IntlDateFormatter::getCalendarObject' => ['IntlCalendar'], +'IntlDateFormatter::getDateType' => ['int'], +'IntlDateFormatter::getErrorCode' => ['int'], +'IntlDateFormatter::getErrorMessage' => ['string'], +'IntlDateFormatter::getLocale' => ['string'], +'IntlDateFormatter::getPattern' => ['string'], +'IntlDateFormatter::getTimeType' => ['int'], +'IntlDateFormatter::getTimeZone' => ['IntlTimeZone'], +'IntlDateFormatter::getTimeZoneId' => ['string'], +'IntlDateFormatter::isLenient' => ['bool'], +'IntlDateFormatter::localtime' => ['array', 'text_to_parse'=>'string', '&w_parse_pos='=>'int'], +'IntlDateFormatter::parse' => ['int', 'text_to_parse'=>'string', '&rw_parse_pos='=>'int'], +'IntlDateFormatter::setCalendar' => ['bool', 'calendar'=>''], +'IntlDateFormatter::setLenient' => ['bool', 'lenient'=>'bool'], +'IntlDateFormatter::setPattern' => ['bool', 'pattern'=>'string'], +'IntlDateFormatter::setTimeZone' => ['bool', 'timezone'=>''], +'IntlDateFormatter::setTimeZoneId' => ['bool', 'zone'=>'string', 'fmt='=>'IntlDateFormatter'], +'IntlGregorianCalendar::getGregorianChange' => ['float'], +'IntlGregorianCalendar::isLeapYear' => ['bool', 'year'=>'int'], +'IntlGregorianCalendar::setGregorianChange' => ['bool', 'date'=>'float'], +'IntlIterator::current' => ['mixed'], +'IntlIterator::key' => ['string'], +'IntlIterator::next' => ['void'], +'IntlIterator::rewind' => ['void'], +'IntlIterator::valid' => ['bool'], +'IntlPartsIterator::getBreakIterator' => ['IntlBreakIterator'], +'IntlRuleBasedBreakIterator::__construct' => ['void', 'rules'=>'string', 'areCompiled='=>'string'], +'IntlRuleBasedBreakIterator::createCharacterInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], +'IntlRuleBasedBreakIterator::createCodePointInstance' => ['IntlCodePointBreakIterator'], +'IntlRuleBasedBreakIterator::createLineInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], +'IntlRuleBasedBreakIterator::createSentenceInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], +'IntlRuleBasedBreakIterator::createTitleInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], +'IntlRuleBasedBreakIterator::createWordInstance' => ['IntlRuleBasedBreakIterator', 'locale'=>'string'], +'IntlRuleBasedBreakIterator::current' => ['int'], +'IntlRuleBasedBreakIterator::first' => ['int'], +'IntlRuleBasedBreakIterator::following' => ['int', 'offset'=>'string'], +'IntlRuleBasedBreakIterator::getBinaryRules' => ['string'], +'IntlRuleBasedBreakIterator::getErrorCode' => ['int'], +'IntlRuleBasedBreakIterator::getErrorMessage' => ['string'], +'IntlRuleBasedBreakIterator::getLocale' => ['string', 'locale_type'=>'string'], +'IntlRuleBasedBreakIterator::getPartsIterator' => ['IntlPartsIterator', 'key_type='=>'string'], +'IntlRuleBasedBreakIterator::getRules' => ['string'], +'IntlRuleBasedBreakIterator::getRuleStatus' => ['int'], +'IntlRuleBasedBreakIterator::getRuleStatusVec' => ['array'], +'IntlRuleBasedBreakIterator::getText' => ['string'], +'IntlRuleBasedBreakIterator::isBoundary' => ['bool', 'offset'=>'string'], +'IntlRuleBasedBreakIterator::last' => ['int'], +'IntlRuleBasedBreakIterator::next' => ['int', 'offset='=>'string'], +'IntlRuleBasedBreakIterator::preceding' => ['int', 'offset'=>'string'], +'IntlRuleBasedBreakIterator::previous' => ['int'], +'IntlRuleBasedBreakIterator::setText' => ['bool', 'text'=>'string'], +'IntlTimeZone::countEquivalentIDs' => ['int', 'zoneId'=>'string'], +'IntlTimeZone::createDefault' => ['IntlTimeZone'], +'IntlTimeZone::createEnumeration' => ['IntlIterator', 'countryOrRawOffset='=>'mixed'], +'IntlTimeZone::createTimeZone' => ['IntlTimeZone', 'zoneId'=>'string'], +'IntlTimeZone::createTimeZoneIDEnumeration' => ['IntlIterator', 'zoneType'=>'int', 'region='=>'string', 'rawOffset='=>'int'], +'IntlTimeZone::fromDateTimeZone' => ['IntlTimeZone', 'zoneId'=>'DateTimeZone'], +'IntlTimeZone::getCanonicalID' => ['string', 'zoneId'=>'string', '&w_isSystemID='=>'bool'], +'IntlTimeZone::getDisplayName' => ['string', 'isDaylight='=>'bool', 'style='=>'int', 'locale='=>'string'], +'IntlTimeZone::getDSTSavings' => ['int'], +'IntlTimeZone::getEquivalentID' => ['string', 'zoneId'=>'string', 'index'=>'int'], +'IntlTimeZone::getErrorCode' => ['int'], +'IntlTimeZone::getErrorMessage' => ['string'], +'IntlTimeZone::getGMT' => ['IntlTimeZone'], +'IntlTimeZone::getID' => ['string'], +'IntlTimeZone::getIDForWindowsID' => ['string', 'timezone'=>'string', 'region='=>'string'], +'IntlTimeZone::getOffset' => ['int', 'date'=>'float', 'local'=>'bool', '&w_rawOffset'=>'int', '&w_dstOffset'=>'int'], +'IntlTimeZone::getRawOffset' => ['int'], +'IntlTimeZone::getRegion' => ['string', 'zoneId'=>'string'], +'IntlTimeZone::getTZDataVersion' => ['string'], +'IntlTimeZone::getUnknown' => ['IntlTimeZone'], +'IntlTimeZone::getWindowsID' => ['string', 'timezone'=>'string'], +'IntlTimeZone::hasSameRules' => ['bool', 'otherTimeZone'=>'IntlTimeZone'], +'IntlTimeZone::toDateTimeZone' => ['DateTimeZone'], +'IntlTimeZone::useDaylightTime' => ['bool'], +'intltz_count_equivalent_ids' => ['int', 'zoneId'=>'string'], +'intltz_create_enumeration' => ['IntlIterator', 'countryOrRawOffset'=>'mixed'], +'intltz_create_time_zone' => ['IntlTimeZone', 'zoneId'=>'string'], +'intltz_from_date_time_zone' => ['IntlTimeZone', 'zoneId'=>'DateTimeZone'], +'intltz_get_canonical_id' => ['string', 'zoneId'=>'string', '&isSystemID'=>'bool'], +'intltz_get_display_name' => ['string', 'obj'=>'IntlTimeZone', 'isDaylight'=>'bool', 'style'=>'int', 'locale'=>'string'], +'intltz_get_dst_savings' => ['int', 'obj'=>'IntlTimeZone'], +'intltz_get_equivalent_id' => ['string', 'zoneId'=>'string', 'index'=>'int'], +'intltz_get_error_code' => ['int', 'obj'=>'IntlTimeZone'], +'intltz_get_error_message' => ['string', 'obj'=>'IntlTimeZone'], +'intltz_get_id' => ['string', 'obj'=>'IntlTimeZone'], +'intltz_get_offset' => ['int', 'obj'=>'IntlTimeZone', 'date'=>'float', 'local'=>'bool', '&rawOffset'=>'int', '&dstOffset'=>'int'], +'intltz_get_raw_offset' => ['int', 'obj'=>'IntlTimeZone'], +'intltz_get_tz_data_version' => ['string', 'obj'=>'IntlTimeZone'], +'intltz_getGMT' => ['IntlTimeZone'], +'intltz_has_same_rules' => ['bool', 'obj'=>'IntlTimeZone', 'otherTimeZone'=>'IntlTimeZone'], +'intltz_to_date_time_zone' => ['DateTimeZone', 'obj'=>''], +'intltz_use_daylight_time' => ['bool', 'obj'=>''], +'intlz_create_default' => ['IntlTimeZone'], +'intval' => ['int', 'var'=>'mixed', 'base='=>'int'], +'InvalidArgumentException::__clone' => ['void'], +'InvalidArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?InvalidArgumentException'], +'InvalidArgumentException::__toString' => ['string'], +'InvalidArgumentException::getCode' => ['int'], +'InvalidArgumentException::getFile' => ['string'], +'InvalidArgumentException::getLine' => ['int'], +'InvalidArgumentException::getMessage' => ['string'], +'InvalidArgumentException::getPrevious' => ['Throwable|InvalidArgumentException|null'], +'InvalidArgumentException::getTrace' => ['array'], +'InvalidArgumentException::getTraceAsString' => ['string'], +'ip2long' => ['int|false', 'ip_address'=>'string'], +'iptcembed' => ['array', 'iptcdata'=>'string', 'jpeg_file_name'=>'string', 'spool='=>'int'], +'iptcparse' => ['array|false', 'iptcdata'=>'string'], +'is_a' => ['bool', 'object_or_string'=>'object|string', 'class_name'=>'string', 'allow_string='=>'bool'], +'is_array' => ['bool', 'var'=>'mixed'], +'is_bool' => ['bool', 'var'=>'mixed'], +'is_callable' => ['bool', 'var'=>'mixed', 'syntax_only='=>'bool', '&w_callable_name='=>'string'], +'is_countable' => ['bool', 'var'=>'mixed'], +'is_dir' => ['bool', 'filename'=>'string'], +'is_double' => ['bool', 'var'=>''], +'is_executable' => ['bool', 'filename'=>'string'], +'is_file' => ['bool', 'filename'=>'string'], +'is_finite' => ['bool', 'val'=>'float'], +'is_float' => ['bool', 'var'=>'mixed'], +'is_infinite' => ['bool', 'val'=>'float'], +'is_int' => ['bool', 'var'=>'mixed'], +'is_integer' => ['bool', 'var'=>''], +'is_iterable' => ['bool', 'var'=>'mixed'], +'is_link' => ['bool', 'filename'=>'string'], +'is_long' => ['bool', 'var'=>''], +'is_nan' => ['bool', 'val'=>'float'], +'is_null' => ['bool', 'var'=>'mixed'], +'is_numeric' => ['bool', 'value'=>'mixed'], +'is_object' => ['bool', 'var'=>'mixed'], +'is_readable' => ['bool', 'filename'=>'string'], +'is_real' => ['bool', 'var'=>''], +'is_resource' => ['bool', 'var'=>'mixed'], +'is_scalar' => ['bool', 'value'=>'mixed'], +'is_soap_fault' => ['bool', 'object'=>'mixed'], +'is_string' => ['bool', 'var'=>'mixed'], +'is_subclass_of' => ['bool', 'object_or_string'=>'object|string', 'class_name'=>'string', 'allow_string='=>'bool'], +'is_tainted' => ['bool', 'string'=>'string'], +'is_uploaded_file' => ['bool', 'path'=>'string'], +'is_writable' => ['bool', 'filename'=>'string'], +'is_writeable' => ['bool', 'filename'=>'string'], +'isset' => ['bool', 'var'=>'mixed', '...rest='=>'mixed'], +'Iterator::current' => ['mixed'], +'Iterator::key' => ['mixed'], +'Iterator::next' => ['void'], +'Iterator::rewind' => ['void'], +'Iterator::valid' => ['bool'], +'iterator_apply' => ['int', 'it'=>'Traversable', 'function'=>'callable', 'params='=>'array'], +'iterator_count' => ['int', 'it'=>'Traversable'], +'iterator_to_array' => ['array', 'it'=>'Traversable', 'use_keys='=>'bool'], +'IteratorAggregate::getIterator' => ['Traversable'], +'IteratorIterator::__construct' => ['void', 'it'=>'Traversable'], +'IteratorIterator::current' => ['mixed'], +'IteratorIterator::getInnerIterator' => ['Traversable'], +'IteratorIterator::key' => ['mixed'], +'IteratorIterator::next' => ['void'], +'IteratorIterator::rewind' => ['void'], +'IteratorIterator::valid' => ['bool'], +'java_last_exception_clear' => [''], +'java_last_exception_get' => ['object'], +'java_reload' => ['array', 'new_jarpath'=>'new_jarpath'], +'java_require' => ['array', 'new_classpath'=>'new_classpath'], +'java_set_encoding' => ['array', 'encoding'=>'encoding'], +'java_set_ignore_case' => ['void', 'ignore'=>'ignore'], +'java_throw_exceptions' => ['void', 'throw'=>'throw'], +'JavaException::getCause' => ['object'], +'jddayofweek' => ['mixed', 'juliandaycount'=>'int', 'mode='=>'int'], +'jdmonthname' => ['string', 'juliandaycount'=>'int', 'mode'=>'int'], +'jdtofrench' => ['string', 'juliandaycount'=>'int'], +'jdtogregorian' => ['string', 'juliandaycount'=>'int'], +'jdtojewish' => ['string', 'juliandaycount'=>'int', 'hebrew='=>'bool', 'fl='=>'int'], +'jdtojulian' => ['string', 'juliandaycount'=>'int'], +'jdtounix' => ['int|false', 'jday'=>'int'], +'jewishtojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], +'jobqueue_license_info' => ['array'], +'join' => ['string', 'glue'=>'string', 'pieces'=>'array'], +'join\'1' => ['string', 'pieces'=>'array'], +'jpeg2wbmp' => ['bool', 'jpegname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'], +'json_decode' => ['mixed', 'json'=>'string', 'assoc='=>'bool', 'depth='=>'int', 'options='=>'int'], +'json_encode' => ['string|false', 'data'=>'mixed', 'options='=>'int', 'depth='=>'int'], +'json_last_error' => ['int'], +'json_last_error_msg' => ['string'], +'JsonIncrementalParser::__construct' => ['void', 'depth'=>'', 'options'=>''], +'JsonIncrementalParser::get' => ['', 'options'=>''], +'JsonIncrementalParser::getError' => [''], +'JsonIncrementalParser::parse' => ['', 'json'=>''], +'JsonIncrementalParser::parseFile' => ['', 'filename'=>''], +'JsonIncrementalParser::reset' => [''], +'JsonSerializable::jsonSerialize' => ['mixed'], +'Judy::__construct' => ['void', 'judy_type'=>'int'], +'Judy::__destruct' => [''], +'Judy::byCount' => ['int', 'nth_index'=>'int'], +'Judy::count' => ['int', 'index_start='=>'int', 'index_end='=>'int'], +'Judy::first' => ['mixed', 'index='=>'mixed'], +'Judy::firstEmpty' => ['int', 'index='=>'mixed'], +'Judy::free' => ['int'], +'Judy::getType' => ['int'], +'Judy::last' => ['void', 'index='=>'string'], +'Judy::lastEmpty' => ['int', 'index='=>'int'], +'Judy::memoryUsage' => ['int'], +'Judy::next' => ['mixed', 'index'=>'mixed'], +'Judy::nextEmpty' => ['int', 'index'=>'int'], +'Judy::offsetExists' => ['bool', 'offset'=>'mixed'], +'Judy::offsetGet' => ['mixed', 'offset'=>'mixed'], +'Judy::offsetSet' => ['bool', 'offset'=>'mixed', 'value'=>'mixed'], +'Judy::offsetUnset' => ['bool', 'offset'=>'mixed'], +'Judy::prev' => ['mixed', 'index'=>'mixed'], +'Judy::prevEmpty' => ['int', 'index'=>'mixed'], +'Judy::size' => ['void'], +'judy_type' => ['int', 'array'=>'judy'], +'judy_version' => ['string'], +'juliantojd' => ['int', 'month'=>'int', 'day'=>'int', 'year'=>'int'], +'kadm5_chpass_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'password'=>'string'], +'kadm5_create_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'password='=>'string', 'options='=>'array'], +'kadm5_delete_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string'], +'kadm5_destroy' => ['bool', 'handle'=>'resource'], +'kadm5_flush' => ['bool', 'handle'=>'resource'], +'kadm5_get_policies' => ['array', 'handle'=>'resource'], +'kadm5_get_principal' => ['array', 'handle'=>'resource', 'principal'=>'string'], +'kadm5_get_principals' => ['array', 'handle'=>'resource'], +'kadm5_init_with_password' => ['resource', 'admin_server'=>'string', 'realm'=>'string', 'principal'=>'string', 'password'=>'string'], +'kadm5_modify_principal' => ['bool', 'handle'=>'resource', 'principal'=>'string', 'options'=>'array'], +'key' => ['int|string|null', 'array_arg'=>'array|object'], +'key_exists' => ['bool', 'key'=>'string|int', 'search'=>'array'], +'krsort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], +'ksort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], +'KTaglib_ID3v2_AttachedPictureFrame::getDescription' => ['string'], +'KTaglib_ID3v2_AttachedPictureFrame::getMimeType' => ['string'], +'KTaglib_ID3v2_AttachedPictureFrame::getType' => ['int'], +'KTaglib_ID3v2_AttachedPictureFrame::savePicture' => ['bool', 'filename'=>'string'], +'KTaglib_ID3v2_AttachedPictureFrame::setMimeType' => ['string', 'type'=>'string'], +'KTaglib_ID3v2_AttachedPictureFrame::setPicture' => ['', 'filename'=>'string'], +'KTaglib_ID3v2_AttachedPictureFrame::setType' => ['', 'type'=>'int'], +'KTaglib_ID3v2_Frame::__toString' => ['string'], +'KTaglib_ID3v2_Frame::getSize' => ['int'], +'KTaglib_ID3v2_Tag::addFrame' => ['bool', 'frame'=>'ktaglib_id3v2_frame'], +'KTaglib_ID3v2_Tag::getFrameList' => ['array'], +'KTaglib_MPEG_AudioProperties::getBitrate' => ['int'], +'KTaglib_MPEG_AudioProperties::getChannels' => ['int'], +'KTaglib_MPEG_AudioProperties::getLayer' => ['int'], +'KTaglib_MPEG_AudioProperties::getLength' => ['int'], +'KTaglib_MPEG_AudioProperties::getSampleBitrate' => ['int'], +'KTaglib_MPEG_AudioProperties::getVersion' => ['int'], +'KTaglib_MPEG_AudioProperties::isCopyrighted' => ['bool'], +'KTaglib_MPEG_AudioProperties::isOriginal' => ['bool'], +'KTaglib_MPEG_AudioProperties::isProtectionEnabled' => ['bool'], +'KTaglib_MPEG_File::getAudioProperties' => ['KTaglib_MPEG_File'], +'KTaglib_MPEG_File::getID3v1Tag' => ['KTaglib_ID3v1_Tag', 'create='=>'bool'], +'KTaglib_MPEG_File::getID3v2Tag' => ['KTaglib_ID3v2_Tag', 'create='=>'bool'], +'KTaglib_Tag::getAlbum' => ['string'], +'KTaglib_Tag::getArtist' => ['string'], +'KTaglib_Tag::getComment' => ['string'], +'KTaglib_Tag::getGenre' => ['string'], +'KTaglib_Tag::getTitle' => ['string'], +'KTaglib_Tag::getTrack' => ['int'], +'KTaglib_Tag::getYear' => ['int'], +'KTaglib_Tag::isEmpty' => ['bool'], +'labelcacheObj::freeCache' => ['bool'], +'labelObj::__construct' => ['void'], +'labelObj::convertToString' => ['string'], +'labelObj::deleteStyle' => ['int', 'index'=>'int'], +'labelObj::free' => ['void'], +'labelObj::getBinding' => ['string', 'labelbinding'=>'mixed'], +'labelObj::getExpressionString' => ['string'], +'labelObj::getStyle' => ['styleObj', 'index'=>'int'], +'labelObj::getTextString' => ['string'], +'labelObj::moveStyleDown' => ['int', 'index'=>'int'], +'labelObj::moveStyleUp' => ['int', 'index'=>'int'], +'labelObj::removeBinding' => ['int', 'labelbinding'=>'mixed'], +'labelObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'labelObj::setBinding' => ['int', 'labelbinding'=>'mixed', 'value'=>'string'], +'labelObj::setExpression' => ['int', 'expression'=>'string'], +'labelObj::setText' => ['int', 'text'=>'string'], +'labelObj::updateFromString' => ['int', 'snippet'=>'string'], +'Lapack::eigenValues' => ['array', 'a'=>'array', 'left='=>'array', 'right='=>'array'], +'Lapack::identity' => ['array', 'n'=>'int'], +'Lapack::leastSquaresByFactorisation' => ['array', 'a'=>'array', 'b'=>'array'], +'Lapack::leastSquaresBySVD' => ['array', 'a'=>'array', 'b'=>'array'], +'Lapack::pseudoInverse' => ['array', 'a'=>'array'], +'Lapack::singularValues' => ['array', 'a'=>'array'], +'Lapack::solveLinearEquation' => ['array', 'a'=>'array', 'b'=>'array'], +'layerObj::addFeature' => ['int', 'shape'=>'shapeObj'], +'layerObj::applySLD' => ['int', 'sldxml'=>'string', 'namedlayer'=>'string'], +'layerObj::applySLDURL' => ['int', 'sldurl'=>'string', 'namedlayer'=>'string'], +'layerObj::clearProcessing' => ['void'], +'layerObj::close' => ['void'], +'layerObj::convertToString' => ['string'], +'layerObj::draw' => ['int', 'image'=>'imageObj'], +'layerObj::drawQuery' => ['int', 'image'=>'imageObj'], +'layerObj::free' => ['void'], +'layerObj::generateSLD' => ['string'], +'layerObj::getClass' => ['classObj', 'classIndex'=>'int'], +'layerObj::getClassIndex' => ['int', 'shape'=>'', 'classgroup'=>'', 'numclasses'=>''], +'layerObj::getExtent' => ['rectObj'], +'layerObj::getFilterString' => ['string'], +'layerObj::getGridIntersectionCoordinates' => ['array'], +'layerObj::getItems' => ['array'], +'layerObj::getMetaData' => ['int', 'name'=>'string'], +'layerObj::getNumResults' => ['int'], +'layerObj::getProcessing' => ['array'], +'layerObj::getProjection' => ['string'], +'layerObj::getResult' => ['resultObj', 'index'=>'int'], +'layerObj::getResultsBounds' => ['rectObj'], +'layerObj::getShape' => ['shapeObj', 'result'=>'resultObj'], +'layerObj::getWMSFeatureInfoURL' => ['string', 'clickX'=>'int', 'clickY'=>'int', 'featureCount'=>'int', 'infoFormat'=>'string'], +'layerObj::isVisible' => ['bool'], +'layerObj::moveclassdown' => ['int', 'index'=>'int'], +'layerObj::moveclassup' => ['int', 'index'=>'int'], +'layerObj::ms_newLayerObj' => ['layerObj', 'map'=>'MapObj', 'layer'=>'layerObj'], +'layerObj::nextShape' => ['shapeObj'], +'layerObj::open' => ['int'], +'layerObj::queryByAttributes' => ['int', 'qitem'=>'string', 'qstring'=>'string', 'mode'=>'int'], +'layerObj::queryByFeatures' => ['int', 'slayer'=>'int'], +'layerObj::queryByPoint' => ['int', 'point'=>'pointObj', 'mode'=>'int', 'buffer'=>'float'], +'layerObj::queryByRect' => ['int', 'rect'=>'rectObj'], +'layerObj::queryByShape' => ['int', 'shape'=>'shapeObj'], +'layerObj::removeClass' => ['classObj', 'index'=>'int'], +'layerObj::removeMetaData' => ['int', 'name'=>'string'], +'layerObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'layerObj::setConnectionType' => ['int', 'connectiontype'=>'int', 'plugin_library'=>'string'], +'layerObj::setFilter' => ['int', 'expression'=>'string'], +'layerObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'], +'layerObj::setProjection' => ['int', 'proj_params'=>'string'], +'layerObj::setWKTProjection' => ['int', 'proj_params'=>'string'], +'layerObj::updateFromString' => ['int', 'snippet'=>'string'], +'lcfirst' => ['string', 'str'=>'string'], +'lcg_value' => ['float'], +'lchgrp' => ['bool', 'filename'=>'string', 'group'=>'string|int'], +'lchown' => ['bool', 'filename'=>'string', 'user'=>'string|int'], +'ldap_8859_to_t61' => ['string', 'value'=>'string'], +'ldap_add' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array'], +'ldap_bind' => ['bool', 'link_identifier'=>'resource', 'dn='=>'string', 'password='=>'string'], +'ldap_close' => ['bool', 'link_identifier'=>'resource'], +'ldap_compare' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'attr'=>'string', 'value'=>'string'], +'ldap_connect' => ['resource|false', 'host='=>'string', 'port='=>'int', 'wallet='=>'string', 'wallet_passwd='=>'string', 'authmode='=>'int'], +'ldap_control_paged_result' => ['bool', 'link_identifier'=>'resource', 'pagesize'=>'int', 'iscritical'=>'bool', 'cookie'=>'string'], +'ldap_control_paged_result_response' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', '&w_cookie='=>'string', '&w_estimated='=>'int'], +'ldap_count_entries' => ['int', 'link_identifier'=>'resource', 'result'=>'resource'], +'ldap_delete' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string'], +'ldap_dn2ufn' => ['string', 'dn'=>'string'], +'ldap_err2str' => ['string', 'errno'=>'int'], +'ldap_errno' => ['int', 'link_identifier'=>'resource'], +'ldap_error' => ['string', 'link_identifier'=>'resource'], +'ldap_escape' => ['string', 'value'=>'string', 'ignore='=>'string', 'flags='=>'int'], +'ldap_exop' => ['mixed', 'link'=>'resource', 'reqoid'=>'string', 'reqdata='=>'string', 'servercontrols='=>'array', 'retdata='=>'string', 'retoid='=>'string'], +'ldap_exop_passwd' => ['mixed', 'link'=>'resource', 'user='=>'string', 'oldpw='=>'string', 'newpw='=>'string', 'serverctrls='=>'array'], +'ldap_exop_refresh' => ['int', 'link'=>'resource', 'dn'=>'string', 'ttl'=>'int'], +'ldap_exop_whoami' => ['string', 'link'=>'resource'], +'ldap_explode_dn' => ['array', 'dn'=>'string', 'with_attrib'=>'int'], +'ldap_first_attribute' => ['string', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], +'ldap_first_entry' => ['resource|false', 'link_identifier'=>'resource', 'result_identifier'=>'resource'], +'ldap_first_reference' => ['resource|false', 'link_identifier'=>'resource', 'result_identifier'=>'resource'], +'ldap_free_result' => ['bool', 'result_identifier'=>'resource'], +'ldap_get_attributes' => ['array', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], +'ldap_get_dn' => ['string', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], +'ldap_get_entries' => ['array', 'link_identifier'=>'resource', 'result_identifier'=>'resource'], +'ldap_get_option' => ['bool', 'link_identifier'=>'resource', 'option'=>'int', '&w_retval'=>'mixed'], +'ldap_get_values' => ['array', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource', 'attribute'=>'string'], +'ldap_get_values_len' => ['array', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource', 'attribute'=>'string'], +'ldap_list' => ['resource|false', 'link'=>'resource|array', 'base_dn'=>'string', 'filter'=>'string', 'attrs='=>'array', 'attrsonly='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'], +'ldap_mod_add' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array'], +'ldap_mod_del' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array'], +'ldap_mod_replace' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array'], +'ldap_modify' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'entry'=>'array'], +'ldap_modify_batch' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'modifs'=>'array'], +'ldap_next_attribute' => ['string', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], +'ldap_next_entry' => ['resource|false', 'link_identifier'=>'resource', 'result_entry_identifier'=>'resource'], +'ldap_next_reference' => ['resource|false', 'link_identifier'=>'resource', 'reference_entry_identifier'=>'resource'], +'ldap_parse_exop' => ['bool', 'link'=>'resource', 'result'=>'resource', 'retdata='=>'string', 'retoid='=>'string'], +'ldap_parse_reference' => ['bool', 'link_identifier'=>'resource', 'reference_entry_identifier'=>'resource', 'referrals'=>'array'], +'ldap_parse_result' => ['bool', 'link_identifier'=>'resource', 'result'=>'resource', 'errcode'=>'int', 'matcheddn='=>'string', 'errmsg='=>'string', 'referrals='=>'array'], +'ldap_read' => ['resource|false', 'link'=>'resource|array', 'base_dn'=>'string', 'filter'=>'string', 'attrs='=>'array', 'attrsonly='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'], +'ldap_rename' => ['bool', 'link_identifier'=>'resource', 'dn'=>'string', 'newrdn'=>'string', 'newparent'=>'string', 'deleteoldrdn'=>'bool'], +'ldap_sasl_bind' => ['bool', 'link_identifier'=>'resource', 'binddn='=>'string', 'password='=>'string', 'sasl_mech='=>'string', 'sasl_realm='=>'string', 'sasl_authc_id='=>'string', 'sasl_authz_id='=>'string', 'props='=>'string'], +'ldap_search' => ['resource|false', 'link_identifier'=>'resource|array', 'base_dn'=>'string', 'filter'=>'string', 'attrs='=>'array', 'attrsonly='=>'int', 'sizelimit='=>'int', 'timelimit='=>'int', 'deref='=>'int'], +'ldap_set_option' => ['bool', 'link_identifier'=>'resource', 'option'=>'int', 'newval'=>'mixed'], +'ldap_set_rebind_proc' => ['bool', 'link_identifier'=>'resource', 'callback'=>'string'], +'ldap_sort' => ['bool', 'link_identifier'=>'resource', 'result_identifier'=>'resource', 'sortfilter'=>'string'], +'ldap_start_tls' => ['bool', 'link_identifier'=>'resource'], +'ldap_t61_to_8859' => ['string', 'value'=>'string'], +'ldap_unbind' => ['bool', 'link_identifier'=>'resource'], +'leak' => ['', 'num_bytes'=>'int'], +'leak_variable' => ['', 'variable'=>'', 'leak_data'=>'bool'], +'legendObj::convertToString' => ['string'], +'legendObj::free' => ['void'], +'legendObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'legendObj::updateFromString' => ['int', 'snippet'=>'string'], +'LengthException::__clone' => ['void'], +'LengthException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?LengthException'], +'LengthException::__toString' => ['string'], +'LengthException::getCode' => ['int'], +'LengthException::getFile' => ['string'], +'LengthException::getLine' => ['int'], +'LengthException::getMessage' => ['string'], +'LengthException::getPrevious' => ['Throwable|LengthException|null'], +'LengthException::getTrace' => ['array'], +'LengthException::getTraceAsString' => ['string'], +'levenshtein' => ['int', 'str1'=>'string', 'str2'=>'string'], +'levenshtein\'1' => ['int', 'str1'=>'string', 'str2'=>'string', 'cost_ins'=>'int', 'cost_rep'=>'int', 'cost_del'=>'int'], +'libxml_clear_errors' => ['void'], +'libxml_disable_entity_loader' => ['bool', 'disable='=>'bool'], +'libxml_get_errors' => ['array'], +'libxml_get_last_error' => ['libXMLError|false'], +'libxml_set_external_entity_loader' => ['bool', 'resolver_function'=>'callable'], +'libxml_set_streams_context' => ['void', 'streams_context'=>'resource'], +'libxml_use_internal_errors' => ['bool', 'use_errors='=>'bool'], +'LimitIterator::__construct' => ['void', 'iterator'=>'Iterator', 'offset='=>'int', 'count='=>'int'], +'LimitIterator::current' => ['mixed'], +'LimitIterator::getInnerIterator' => ['Iterator'], +'LimitIterator::getPosition' => ['int'], +'LimitIterator::key' => ['mixed'], +'LimitIterator::next' => ['void'], +'LimitIterator::rewind' => ['void'], +'LimitIterator::seek' => ['int', 'position'=>'int'], +'LimitIterator::valid' => ['bool'], +'lineObj::__construct' => ['void'], +'lineObj::add' => ['int', 'point'=>'pointObj'], +'lineObj::addXY' => ['int', 'x'=>'float', 'y'=>'float', 'm'=>'float'], +'lineObj::addXYZ' => ['int', 'x'=>'float', 'y'=>'float', 'z'=>'float', 'm'=>'float'], +'lineObj::ms_newLineObj' => ['lineObj'], +'lineObj::point' => ['pointObj', 'i'=>'int'], +'lineObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'], +'link' => ['bool', 'target'=>'string', 'link'=>'string'], +'linkinfo' => ['int', 'filename'=>'string'], +'litespeed_request_headers' => ['array'], +'litespeed_response_headers' => ['array'], +'Locale::acceptFromHttp' => ['string|false', 'header'=>'string'], +'Locale::canonicalize' => ['string', 'locale'=>'string'], +'Locale::composeLocale' => ['string', 'subtags'=>'array'], +'Locale::filterMatches' => ['bool', 'langtag'=>'string', 'locale'=>'string', 'canonicalize='=>'bool'], +'Locale::getAllVariants' => ['array', 'locale'=>'string'], +'Locale::getDefault' => ['string'], +'Locale::getDisplayLanguage' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'Locale::getDisplayName' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'Locale::getDisplayRegion' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'Locale::getDisplayScript' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'Locale::getDisplayVariant' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'Locale::getKeywords' => ['array|false', 'locale'=>'string'], +'Locale::getPrimaryLanguage' => ['string', 'locale'=>'string'], +'Locale::getRegion' => ['string', 'locale'=>'string'], +'Locale::getScript' => ['string', 'locale'=>'string'], +'Locale::lookup' => ['string', 'langtag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'default='=>'string'], +'Locale::parseLocale' => ['array', 'locale'=>'string'], +'Locale::setDefault' => ['bool', 'locale'=>'string'], +'locale_accept_from_http' => ['string|false', 'header'=>'string'], +'locale_canonicalize' => ['', 'arg1'=>''], +'locale_compose' => ['string|false', 'subtags'=>'array'], +'locale_filter_matches' => ['bool', 'langtag'=>'string', 'locale'=>'string', 'canonicalize='=>'bool'], +'locale_get_all_variants' => ['array', 'locale'=>'string'], +'locale_get_default' => ['string'], +'locale_get_display_language' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'locale_get_display_name' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'locale_get_display_region' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'locale_get_display_script' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'locale_get_display_variant' => ['string', 'locale'=>'string', 'in_locale='=>'string'], +'locale_get_keywords' => ['array|false', 'locale'=>'string'], +'locale_get_primary_language' => ['string', 'locale'=>'string'], +'locale_get_region' => ['string', 'locale'=>'string'], +'locale_get_script' => ['string', 'locale'=>'string'], +'locale_lookup' => ['string', 'langtag'=>'array', 'locale'=>'string', 'canonicalize='=>'bool', 'default='=>'string'], +'locale_parse' => ['array', 'locale'=>'string'], +'locale_set_default' => ['bool', 'locale'=>'string'], +'localeconv' => ['array'], +'localtime' => ['array', 'timestamp='=>'int', 'associative_array='=>'bool'], +'log' => ['float', 'number'=>'float', 'base='=>'float'], +'log10' => ['float', 'number'=>'float'], +'log1p' => ['float', 'number'=>'float'], +'LogicException::__clone' => ['void'], +'LogicException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?LogicException'], +'LogicException::__toString' => ['string'], +'LogicException::getCode' => ['int'], +'LogicException::getFile' => ['string'], +'LogicException::getLine' => ['int'], +'LogicException::getMessage' => ['string'], +'LogicException::getPrevious' => ['Throwable|LogicException|null'], +'LogicException::getTrace' => ['array'], +'LogicException::getTraceAsString' => ['string'], +'long2ip' => ['string', 'proper_address'=>'int'], +'lstat' => ['array|false', 'filename'=>'string'], +'ltrim' => ['string', 'str'=>'string', 'character_mask='=>'string'], +'Lua::__call' => ['mixed', 'lua_func'=>'callable', 'args='=>'array', 'use_self='=>'int'], +'Lua::__construct' => ['void', 'lua_script_file'=>'string'], +'Lua::assign' => ['mixed', 'name'=>'string', 'value'=>'string'], +'Lua::call' => ['mixed', 'lua_func'=>'callable', 'args='=>'array', 'use_self='=>'int'], +'Lua::eval' => ['mixed', 'statements'=>'string'], +'Lua::getVersion' => ['string'], +'Lua::include' => ['mixed', 'file'=>'string'], +'Lua::registerCallback' => ['mixed', 'name'=>'string', 'function'=>'callable'], +'LuaClosure::__invoke' => ['void', 'arg'=>'mixed', '...args='=>'mixed'], +'lzf_compress' => ['string', 'data'=>'string'], +'lzf_decompress' => ['string', 'data'=>'string'], +'lzf_optimized_for' => ['int'], +'m_checkstatus' => ['int', 'conn'=>'resource', 'identifier'=>'int'], +'m_completeauthorizations' => ['int', 'conn'=>'resource', 'array'=>'int'], +'m_connect' => ['int', 'conn'=>'resource'], +'m_connectionerror' => ['string', 'conn'=>'resource'], +'m_deletetrans' => ['bool', 'conn'=>'resource', 'identifier'=>'int'], +'m_destroyconn' => ['bool', 'conn'=>'resource'], +'m_destroyengine' => ['void'], +'m_getcell' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column'=>'string', 'row'=>'int'], +'m_getcellbynum' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column'=>'int', 'row'=>'int'], +'m_getcommadelimited' => ['string', 'conn'=>'resource', 'identifier'=>'int'], +'m_getheader' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'column_num'=>'int'], +'m_initconn' => ['resource'], +'m_initengine' => ['int', 'location'=>'string'], +'m_iscommadelimited' => ['int', 'conn'=>'resource', 'identifier'=>'int'], +'m_maxconntimeout' => ['bool', 'conn'=>'resource', 'secs'=>'int'], +'m_monitor' => ['int', 'conn'=>'resource'], +'m_numcolumns' => ['int', 'conn'=>'resource', 'identifier'=>'int'], +'m_numrows' => ['int', 'conn'=>'resource', 'identifier'=>'int'], +'m_parsecommadelimited' => ['int', 'conn'=>'resource', 'identifier'=>'int'], +'m_responsekeys' => ['array', 'conn'=>'resource', 'identifier'=>'int'], +'m_responseparam' => ['string', 'conn'=>'resource', 'identifier'=>'int', 'key'=>'string'], +'m_returnstatus' => ['int', 'conn'=>'resource', 'identifier'=>'int'], +'m_setblocking' => ['int', 'conn'=>'resource', 'tf'=>'int'], +'m_setdropfile' => ['int', 'conn'=>'resource', 'directory'=>'string'], +'m_setip' => ['int', 'conn'=>'resource', 'host'=>'string', 'port'=>'int'], +'m_setssl' => ['int', 'conn'=>'resource', 'host'=>'string', 'port'=>'int'], +'m_setssl_cafile' => ['int', 'conn'=>'resource', 'cafile'=>'string'], +'m_setssl_files' => ['int', 'conn'=>'resource', 'sslkeyfile'=>'string', 'sslcertfile'=>'string'], +'m_settimeout' => ['int', 'conn'=>'resource', 'seconds'=>'int'], +'m_sslcert_gen_hash' => ['string', 'filename'=>'string'], +'m_transactionssent' => ['int', 'conn'=>'resource'], +'m_transinqueue' => ['int', 'conn'=>'resource'], +'m_transkeyval' => ['int', 'conn'=>'resource', 'identifier'=>'int', 'key'=>'string', 'value'=>'string'], +'m_transnew' => ['int', 'conn'=>'resource'], +'m_transsend' => ['int', 'conn'=>'resource', 'identifier'=>'int'], +'m_uwait' => ['int', 'microsecs'=>'int'], +'m_validateidentifier' => ['int', 'conn'=>'resource', 'tf'=>'int'], +'m_verifyconnection' => ['bool', 'conn'=>'resource', 'tf'=>'int'], +'m_verifysslcert' => ['bool', 'conn'=>'resource', 'tf'=>'int'], +'magic_quotes_runtime' => ['', 'new_setting'=>''], +'mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string', 'additional_parameters='=>'string'], +'mailparse_determine_best_xfer_encoding' => ['string', 'fp'=>'resource'], +'mailparse_msg_create' => ['resource'], +'mailparse_msg_extract_part' => ['void', 'mimemail'=>'resource', 'msgbody'=>'string', 'callbackfunc='=>'callable'], +'mailparse_msg_extract_part_file' => ['string', 'mimemail'=>'resource', 'filename'=>'mixed', 'callbackfunc='=>'callable'], +'mailparse_msg_extract_whole_part_file' => ['string', 'mimemail'=>'resource', 'filename'=>'string', 'callbackfunc='=>'callable'], +'mailparse_msg_free' => ['bool', 'mimemail'=>'resource'], +'mailparse_msg_get_part' => ['resource', 'mimemail'=>'resource', 'mimesection'=>'string'], +'mailparse_msg_get_part_data' => ['array', 'mimemail'=>'resource'], +'mailparse_msg_get_structure' => ['array', 'mimemail'=>'resource'], +'mailparse_msg_parse' => ['bool', 'mimemail'=>'resource', 'data'=>'string'], +'mailparse_msg_parse_file' => ['resource', 'filename'=>'string'], +'mailparse_rfc822_parse_addresses' => ['array', 'addresses'=>'string'], +'mailparse_stream_encode' => ['bool', 'sourcefp'=>'resource', 'destfp'=>'resource', 'encoding'=>'string'], +'mailparse_uudecode_all' => ['array', 'fp'=>'resource'], +'mapObj::__construct' => ['void', 'map_file_name'=>'string', 'new_map_path'=>'string'], +'mapObj::appendOutputFormat' => ['int', 'outputFormat'=>'outputformatObj'], +'mapObj::applyconfigoptions' => ['int'], +'mapObj::applySLD' => ['int', 'sldxml'=>'string'], +'mapObj::applySLDURL' => ['int', 'sldurl'=>'string'], +'mapObj::convertToString' => ['string'], +'mapObj::draw' => ['imageObj'], +'mapObj::drawLabelCache' => ['int', 'image'=>'imageObj'], +'mapObj::drawLegend' => ['imageObj'], +'mapObj::drawQuery' => ['imageObj'], +'mapObj::drawReferenceMap' => ['imageObj'], +'mapObj::drawScaleBar' => ['imageObj'], +'mapObj::embedLegend' => ['int', 'image'=>'imageObj'], +'mapObj::embedScalebar' => ['int', 'image'=>'imageObj'], +'mapObj::free' => ['void'], +'mapObj::generateSLD' => ['string'], +'mapObj::getAllGroupNames' => ['array'], +'mapObj::getAllLayerNames' => ['array'], +'mapObj::getColorbyIndex' => ['colorObj', 'iCloIndex'=>'int'], +'mapObj::getConfigOption' => ['string', 'key'=>'string'], +'mapObj::getLabel' => ['labelcacheMemberObj', 'index'=>'int'], +'mapObj::getLayer' => ['layerObj', 'index'=>'int'], +'mapObj::getLayerByName' => ['layerObj', 'layer_name'=>'string'], +'mapObj::getLayersDrawingOrder' => ['array'], +'mapObj::getLayersIndexByGroup' => ['array', 'groupname'=>'string'], +'mapObj::getMetaData' => ['int', 'name'=>'string'], +'mapObj::getNumSymbols' => ['int'], +'mapObj::getOutputFormat' => ['outputformatObj', 'index'=>'int'], +'mapObj::getProjection' => ['string'], +'mapObj::getSymbolByName' => ['int', 'symbol_name'=>'string'], +'mapObj::getSymbolObjectById' => ['symbolObj', 'symbolid'=>'int'], +'mapObj::loadMapContext' => ['int', 'filename'=>'string', 'unique_layer_name'=>'bool'], +'mapObj::loadOWSParameters' => ['int', 'request'=>'OwsrequestObj', 'version'=>'string'], +'mapObj::moveLayerDown' => ['int', 'layerindex'=>'int'], +'mapObj::moveLayerUp' => ['int', 'layerindex'=>'int'], +'mapObj::ms_newMapObjFromString' => ['MapObj', 'map_file_string'=>'string', 'new_map_path'=>'string'], +'mapObj::offsetExtent' => ['int', 'x'=>'float', 'y'=>'float'], +'mapObj::owsDispatch' => ['int', 'request'=>'OwsrequestObj'], +'mapObj::prepareImage' => ['imageObj'], +'mapObj::prepareQuery' => ['void'], +'mapObj::processLegendTemplate' => ['string', 'params'=>'array'], +'mapObj::processQueryTemplate' => ['string', 'params'=>'array', 'generateimages'=>'bool'], +'mapObj::processTemplate' => ['string', 'params'=>'array', 'generateimages'=>'bool'], +'mapObj::queryByFeatures' => ['int', 'slayer'=>'int'], +'mapObj::queryByIndex' => ['int', 'layerindex'=>'', 'tileindex'=>'', 'shapeindex'=>'', 'addtoquery'=>''], +'mapObj::queryByPoint' => ['int', 'point'=>'pointObj', 'mode'=>'int', 'buffer'=>'float'], +'mapObj::queryByRect' => ['int', 'rect'=>'rectObj'], +'mapObj::queryByShape' => ['int', 'shape'=>'shapeObj'], +'mapObj::removeLayer' => ['layerObj', 'nIndex'=>'int'], +'mapObj::removeMetaData' => ['int', 'name'=>'string'], +'mapObj::removeOutputFormat' => ['int', 'name'=>'string'], +'mapObj::save' => ['int', 'filename'=>'string'], +'mapObj::saveMapContext' => ['int', 'filename'=>'string'], +'mapObj::saveQuery' => ['int', 'filename'=>'string', 'results'=>'int'], +'mapObj::scaleExtent' => ['int', 'zoomfactor'=>'float', 'minscaledenom'=>'float', 'maxscaledenom'=>'float'], +'mapObj::selectOutputFormat' => ['int', 'type'=>'string'], +'mapObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'mapObj::setCenter' => ['int', 'center'=>'pointObj'], +'mapObj::setConfigOption' => ['int', 'key'=>'string', 'value'=>'string'], +'mapObj::setExtent' => ['void', 'minx'=>'float', 'miny'=>'float', 'maxx'=>'float', 'maxy'=>'float'], +'mapObj::setFontSet' => ['int', 'fileName'=>'string'], +'mapObj::setMetaData' => ['int', 'name'=>'string', 'value'=>'string'], +'mapObj::setProjection' => ['int', 'proj_params'=>'string', 'bSetUnitsAndExtents'=>'bool'], +'mapObj::setRotation' => ['int', 'rotation_angle'=>'float'], +'mapObj::setSize' => ['int', 'width'=>'int', 'height'=>'int'], +'mapObj::setSymbolSet' => ['int', 'fileName'=>'string'], +'mapObj::setWKTProjection' => ['int', 'proj_params'=>'string', 'bSetUnitsAndExtents'=>'bool'], +'mapObj::zoomPoint' => ['int', 'nZoomFactor'=>'int', 'oPixelPos'=>'pointObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj'], +'mapObj::zoomRectangle' => ['int', 'oPixelExt'=>'rectObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj'], +'mapObj::zoomScale' => ['int', 'nScaleDenom'=>'float', 'oPixelPos'=>'pointObj', 'nImageWidth'=>'int', 'nImageHeight'=>'int', 'oGeorefExt'=>'rectObj', 'oMaxGeorefExt'=>'rectObj'], +'max' => ['', '...arg1'=>'array'], +'max\'1' => ['', 'arg1'=>'', 'arg2'=>'', '...args='=>''], +'maxdb::__construct' => ['void', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], +'maxdb::affected_rows' => ['int', 'link'=>''], +'maxdb::auto_commit' => ['bool', 'link'=>'', 'mode'=>'bool'], +'maxdb::change_user' => ['bool', 'link'=>'', 'user'=>'string', 'password'=>'string', 'database'=>'string'], +'maxdb::character_set_name' => ['string', 'link'=>''], +'maxdb::close' => ['bool', 'link'=>''], +'maxdb::commit' => ['bool', 'link'=>''], +'maxdb::disable_reads_from_master' => ['', 'link'=>''], +'maxdb::errno' => ['int', 'link'=>''], +'maxdb::error' => ['string', 'link'=>''], +'maxdb::field_count' => ['int', 'link'=>''], +'maxdb::get_host_info' => ['string', 'link'=>''], +'maxdb::info' => ['string', 'link'=>''], +'maxdb::insert_id' => ['', 'link'=>''], +'maxdb::kill' => ['bool', 'link'=>'', 'processid'=>'int'], +'maxdb::more_results' => ['bool', 'link'=>''], +'maxdb::multi_query' => ['bool', 'link'=>'', 'query'=>'string'], +'maxdb::next_result' => ['bool', 'link'=>''], +'maxdb::num_rows' => ['int', 'result'=>''], +'maxdb::options' => ['bool', 'link'=>'', 'option'=>'int', 'value'=>''], +'maxdb::ping' => ['bool', 'link'=>''], +'maxdb::prepare' => ['maxdb_stmt', 'link'=>'', 'query'=>'string'], +'maxdb::protocol_version' => ['string', 'link'=>''], +'maxdb::query' => ['', 'link'=>'', 'query'=>'string', 'resultmode='=>'int'], +'maxdb::real_connect' => ['bool', 'link'=>'', 'hostname='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], +'maxdb::real_escape_string' => ['string', 'link'=>'', 'escapestr'=>'string'], +'maxdb::real_query' => ['bool', 'link'=>'', 'query'=>'string'], +'maxdb::rollback' => ['bool', 'link'=>''], +'maxdb::rpl_query_type' => ['int', 'link'=>''], +'maxdb::select_db' => ['bool', 'link'=>'', 'dbname'=>'string'], +'maxdb::send_query' => ['bool', 'link'=>'', 'query'=>'string'], +'maxdb::server_info' => ['string', 'link'=>''], +'maxdb::server_version' => ['int', 'link'=>''], +'maxdb::sqlstate' => ['string', 'link'=>''], +'maxdb::ssl_set' => ['bool', 'link'=>'', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], +'maxdb::stat' => ['string', 'link'=>''], +'maxdb::stmt_init' => ['object', 'link'=>''], +'maxdb::store_result' => ['bool', 'link'=>''], +'maxdb::thread_id' => ['int', 'link'=>''], +'maxdb::use_result' => ['resource', 'link'=>''], +'maxdb::warning_count' => ['int', 'link'=>''], +'maxdb_affected_rows' => ['int', 'link'=>'resource'], +'maxdb_autocommit' => ['bool', 'link'=>'', 'mode'=>'bool'], +'maxdb_change_user' => ['bool', 'link'=>'', 'user'=>'string', 'password'=>'string', 'database'=>'string'], +'maxdb_character_set_name' => ['string', 'link'=>''], +'maxdb_close' => ['bool', 'link'=>''], +'maxdb_commit' => ['bool', 'link'=>''], +'maxdb_connect' => ['resource', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], +'maxdb_connect_errno' => ['int'], +'maxdb_connect_error' => ['string'], +'maxdb_data_seek' => ['bool', 'result'=>'', 'offset'=>'int'], +'maxdb_debug' => ['void', 'debug'=>'string'], +'maxdb_disable_reads_from_master' => ['', 'link'=>''], +'maxdb_disable_rpl_parse' => ['bool', 'link'=>'resource'], +'maxdb_dump_debug_info' => ['bool', 'link'=>'resource'], +'maxdb_embedded_connect' => ['resource', 'dbname='=>'string'], +'maxdb_enable_reads_from_master' => ['bool', 'link'=>'resource'], +'maxdb_enable_rpl_parse' => ['bool', 'link'=>'resource'], +'maxdb_errno' => ['int', 'link'=>'resource'], +'maxdb_error' => ['string', 'link'=>'resource'], +'maxdb_fetch_array' => ['', 'result'=>'', 'resulttype='=>'int'], +'maxdb_fetch_assoc' => ['array', 'result'=>''], +'maxdb_fetch_field' => ['', 'result'=>''], +'maxdb_fetch_field_direct' => ['', 'result'=>'', 'fieldnr'=>'int'], +'maxdb_fetch_fields' => ['', 'result'=>''], +'maxdb_fetch_lengths' => ['array', 'result'=>'resource'], +'maxdb_fetch_object' => ['object', 'result'=>'object'], +'maxdb_fetch_row' => ['', 'result'=>''], +'maxdb_field_count' => ['int', 'link'=>''], +'maxdb_field_seek' => ['bool', 'result'=>'', 'fieldnr'=>'int'], +'maxdb_field_tell' => ['int', 'result'=>'resource'], +'maxdb_free_result' => ['', 'result'=>''], +'maxdb_get_client_info' => ['string'], +'maxdb_get_client_version' => ['int'], +'maxdb_get_host_info' => ['string', 'link'=>'resource'], +'maxdb_get_proto_info' => ['string', 'link'=>'resource'], +'maxdb_get_server_info' => ['string', 'link'=>'resource'], +'maxdb_get_server_version' => ['int', 'link'=>'resource'], +'maxdb_info' => ['string', 'link'=>'resource'], +'maxdb_init' => ['resource'], +'maxdb_insert_id' => ['mixed', 'link'=>'resource'], +'maxdb_kill' => ['bool', 'link'=>'', 'processid'=>'int'], +'maxdb_master_query' => ['bool', 'link'=>'resource', 'query'=>'string'], +'maxdb_more_results' => ['bool', 'link'=>'resource'], +'maxdb_multi_query' => ['bool', 'link'=>'', 'query'=>'string'], +'maxdb_next_result' => ['bool', 'link'=>'resource'], +'maxdb_num_fields' => ['int', 'result'=>'resource'], +'maxdb_num_rows' => ['int', 'result'=>'resource'], +'maxdb_options' => ['bool', 'link'=>'', 'option'=>'int', 'value'=>''], +'maxdb_ping' => ['bool', 'link'=>''], +'maxdb_prepare' => ['maxdb_stmt', 'link'=>'', 'query'=>'string'], +'maxdb_query' => ['', 'link'=>'', 'query'=>'string', 'resultmode='=>'int'], +'maxdb_real_connect' => ['bool', 'link'=>'', 'hostname='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], +'maxdb_real_escape_string' => ['string', 'link'=>'', 'escapestr'=>'string'], +'maxdb_real_query' => ['bool', 'link'=>'', 'query'=>'string'], +'maxdb_report' => ['bool', 'flags'=>'int'], +'maxdb_result::current_field' => ['int', 'result'=>''], +'maxdb_result::data_seek' => ['bool', 'result'=>'', 'offset'=>'int'], +'maxdb_result::fetch_array' => ['', 'result'=>'', 'resulttype='=>'int'], +'maxdb_result::fetch_assoc' => ['array', 'result'=>''], +'maxdb_result::fetch_field' => ['', 'result'=>''], +'maxdb_result::fetch_field_direct' => ['', 'result'=>'', 'fieldnr'=>'int'], +'maxdb_result::fetch_fields' => ['', 'result'=>''], +'maxdb_result::fetch_object' => ['object', 'result'=>'object'], +'maxdb_result::fetch_row' => ['', 'result'=>''], +'maxdb_result::field_count' => ['int', 'result'=>''], +'maxdb_result::field_seek' => ['bool', 'result'=>'', 'fieldnr'=>'int'], +'maxdb_result::free' => ['', 'result'=>''], +'maxdb_result::lengths' => ['array', 'result'=>''], +'maxdb_rollback' => ['bool', 'link'=>''], +'maxdb_rpl_parse_enabled' => ['int', 'link'=>'resource'], +'maxdb_rpl_probe' => ['bool', 'link'=>'resource'], +'maxdb_rpl_query_type' => ['int', 'link'=>''], +'maxdb_select_db' => ['bool', 'link'=>'resource', 'dbname'=>'string'], +'maxdb_send_query' => ['bool', 'link'=>'', 'query'=>'string'], +'maxdb_server_end' => ['void'], +'maxdb_server_init' => ['bool', 'server='=>'array', 'groups='=>'array'], +'maxdb_sqlstate' => ['string', 'link'=>'resource'], +'maxdb_ssl_set' => ['bool', 'link'=>'', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], +'maxdb_stat' => ['string', 'link'=>''], +'maxdb_stmt::affected_rows' => ['int', 'stmt'=>''], +'maxdb_stmt::bind_param' => ['bool', 'stmt'=>'', 'types'=>'string', '&...rw_var'=>''], +'maxdb_stmt::bind_param\'1' => ['bool', 'stmt'=>'', 'types'=>'string', '&rw_var'=>'array'], +'maxdb_stmt::bind_result' => ['bool', 'stmt'=>'', '&rw_var1'=>'', '&...rw_vars='=>''], +'maxdb_stmt::close' => ['bool', 'stmt'=>''], +'maxdb_stmt::close_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int'], +'maxdb_stmt::data_seek' => ['bool', 'statement'=>'', 'offset'=>'int'], +'maxdb_stmt::errno' => ['int', 'stmt'=>''], +'maxdb_stmt::error' => ['string', 'stmt'=>''], +'maxdb_stmt::execute' => ['bool', 'stmt'=>''], +'maxdb_stmt::fetch' => ['bool', 'stmt'=>''], +'maxdb_stmt::free_result' => ['', 'stmt'=>''], +'maxdb_stmt::num_rows' => ['int', 'stmt'=>''], +'maxdb_stmt::param_count' => ['int', 'stmt'=>''], +'maxdb_stmt::prepare' => ['', 'stmt'=>'', 'query'=>'string'], +'maxdb_stmt::reset' => ['bool', 'stmt'=>''], +'maxdb_stmt::result_metadata' => ['resource', 'stmt'=>''], +'maxdb_stmt::send_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int', 'data'=>'string'], +'maxdb_stmt::stmt_send_long_data' => ['bool', 'param_nr'=>'int', 'data'=>'string'], +'maxdb_stmt::store_result' => ['bool'], +'maxdb_stmt_affected_rows' => ['int', 'stmt'=>'resource'], +'maxdb_stmt_bind_param' => ['bool', 'stmt'=>'', 'types'=>'string', 'var1'=>'', '...args='=>'', 'var='=>'array'], +'maxdb_stmt_bind_result' => ['bool', 'stmt'=>'', '&rw_var1'=>'', '&...rw_vars='=>''], +'maxdb_stmt_close' => ['bool', 'stmt'=>''], +'maxdb_stmt_close_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int'], +'maxdb_stmt_data_seek' => ['bool', 'statement'=>'', 'offset'=>'int'], +'maxdb_stmt_errno' => ['int', 'stmt'=>'resource'], +'maxdb_stmt_error' => ['string', 'stmt'=>'resource'], +'maxdb_stmt_execute' => ['bool', 'stmt'=>''], +'maxdb_stmt_fetch' => ['bool', 'stmt'=>''], +'maxdb_stmt_free_result' => ['', 'stmt'=>''], +'maxdb_stmt_init' => ['object', 'link'=>''], +'maxdb_stmt_num_rows' => ['int', 'stmt'=>'resource'], +'maxdb_stmt_param_count' => ['int', 'stmt'=>'resource'], +'maxdb_stmt_prepare' => ['', 'stmt'=>'', 'query'=>'string'], +'maxdb_stmt_reset' => ['bool', 'stmt'=>''], +'maxdb_stmt_result_metadata' => ['resource', 'stmt'=>''], +'maxdb_stmt_send_long_data' => ['bool', 'stmt'=>'', 'param_nr'=>'int', 'data'=>'string'], +'maxdb_stmt_sqlstate' => ['string', 'stmt'=>'resource'], +'maxdb_stmt_store_result' => ['bool', 'stmt'=>''], +'maxdb_store_result' => ['bool', 'link'=>''], +'maxdb_thread_id' => ['int', 'link'=>'resource'], +'maxdb_thread_safe' => ['bool'], +'maxdb_use_result' => ['resource', 'link'=>''], +'maxdb_warning_count' => ['int', 'link'=>'resource'], +'mb_check_encoding' => ['bool', 'var='=>'string', 'encoding='=>'string'], +'mb_chr' => ['string|false', 'cp'=>'int', 'encoding='=>'string'], +'mb_convert_case' => ['string', 'sourcestring'=>'string', 'mode'=>'int', 'encoding='=>'string'], +'mb_convert_encoding' => ['string', 'str'=>'string', 'to_encoding'=>'string', 'from_encoding='=>'mixed'], +'mb_convert_kana' => ['string', 'str'=>'string', 'option='=>'string', 'encoding='=>'string'], +'mb_convert_variables' => ['string|false', 'to_encoding'=>'string', 'from_encoding'=>'array|string', '&rw_vars'=>'string|array|object', '&...rw_vars='=>'string|array|object'], +'mb_decode_mimeheader' => ['string', 'string'=>'string'], +'mb_decode_numericentity' => ['string', 'string'=>'string', 'convmap'=>'array', 'encoding'=>'string'], +'mb_detect_encoding' => ['string|false', 'str'=>'string', 'encoding_list='=>'mixed', 'strict='=>'bool'], +'mb_detect_order' => ['bool|array', 'encoding_list='=>'mixed'], +'mb_encode_mimeheader' => ['string', 'str'=>'string', 'charset='=>'string', 'transfer_encoding='=>'string', 'linefeed='=>'string', 'indent='=>'int'], +'mb_encode_numericentity' => ['string', 'string'=>'string', 'convmap'=>'array', 'encoding'=>'string', 'is_hex='=>'bool'], +'mb_encoding_aliases' => ['array|false', 'encoding'=>'string'], +'mb_ereg' => ['int|false', 'pattern'=>'string', 'string'=>'string', '&w_registers='=>'array'], +'mb_ereg_match' => ['bool', 'pattern'=>'string', 'string'=>'string', 'option='=>'string'], +'mb_ereg_replace' => ['string|false', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'option='=>'string'], +'mb_ereg_replace_callback' => ['string|false', 'pattern'=>'string', 'callback'=>'string', 'string'=>'string', 'option='=>'string'], +'mb_ereg_search' => ['bool', 'pattern='=>'string', 'option='=>'string'], +'mb_ereg_search_getpos' => ['int'], +'mb_ereg_search_getregs' => ['array|false'], +'mb_ereg_search_init' => ['bool', 'string'=>'string', 'pattern='=>'string', 'option='=>'string'], +'mb_ereg_search_pos' => ['array|false', 'pattern='=>'string', 'option='=>'string'], +'mb_ereg_search_regs' => ['array|false', 'pattern='=>'string', 'option='=>'string'], +'mb_ereg_search_setpos' => ['bool', 'position'=>'int'], +'mb_eregi' => ['int', 'pattern'=>'string', 'string'=>'string', '&w_registers='=>'array'], +'mb_eregi_replace' => ['string|false', 'pattern'=>'string', 'replacement'=>'string', 'string'=>'string', 'option='=>'string'], +'mb_get_info' => ['mixed', 'type='=>'string'], +'mb_http_input' => ['mixed', 'type='=>'string'], +'mb_http_output' => ['string|bool', 'encoding='=>'string'], +'mb_internal_encoding' => ['string|bool', 'encoding='=>'string'], +'mb_language' => ['string|bool', 'language='=>'string'], +'mb_list_encodings' => ['array'], +'mb_ord' => ['int|false', 'str'=>'string', 'enc='=>'string'], +'mb_output_handler' => ['string', 'contents'=>'string', 'status'=>'int'], +'mb_parse_str' => ['bool', 'encoded_string'=>'string', '&w_result='=>'array'], +'mb_preferred_mime_name' => ['string', 'encoding'=>'string'], +'mb_regex_encoding' => ['string|bool', 'encoding='=>'string'], +'mb_regex_set_options' => ['string', 'options='=>'string'], +'mb_scrub' => ['string', 'str'=>'string', 'enc='=>'string'], +'mb_send_mail' => ['bool', 'to'=>'string', 'subject'=>'string', 'message'=>'string', 'additional_headers='=>'string', 'additional_parameter='=>'string'], +'mb_split' => ['array', 'pattern'=>'string', 'string'=>'string', 'limit='=>'int'], +'mb_strcut' => ['string', 'str'=>'string', 'start'=>'int', 'length='=>'int', 'encoding='=>'string'], +'mb_strimwidth' => ['string', 'str'=>'string', 'start'=>'int', 'width'=>'int', 'trimmarker='=>'string', 'encoding='=>'string'], +'mb_stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'], +'mb_stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'], +'mb_strlen' => ['int|false', 'str'=>'string', 'encoding='=>'string'], +'mb_strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'], +'mb_strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'], +'mb_strrichr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'], +'mb_strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'], +'mb_strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'encoding='=>'string'], +'mb_strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'part='=>'bool', 'encoding='=>'string'], +'mb_strtolower' => ['string', 'str'=>'string', 'encoding='=>'string'], +'mb_strtoupper' => ['string', 'str'=>'string', 'encoding='=>'string'], +'mb_strwidth' => ['int', 'str'=>'string', 'encoding='=>'string'], +'mb_substitute_character' => ['mixed', 'substchar='=>'mixed'], +'mb_substr' => ['string', 'str'=>'string', 'start'=>'int', 'length='=>'?int', 'encoding='=>'string'], +'mb_substr_count' => ['int', 'haystack'=>'string', 'needle'=>'string', 'encoding='=>'string'], +'mcrypt_cbc' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], +'mcrypt_cfb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], +'mcrypt_create_iv' => ['string', 'size'=>'int', 'source='=>'int'], +'mcrypt_decrypt' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'string', 'iv='=>'string'], +'mcrypt_ecb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], +'mcrypt_enc_get_algorithms_name' => ['string', 'td'=>'resource'], +'mcrypt_enc_get_block_size' => ['int', 'td'=>'resource'], +'mcrypt_enc_get_iv_size' => ['int', 'td'=>'resource'], +'mcrypt_enc_get_key_size' => ['int', 'td'=>'resource'], +'mcrypt_enc_get_modes_name' => ['string', 'td'=>'resource'], +'mcrypt_enc_get_supported_key_sizes' => ['array', 'td'=>'resource'], +'mcrypt_enc_is_block_algorithm' => ['bool', 'td'=>'resource'], +'mcrypt_enc_is_block_algorithm_mode' => ['bool', 'td'=>'resource'], +'mcrypt_enc_is_block_mode' => ['bool', 'td'=>'resource'], +'mcrypt_enc_self_test' => ['int', 'td'=>'resource'], +'mcrypt_encrypt' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'string', 'iv='=>'string'], +'mcrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], +'mcrypt_generic_deinit' => ['bool', 'td'=>'resource'], +'mcrypt_generic_end' => ['bool', 'td'=>'resource'], +'mcrypt_generic_init' => ['int', 'td'=>'resource', 'key'=>'string', 'iv'=>'string'], +'mcrypt_get_block_size' => ['int', 'cipher'=>'string', 'module'=>'string'], +'mcrypt_get_cipher_name' => ['string', 'cipher'=>'string'], +'mcrypt_get_iv_size' => ['int', 'cipher'=>'string', 'module'=>'string'], +'mcrypt_get_key_size' => ['int', 'cipher'=>'string', 'module'=>'string'], +'mcrypt_list_algorithms' => ['array', 'lib_dir='=>'string'], +'mcrypt_list_modes' => ['array', 'lib_dir='=>'string'], +'mcrypt_module_close' => ['bool', 'td'=>'resource'], +'mcrypt_module_get_algo_block_size' => ['int', 'algorithm'=>'string', 'lib_dir='=>'string'], +'mcrypt_module_get_algo_key_size' => ['int', 'algorithm'=>'string', 'lib_dir='=>'string'], +'mcrypt_module_get_supported_key_sizes' => ['array', 'algorithm'=>'string', 'lib_dir='=>'string'], +'mcrypt_module_is_block_algorithm' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], +'mcrypt_module_is_block_algorithm_mode' => ['bool', 'mode'=>'string', 'lib_dir='=>'string'], +'mcrypt_module_is_block_mode' => ['bool', 'mode'=>'string', 'lib_dir='=>'string'], +'mcrypt_module_open' => ['resource', 'cipher'=>'string', 'cipher_directory'=>'string', 'mode'=>'string', 'mode_directory'=>'string'], +'mcrypt_module_self_test' => ['bool', 'algorithm'=>'string', 'lib_dir='=>'string'], +'mcrypt_ofb' => ['string', 'cipher'=>'string', 'key'=>'string', 'data'=>'string', 'mode'=>'int', 'iv='=>'string'], +'md5' => ['string', 'str'=>'string', 'raw_output='=>'bool'], +'md5_file' => ['string|false', 'filename'=>'string', 'raw_output='=>'bool'], +'mdecrypt_generic' => ['string', 'td'=>'resource', 'data'=>'string'], +'Memcache::add' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], +'Memcache::addServer' => ['bool', 'host'=>'string', 'port='=>'int', 'persistent='=>'bool', 'weight='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable', 'timeoutms='=>'int'], +'Memcache::close' => ['bool'], +'Memcache::connect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'], +'Memcache::decrement' => ['int', 'key'=>'string', 'value='=>'int'], +'Memcache::delete' => ['bool', 'key'=>'string', 'timeout='=>'int'], +'Memcache::flush' => ['bool'], +'Memcache::get' => ['array', 'key'=>'string', 'flags='=>'array', 'keys='=>'array'], +'Memcache::getExtendedStats' => ['array', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'], +'Memcache::getServerStatus' => ['int', 'host'=>'string', 'port='=>'int'], +'Memcache::getStats' => ['array', 'type='=>'string', 'slabid='=>'int', 'limit='=>'int'], +'Memcache::getVersion' => ['string'], +'Memcache::increment' => ['int', 'key'=>'string', 'value='=>'int'], +'Memcache::pconnect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int'], +'Memcache::replace' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], +'Memcache::set' => ['bool', 'key'=>'string', 'var'=>'mixed', 'flag='=>'int', 'expire='=>'int'], +'Memcache::setCompressThreshold' => ['bool', 'threshold'=>'int', 'min_savings='=>'float'], +'Memcache::setServerParams' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'int', 'retry_interval='=>'int', 'status='=>'bool', 'failure_callback='=>'callable'], +'memcache_debug' => ['bool', 'on_off'=>'bool'], +'Memcached::add' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], +'Memcached::addByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], +'Memcached::addServer' => ['bool', 'host'=>'string', 'port'=>'int', 'weight='=>'int'], +'Memcached::addServers' => ['bool', 'servers'=>'array'], +'Memcached::append' => ['bool', 'key'=>'string', 'value'=>'string'], +'Memcached::appendByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'string'], +'Memcached::cas' => ['bool', 'cas_token'=>'float', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], +'Memcached::casByKey' => ['bool', 'cas_token'=>'float', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], +'Memcached::decrement' => ['int|false', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'], +'Memcached::decrementByKey' => ['int|false', 'server_key'=>'string', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'], +'Memcached::delete' => ['bool', 'key'=>'string', 'time='=>'int'], +'Memcached::deleteByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'time='=>'int'], +'Memcached::deleteMulti' => ['bool', 'keys'=>'array', 'time='=>'int'], +'Memcached::deleteMultiByKey' => ['bool', 'server_key'=>'string', 'keys'=>'array', 'time='=>'int'], +'Memcached::fetch' => ['array'], +'Memcached::fetchAll' => ['array'], +'Memcached::flush' => ['bool', 'delay='=>'int'], +'Memcached::get' => ['mixed', 'key'=>'string', 'cache_cb='=>'?callable', 'flags='=>'int'], +'Memcached::getAllKeys' => ['array'], +'Memcached::getByKey' => ['mixed', 'server_key'=>'string', 'key'=>'string', 'value_cb='=>'?callable', 'flags='=>'int'], +'Memcached::getDelayed' => ['bool', 'keys'=>'array', 'with_cas='=>'bool', 'value_cb='=>'callable'], +'Memcached::getDelayedByKey' => ['bool', 'server_key'=>'string', 'keys'=>'array', 'with_cas='=>'bool', 'value_cb='=>'?callable'], +'Memcached::getMulti' => ['array|false', 'keys'=>'array', 'flags='=>'int'], +'Memcached::getMultiByKey' => ['array', 'server_key'=>'string', 'keys'=>'array', 'flags='=>'int'], +'Memcached::getOption' => ['mixed', 'option'=>'int'], +'Memcached::getResultCode' => ['int'], +'Memcached::getResultMessage' => ['string'], +'Memcached::getServerByKey' => ['array', 'server_key'=>'string'], +'Memcached::getServerList' => ['array'], +'Memcached::getStats' => ['array', 'type='=>'?string'], +'Memcached::getVersion' => ['array'], +'Memcached::increment' => ['int|false', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'], +'Memcached::incrementByKey' => ['int|false', 'server_key'=>'string', 'key'=>'string', 'offset='=>'int', 'initial_value='=>'int', 'expiry='=>'int'], +'Memcached::isPersistent' => ['bool'], +'Memcached::isPristine' => ['bool'], +'Memcached::prepend' => ['bool', 'key'=>'string', 'value'=>'string'], +'Memcached::prependByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'string'], +'Memcached::quit' => ['bool'], +'Memcached::replace' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], +'Memcached::replaceByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], +'Memcached::resetServerList' => ['bool'], +'Memcached::set' => ['bool', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], +'Memcached::setByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'value'=>'mixed', 'expiration='=>'int'], +'Memcached::setMulti' => ['bool', 'items'=>'array', 'expiration='=>'int'], +'Memcached::setMultiByKey' => ['bool', 'server_key'=>'string', 'items'=>'array', 'expiration='=>'int'], +'Memcached::setOption' => ['bool', 'option'=>'int', 'value'=>'mixed'], +'Memcached::setOptions' => ['bool', 'options'=>'array'], +'Memcached::setSaslAuthData' => ['void', 'username'=>'string', 'password'=>'string'], +'Memcached::touch' => ['bool', 'key'=>'string', 'expiration'=>'int'], +'Memcached::touchByKey' => ['bool', 'server_key'=>'string', 'key'=>'string', 'expiration'=>'int'], +'memory_get_peak_usage' => ['int', 'real_usage='=>'bool'], +'memory_get_usage' => ['int', 'real_usage='=>'bool'], +'MessageFormatter::__construct' => ['void', 'locale'=>'string', 'pattern'=>'string'], +'MessageFormatter::create' => ['MessageFormatter', 'locale'=>'string', 'pattern'=>'string'], +'MessageFormatter::format' => ['false|string', 'args'=>'array'], +'MessageFormatter::formatMessage' => ['false|string', 'locale'=>'string', 'pattern'=>'string', 'args'=>'array'], +'MessageFormatter::getErrorCode' => ['int'], +'MessageFormatter::getErrorMessage' => ['string'], +'MessageFormatter::getLocale' => ['string'], +'MessageFormatter::getPattern' => ['string'], +'MessageFormatter::parse' => ['array', 'value'=>'string'], +'MessageFormatter::parseMessage' => ['array', 'locale'=>'string', 'pattern'=>'string', 'source'=>'string'], +'MessageFormatter::setPattern' => ['bool', 'pattern'=>'string'], +'metaphone' => ['string', 'text'=>'string', 'phones='=>'int'], +'method_exists' => ['bool', 'object'=>'object|string', 'method'=>'string'], +'mhash' => ['string', 'hash'=>'int', 'data'=>'string', 'key='=>'string'], +'mhash_count' => ['int'], +'mhash_get_block_size' => ['int', 'hash'=>'int'], +'mhash_get_hash_name' => ['string', 'hash'=>'int'], +'mhash_keygen_s2k' => ['string', 'hash'=>'int', 'input_password'=>'string', 'salt'=>'string', 'bytes'=>'int'], +'microtime' => ['mixed', 'get_as_float='=>'bool'], +'mime_content_type' => ['string|false', 'filename_or_stream'=>'string'], +'min' => ['', '...arg1'=>'array'], +'min\'1' => ['', 'arg1'=>'', 'arg2'=>'', '...args='=>''], +'ming_keypress' => ['int', 'char'=>'string'], +'ming_setcubicthreshold' => ['void', 'threshold'=>'int'], +'ming_setscale' => ['void', 'scale'=>'float'], +'ming_setswfcompression' => ['void', 'level'=>'int'], +'ming_useconstants' => ['void', 'use'=>'int'], +'ming_useswfversion' => ['void', 'version'=>'int'], +'mkdir' => ['bool', 'pathname'=>'string', 'mode='=>'int', 'recursive='=>'bool', 'context='=>'resource'], +'mktime' => ['int', 'hour='=>'int', 'min='=>'int', 'sec='=>'int', 'mon='=>'int', 'day='=>'int', 'year='=>'int'], +'money_format' => ['string', 'format'=>'string', 'value'=>'float'], +'Mongo::__get' => ['MongoDB', 'dbname'=>'string'], +'Mongo::__toString' => ['string'], +'Mongo::close' => ['bool'], +'Mongo::connect' => ['bool'], +'Mongo::connectUtil' => ['bool'], +'Mongo::dropDB' => ['array', 'db'=>''], +'Mongo::forceError' => ['bool'], +'Mongo::getConnections' => ['array'], +'Mongo::getHosts' => ['array'], +'Mongo::getPoolSize' => ['int'], +'Mongo::getReadPreference' => ['array'], +'Mongo::getSlave' => ['string'], +'Mongo::getSlaveOkay' => ['bool'], +'Mongo::getWriteConcern' => ['array'], +'Mongo::killCursor' => ['', 'server_hash'=>'string', 'id'=>'MongoInt64|int'], +'Mongo::lastError' => ['array|null'], +'Mongo::listDBs' => ['array'], +'Mongo::pairConnect' => ['bool'], +'Mongo::pairPersistConnect' => ['bool', 'username='=>'string', 'password='=>'string'], +'Mongo::persistConnect' => ['bool', 'username='=>'string', 'password='=>'string'], +'Mongo::poolDebug' => ['array'], +'Mongo::prevError' => ['array'], +'Mongo::resetError' => ['array'], +'Mongo::selectCollection' => ['MongoCollection', 'db'=>'string', 'collection'=>'string'], +'Mongo::selectDB' => ['MongoDB', 'name'=>'string'], +'Mongo::setPoolSize' => ['bool', 'size'=>'int'], +'Mongo::setReadPreference' => ['bool', 'readPreference'=>'string', 'tags='=>'array'], +'Mongo::setSlaveOkay' => ['bool', 'ok='=>'bool'], +'Mongo::switchSlave' => ['string'], +'MongoBinData::__construct' => ['void', 'data'=>'string', 'type='=>'int'], +'MongoBinData::__toString' => ['string'], +'MongoClient::__construct' => ['void', 'server='=>'string', 'options='=>'array', 'driver_options'=>'array'], +'MongoClient::__get' => ['MongoDB', 'dbname'=>'string'], +'MongoClient::__toString' => ['string'], +'MongoClient::close' => ['bool', 'connection='=>'bool|string'], +'MongoClient::connect' => ['bool'], +'MongoClient::dropDB' => ['array', 'db'=>'mixed'], +'MongoClient::getConnections' => ['array'], +'MongoClient::getHosts' => ['array'], +'MongoClient::getReadPreference' => ['array'], +'MongoClient::getWriteConcern' => ['array'], +'MongoClient::killCursor' => ['bool', 'server_hash'=>'string', 'id'=>'int|MongoInt64'], +'MongoClient::listDBs' => ['array'], +'MongoClient::selectCollection' => ['MongoCollection', 'db'=>'string', 'collection'=>'string'], +'MongoClient::selectDB' => ['MongoDB', 'name'=>'string'], +'MongoClient::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'], +'MongoClient::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'], +'MongoClient::switchSlave' => ['string'], +'MongoCode::__construct' => ['void', 'code'=>'string', 'scope='=>'array'], +'MongoCode::__toString' => ['string'], +'MongoCollection::__construct' => ['void', 'db'=>'MongoDB', 'name'=>'string'], +'MongoCollection::__get' => ['MongoCollection', 'name'=>'string'], +'MongoCollection::__toString' => ['string'], +'MongoCollection::aggregate' => ['array', 'op'=>'array', 'op='=>'array', '...args='=>'array'], +'MongoCollection::aggregate\'1' => ['array', 'pipeline'=>'array', 'options='=>'array'], +'MongoCollection::aggregateCursor' => ['MongoCommandCursor', 'command'=>'array', 'options='=>'array'], +'MongoCollection::batchInsert' => ['mixed', 'a'=>'array', 'options='=>'array'], +'MongoCollection::count' => ['int', 'query='=>'array', 'limit='=>'int', 'skip='=>'int'], +'MongoCollection::createDBRef' => ['array', 'a'=>'array'], +'MongoCollection::createIndex' => ['bool', 'keys'=>'array', 'options='=>'array'], +'MongoCollection::deleteIndex' => ['array', 'keys'=>'string|array'], +'MongoCollection::deleteIndexes' => ['array'], +'MongoCollection::distinct' => ['array', 'key'=>'string', 'query='=>'array'], +'MongoCollection::drop' => ['array'], +'MongoCollection::ensureIndex' => ['bool', 'keys'=>'array', 'options='=>'array'], +'MongoCollection::find' => ['MongoCursor', 'query='=>'array', 'fields='=>'array'], +'MongoCollection::findAndModify' => ['array', 'query'=>'array', 'update='=>'array', 'fields='=>'array', 'options='=>'array'], +'MongoCollection::findOne' => ['array', 'query='=>'array', 'fields='=>'array'], +'MongoCollection::getDBRef' => ['array', 'ref'=>'array'], +'MongoCollection::getIndexInfo' => ['array'], +'MongoCollection::getName' => ['string'], +'MongoCollection::getReadPreference' => ['array'], +'MongoCollection::getSlaveOkay' => ['bool'], +'MongoCollection::getWriteConcern' => ['array'], +'MongoCollection::group' => ['array', 'keys'=>'mixed', 'initial'=>'array', 'reduce'=>'mongocode', 'options='=>'array'], +'MongoCollection::insert' => ['bool|array', 'a'=>'array', 'options='=>'array'], +'MongoCollection::parallelCollectionScan' => ['MongoCommandCursor[]', 'num_cursors'=>'int'], +'MongoCollection::remove' => ['bool|array', 'criteria='=>'array', 'options='=>'array'], +'MongoCollection::save' => ['mixed', 'a'=>'array', 'options='=>'array'], +'MongoCollection::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'], +'MongoCollection::setSlaveOkay' => ['bool', 'ok='=>'bool'], +'MongoCollection::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'], +'MongoCollection::toIndexString' => ['string', 'keys'=>'mixed'], +'MongoCollection::update' => ['bool', 'criteria'=>'array', 'newobj'=>'array', 'options='=>'array'], +'MongoCollection::validate' => ['array', 'scan_data='=>'bool'], +'MongoCommandCursor::__construct' => ['void', 'connection'=>'MongoClient', 'ns'=>'string', 'command'=>'array'], +'MongoCommandCursor::batchSize' => ['MongoCommandCursor', 'batchSize'=>'int'], +'MongoCommandCursor::createFromDocument' => ['MongoCommandCursor', 'connection'=>'MongoClient', 'hash'=>'string', 'document'=>'array'], +'MongoCommandCursor::current' => ['array'], +'MongoCommandCursor::dead' => ['bool'], +'MongoCommandCursor::getReadPreference' => ['array'], +'MongoCommandCursor::info' => ['array'], +'MongoCommandCursor::key' => ['int'], +'MongoCommandCursor::next' => ['void'], +'MongoCommandCursor::rewind' => ['array'], +'MongoCommandCursor::setReadPreference' => ['MongoCommandCursor', 'read_preference'=>'string', 'tags='=>'array'], +'MongoCommandCursor::timeout' => ['MongoCommandCursor', 'ms'=>'int'], +'MongoCommandCursor::valid' => ['bool'], +'MongoCursor::__construct' => ['void', 'connection'=>'MongoClient', 'ns'=>'string', 'query='=>'array', 'fields='=>'array'], +'MongoCursor::addOption' => ['MongoCursor', 'key'=>'string', 'value'=>'mixed'], +'MongoCursor::awaitData' => ['MongoCursor', 'wait='=>'bool'], +'MongoCursor::batchSize' => ['MongoCursor', 'num'=>'int'], +'MongoCursor::count' => ['int', 'foundonly='=>'bool'], +'MongoCursor::current' => ['array'], +'MongoCursor::dead' => ['bool'], +'MongoCursor::doQuery' => ['void'], +'MongoCursor::explain' => ['array'], +'MongoCursor::fields' => ['MongoCursor', 'f'=>'array'], +'MongoCursor::getNext' => ['array'], +'MongoCursor::getReadPreference' => ['array'], +'MongoCursor::hasNext' => ['bool'], +'MongoCursor::hint' => ['MongoCursor', 'key_pattern'=>'array'], +'MongoCursor::immortal' => ['MongoCursor', 'liveforever='=>'bool'], +'MongoCursor::info' => ['array'], +'MongoCursor::key' => ['string'], +'MongoCursor::limit' => ['MongoCursor', 'num'=>'int'], +'MongoCursor::maxTimeMS' => ['MongoCursor', 'ms'=>'int'], +'MongoCursor::next' => ['array'], +'MongoCursor::partial' => ['MongoCursor', 'okay='=>'bool'], +'MongoCursor::reset' => ['void'], +'MongoCursor::rewind' => ['void'], +'MongoCursor::setFlag' => ['MongoCursor', 'flag'=>'int', 'set='=>'bool'], +'MongoCursor::setReadPreference' => ['MongoCursor', 'read_preference'=>'string', 'tags='=>'array'], +'MongoCursor::skip' => ['MongoCursor', 'num'=>'int'], +'MongoCursor::slaveOkay' => ['MongoCursor', 'okay='=>'bool'], +'MongoCursor::snapshot' => ['MongoCursor'], +'MongoCursor::sort' => ['MongoCursor', 'fields'=>'array'], +'MongoCursor::tailable' => ['MongoCursor', 'tail='=>'bool'], +'MongoCursor::timeout' => ['MongoCursor', 'ms'=>'int'], +'MongoCursor::valid' => ['bool'], +'MongoCursorException::__clone' => ['void'], +'MongoCursorException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'MongoCursorException::__toString' => ['string'], +'MongoCursorException::__wakeup' => ['void'], +'MongoCursorException::getCode' => ['int'], +'MongoCursorException::getFile' => ['string'], +'MongoCursorException::getHost' => ['string'], +'MongoCursorException::getLine' => ['int'], +'MongoCursorException::getMessage' => ['string'], +'MongoCursorException::getPrevious' => ['Exception|Throwable'], +'MongoCursorException::getTrace' => ['array'], +'MongoCursorException::getTraceAsString' => ['string'], +'MongoCursorInterface::__construct' => ['void'], +'MongoCursorInterface::batchSize' => ['MongoCursorInterface', 'batchSize'=>'int'], +'MongoCursorInterface::current' => ['mixed'], +'MongoCursorInterface::dead' => ['bool'], +'MongoCursorInterface::getReadPreference' => ['array'], +'MongoCursorInterface::info' => ['array'], +'MongoCursorInterface::key' => ['int|string'], +'MongoCursorInterface::next' => ['void'], +'MongoCursorInterface::rewind' => ['void'], +'MongoCursorInterface::setReadPreference' => ['MongoCursorInterface', 'read_preference'=>'string', 'tags='=>'array'], +'MongoCursorInterface::timeout' => ['MongoCursorInterface', 'ms'=>'int'], +'MongoCursorInterface::valid' => ['bool'], +'MongoDate::__construct' => ['void', 'sec='=>'int', 'usec='=>'int'], +'MongoDate::__toString' => ['string'], +'MongoDate::toDateTime' => ['DateTime'], +'MongoDB::__construct' => ['void', 'conn'=>'MongoClient', 'name'=>'string'], +'MongoDB::__get' => ['MongoCollection', 'name'=>'string'], +'MongoDB::__toString' => ['string'], +'MongoDB::authenticate' => ['array', 'username'=>'string', 'password'=>'string'], +'MongoDB::command' => ['array', 'command'=>'array'], +'MongoDB::createCollection' => ['MongoCollection', 'name'=>'string', 'capped='=>'bool', 'size='=>'int', 'max='=>'int'], +'MongoDB::createDBRef' => ['array', 'collection'=>'string', 'a'=>''], +'MongoDB::drop' => ['array'], +'MongoDB::dropCollection' => ['array', 'coll'=>''], +'MongoDB::execute' => ['array', 'code'=>'', 'args='=>'array'], +'MongoDB::forceError' => ['bool'], +'MongoDB::getCollectionInfo' => ['array', 'options='=>'array'], +'MongoDB::getCollectionNames' => ['array', 'options='=>'array'], +'MongoDB::getDBRef' => ['array', 'ref'=>'array'], +'MongoDB::getGridFS' => ['MongoGridFS', 'prefix='=>'string'], +'MongoDB::getProfilingLevel' => ['int'], +'MongoDB::getReadPreference' => ['array'], +'MongoDB::getSlaveOkay' => ['bool'], +'MongoDB::getWriteConcern' => ['array'], +'MongoDB::lastError' => ['array'], +'MongoDB::listCollections' => ['array'], +'MongoDB::prevError' => ['array'], +'MongoDB::repair' => ['array', 'preserve_cloned_files='=>'bool', 'backup_original_files='=>'bool'], +'MongoDB::resetError' => ['array'], +'MongoDB::selectCollection' => ['MongoCollection', 'name'=>'string'], +'MongoDB::setProfilingLevel' => ['int', 'level'=>'int'], +'MongoDB::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags='=>'array'], +'MongoDB::setSlaveOkay' => ['bool', 'ok='=>'bool'], +'MongoDB::setWriteConcern' => ['bool', 'w'=>'mixed', 'wtimeout='=>'int'], +'MongoDB\BSON\Binary::__construct' => ['void', 'data'=>'string', 'type'=>'int'], +'MongoDB\BSON\Binary::getData' => ['string'], +'MongoDB\BSON\Binary::getType' => ['int'], +'MongoDB\BSON\Decimal128::__construct' => ['void', 'value='=>'string'], +'MongoDB\BSON\Decimal128::__toString' => ['string'], +'MongoDB\BSON\fromJSON' => ['string', 'json'=>'string'], +'MongoDB\BSON\fromPHP' => ['string', 'value'=>'array|object'], +'MongoDB\BSON\Javascript::__construct' => ['void', 'code'=>'string', 'scope='=>'array|object'], +'MongoDB\BSON\ObjectId::__construct' => ['void', 'id='=>'string'], +'MongoDB\BSON\ObjectId::__toString' => ['string'], +'MongoDB\BSON\Regex::__construct' => ['void', 'pattern'=>'string', 'flags='=>'string'], +'MongoDB\BSON\Regex::__toString' => ['string'], +'MongoDB\BSON\Regex::getFlags' => [''], +'MongoDB\BSON\Regex::getPattern' => ['string'], +'MongoDB\BSON\Serializable::bsonSerialize' => ['array|object'], +'MongoDB\BSON\Timestamp::__construct' => ['void', 'increment'=>'int', 'timestamp'=>'int'], +'MongoDB\BSON\Timestamp::__toString' => ['string'], +'MongoDB\BSON\toJSON' => ['string', 'bson'=>'string'], +'MongoDB\BSON\toPHP' => ['object', 'bson'=>'string', 'typeMap'=>'array'], +'MongoDB\BSON\Unserializable::bsonUnserialize' => ['', 'data'=>'array'], +'MongoDB\BSON\UTCDateTime::__construct' => ['void', 'milliseconds='=>'int|DateTimeInterface'], +'MongoDB\BSON\UTCDateTime::__toString' => ['string'], +'MongoDB\BSON\UTCDateTime::toDateTime' => ['DateTime'], +'MongoDB\Driver\BulkWrite::__construct' => ['void', 'ordered='=>'bool'], +'MongoDB\Driver\BulkWrite::count' => ['int'], +'MongoDB\Driver\BulkWrite::delete' => ['void', 'filter'=>'array|object', 'deleteOptions='=>'array'], +'MongoDB\Driver\BulkWrite::insert' => ['MongoDB\Driver\ObjectID', 'document'=>'array|object'], +'MongoDB\Driver\BulkWrite::update' => ['void', 'filter'=>'array|object', 'newObj'=>'array|object', 'updateOptions='=>'array'], +'MongoDB\Driver\Command::__construct' => ['void', 'document'=>'array|object'], +'MongoDB\Driver\Cursor::__construct' => ['void', 'server'=>'Server', 'responseDocument'=>'string'], +'MongoDB\Driver\Cursor::getId' => ['MongoDB\Driver\CursorId'], +'MongoDB\Driver\Cursor::getServer' => ['MongoDB\Driver\Server'], +'MongoDB\Driver\Cursor::isDead' => ['bool'], +'MongoDB\Driver\Cursor::setTypeMap' => ['void', 'typemap'=>'array'], +'MongoDB\Driver\Cursor::toArray' => ['array'], +'MongoDB\Driver\CursorId::__construct' => ['void', 'id'=>'string'], +'MongoDB\Driver\CursorId::__toString' => ['string'], +'MongoDB\Driver\Exception\RuntimeException::__clone' => ['void'], +'MongoDB\Driver\Exception\RuntimeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\RuntimeException|?\Throwable'], +'MongoDB\Driver\Exception\RuntimeException::__toString' => ['string'], +'MongoDB\Driver\Exception\RuntimeException::__wakeup' => ['void'], +'MongoDB\Driver\Exception\RuntimeException::getCode' => ['int'], +'MongoDB\Driver\Exception\RuntimeException::getFile' => ['string'], +'MongoDB\Driver\Exception\RuntimeException::getLine' => ['int'], +'MongoDB\Driver\Exception\RuntimeException::getMessage' => ['string'], +'MongoDB\Driver\Exception\RuntimeException::getPrevious' => ['RuntimeException|Throwable'], +'MongoDB\Driver\Exception\RuntimeException::getTrace' => ['array'], +'MongoDB\Driver\Exception\RuntimeException::getTraceAsString' => ['string'], +'MongoDB\Driver\Exception\WriteException::__clone' => ['void'], +'MongoDB\Driver\Exception\WriteException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\RuntimeException|?\Throwable'], +'MongoDB\Driver\Exception\WriteException::__toString' => ['string'], +'MongoDB\Driver\Exception\WriteException::__wakeup' => ['void'], +'MongoDB\Driver\Exception\WriteException::getCode' => ['int'], +'MongoDB\Driver\Exception\WriteException::getFile' => ['string'], +'MongoDB\Driver\Exception\WriteException::getLine' => ['int'], +'MongoDB\Driver\Exception\WriteException::getMessage' => ['string'], +'MongoDB\Driver\Exception\WriteException::getPrevious' => ['RuntimeException|Throwable'], +'MongoDB\Driver\Exception\WriteException::getTrace' => ['array'], +'MongoDB\Driver\Exception\WriteException::getTraceAsString' => ['string'], +'MongoDB\Driver\Exception\WriteException::getWriteResult' => ['MongoDB\Driver\WriteResult'], +'MongoDB\Driver\Manager::__construct' => ['void', 'uri'=>'string', 'options='=>'array', 'driverOptions='=>'array'], +'MongoDB\Driver\Manager::executeBulkWrite' => ['MongoDB\Driver\WriteResult', 'namespace'=>'string', 'bulk'=>'MongoDB\Driver\BulkWrite', 'writeConcern='=>'MongoDB\Driver\WriteConcern'], +'MongoDB\Driver\Manager::executeCommand' => ['MongoDB\Driver\Cursor', 'db'=>'string', 'command'=>'MongoDB\Driver\Command', 'readPreference='=>'MongoDB\Driver\ReadPreference'], +'MongoDB\Driver\Manager::executeDelete' => ['MongoDB\Driver\WriteResult', 'namespace'=>'string', 'filter'=>'array|object', 'deleteOptions='=>'array', 'writeConcern='=>'MongoDB\Driver\WriteConcern'], +'MongoDB\Driver\Manager::executeInsert' => ['MongoDB\Driver\WriteResult', 'namespace'=>'string', 'document'=>'array|object', 'writeConcern='=>'MongoDB\Driver\WriteConcern'], +'MongoDB\Driver\Manager::executeQuery' => ['MongoDB\Driver\Cursor', 'namespace'=>'string', 'query'=>'MongoDB\Driver\Query', 'readPreference='=>'MongoDB\Driver\ReadPreference'], +'MongoDB\Driver\Manager::executeUpdate' => ['MongoDB\Driver\WriteResult', 'namespace'=>'string', 'filter'=>'array|object', 'newObj'=>'array|object', 'updateOptions='=>'array', 'writeConcern='=>'MongoDB\Driver\WriteConcern'], +'MongoDB\Driver\Manager::getReadConcern' => ['MongoDB\Driver\ReadConcern'], +'MongoDB\Driver\Manager::getReadPreference' => ['MongoDB\Driver\ReadPreference'], +'MongoDB\Driver\Manager::getServers' => ['array'], +'MongoDB\Driver\Manager::getWriteConcern' => ['MongoDB\Driver\WriteConcern'], +'MongoDB\Driver\Manager::selectServer' => ['MongoDB\Driver\Server', 'readPreference'=>'MongoDB\Driver\ReadPreference'], +'MongoDB\Driver\Query::__construct' => ['void', 'filter'=>'array|object', 'queryOptions='=>'array'], +'MongoDB\Driver\ReadConcern::__construct' => ['void', 'level='=>'string'], +'MongoDB\Driver\ReadConcern::bsonSerialize' => ['object'], +'MongoDB\Driver\ReadConcern::getLevel' => ['null|string'], +'MongoDB\Driver\ReadPreference::__construct' => ['void', 'readPreference'=>'string', 'tagSets='=>'array'], +'MongoDB\Driver\ReadPreference::bsonSerialize' => ['object'], +'MongoDB\Driver\ReadPreference::getMode' => ['int'], +'MongoDB\Driver\ReadPreference::getTagSets' => ['array'], +'MongoDB\Driver\Server::__construct' => ['void', 'host'=>'string', 'port'=>'string', 'options='=>'array', 'driverOptions='=>'array'], +'MongoDB\Driver\Server::executeBulkWrite' => ['', 'namespace'=>'string', 'zwrite'=>'BulkWrite'], +'MongoDB\Driver\Server::executeCommand' => ['', 'db'=>'string', 'command'=>'Command'], +'MongoDB\Driver\Server::executeQuery' => ['', 'namespace'=>'string', 'zquery'=>'Query'], +'MongoDB\Driver\Server::getHost' => [''], +'MongoDB\Driver\Server::getInfo' => [''], +'MongoDB\Driver\Server::getLatency' => [''], +'MongoDB\Driver\Server::getPort' => [''], +'MongoDB\Driver\Server::getState' => [''], +'MongoDB\Driver\Server::getTags' => ['array'], +'MongoDB\Driver\Server::getType' => [''], +'MongoDB\Driver\Server::isArbiter' => ['bool'], +'MongoDB\Driver\Server::isDelayed' => [''], +'MongoDB\Driver\Server::isHidden' => ['bool'], +'MongoDB\Driver\Server::isPassive' => [''], +'MongoDB\Driver\Server::isPrimary' => ['bool'], +'MongoDB\Driver\Server::isSecondary' => ['bool'], +'MongoDB\Driver\WriteConcern::__construct' => ['void', 'w'=>'string|int', 'wtimeout='=>'int', 'journal='=>'bool', 'fsync='=>'bool'], +'MongoDB\Driver\WriteConcern::getJurnal' => ['bool|null'], +'MongoDB\Driver\WriteConcern::getW' => ['int|null|string'], +'MongoDB\Driver\WriteConcern::getWtimeout' => ['int'], +'MongoDB\Driver\WriteConcernError::getCode' => [''], +'MongoDB\Driver\WriteConcernError::getInfo' => [''], +'MongoDB\Driver\WriteConcernError::getMessage' => [''], +'MongoDB\Driver\WriteError::getCode' => [''], +'MongoDB\Driver\WriteError::getIndex' => [''], +'MongoDB\Driver\WriteError::getInfo' => ['mixed'], +'MongoDB\Driver\WriteError::getMessage' => [''], +'MongoDB\Driver\WriteException::getWriteResult' => [''], +'MongoDB\Driver\WriteResult::getDeletedCount' => ['int'], +'MongoDB\Driver\WriteResult::getInfo' => [''], +'MongoDB\Driver\WriteResult::getInsertedCount' => ['int'], +'MongoDB\Driver\WriteResult::getMatchedCount' => ['int'], +'MongoDB\Driver\WriteResult::getModifiedCount' => ['int'], +'MongoDB\Driver\WriteResult::getServer' => [''], +'MongoDB\Driver\WriteResult::getUpsertedCount' => ['int'], +'MongoDB\Driver\WriteResult::getUpsertedIds' => [''], +'MongoDB\Driver\WriteResult::getWriteConcernError' => [''], +'MongoDB\Driver\WriteResult::getWriteErrors' => [''], +'MongoDB\Driver\WriteResult::isAcknowledged' => ['bool'], +'MongoDBRef::create' => ['array', 'collection'=>'string', 'id'=>'mixed', 'database='=>'string'], +'MongoDBRef::get' => ['array', 'db'=>'mongodb', 'ref'=>'array'], +'MongoDBRef::isRef' => ['bool', 'ref'=>'mixed'], +'MongoDeleteBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'], +'MongoException::__clone' => ['void'], +'MongoException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'MongoException::__toString' => ['string'], +'MongoException::__wakeup' => ['void'], +'MongoException::getCode' => ['int'], +'MongoException::getFile' => ['string'], +'MongoException::getLine' => ['int'], +'MongoException::getMessage' => ['string'], +'MongoException::getPrevious' => ['Exception|Throwable'], +'MongoException::getTrace' => ['array'], +'MongoException::getTraceAsString' => ['string'], +'MongoGridFS::__construct' => ['void', 'db'=>'MongoDB', 'prefix='=>'string', 'chunks='=>'mixed'], +'MongoGridFS::__get' => ['MongoCollection', 'name'=>'string'], +'MongoGridFS::__toString' => ['string'], +'MongoGridFS::aggregate' => ['array', 'pipeline'=>'array', 'op'=>'array', 'pipelineOperators'=>'array'], +'MongoGridFS::aggregateCursor' => ['MongoCommandCursor', 'pipeline'=>'array', 'options'=>'array'], +'MongoGridFS::batchInsert' => ['mixed', 'a'=>'array', 'options='=>'array'], +'MongoGridFS::count' => ['int', 'query='=>'stdClass|array'], +'MongoGridFS::createDBRef' => ['array', 'a'=>'array'], +'MongoGridFS::createIndex' => ['array', 'keys'=>'array', 'options='=>'array'], +'MongoGridFS::delete' => ['bool', 'id'=>'mixed'], +'MongoGridFS::deleteIndex' => ['array', 'keys'=>'array|string'], +'MongoGridFS::deleteIndexes' => ['array'], +'MongoGridFS::distinct' => ['array|bool', 'key'=>'string', 'query='=>'?array'], +'MongoGridFS::drop' => ['array'], +'MongoGridFS::ensureIndex' => ['bool', 'keys'=>'array', 'options='=>'array'], +'MongoGridFS::find' => ['MongoGridFSCursor', 'query='=>'array', 'fields='=>'array'], +'MongoGridFS::findAndModify' => ['array', 'query'=>'array', 'update='=>'?array', 'fields='=>'?array', 'options='=>'?array'], +'MongoGridFS::findOne' => ['MongoGridFSFile', 'query='=>'mixed', 'fields='=>'mixed'], +'MongoGridFS::get' => ['MongoGridFSFile', 'id'=>'mixed'], +'MongoGridFS::getDBRef' => ['array', 'ref'=>'array'], +'MongoGridFS::getIndexInfo' => ['array'], +'MongoGridFS::getName' => ['string'], +'MongoGridFS::getReadPreference' => ['array'], +'MongoGridFS::getSlaveOkay' => ['bool'], +'MongoGridFS::group' => ['array', 'keys'=>'mixed', 'initial'=>'array', 'reduce'=>'MongoCode', 'condition='=>'array'], +'MongoGridFS::insert' => ['array|bool', 'a'=>'array|object', 'options='=>'array'], +'MongoGridFS::put' => ['mixed', 'filename'=>'string', 'extra='=>'array'], +'MongoGridFS::remove' => ['bool', 'criteria='=>'array', 'options='=>'array'], +'MongoGridFS::save' => ['array|bool', 'a'=>'array|object', 'options='=>'array'], +'MongoGridFS::setReadPreference' => ['bool', 'read_preference'=>'string', 'tags'=>'array'], +'MongoGridFS::setSlaveOkay' => ['bool', 'ok='=>'bool|true'], +'MongoGridFS::storeBytes' => ['mixed', 'bytes'=>'string', 'extra='=>'array', 'options='=>'array'], +'MongoGridFS::storeFile' => ['mixed', 'filename'=>'string', 'extra='=>'array', 'options='=>'array'], +'MongoGridFS::storeUpload' => ['mixed', 'name'=>'string', 'filename='=>'string'], +'MongoGridFS::toIndexString' => ['string', 'keys'=>'mixed'], +'MongoGridFS::update' => ['bool', 'criteria'=>'array', 'newobj'=>'array', 'options='=>'array'], +'MongoGridFS::validate' => ['array', 'scan_data='=>'bool|false'], +'MongoGridFSCursor::__construct' => ['void', 'gridfs'=>'MongoGridFS', 'connection'=>'resource', 'ns'=>'string', 'query'=>'array', 'fields'=>'array'], +'MongoGridFSCursor::addOption' => ['MongoCursor', 'key'=>'string', 'value'=>'mixed'], +'MongoGridFSCursor::awaitData' => ['MongoCursor', 'wait='=>'bool|true'], +'MongoGridFSCursor::batchSize' => ['MongoCursor', 'batchSize'=>'int'], +'MongoGridFSCursor::count' => ['int', 'all='=>'bool|false'], +'MongoGridFSCursor::current' => ['MongoGridFSFile'], +'MongoGridFSCursor::dead' => ['bool'], +'MongoGridFSCursor::doQuery' => ['void'], +'MongoGridFSCursor::explain' => ['array'], +'MongoGridFSCursor::fields' => ['MongoCursor', 'f'=>'array'], +'MongoGridFSCursor::getNext' => ['MongoGridFSFile'], +'MongoGridFSCursor::getReadPreference' => ['array'], +'MongoGridFSCursor::hasNext' => ['bool'], +'MongoGridFSCursor::hint' => ['MongoCursor', 'key_pattern'=>'mixed'], +'MongoGridFSCursor::immortal' => ['MongoCursor', 'liveForever='=>'bool|true'], +'MongoGridFSCursor::info' => ['array'], +'MongoGridFSCursor::key' => ['string'], +'MongoGridFSCursor::limit' => ['MongoCursor', 'num'=>'int'], +'MongoGridFSCursor::maxTimeMS' => ['MongoCursor', 'ms'=>'int'], +'MongoGridFSCursor::next' => ['void'], +'MongoGridFSCursor::partial' => ['MongoCursor', 'okay='=>'bool|true'], +'MongoGridFSCursor::reset' => ['void'], +'MongoGridFSCursor::rewind' => ['void'], +'MongoGridFSCursor::setFlag' => ['MongoCursor', 'flag'=>'int', 'set='=>'bool|true'], +'MongoGridFSCursor::setReadPreference' => ['MongoCursor', 'read_preference'=>'string', 'tags'=>'array'], +'MongoGridFSCursor::skip' => ['MongoCursor', 'num'=>'int'], +'MongoGridFSCursor::slaveOkay' => ['MongoCursor', 'okay='=>'bool|true'], +'MongoGridFSCursor::snapshot' => ['MongoCursor'], +'MongoGridFSCursor::sort' => ['MongoCursor', 'fields'=>'array'], +'MongoGridFSCursor::tailable' => ['MongoCursor', 'tail='=>'bool|true'], +'MongoGridFSCursor::timeout' => ['MongoCursor', 'ms'=>'int'], +'MongoGridFSCursor::valid' => ['bool'], +'MongoGridfsFile::__construct' => ['void', 'gridfs'=>'MongoGridFS', 'file'=>'array'], +'MongoGridFSFile::getBytes' => ['string'], +'MongoGridFSFile::getFilename' => ['string'], +'MongoGridFSFile::getResource' => ['resource'], +'MongoGridFSFile::getSize' => ['int'], +'MongoGridFSFile::write' => ['int', 'filename='=>'string'], +'MongoId::__construct' => ['void', 'id='=>'string|MongoId'], +'MongoId::__set_state' => ['MongoId', 'props'=>'array'], +'MongoId::__toString' => ['string'], +'MongoId::getHostname' => ['string'], +'MongoId::getInc' => ['int'], +'MongoId::getPID' => ['int'], +'MongoId::getTimestamp' => ['int'], +'MongoId::isValid' => ['bool', 'value'=>'mixed'], +'MongoInsertBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'], +'MongoInt32::__construct' => ['void', 'value'=>'string'], +'MongoInt32::__toString' => ['string'], +'MongoInt64::__construct' => ['void', 'value'=>'string'], +'MongoInt64::__toString' => ['string'], +'MongoLog::getCallback' => ['callable'], +'MongoLog::getLevel' => ['int'], +'MongoLog::getModule' => ['int'], +'MongoLog::setCallback' => ['void', 'log_function'=>'callable'], +'MongoLog::setLevel' => ['void', 'level'=>'int'], +'MongoLog::setModule' => ['void', 'module'=>'int'], +'MongoPool::getSize' => ['int'], +'MongoPool::info' => ['array'], +'MongoPool::setSize' => ['bool', 'size'=>'int'], +'MongoRegex::__construct' => ['void', 'regex'=>'string'], +'MongoRegex::__toString' => ['string'], +'MongoResultException::__clone' => ['void'], +'MongoResultException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'MongoResultException::__toString' => ['string'], +'MongoResultException::__wakeup' => ['void'], +'MongoResultException::getCode' => ['int'], +'MongoResultException::getDocument' => ['array'], +'MongoResultException::getFile' => ['string'], +'MongoResultException::getLine' => ['int'], +'MongoResultException::getMessage' => ['string'], +'MongoResultException::getPrevious' => ['Exception|Throwable'], +'MongoResultException::getTrace' => ['array'], +'MongoResultException::getTraceAsString' => ['string'], +'MongoTimestamp::__construct' => ['void', 'sec='=>'int', 'inc='=>'int'], +'MongoTimestamp::__toString' => ['string'], +'MongoUpdateBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'write_options='=>'array'], +'MongoUpdateBatch::add' => ['bool', 'item'=>'array'], +'MongoUpdateBatch::execute' => ['array', 'write_options'=>'array'], +'MongoWriteBatch::__construct' => ['void', 'collection'=>'MongoCollection', 'batch_type'=>'string', 'write_options'=>'array'], +'MongoWriteBatch::add' => ['bool', 'item'=>'array'], +'MongoWriteBatch::execute' => ['array', 'write_options'=>'array'], +'MongoWriteConcernException::__clone' => ['void'], +'MongoWriteConcernException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'MongoWriteConcernException::__toString' => ['string'], +'MongoWriteConcernException::__wakeup' => ['void'], +'MongoWriteConcernException::getCode' => ['int'], +'MongoWriteConcernException::getDocument' => ['array'], +'MongoWriteConcernException::getFile' => ['string'], +'MongoWriteConcernException::getLine' => ['int'], +'MongoWriteConcernException::getMessage' => ['string'], +'MongoWriteConcernException::getPrevious' => ['Exception|Throwable'], +'MongoWriteConcernException::getTrace' => ['array'], +'MongoWriteConcernException::getTraceAsString' => ['string'], +'monitor_custom_event' => ['void', 'class'=>'class', 'text'=>'text', 'severe='=>'severe', 'user_data='=>'user_data'], +'monitor_httperror_event' => ['void', 'error_code'=>'error_code', 'url'=>'url', 'severe='=>'severe'], +'monitor_license_info' => ['array'], +'monitor_pass_error' => ['void', 'errno'=>'', 'errstr'=>'', 'errfile'=>'', 'errline'=>''], +'monitor_set_aggregation_hint' => ['void', 'hint'=>'hint'], +'move_uploaded_file' => ['bool', 'path'=>'string', 'new_path'=>'string'], +'mqseries_back' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_begin' => ['void', 'hconn'=>'resource', 'beginoptions'=>'array', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_close' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'options'=>'int', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_cmit' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_conn' => ['void', 'qmanagername'=>'string', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_connx' => ['void', 'qmanagername'=>'string', 'connoptions'=>'array', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_disc' => ['void', 'hconn'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_get' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'md'=>'array', 'gmo'=>'array', 'bufferlength'=>'int', 'msg'=>'string', 'data_length'=>'int', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_inq' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'selectorcount'=>'int', 'selectors'=>'array', 'intattrcount'=>'int', 'intattr'=>'resource', 'charattrlength'=>'int', 'charattr'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_open' => ['void', 'hconn'=>'resource', 'objdesc'=>'array', 'option'=>'int', 'hobj'=>'resource', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_put' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'md'=>'array', 'pmo'=>'array', 'message'=>'string', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_put1' => ['void', 'hconn'=>'resource', 'objdesc'=>'resource', 'msgdesc'=>'resource', 'pmo'=>'resource', 'buffer'=>'string', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_set' => ['void', 'hconn'=>'resource', 'hobj'=>'resource', 'selectorcount'=>'int', 'selectors'=>'array', 'intattrcount'=>'int', 'intattrs'=>'array', 'charattrlength'=>'int', 'charattrs'=>'array', 'compcode'=>'resource', 'reason'=>'resource'], +'mqseries_strerror' => ['string', 'reason'=>'int'], +'ms_GetErrorObj' => ['errorObj'], +'ms_GetVersion' => ['string'], +'ms_GetVersionInt' => ['int'], +'ms_iogetStdoutBufferBytes' => ['int'], +'ms_iogetstdoutbufferstring' => ['void'], +'ms_ioinstallstdinfrombuffer' => ['void'], +'ms_ioinstallstdouttobuffer' => ['void'], +'ms_ioresethandlers' => ['void'], +'ms_iostripstdoutbuffercontentheaders' => ['void'], +'ms_iostripstdoutbuffercontenttype' => ['string'], +'ms_ResetErrorList' => ['void'], +'ms_TokenizeMap' => ['array', 'map_file_name'=>'string'], +'msession_connect' => ['bool', 'host'=>'string', 'port'=>'string'], +'msession_count' => ['int'], +'msession_create' => ['bool', 'session'=>'string', 'classname='=>'string', 'data='=>'string'], +'msession_destroy' => ['bool', 'name'=>'string'], +'msession_disconnect' => ['void'], +'msession_find' => ['array', 'name'=>'string', 'value'=>'string'], +'msession_get' => ['string', 'session'=>'string', 'name'=>'string', 'value'=>'string'], +'msession_get_array' => ['array', 'session'=>'string'], +'msession_get_data' => ['string', 'session'=>'string'], +'msession_inc' => ['string', 'session'=>'string', 'name'=>'string'], +'msession_list' => ['array'], +'msession_listvar' => ['array', 'name'=>'string'], +'msession_lock' => ['int', 'name'=>'string'], +'msession_plugin' => ['string', 'session'=>'string', 'val'=>'string', 'param='=>'string'], +'msession_randstr' => ['string', 'param'=>'int'], +'msession_set' => ['bool', 'session'=>'string', 'name'=>'string', 'value'=>'string'], +'msession_set_array' => ['void', 'session'=>'string', 'tuples'=>'array'], +'msession_set_data' => ['bool', 'session'=>'string', 'value'=>'string'], +'msession_timeout' => ['int', 'session'=>'string', 'param='=>'int'], +'msession_uniq' => ['string', 'param'=>'int', 'classname='=>'string', 'data='=>'string'], +'msession_unlock' => ['int', 'session'=>'string', 'key'=>'int'], +'msg_get_queue' => ['resource', 'key'=>'int', 'perms='=>'int'], +'msg_queue_exists' => ['bool', 'key'=>'int'], +'msg_receive' => ['bool', 'queue'=>'resource', 'desiredmsgtype'=>'int', '&w_msgtype'=>'int', 'maxsize'=>'int', '&w_message'=>'mixed', 'unserialize='=>'bool', 'flags='=>'int', '&w_errorcode='=>'int'], +'msg_remove_queue' => ['bool', 'queue'=>'resource'], +'msg_send' => ['bool', 'queue'=>'resource', 'msgtype'=>'int', 'message'=>'mixed', 'serialize='=>'bool', 'blocking='=>'bool', '&w_errorcode='=>'int'], +'msg_set_queue' => ['bool', 'queue'=>'resource', 'data'=>'array'], +'msg_stat_queue' => ['array', 'queue'=>'resource'], +'msgfmt_create' => ['MessageFormatter', 'locale'=>'string', 'pattern'=>'string'], +'msgfmt_format' => ['string', 'fmt'=>'messageformatter', 'args'=>'array'], +'msgfmt_format_message' => ['string', 'locale'=>'string', 'pattern'=>'string', 'args'=>'array'], +'msgfmt_get_error_code' => ['int', 'fmt'=>'messageformatter'], +'msgfmt_get_error_message' => ['string', 'fmt'=>'messageformatter'], +'msgfmt_get_locale' => ['string', 'formatter'=>'messageformatter'], +'msgfmt_get_pattern' => ['string', 'fmt'=>'messageformatter'], +'msgfmt_parse' => ['array', 'fmt'=>'messageformatter', 'value'=>'string'], +'msgfmt_parse_message' => ['array', 'locale'=>'string', 'pattern'=>'string', 'source'=>'string'], +'msgfmt_set_pattern' => ['bool', 'fmt'=>'messageformatter', 'pattern'=>'string'], +'msql_affected_rows' => ['int', 'result'=>'resource'], +'msql_close' => ['bool', 'link_identifier='=>'?resource'], +'msql_connect' => ['resource', 'hostname='=>'string'], +'msql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], +'msql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'], +'msql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'?resource'], +'msql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], +'msql_error' => ['string'], +'msql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], +'msql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], +'msql_fetch_object' => ['object', 'result'=>'resource'], +'msql_fetch_row' => ['array', 'result'=>'resource'], +'msql_field_flags' => ['string', 'result'=>'resource', 'field_offset'=>'int'], +'msql_field_len' => ['int', 'result'=>'resource', 'field_offset'=>'int'], +'msql_field_name' => ['string', 'result'=>'resource', 'field_offset'=>'int'], +'msql_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'], +'msql_field_table' => ['int', 'result'=>'resource', 'field_offset'=>'int'], +'msql_field_type' => ['string', 'result'=>'resource', 'field_offset'=>'int'], +'msql_free_result' => ['bool', 'result'=>'resource'], +'msql_list_dbs' => ['resource', 'link_identifier='=>'?resource'], +'msql_list_fields' => ['resource', 'database'=>'string', 'tablename'=>'string', 'link_identifier='=>'?resource'], +'msql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'?resource'], +'msql_num_fields' => ['int', 'result'=>'resource'], +'msql_num_rows' => ['int', 'query_identifier'=>'resource'], +'msql_pconnect' => ['resource', 'hostname='=>'string'], +'msql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'?resource'], +'msql_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field='=>'mixed'], +'msql_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'?resource'], +'mssql_bind' => ['bool', 'stmt'=>'resource', 'param_name'=>'string', 'var'=>'mixed', 'type'=>'int', 'is_output='=>'bool', 'is_null='=>'bool', 'maxlen='=>'int'], +'mssql_close' => ['bool', 'link_identifier='=>'resource'], +'mssql_connect' => ['resource', 'servername='=>'string', 'username='=>'string', 'password='=>'string', 'new_link='=>'bool'], +'mssql_data_seek' => ['bool', 'result_identifier'=>'resource', 'row_number'=>'int'], +'mssql_execute' => ['mixed', 'stmt'=>'resource', 'skip_results='=>'bool'], +'mssql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], +'mssql_fetch_assoc' => ['array', 'result_id'=>'resource'], +'mssql_fetch_batch' => ['int', 'result'=>'resource'], +'mssql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], +'mssql_fetch_object' => ['object', 'result'=>'resource'], +'mssql_fetch_row' => ['array', 'result'=>'resource'], +'mssql_field_length' => ['int', 'result'=>'resource', 'offset='=>'int'], +'mssql_field_name' => ['string', 'result'=>'resource', 'offset='=>'int'], +'mssql_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'], +'mssql_field_type' => ['string', 'result'=>'resource', 'offset='=>'int'], +'mssql_free_result' => ['bool', 'result'=>'resource'], +'mssql_free_statement' => ['bool', 'stmt'=>'resource'], +'mssql_get_last_message' => ['string'], +'mssql_guid_string' => ['string', 'binary'=>'string', 'short_format='=>'bool'], +'mssql_init' => ['resource', 'sp_name'=>'string', 'link_identifier='=>'resource'], +'mssql_min_error_severity' => ['void', 'severity'=>'int'], +'mssql_min_message_severity' => ['void', 'severity'=>'int'], +'mssql_next_result' => ['bool', 'result_id'=>'resource'], +'mssql_num_fields' => ['int', 'result'=>'resource'], +'mssql_num_rows' => ['int', 'result'=>'resource'], +'mssql_pconnect' => ['resource', 'servername='=>'string', 'username='=>'string', 'password='=>'string', 'new_link='=>'bool'], +'mssql_query' => ['mixed', 'query'=>'string', 'link_identifier='=>'resource', 'batch_size='=>'int'], +'mssql_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field'=>'mixed'], +'mssql_rows_affected' => ['int', 'link_identifier'=>'resource'], +'mssql_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], +'mt_getrandmax' => ['int'], +'mt_rand' => ['int', 'min'=>'int', 'max'=>'int'], +'mt_rand\'1' => ['int'], +'mt_srand' => ['void', 'seed='=>'int', 'mode='=>'int'], +'MultipleIterator::__construct' => ['void', 'flags='=>'int'], +'MultipleIterator::attachIterator' => ['void', 'iterator'=>'iterator', 'infos='=>'string'], +'MultipleIterator::containsIterator' => ['bool', 'iterator'=>'iterator'], +'MultipleIterator::countIterators' => ['int'], +'MultipleIterator::current' => ['array'], +'MultipleIterator::detachIterator' => ['void', 'iterator'=>'iterator'], +'MultipleIterator::getFlags' => ['int'], +'MultipleIterator::key' => ['array'], +'MultipleIterator::next' => ['void'], +'MultipleIterator::rewind' => ['void'], +'MultipleIterator::setFlags' => ['int', 'flags'=>'int'], +'MultipleIterator::valid' => ['bool'], +'Mutex::create' => ['long', 'lock='=>'bool'], +'Mutex::destroy' => ['bool', 'mutex'=>'long'], +'Mutex::lock' => ['bool', 'mutex'=>'long'], +'Mutex::trylock' => ['bool', 'mutex'=>'long'], +'Mutex::unlock' => ['bool', 'mutex'=>'long', 'destroy='=>'bool'], +'mysql_affected_rows' => ['int', 'link_identifier='=>'resource'], +'mysql_client_encoding' => ['string', 'link_identifier='=>'resource'], +'mysql_close' => ['bool', 'link_identifier='=>'resource'], +'mysql_connect' => ['resource', 'server='=>'string', 'username='=>'string', 'password='=>'string', 'new_link='=>'bool', 'client_flags='=>'int'], +'mysql_create_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], +'mysql_data_seek' => ['bool', 'result'=>'resource', 'row_number'=>'int'], +'mysql_db_name' => ['string', 'result'=>'resource', 'row'=>'int', 'field='=>'mixed'], +'mysql_db_query' => ['resource', 'database'=>'string', 'query'=>'string', 'link_identifier='=>'resource'], +'mysql_drop_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], +'mysql_errno' => ['int', 'link_identifier='=>'resource'], +'mysql_error' => ['string', 'link_identifier='=>'resource'], +'mysql_escape_string' => ['string', 'unescaped_string'=>'string'], +'mysql_fetch_array' => ['array', 'result'=>'resource', 'result_type='=>'int'], +'mysql_fetch_assoc' => ['array', 'result'=>'resource'], +'mysql_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], +'mysql_fetch_lengths' => ['array', 'result'=>'resource'], +'mysql_fetch_object' => ['object', 'result'=>'resource', 'class_name='=>'string', 'params='=>'array'], +'mysql_fetch_row' => ['array', 'result'=>'resource'], +'mysql_field_flags' => ['string', 'result'=>'resource', 'field_offset'=>'int'], +'mysql_field_len' => ['int', 'result'=>'resource', 'field_offset'=>'int'], +'mysql_field_name' => ['string', 'result'=>'resource', 'field_offset'=>'int'], +'mysql_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'], +'mysql_field_table' => ['string', 'result'=>'resource', 'field_offset'=>'int'], +'mysql_field_type' => ['string', 'result'=>'resource', 'field_offset'=>'int'], +'mysql_free_result' => ['bool', 'result'=>'resource'], +'mysql_get_client_info' => ['string'], +'mysql_get_host_info' => ['string', 'link_identifier='=>'resource'], +'mysql_get_proto_info' => ['int', 'link_identifier='=>'resource'], +'mysql_get_server_info' => ['string', 'link_identifier='=>'resource'], +'mysql_info' => ['string', 'link_identifier='=>'resource'], +'mysql_insert_id' => ['int', 'link_identifier='=>'resource'], +'mysql_list_dbs' => ['resource', 'link_identifier='=>'resource'], +'mysql_list_fields' => ['resource', 'database_name'=>'string', 'table_name'=>'string', 'link_identifier='=>'resource'], +'mysql_list_processes' => ['resource', 'link_identifier='=>'resource'], +'mysql_list_tables' => ['resource', 'database'=>'string', 'link_identifier='=>'resource'], +'mysql_num_fields' => ['int', 'result'=>'resource'], +'mysql_num_rows' => ['int', 'result'=>'resource'], +'mysql_pconnect' => ['resource', 'server='=>'string', 'username='=>'string', 'password='=>'string', 'client_flags='=>'int'], +'mysql_ping' => ['bool', 'link_identifier='=>'resource'], +'mysql_query' => ['resource', 'query'=>'string', 'link_identifier='=>'resource'], +'mysql_real_escape_string' => ['string', 'unescaped_string'=>'string', 'link_identifier='=>'resource'], +'mysql_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field='=>'mixed'], +'mysql_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], +'mysql_set_charset' => ['bool', 'charset'=>'string', 'link_identifier='=>'resource'], +'mysql_stat' => ['string', 'link_identifier='=>'resource'], +'mysql_tablename' => ['string', 'result'=>'resource', 'i'=>'int'], +'mysql_thread_id' => ['int', 'link_identifier='=>'resource'], +'mysql_unbuffered_query' => ['resource', 'query'=>'string', 'link_identifier='=>'resource'], +'mysqli::__construct' => ['void', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], +'mysqli::autocommit' => ['bool', 'mode'=>'bool'], +'mysqli::begin_transaction' => ['bool', 'flags='=>'int', 'name='=>'string'], +'mysqli::change_user' => ['bool', 'user'=>'string', 'password'=>'string', 'database'=>'string'], +'mysqli::character_set_name' => ['string'], +'mysqli::close' => ['bool'], +'mysqli::commit' => ['bool', 'flags='=>'int', 'name='=>'string'], +'mysqli::debug' => ['bool', 'message'=>'string'], +'mysqli::disable_reads_from_master' => ['bool'], +'mysqli::dump_debug_info' => ['bool'], +'mysqli::get_charset' => ['object'], +'mysqli::get_client_info' => ['string'], +'mysqli::get_connection_stats' => ['array|false'], +'mysqli::get_warnings' => ['mysqli_warning'], +'mysqli::init' => ['mysqli'], +'mysqli::kill' => ['bool', 'processid'=>'int'], +'mysqli::more_results' => ['bool'], +'mysqli::multi_query' => ['bool', 'query'=>'string'], +'mysqli::next_result' => ['bool'], +'mysqli::options' => ['bool', 'option'=>'int', 'value'=>'mixed'], +'mysqli::ping' => ['bool'], +'mysqli::poll' => ['int|false', 'read'=>'array', 'error'=>'array', 'reject'=>'array', 'sec'=>'int', 'usec='=>'int'], +'mysqli::prepare' => ['mysqli_stmt|false', 'query'=>'string'], +'mysqli::query' => ['bool|mysqli_result', 'query'=>'string', 'resultmode='=>'int'], +'mysqli::real_connect' => ['bool', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string', 'flags='=>'int'], +'mysqli::real_escape_string' => ['string', 'escapestr'=>'string'], +'mysqli::real_query' => ['bool', 'query'=>'string'], +'mysqli::reap_async_query' => ['mysqli_result|false'], +'mysqli::refresh' => ['bool', 'options'=>'int'], +'mysqli::release_savepoint' => ['bool', 'name'=>'string'], +'mysqli::rollback' => ['bool', 'flags='=>'int', 'name='=>'string'], +'mysqli::rpl_query_type' => ['int', 'query'=>'string'], +'mysqli::savepoint' => ['bool', 'name'=>'string'], +'mysqli::select_db' => ['bool', 'dbname'=>'string'], +'mysqli::send_query' => ['bool', 'query'=>'string'], +'mysqli::set_charset' => ['bool', 'charset'=>'string'], +'mysqli::set_local_infile_default' => ['void'], +'mysqli::set_local_infile_handler' => ['bool', 'read_func='=>'callable'], +'mysqli::ssl_set' => ['bool', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], +'mysqli::stat' => ['string|false'], +'mysqli::stmt_init' => ['mysqli_stmt'], +'mysqli::store_result' => ['mysqli_result|false', 'option='=>'int'], +'mysqli::thread_safe' => ['bool'], +'mysqli::use_result' => ['mysqli_result|false'], +'mysqli_affected_rows' => ['int', 'link'=>'mysqli'], +'mysqli_autocommit' => ['bool', 'link'=>'mysqli', 'mode'=>'bool'], +'mysqli_begin_transaction' => ['bool', 'link'=>'mysqli', 'flags'=>'int', 'name'=>'string'], +'mysqli_change_user' => ['bool', 'link'=>'mysqli', 'user'=>'string', 'password'=>'string', 'database'=>'string'], +'mysqli_character_set_name' => ['string', 'link'=>'mysqli'], +'mysqli_close' => ['bool', 'link'=>'mysqli'], +'mysqli_commit' => ['bool', 'link'=>'mysqli', 'flags='=>'int', 'name='=>'string'], +'mysqli_connect' => ['mysqli|false', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string'], +'mysqli_connect_errno' => ['int'], +'mysqli_connect_error' => ['string'], +'mysqli_data_seek' => ['bool', 'result'=>'mysqli_result', 'offset'=>'int'], +'mysqli_debug' => ['bool', 'message'=>'string'], +'mysqli_disable_reads_from_master' => ['bool', 'link'=>'mysqli'], +'mysqli_disable_rpl_parse' => ['bool', 'link'=>'mysqli'], +'mysqli_driver::embedded_server_end' => ['void'], +'mysqli_driver::embedded_server_start' => ['bool', 'start'=>'int', 'arguments'=>'array', 'groups'=>'array'], +'mysqli_dump_debug_info' => ['bool', 'link'=>'mysqli'], +'mysqli_embedded_server_end' => ['void'], +'mysqli_embedded_server_start' => ['bool', 'start'=>'int', 'arguments'=>'array', 'groups'=>'array'], +'mysqli_enable_reads_from_master' => ['bool', 'link'=>'mysqli'], +'mysqli_enable_rpl_parse' => ['bool', 'link'=>'mysqli'], +'mysqli_errno' => ['int', 'link'=>'mysqli'], +'mysqli_error' => ['string', 'link'=>'mysqli'], +'mysqli_error_list' => ['array', 'connection'=>'mysqli'], +'mysqli_fetch_all' => ['array', 'result'=>'mysqli_result', 'resulttype='=>'int'], +'mysqli_fetch_array' => ['array|null', 'result'=>'mysqli_result', 'resulttype='=>'int'], +'mysqli_fetch_assoc' => ['array|null', 'result'=>'mysqli_result'], +'mysqli_fetch_field' => ['object|false', 'result'=>'mysqli_result'], +'mysqli_fetch_field_direct' => ['object|false', 'result'=>'mysqli_result', 'fieldnr'=>'int'], +'mysqli_fetch_fields' => ['array|false', 'result'=>'mysqli_result'], +'mysqli_fetch_lengths' => ['array|false', 'result'=>'mysqli_result'], +'mysqli_fetch_object' => ['object|null', 'result'=>'mysqli_result', 'class_name='=>'string', 'params='=>'?array'], +'mysqli_fetch_row' => ['array|null', 'result'=>'mysqli_result'], +'mysqli_field_count' => ['int', 'link'=>'mysqli'], +'mysqli_field_seek' => ['bool', 'result'=>'mysqli_result', 'fieldnr'=>'int'], +'mysqli_field_tell' => ['int', 'result'=>'mysqli_result'], +'mysqli_free_result' => ['void', 'link'=>'mysqli_result'], +'mysqli_get_cache_stats' => ['array'], +'mysqli_get_charset' => ['object', 'link'=>'mysqli'], +'mysqli_get_client_info' => ['string', 'link'=>'mysqli'], +'mysqli_get_client_stats' => ['array|false'], +'mysqli_get_client_version' => ['int', 'link'=>'mysqli'], +'mysqli_get_connection_stats' => ['array|false', 'link'=>'mysqli'], +'mysqli_get_host_info' => ['string', 'link'=>'mysqli'], +'mysqli_get_links_stats' => ['array'], +'mysqli_get_proto_info' => ['int', 'link'=>'mysqli'], +'mysqli_get_server_info' => ['string', 'link'=>'mysqli'], +'mysqli_get_server_version' => ['int', 'link'=>'mysqli'], +'mysqli_get_warnings' => ['mysqli_warning', 'link'=>'mysqli'], +'mysqli_info' => ['?string', 'link'=>'mysqli'], +'mysqli_init' => ['mysqli'], +'mysqli_insert_id' => ['int|string', 'link'=>'mysqli'], +'mysqli_kill' => ['bool', 'link'=>'mysqli', 'processid'=>'int'], +'mysqli_link_construct' => ['object'], +'mysqli_master_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], +'mysqli_more_results' => ['bool', 'link'=>'mysqli'], +'mysqli_multi_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], +'mysqli_next_result' => ['bool', 'link'=>'mysqli'], +'mysqli_num_fields' => ['int', 'link'=>'mysqli_result'], +'mysqli_num_rows' => ['int', 'link'=>'mysqli_result'], +'mysqli_options' => ['bool', 'link'=>'mysqli', 'option'=>'int', 'value'=>'mixed'], +'mysqli_ping' => ['bool', 'link'=>'mysqli'], +'mysqli_poll' => ['int|false', 'read'=>'array', 'error'=>'array', 'reject'=>'array', 'sec'=>'int', 'usec='=>'int'], +'mysqli_prepare' => ['mysqli_stmt|false', 'link'=>'mysqli', 'query'=>'string'], +'mysqli_query' => ['mysqli_result|bool', 'link'=>'mysqli', 'query'=>'string', 'resultmode='=>'int'], +'mysqli_real_connect' => ['bool', 'link='=>'mysqli', 'host='=>'string', 'username='=>'string', 'passwd='=>'string', 'dbname='=>'string', 'port='=>'int', 'socket='=>'string', 'flags='=>'int'], +'mysqli_real_escape_string' => ['string', 'link'=>'mysqli', 'escapestr'=>'string'], +'mysqli_real_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], +'mysqli_reap_async_query' => ['mysqli_result|false', 'link'=>'mysqli'], +'mysqli_refresh' => ['bool', 'link'=>'mysqli', 'options'=>'int'], +'mysqli_release_savepoint' => ['bool', 'link'=>'mysqli', 'name'=>'string'], +'mysqli_report' => ['bool', 'flags'=>'int'], +'mysqli_result::__construct' => ['void', 'link'=>'mysqli', 'resultmode='=>'int'], +'mysqli_result::close' => ['void'], +'mysqli_result::data_seek' => ['bool', 'offset'=>'int'], +'mysqli_result::fetch_all' => ['array', 'resulttype='=>'int'], +'mysqli_result::fetch_array' => ['array|null', 'resulttype='=>'int'], +'mysqli_result::fetch_assoc' => ['array|null'], +'mysqli_result::fetch_field' => ['object|false'], +'mysqli_result::fetch_field_direct' => ['object|false', 'fieldnr'=>'int'], +'mysqli_result::fetch_fields' => ['array|false'], +'mysqli_result::fetch_object' => ['object|null', 'class_name='=>'string', 'params='=>'array'], +'mysqli_result::fetch_row' => ['array|null'], +'mysqli_result::field_seek' => ['bool', 'fieldnr'=>'int'], +'mysqli_result::free' => ['void'], +'mysqli_result::free_result' => ['void'], +'mysqli_rollback' => ['bool', 'link'=>'mysqli', 'flags='=>'int', 'name='=>'string'], +'mysqli_rpl_parse_enabled' => ['int', 'link'=>'mysqli'], +'mysqli_rpl_probe' => ['bool', 'link'=>'mysqli'], +'mysqli_rpl_query_type' => ['int', 'link'=>'mysqli', 'query'=>'string'], +'mysqli_savepoint' => ['bool', 'link'=>'mysqli', 'name'=>'string'], +'mysqli_savepoint_libmysql' => ['bool'], +'mysqli_select_db' => ['bool', 'link'=>'mysqli', 'dbname'=>'string'], +'mysqli_send_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], +'mysqli_set_charset' => ['bool', 'link'=>'mysqli', 'charset'=>'string'], +'mysqli_set_local_infile_default' => ['void', 'link'=>'mysqli'], +'mysqli_set_local_infile_handler' => ['bool', 'link'=>'mysqli', 'read_func'=>'callable'], +'mysqli_slave_query' => ['bool', 'link'=>'mysqli', 'query'=>'string'], +'mysqli_sqlstate' => ['string', 'link'=>'mysqli'], +'mysqli_ssl_set' => ['bool', 'link'=>'mysqli', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], +'mysqli_stat' => ['string|false', 'link'=>'mysqli'], +'mysqli_stmt::__construct' => ['void', 'query='=>'string'], +'mysqli_stmt::attr_get' => ['false|int', 'attr'=>'int'], +'mysqli_stmt::attr_set' => ['bool', 'attr'=>'int', 'mode'=>'int'], +'mysqli_stmt::bind_param' => ['bool', 'types'=>'string', 'var1'=>'mixed', '...args='=>'mixed'], +'mysqli_stmt::bind_result' => ['bool', 'var1'=>'mixed', '...args='=>'mixed'], +'mysqli_stmt::close' => ['bool'], +'mysqli_stmt::data_seek' => ['void', 'offset'=>'int'], +'mysqli_stmt::execute' => ['bool'], +'mysqli_stmt::fetch' => ['bool'], +'mysqli_stmt::free_result' => ['void'], +'mysqli_stmt::get_result' => ['mysqli_result|false'], +'mysqli_stmt::get_warnings' => ['object'], +'mysqli_stmt::more_results' => ['bool'], +'mysqli_stmt::next_result' => ['bool'], +'mysqli_stmt::num_rows' => ['int'], +'mysqli_stmt::prepare' => ['bool', 'query'=>'string'], +'mysqli_stmt::reset' => ['bool'], +'mysqli_stmt::result_metadata' => ['mysqli_result|false'], +'mysqli_stmt::send_long_data' => ['bool', 'param_nr'=>'int', 'data'=>'string'], +'mysqli_stmt::store_result' => ['bool'], +'mysqli_stmt_affected_rows' => ['int|string', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_attr_get' => ['int|false', 'stmt'=>'mysqli_stmt', 'attr'=>'int'], +'mysqli_stmt_attr_set' => ['bool', 'stmt'=>'mysqli_stmt', 'attr'=>'int', 'mode'=>'int'], +'mysqli_stmt_bind_param' => ['bool', 'stmt'=>'mysqli_stmt', 'types'=>'string', 'var1'=>'mixed', '...args='=>'mixed'], +'mysqli_stmt_bind_result' => ['bool', 'stmt'=>'mysqli_stmt', 'var1='=>'mixed', '...args='=>'mixed'], +'mysqli_stmt_close' => ['bool', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_data_seek' => ['void', 'stmt'=>'mysqli_stmt', 'offset'=>'int'], +'mysqli_stmt_errno' => ['int', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_error' => ['string', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_error_list' => ['array', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_execute' => ['bool', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_fetch' => ['bool', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_field_count' => ['int', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_free_result' => ['void', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_get_result' => ['mysqli_result|false', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_get_warnings' => ['object', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_init' => ['mysqli_stmt', 'link'=>'mysqli'], +'mysqli_stmt_insert_id' => ['', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_more_results' => ['bool', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_next_result' => ['bool', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_num_rows' => ['int', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_param_count' => ['int', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_prepare' => ['bool', 'stmt'=>'mysqli_stmt', 'query'=>'string'], +'mysqli_stmt_reset' => ['bool', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_result_metadata' => ['mysqli_result|false', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_send_long_data' => ['bool', 'stmt'=>'mysqli_stmt', 'param_nr'=>'int', 'data'=>'string'], +'mysqli_stmt_sqlstate' => ['string', 'stmt'=>'mysqli_stmt'], +'mysqli_stmt_store_result' => ['bool', 'stmt'=>'mysqli_stmt'], +'mysqli_store_result' => ['mysqli_result|false', 'link'=>'mysqli', 'option='=>'int'], +'mysqli_thread_id' => ['int', 'link'=>'mysqli'], +'mysqli_thread_safe' => ['bool'], +'mysqli_use_result' => ['mysqli_result|false', 'link'=>'mysqli'], +'mysqli_warning::__construct' => ['void'], +'mysqli_warning::next' => ['void'], +'mysqli_warning_count' => ['int', 'link'=>'mysqli'], +'mysqlnd_memcache_get_config' => ['array', 'connection'=>'mixed'], +'mysqlnd_memcache_set' => ['bool', 'mysql_connection'=>'mixed', 'memcache_connection='=>'Memcached', 'pattern='=>'string', 'callback='=>'callable'], +'mysqlnd_ms_dump_servers' => ['array', 'connection'=>'mixed'], +'mysqlnd_ms_fabric_select_global' => ['array', 'connection'=>'mixed', 'table_name'=>'mixed'], +'mysqlnd_ms_fabric_select_shard' => ['array', 'connection'=>'mixed', 'table_name'=>'mixed', 'shard_key'=>'mixed'], +'mysqlnd_ms_get_last_gtid' => ['string', 'connection'=>'mixed'], +'mysqlnd_ms_get_last_used_connection' => ['array', 'connection'=>'mixed'], +'mysqlnd_ms_get_stats' => ['array'], +'mysqlnd_ms_match_wild' => ['bool', 'table_name'=>'string', 'wildcard'=>'string'], +'mysqlnd_ms_query_is_select' => ['int', 'query'=>'string'], +'mysqlnd_ms_set_qos' => ['bool', 'connection'=>'mixed', 'service_level'=>'int', 'service_level_option='=>'int', 'option_value='=>'mixed'], +'mysqlnd_ms_set_user_pick_server' => ['bool', 'function'=>'string'], +'mysqlnd_ms_xa_begin' => ['int', 'connection'=>'mixed', 'gtrid'=>'string', 'timeout='=>'int'], +'mysqlnd_ms_xa_commit' => ['int', 'connection'=>'mixed', 'gtrid'=>'string'], +'mysqlnd_ms_xa_gc' => ['int', 'connection'=>'mixed', 'gtrid='=>'string', 'ignore_max_retries='=>'bool'], +'mysqlnd_ms_xa_rollback' => ['int', 'connection'=>'mixed', 'gtrid'=>'string'], +'mysqlnd_qc_change_handler' => ['bool', 'handler'=>''], +'mysqlnd_qc_clear_cache' => ['bool'], +'mysqlnd_qc_get_available_handlers' => ['array'], +'mysqlnd_qc_get_cache_info' => ['array'], +'mysqlnd_qc_get_core_stats' => ['array'], +'mysqlnd_qc_get_handler' => ['array'], +'mysqlnd_qc_get_normalized_query_trace_log' => ['array'], +'mysqlnd_qc_get_query_trace_log' => ['array'], +'mysqlnd_qc_set_cache_condition' => ['bool', 'condition_type'=>'int', 'condition'=>'mixed', 'condition_option'=>'mixed'], +'mysqlnd_qc_set_is_select' => ['mixed', 'callback'=>'string'], +'mysqlnd_qc_set_storage_handler' => ['bool', 'handler'=>'string'], +'mysqlnd_qc_set_user_handlers' => ['bool', 'get_hash'=>'string', 'find_query_in_cache'=>'string', 'return_to_cache'=>'string', 'add_query_to_cache_if_not_exists'=>'string', 'query_is_select'=>'string', 'update_query_run_time_stats'=>'string', 'get_stats'=>'string', 'clear_cache'=>'string'], +'mysqlnd_uh_convert_to_mysqlnd' => ['resource', '&rw_mysql_connection'=>'mysqli'], +'mysqlnd_uh_set_connection_proxy' => ['bool', '&rw_connection_proxy'=>'MysqlndUhConnection', '&rw_mysqli_connection='=>'mysqli'], +'mysqlnd_uh_set_statement_proxy' => ['bool', '&rw_statement_proxy'=>'MysqlndUhStatement'], +'MysqlndUhConnection::__construct' => ['void'], +'MysqlndUhConnection::changeUser' => ['bool', 'connection'=>'mysqlnd_connection', 'user'=>'string', 'password'=>'string', 'database'=>'string', 'silent'=>'bool', 'passwd_len'=>'int'], +'MysqlndUhConnection::charsetName' => ['string', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::close' => ['bool', 'connection'=>'mysqlnd_connection', 'close_type'=>'int'], +'MysqlndUhConnection::connect' => ['bool', 'connection'=>'mysqlnd_connection', 'host'=>'string', 'use'=>'string', 'password'=>'string', 'database'=>'string', 'port'=>'int', 'socket'=>'string', 'mysql_flags'=>'int'], +'MysqlndUhConnection::endPSession' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::escapeString' => ['string', 'connection'=>'mysqlnd_connection', 'escape_string'=>'string'], +'MysqlndUhConnection::getAffectedRows' => ['int', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getErrorNumber' => ['int', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getErrorString' => ['string', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getFieldCount' => ['int', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getHostInformation' => ['string', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getLastInsertId' => ['int', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getLastMessage' => ['void', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getProtocolInformation' => ['string', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getServerInformation' => ['string', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getServerStatistics' => ['string', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getServerVersion' => ['int', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getSqlstate' => ['string', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getStatistics' => ['array', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getThreadId' => ['int', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::getWarningCount' => ['int', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::init' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::killConnection' => ['bool', 'connection'=>'mysqlnd_connection', 'pid'=>'int'], +'MysqlndUhConnection::listFields' => ['array', 'connection'=>'mysqlnd_connection', 'table'=>'string', 'achtung_wild'=>'string'], +'MysqlndUhConnection::listMethod' => ['void', 'connection'=>'mysqlnd_connection', 'query'=>'string', 'achtung_wild'=>'string', 'par1'=>'string'], +'MysqlndUhConnection::moreResults' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::nextResult' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::ping' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::query' => ['bool', 'connection'=>'mysqlnd_connection', 'query'=>'string'], +'MysqlndUhConnection::queryReadResultsetHeader' => ['bool', 'connection'=>'mysqlnd_connection', 'mysqlnd_stmt'=>'mysqlnd_statement'], +'MysqlndUhConnection::reapQuery' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::refreshServer' => ['bool', 'connection'=>'mysqlnd_connection', 'options'=>'int'], +'MysqlndUhConnection::restartPSession' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::selectDb' => ['bool', 'connection'=>'mysqlnd_connection', 'database'=>'string'], +'MysqlndUhConnection::sendClose' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::sendQuery' => ['bool', 'connection'=>'mysqlnd_connection', 'query'=>'string'], +'MysqlndUhConnection::serverDumpDebugInformation' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::setAutocommit' => ['bool', 'connection'=>'mysqlnd_connection', 'mode'=>'int'], +'MysqlndUhConnection::setCharset' => ['bool', 'connection'=>'mysqlnd_connection', 'charset'=>'string'], +'MysqlndUhConnection::setClientOption' => ['bool', 'connection'=>'mysqlnd_connection', 'option'=>'int', 'value'=>'int'], +'MysqlndUhConnection::setServerOption' => ['void', 'connection'=>'mysqlnd_connection', 'option'=>'int'], +'MysqlndUhConnection::shutdownServer' => ['void', 'MYSQLND_UH_RES_MYSQLND_NAME'=>'string', 'level'=>'string'], +'MysqlndUhConnection::simpleCommand' => ['bool', 'connection'=>'mysqlnd_connection', 'command'=>'int', 'arg'=>'string', 'ok_packet'=>'int', 'silent'=>'bool', 'ignore_upsert_status'=>'bool'], +'MysqlndUhConnection::simpleCommandHandleResponse' => ['bool', 'connection'=>'mysqlnd_connection', 'ok_packet'=>'int', 'silent'=>'bool', 'command'=>'int', 'ignore_upsert_status'=>'bool'], +'MysqlndUhConnection::sslSet' => ['bool', 'connection'=>'mysqlnd_connection', 'key'=>'string', 'cert'=>'string', 'ca'=>'string', 'capath'=>'string', 'cipher'=>'string'], +'MysqlndUhConnection::stmtInit' => ['resource', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::storeResult' => ['resource', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::txCommit' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::txRollback' => ['bool', 'connection'=>'mysqlnd_connection'], +'MysqlndUhConnection::useResult' => ['resource', 'connection'=>'mysqlnd_connection'], +'MysqlndUhPreparedStatement::__construct' => ['void'], +'MysqlndUhPreparedStatement::execute' => ['bool', 'statement'=>'mysqlnd_prepared_statement'], +'MysqlndUhPreparedStatement::prepare' => ['bool', 'statement'=>'mysqlnd_prepared_statement', 'query'=>'string'], +'natcasesort' => ['bool', '&rw_array_arg'=>'array'], +'natsort' => ['bool', '&rw_array_arg'=>'array'], +'ncurses_addch' => ['int', 'ch'=>'int'], +'ncurses_addchnstr' => ['int', 's'=>'string', 'n'=>'int'], +'ncurses_addchstr' => ['int', 's'=>'string'], +'ncurses_addnstr' => ['int', 's'=>'string', 'n'=>'int'], +'ncurses_addstr' => ['int', 'text'=>'string'], +'ncurses_assume_default_colors' => ['int', 'fg'=>'int', 'bg'=>'int'], +'ncurses_attroff' => ['int', 'attributes'=>'int'], +'ncurses_attron' => ['int', 'attributes'=>'int'], +'ncurses_attrset' => ['int', 'attributes'=>'int'], +'ncurses_baudrate' => ['int'], +'ncurses_beep' => ['int'], +'ncurses_bkgd' => ['int', 'attrchar'=>'int'], +'ncurses_bkgdset' => ['void', 'attrchar'=>'int'], +'ncurses_border' => ['int', 'left'=>'int', 'right'=>'int', 'top'=>'int', 'bottom'=>'int', 'tl_corner'=>'int', 'tr_corner'=>'int', 'bl_corner'=>'int', 'br_corner'=>'int'], +'ncurses_bottom_panel' => ['int', 'panel'=>'resource'], +'ncurses_can_change_color' => ['bool'], +'ncurses_cbreak' => ['bool'], +'ncurses_clear' => ['bool'], +'ncurses_clrtobot' => ['bool'], +'ncurses_clrtoeol' => ['bool'], +'ncurses_color_content' => ['int', 'color'=>'int', 'r'=>'int', 'g'=>'int', 'b'=>'int'], +'ncurses_color_set' => ['int', 'pair'=>'int'], +'ncurses_curs_set' => ['int', 'visibility'=>'int'], +'ncurses_def_prog_mode' => ['bool'], +'ncurses_def_shell_mode' => ['bool'], +'ncurses_define_key' => ['int', 'definition'=>'string', 'keycode'=>'int'], +'ncurses_del_panel' => ['bool', 'panel'=>'resource'], +'ncurses_delay_output' => ['int', 'milliseconds'=>'int'], +'ncurses_delch' => ['bool'], +'ncurses_deleteln' => ['bool'], +'ncurses_delwin' => ['bool', 'window'=>'resource'], +'ncurses_doupdate' => ['bool'], +'ncurses_echo' => ['bool'], +'ncurses_echochar' => ['int', 'character'=>'int'], +'ncurses_end' => ['int'], +'ncurses_erase' => ['bool'], +'ncurses_erasechar' => ['string'], +'ncurses_filter' => ['void'], +'ncurses_flash' => ['bool'], +'ncurses_flushinp' => ['bool'], +'ncurses_getch' => ['int'], +'ncurses_getmaxyx' => ['void', 'window'=>'resource', 'y'=>'int', 'x'=>'int'], +'ncurses_getmouse' => ['bool', 'mevent'=>'array'], +'ncurses_getyx' => ['void', 'window'=>'resource', 'y'=>'int', 'x'=>'int'], +'ncurses_halfdelay' => ['int', 'tenth'=>'int'], +'ncurses_has_colors' => ['bool'], +'ncurses_has_ic' => ['bool'], +'ncurses_has_il' => ['bool'], +'ncurses_has_key' => ['int', 'keycode'=>'int'], +'ncurses_hide_panel' => ['int', 'panel'=>'resource'], +'ncurses_hline' => ['int', 'charattr'=>'int', 'n'=>'int'], +'ncurses_inch' => ['string'], +'ncurses_init' => ['void'], +'ncurses_init_color' => ['int', 'color'=>'int', 'r'=>'int', 'g'=>'int', 'b'=>'int'], +'ncurses_init_pair' => ['int', 'pair'=>'int', 'fg'=>'int', 'bg'=>'int'], +'ncurses_insch' => ['int', 'character'=>'int'], +'ncurses_insdelln' => ['int', 'count'=>'int'], +'ncurses_insertln' => ['int'], +'ncurses_insstr' => ['int', 'text'=>'string'], +'ncurses_instr' => ['int', 'buffer'=>'string'], +'ncurses_isendwin' => ['bool'], +'ncurses_keyok' => ['int', 'keycode'=>'int', 'enable'=>'bool'], +'ncurses_keypad' => ['int', 'window'=>'resource', 'bf'=>'bool'], +'ncurses_killchar' => ['string'], +'ncurses_longname' => ['string'], +'ncurses_meta' => ['int', 'window'=>'resource', '_8bit'=>'bool'], +'ncurses_mouse_trafo' => ['bool', 'y'=>'int', 'x'=>'int', 'toscreen'=>'bool'], +'ncurses_mouseinterval' => ['int', 'milliseconds'=>'int'], +'ncurses_mousemask' => ['int', 'newmask'=>'int', 'oldmask'=>'int'], +'ncurses_move' => ['int', 'y'=>'int', 'x'=>'int'], +'ncurses_move_panel' => ['int', 'panel'=>'resource', 'startx'=>'int', 'starty'=>'int'], +'ncurses_mvaddch' => ['int', 'y'=>'int', 'x'=>'int', 'c'=>'int'], +'ncurses_mvaddchnstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string', 'n'=>'int'], +'ncurses_mvaddchstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string'], +'ncurses_mvaddnstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string', 'n'=>'int'], +'ncurses_mvaddstr' => ['int', 'y'=>'int', 'x'=>'int', 's'=>'string'], +'ncurses_mvcur' => ['int', 'old_y'=>'int', 'old_x'=>'int', 'new_y'=>'int', 'new_x'=>'int'], +'ncurses_mvdelch' => ['int', 'y'=>'int', 'x'=>'int'], +'ncurses_mvgetch' => ['int', 'y'=>'int', 'x'=>'int'], +'ncurses_mvhline' => ['int', 'y'=>'int', 'x'=>'int', 'attrchar'=>'int', 'n'=>'int'], +'ncurses_mvinch' => ['int', 'y'=>'int', 'x'=>'int'], +'ncurses_mvvline' => ['int', 'y'=>'int', 'x'=>'int', 'attrchar'=>'int', 'n'=>'int'], +'ncurses_mvwaddstr' => ['int', 'window'=>'resource', 'y'=>'int', 'x'=>'int', 'text'=>'string'], +'ncurses_napms' => ['int', 'milliseconds'=>'int'], +'ncurses_new_panel' => ['resource', 'window'=>'resource'], +'ncurses_newpad' => ['resource', 'rows'=>'int', 'cols'=>'int'], +'ncurses_newwin' => ['resource', 'rows'=>'int', 'cols'=>'int', 'y'=>'int', 'x'=>'int'], +'ncurses_nl' => ['bool'], +'ncurses_nocbreak' => ['bool'], +'ncurses_noecho' => ['bool'], +'ncurses_nonl' => ['bool'], +'ncurses_noqiflush' => ['void'], +'ncurses_noraw' => ['bool'], +'ncurses_pair_content' => ['int', 'pair'=>'int', 'f'=>'int', 'b'=>'int'], +'ncurses_panel_above' => ['resource', 'panel'=>'resource'], +'ncurses_panel_below' => ['resource', 'panel'=>'resource'], +'ncurses_panel_window' => ['resource', 'panel'=>'resource'], +'ncurses_pnoutrefresh' => ['int', 'pad'=>'resource', 'pminrow'=>'int', 'pmincol'=>'int', 'sminrow'=>'int', 'smincol'=>'int', 'smaxrow'=>'int', 'smaxcol'=>'int'], +'ncurses_prefresh' => ['int', 'pad'=>'resource', 'pminrow'=>'int', 'pmincol'=>'int', 'sminrow'=>'int', 'smincol'=>'int', 'smaxrow'=>'int', 'smaxcol'=>'int'], +'ncurses_putp' => ['int', 'text'=>'string'], +'ncurses_qiflush' => ['void'], +'ncurses_raw' => ['bool'], +'ncurses_refresh' => ['int', 'ch'=>'int'], +'ncurses_replace_panel' => ['int', 'panel'=>'resource', 'window'=>'resource'], +'ncurses_reset_prog_mode' => ['int'], +'ncurses_reset_shell_mode' => ['int'], +'ncurses_resetty' => ['bool'], +'ncurses_savetty' => ['bool'], +'ncurses_scr_dump' => ['int', 'filename'=>'string'], +'ncurses_scr_init' => ['int', 'filename'=>'string'], +'ncurses_scr_restore' => ['int', 'filename'=>'string'], +'ncurses_scr_set' => ['int', 'filename'=>'string'], +'ncurses_scrl' => ['int', 'count'=>'int'], +'ncurses_show_panel' => ['int', 'panel'=>'resource'], +'ncurses_slk_attr' => ['int'], +'ncurses_slk_attroff' => ['int', 'intarg'=>'int'], +'ncurses_slk_attron' => ['int', 'intarg'=>'int'], +'ncurses_slk_attrset' => ['int', 'intarg'=>'int'], +'ncurses_slk_clear' => ['bool'], +'ncurses_slk_color' => ['int', 'intarg'=>'int'], +'ncurses_slk_init' => ['bool', 'format'=>'int'], +'ncurses_slk_noutrefresh' => ['bool'], +'ncurses_slk_refresh' => ['int'], +'ncurses_slk_restore' => ['int'], +'ncurses_slk_set' => ['bool', 'labelnr'=>'int', 'label'=>'string', 'format'=>'int'], +'ncurses_slk_touch' => ['int'], +'ncurses_standend' => ['int'], +'ncurses_standout' => ['int'], +'ncurses_start_color' => ['int'], +'ncurses_termattrs' => ['bool'], +'ncurses_termname' => ['string'], +'ncurses_timeout' => ['void', 'millisec'=>'int'], +'ncurses_top_panel' => ['int', 'panel'=>'resource'], +'ncurses_typeahead' => ['int', 'fd'=>'int'], +'ncurses_ungetch' => ['int', 'keycode'=>'int'], +'ncurses_ungetmouse' => ['bool', 'mevent'=>'array'], +'ncurses_update_panels' => ['void'], +'ncurses_use_default_colors' => ['bool'], +'ncurses_use_env' => ['void', 'flag'=>'bool'], +'ncurses_use_extended_names' => ['int', 'flag'=>'bool'], +'ncurses_vidattr' => ['int', 'intarg'=>'int'], +'ncurses_vline' => ['int', 'charattr'=>'int', 'n'=>'int'], +'ncurses_waddch' => ['int', 'window'=>'resource', 'ch'=>'int'], +'ncurses_waddstr' => ['int', 'window'=>'resource', 'str'=>'string', 'n='=>'int'], +'ncurses_wattroff' => ['int', 'window'=>'resource', 'attrs'=>'int'], +'ncurses_wattron' => ['int', 'window'=>'resource', 'attrs'=>'int'], +'ncurses_wattrset' => ['int', 'window'=>'resource', 'attrs'=>'int'], +'ncurses_wborder' => ['int', 'window'=>'resource', 'left'=>'int', 'right'=>'int', 'top'=>'int', 'bottom'=>'int', 'tl_corner'=>'int', 'tr_corner'=>'int', 'bl_corner'=>'int', 'br_corner'=>'int'], +'ncurses_wclear' => ['int', 'window'=>'resource'], +'ncurses_wcolor_set' => ['int', 'window'=>'resource', 'color_pair'=>'int'], +'ncurses_werase' => ['int', 'window'=>'resource'], +'ncurses_wgetch' => ['int', 'window'=>'resource'], +'ncurses_whline' => ['int', 'window'=>'resource', 'charattr'=>'int', 'n'=>'int'], +'ncurses_wmouse_trafo' => ['bool', 'window'=>'resource', 'y'=>'int', 'x'=>'int', 'toscreen'=>'bool'], +'ncurses_wmove' => ['int', 'window'=>'resource', 'y'=>'int', 'x'=>'int'], +'ncurses_wnoutrefresh' => ['int', 'window'=>'resource'], +'ncurses_wrefresh' => ['int', 'window'=>'resource'], +'ncurses_wstandend' => ['int', 'window'=>'resource'], +'ncurses_wstandout' => ['int', 'window'=>'resource'], +'ncurses_wvline' => ['int', 'window'=>'resource', 'charattr'=>'int', 'n'=>'int'], +'newrelic_add_custom_parameter' => ['bool', 'key'=>'string', 'value'=>''], +'newrelic_add_custom_tracer' => ['bool', 'function_name'=>'string'], +'newrelic_background_job' => ['void', 'flag='=>'bool'], +'newrelic_capture_params' => ['void', 'enable='=>'bool'], +'newrelic_custom_metric' => ['bool', 'metric_name'=>'string', 'value'=>'float'], +'newrelic_disable_autorum' => ['bool'], +'newrelic_end_of_transaction' => ['void'], +'newrelic_end_transaction' => ['bool', 'ignore='=>'bool'], +'newrelic_get_browser_timing_footer' => ['string', 'include_tags='=>'bool'], +'newrelic_get_browser_timing_header' => ['string', 'include_tags='=>'bool'], +'newrelic_ignore_apdex' => ['void'], +'newrelic_ignore_transaction' => ['void'], +'newrelic_name_transaction' => ['bool', 'name'=>'string'], +'newrelic_notice_error' => ['void', 'message'=>'string', 'exception='=>'Exception|Throwable'], +'newrelic_notice_error\'1' => ['void', 'unused_1'=>'string', 'message'=>'string', 'unused_2'=>'string', 'unused_3'=>'int', 'unused_4='=>''], +'newrelic_record_custom_event' => ['void', 'name'=>'string', 'attributes'=>'array'], +'newrelic_record_datastore_segment' => ['mixed', 'func'=>'callable', 'parameters'=>'array'], +'newrelic_set_appname' => ['bool', 'name'=>'string', 'license='=>'string', 'xmit='=>'bool'], +'newrelic_set_user_attributes' => ['bool', 'user'=>'string', 'account'=>'string', 'product'=>'string'], +'newrelic_start_transaction' => ['bool', 'appname'=>'string', 'license='=>'string'], +'newt_bell' => ['void'], +'newt_button' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'], +'newt_button_bar' => ['resource', 'buttons'=>'array'], +'newt_centered_window' => ['int', 'width'=>'int', 'height'=>'int', 'title='=>'string'], +'newt_checkbox' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'def_value'=>'string', 'seq='=>'string'], +'newt_checkbox_get_value' => ['string', 'checkbox'=>'resource'], +'newt_checkbox_set_flags' => ['void', 'checkbox'=>'resource', 'flags'=>'int', 'sense'=>'int'], +'newt_checkbox_set_value' => ['void', 'checkbox'=>'resource', 'value'=>'string'], +'newt_checkbox_tree' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'flags='=>'int'], +'newt_checkbox_tree_add_item' => ['void', 'checkboxtree'=>'resource', 'text'=>'string', 'data'=>'mixed', 'flags'=>'int', 'index'=>'int', '...args='=>'int'], +'newt_checkbox_tree_find_item' => ['array', 'checkboxtree'=>'resource', 'data'=>'mixed'], +'newt_checkbox_tree_get_current' => ['mixed', 'checkboxtree'=>'resource'], +'newt_checkbox_tree_get_entry_value' => ['string', 'checkboxtree'=>'resource', 'data'=>'mixed'], +'newt_checkbox_tree_get_multi_selection' => ['array', 'checkboxtree'=>'resource', 'seqnum'=>'string'], +'newt_checkbox_tree_get_selection' => ['array', 'checkboxtree'=>'resource'], +'newt_checkbox_tree_multi' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'seq'=>'string', 'flags='=>'int'], +'newt_checkbox_tree_set_current' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed'], +'newt_checkbox_tree_set_entry' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed', 'text'=>'string'], +'newt_checkbox_tree_set_entry_value' => ['void', 'checkboxtree'=>'resource', 'data'=>'mixed', 'value'=>'string'], +'newt_checkbox_tree_set_width' => ['void', 'checkbox_tree'=>'resource', 'width'=>'int'], +'newt_clear_key_buffer' => ['void'], +'newt_cls' => ['void'], +'newt_compact_button' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'], +'newt_component_add_callback' => ['void', 'component'=>'resource', 'func_name'=>'mixed', 'data'=>'mixed'], +'newt_component_takes_focus' => ['void', 'component'=>'resource', 'takes_focus'=>'bool'], +'newt_create_grid' => ['resource', 'cols'=>'int', 'rows'=>'int'], +'newt_cursor_off' => ['void'], +'newt_cursor_on' => ['void'], +'newt_delay' => ['void', 'microseconds'=>'int'], +'newt_draw_form' => ['void', 'form'=>'resource'], +'newt_draw_root_text' => ['void', 'left'=>'int', 'top'=>'int', 'text'=>'string'], +'newt_entry' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'init_value='=>'string', 'flags='=>'int'], +'newt_entry_get_value' => ['string', 'entry'=>'resource'], +'newt_entry_set' => ['void', 'entry'=>'resource', 'value'=>'string', 'cursor_at_end='=>'bool'], +'newt_entry_set_filter' => ['void', 'entry'=>'resource', 'filter'=>'callable', 'data'=>'mixed'], +'newt_entry_set_flags' => ['void', 'entry'=>'resource', 'flags'=>'int', 'sense'=>'int'], +'newt_finished' => ['int'], +'newt_form' => ['resource', 'vert_bar='=>'resource', 'help='=>'string', 'flags='=>'int'], +'newt_form_add_component' => ['void', 'form'=>'resource', 'component'=>'resource'], +'newt_form_add_components' => ['void', 'form'=>'resource', 'components'=>'array'], +'newt_form_add_hot_key' => ['void', 'form'=>'resource', 'key'=>'int'], +'newt_form_destroy' => ['void', 'form'=>'resource'], +'newt_form_get_current' => ['resource', 'form'=>'resource'], +'newt_form_run' => ['void', 'form'=>'resource', 'exit_struct'=>'array'], +'newt_form_set_background' => ['void', 'from'=>'resource', 'background'=>'int'], +'newt_form_set_height' => ['void', 'form'=>'resource', 'height'=>'int'], +'newt_form_set_size' => ['void', 'form'=>'resource'], +'newt_form_set_timer' => ['void', 'form'=>'resource', 'milliseconds'=>'int'], +'newt_form_set_width' => ['void', 'form'=>'resource', 'width'=>'int'], +'newt_form_watch_fd' => ['void', 'form'=>'resource', 'stream'=>'resource', 'flags='=>'int'], +'newt_get_screen_size' => ['void', 'cols'=>'int', 'rows'=>'int'], +'newt_grid_add_components_to_form' => ['void', 'grid'=>'resource', 'form'=>'resource', 'recurse'=>'bool'], +'newt_grid_basic_window' => ['resource', 'text'=>'resource', 'middle'=>'resource', 'buttons'=>'resource'], +'newt_grid_free' => ['void', 'grid'=>'resource', 'recurse'=>'bool'], +'newt_grid_get_size' => ['void', 'grid'=>'resource', 'width'=>'int', 'height'=>'int'], +'newt_grid_h_close_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'], +'newt_grid_h_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'], +'newt_grid_place' => ['void', 'grid'=>'resource', 'left'=>'int', 'top'=>'int'], +'newt_grid_set_field' => ['void', 'grid'=>'resource', 'col'=>'int', 'row'=>'int', 'type'=>'int', 'val'=>'resource', 'pad_left'=>'int', 'pad_top'=>'int', 'pad_right'=>'int', 'pad_bottom'=>'int', 'anchor'=>'int', 'flags='=>'int'], +'newt_grid_simple_window' => ['resource', 'text'=>'resource', 'middle'=>'resource', 'buttons'=>'resource'], +'newt_grid_v_close_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'], +'newt_grid_v_stacked' => ['resource', 'element1_type'=>'int', 'element1'=>'resource', '...args='=>'resource'], +'newt_grid_wrapped_window' => ['void', 'grid'=>'resource', 'title'=>'string'], +'newt_grid_wrapped_window_at' => ['void', 'grid'=>'resource', 'title'=>'string', 'left'=>'int', 'top'=>'int'], +'newt_init' => ['int'], +'newt_label' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string'], +'newt_label_set_text' => ['void', 'label'=>'resource', 'text'=>'string'], +'newt_listbox' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'flags='=>'int'], +'newt_listbox_append_entry' => ['void', 'listbox'=>'resource', 'text'=>'string', 'data'=>'mixed'], +'newt_listbox_clear' => ['void', 'listobx'=>'resource'], +'newt_listbox_clear_selection' => ['void', 'listbox'=>'resource'], +'newt_listbox_delete_entry' => ['void', 'listbox'=>'resource', 'key'=>'mixed'], +'newt_listbox_get_current' => ['string', 'listbox'=>'resource'], +'newt_listbox_get_selection' => ['array', 'listbox'=>'resource'], +'newt_listbox_insert_entry' => ['void', 'listbox'=>'resource', 'text'=>'string', 'data'=>'mixed', 'key'=>'mixed'], +'newt_listbox_item_count' => ['int', 'listbox'=>'resource'], +'newt_listbox_select_item' => ['void', 'listbox'=>'resource', 'key'=>'mixed', 'sense'=>'int'], +'newt_listbox_set_current' => ['void', 'listbox'=>'resource', 'num'=>'int'], +'newt_listbox_set_current_by_key' => ['void', 'listbox'=>'resource', 'key'=>'mixed'], +'newt_listbox_set_data' => ['void', 'listbox'=>'resource', 'num'=>'int', 'data'=>'mixed'], +'newt_listbox_set_entry' => ['void', 'listbox'=>'resource', 'num'=>'int', 'text'=>'string'], +'newt_listbox_set_width' => ['void', 'listbox'=>'resource', 'width'=>'int'], +'newt_listitem' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'is_default'=>'bool', 'prev_item'=>'resource', 'data'=>'mixed', 'flags='=>'int'], +'newt_listitem_get_data' => ['mixed', 'item'=>'resource'], +'newt_listitem_set' => ['void', 'item'=>'resource', 'text'=>'string'], +'newt_open_window' => ['int', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'height'=>'int', 'title='=>'string'], +'newt_pop_help_line' => ['void'], +'newt_pop_window' => ['void'], +'newt_push_help_line' => ['void', 'text='=>'string'], +'newt_radio_get_current' => ['resource', 'set_member'=>'resource'], +'newt_radiobutton' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'string', 'is_default'=>'bool', 'prev_button='=>'resource'], +'newt_redraw_help_line' => ['void'], +'newt_reflow_text' => ['string', 'text'=>'string', 'width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'actual_width'=>'int', 'actual_height'=>'int'], +'newt_refresh' => ['void'], +'newt_resize_screen' => ['void', 'redraw='=>'bool'], +'newt_resume' => ['void'], +'newt_run_form' => ['resource', 'form'=>'resource'], +'newt_scale' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'full_value'=>'int'], +'newt_scale_set' => ['void', 'scale'=>'resource', 'amount'=>'int'], +'newt_scrollbar_set' => ['void', 'scrollbar'=>'resource', 'where'=>'int', 'total'=>'int'], +'newt_set_help_callback' => ['void', 'function'=>'mixed'], +'newt_set_suspend_callback' => ['void', 'function'=>'callable', 'data'=>'mixed'], +'newt_suspend' => ['void'], +'newt_textbox' => ['resource', 'left'=>'int', 'top'=>'int', 'width'=>'int', 'height'=>'int', 'flags='=>'int'], +'newt_textbox_get_num_lines' => ['int', 'textbox'=>'resource'], +'newt_textbox_reflowed' => ['resource', 'left'=>'int', 'top'=>'int', 'text'=>'char', 'width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'flags='=>'int'], +'newt_textbox_set_height' => ['void', 'textbox'=>'resource', 'height'=>'int'], +'newt_textbox_set_text' => ['void', 'textbox'=>'resource', 'text'=>'string'], +'newt_vertical_scrollbar' => ['resource', 'left'=>'int', 'top'=>'int', 'height'=>'int', 'normal_colorset='=>'int', 'thumb_colorset='=>'int'], +'newt_wait_for_key' => ['void'], +'newt_win_choice' => ['int', 'title'=>'string', 'button1_text'=>'string', 'button2_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'], +'newt_win_entries' => ['int', 'title'=>'string', 'text'=>'string', 'suggested_width'=>'int', 'flex_down'=>'int', 'flex_up'=>'int', 'data_width'=>'int', 'items'=>'array', 'button1'=>'string', '...args='=>'string'], +'newt_win_menu' => ['int', 'title'=>'string', 'text'=>'string', 'suggestedwidth'=>'int', 'flexdown'=>'int', 'flexup'=>'int', 'maxlistheight'=>'int', 'items'=>'array', 'listitem'=>'int', 'button1='=>'string', '...args='=>'string'], +'newt_win_message' => ['void', 'title'=>'string', 'button_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'], +'newt_win_messagev' => ['void', 'title'=>'string', 'button_text'=>'string', 'format'=>'string', 'args'=>'array'], +'newt_win_ternary' => ['int', 'title'=>'string', 'button1_text'=>'string', 'button2_text'=>'string', 'button3_text'=>'string', 'format'=>'string', 'args='=>'mixed', '...args='=>'mixed'], +'next' => ['mixed', '&rw_array_arg'=>'array|object'], +'ngettext' => ['string', 'msgid1'=>'string', 'msgid2'=>'string', 'n'=>'int'], +'nl2br' => ['string', 'str'=>'string', 'is_xhtml='=>'bool'], +'nl_langinfo' => ['string', 'item'=>'int'], +'NoRewindIterator::__construct' => ['void', 'it'=>'iterator'], +'NoRewindIterator::current' => ['mixed'], +'NoRewindIterator::getInnerIterator' => ['iterator'], +'NoRewindIterator::key' => ['mixed'], +'NoRewindIterator::next' => ['void'], +'NoRewindIterator::rewind' => ['void'], +'NoRewindIterator::valid' => ['bool'], +'Normalizer::isNormalized' => ['bool', 'input'=>'string', 'form='=>'int'], +'Normalizer::normalize' => ['string', 'input'=>'string', 'form='=>'int'], +'normalizer_is_normalized' => ['bool', 'input'=>'string', 'form='=>'int'], +'normalizer_normalize' => ['string', 'input'=>'string', 'form='=>'int'], +'notes_body' => ['array', 'server'=>'string', 'mailbox'=>'string', 'msg_number'=>'int'], +'notes_copy_db' => ['bool', 'from_database_name'=>'string', 'to_database_name'=>'string'], +'notes_create_db' => ['bool', 'database_name'=>'string'], +'notes_create_note' => ['bool', 'database_name'=>'string', 'form_name'=>'string'], +'notes_drop_db' => ['bool', 'database_name'=>'string'], +'notes_find_note' => ['int', 'database_name'=>'string', 'name'=>'string', 'type='=>'string'], +'notes_header_info' => ['object', 'server'=>'string', 'mailbox'=>'string', 'msg_number'=>'int'], +'notes_list_msgs' => ['bool', 'db'=>'string'], +'notes_mark_read' => ['bool', 'database_name'=>'string', 'user_name'=>'string', 'note_id'=>'string'], +'notes_mark_unread' => ['bool', 'database_name'=>'string', 'user_name'=>'string', 'note_id'=>'string'], +'notes_nav_create' => ['bool', 'database_name'=>'string', 'name'=>'string'], +'notes_search' => ['array', 'database_name'=>'string', 'keywords'=>'string'], +'notes_unread' => ['array', 'database_name'=>'string', 'user_name'=>'string'], +'notes_version' => ['float', 'database_name'=>'string'], +'nsapi_request_headers' => ['array'], +'nsapi_response_headers' => ['array'], +'nsapi_virtual' => ['bool', 'uri'=>'string'], +'nthmac' => ['string', 'clent'=>'string', 'data'=>'string'], +'number_format' => ['string', 'number'=>'float', 'num_decimal_places='=>'int'], +'number_format\'1' => ['string', 'number'=>'float', 'num_decimal_places'=>'int', 'dec_separator'=>'string', 'thousands_separator'=>'string'], +'NumberFormatter::__construct' => ['void', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'], +'NumberFormatter::create' => ['NumberFormatter', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'], +'NumberFormatter::format' => ['string', 'num'=>'', 'type='=>'int'], +'NumberFormatter::formatCurrency' => ['string', 'num'=>'float', 'currency'=>'string'], +'NumberFormatter::getAttribute' => ['int', 'attr'=>'int'], +'NumberFormatter::getErrorCode' => ['int'], +'NumberFormatter::getErrorMessage' => ['string'], +'NumberFormatter::getLocale' => ['string', 'type='=>'int'], +'NumberFormatter::getPattern' => ['string'], +'NumberFormatter::getSymbol' => ['string', 'attr'=>'int'], +'NumberFormatter::getTextAttribute' => ['string', 'attr'=>'int'], +'NumberFormatter::parse' => ['float|false', 'str'=>'string', 'type='=>'int', '&rw_position='=>'int'], +'NumberFormatter::parseCurrency' => ['float', 'str'=>'string', '&w_currency'=>'string', '&rw_position='=>'int'], +'NumberFormatter::setAttribute' => ['bool', 'attr'=>'int', 'value'=>''], +'NumberFormatter::setPattern' => ['bool', 'pattern'=>'string'], +'NumberFormatter::setSymbol' => ['bool', 'attr'=>'int', 'symbol'=>'string'], +'NumberFormatter::setTextAttribute' => ['bool', 'attr'=>'int', 'value'=>'string'], +'numfmt_create' => ['NumberFormatter', 'locale'=>'string', 'style'=>'int', 'pattern='=>'string'], +'numfmt_format' => ['string', 'fmt'=>'numberformatter', 'value='=>'float', 'type='=>'int'], +'numfmt_format_currency' => ['string|false', 'fmt'=>'numberformatter', 'value'=>'float', 'currency'=>'string'], +'numfmt_get_attribute' => ['int', 'fmt'=>'numberformatter', 'attr'=>'int'], +'numfmt_get_error_code' => ['int', 'fmt'=>'numberformatter'], +'numfmt_get_error_message' => ['string', 'fmt'=>'numberformatter'], +'numfmt_get_locale' => ['string', 'fmt'=>'numberformatter', 'type='=>'int'], +'numfmt_get_pattern' => ['string', 'fmt'=>'numberformatter'], +'numfmt_get_symbol' => ['string', 'fmt'=>'numberformatter', 'attr'=>'int'], +'numfmt_get_text_attribute' => ['string', 'fmt'=>'numberformatter', 'attr'=>'int'], +'numfmt_parse' => ['float|false', 'fmt'=>'numberformatter', 'value'=>'string', 'type='=>'int', '&rw_position='=>'int'], +'numfmt_parse_currency' => ['float|false', 'fmt'=>'numberformatter', 'value'=>'string', '&w_currency'=>'string', '&rw_position='=>'int'], +'numfmt_set_attribute' => ['bool', 'fmt'=>'numberformatter', 'attr'=>'int', 'value'=>'int'], +'numfmt_set_pattern' => ['bool', 'fmt'=>'numberformatter', 'pattern'=>'string'], +'numfmt_set_symbol' => ['bool', 'fmt'=>'numberformatter', 'attr'=>'int', 'value'=>'string'], +'numfmt_set_text_attribute' => ['bool', 'fmt'=>'numberformatter', 'attr'=>'int', 'value'=>'string'], +'OAuth::__construct' => ['void', 'consumer_key'=>'string', 'consumer_secret'=>'string', 'signature_method='=>'string', 'auth_type='=>'int'], +'OAuth::__destruct' => [''], +'OAuth::disableDebug' => ['bool'], +'OAuth::disableRedirects' => ['bool'], +'OAuth::disableSSLChecks' => ['bool'], +'OAuth::enableDebug' => ['bool'], +'OAuth::enableRedirects' => ['bool'], +'OAuth::enableSSLChecks' => ['bool'], +'OAuth::fetch' => ['mixed', 'protected_resource_url'=>'string', 'extra_parameters='=>'array', 'http_method='=>'string', 'http_headers='=>'array'], +'OAuth::generateSignature' => ['string', 'http_method'=>'string', 'url'=>'string', 'extra_parameters='=>'mixed'], +'OAuth::getAccessToken' => ['array|false', 'access_token_url'=>'string', 'auth_session_handle='=>'string', 'verifier_token='=>'string'], +'OAuth::getCAPath' => ['array'], +'OAuth::getLastResponse' => ['string'], +'OAuth::getLastResponseHeaders' => ['string|false'], +'OAuth::getLastResponseInfo' => ['array'], +'OAuth::getRequestHeader' => ['string|false', 'http_method'=>'string', 'url'=>'string', 'extra_parameters='=>'mixed'], +'OAuth::getRequestToken' => ['array|false', 'request_token_url'=>'string', 'callback_url='=>'string'], +'OAuth::setAuthType' => ['bool', 'auth_type'=>'int'], +'OAuth::setCAPath' => ['mixed', 'ca_path='=>'string', 'ca_info='=>'string'], +'OAuth::setNonce' => ['mixed', 'nonce'=>'string'], +'OAuth::setRequestEngine' => ['void', 'reqengine'=>'int'], +'OAuth::setRSACertificate' => ['mixed', 'cert'=>'string'], +'OAuth::setSSLChecks' => ['bool', 'sslcheck'=>'int'], +'OAuth::setTimestamp' => ['mixed', 'timestamp'=>'string'], +'OAuth::setToken' => ['bool', 'token'=>'string', 'token_secret'=>'string'], +'OAuth::setVersion' => ['bool', 'version'=>'string'], +'oauth_get_sbs' => ['string', 'http_method'=>'string', 'uri'=>'string', 'request_parameters='=>'array'], +'oauth_urlencode' => ['string', 'uri'=>'string'], +'OAuthProvider::__construct' => ['void', 'params_array='=>'array'], +'OAuthProvider::addRequiredParameter' => ['bool', 'req_params'=>'string'], +'OAuthProvider::callconsumerHandler' => ['void'], +'OAuthProvider::callTimestampNonceHandler' => ['void'], +'OAuthProvider::calltokenHandler' => ['void'], +'OAuthProvider::checkOAuthRequest' => ['void', 'uri='=>'string', 'method='=>'string'], +'OAuthProvider::consumerHandler' => ['void', 'callback_function'=>'callable'], +'OAuthProvider::generateToken' => ['string', 'size'=>'int', 'strong='=>'bool'], +'OAuthProvider::is2LeggedEndpoint' => ['void', 'params_array'=>'mixed'], +'OAuthProvider::isRequestTokenEndpoint' => ['void', 'will_issue_request_token'=>'bool'], +'OAuthProvider::removeRequiredParameter' => ['bool', 'req_params'=>'string'], +'OAuthProvider::reportProblem' => ['string', 'oauthexception'=>'string', 'send_headers='=>'bool'], +'OAuthProvider::setParam' => ['bool', 'param_key'=>'string', 'param_val='=>'mixed'], +'OAuthProvider::setRequestTokenPath' => ['bool', 'path'=>'string'], +'OAuthProvider::timestampNonceHandler' => ['void', 'callback_function'=>'callable'], +'OAuthProvider::tokenHandler' => ['void', 'callback_function'=>'callable'], +'ob_clean' => ['bool'], +'ob_deflatehandler' => ['string', 'data'=>'string', 'mode'=>'int'], +'ob_end_clean' => ['bool'], +'ob_end_flush' => ['bool'], +'ob_etaghandler' => ['string', 'data'=>'string', 'mode'=>'int'], +'ob_flush' => ['bool'], +'ob_get_clean' => ['string|false'], +'ob_get_contents' => ['string|false'], +'ob_get_flush' => ['string|false'], +'ob_get_length' => ['int|false'], +'ob_get_level' => ['int'], +'ob_get_status' => ['array', 'full_status='=>'bool'], +'ob_gzhandler' => ['string|false', 'data'=>'string', 'flags'=>'int'], +'ob_iconv_handler' => ['string', 'contents'=>'string', 'status'=>'int'], +'ob_implicit_flush' => ['void', 'flag='=>'int'], +'ob_inflatehandler' => ['string', 'data'=>'string', 'mode'=>'int'], +'ob_list_handlers' => ['false|array'], +'ob_start' => ['bool', 'user_function='=>'string|array|?callable', 'chunk_size='=>'int', 'flags='=>'int'], +'ob_tidyhandler' => ['string', 'input'=>'string', 'mode='=>'int'], +'OCI-Collection::assignElem' => ['bool', 'index'=>'int', 'value'=>''], +'OCI-Collection::getElem' => ['', 'index'=>'int'], +'OCI-Lob::append' => ['bool', 'lob_from'=>'OCI-Lob'], +'OCI-Lob::close' => ['bool'], +'OCI-Lob::eof' => ['bool'], +'OCI-Lob::erase' => ['int', 'offset='=>'int', 'length='=>'int'], +'OCI-Lob::export' => ['bool', 'filename'=>'string', 'start='=>'int', 'length='=>'int'], +'OCI-Lob::flush' => ['bool', 'flag='=>'int'], +'OCI-Lob::free' => ['bool'], +'OCI-Lob::getBuffering' => ['bool'], +'OCI-Lob::import' => ['bool', 'filename'=>'string'], +'OCI-Lob::load' => ['string'], +'OCI-Lob::read' => ['string', 'length'=>'int'], +'OCI-Lob::rewind' => ['bool'], +'OCI-Lob::save' => ['bool', 'data'=>'string', 'offset='=>'int'], +'OCI-Lob::seek' => ['bool', 'offset'=>'int', 'whence='=>'int'], +'OCI-Lob::setBuffering' => ['bool', 'on_off'=>'bool'], +'OCI-Lob::size' => ['int'], +'OCI-Lob::tell' => ['int'], +'OCI-Lob::truncate' => ['bool', 'length='=>'int'], +'OCI-Lob::write' => ['int', 'data'=>'string', 'length='=>'int'], +'OCI-Lob::writeTemporary' => ['bool', 'data'=>'string', 'lob_type='=>'int'], +'oci_bind_array_by_name' => ['bool', 'stmt'=>'resource', 'name'=>'string', '&rw_var'=>'array', 'max_table_length'=>'int', 'max_item_length='=>'int', 'type='=>'int'], +'oci_bind_by_name' => ['bool', 'stmt'=>'resource', 'name'=>'string', '&rw_var'=>'mixed', 'maxlength='=>'int', 'type='=>'int'], +'oci_cancel' => ['bool', 'stmt'=>'resource'], +'oci_client_version' => ['string'], +'oci_close' => ['bool', 'connection'=>'resource'], +'OCI-Collection::append' => ['bool', 'value'=>'mixed'], +'OCI-Collection::assign' => ['bool', 'from'=>'OCI-Collection'], +'OCI-Collection::assignelem' => ['bool', 'index'=>'int', 'value'=>'mixed'], +'OCI-Collection::free' => ['bool'], +'OCI-Collection::getelem' => ['mixed', 'index'=>'int'], +'OCI-Collection::max' => ['int'], +'OCI-Collection::size' => ['int'], +'OCI-Collection::trim' => ['bool', 'num'=>'int'], +'oci_collection_append' => ['bool', 'value'=>'string'], +'oci_collection_assign' => ['bool', 'from'=>'OCI-Collection'], +'oci_collection_element_assign' => ['bool', 'index'=>'int', 'val'=>'string'], +'oci_collection_element_get' => ['string', 'ndx'=>'int'], +'oci_collection_max' => ['int'], +'oci_collection_size' => ['int'], +'oci_collection_trim' => ['bool', 'num'=>'int'], +'oci_commit' => ['bool', 'connection'=>'resource'], +'oci_connect' => ['resource|false', 'user'=>'string', 'pass'=>'string', 'db='=>'string', 'charset='=>'string', 'session_mode='=>'int'], +'oci_define_by_name' => ['bool', 'stmt'=>'resource', 'name'=>'string', '&w_var'=>'mixed', 'type='=>'int'], +'oci_error' => ['array|false', 'resource='=>'resource'], +'oci_execute' => ['bool', 'stmt'=>'resource', 'mode='=>'int'], +'oci_fetch' => ['bool', 'stmt'=>'resource'], +'oci_fetch_all' => ['int|false', 'stmt'=>'resource', '&w_output'=>'array', 'skip='=>'int', 'maxrows='=>'int', 'flags='=>'int'], +'oci_fetch_array' => ['array|false', 'stmt'=>'resource', 'mode='=>'int'], +'oci_fetch_assoc' => ['array|false', 'stmt'=>'resource'], +'oci_fetch_object' => ['object|false', 'stmt'=>'resource'], +'oci_fetch_row' => ['array|false', 'stmt'=>'resource'], +'oci_field_is_null' => ['bool', 'stmt'=>'resource', 'col'=>'mixed'], +'oci_field_name' => ['string|false', 'stmt'=>'resource', 'col'=>'mixed'], +'oci_field_precision' => ['int|false', 'stmt'=>'resource', 'col'=>'mixed'], +'oci_field_scale' => ['int|false', 'stmt'=>'resource', 'col'=>'mixed'], +'oci_field_size' => ['int|false', 'stmt'=>'resource', 'col'=>'mixed'], +'oci_field_type' => ['mixed', 'stmt'=>'resource', 'col'=>'mixed'], +'oci_field_type_raw' => ['int|false', 'stmt'=>'resource', 'col'=>'mixed'], +'oci_free_collection' => ['bool'], +'oci_free_cursor' => ['bool', 'stmt'=>'resource'], +'oci_free_descriptor' => ['bool'], +'oci_free_statement' => ['bool', 'stmt'=>'resource'], +'oci_get_implicit' => ['bool', 'stmt'=>''], +'oci_get_implicit_resultset' => ['resource|false', 'statement'=>'resource'], +'oci_internal_debug' => ['void', 'onoff'=>'bool'], +'OCI-Lob::getbuffering' => ['bool'], +'OCI-Lob::savefile' => ['bool', 'filename'=>''], +'OCI-Lob::setbuffering' => ['bool', 'on_off'=>'bool'], +'OCI-Lob::writetofile' => ['bool', 'filename'=>'', 'start'=>'', 'length'=>''], +'oci_lob_append' => ['bool', 'lob'=>'OCI-Lob'], +'oci_lob_close' => ['bool'], +'oci_lob_copy' => ['bool', 'lob_to'=>'OCI-Lob', 'lob_from'=>'OCI-Lob', 'length='=>'int'], +'oci_lob_eof' => ['bool'], +'oci_lob_erase' => ['int', 'offset'=>'int', 'length'=>'int'], +'oci_lob_export' => ['bool', 'filename'=>'string', 'start'=>'int', 'length'=>'int'], +'oci_lob_flush' => ['bool', 'flag'=>'int'], +'oci_lob_import' => ['bool', 'filename'=>'string'], +'oci_lob_is_equal' => ['bool', 'lob1'=>'OCI-Lob', 'lob2'=>'OCI-Lob'], +'oci_lob_load' => ['string'], +'oci_lob_read' => ['string', 'length'=>'int'], +'oci_lob_rewind' => ['bool'], +'oci_lob_save' => ['bool', 'data'=>'string', 'offset'=>'int'], +'oci_lob_seek' => ['bool', 'offset'=>'int', 'whence'=>'int'], +'oci_lob_size' => ['int'], +'oci_lob_tell' => ['int'], +'oci_lob_truncate' => ['bool', 'length'=>'int'], +'oci_lob_write' => ['int', 'string'=>'string', 'length'=>'int'], +'oci_lob_write_temporary' => ['bool', 'var'=>'string', 'lob_type'=>'int'], +'oci_new_collection' => ['OCI-Collection|false', 'connection'=>'resource', 'tdo'=>'string', 'schema='=>'string'], +'oci_new_connect' => ['resource|false', 'user'=>'string', 'pass'=>'string', 'db='=>'string', 'charset='=>'string', 'session_mode='=>'int'], +'oci_new_cursor' => ['resource|false', 'connection'=>'resource'], +'oci_new_descriptor' => ['OCI-Lob|false', 'connection'=>'resource', 'type='=>'int'], +'oci_num_fields' => ['int|false', 'stmt'=>'resource'], +'oci_num_rows' => ['int|false', 'stmt'=>'resource'], +'oci_parse' => ['resource|false', 'connection'=>'resource', 'statement'=>'string'], +'oci_password_change' => ['bool', 'connection'=>'', 'username'=>'string', 'old_password'=>'string', 'new_password'=>'string'], +'oci_pconnect' => ['resource|false', 'user'=>'string', 'pass'=>'string', 'db='=>'string', 'charset='=>'string', 'session_mode='=>'int'], +'oci_register_taf_callback' => ['bool', 'connection'=>'resource', 'callback='=>'callable'], +'oci_result' => ['string|false', 'stmt'=>'resource', 'column'=>'mixed'], +'oci_rollback' => ['bool', 'connection'=>'resource'], +'oci_server_version' => ['string|false', 'connection'=>'resource'], +'oci_set_action' => ['bool', 'connection'=>'resource', 'value'=>'string'], +'oci_set_client_identifier' => ['bool', 'connection'=>'resource', 'value'=>'string'], +'oci_set_client_info' => ['bool', 'connection'=>'resource', 'value'=>'string'], +'oci_set_db_operation' => ['bool', 'connection'=>'resource', 'value'=>'string'], +'oci_set_edition' => ['bool', 'value'=>'string'], +'oci_set_module_name' => ['bool', 'connection'=>'resource', 'value'=>'string'], +'oci_set_prefetch' => ['bool', 'stmt'=>'resource', 'prefetch_rows'=>'int'], +'oci_statement_type' => ['string|false', 'stmt'=>'resource'], +'oci_unregister_taf_callback' => ['bool', 'connection'=>'resource'], +'ocifetchinto' => ['int', 'stmt'=>'', '&w_output'=>'array', 'mode='=>'int'], +'ocigetbufferinglob' => ['bool'], +'ocisetbufferinglob' => ['bool', 'flag'=>'bool'], +'octdec' => ['int', 'octal_number'=>'string'], +'odbc_autocommit' => ['mixed', 'connection_id'=>'resource', 'onoff='=>'bool'], +'odbc_binmode' => ['bool', 'result_id'=>'int', 'mode'=>'int'], +'odbc_close' => ['void', 'connection_id'=>'resource'], +'odbc_close_all' => ['void'], +'odbc_columnprivileges' => ['resource', 'connection_id'=>'resource', 'catalog'=>'string', 'schema'=>'string', 'table'=>'string', 'column'=>'string'], +'odbc_columns' => ['resource', 'connection_id'=>'resource', 'qualifier='=>'string', 'owner='=>'string', 'table_name='=>'string', 'column_name='=>'string'], +'odbc_commit' => ['bool', 'connection_id'=>'resource'], +'odbc_connect' => ['resource', 'dsn'=>'string', 'user'=>'string', 'password'=>'string', 'cursor_option='=>'int'], +'odbc_cursor' => ['string', 'result_id'=>'resource'], +'odbc_data_source' => ['array', 'connection_id'=>'resource', 'fetch_type'=>'int'], +'odbc_do' => ['resource', 'connection_id'=>'resource', 'query'=>'string', 'flags='=>'int'], +'odbc_error' => ['string', 'connection_id='=>'resource'], +'odbc_errormsg' => ['string', 'connection_id='=>'resource'], +'odbc_exec' => ['resource', 'connection_id'=>'resource', 'query'=>'string', 'flags='=>'int'], +'odbc_execute' => ['bool', 'result_id'=>'resource', 'parameters_array='=>'array'], +'odbc_fetch_array' => ['array', 'result'=>'resource', 'rownumber='=>'int'], +'odbc_fetch_into' => ['int', 'result_id'=>'resource', '&w_result_array'=>'array', 'rownumber='=>'int'], +'odbc_fetch_object' => ['object', 'result'=>'int', 'rownumber='=>'int'], +'odbc_fetch_row' => ['bool', 'result_id'=>'resource', 'row_number='=>'int'], +'odbc_field_len' => ['int', 'result_id'=>'resource', 'field_number'=>'int'], +'odbc_field_name' => ['string', 'result_id'=>'resource', 'field_number'=>'int'], +'odbc_field_num' => ['int', 'result_id'=>'resource', 'field_name'=>'string'], +'odbc_field_precision' => ['int', 'result_id'=>'resource', 'field_number'=>'int'], +'odbc_field_scale' => ['int', 'result_id'=>'resource', 'field_number'=>'int'], +'odbc_field_type' => ['string', 'result_id'=>'resource', 'field_number'=>'int'], +'odbc_foreignkeys' => ['resource', 'connection_id'=>'resource', 'pk_qualifier'=>'string', 'pk_owner'=>'string', 'pk_table'=>'string', 'fk_qualifier'=>'string', 'fk_owner'=>'string', 'fk_table'=>'string'], +'odbc_free_result' => ['bool', 'result_id'=>'resource'], +'odbc_gettypeinfo' => ['resource', 'connection_id'=>'resource', 'data_type='=>'int'], +'odbc_longreadlen' => ['bool', 'result_id'=>'int', 'length'=>'int'], +'odbc_next_result' => ['bool', 'result_id'=>'resource'], +'odbc_num_fields' => ['int', 'result_id'=>'resource'], +'odbc_num_rows' => ['int', 'result_id'=>'resource'], +'odbc_pconnect' => ['resource', 'dsn'=>'string', 'user'=>'string', 'password'=>'string', 'cursor_option='=>'int'], +'odbc_prepare' => ['resource', 'connection_id'=>'resource', 'query'=>'string'], +'odbc_primarykeys' => ['resource', 'connection_id'=>'resource', 'qualifier'=>'string', 'owner'=>'string', 'table'=>'string'], +'odbc_procedurecolumns' => ['resource', 'connection_id'=>'', 'qualifier'=>'string', 'owner'=>'string', 'proc'=>'string', 'column'=>'string'], +'odbc_procedures' => ['resource', 'connection_id'=>'', 'qualifier'=>'string', 'owner'=>'string', 'name'=>'string'], +'odbc_result' => ['mixed', 'result_id'=>'resource', 'field'=>'mixed'], +'odbc_result_all' => ['int', 'result_id'=>'resource', 'format='=>'string'], +'odbc_rollback' => ['bool', 'connection_id'=>'resource'], +'odbc_setoption' => ['bool', 'result_id'=>'resource', 'which'=>'int', 'option'=>'int', 'value'=>'int'], +'odbc_specialcolumns' => ['resource', 'connection_id'=>'resource', 'type'=>'int', 'qualifier'=>'string', 'owner'=>'string', 'table'=>'string', 'scope'=>'int', 'nullable'=>'int'], +'odbc_statistics' => ['resource', 'connection_id'=>'resource', 'qualifier'=>'string', 'owner'=>'string', 'name'=>'string', 'unique'=>'int', 'accuracy'=>'int'], +'odbc_tableprivileges' => ['resource', 'connection_id'=>'resource', 'qualifier'=>'string', 'owner'=>'string', 'name'=>'string'], +'odbc_tables' => ['resource', 'connection_id'=>'resource', 'qualifier='=>'string', 'owner='=>'string', 'name='=>'string', 'table_types='=>'string'], +'opcache_compile_file' => ['bool', 'file'=>'string'], +'opcache_get_configuration' => ['array'], +'opcache_get_status' => ['array|false', 'get_scripts='=>'bool'], +'opcache_invalidate' => ['bool', 'script'=>'string', 'force='=>'bool'], +'opcache_is_script_cached' => ['bool', 'script'=>'string'], +'opcache_reset' => ['bool'], +'openal_buffer_create' => ['resource'], +'openal_buffer_data' => ['bool', 'buffer'=>'resource', 'format'=>'int', 'data'=>'string', 'freq'=>'int'], +'openal_buffer_destroy' => ['bool', 'buffer'=>'resource'], +'openal_buffer_get' => ['int', 'buffer'=>'resource', 'property'=>'int'], +'openal_buffer_loadwav' => ['bool', 'buffer'=>'resource', 'wavfile'=>'string'], +'openal_context_create' => ['resource', 'device'=>'resource'], +'openal_context_current' => ['bool', 'context'=>'resource'], +'openal_context_destroy' => ['bool', 'context'=>'resource'], +'openal_context_process' => ['bool', 'context'=>'resource'], +'openal_context_suspend' => ['bool', 'context'=>'resource'], +'openal_device_close' => ['bool', 'device'=>'resource'], +'openal_device_open' => ['resource', 'device_desc='=>'string'], +'openal_listener_get' => ['mixed', 'property'=>'int'], +'openal_listener_set' => ['bool', 'property'=>'int', 'setting'=>'mixed'], +'openal_source_create' => ['resource'], +'openal_source_destroy' => ['bool', 'source'=>'resource'], +'openal_source_get' => ['mixed', 'source'=>'resource', 'property'=>'int'], +'openal_source_pause' => ['bool', 'source'=>'resource'], +'openal_source_play' => ['bool', 'source'=>'resource'], +'openal_source_rewind' => ['bool', 'source'=>'resource'], +'openal_source_set' => ['bool', 'source'=>'resource', 'property'=>'int', 'setting'=>'mixed'], +'openal_source_stop' => ['bool', 'source'=>'resource'], +'openal_stream' => ['resource', 'source'=>'resource', 'format'=>'int', 'rate'=>'int'], +'opendir' => ['resource|false', 'path'=>'string', 'context='=>'resource'], +'openlog' => ['bool', 'ident'=>'string', 'option'=>'int', 'facility'=>'int'], +'openssl_cipher_iv_length' => ['int|false', 'method'=>'string'], +'openssl_csr_export' => ['bool', 'csr'=>'string|resource', '&w_out'=>'string', 'notext='=>'bool'], +'openssl_csr_export_to_file' => ['bool', 'csr'=>'string|resource', 'outfilename'=>'string', 'notext='=>'bool'], +'openssl_csr_get_public_key' => ['resource|false', 'csr'=>'string|resource', 'use_shortnames='=>'bool'], +'openssl_csr_get_subject' => ['array|false', 'csr'=>'string|resource', 'use_shortnames='=>'bool'], +'openssl_csr_new' => ['resource|false', 'dn'=>'array', '&w_privkey'=>'resource', 'configargs='=>'array', 'extraattribs='=>'array'], +'openssl_csr_sign' => ['resource|false', 'csr'=>'string|resource', 'x509'=>'string|resource|null', 'priv_key'=>'string|resource|array', 'days'=>'int', 'config_args='=>'array', 'serial='=>'int'], +'openssl_decrypt' => ['string|false', 'data'=>'string', 'method'=>'string', 'key'=>'string', 'options='=>'int', 'iv='=>'string', 'tag='=>'string', 'aad='=>'string'], +'openssl_dh_compute_key' => ['string|false', 'pub_key'=>'string', 'dh_key'=>'resource'], +'openssl_digest' => ['string|false', 'data'=>'string', 'method'=>'string', 'raw_output='=>'bool'], +'openssl_encrypt' => ['string|false', 'data'=>'string', 'method'=>'string', 'key'=>'string', 'options='=>'int', 'iv='=>'string', '&rw_tag='=>'string', 'aad='=>'string', 'tag_length='=>'int'], +'openssl_error_string' => ['string|false'], +'openssl_free_key' => ['void', 'key_identifier'=>'resource'], +'openssl_get_cert_locations' => ['array'], +'openssl_get_cipher_methods' => ['array', 'aliases='=>'bool'], +'openssl_get_curve_names' => ['array'], +'openssl_get_md_methods' => ['array', 'aliases='=>'bool'], +'openssl_get_privatekey' => ['resource|false', 'key'=>'string', 'passphrase='=>'string'], +'openssl_get_publickey' => ['resource|false', 'cert'=>'resource|string'], +'openssl_open' => ['bool', 'sealed_data'=>'string', '&w_open_data'=>'string', 'env_key'=>'string', 'priv_key_id'=>'string|array|resource', 'method='=>'string', 'iv='=>'string'], +'openssl_pbkdf2' => ['string|false', 'password'=>'string', 'salt'=>'string', 'key_length'=>'int', 'iterations'=>'int', 'digest_algorithm'=>'string'], +'openssl_pkcs12_export' => ['bool', 'x509'=>'string|resource', '&w_out'=>'string', 'priv_key'=>'string|array|resource', 'pass'=>'string', 'args='=>'array'], +'openssl_pkcs12_export_to_file' => ['bool', 'x509'=>'string|resource', 'filename'=>'string', 'priv_key'=>'string|array|resource', 'pass'=>'string', 'args='=>'array'], +'openssl_pkcs12_read' => ['bool', 'pkcs12'=>'string', '&w_certs'=>'array', 'pass'=>'string'], +'openssl_pkcs7_decrypt' => ['bool', 'infilename'=>'string', 'outfilename'=>'string', 'recipcert'=>'string|resource', 'recipkey='=>'string|resource|array'], +'openssl_pkcs7_encrypt' => ['bool', 'infile'=>'string', 'outfile'=>'string', 'recipcerts'=>'string|resource|array', 'headers'=>'array', 'flags='=>'int', 'cipherid='=>'int'], +'openssl_pkcs7_read' => ['bool', 'infilename'=>'string', 'certs'=>'array'], +'openssl_pkcs7_sign' => ['bool', 'infile'=>'string', 'outfile'=>'string', 'signcert'=>'string|resource', 'privkey'=>'string|resource|array', 'headers'=>'array', 'flags='=>'int', 'extracerts='=>'string'], +'openssl_pkcs7_verify' => ['bool|int', 'filename'=>'string', 'flags'=>'int', 'outfilename='=>'string', 'cainfo='=>'array', 'extracerts='=>'string', 'content='=>'string', 'p7bfilename='=>'string'], +'openssl_pkey_export' => ['bool', 'key'=>'resource', '&w_out'=>'string', 'passphrase='=>'string', 'configargs='=>'array'], +'openssl_pkey_export_to_file' => ['bool', 'key'=>'resource|string|array', 'outfilename'=>'string', 'passphrase='=>'string', 'configargs='=>'array'], +'openssl_pkey_free' => ['void', 'key'=>'resource'], +'openssl_pkey_get_details' => ['array|false', 'key'=>'resource'], +'openssl_pkey_get_private' => ['resource|false', 'key'=>'string', 'passphrase='=>'string'], +'openssl_pkey_get_public' => ['resource|false', 'certificate'=>'resource|string'], +'openssl_pkey_new' => ['resource|false', 'configargs='=>'array'], +'openssl_private_decrypt' => ['bool', 'data'=>'string', '&w_decrypted'=>'string', 'key'=>'string|resource|array', 'padding='=>'int'], +'openssl_private_encrypt' => ['bool', 'data'=>'string', '&w_crypted'=>'string', 'key'=>'string|resource|array', 'padding='=>'int'], +'openssl_public_decrypt' => ['bool', 'data'=>'string', '&w_decrypted'=>'string', 'key'=>'string|resource', 'padding='=>'int'], +'openssl_public_encrypt' => ['bool', 'data'=>'string', '&w_crypted'=>'string', 'key'=>'string|resource', 'padding='=>'int'], +'openssl_random_pseudo_bytes' => ['string|false', 'length'=>'int', '&w_crypto_strong='=>'bool'], +'openssl_seal' => ['int|false', 'data'=>'string', '&w_sealed_data'=>'string', '&rw_env_keys'=>'array', 'pub_key_ids'=>'array', 'method='=>'string'], +'openssl_sign' => ['bool', 'data'=>'string', '&w_signature'=>'string', 'priv_key_id'=>'resource|string', 'signature_alg='=>'int|string'], +'openssl_spki_export' => ['string|null', 'spkac'=>'string'], +'openssl_spki_export_challenge' => ['string|null', 'spkac'=>'string'], +'openssl_spki_new' => ['string|null', 'privkey'=>'resource', 'challenge'=>'string', 'algorithm='=>'int'], +'openssl_spki_verify' => ['bool', 'spkac'=>'string'], +'openssl_verify' => ['int', 'data'=>'string', 'signature'=>'string', 'pub_key_id'=>'resource|string', 'signature_alg='=>'int|string'], +'openssl_x509_check_private_key' => ['bool', 'cert'=>'string|resource', 'key'=>'string|resource|array'], +'openssl_x509_checkpurpose' => ['bool|int', 'x509cert'=>'string|resource', 'purpose'=>'int', 'cainfo='=>'array', 'untrustedfile='=>'string'], +'openssl_x509_export' => ['bool', 'x509'=>'string|resource', '&w_output'=>'string', 'notext='=>'bool'], +'openssl_x509_export_to_file' => ['bool', 'x509'=>'string|resource', 'outfilename'=>'string', 'notext='=>'bool'], +'openssl_x509_fingerprint' => ['string|false', 'x509'=>'string|resource', 'hash_algorithm='=>'string', 'raw_output='=>'bool'], +'openssl_x509_free' => ['void', 'x509'=>'resource'], +'openssl_x509_parse' => ['array|false', 'x509cert'=>'string|resource', 'shortnames='=>'bool'], +'openssl_x509_read' => ['resource|false', 'x509certdata'=>'string|resource'], +'ord' => ['int', 'character'=>'string'], +'OuterIterator::getInnerIterator' => ['Iterator'], +'OutOfBoundsException::__clone' => ['void'], +'OutOfBoundsException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?OutOfBoundsException'], +'OutOfBoundsException::__toString' => ['string'], +'OutOfBoundsException::getCode' => ['int'], +'OutOfBoundsException::getFile' => ['string'], +'OutOfBoundsException::getLine' => ['int'], +'OutOfBoundsException::getMessage' => ['string'], +'OutOfBoundsException::getPrevious' => ['Throwable|OutOfBoundsException|null'], +'OutOfBoundsException::getTrace' => ['array'], +'OutOfBoundsException::getTraceAsString' => ['string'], +'OutOfRangeException::__clone' => ['void'], +'OutOfRangeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?OutOfRangeException'], +'OutOfRangeException::__toString' => ['string'], +'OutOfRangeException::getCode' => ['int'], +'OutOfRangeException::getFile' => ['string'], +'OutOfRangeException::getLine' => ['int'], +'OutOfRangeException::getMessage' => ['string'], +'OutOfRangeException::getPrevious' => ['Throwable|OutOfRangeException|null'], +'OutOfRangeException::getTrace' => ['array'], +'OutOfRangeException::getTraceAsString' => ['string'], +'output_add_rewrite_var' => ['bool', 'name'=>'string', 'value'=>'string'], +'output_reset_rewrite_vars' => ['bool'], +'OverflowException::__clone' => ['void'], +'OverflowException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?OverflowException'], +'OverflowException::__toString' => ['string'], +'OverflowException::getCode' => ['int'], +'OverflowException::getFile' => ['string'], +'OverflowException::getLine' => ['int'], +'OverflowException::getMessage' => ['string'], +'OverflowException::getPrevious' => ['Throwable|OverflowException|null'], +'OverflowException::getTrace' => ['array'], +'OverflowException::getTraceAsString' => ['string'], +'overload' => ['', 'class_name'=>'string'], +'override_function' => ['bool', 'function_name'=>'string', 'function_args'=>'string', 'function_code'=>'string'], +'pack' => ['string', 'format'=>'string', '...args='=>'mixed'], +'ParentIterator::__construct' => ['void', 'it'=>'recursiveiterator'], +'ParentIterator::accept' => ['bool'], +'ParentIterator::getChildren' => ['ParentIterator'], +'ParentIterator::hasChildren' => ['bool'], +'ParentIterator::next' => ['void'], +'ParentIterator::rewind' => ['void'], +'ParentIterator::valid' => [''], +'Parle\Lexer::advance' => ['void'], +'Parle\Lexer::build' => ['void'], +'Parle\Lexer::callout' => ['void', 'id'=>'int', 'callback'=>'callable'], +'Parle\Lexer::consume' => ['void', 'data'=>'string'], +'Parle\Lexer::dump' => ['void'], +'Parle\Lexer::getToken' => ['Parle\Token'], +'Parle\Lexer::insertMacro' => ['void', 'name'=>'string', 'regex'=>'string'], +'Parle\Lexer::push' => ['void', 'regex'=>'string', 'id'=>'int'], +'Parle\Lexer::reset' => ['void', 'pos'=>'int'], +'Parle\Parser::advance' => ['void'], +'Parle\Parser::build' => ['void'], +'Parle\Parser::consume' => ['void', 'data'=>'string', 'lexer'=>'Parle\Lexer'], +'Parle\Parser::dump' => ['void'], +'Parle\Parser::errorInfo' => ['Parle\ErrorInfo'], +'Parle\Parser::left' => ['void', 'token'=>'string'], +'Parle\Parser::nonassoc' => ['void', 'token'=>'string'], +'Parle\Parser::precedence' => ['void', 'token'=>'string'], +'Parle\Parser::push' => ['int', 'name'=>'string', 'rule'=>'string'], +'Parle\Parser::reset' => ['void', 'tokenId'=>'int'], +'Parle\Parser::right' => ['void', 'token'=>'string'], +'Parle\Parser::sigil' => ['string', 'idx'=>'array'], +'Parle\Parser::token' => ['void', 'token'=>'string'], +'Parle\Parser::tokenId' => ['int', 'token'=>'string'], +'Parle\Parser::trace' => ['string'], +'Parle\Parser::validate' => ['bool', 'data'=>'string', 'lexer'=>'Parle\Lexer'], +'Parle\RLexer::advance' => ['void'], +'Parle\RLexer::build' => ['void'], +'Parle\RLexer::callout' => ['void', 'id'=>'int', 'callback'=>'callable'], +'Parle\RLexer::consume' => ['void', 'data'=>'string'], +'Parle\RLexer::dump' => ['void'], +'Parle\RLexer::getToken' => ['Parle\Token'], +'Parle\RLexer::push' => ['void', 'state'=>'string', 'regex'=>'string', 'newState'=>'string'], +'Parle\RLexer::pushState' => ['int', 'state'=>'string'], +'Parle\RLexer::reset' => ['void', 'pos'=>'int'], +'Parle\RParser::advance' => ['void'], +'Parle\RParser::build' => ['void'], +'Parle\RParser::consume' => ['void', 'data'=>'string', 'lexer'=>'Parle\Lexer'], +'Parle\RParser::dump' => ['void'], +'Parle\RParser::errorInfo' => ['Parle\ErrorInfo'], +'Parle\RParser::left' => ['void', 'token'=>'string'], +'Parle\RParser::nonassoc' => ['void', 'token'=>'string'], +'Parle\RParser::precedence' => ['void', 'token'=>'string'], +'Parle\RParser::push' => ['int', 'name'=>'string', 'rule'=>'string'], +'Parle\RParser::reset' => ['void', 'tokenId'=>'int'], +'Parle\RParser::right' => ['void', 'token'=>'string'], +'Parle\RParser::sigil' => ['string', 'idx'=>'array'], +'Parle\RParser::token' => ['void', 'token'=>'string'], +'Parle\RParser::tokenId' => ['int', 'token'=>'string'], +'Parle\RParser::trace' => ['string'], +'Parle\RParser::validate' => ['bool', 'data'=>'string', 'lexer'=>'Parle\Lexer'], +'Parle\Stack::pop' => ['void'], +'Parle\Stack::push' => ['void', 'item'=>''], +'parse_ini_file' => ['array|false', 'filename'=>'string', 'process_sections='=>'bool', 'scanner_mode='=>'int'], +'parse_ini_string' => ['array|false', 'ini_string'=>'string', 'process_sections='=>'bool', 'scanner_mode='=>'int'], +'parse_str' => ['void', 'encoded_string'=>'string', '&w_result='=>'array'], +'parse_url' => ['mixed', 'url'=>'string', 'url_component='=>'int'], +'ParseError::__clone' => ['void'], +'ParseError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?ParseError'], +'ParseError::__toString' => ['string'], +'ParseError::getCode' => ['int'], +'ParseError::getFile' => ['string'], +'ParseError::getLine' => ['int'], +'ParseError::getMessage' => ['string'], +'ParseError::getPrevious' => ['Throwable|ParseError|null'], +'ParseError::getTrace' => ['array'], +'ParseError::getTraceAsString' => ['string'], +'parsekit_compile_file' => ['array', 'filename'=>'string', 'errors='=>'array', 'options='=>'int'], +'parsekit_compile_string' => ['array', 'phpcode'=>'string', 'errors='=>'array', 'options='=>'int'], +'parsekit_func_arginfo' => ['array', 'function'=>'mixed'], +'passthru' => ['void', 'command'=>'string', '&w_return_value='=>'int'], +'password_get_info' => ['array', 'hash'=>'string'], +'password_hash' => ['string|false', 'password'=>'string', 'algo'=>'int', 'options='=>'array'], +'password_make_salt' => ['bool', 'password'=>'string', 'hash'=>'string'], +'password_needs_rehash' => ['bool', 'hash'=>'string', 'algo'=>'int', 'options='=>'array'], +'password_verify' => ['bool', 'password'=>'string', 'hash'=>'string'], +'pathinfo' => ['array|string', 'path'=>'string', 'options='=>'int'], +'pclose' => ['int', 'fp'=>'resource'], +'pcnlt_sigwaitinfo' => ['int', 'set'=>'array', '&w_siginfo'=>'array'], +'pcntl_alarm' => ['int', 'seconds'=>'int'], +'pcntl_async_signals' => ['bool', 'on='=>'bool'], +'pcntl_exec' => ['bool', 'path'=>'string', 'args='=>'array', 'envs='=>'array'], +'pcntl_fork' => ['int'], +'pcntl_get_last_error' => ['int'], +'pcntl_getpriority' => ['int', 'pid='=>'int', 'process_identifier='=>'int'], +'pcntl_setpriority' => ['bool', 'priority'=>'int', 'pid='=>'int', 'process_identifier='=>'int'], +'pcntl_signal' => ['bool', 'signo'=>'int', 'handle'=>'callable|int', 'restart_syscalls='=>'bool'], +'pcntl_signal_dispatch' => ['bool'], +'pcntl_signal_get_handler' => ['int|string', 'signo'=>'int'], +'pcntl_sigprocmask' => ['bool', 'how'=>'int', 'set'=>'array', '&w_oldset='=>'array'], +'pcntl_sigtimedwait' => ['int', 'set'=>'array', '&w_siginfo='=>'array', 'seconds='=>'int', 'nanoseconds='=>'int'], +'pcntl_sigwaitinfo' => ['int', 'set'=>'array', '&w_siginfo='=>'array'], +'pcntl_strerror' => ['string', 'errno'=>'int'], +'pcntl_wait' => ['int', '&w_status'=>'int', 'options='=>'int', '&w_rusage='=>'array'], +'pcntl_waitpid' => ['int', 'pid'=>'int', '&w_status'=>'int', 'options='=>'int', '&w_rusage='=>'array'], +'pcntl_wexitstatus' => ['int', 'status'=>'int'], +'pcntl_wifcontinued' => ['bool', 'status'=>'int'], +'pcntl_wifexited' => ['bool', 'status'=>'int'], +'pcntl_wifsignaled' => ['bool', 'status'=>'int'], +'pcntl_wifstopped' => ['bool', 'status'=>'int'], +'pcntl_wstopsig' => ['int', 'status'=>'int'], +'pcntl_wtermsig' => ['int', 'status'=>'int'], +'PDF_activate_item' => ['bool', 'pdfdoc'=>'resource', 'id'=>'int'], +'PDF_add_launchlink' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'], +'PDF_add_locallink' => ['bool', 'pdfdoc'=>'resource', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'page'=>'int', 'dest'=>'string'], +'PDF_add_nameddest' => ['bool', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'], +'PDF_add_note' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'], +'PDF_add_pdflink' => ['bool', 'pdfdoc'=>'resource', 'bottom_left_x'=>'float', 'bottom_left_y'=>'float', 'up_right_x'=>'float', 'up_right_y'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'], +'PDF_add_table_cell' => ['int', 'pdfdoc'=>'resource', 'table'=>'int', 'column'=>'int', 'row'=>'int', 'text'=>'string', 'optlist'=>'string'], +'PDF_add_textflow' => ['int', 'pdfdoc'=>'resource', 'textflow'=>'int', 'text'=>'string', 'optlist'=>'string'], +'PDF_add_thumbnail' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int'], +'PDF_add_weblink' => ['bool', 'pdfdoc'=>'resource', 'lowerleftx'=>'float', 'lowerlefty'=>'float', 'upperrightx'=>'float', 'upperrighty'=>'float', 'url'=>'string'], +'PDF_arc' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'], +'PDF_arcn' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'alpha'=>'float', 'beta'=>'float'], +'PDF_attach_file' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'description'=>'string', 'author'=>'string', 'mimetype'=>'string', 'icon'=>'string'], +'PDF_begin_document' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string'], +'PDF_begin_font' => ['bool', 'pdfdoc'=>'resource', 'filename'=>'string', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float', 'optlist'=>'string'], +'PDF_begin_glyph' => ['bool', 'pdfdoc'=>'resource', 'glyphname'=>'string', 'wx'=>'float', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float'], +'PDF_begin_item' => ['int', 'pdfdoc'=>'resource', 'tag'=>'string', 'optlist'=>'string'], +'PDF_begin_layer' => ['bool', 'pdfdoc'=>'resource', 'layer'=>'int'], +'PDF_begin_page' => ['bool', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float'], +'PDF_begin_page_ext' => ['bool', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'], +'PDF_begin_pattern' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'], +'PDF_begin_template' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float'], +'PDF_begin_template_ext' => ['int', 'pdfdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'optlist'=>'string'], +'PDF_circle' => ['bool', 'pdfdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'r'=>'float'], +'PDF_clip' => ['bool', 'p'=>'resource'], +'PDF_close' => ['bool', 'p'=>'resource'], +'PDF_close_image' => ['bool', 'p'=>'resource', 'image'=>'int'], +'PDF_close_pdi' => ['bool', 'p'=>'resource', 'doc'=>'int'], +'PDF_close_pdi_page' => ['bool', 'p'=>'resource', 'page'=>'int'], +'PDF_closepath' => ['bool', 'p'=>'resource'], +'PDF_closepath_fill_stroke' => ['bool', 'p'=>'resource'], +'PDF_closepath_stroke' => ['bool', 'p'=>'resource'], +'PDF_concat' => ['bool', 'p'=>'resource', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'], +'PDF_continue_text' => ['bool', 'p'=>'resource', 'text'=>'string'], +'PDF_create_3dview' => ['int', 'pdfdoc'=>'resource', 'username'=>'string', 'optlist'=>'string'], +'PDF_create_action' => ['int', 'pdfdoc'=>'resource', 'type'=>'string', 'optlist'=>'string'], +'PDF_create_annotation' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'type'=>'string', 'optlist'=>'string'], +'PDF_create_bookmark' => ['int', 'pdfdoc'=>'resource', 'text'=>'string', 'optlist'=>'string'], +'PDF_create_field' => ['bool', 'pdfdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'name'=>'string', 'type'=>'string', 'optlist'=>'string'], +'PDF_create_fieldgroup' => ['bool', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'], +'PDF_create_gstate' => ['int', 'pdfdoc'=>'resource', 'optlist'=>'string'], +'PDF_create_pvf' => ['bool', 'pdfdoc'=>'resource', 'filename'=>'string', 'data'=>'string', 'optlist'=>'string'], +'PDF_create_textflow' => ['int', 'pdfdoc'=>'resource', 'text'=>'string', 'optlist'=>'string'], +'PDF_curveto' => ['bool', 'p'=>'resource', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], +'PDF_define_layer' => ['int', 'pdfdoc'=>'resource', 'name'=>'string', 'optlist'=>'string'], +'PDF_delete' => ['bool', 'pdfdoc'=>'resource'], +'PDF_delete_pvf' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string'], +'PDF_delete_table' => ['bool', 'pdfdoc'=>'resource', 'table'=>'int', 'optlist'=>'string'], +'PDF_delete_textflow' => ['bool', 'pdfdoc'=>'resource', 'textflow'=>'int'], +'PDF_encoding_set_char' => ['bool', 'pdfdoc'=>'resource', 'encoding'=>'string', 'slot'=>'int', 'glyphname'=>'string', 'uv'=>'int'], +'PDF_end_document' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], +'PDF_end_font' => ['bool', 'pdfdoc'=>'resource'], +'PDF_end_glyph' => ['bool', 'pdfdoc'=>'resource'], +'PDF_end_item' => ['bool', 'pdfdoc'=>'resource', 'id'=>'int'], +'PDF_end_layer' => ['bool', 'pdfdoc'=>'resource'], +'PDF_end_page' => ['bool', 'p'=>'resource'], +'PDF_end_page_ext' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], +'PDF_end_pattern' => ['bool', 'p'=>'resource'], +'PDF_end_template' => ['bool', 'p'=>'resource'], +'PDF_endpath' => ['bool', 'p'=>'resource'], +'PDF_fill' => ['bool', 'p'=>'resource'], +'PDF_fill_imageblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'image'=>'int', 'optlist'=>'string'], +'PDF_fill_pdfblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'contents'=>'int', 'optlist'=>'string'], +'PDF_fill_stroke' => ['bool', 'p'=>'resource'], +'PDF_fill_textblock' => ['int', 'pdfdoc'=>'resource', 'page'=>'int', 'blockname'=>'string', 'text'=>'string', 'optlist'=>'string'], +'PDF_findfont' => ['int', 'p'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'embed'=>'int'], +'PDF_fit_image' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'], +'PDF_fit_pdi_page' => ['bool', 'pdfdoc'=>'resource', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'], +'PDF_fit_table' => ['string', 'pdfdoc'=>'resource', 'table'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'], +'PDF_fit_textflow' => ['string', 'pdfdoc'=>'resource', 'textflow'=>'int', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'optlist'=>'string'], +'PDF_fit_textline' => ['bool', 'pdfdoc'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float', 'optlist'=>'string'], +'PDF_get_apiname' => ['string', 'pdfdoc'=>'resource'], +'PDF_get_buffer' => ['string', 'p'=>'resource'], +'PDF_get_errmsg' => ['string', 'pdfdoc'=>'resource'], +'PDF_get_errnum' => ['int', 'pdfdoc'=>'resource'], +'PDF_get_majorversion' => ['int'], +'PDF_get_minorversion' => ['int'], +'PDF_get_parameter' => ['string', 'p'=>'resource', 'key'=>'string', 'modifier'=>'float'], +'PDF_get_pdi_parameter' => ['string', 'p'=>'resource', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'], +'PDF_get_pdi_value' => ['float', 'p'=>'resource', 'key'=>'string', 'doc'=>'int', 'page'=>'int', 'reserved'=>'int'], +'PDF_get_value' => ['float', 'p'=>'resource', 'key'=>'string', 'modifier'=>'float'], +'PDF_info_font' => ['float', 'pdfdoc'=>'resource', 'font'=>'int', 'keyword'=>'string', 'optlist'=>'string'], +'PDF_info_matchbox' => ['float', 'pdfdoc'=>'resource', 'boxname'=>'string', 'num'=>'int', 'keyword'=>'string'], +'PDF_info_table' => ['float', 'pdfdoc'=>'resource', 'table'=>'int', 'keyword'=>'string'], +'PDF_info_textflow' => ['float', 'pdfdoc'=>'resource', 'textflow'=>'int', 'keyword'=>'string'], +'PDF_info_textline' => ['float', 'pdfdoc'=>'resource', 'text'=>'string', 'keyword'=>'string', 'optlist'=>'string'], +'PDF_initgraphics' => ['bool', 'p'=>'resource'], +'PDF_lineto' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'], +'PDF_load_3ddata' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string'], +'PDF_load_font' => ['int', 'pdfdoc'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'optlist'=>'string'], +'PDF_load_iccprofile' => ['int', 'pdfdoc'=>'resource', 'profilename'=>'string', 'optlist'=>'string'], +'PDF_load_image' => ['int', 'pdfdoc'=>'resource', 'imagetype'=>'string', 'filename'=>'string', 'optlist'=>'string'], +'PDF_makespotcolor' => ['int', 'p'=>'resource', 'spotname'=>'string'], +'PDF_moveto' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'], +'PDF_new' => ['resource'], +'PDF_open_ccitt' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'width'=>'int', 'height'=>'int', 'bitreverse'=>'int', 'k'=>'int', 'blackls1'=>'int'], +'PDF_open_file' => ['bool', 'p'=>'resource', 'filename'=>'string'], +'PDF_open_image' => ['int', 'p'=>'resource', 'imagetype'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'], +'PDF_open_image_file' => ['int', 'p'=>'resource', 'imagetype'=>'string', 'filename'=>'string', 'stringparam'=>'string', 'intparam'=>'int'], +'PDF_open_memory_image' => ['int', 'p'=>'resource', 'image'=>'resource'], +'PDF_open_pdi' => ['int', 'pdfdoc'=>'resource', 'filename'=>'string', 'optlist'=>'string', 'len'=>'int'], +'PDF_open_pdi_document' => ['int', 'p'=>'resource', 'filename'=>'string', 'optlist'=>'string'], +'PDF_open_pdi_page' => ['int', 'p'=>'resource', 'doc'=>'int', 'pagenumber'=>'int', 'optlist'=>'string'], +'PDF_pcos_get_number' => ['float', 'p'=>'resource', 'doc'=>'int', 'path'=>'string'], +'PDF_pcos_get_stream' => ['string', 'p'=>'resource', 'doc'=>'int', 'optlist'=>'string', 'path'=>'string'], +'PDF_pcos_get_string' => ['string', 'p'=>'resource', 'doc'=>'int', 'path'=>'string'], +'PDF_place_image' => ['bool', 'pdfdoc'=>'resource', 'image'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'], +'PDF_place_pdi_page' => ['bool', 'pdfdoc'=>'resource', 'page'=>'int', 'x'=>'float', 'y'=>'float', 'sx'=>'float', 'sy'=>'float'], +'PDF_process_pdi' => ['int', 'pdfdoc'=>'resource', 'doc'=>'int', 'page'=>'int', 'optlist'=>'string'], +'PDF_rect' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], +'PDF_restore' => ['bool', 'p'=>'resource'], +'PDF_resume_page' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], +'PDF_rotate' => ['bool', 'p'=>'resource', 'phi'=>'float'], +'PDF_save' => ['bool', 'p'=>'resource'], +'PDF_scale' => ['bool', 'p'=>'resource', 'sx'=>'float', 'sy'=>'float'], +'PDF_set_border_color' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], +'PDF_set_border_dash' => ['bool', 'pdfdoc'=>'resource', 'black'=>'float', 'white'=>'float'], +'PDF_set_border_style' => ['bool', 'pdfdoc'=>'resource', 'style'=>'string', 'width'=>'float'], +'PDF_set_gstate' => ['bool', 'pdfdoc'=>'resource', 'gstate'=>'int'], +'PDF_set_info' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'], +'PDF_set_layer_dependency' => ['bool', 'pdfdoc'=>'resource', 'type'=>'string', 'optlist'=>'string'], +'PDF_set_parameter' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'string'], +'PDF_set_text_pos' => ['bool', 'p'=>'resource', 'x'=>'float', 'y'=>'float'], +'PDF_set_value' => ['bool', 'p'=>'resource', 'key'=>'string', 'value'=>'float'], +'PDF_setcolor' => ['bool', 'p'=>'resource', 'fstype'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'], +'PDF_setdash' => ['bool', 'pdfdoc'=>'resource', 'b'=>'float', 'w'=>'float'], +'PDF_setdashpattern' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], +'PDF_setflat' => ['bool', 'pdfdoc'=>'resource', 'flatness'=>'float'], +'PDF_setfont' => ['bool', 'pdfdoc'=>'resource', 'font'=>'int', 'fontsize'=>'float'], +'PDF_setgray' => ['bool', 'p'=>'resource', 'g'=>'float'], +'PDF_setgray_fill' => ['bool', 'p'=>'resource', 'g'=>'float'], +'PDF_setgray_stroke' => ['bool', 'p'=>'resource', 'g'=>'float'], +'PDF_setlinecap' => ['bool', 'p'=>'resource', 'linecap'=>'int'], +'PDF_setlinejoin' => ['bool', 'p'=>'resource', 'value'=>'int'], +'PDF_setlinewidth' => ['bool', 'p'=>'resource', 'width'=>'float'], +'PDF_setmatrix' => ['bool', 'p'=>'resource', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'e'=>'float', 'f'=>'float'], +'PDF_setmiterlimit' => ['bool', 'pdfdoc'=>'resource', 'miter'=>'float'], +'PDF_setrgbcolor' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], +'PDF_setrgbcolor_fill' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], +'PDF_setrgbcolor_stroke' => ['bool', 'p'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], +'PDF_shading' => ['int', 'pdfdoc'=>'resource', 'shtype'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'], +'PDF_shading_pattern' => ['int', 'pdfdoc'=>'resource', 'shading'=>'int', 'optlist'=>'string'], +'PDF_shfill' => ['bool', 'pdfdoc'=>'resource', 'shading'=>'int'], +'PDF_show' => ['bool', 'pdfdoc'=>'resource', 'text'=>'string'], +'PDF_show_boxed' => ['int', 'p'=>'resource', 'text'=>'string', 'left'=>'float', 'top'=>'float', 'width'=>'float', 'height'=>'float', 'mode'=>'string', 'feature'=>'string'], +'PDF_show_xy' => ['bool', 'p'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float'], +'PDF_skew' => ['bool', 'p'=>'resource', 'alpha'=>'float', 'beta'=>'float'], +'PDF_stringwidth' => ['float', 'p'=>'resource', 'text'=>'string', 'font'=>'int', 'fontsize'=>'float'], +'PDF_stroke' => ['bool', 'p'=>'resource'], +'PDF_suspend_page' => ['bool', 'pdfdoc'=>'resource', 'optlist'=>'string'], +'PDF_translate' => ['bool', 'p'=>'resource', 'tx'=>'float', 'ty'=>'float'], +'PDF_utf16_to_utf8' => ['string', 'pdfdoc'=>'resource', 'utf16string'=>'string'], +'PDF_utf32_to_utf16' => ['string', 'pdfdoc'=>'resource', 'utf32string'=>'string', 'ordering'=>'string'], +'PDF_utf8_to_utf16' => ['string', 'pdfdoc'=>'resource', 'utf8string'=>'string', 'ordering'=>'string'], +'PDO::__construct' => ['void', 'dsn'=>'string', 'username='=>'?string', 'passwd='=>'?string', 'options='=>'?array'], +'PDO::__sleep' => ['int'], +'PDO::__wakeup' => ['void'], +'PDO::beginTransaction' => ['bool'], +'PDO::commit' => ['bool'], +'PDO::cubrid_schema' => ['array', 'schema_type'=>'int', 'table_name='=>'string', 'col_name='=>'string'], +'PDO::errorCode' => ['string'], +'PDO::errorInfo' => ['array'], +'PDO::exec' => ['int', 'query'=>'string'], +'PDO::getAttribute' => ['', 'attribute'=>'int'], +'PDO::getAvailableDrivers' => ['array'], +'PDO::inTransaction' => ['bool'], +'PDO::lastInsertId' => ['string', 'seqname='=>'string'], +'PDO::pgsqlCopyFromArray' => ['bool', 'table_name'=>'string', 'rows'=>'array', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'], +'PDO::pgsqlCopyFromFile' => ['bool', 'table_name'=>'string', 'filename'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'], +'PDO::pgsqlCopyToArray' => ['array', 'table_name'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'], +'PDO::pgsqlCopyToFile' => ['bool', 'table_name'=>'string', 'filename'=>'string', 'delimiter'=>'string', 'null_as'=>'string', 'fields'=>'string'], +'PDO::pgsqlGetNotify' => ['array', 'result_type'=>'int', 'ms_timeout'=>'int'], +'PDO::pgsqlGetPid' => ['int'], +'PDO::pgsqlLOBCreate' => ['string'], +'PDO::pgsqlLOBOpen' => ['resource', 'oid'=>'string', 'mode='=>'string'], +'PDO::pgsqlLOBUnlink' => ['bool', 'oid'=>'string'], +'PDO::prepare' => ['PDOStatement', 'statement'=>'string', 'options='=>'array'], +'PDO::query' => ['PDOStatement|false', 'sql'=>'string'], +'PDO::query\'1' => ['PDOStatement|false', 'sql'=>'string', 'fetch_column'=>'int', 'colno'=>'int'], +'PDO::query\'2' => ['PDOStatement|false', 'sql'=>'string', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs'=>'array'], +'PDO::query\'3' => ['PDOStatement|false', 'sql'=>'string', 'fetch_into'=>'int', 'object'=>'object'], +'PDO::quote' => ['string', 'string'=>'string', 'paramtype='=>'int'], +'PDO::rollBack' => ['bool'], +'PDO::setAttribute' => ['bool', 'attribute'=>'int', 'value'=>''], +'PDO::sqliteCreateAggregate' => ['bool', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'], +'PDO::sqliteCreateCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'], +'PDO::sqliteCreateFunction' => ['bool', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'], +'pdo_drivers' => ['array'], +'PDOException::getCode' => [''], +'PDOException::getFile' => [''], +'PDOException::getLine' => [''], +'PDOException::getMessage' => [''], +'PDOException::getPrevious' => [''], +'PDOException::getTrace' => [''], +'PDOException::getTraceAsString' => [''], +'PDOStatement::__sleep' => ['int'], +'PDOStatement::__wakeup' => ['void'], +'PDOStatement::bindColumn' => ['bool', 'column'=>'mixed', '&rw_param'=>'mixed', 'type='=>'int', 'maxlen='=>'int', 'driverdata='=>'mixed'], +'PDOStatement::bindParam' => ['bool', 'paramno'=>'mixed', '&rw_param'=>'mixed', 'type='=>'int', 'maxlen='=>'int', 'driverdata='=>'mixed'], +'PDOStatement::bindValue' => ['bool', 'paramno'=>'mixed', 'param'=>'mixed', 'type='=>'int'], +'PDOStatement::closeCursor' => ['bool'], +'PDOStatement::columnCount' => ['int'], +'PDOStatement::debugDumpParams' => ['void'], +'PDOStatement::errorCode' => ['string'], +'PDOStatement::errorInfo' => ['array'], +'PDOStatement::execute' => ['bool', 'bound_input_params='=>'?array'], +'PDOStatement::fetch' => ['mixed', 'how='=>'int', 'orientation='=>'int', 'offset='=>'int'], +'PDOStatement::fetchAll' => ['array|false', 'how='=>'int', 'fetch_argument='=>'int|string|callable', 'ctor_args='=>'?array'], +'PDOStatement::fetchColumn' => ['string|null|false', 'column_number='=>'int'], +'PDOStatement::fetchObject' => ['mixed', 'class_name='=>'string', 'ctor_args='=>'?array'], +'PDOStatement::getAttribute' => ['mixed', 'attribute'=>'int'], +'PDOStatement::getColumnMeta' => ['array', 'column'=>'int'], +'PDOStatement::nextRowset' => ['bool'], +'PDOStatement::rowCount' => ['int'], +'PDOStatement::setAttribute' => ['bool', 'attribute'=>'int', 'value'=>'mixed'], +'PDOStatement::setFetchMode' => ['bool', 'mode'=>'int'], +'PDOStatement::setFetchMode\'1' => ['bool', 'fetch_column'=>'int', 'colno'=>'int'], +'PDOStatement::setFetchMode\'2' => ['bool', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs'=>'array'], +'PDOStatement::setFetchMode\'3' => ['bool', 'fetch_into'=>'int', 'object'=>'object'], +'pfsockopen' => ['resource', 'hostname'=>'string', 'port='=>'int', '&w_errno='=>'int', '&w_errstr='=>'string', 'timeout='=>'float'], +'pg_affected_rows' => ['int', 'result'=>'resource'], +'pg_cancel_query' => ['bool', 'connection'=>'resource'], +'pg_client_encoding' => ['string', 'connection='=>'resource'], +'pg_close' => ['bool', 'connection='=>'resource'], +'pg_connect' => ['resource|false', 'connection_string'=>'string', 'connect_type='=>'int'], +'pg_connect_poll' => ['int', 'connection'=>'resource'], +'pg_connection_busy' => ['bool', 'connection'=>'resource'], +'pg_connection_reset' => ['bool', 'connection'=>'resource'], +'pg_connection_status' => ['int', 'connection'=>'resource'], +'pg_consume_input' => ['bool', 'connection'=>'resource'], +'pg_convert' => ['array', 'db'=>'resource', 'table'=>'string', 'values'=>'array', 'options='=>'int'], +'pg_copy_from' => ['bool', 'connection'=>'resource', 'table_name'=>'string', 'rows'=>'array', 'delimiter='=>'string', 'null_as='=>'string'], +'pg_copy_to' => ['array', 'connection'=>'resource', 'table_name'=>'string', 'delimiter='=>'string', 'null_as='=>'string'], +'pg_dbname' => ['string', 'connection='=>'resource'], +'pg_delete' => ['mixed', 'db'=>'resource', 'table'=>'string', 'ids'=>'array', 'options='=>'int'], +'pg_end_copy' => ['bool', 'connection='=>'resource'], +'pg_escape_bytea' => ['string', 'connection'=>'resource', 'data'=>'string'], +'pg_escape_bytea\'1' => ['string', 'data'=>'string'], +'pg_escape_identifier' => ['string', 'connection'=>'resource', 'data'=>'string'], +'pg_escape_identifier\'1' => ['string', 'data'=>'string'], +'pg_escape_literal' => ['string', 'connection'=>'resource', 'data'=>'string'], +'pg_escape_literal\'1' => ['string', 'data'=>'string'], +'pg_escape_string' => ['string', 'connection'=>'resource', 'data'=>'string'], +'pg_escape_string\'1' => ['string', 'data'=>'string'], +'pg_execute' => ['resource|false', 'connection'=>'resource', 'stmtname'=>'string', 'params'=>'array'], +'pg_execute\'1' => ['resource|false', 'stmtname'=>'string', 'params'=>'array'], +'pg_fetch_all' => ['array|false', 'result'=>'resource', 'result_type='=>'int'], +'pg_fetch_all_columns' => ['array|false', 'result'=>'resource', 'column_number='=>'int'], +'pg_fetch_array' => ['array|false', 'result'=>'resource', 'row='=>'?int', 'result_type='=>'int'], +'pg_fetch_assoc' => ['array|false', 'result'=>'resource', 'row='=>'?int'], +'pg_fetch_object' => ['object', 'result'=>'', 'row='=>'?int', 'result_type='=>'int'], +'pg_fetch_object\'1' => ['object', 'result'=>'', 'row='=>'?int', 'class_name='=>'string', 'ctor_params='=>'array'], +'pg_fetch_result' => ['', 'result'=>'', 'field_name'=>'string|int'], +'pg_fetch_result\'1' => ['', 'result'=>'', 'row_number'=>'int', 'field_name'=>'string|int'], +'pg_fetch_row' => ['array', 'result'=>'resource', 'row='=>'?int', 'result_type='=>'int'], +'pg_field_is_null' => ['int', 'result'=>'', 'field_name_or_number'=>'string|int'], +'pg_field_is_null\'1' => ['int', 'result'=>'', 'row'=>'int', 'field_name_or_number'=>'string|int'], +'pg_field_name' => ['string', 'result'=>'resource', 'field_number'=>'int'], +'pg_field_num' => ['int', 'result'=>'resource', 'field_name'=>'string'], +'pg_field_prtlen' => ['int', 'result'=>'', 'field_name_or_number'=>''], +'pg_field_prtlen\'1' => ['int', 'result'=>'', 'row'=>'int', 'field_name_or_number'=>'string|int'], +'pg_field_size' => ['int', 'result'=>'resource', 'field_number'=>'int'], +'pg_field_table' => ['mixed', 'result'=>'resource', 'field_number'=>'int', 'oid_only='=>'bool'], +'pg_field_type' => ['string', 'result'=>'resource', 'field_number'=>'int'], +'pg_field_type_oid' => ['int|false', 'result'=>'resource', 'field_number'=>'int'], +'pg_flush' => ['mixed', 'connection'=>'resource'], +'pg_free_result' => ['bool', 'result'=>'resource'], +'pg_get_notify' => ['array', 'connection'=>'resource', 'result_type='=>'int'], +'pg_get_pid' => ['int|false', 'connection'=>'resource'], +'pg_get_result' => ['resource|false', 'connection='=>'resource'], +'pg_host' => ['string', 'connection='=>'resource'], +'pg_insert' => ['mixed', 'db'=>'resource', 'table'=>'string', 'values'=>'array', 'options='=>'int'], +'pg_last_error' => ['string', 'connection='=>'resource', 'operation='=>'int'], +'pg_last_notice' => ['string', 'connection'=>'resource', 'option='=>'int'], +'pg_last_oid' => ['string', 'result'=>'resource'], +'pg_lo_close' => ['bool', 'large_object'=>'resource'], +'pg_lo_create' => ['int', 'connection='=>'resource', 'large_object_oid='=>''], +'pg_lo_export' => ['bool', 'connection'=>'resource', 'oid'=>'int', 'filename'=>'string'], +'pg_lo_export\'1' => ['bool', 'oid'=>'int', 'pathname'=>'string'], +'pg_lo_import' => ['int', 'connection'=>'resource', 'pathname'=>'string', 'oid'=>''], +'pg_lo_import\'1' => ['int', 'pathname'=>'string', 'oid'=>''], +'pg_lo_open' => ['resource|false', 'connection'=>'resource', 'oid'=>'int', 'mode'=>'string'], +'pg_lo_read' => ['string', 'large_object'=>'resource', 'len='=>'int'], +'pg_lo_read_all' => ['int', 'large_object'=>'resource'], +'pg_lo_seek' => ['bool', 'large_object'=>'resource', 'offset'=>'int', 'whence='=>'int'], +'pg_lo_tell' => ['int', 'large_object'=>'resource'], +'pg_lo_truncate' => ['bool', 'large_object'=>'resource', 'size'=>'int'], +'pg_lo_unlink' => ['bool', 'connection'=>'resource', 'oid'=>'int'], +'pg_lo_write' => ['int', 'large_object'=>'resource', 'data'=>'string', 'len='=>'int'], +'pg_meta_data' => ['array', 'db'=>'resource', 'table'=>'string', 'extended='=>'bool'], +'pg_num_fields' => ['int', 'result'=>'resource'], +'pg_num_rows' => ['int', 'result'=>'resource'], +'pg_options' => ['string', 'connection='=>'resource'], +'pg_parameter_status' => ['string|false', 'connection'=>'resource', 'param_name'=>'string'], +'pg_parameter_status\'1' => ['string|false', 'param_name'=>'string'], +'pg_pconnect' => ['resource|false', 'connection_string'=>'string', 'host='=>'string', 'port='=>'string|int', 'options='=>'string', 'tty='=>'string', 'database='=>'string'], +'pg_ping' => ['bool', 'connection='=>'resource'], +'pg_port' => ['int', 'connection='=>'resource'], +'pg_prepare' => ['resource|false', 'connection'=>'resource', 'stmtname'=>'string', 'query'=>'string'], +'pg_prepare\'1' => ['resource|false', 'stmtname'=>'string', 'query'=>'string'], +'pg_put_line' => ['bool', 'connection'=>'resource', 'data'=>'string'], +'pg_put_line\'1' => ['bool', 'data'=>'string'], +'pg_query' => ['resource|false', 'connection'=>'resource', 'query'=>'string'], +'pg_query\'1' => ['resource|false', 'query'=>'string'], +'pg_query_params' => ['resource|false', 'connection'=>'resource', 'query'=>'string', 'params'=>'array'], +'pg_query_params\'1' => ['resource|false', 'query'=>'string', 'params'=>'array'], +'pg_result_error' => ['string|false', 'result'=>'resource'], +'pg_result_error_field' => ['string|?false', 'result'=>'resource', 'fieldcode'=>'int'], +'pg_result_seek' => ['bool', 'result'=>'resource', 'offset'=>'int'], +'pg_result_status' => ['mixed', 'result'=>'resource', 'result_type='=>'int'], +'pg_select' => ['mixed', 'db'=>'resource', 'table'=>'string', 'ids'=>'array', 'options='=>'int', 'result_type='=>'int'], +'pg_send_execute' => ['bool', 'connection'=>'resource', 'stmtname'=>'string', 'params'=>'array'], +'pg_send_prepare' => ['bool', 'connection'=>'resource', 'stmtname'=>'string', 'query'=>'string'], +'pg_send_query' => ['bool', 'connection'=>'resource', 'query'=>'string'], +'pg_send_query_params' => ['bool', 'connection'=>'resource', 'query'=>'string', 'params'=>'array'], +'pg_set_client_encoding' => ['int', 'connection'=>'resource', 'encoding'=>'string'], +'pg_set_client_encoding\'1' => ['int', 'encoding'=>'string'], +'pg_set_error_verbosity' => ['int', 'connection'=>'resource', 'verbosity'=>'int'], +'pg_set_error_verbosity\'1' => ['int', 'verbosity'=>'int'], +'pg_socket' => ['resource|false', 'connection'=>'resource'], +'pg_trace' => ['bool', 'filename'=>'string', 'mode='=>'string', 'connection='=>'resource'], +'pg_transaction_status' => ['int', 'connection'=>'resource'], +'pg_tty' => ['string', 'connection='=>'resource'], +'pg_tty\'1' => ['string'], +'pg_unescape_bytea' => ['string', 'data'=>'string'], +'pg_untrace' => ['bool', 'connection='=>'resource'], +'pg_untrace\'1' => ['bool'], +'pg_update' => ['mixed', 'db'=>'resource', 'table'=>'string', 'fields'=>'array', 'ids'=>'array', 'options='=>'int'], +'pg_version' => ['array', 'connection='=>'resource'], +'Phar::__construct' => ['void', 'fname'=>'string', 'flags='=>'int', 'alias='=>'string'], +'Phar::addEmptyDir' => ['', 'dirname'=>'string'], +'Phar::addFile' => ['', 'file'=>'string', 'localname='=>'string'], +'Phar::addFromString' => ['', 'localname'=>'string', 'contents'=>'string'], +'Phar::apiVersion' => ['string'], +'Phar::buildFromDirectory' => ['array', 'base_dir'=>'string', 'regex='=>'string'], +'Phar::buildFromIterator' => ['array', 'iter'=>'iterator', 'base_directory='=>'string'], +'Phar::canCompress' => ['bool', 'method='=>'int'], +'Phar::canWrite' => ['bool'], +'Phar::compress' => ['object', 'compression'=>'int', 'extension='=>'string'], +'Phar::compressAllFilesBZIP2' => ['bool'], +'Phar::compressAllFilesGZ' => ['bool'], +'Phar::compressFiles' => ['', 'compression'=>'int'], +'Phar::convertToData' => ['PharData', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'], +'Phar::convertToExecutable' => ['Phar', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'], +'Phar::copy' => ['bool', 'oldfile'=>'string', 'newfile'=>'string'], +'Phar::count' => ['int'], +'Phar::createDefaultStub' => ['string', 'indexfile='=>'string', 'webindexfile='=>'string'], +'Phar::decompress' => ['object', 'extension='=>'string'], +'Phar::decompressFiles' => ['bool'], +'Phar::delete' => ['bool', 'entry'=>'string'], +'Phar::delMetadata' => ['bool'], +'Phar::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array', 'overwrite='=>'bool'], +'Phar::getAlias' => ['string'], +'Phar::getMetadata' => ['mixed'], +'Phar::getModified' => ['bool'], +'Phar::getPath' => ['string'], +'Phar::getSignature' => ['array'], +'Phar::getStub' => ['string'], +'Phar::getSupportedCompression' => ['array'], +'Phar::getSupportedSignatures' => ['array'], +'Phar::getVersion' => ['string'], +'Phar::hasMetadata' => ['bool'], +'Phar::interceptFileFuncs' => [''], +'Phar::isBuffering' => ['bool'], +'Phar::isCompressed' => [''], +'Phar::isFileFormat' => ['bool', 'format'=>'int'], +'Phar::isValidPharFilename' => ['bool', 'filename'=>'string', 'executable='=>'bool'], +'Phar::isWritable' => ['bool'], +'Phar::loadPhar' => ['bool', 'filename'=>'string', 'alias='=>'string'], +'Phar::mapPhar' => ['bool', 'alias='=>'string', 'dataoffset='=>'int'], +'Phar::mount' => ['void', 'pharpath'=>'string', 'externalpath'=>'string'], +'Phar::mungServer' => ['', 'munglist'=>'array'], +'Phar::offsetExists' => ['bool', 'offset'=>'string'], +'Phar::offsetGet' => ['int', 'offset'=>'string'], +'Phar::offsetSet' => ['', 'offset'=>'string', 'value'=>'string'], +'Phar::offsetUnset' => ['bool', 'offset'=>'string'], +'Phar::running' => ['string', 'retphar='=>'bool'], +'Phar::setAlias' => ['bool', 'alias'=>'string'], +'Phar::setDefaultStub' => ['bool', 'index='=>'string', 'webindex='=>'string'], +'Phar::setMetadata' => ['', 'metadata'=>''], +'Phar::setSignatureAlgorithm' => ['', 'sigtype'=>'int', 'privatekey='=>'string'], +'Phar::setStub' => ['bool', 'stub'=>'string'], +'Phar::startBuffering' => [''], +'Phar::stopBuffering' => [''], +'Phar::uncompressAllFiles' => ['bool'], +'Phar::unlinkArchive' => ['bool', 'archive'=>'string'], +'Phar::webPhar' => ['', 'alias='=>'string', 'index='=>'string', 'f404='=>'string', 'mimetypes='=>'array', 'rewrites='=>'array'], +'PharData::__construct' => ['void', 'fname'=>'string', 'flags='=>'int', 'alias='=>'string', 'format='=>'int'], +'PharData::addEmptyDir' => ['bool', 'dirname'=>'string'], +'PharData::addFile' => ['', 'file'=>'string', 'localname='=>'string'], +'PharData::addFromString' => ['bool', 'localname'=>'string', 'contents'=>'string'], +'PharData::buildFromDirectory' => ['array', 'base_dir'=>'string', 'regex='=>'string'], +'PharData::buildFromIterator' => ['array', 'iter'=>'iterator', 'base_directory='=>'string'], +'PharData::compress' => ['object', 'compression'=>'int', 'extension='=>'string'], +'PharData::compressFiles' => ['bool', 'compression'=>'int'], +'PharData::convertToData' => ['PharData', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'], +'PharData::convertToExecutable' => ['Phar', 'format='=>'int', 'compression='=>'int', 'extension='=>'string'], +'PharData::copy' => ['bool', 'oldfile'=>'string', 'newfile'=>'string'], +'PharData::decompress' => ['object', 'extension='=>'string'], +'PharData::decompressFiles' => ['bool'], +'PharData::delete' => ['bool', 'entry'=>'string'], +'PharData::delMetadata' => ['bool'], +'PharData::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string|array', 'overwrite='=>'bool'], +'PharData::isWritable' => ['bool'], +'PharData::offsetSet' => ['', 'offset'=>'string', 'value'=>'string'], +'PharData::offsetUnset' => ['bool', 'offset'=>'string'], +'PharData::setAlias' => ['bool', 'alias'=>'string'], +'PharData::setDefaultStub' => ['bool', 'index='=>'string', 'webindex='=>'string'], +'PharData::setStub' => ['bool', 'stub'=>'string'], +'PharFileInfo::__construct' => ['void', 'entry'=>'string'], +'PharFileInfo::chmod' => ['void', 'permissions'=>'int'], +'PharFileInfo::compress' => ['bool', 'compression'=>'int'], +'PharFileInfo::decompress' => ['bool'], +'PharFileInfo::delMetadata' => ['bool'], +'PharFileInfo::getCompressedSize' => ['int'], +'PharFileInfo::getContent' => ['string'], +'PharFileInfo::getCRC32' => ['int'], +'PharFileInfo::getMetadata' => ['mixed'], +'PharFileInfo::getPharFlags' => ['int'], +'PharFileInfo::hasMetadata' => ['bool'], +'PharFileInfo::isCompressed' => ['bool', 'compression_type='=>'int'], +'PharFileInfo::isCompressedBZIP2' => ['bool'], +'PharFileInfo::isCompressedGZ' => ['bool'], +'PharFileInfo::isCRCChecked' => ['bool'], +'PharFileInfo::setCompressedBZIP2' => ['bool'], +'PharFileInfo::setCompressedGZ' => ['bool'], +'PharFileInfo::setMetadata' => ['void', 'metadata'=>'mixed'], +'PharFileInfo::setUncompressed' => ['bool'], +'phdfs::__construct' => ['void', 'ip'=>'string', 'port'=>'string'], +'phdfs::__destruct' => [''], +'phdfs::connect' => ['bool'], +'phdfs::copy' => ['bool', 'source_file'=>'string', 'destination_file'=>'string'], +'phdfs::create_directory' => ['bool', 'path'=>'string'], +'phdfs::delete' => ['bool', 'path'=>'string'], +'phdfs::disconnect' => ['bool'], +'phdfs::exists' => ['bool', 'path'=>'string'], +'phdfs::file_info' => ['array', 'path'=>'string'], +'phdfs::list_directory' => ['array', 'path'=>'string'], +'phdfs::read' => ['string', 'path'=>'string', 'length='=>'string'], +'phdfs::rename' => ['bool', 'old_path'=>'string', 'new_path'=>'string'], +'phdfs::tell' => ['int', 'path'=>'string'], +'phdfs::write' => ['bool', 'path'=>'string', 'buffer'=>'string', 'mode='=>'string'], +'php_check_syntax' => ['bool', 'filename'=>'string', 'error_message='=>'string'], +'php_ini_loaded_file' => ['string'], +'php_ini_scanned_files' => ['string'], +'php_logo_guid' => ['string'], +'php_sapi_name' => ['string'], +'php_strip_whitespace' => ['string', 'file_name'=>'string'], +'php_uname' => ['string', 'mode='=>'string'], +'php_user_filter::filter' => ['int', 'in'=>'resource', 'out'=>'resource', '&rw_consumed'=>'int', 'closing'=>'bool'], +'php_user_filter::onClose' => ['void'], +'php_user_filter::onCreate' => ['bool'], +'phpcredits' => ['bool', 'flag='=>'int'], +'phpdbg_break' => [''], +'phpdbg_break_file' => ['', 'file'=>'string', 'line'=>'int'], +'phpdbg_break_function' => ['', 'function'=>'string'], +'phpdbg_break_method' => ['', 'class'=>'string', 'method'=>'string'], +'phpdbg_clear' => [''], +'phpdbg_color' => ['', 'element'=>'int', 'color'=>'string'], +'phpdbg_end_oplog' => [''], +'phpdbg_prompt' => ['', 'prompt'=>'string'], +'phpdbg_start_oplog' => [''], +'phpinfo' => ['bool', 'what='=>'int'], +'phpversion' => ['string|false', 'extension='=>'string'], +'pht\AtomicInteger::__construct' => ['void', 'value='=>'int'], +'pht\AtomicInteger::dec' => ['void'], +'pht\AtomicInteger::get' => ['int'], +'pht\AtomicInteger::inc' => ['void'], +'pht\AtomicInteger::lock' => ['void'], +'pht\AtomicInteger::set' => ['void', 'value'=>'int'], +'pht\AtomicInteger::unlock' => ['void'], +'pht\HashTable::lock' => ['void'], +'pht\HashTable::size' => ['int'], +'pht\HashTable::unlock' => ['void'], +'pht\Queue::front' => ['mixed'], +'pht\Queue::lock' => ['void'], +'pht\Queue::pop' => ['mixed'], +'pht\Queue::push' => ['void', 'value'=>'mixed'], +'pht\Queue::size' => ['int'], +'pht\Queue::unlock' => ['void'], +'pht\Runnable::run' => ['void'], +'pht\Vector::__construct' => ['void', 'size='=>'int', 'value='=>'mixed'], +'pht\Vector::deleteAt' => ['void', 'offset'=>'int'], +'pht\Vector::insertAt' => ['void', 'value'=>'mixed', 'offset'=>'int'], +'pht\Vector::lock' => ['void'], +'pht\Vector::pop' => ['mixed'], +'pht\Vector::push' => ['void', 'value'=>'mixed'], +'pht\Vector::resize' => ['void', 'size'=>'int', 'value='=>'mixed'], +'pht\Vector::shift' => ['mixed'], +'pht\Vector::size' => ['int'], +'pht\Vector::unlock' => ['void'], +'pht\Vector::unshift' => ['void', 'value'=>'mixed'], +'pht\Vector::updateAt' => ['void', 'value'=>'mixed', 'offset'=>'int'], +'pi' => ['float'], +'png2wbmp' => ['bool', 'pngname'=>'string', 'wbmpname'=>'string', 'dest_height'=>'int', 'dest_width'=>'int', 'threshold'=>'int'], +'pointObj::__construct' => ['void'], +'pointObj::distanceToLine' => ['float', 'p1'=>'pointObj', 'p2'=>'pointObj'], +'pointObj::distanceToPoint' => ['float', 'poPoint'=>'pointObj'], +'pointObj::distanceToShape' => ['float', 'shape'=>'shapeObj'], +'pointObj::draw' => ['int', 'map'=>'MapObj', 'layer'=>'layerObj', 'img'=>'imageObj', 'class_index'=>'int', 'text'=>'string'], +'pointObj::ms_newPointObj' => ['pointObj'], +'pointObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'], +'pointObj::setXY' => ['int', 'x'=>'float', 'y'=>'float', 'm'=>'float'], +'pointObj::setXYZ' => ['int', 'x'=>'float', 'y'=>'float', 'z'=>'float', 'm'=>'float'], +'Pool::__construct' => ['void', 'size'=>'int', 'class'=>'string', 'ctor='=>'array'], +'Pool::collect' => ['void', 'collector'=>'Callable'], +'Pool::resize' => ['void', 'size'=>'int'], +'Pool::shutdown' => ['void'], +'Pool::submit' => ['int', 'task'=>'Threaded'], +'Pool::submitTo' => ['int', 'worker'=>'int', 'task'=>'Threaded'], +'popen' => ['resource|false', 'command'=>'string', 'mode'=>'string'], +'pos' => ['mixed', 'array_arg'=>'array'], +'posix_access' => ['bool', 'file'=>'string', 'mode='=>'int'], +'posix_ctermid' => ['string'], +'posix_errno' => ['int'], +'posix_get_last_error' => ['int'], +'posix_getcwd' => ['string'], +'posix_getegid' => ['int'], +'posix_geteuid' => ['int'], +'posix_getgid' => ['int'], +'posix_getgrgid' => ['array', 'gid'=>'int'], +'posix_getgrnam' => ['array|false', 'groupname'=>'string'], +'posix_getgroups' => ['array'], +'posix_getlogin' => ['string'], +'posix_getpgid' => ['int', 'pid'=>'int'], +'posix_getpgrp' => ['int'], +'posix_getpid' => ['int'], +'posix_getppid' => ['int'], +'posix_getpwnam' => ['array|false', 'groupname'=>'string'], +'posix_getpwuid' => ['array', 'uid'=>'int'], +'posix_getrlimit' => ['array'], +'posix_getsid' => ['int', 'pid'=>'int'], +'posix_getuid' => ['int'], +'posix_initgroups' => ['bool', 'name'=>'string', 'base_group_id'=>'int'], +'posix_isatty' => ['bool', 'fd'=>'resource|int'], +'posix_kill' => ['bool', 'pid'=>'int', 'sig'=>'int'], +'posix_mkfifo' => ['bool', 'pathname'=>'string', 'mode'=>'int'], +'posix_mknod' => ['bool', 'pathname'=>'string', 'mode'=>'int', 'major='=>'int', 'minor='=>'int'], +'posix_setegid' => ['bool', 'uid'=>'int'], +'posix_seteuid' => ['bool', 'uid'=>'int'], +'posix_setgid' => ['bool', 'uid'=>'int'], +'posix_setpgid' => ['bool', 'pid'=>'int', 'pgid'=>'int'], +'posix_setrlimit' => ['bool', 'resource'=>'int', 'softlimit'=>'int', 'hardlimit'=>'int'], +'posix_setsid' => ['int'], +'posix_setuid' => ['bool', 'uid'=>'int'], +'posix_strerror' => ['string', 'errno'=>'int'], +'posix_times' => ['array'], +'posix_ttyname' => ['string|false', 'fd'=>'resource|int'], +'posix_uname' => ['array'], +'Postal\Expand::expand_address' => ['string[]', 'address'=>'string', 'options='=>'array'], +'Postal\Parser::parse_address' => ['array', 'address'=>'string', 'options='=>'array'], +'pow' => ['float|int', 'base'=>'int|float', 'exponent'=>'int|float'], +'preg_filter' => ['mixed', 'regex'=>'mixed', 'replace'=>'mixed', 'subject'=>'mixed', 'limit='=>'int', '&w_count='=>'int'], +'preg_grep' => ['array', 'regex'=>'string', 'input'=>'array', 'flags='=>'int'], +'preg_last_error' => ['int'], +'preg_match' => ['int|false', 'pattern'=>'string', 'subject'=>'string', '&w_subpatterns='=>'string[]', 'flags='=>'int', 'offset='=>'int'], +'preg_match_all' => ['int|false', 'pattern'=>'string', 'subject'=>'string', '&w_subpatterns='=>'array', 'flags='=>'int', 'offset='=>'int'], +'preg_quote' => ['string', 'str'=>'string', 'delim_char='=>'string'], +'preg_replace' => ['string|array|null', 'regex'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'], +'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'], +'preg_replace_callback_array' => ['string|array|null', 'pattern'=>'array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'], +'preg_split' => ['array|false', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'?int', 'flags='=>'int'], +'prev' => ['mixed', '&rw_array_arg'=>'array|object'], +'print' => ['int', 'arg'=>'string'], +'print_r' => ['string|true', 'var'=>'mixed', 'return='=>'bool'], +'printf' => ['int', 'format'=>'string', '...args='=>'string|int|float'], +'proc_close' => ['int', 'process'=>'resource'], +'proc_get_status' => ['array', 'process'=>'resource'], +'proc_nice' => ['bool', 'priority'=>'int'], +'proc_open' => ['resource|false', 'command'=>'string', 'descriptorspec'=>'array', '&w_pipes'=>'resource[]', 'cwd='=>'?string', 'env='=>'?array', 'other_options='=>'array'], +'proc_terminate' => ['bool', 'process'=>'resource', 'signal='=>'int'], +'projectionObj::__construct' => ['void', 'projectionString'=>'string'], +'projectionObj::getUnits' => ['int'], +'projectionObj::ms_newProjectionObj' => ['projectionObj', 'projectionString'=>'string'], +'property_exists' => ['bool', 'object_or_class'=>'object|string', 'property_name'=>'string'], +'ps_add_bookmark' => ['int', 'psdoc'=>'resource', 'text'=>'string', 'parent='=>'int', 'open='=>'int'], +'ps_add_launchlink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string'], +'ps_add_locallink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'page'=>'int', 'dest'=>'string'], +'ps_add_note' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'contents'=>'string', 'title'=>'string', 'icon'=>'string', 'open'=>'int'], +'ps_add_pdflink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'filename'=>'string', 'page'=>'int', 'dest'=>'string'], +'ps_add_weblink' => ['bool', 'psdoc'=>'resource', 'llx'=>'float', 'lly'=>'float', 'urx'=>'float', 'ury'=>'float', 'url'=>'string'], +'ps_arc' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'alpha'=>'float', 'beta'=>'float'], +'ps_arcn' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float', 'alpha'=>'float', 'beta'=>'float'], +'ps_begin_page' => ['bool', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float'], +'ps_begin_pattern' => ['int', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float', 'xstep'=>'float', 'ystep'=>'float', 'painttype'=>'int'], +'ps_begin_template' => ['int', 'psdoc'=>'resource', 'width'=>'float', 'height'=>'float'], +'ps_circle' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'radius'=>'float'], +'ps_clip' => ['bool', 'psdoc'=>'resource'], +'ps_close' => ['bool', 'psdoc'=>'resource'], +'ps_close_image' => ['void', 'psdoc'=>'resource', 'imageid'=>'int'], +'ps_closepath' => ['bool', 'psdoc'=>'resource'], +'ps_closepath_stroke' => ['bool', 'psdoc'=>'resource'], +'ps_continue_text' => ['bool', 'psdoc'=>'resource', 'text'=>'string'], +'ps_curveto' => ['bool', 'psdoc'=>'resource', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], +'ps_delete' => ['bool', 'psdoc'=>'resource'], +'ps_end_page' => ['bool', 'psdoc'=>'resource'], +'ps_end_pattern' => ['bool', 'psdoc'=>'resource'], +'ps_end_template' => ['bool', 'psdoc'=>'resource'], +'ps_fill' => ['bool', 'psdoc'=>'resource'], +'ps_fill_stroke' => ['bool', 'psdoc'=>'resource'], +'ps_findfont' => ['int', 'psdoc'=>'resource', 'fontname'=>'string', 'encoding'=>'string', 'embed='=>'bool'], +'ps_get_buffer' => ['string', 'psdoc'=>'resource'], +'ps_get_parameter' => ['string', 'psdoc'=>'resource', 'name'=>'string', 'modifier='=>'float'], +'ps_get_value' => ['float', 'psdoc'=>'resource', 'name'=>'string', 'modifier='=>'float'], +'ps_hyphenate' => ['array', 'psdoc'=>'resource', 'text'=>'string'], +'ps_include_file' => ['bool', 'psdoc'=>'resource', 'file'=>'string'], +'ps_lineto' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], +'ps_makespotcolor' => ['int', 'psdoc'=>'resource', 'name'=>'string', 'reserved='=>'int'], +'ps_moveto' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], +'ps_new' => ['resource'], +'ps_open_file' => ['bool', 'psdoc'=>'resource', 'filename='=>'string'], +'ps_open_image' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'source'=>'string', 'data'=>'string', 'length'=>'int', 'width'=>'int', 'height'=>'int', 'components'=>'int', 'bpc'=>'int', 'params'=>'string'], +'ps_open_image_file' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'filename'=>'string', 'stringparam='=>'string', 'intparam='=>'int'], +'ps_open_memory_image' => ['int', 'psdoc'=>'resource', 'gd'=>'int'], +'ps_place_image' => ['bool', 'psdoc'=>'resource', 'imageid'=>'int', 'x'=>'float', 'y'=>'float', 'scale'=>'float'], +'ps_rect' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float', 'width'=>'float', 'height'=>'float'], +'ps_restore' => ['bool', 'psdoc'=>'resource'], +'ps_rotate' => ['bool', 'psdoc'=>'resource', 'rot'=>'float'], +'ps_save' => ['bool', 'psdoc'=>'resource'], +'ps_scale' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], +'ps_set_border_color' => ['bool', 'psdoc'=>'resource', 'red'=>'float', 'green'=>'float', 'blue'=>'float'], +'ps_set_border_dash' => ['bool', 'psdoc'=>'resource', 'black'=>'float', 'white'=>'float'], +'ps_set_border_style' => ['bool', 'psdoc'=>'resource', 'style'=>'string', 'width'=>'float'], +'ps_set_info' => ['bool', 'p'=>'resource', 'key'=>'string', 'val'=>'string'], +'ps_set_parameter' => ['bool', 'psdoc'=>'resource', 'name'=>'string', 'value'=>'string'], +'ps_set_text_pos' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], +'ps_set_value' => ['bool', 'psdoc'=>'resource', 'name'=>'string', 'value'=>'float'], +'ps_setcolor' => ['bool', 'psdoc'=>'resource', 'type'=>'string', 'colorspace'=>'string', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float'], +'ps_setdash' => ['bool', 'psdoc'=>'resource', 'on'=>'float', 'off'=>'float'], +'ps_setflat' => ['bool', 'psdoc'=>'resource', 'value'=>'float'], +'ps_setfont' => ['bool', 'psdoc'=>'resource', 'fontid'=>'int', 'size'=>'float'], +'ps_setgray' => ['bool', 'psdoc'=>'resource', 'gray'=>'float'], +'ps_setlinecap' => ['bool', 'psdoc'=>'resource', 'type'=>'int'], +'ps_setlinejoin' => ['bool', 'psdoc'=>'resource', 'type'=>'int'], +'ps_setlinewidth' => ['bool', 'psdoc'=>'resource', 'width'=>'float'], +'ps_setmiterlimit' => ['bool', 'psdoc'=>'resource', 'value'=>'float'], +'ps_setoverprintmode' => ['bool', 'psdoc'=>'resource', 'mode'=>'int'], +'ps_setpolydash' => ['bool', 'psdoc'=>'resource', 'arr'=>'float'], +'ps_shading' => ['int', 'psdoc'=>'resource', 'type'=>'string', 'x0'=>'float', 'y0'=>'float', 'x1'=>'float', 'y1'=>'float', 'c1'=>'float', 'c2'=>'float', 'c3'=>'float', 'c4'=>'float', 'optlist'=>'string'], +'ps_shading_pattern' => ['int', 'psdoc'=>'resource', 'shadingid'=>'int', 'optlist'=>'string'], +'ps_shfill' => ['bool', 'psdoc'=>'resource', 'shadingid'=>'int'], +'ps_show' => ['bool', 'psdoc'=>'resource', 'text'=>'string'], +'ps_show2' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'len'=>'int'], +'ps_show_boxed' => ['int', 'psdoc'=>'resource', 'text'=>'string', 'left'=>'float', 'bottom'=>'float', 'width'=>'float', 'height'=>'float', 'hmode'=>'string', 'feature='=>'string'], +'ps_show_xy' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'x'=>'float', 'y'=>'float'], +'ps_show_xy2' => ['bool', 'psdoc'=>'resource', 'text'=>'string', 'len'=>'int', 'xcoor'=>'float', 'ycoor'=>'float'], +'ps_string_geometry' => ['array', 'psdoc'=>'resource', 'text'=>'string', 'fontid='=>'int', 'size='=>'float'], +'ps_stringwidth' => ['float', 'psdoc'=>'resource', 'text'=>'string', 'fontid='=>'int', 'size='=>'float'], +'ps_stroke' => ['bool', 'psdoc'=>'resource'], +'ps_symbol' => ['bool', 'psdoc'=>'resource', 'ord'=>'int'], +'ps_symbol_name' => ['string', 'psdoc'=>'resource', 'ord'=>'int', 'fontid='=>'int'], +'ps_symbol_width' => ['float', 'psdoc'=>'resource', 'ord'=>'int', 'fontid='=>'int', 'size='=>'float'], +'ps_translate' => ['bool', 'psdoc'=>'resource', 'x'=>'float', 'y'=>'float'], +'pspell_add_to_personal' => ['bool', 'pspell'=>'int', 'word'=>'string'], +'pspell_add_to_session' => ['bool', 'pspell'=>'int', 'word'=>'string'], +'pspell_check' => ['bool', 'pspell'=>'int', 'word'=>'string'], +'pspell_clear_session' => ['bool', 'pspell'=>'int'], +'pspell_config_create' => ['int|false', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string'], +'pspell_config_data_dir' => ['bool', 'conf'=>'int', 'directory'=>'string'], +'pspell_config_dict_dir' => ['bool', 'conf'=>'int', 'directory'=>'string'], +'pspell_config_ignore' => ['bool', 'conf'=>'int', 'ignore'=>'int'], +'pspell_config_mode' => ['bool', 'conf'=>'int', 'mode'=>'int'], +'pspell_config_personal' => ['bool', 'conf'=>'int', 'personal'=>'string'], +'pspell_config_repl' => ['bool', 'conf'=>'int', 'repl'=>'string'], +'pspell_config_runtogether' => ['bool', 'conf'=>'int', 'runtogether'=>'bool'], +'pspell_config_save_repl' => ['bool', 'conf'=>'int', 'save'=>'bool'], +'pspell_new' => ['int|false', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'], +'pspell_new_config' => ['int|false', 'config'=>'int'], +'pspell_new_personal' => ['int|false', 'personal'=>'string', 'language'=>'string', 'spelling='=>'string', 'jargon='=>'string', 'encoding='=>'string', 'mode='=>'int'], +'pspell_save_wordlist' => ['bool', 'pspell'=>'int'], +'pspell_store_replacement' => ['bool', 'pspell'=>'int', 'misspell'=>'string', 'correct'=>'string'], +'pspell_suggest' => ['array', 'pspell'=>'int', 'word'=>'string'], +'putenv' => ['bool', 'setting'=>'string'], +'px_close' => ['bool', 'pxdoc'=>'resource'], +'px_create_fp' => ['bool', 'pxdoc'=>'resource', 'file'=>'resource', 'fielddesc'=>'array'], +'px_date2string' => ['string', 'pxdoc'=>'resource', 'value'=>'int', 'format'=>'string'], +'px_delete' => ['bool', 'pxdoc'=>'resource'], +'px_delete_record' => ['bool', 'pxdoc'=>'resource', 'num'=>'int'], +'px_get_field' => ['array', 'pxdoc'=>'resource', 'fieldno'=>'int'], +'px_get_info' => ['array', 'pxdoc'=>'resource'], +'px_get_parameter' => ['string', 'pxdoc'=>'resource', 'name'=>'string'], +'px_get_record' => ['array', 'pxdoc'=>'resource', 'num'=>'int', 'mode='=>'int'], +'px_get_schema' => ['array', 'pxdoc'=>'resource', 'mode='=>'int'], +'px_get_value' => ['float', 'pxdoc'=>'resource', 'name'=>'string'], +'px_insert_record' => ['int', 'pxdoc'=>'resource', 'data'=>'array'], +'px_new' => ['resource'], +'px_numfields' => ['int', 'pxdoc'=>'resource'], +'px_numrecords' => ['int', 'pxdoc'=>'resource'], +'px_open_fp' => ['bool', 'pxdoc'=>'resource', 'file'=>'resource'], +'px_put_record' => ['bool', 'pxdoc'=>'resource', 'record'=>'array', 'recpos='=>'int'], +'px_retrieve_record' => ['array', 'pxdoc'=>'resource', 'num'=>'int', 'mode='=>'int'], +'px_set_blob_file' => ['bool', 'pxdoc'=>'resource', 'filename'=>'string'], +'px_set_parameter' => ['bool', 'pxdoc'=>'resource', 'name'=>'string', 'value'=>'string'], +'px_set_tablename' => ['void', 'pxdoc'=>'resource', 'name'=>'string'], +'px_set_targetencoding' => ['bool', 'pxdoc'=>'resource', 'encoding'=>'string'], +'px_set_value' => ['bool', 'pxdoc'=>'resource', 'name'=>'string', 'value'=>'float'], +'px_timestamp2string' => ['string', 'pxdoc'=>'resource', 'value'=>'float', 'format'=>'string'], +'px_update_record' => ['bool', 'pxdoc'=>'resource', 'data'=>'array', 'num'=>'int'], +'qdom_error' => ['string'], +'qdom_tree' => ['QDomDocument', 'doc'=>'string'], +'querymapObj::convertToString' => ['string'], +'querymapObj::free' => ['void'], +'querymapObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'querymapObj::updateFromString' => ['int', 'snippet'=>'string'], +'QuickHashIntHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'], +'QuickHashIntHash::add' => ['bool', 'key'=>'int', 'value='=>'int'], +'QuickHashIntHash::delete' => ['bool', 'key'=>'int'], +'QuickHashIntHash::exists' => ['bool', 'key'=>'int'], +'QuickHashIntHash::get' => ['int', 'key'=>'int'], +'QuickHashIntHash::getSize' => ['int'], +'QuickHashIntHash::loadFromFile' => ['QuickHashIntHash', 'filename'=>'string', 'options='=>'int'], +'QuickHashIntHash::loadFromString' => ['QuickHashIntHash', 'contents'=>'string', 'options='=>'int'], +'QuickHashIntHash::saveToFile' => ['void', 'filename'=>'string'], +'QuickHashIntHash::saveToString' => ['string'], +'QuickHashIntHash::set' => ['bool', 'key'=>'int', 'value'=>'int'], +'QuickHashIntHash::update' => ['bool', 'key'=>'int', 'value'=>'int'], +'QuickHashIntSet::__construct' => ['void', 'size'=>'int', 'options='=>'int'], +'QuickHashIntSet::add' => ['bool', 'key'=>'int'], +'QuickHashIntSet::delete' => ['bool', 'key'=>'int'], +'QuickHashIntSet::exists' => ['bool', 'key'=>'int'], +'QuickHashIntSet::getSize' => ['int'], +'QuickHashIntSet::loadFromFile' => ['QuickHashIntSet', 'filename'=>'string', 'size='=>'int', 'options='=>'int'], +'QuickHashIntSet::loadFromString' => ['QuickHashIntSet', 'contents'=>'string', 'size='=>'int', 'options='=>'int'], +'QuickHashIntSet::saveToFile' => ['void', 'filename'=>'string'], +'QuickHashIntSet::saveToString' => ['string'], +'QuickHashIntStringHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'], +'QuickHashIntStringHash::add' => ['bool', 'key'=>'int', 'value'=>'string'], +'QuickHashIntStringHash::delete' => ['bool', 'key'=>'int'], +'QuickHashIntStringHash::exists' => ['bool', 'key'=>'int'], +'QuickHashIntStringHash::get' => ['mixed', 'key'=>'int'], +'QuickHashIntStringHash::getSize' => ['int'], +'QuickHashIntStringHash::loadFromFile' => ['QuickHashIntStringHash', 'filename'=>'string', 'size='=>'int', 'options='=>'int'], +'QuickHashIntStringHash::loadFromString' => ['QuickHashIntStringHash', 'contents'=>'string', 'size='=>'int', 'options='=>'int'], +'QuickHashIntStringHash::saveToFile' => ['void', 'filename'=>'string'], +'QuickHashIntStringHash::saveToString' => ['string'], +'QuickHashIntStringHash::set' => ['int', 'key'=>'int', 'value'=>'string'], +'QuickHashIntStringHash::update' => ['bool', 'key'=>'int', 'value'=>'string'], +'QuickHashStringIntHash::__construct' => ['void', 'size'=>'int', 'options='=>'int'], +'QuickHashStringIntHash::add' => ['bool', 'key'=>'string', 'value'=>'int'], +'QuickHashStringIntHash::delete' => ['bool', 'key'=>'string'], +'QuickHashStringIntHash::exists' => ['bool', 'key'=>'string'], +'QuickHashStringIntHash::get' => ['mixed', 'key'=>'string'], +'QuickHashStringIntHash::getSize' => ['int'], +'QuickHashStringIntHash::loadFromFile' => ['QuickHashStringIntHash', 'filename'=>'string', 'size='=>'int', 'options='=>'int'], +'QuickHashStringIntHash::loadFromString' => ['QuickHashStringIntHash', 'contents'=>'string', 'size='=>'int', 'options='=>'int'], +'QuickHashStringIntHash::saveToFile' => ['void', 'filename'=>'string'], +'QuickHashStringIntHash::saveToString' => ['string'], +'QuickHashStringIntHash::set' => ['int', 'key'=>'string', 'value'=>'int'], +'QuickHashStringIntHash::update' => ['bool', 'key'=>'string', 'value'=>'int'], +'quoted_printable_decode' => ['string', 'str'=>'string'], +'quoted_printable_encode' => ['string', 'str'=>'string'], +'quotemeta' => ['string', 'str'=>'string'], +'rad2deg' => ['float', 'number'=>'float'], +'radius_acct_open' => ['resource'], +'radius_add_server' => ['bool', 'radius_handle'=>'resource', 'hostname'=>'string', 'port'=>'int', 'secret'=>'string', 'timeout'=>'int', 'max_tries'=>'int'], +'radius_auth_open' => ['resource'], +'radius_close' => ['bool', 'radius_handle'=>'resource'], +'radius_config' => ['bool', 'radius_handle'=>'resource', 'file'=>'string'], +'radius_create_request' => ['bool', 'radius_handle'=>'resource', 'type'=>'int'], +'radius_cvt_addr' => ['string', 'data'=>'string'], +'radius_cvt_int' => ['int', 'data'=>'string'], +'radius_cvt_string' => ['string', 'data'=>'string'], +'radius_demangle' => ['string', 'radius_handle'=>'resource', 'mangled'=>'string'], +'radius_demangle_mppe_key' => ['string', 'radius_handle'=>'resource', 'mangled'=>'string'], +'radius_get_attr' => ['mixed', 'radius_handle'=>'resource'], +'radius_get_tagged_attr_data' => ['string', 'data'=>'string'], +'radius_get_tagged_attr_tag' => ['int', 'data'=>'string'], +'radius_get_vendor_attr' => ['array', 'data'=>'string'], +'radius_put_addr' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'addr'=>'string'], +'radius_put_attr' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'string'], +'radius_put_int' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'int'], +'radius_put_string' => ['bool', 'radius_handle'=>'resource', 'type'=>'int', 'value'=>'string'], +'radius_put_vendor_addr' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'addr'=>'string'], +'radius_put_vendor_attr' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'string'], +'radius_put_vendor_int' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'int'], +'radius_put_vendor_string' => ['bool', 'radius_handle'=>'resource', 'vendor'=>'int', 'type'=>'int', 'value'=>'string'], +'radius_request_authenticator' => ['string', 'radius_handle'=>'resource'], +'radius_salt_encrypt_attr' => ['string', 'radius_handle'=>'resource', 'data'=>'string'], +'radius_send_request' => ['int', 'radius_handle'=>'resource'], +'radius_server_secret' => ['string', 'radius_handle'=>'resource'], +'radius_strerror' => ['string', 'radius_handle'=>'resource'], +'rand' => ['int', 'min'=>'int', 'max'=>'int'], +'rand\'1' => ['int'], +'random_bytes' => ['string', 'length'=>'int'], +'random_int' => ['int', 'min'=>'int', 'max'=>'int'], +'range' => ['array', 'low'=>'mixed', 'high'=>'mixed', 'step='=>'int|float'], +'RangeException::__clone' => ['void'], +'RangeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?RangeException'], +'RangeException::__toString' => ['string'], +'RangeException::getCode' => ['int'], +'RangeException::getFile' => ['string'], +'RangeException::getLine' => ['int'], +'RangeException::getMessage' => ['string'], +'RangeException::getPrevious' => ['Throwable|RangeException|null'], +'RangeException::getTrace' => ['array'], +'RangeException::getTraceAsString' => ['string'], +'rar_allow_broken_set' => ['bool', 'rarfile'=>'RarArchive', 'allow_broken'=>'bool'], +'rar_broken_is' => ['bool', 'rarfile'=>'rararchive'], +'rar_close' => ['bool', 'rarfile'=>'rararchive'], +'rar_comment_get' => ['string', 'rarfile'=>'rararchive'], +'rar_entry_get' => ['RarEntry', 'entryname'=>'string', 'rarfile'=>'rararchive'], +'rar_list' => ['RarArchive', 'rarfile'=>'rararchive'], +'rar_open' => ['RarArchive', 'filename'=>'string', 'password='=>'string', 'volume_callback='=>'callable'], +'rar_solid_is' => ['bool', 'rarfile'=>'rararchive'], +'rar_wrapper_cache_stats' => ['string'], +'RarArchive::__toString' => ['string'], +'RarArchive::close' => ['bool', 'rarfile'=>'rararchive'], +'RarArchive::getComment' => ['string', 'rarfile'=>'rararchive'], +'RarArchive::getEntries' => ['RarArchive', 'rarfile'=>'rararchive'], +'RarArchive::getEntry' => ['RarEntry', 'entryname'=>'string', 'rarfile'=>'rararchive'], +'RarArchive::isBroken' => ['bool', 'rarfile'=>'rararchive'], +'RarArchive::isSolid' => ['bool', 'rarfile'=>'rararchive'], +'RarArchive::open' => ['RarArchive', 'filename'=>'string', 'password='=>'string', 'volume_callback='=>'callable'], +'RarArchive::setAllowBroken' => ['bool', 'allow_broken'=>'bool', 'rarfile'=>'rararchive'], +'RarEntry::__toString' => ['string'], +'RarEntry::extract' => ['bool', 'dir'=>'string', 'filepath='=>'string', 'password='=>'string', 'extended_data='=>'bool'], +'RarEntry::getAttr' => ['int'], +'RarEntry::getCrc' => ['string'], +'RarEntry::getFileTime' => ['string'], +'RarEntry::getHostOs' => ['int'], +'RarEntry::getMethod' => ['int'], +'RarEntry::getName' => ['string'], +'RarEntry::getPackedSize' => ['int'], +'RarEntry::getStream' => ['resource', 'password='=>'string'], +'RarEntry::getUnpackedSize' => ['int'], +'RarEntry::getVersion' => ['int'], +'RarEntry::isDirectory' => ['bool'], +'RarEntry::isEncrypted' => ['bool'], +'RarException::getCode' => ['int'], +'RarException::getFile' => ['string'], +'RarException::getLine' => ['int'], +'RarException::getMessage' => ['string'], +'RarException::getPrevious' => ['Exception|Throwable'], +'RarException::getTrace' => ['array'], +'RarException::getTraceAsString' => ['string'], +'RarException::isUsingExceptions' => ['bool'], +'RarException::setUsingExceptions' => ['RarEntry', 'using_exceptions'=>'bool'], +'rawurldecode' => ['string', 'str'=>'string'], +'rawurlencode' => ['string', 'str'=>'string'], +'read_exif_data' => ['array', 'filename'=>'string', 'sections_needed='=>'string', 'sub_arrays='=>'bool', 'read_thumbnail='=>'bool'], +'readdir' => ['string|false', 'dir_handle='=>'resource'], +'readfile' => ['int|false', 'filename'=>'string', 'use_include_path='=>'bool', 'context='=>'resource'], +'readgzfile' => ['int|false', 'filename'=>'string', 'use_include_path='=>'int'], +'readline' => ['string', 'prompt='=>'?string'], +'readline_add_history' => ['bool', 'prompt'=>'string'], +'readline_callback_handler_install' => ['bool', 'prompt'=>'string', 'callback'=>'callable'], +'readline_callback_handler_remove' => ['bool'], +'readline_callback_read_char' => ['void'], +'readline_clear_history' => ['bool'], +'readline_completion_function' => ['bool', 'funcname'=>'callable'], +'readline_info' => ['mixed', 'varname='=>'string', 'newvalue='=>'string'], +'readline_list_history' => ['array'], +'readline_on_new_line' => ['void'], +'readline_read_history' => ['bool', 'filename='=>'string'], +'readline_redisplay' => ['void'], +'readline_write_history' => ['bool', 'filename='=>'string'], +'readlink' => ['string', 'filename'=>'string'], +'realpath' => ['string|false', 'path'=>'string'], +'realpath_cache_get' => ['array'], +'realpath_cache_size' => ['int'], +'recode' => ['string', 'request'=>'string', 'str'=>'string'], +'recode_file' => ['bool', 'request'=>'string', 'input'=>'resource', 'output'=>'resource'], +'recode_string' => ['string', 'request'=>'string', 'str'=>'string'], +'rectObj::__construct' => ['void'], +'rectObj::draw' => ['int', 'map'=>'MapObj', 'layer'=>'layerObj', 'img'=>'imageObj', 'class_index'=>'int', 'text'=>'string'], +'rectObj::fit' => ['float', 'width'=>'int', 'height'=>'int'], +'rectObj::ms_newRectObj' => ['rectObj'], +'rectObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'], +'rectObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'rectObj::setextent' => ['void', 'minx'=>'float', 'miny'=>'float', 'maxx'=>'float', 'maxy'=>'float'], +'RecursiveArrayIterator::getChildren' => ['RecursiveArrayIterator'], +'RecursiveArrayIterator::hasChildren' => ['bool'], +'RecursiveCachingIterator::__construct' => ['void', 'it'=>'Iterator', 'flags'=>''], +'RecursiveCachingIterator::getChildren' => ['RecursiveCachingIterator'], +'RecursiveCachingIterator::hasChildren' => ['bool'], +'RecursiveCallbackFilterIterator::__construct' => ['void', 'it'=>'recursiveiterator', 'func'=>'callable'], +'RecursiveCallbackFilterIterator::getChildren' => ['RecursiveCallbackFilterIterator'], +'RecursiveCallbackFilterIterator::hasChildren' => ['void'], +'RecursiveDirectoryIterator::__construct' => ['void', 'path'=>'string', 'flags='=>'int'], +'RecursiveDirectoryIterator::getChildren' => ['object'], +'RecursiveDirectoryIterator::getSubPath' => ['string'], +'RecursiveDirectoryIterator::getSubPathname' => ['string'], +'RecursiveDirectoryIterator::hasChildren' => ['bool', 'allow_links='=>'bool'], +'RecursiveDirectoryIterator::key' => ['string'], +'RecursiveDirectoryIterator::next' => ['void'], +'RecursiveDirectoryIterator::rewind' => ['void'], +'RecursiveFilterIterator::__construct' => ['void', 'it'=>'recursiveiterator'], +'RecursiveFilterIterator::getChildren' => ['RecursiveFilterIterator'], +'RecursiveFilterIterator::hasChildren' => ['bool'], +'RecursiveIterator::getChildren' => ['RecursiveIterator'], +'RecursiveIterator::hasChildren' => ['bool'], +'RecursiveIteratorIterator::__construct' => ['void', 'it'=>'RecursiveIterator|IteratorAggregate', 'mode='=>'int', 'flags='=>'int'], +'RecursiveIteratorIterator::beginChildren' => ['void'], +'RecursiveIteratorIterator::beginIteration' => ['RecursiveIterator'], +'RecursiveIteratorIterator::callGetChildren' => ['RecursiveIterator'], +'RecursiveIteratorIterator::callHasChildren' => ['bool'], +'RecursiveIteratorIterator::current' => ['mixed'], +'RecursiveIteratorIterator::endChildren' => ['void'], +'RecursiveIteratorIterator::endIteration' => ['RecursiveIterator'], +'RecursiveIteratorIterator::getDepth' => ['int'], +'RecursiveIteratorIterator::getInnerIterator' => ['RecursiveIterator'], +'RecursiveIteratorIterator::getMaxDepth' => ['int|false'], +'RecursiveIteratorIterator::getSubIterator' => ['RecursiveIterator', 'level='=>'int'], +'RecursiveIteratorIterator::key' => ['mixed'], +'RecursiveIteratorIterator::next' => ['void'], +'RecursiveIteratorIterator::nextElement' => ['void'], +'RecursiveIteratorIterator::rewind' => ['void'], +'RecursiveIteratorIterator::setMaxDepth' => ['void', 'max_depth='=>'int'], +'RecursiveIteratorIterator::valid' => ['bool'], +'RecursiveRegexIterator::__construct' => ['void', 'it'=>'recursiveiterator', 'regex='=>'string', 'mode='=>'int', 'flags='=>'int', 'preg_flags='=>'int'], +'RecursiveRegexIterator::getChildren' => ['RecursiveRegexIterator'], +'RecursiveRegexIterator::hasChildren' => ['bool'], +'RecursiveTreeIterator::__construct' => ['void', 'it'=>'recursiveiterator|iteratoraggregate', 'flags'=>'int', 'cit_flags'=>'int', 'mode'=>'int'], +'RecursiveTreeIterator::beginChildren' => ['void'], +'RecursiveTreeIterator::beginIteration' => ['RecursiveIterator'], +'RecursiveTreeIterator::callGetChildren' => ['RecursiveIterator'], +'RecursiveTreeIterator::callHasChildren' => ['bool'], +'RecursiveTreeIterator::current' => ['string'], +'RecursiveTreeIterator::endChildren' => ['void'], +'RecursiveTreeIterator::endIteration' => ['void'], +'RecursiveTreeIterator::getEntry' => ['string'], +'RecursiveTreeIterator::getPostfix' => ['string'], +'RecursiveTreeIterator::getPrefix' => ['string'], +'RecursiveTreeIterator::key' => ['string'], +'RecursiveTreeIterator::next' => ['void'], +'RecursiveTreeIterator::nextElement' => ['void'], +'RecursiveTreeIterator::rewind' => ['void'], +'RecursiveTreeIterator::setPostfix' => ['void', 'prefix'=>'string'], +'RecursiveTreeIterator::setPrefixPart' => ['void', 'part'=>'int', 'prefix'=>'string'], +'RecursiveTreeIterator::valid' => ['bool'], +'Redis::__construct' => ['void'], +'Redis::_prefix' => ['string', 'value'=>'mixed'], +'Redis::_serialize' => ['mixed', 'value'=>'mixed'], +'Redis::_unserialize' => ['mixed', 'value'=>'string'], +'Redis::append' => ['int', 'key'=>'string', 'value'=>'string'], +'Redis::auth' => ['bool', 'password'=>'string'], +'Redis::bgRewriteAOF' => ['bool'], +'Redis::bgrewriteaof' => ['bool'], +'Redis::bgSave' => ['bool'], +'Redis::bitCount' => ['int', 'key'=>'string'], +'Redis::bitcount' => ['int', 'key'=>'string'], +'Redis::bitOp' => ['int', 'operation'=>'string', '...args'=>'string'], +'Redis::bitop' => ['int', 'operation'=>'string', '...args'=>'string'], +'Redis::bitpos' => ['int', 'key'=>'string', 'bit'=>'int', 'start='=>'int', 'end='=>'int'], +'Redis::blPop' => ['array', 'keys'=>'array', 'timeout'=>'int'], +'Redis::brPop' => ['array', 'keys'=>'array', 'timeout'=>'int'], +'Redis::brpoplpush' => ['string|false', 'srcKey'=>'string', 'dstKey'=>'string', 'timeout'=>'int'], +'Redis::clearLastError' => ['bool'], +'Redis::client' => ['mixed', 'command'=>'string', 'arg='=>'string'], +'Redis::close' => ['void'], +'Redis::config' => ['string', 'key'=>'string', 'value='=>'string'], +'Redis::connect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'retry_interval='=>'?int'], +'Redis::dbSize' => ['int'], +'Redis::decr' => ['int', 'key'=>'string'], +'Redis::decrBy' => ['int', 'key'=>'string', 'value'=>'int'], +'Redis::decrByFloat' => ['float', 'key'=>'string', 'value'=>'float'], +'Redis::del' => ['int', 'key'=>'string', '...args'=>'string'], +'Redis::del\'1' => ['int', 'key'=>'string[]'], +'Redis::delete' => ['int', 'key'=>'string', '...args'=>'string'], +'Redis::delete\'1' => ['int', 'key'=>'string[]'], +'Redis::discard' => [''], +'Redis::dump' => ['string|false', 'key'=>'string'], +'Redis::echo' => ['string', 'message'=>'string'], +'Redis::eval' => ['mixed', 'script'=>'', 'args='=>'', 'numKeys='=>''], +'Redis::evalSha' => ['mixed', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'], +'Redis::evalsha' => ['mixed', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'], +'Redis::evaluate' => ['mixed', 'script'=>'string', 'args='=>'array', 'numKeys='=>'int'], +'Redis::evaluateSha' => ['', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'], +'Redis::exec' => ['array'], +'Redis::exists' => ['bool', 'key'=>'string'], +'Redis::expire' => ['bool', 'key'=>'string', 'ttl'=>'int'], +'Redis::expireAt' => ['bool', 'key'=>'string', 'expiry'=>'int'], +'Redis::flushAll' => ['bool'], +'Redis::flushDb' => ['bool'], +'Redis::flushDB' => ['bool'], +'Redis::get' => ['string|false', 'key'=>'string'], +'Redis::getBit' => ['int', 'key'=>'string', 'offset'=>'int'], +'Redis::getKeys' => ['array', 'pattern'=>'string'], +'Redis::getLastError' => ['null|string'], +'Redis::getMode' => ['int'], +'Redis::getMultiple' => ['array', 'keys'=>'string[]'], +'Redis::getOption' => ['int', 'name'=>'int'], +'Redis::getRange' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'Redis::getSet' => ['string', 'key'=>'string', 'string'=>'string'], +'Redis::hDel' => ['int|false', 'key'=>'string', 'hashKey1'=>'string', 'hashKey2='=>'string', 'hashKeyN='=>'string'], +'Redis::hExists' => ['bool', 'key'=>'string', 'hashKey'=>'string'], +'Redis::hGet' => ['string|false', 'key'=>'string', 'hashKey'=>'string'], +'Redis::hGetAll' => ['array', 'key'=>'string'], +'Redis::hIncrBy' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'int'], +'Redis::hIncrByFloat' => ['float', 'key'=>'string', 'field'=>'string', 'increment'=>'float'], +'Redis::hKeys' => ['array', 'key'=>'string'], +'Redis::hLen' => ['int|false', 'key'=>'string'], +'Redis::hMGet' => ['array', 'key'=>'string', 'hashKeys'=>'array'], +'Redis::hMget' => ['array', 'key'=>'string', 'hashKeys'=>'array'], +'Redis::hMSet' => ['bool', 'key'=>'string', 'hashKeys'=>'array'], +'Redis::hMset' => ['bool', 'key'=>'string', 'hashKeys'=>'array'], +'Redis::hScan' => ['array', 'key'=>'string', 'iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'Redis::hscan' => ['array', 'key'=>'string', 'iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'Redis::hSet' => ['int|false', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'], +'Redis::hSetNx' => ['bool', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'], +'Redis::hVals' => ['array', 'key'=>'string'], +'Redis::incr' => ['int', 'key'=>'string'], +'Redis::incrBy' => ['int', 'key'=>'string', 'value'=>'int'], +'Redis::incrByFloat' => ['float', 'key'=>'string'], +'Redis::info' => ['array', 'option='=>'string'], +'Redis::keys' => ['array', 'pattern'=>'string'], +'Redis::lastSave' => ['int'], +'Redis::lGet' => ['', 'key'=>'string', 'index'=>'int'], +'Redis::lGetRange' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'Redis::lIndex' => ['string|false', 'key'=>'string', 'index'=>'int'], +'Redis::lindex' => ['string|false', 'key'=>'string', 'index'=>'int'], +'Redis::lInsert' => ['int', 'key'=>'string', 'position'=>'int', 'pivot'=>'string', 'value'=>'string'], +'Redis::listTrim' => ['', 'key'=>'string', 'start'=>'int', 'stop'=>'int'], +'Redis::lLen' => ['int|false', 'key'=>'string'], +'Redis::lPop' => ['string', 'key'=>'string'], +'Redis::lPush' => ['bool|int', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], +'Redis::lPushx' => ['int', 'key'=>'string', 'value'=>'string'], +'Redis::lRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'Redis::lrange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'Redis::lRem' => ['int|false', 'key'=>'string', 'value'=>'string', 'count'=>'int'], +'Redis::lrem' => ['int|false', 'key'=>'string', 'value'=>'string', 'count'=>'int'], +'Redis::lRemove' => ['', 'key'=>'string', 'value'=>'string', 'count'=>'int'], +'Redis::lSet' => ['bool', 'key'=>'string', 'index'=>'int', 'value'=>'string'], +'Redis::lSize' => ['', 'key'=>'string'], +'Redis::lTrim' => ['array|false', 'key'=>'string', 'start'=>'int', 'stop'=>'int'], +'Redis::ltrim' => ['array|false', 'key'=>'string', 'start'=>'int', 'stop'=>'int'], +'Redis::mGet' => ['array', 'keys'=>'string[]'], +'Redis::mget' => ['array', 'keys'=>'string[]'], +'Redis::migrate' => ['bool', 'host'=>'string', 'port'=>'int', 'db'=>'int', 'timeout'=>'int', 'copy='=>'bool', 'replace='=>'bool'], +'Redis::move' => ['bool', 'key'=>'string', 'dbindex'=>'int'], +'Redis::mSet' => ['bool', 'pairs'=>'array'], +'Redis::mset' => ['bool', 'pairs'=>'array'], +'Redis::mSetNx' => ['bool', 'pairs'=>'array'], +'Redis::msetnx' => ['bool', 'pairs'=>'array'], +'Redis::multi' => ['Redis', 'mode='=>'int'], +'Redis::object' => ['string|long|false', 'info'=>'string', 'key'=>'string'], +'Redis::open' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'retry_interval='=>'?int'], +'Redis::pconnect' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'string', 'retry_interval='=>'?int'], +'Redis::persist' => ['bool', 'key'=>'string'], +'Redis::pExpire' => ['bool', 'key'=>'string', 'ttl'=>'int'], +'Redis::pexpire' => ['bool', 'key'=>'string', 'ttl'=>'int'], +'Redis::pexpireAt' => ['bool', 'key'=>'string', 'expiry'=>'int'], +'Redis::pfAdd' => ['bool', 'key'=>'string', 'elements'=>'array'], +'Redis::pfadd' => ['bool', 'key'=>'string', 'elements'=>'array'], +'Redis::pfCount' => ['int', 'key'=>'array|string'], +'Redis::pfcount' => ['int', 'key'=>'array|string'], +'Redis::pfMerge' => ['bool', 'destkey'=>'string', 'sourcekeys'=>'array'], +'Redis::pfmerge' => ['bool', 'destkey'=>'string', 'sourcekeys'=>'array'], +'Redis::ping' => ['string'], +'Redis::popen' => ['bool', 'host'=>'string', 'port='=>'int', 'timeout='=>'float', 'persistent_id='=>'string', 'retry_interval='=>'?int'], +'Redis::psetex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], +'Redis::psubscribe' => ['', 'patterns'=>'array', 'callback'=>'array|string'], +'Redis::pttl' => ['int|false', 'key'=>'string'], +'Redis::publish' => ['int', 'channel'=>'string', 'message'=>'string'], +'Redis::pubsub' => ['array|int', 'keyword'=>'string', 'argument'=>'array|string'], +'Redis::randomKey' => ['string'], +'Redis::rawCommand' => ['mixed', 'command'=>'string', 'arguments'=>'mixed'], +'Redis::rawcommand' => ['mixed', 'command'=>'string', 'arguments'=>'mixed'], +'Redis::rename' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'], +'Redis::renameKey' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'], +'Redis::renameNx' => ['bool', 'srckey'=>'string', 'dstkey'=>'string'], +'Redis::resetStat' => ['bool'], +'Redis::restore' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], +'Redis::rPop' => ['string', 'key'=>'string'], +'Redis::rpoplpush' => ['string', 'srcKey'=>'string', 'dstKey'=>'string'], +'Redis::rPush' => ['bool|int', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], +'Redis::rPushx' => ['int', 'key'=>'string', 'value'=>'string'], +'Redis::sAdd' => ['int|false', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], +'Redis::sAddArray' => ['bool', 'key'=>'string', 'values'=>'array'], +'Redis::save' => ['bool'], +'Redis::scan' => ['array|false', '&rw_iterator'=>'?int', 'pattern='=>'?string', 'count='=>'?int'], +'Redis::sCard' => ['int', 'key'=>'string'], +'Redis::scard' => ['int', 'key'=>'string'], +'Redis::sContains' => ['', 'key'=>'string', 'value'=>'string'], +'Redis::script' => ['mixed', 'command'=>'string', 'script'=>'string'], +'Redis::sDiff' => ['array', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'Redis::sDiffStore' => ['int|false', 'dstKey'=>'string', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'Redis::select' => ['bool', 'dbindex'=>'int'], +'Redis::set' => ['bool', 'key'=>'string', 'value'=>'string', 'options='=>'array'], +'Redis::set\'1' => ['bool', 'key'=>'string', 'value'=>'string', 'timeout='=>'int'], +'Redis::setBit' => ['int', 'key'=>'string', 'offset'=>'int', 'value'=>'int'], +'Redis::setEx' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], +'Redis::setex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], +'Redis::setNx' => ['bool', 'key'=>'string', 'value'=>'string'], +'Redis::setnx' => ['bool', 'key'=>'string', 'value'=>'string'], +'Redis::setOption' => ['bool', 'name'=>'int', 'value'=>'string'], +'Redis::setRange' => ['int', 'key'=>'string', 'offset'=>'int', 'end'=>'int'], +'Redis::setTimeout' => ['', 'key'=>'string', 'ttl'=>'int'], +'Redis::sGetMembers' => ['', 'key'=>'string'], +'Redis::sInter' => ['array|false', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'Redis::sInterStore' => ['int|false', 'dstKey'=>'string', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'Redis::sIsMember' => ['bool', 'key'=>'string', 'value'=>'string'], +'Redis::sismember' => ['bool', 'key'=>'string', 'value'=>'string'], +'Redis::slave' => ['bool', 'host'=>'string', 'port'=>'int'], +'Redis::slave\'1' => ['bool', 'host'=>'string', 'port'=>'int'], +'Redis::slaveof' => ['bool', 'host='=>'string', 'port='=>'int'], +'Redis::slowLog' => ['mixed', 'operation'=>'string', 'length='=>'int'], +'Redis::slowlog' => ['mixed', 'operation'=>'string', 'length='=>'int'], +'Redis::sMembers' => ['array', 'key'=>'string'], +'Redis::sMove' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string', 'member'=>'string'], +'Redis::sort' => ['array|int', 'options='=>'?array'], +'Redis::sPop' => ['string|false', 'key'=>'string'], +'Redis::sRandMember' => ['array|string|false', 'key'=>'string', 'count='=>'int'], +'Redis::sRem' => ['int', 'key'=>'string', 'member1'=>'string', 'member2='=>'string', 'memberN='=>'string'], +'Redis::srem' => ['int', 'key'=>'string', 'member1'=>'string', 'member2='=>'string', 'memberN='=>'string'], +'Redis::sRemove' => ['', 'key'=>'string', 'member1'=>'string', 'member2='=>'string', 'memberN='=>'string'], +'Redis::sScan' => ['array|bool', 'key'=>'string', 'iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'Redis::sscan' => ['array|bool', 'key'=>'string', 'iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'Redis::strLen' => ['int', 'key'=>'string'], +'Redis::strlen' => ['int', 'key'=>'string'], +'Redis::subscribe' => ['', 'channels'=>'array', 'callback'=>'string'], +'Redis::substr' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'Redis::sUnion' => ['array', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'Redis::sUnionStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'Redis::time' => ['array'], +'Redis::ttl' => ['int|false', 'key'=>'string'], +'Redis::type' => ['int', 'key'=>'string'], +'Redis::unlink' => ['int', 'key'=>'string', '...args'=>'string'], +'Redis::unlink\'1' => ['int', 'key'=>'string[]'], +'Redis::unwatch' => [''], +'Redis::wait' => ['int', 'numSlaves'=>'int', 'timeout'=>'int'], +'Redis::watch' => ['void', 'key'=>'string'], +'Redis::zAdd' => ['int', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'], +'Redis::zCard' => ['int', 'key'=>'string'], +'Redis::zCount' => ['int', 'key'=>'string', 'start'=>'string', 'end'=>'string'], +'Redis::zDelete' => ['int', 'key'=>'string', 'member1'=>'string', 'member2='=>'string', 'memberN='=>'string'], +'Redis::zDeleteRangeByRank' => ['', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'Redis::zDeleteRangeByScore' => ['', 'key'=>'string', 'start'=>'float', 'end'=>'float'], +'Redis::zIncrBy' => ['float', 'key'=>'string', 'value'=>'float', 'member'=>'string'], +'Redis::zInter' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'], +'Redis::zRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscores='=>'bool'], +'Redis::zRangeByLex' => ['array|false', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'], +'Redis::zRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'], +'Redis::zRank' => ['int', 'key'=>'string', 'member'=>'string'], +'Redis::zRem' => ['int', 'key'=>'string', 'member1'=>'string', 'member2='=>'string', 'memberN='=>'string'], +'Redis::zRemRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'Redis::zRemRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'], +'Redis::zRevRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'], +'Redis::zRevRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'], +'Redis::zRevRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'], +'Redis::zRevRank' => ['int', 'key'=>'string', 'member'=>'string'], +'Redis::zScan' => ['array|bool', 'key'=>'string', 'iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'Redis::zscan' => ['array|bool', 'key'=>'string', 'iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'Redis::zScore' => ['float', 'key'=>'string', 'member'=>'string'], +'Redis::zSize' => ['', 'key'=>'string'], +'Redis::zUnion' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'], +'RedisArray::__construct' => ['void', 'name='=>'string', 'hosts='=>'?array', 'opts='=>'?array'], +'RedisArray::_function' => ['string'], +'RedisArray::_hosts' => ['array'], +'RedisArray::_rehash' => [''], +'RedisArray::_target' => ['string', 'key'=>'string'], +'RedisCluster::__construct' => ['void', 'name'=>'string', 'seeds'=>'array', 'timeout='=>'float', 'readTimeout='=>'float', 'persistent='=>'bool|false'], +'RedisCluster::_masters' => ['array'], +'RedisCluster::_prefix' => ['string', 'value'=>'mixed'], +'RedisCluster::_serialize' => ['mixed', 'value'=>'mixed'], +'RedisCluster::_unserialize' => ['mixed', 'value'=>'string'], +'RedisCluster::append' => ['int', 'key'=>'string', 'value'=>'string'], +'RedisCluster::bgrewriteaof' => ['bool', 'nodeParams'=>'string'], +'RedisCluster::bgsave' => ['bool', 'nodeParams'=>'string'], +'RedisCluster::bitCount' => ['int', 'key'=>'string'], +'RedisCluster::bitOp' => ['int', 'operation'=>'string', 'retKey'=>'string', 'key1'=>'string', 'key2'=>'string', 'key3='=>'string'], +'RedisCluster::bitpos' => ['int', 'key'=>'string', 'bit'=>'int', 'start='=>'int', 'end='=>'int'], +'RedisCluster::blPop' => ['array', 'keys'=>'array', 'timeout'=>'int'], +'RedisCluster::brPop' => ['array', 'keys'=>'array', 'timeout'=>'int'], +'RedisCluster::brpoplpush' => ['string', 'srcKey'=>'string', 'dstKey'=>'string', 'timeout'=>'int'], +'RedisCluster::clearLastError' => ['bool'], +'RedisCluster::client' => ['', 'nodeParams'=>'string', 'subCmd'=>'', 'args'=>''], +'RedisCluster::close' => [''], +'RedisCluster::cluster' => ['mixed', 'nodeParams'=>'string', 'command'=>'string', 'arguments'=>'mixed'], +'RedisCluster::command' => ['mixed'], +'RedisCluster::config' => ['array', 'nodeParams'=>'string', 'operation'=>'string', 'key'=>'string', 'value'=>'string'], +'RedisCluster::dbSize' => ['int', 'nodeParams'=>'string'], +'RedisCluster::decr' => ['int', 'key'=>'string'], +'RedisCluster::decrBy' => ['int', 'key'=>'string', 'value'=>'int'], +'RedisCluster::del' => ['int', 'key1'=>'int', 'key2='=>'string', 'key3='=>'string'], +'RedisCluster::discard' => [''], +'RedisCluster::dump' => ['string', 'key'=>'string'], +'RedisCluster::echo' => ['mixed', 'nodeParams'=>'string', 'msg'=>'string'], +'RedisCluster::eval' => ['mixed', 'script'=>'', 'args='=>'', 'numKeys='=>''], +'RedisCluster::evalSha' => ['mixed', 'scriptSha'=>'string', 'args='=>'array', 'numKeys='=>'int'], +'RedisCluster::exec' => ['array|void'], +'RedisCluster::exists' => ['bool', 'key'=>'string'], +'RedisCluster::expire' => ['bool', 'key'=>'string', 'ttl'=>'int'], +'RedisCluster::expireAt' => ['bool', 'key'=>'string', 'timestamp'=>'int'], +'RedisCluster::flushAll' => ['bool', 'nodeParams'=>'string'], +'RedisCluster::flushDB' => ['bool', 'nodeParams'=>'string'], +'RedisCluster::geoAdd' => ['', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'member'=>'string'], +'RedisCluster::geoDist' => ['', 'key'=>'string', 'member1'=>'string', 'member2'=>'string', 'unit='=>'string'], +'RedisCluster::geohash' => ['', 'key'=>'', 'member1'=>'', 'member2='=>'mixed', 'memberN='=>'mixed'], +'RedisCluster::geopos' => ['', 'key'=>'', 'member1'=>'', 'member2='=>'mixed', 'memberN='=>'mixed'], +'RedisCluster::geoRadius' => ['', 'key'=>'string', 'longitude'=>'float', 'latitude'=>'float', 'radius'=>'float', 'radiusUnit'=>'string', 'options'=>'array'], +'RedisCluster::geoRadiusByMember' => ['', 'key'=>'string', 'member'=>'string', 'radius'=>'float', 'radiusUnit'=>'string', 'options'=>'array'], +'RedisCluster::get' => ['bool|string', 'key'=>'string'], +'RedisCluster::getBit' => ['int', 'key'=>'string', 'offset'=>'int'], +'RedisCluster::getLastError' => ['string'], +'RedisCluster::getMode' => ['int'], +'RedisCluster::getOption' => ['int', 'name'=>'string'], +'RedisCluster::getRange' => ['string', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'RedisCluster::getSet' => ['string', 'key'=>'string', 'value'=>'string'], +'RedisCluster::hDel' => ['int', 'key'=>'string', 'hashKey1'=>'string', 'hashKey2='=>'string', 'hashKeyN='=>'string'], +'RedisCluster::hExists' => ['bool', 'key'=>'string', 'hashKey'=>'string'], +'RedisCluster::hGet' => ['string', 'key'=>'string', 'hashKey'=>'string'], +'RedisCluster::hGetAll' => ['array', 'key'=>'string'], +'RedisCluster::hIncrBy' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'int'], +'RedisCluster::hIncrByFloat' => ['float', 'key'=>'string', 'field'=>'string', 'increment'=>'float'], +'RedisCluster::hKeys' => ['array', 'key'=>'string'], +'RedisCluster::hLen' => ['int', 'key'=>'string'], +'RedisCluster::hMGet' => ['array', 'key'=>'string', 'hashKeys'=>'array'], +'RedisCluster::hMSet' => ['bool', 'key'=>'string', 'hashKeys'=>'array'], +'RedisCluster::hScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'RedisCluster::hSet' => ['int', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'], +'RedisCluster::hSetNx' => ['bool', 'key'=>'string', 'hashKey'=>'string', 'value'=>'string'], +'RedisCluster::hVals' => ['array', 'key'=>'string'], +'RedisCluster::incr' => ['int', 'key'=>'string'], +'RedisCluster::incrBy' => ['int', 'key'=>'string', 'value'=>'int'], +'RedisCluster::incrByFloat' => ['float', 'key'=>'string', 'increment'=>'float'], +'RedisCluster::info' => ['string', 'option='=>'string'], +'RedisCluster::keys' => ['array', 'pattern'=>'string'], +'RedisCluster::lastSave' => ['int', 'nodeParams'=>'string'], +'RedisCluster::lGet' => ['', 'key'=>'string', 'index'=>'int'], +'RedisCluster::lIndex' => ['string', 'key'=>'string', 'index'=>'int'], +'RedisCluster::lInsert' => ['int', 'key'=>'string', 'position'=>'int', 'pivot'=>'string', 'value'=>'string'], +'RedisCluster::lLen' => ['int', 'key'=>'string'], +'RedisCluster::lPop' => ['string', 'key'=>'string'], +'RedisCluster::lPush' => ['int', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], +'RedisCluster::lPushx' => ['int', 'key'=>'string', 'value'=>'string'], +'RedisCluster::lRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'RedisCluster::lRem' => ['int', 'key'=>'string', 'value'=>'string', 'count'=>'int'], +'RedisCluster::lSet' => ['bool', 'key'=>'string', 'index'=>'int', 'value'=>'string'], +'RedisCluster::lTrim' => ['array', 'key'=>'string', 'start'=>'int', 'stop'=>'int'], +'RedisCluster::mget' => ['array', 'array'=>'array'], +'RedisCluster::mset' => ['bool', 'array'=>'array'], +'RedisCluster::msetnx' => ['int', 'array'=>'array'], +'RedisCluster::multi' => ['Redis', 'mode='=>'int'], +'RedisCluster::object' => ['string', 'string='=>'string', 'key='=>'string'], +'RedisCluster::persist' => ['bool', 'key'=>'string'], +'RedisCluster::pExpire' => ['bool', 'key'=>'string', 'ttl'=>'int'], +'RedisCluster::pExpireAt' => ['bool', 'key'=>'string', 'timestamp'=>'int'], +'RedisCluster::pfAdd' => ['bool', 'key'=>'string', 'elements'=>'array'], +'RedisCluster::pfCount' => ['int', 'key'=>'string'], +'RedisCluster::pfMerge' => ['bool', 'destKey'=>'string', 'sourceKeys'=>'array'], +'RedisCluster::ping' => ['string', 'nodeParams'=>'string'], +'RedisCluster::psetex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], +'RedisCluster::psubscribe' => ['mixed', 'patterns'=>'array', 'callback'=>'string'], +'RedisCluster::pttl' => ['int', 'key'=>'string'], +'RedisCluster::publish' => ['int', 'channel'=>'string', 'message'=>'string'], +'RedisCluster::pubsub' => ['array', 'nodeParams'=>'string', 'keyword'=>'string', 'argument'=>'string'], +'RedisCluster::punSubscribe' => ['', 'channels'=>'', 'callback'=>''], +'RedisCluster::randomKey' => ['string', 'nodeParams'=>'string'], +'RedisCluster::rawCommand' => ['mixed', 'nodeParams'=>'string', 'command'=>'string', 'arguments'=>'mixed'], +'RedisCluster::rename' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string'], +'RedisCluster::renameNx' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string'], +'RedisCluster::restore' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], +'RedisCluster::role' => ['array', 'nodeParams'=>'string'], +'RedisCluster::rPop' => ['string', 'key'=>'string'], +'RedisCluster::rpoplpush' => ['string', 'srcKey'=>'string', 'dstKey'=>'string'], +'RedisCluster::rPush' => ['int', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], +'RedisCluster::rPushx' => ['int', 'key'=>'string', 'value'=>'string'], +'RedisCluster::sAdd' => ['int', 'key'=>'string', 'value1'=>'string', 'value2='=>'string', 'valueN='=>'string'], +'RedisCluster::sAddArray' => ['int', 'key'=>'string', 'valueArray'=>'array'], +'RedisCluster::save' => ['bool', 'nodeParams'=>'string'], +'RedisCluster::scan' => ['array', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'RedisCluster::sCard' => ['int', 'key'=>'string'], +'RedisCluster::script' => ['mixed', 'nodeParams'=>'string', 'command'=>'string', 'script'=>'string'], +'RedisCluster::sDiff' => ['array', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'RedisCluster::sDiffStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'RedisCluster::set' => ['bool', 'key'=>'string', 'value'=>'string', 'timeout='=>'array|int'], +'RedisCluster::setBit' => ['int', 'key'=>'string', 'offset'=>'int', 'value'=>'bool|int'], +'RedisCluster::setex' => ['bool', 'key'=>'string', 'ttl'=>'int', 'value'=>'string'], +'RedisCluster::setnx' => ['bool', 'key'=>'string', 'value'=>'string'], +'RedisCluster::setOption' => ['bool', 'name'=>'string', 'value'=>'string'], +'RedisCluster::setRange' => ['string', 'key'=>'string', 'offset'=>'int', 'value'=>'string'], +'RedisCluster::sInter' => ['array', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'RedisCluster::sInterStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'RedisCluster::sIsMember' => ['bool', 'key'=>'string', 'value'=>'string'], +'RedisCluster::slowLog' => ['', 'nodeParams'=>'string', 'command'=>'string', 'argument'=>'mixed'], +'RedisCluster::sMembers' => ['array', 'key'=>'string'], +'RedisCluster::sMove' => ['bool', 'srcKey'=>'string', 'dstKey'=>'string', 'member'=>'string'], +'RedisCluster::sort' => ['array', 'key'=>'string', 'option='=>'array'], +'RedisCluster::sPop' => ['string', 'key'=>'string'], +'RedisCluster::sRandMember' => ['array|string', 'key'=>'string', 'count='=>'int'], +'RedisCluster::sRem' => ['int', 'key'=>'string', 'member1'=>'string', 'member2='=>'string', 'memberN='=>'string'], +'RedisCluster::sScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'null', 'count='=>'int'], +'RedisCluster::strlen' => ['int', 'key'=>'string'], +'RedisCluster::subscribe' => ['mixed', 'channels'=>'array', 'callback'=>'string'], +'RedisCluster::sUnion' => ['array', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'RedisCluster::sUnionStore' => ['int', 'dstKey'=>'string', 'key1'=>'string', 'key2'=>'string', 'keyN='=>'string'], +'RedisCluster::time' => ['array', 'nodeParams'=>'string'], +'RedisCluster::ttl' => ['int', 'key'=>'string'], +'RedisCluster::type' => ['int', 'key'=>'string'], +'RedisCluster::unSubscribe' => ['', 'channels'=>'', 'callback'=>''], +'RedisCluster::unwatch' => [''], +'RedisCluster::watch' => ['void', 'key'=>'string'], +'RedisCluster::zAdd' => ['int', 'key'=>'string', 'score1'=>'float', 'value1'=>'string', 'score2='=>'float', 'value2='=>'string', 'scoreN='=>'float', 'valueN='=>'string'], +'RedisCluster::zCard' => ['int', 'key'=>'string'], +'RedisCluster::zCount' => ['int', 'key'=>'string', 'start'=>'string', 'end'=>'string'], +'RedisCluster::zIncrBy' => ['float', 'key'=>'string', 'value'=>'float', 'member'=>'string'], +'RedisCluster::zInterStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'], +'RedisCluster::zLexCount' => ['int', 'key'=>'string', 'min'=>'int', 'max'=>'int'], +'RedisCluster::zRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscores='=>'bool'], +'RedisCluster::zRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'], +'RedisCluster::zRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'], +'RedisCluster::zRank' => ['int', 'key'=>'string', 'member'=>'string'], +'RedisCluster::zRem' => ['int', 'key'=>'string', 'member1'=>'string', 'member2='=>'string', 'memberN='=>'string'], +'RedisCluster::zRemRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int'], +'RedisCluster::zRemRangeByRank' => ['int', 'key'=>'string', 'start'=>'int', 'end'=>'int'], +'RedisCluster::zRemRangeByScore' => ['int', 'key'=>'string', 'start'=>'float|string', 'end'=>'float|string'], +'RedisCluster::zRevRange' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'withscore='=>'bool'], +'RedisCluster::zRevRangeByLex' => ['array', 'key'=>'string', 'min'=>'int', 'max'=>'int', 'offset='=>'int', 'limit='=>'int'], +'RedisCluster::zRevRangeByScore' => ['array', 'key'=>'string', 'start'=>'int', 'end'=>'int', 'options='=>'array'], +'RedisCluster::zRevRank' => ['int', 'key'=>'string', 'member'=>'string'], +'RedisCluster::zScan' => ['array', 'key'=>'string', '&iterator'=>'int', 'pattern='=>'string', 'count='=>'int'], +'RedisCluster::zScore' => ['float', 'key'=>'string', 'member'=>'string'], +'RedisCluster::zUnionStore' => ['int', 'Output'=>'string', 'ZSetKeys'=>'array', 'Weights='=>'?array', 'aggregateFunction='=>'string'], +'Reflection::export' => ['string|null', 'r'=>'reflector', 'return='=>'bool'], +'Reflection::getModifierNames' => ['array', 'modifiers'=>'int'], +'ReflectionClass::__clone' => ['void'], +'ReflectionClass::__construct' => ['void', 'argument'=>''], +'ReflectionClass::__toString' => ['string'], +'ReflectionClass::export' => ['string|null', 'argument'=>'string|object', 'return='=>'bool'], +'ReflectionClass::getConstant' => ['mixed', 'name'=>'string'], +'ReflectionClass::getConstants' => ['array'], +'ReflectionClass::getConstructor' => ['ReflectionMethod|null'], +'ReflectionClass::getDefaultProperties' => ['array'], +'ReflectionClass::getDocComment' => ['string|false'], +'ReflectionClass::getEndLine' => ['int|false'], +'ReflectionClass::getExtension' => ['ReflectionExtension|null'], +'ReflectionClass::getExtensionName' => ['string|false'], +'ReflectionClass::getFileName' => ['string|false'], +'ReflectionClass::getInterfaceNames' => ['string[]'], +'ReflectionClass::getInterfaces' => ['array'], +'ReflectionClass::getMethod' => ['ReflectionMethod', 'name'=>'string'], +'ReflectionClass::getMethods' => ['ReflectionMethod[]', 'filter='=>'int'], +'ReflectionClass::getModifiers' => ['int'], +'ReflectionClass::getName' => ['string'], +'ReflectionClass::getNamespaceName' => ['string'], +'ReflectionClass::getParentClass' => ['ReflectionClass|false'], +'ReflectionClass::getProperties' => ['ReflectionProperty[]', 'filter='=>'int'], +'ReflectionClass::getProperty' => ['ReflectionProperty', 'name'=>'string'], +'ReflectionClass::getReflectionConstant' => ['ReflectionClassConstant|false', 'name'=>'string'], +'ReflectionClass::getReflectionConstants' => ['array'], +'ReflectionClass::getShortName' => ['string'], +'ReflectionClass::getStartLine' => ['int|false'], +'ReflectionClass::getStaticProperties' => ['ReflectionProperty[]'], +'ReflectionClass::getStaticPropertyValue' => ['mixed', 'name'=>'string', 'default='=>'mixed'], +'ReflectionClass::getTraitAliases' => ['array'], +'ReflectionClass::getTraitNames' => ['array'], +'ReflectionClass::getTraits' => ['array'], +'ReflectionClass::hasConstant' => ['bool', 'name'=>'string'], +'ReflectionClass::hasMethod' => ['bool', 'name'=>'string'], +'ReflectionClass::hasProperty' => ['bool', 'name'=>'string'], +'ReflectionClass::implementsInterface' => ['bool', 'interface_name'=>'string|reflectionclass'], +'ReflectionClass::inNamespace' => ['bool'], +'ReflectionClass::isAbstract' => ['bool'], +'ReflectionClass::isAnonymous' => ['bool'], +'ReflectionClass::isCloneable' => ['bool'], +'ReflectionClass::isFinal' => ['bool'], +'ReflectionClass::isInstance' => ['bool', 'object'=>'object'], +'ReflectionClass::isInstantiable' => ['bool'], +'ReflectionClass::isInterface' => ['bool'], +'ReflectionClass::isInternal' => ['bool'], +'ReflectionClass::isIterable' => ['bool'], +'ReflectionClass::isIterateable' => ['bool'], +'ReflectionClass::isSubclassOf' => ['bool', 'class'=>'string|reflectionclass'], +'ReflectionClass::isTrait' => ['bool'], +'ReflectionClass::isUserDefined' => ['bool'], +'ReflectionClass::newInstance' => ['object', 'args='=>'mixed', '...args='=>'mixed'], +'ReflectionClass::newInstanceArgs' => ['object', 'args='=>'array'], +'ReflectionClass::newInstanceWithoutConstructor' => ['object'], +'ReflectionClass::setStaticPropertyValue' => ['void', 'name'=>'string', 'value'=>'string'], +'ReflectionClassConstant::__construct' => ['void', 'class'=>'mixed', 'name'=>'string'], +'ReflectionClassConstant::__toString' => ['string'], +'ReflectionClassConstant::export' => ['string', 'class'=>'mixed', 'name'=>'string', 'return='=>'bool'], +'ReflectionClassConstant::getDeclaringClass' => ['ReflectionClass'], +'ReflectionClassConstant::getDocComment' => ['string|false'], +'ReflectionClassConstant::getModifiers' => ['int'], +'ReflectionClassConstant::getName' => ['string'], +'ReflectionClassConstant::getValue' => ['mixed'], +'ReflectionClassConstant::isPrivate' => ['bool'], +'ReflectionClassConstant::isProtected' => ['bool'], +'ReflectionClassConstant::isPublic' => ['bool'], +'ReflectionExtension::__clone' => ['void'], +'ReflectionExtension::__construct' => ['void', 'name'=>'string'], +'ReflectionExtension::__toString' => ['string'], +'ReflectionExtension::export' => ['string|null', 'name'=>'string', 'return='=>'bool'], +'ReflectionExtension::getClasses' => ['array'], +'ReflectionExtension::getClassNames' => ['array'], +'ReflectionExtension::getConstants' => ['array'], +'ReflectionExtension::getDependencies' => ['array'], +'ReflectionExtension::getFunctions' => ['array'], +'ReflectionExtension::getINIEntries' => ['array'], +'ReflectionExtension::getName' => ['string'], +'ReflectionExtension::getVersion' => ['string'], +'ReflectionExtension::info' => ['void'], +'ReflectionExtension::isPersistent' => ['void'], +'ReflectionExtension::isTemporary' => ['bool'], +'ReflectionFunction::__construct' => ['void', 'name'=>'string|Closure'], +'ReflectionFunction::__toString' => ['string'], +'ReflectionFunction::export' => ['string|null', 'name'=>'string', 'return='=>'bool'], +'ReflectionFunction::getClosure' => ['?Closure'], +'ReflectionFunction::getClosureScopeClass' => ['ReflectionClass'], +'ReflectionFunction::getClosureThis' => ['bool'], +'ReflectionFunction::getDocComment' => ['string|false'], +'ReflectionFunction::getEndLine' => ['int|false'], +'ReflectionFunction::getExtension' => ['ReflectionExtension|null'], +'ReflectionFunction::getExtensionName' => ['string|false'], +'ReflectionFunction::getFileName' => ['string|false'], +'ReflectionFunction::getName' => ['string'], +'ReflectionFunction::getNamespaceName' => ['string'], +'ReflectionFunction::getNumberOfParameters' => ['int'], +'ReflectionFunction::getNumberOfRequiredParameters' => ['int'], +'ReflectionFunction::getParameters' => ['array'], +'ReflectionFunction::getReturnType' => ['?ReflectionType'], +'ReflectionFunction::getShortName' => ['string'], +'ReflectionFunction::getStartLine' => ['int|false'], +'ReflectionFunction::getStaticVariables' => ['array'], +'ReflectionFunction::inNamespace' => ['bool'], +'ReflectionFunction::invoke' => ['mixed', '...args='=>'mixed'], +'ReflectionFunction::invokeArgs' => ['mixed', 'args'=>'array'], +'ReflectionFunction::isClosure' => ['bool'], +'ReflectionFunction::isDeprecated' => ['bool'], +'ReflectionFunction::isDisabled' => ['bool'], +'ReflectionFunction::isGenerator' => ['bool'], +'ReflectionFunction::isInternal' => ['bool'], +'ReflectionFunction::isUserDefined' => ['bool'], +'ReflectionFunction::isVariadic' => ['bool'], +'ReflectionFunction::returnsReference' => ['bool'], +'ReflectionFunctionAbstract::__clone' => ['void'], +'ReflectionFunctionAbstract::__toString' => ['string'], +'ReflectionFunctionAbstract::getClosureScopeClass' => ['ReflectionClass'], +'ReflectionFunctionAbstract::getClosureThis' => ['object'], +'ReflectionFunctionAbstract::getDocComment' => ['string|false'], +'ReflectionFunctionAbstract::getEndLine' => ['int|false'], +'ReflectionFunctionAbstract::getExtension' => ['ReflectionExtension'], +'ReflectionFunctionAbstract::getExtensionName' => ['string'], +'ReflectionFunctionAbstract::getFileName' => ['string|false'], +'ReflectionFunctionAbstract::getName' => ['string'], +'ReflectionFunctionAbstract::getNamespaceName' => ['string'], +'ReflectionFunctionAbstract::getNumberOfParameters' => ['int'], +'ReflectionFunctionAbstract::getNumberOfRequiredParameters' => ['int'], +'ReflectionFunctionAbstract::getParameters' => ['array'], +'ReflectionFunctionAbstract::getReturnType' => ['?ReflectionType'], +'ReflectionFunctionAbstract::getShortName' => ['string'], +'ReflectionFunctionAbstract::getStartLine' => ['int|false'], +'ReflectionFunctionAbstract::getStaticVariables' => ['array'], +'ReflectionFunctionAbstract::hasReturnType' => ['bool'], +'ReflectionFunctionAbstract::inNamespace' => ['bool'], +'ReflectionFunctionAbstract::isClosure' => ['bool'], +'ReflectionFunctionAbstract::isDeprecated' => ['bool'], +'ReflectionFunctionAbstract::isGenerator' => ['bool'], +'ReflectionFunctionAbstract::isInternal' => ['bool'], +'ReflectionFunctionAbstract::isUserDefined' => ['bool'], +'ReflectionFunctionAbstract::isVariadic' => ['bool'], +'ReflectionFunctionAbstract::returnsReference' => ['bool'], +'ReflectionGenerator::__construct' => ['void', 'generator'=>'object'], +'ReflectionGenerator::getExecutingFile' => ['string'], +'ReflectionGenerator::getExecutingGenerator' => ['Generator'], +'ReflectionGenerator::getExecutingLine' => ['int'], +'ReflectionGenerator::getFunction' => ['ReflectionFunctionAbstract'], +'ReflectionGenerator::getThis' => ['object'], +'ReflectionGenerator::getTrace' => ['array', 'options'=>'int'], +'ReflectionMethod::__construct' => ['void', 'class'=>'string|object', 'name'=>'string'], +'ReflectionMethod::__construct\'1' => ['void', 'class_method'=>'string'], +'ReflectionMethod::__toString' => ['string'], +'ReflectionMethod::export' => ['string|null', 'class'=>'string', 'name'=>'string', 'return='=>'bool'], +'ReflectionMethod::getClosure' => ['?Closure', 'object'=>'?object'], +'ReflectionMethod::getDeclaringClass' => ['ReflectionClass'], +'ReflectionMethod::getModifiers' => ['int'], +'ReflectionMethod::getPrototype' => ['ReflectionMethod'], +'ReflectionMethod::invoke' => ['mixed', 'object'=>'?object', '...args='=>'mixed'], +'ReflectionMethod::invokeArgs' => ['mixed', 'object'=>'?object', 'args'=>'array'], +'ReflectionMethod::isAbstract' => ['bool'], +'ReflectionMethod::isConstructor' => ['bool'], +'ReflectionMethod::isDestructor' => ['bool'], +'ReflectionMethod::isFinal' => ['bool'], +'ReflectionMethod::isPrivate' => ['bool'], +'ReflectionMethod::isProtected' => ['bool'], +'ReflectionMethod::isPublic' => ['bool'], +'ReflectionMethod::isStatic' => ['bool'], +'ReflectionMethod::setAccessible' => ['void', 'visible'=>'bool'], +'ReflectionNamedType::getName' => ['string'], +'ReflectionObject::__construct' => ['void', 'argument'=>'object'], +'ReflectionObject::export' => ['string|null', 'argument'=>'object', 'return='=>'bool'], +'ReflectionParameter::__clone' => ['void'], +'ReflectionParameter::__construct' => ['void', 'function'=>'', 'parameter'=>''], +'ReflectionParameter::__toString' => ['string'], +'ReflectionParameter::allowsNull' => ['bool'], +'ReflectionParameter::canBePassedByValue' => ['bool'], +'ReflectionParameter::export' => ['string|null', 'function'=>'string', 'parameter'=>'string', 'return='=>'bool'], +'ReflectionParameter::getClass' => ['ReflectionClass|null'], +'ReflectionParameter::getDeclaringClass' => ['ReflectionClass|null'], +'ReflectionParameter::getDeclaringFunction' => ['ReflectionFunctionAbstract'], +'ReflectionParameter::getDefaultValue' => ['mixed'], +'ReflectionParameter::getDefaultValueConstantName' => ['string'], +'ReflectionParameter::getName' => ['string'], +'ReflectionParameter::getPosition' => ['int'], +'ReflectionParameter::getType' => ['ReflectionType|null'], +'ReflectionParameter::hasType' => ['bool'], +'ReflectionParameter::isArray' => ['bool'], +'ReflectionParameter::isCallable' => ['bool'], +'ReflectionParameter::isDefaultValueAvailable' => ['bool'], +'ReflectionParameter::isDefaultValueConstant' => ['bool'], +'ReflectionParameter::isOptional' => ['bool'], +'ReflectionParameter::isPassedByReference' => ['bool'], +'ReflectionParameter::isVariadic' => ['bool'], +'ReflectionProperty::__clone' => ['void'], +'ReflectionProperty::__construct' => ['void', 'class'=>'', 'name'=>'string'], +'ReflectionProperty::__toString' => ['string'], +'ReflectionProperty::export' => ['string|null', 'class'=>'mixed', 'name'=>'string', 'return='=>'bool'], +'ReflectionProperty::getDeclaringClass' => ['ReflectionClass'], +'ReflectionProperty::getDocComment' => ['string|false'], +'ReflectionProperty::getModifiers' => ['int'], +'ReflectionProperty::getName' => ['string'], +'ReflectionProperty::getValue' => ['mixed', 'object='=>'object'], +'ReflectionProperty::isDefault' => ['bool'], +'ReflectionProperty::isPrivate' => ['bool'], +'ReflectionProperty::isProtected' => ['bool'], +'ReflectionProperty::isPublic' => ['bool'], +'ReflectionProperty::isStatic' => ['bool'], +'ReflectionProperty::setAccessible' => ['void', 'visible'=>'bool'], +'ReflectionProperty::setValue' => ['void', 'object'=>'object', 'value'=>''], +'ReflectionProperty::setValue\'1' => ['void', 'value'=>''], +'ReflectionType::__toString' => ['string'], +'ReflectionType::allowsNull' => ['bool'], +'ReflectionType::getName' => ['string'], +'ReflectionType::isBuiltin' => ['bool'], +'ReflectionZendExtension::__clone' => ['void'], +'ReflectionZendExtension::__construct' => ['void', 'name'=>'string'], +'ReflectionZendExtension::__toString' => ['string'], +'ReflectionZendExtension::export' => ['string|null', 'name'=>'string', 'return='=>'bool'], +'ReflectionZendExtension::getAuthor' => ['string'], +'ReflectionZendExtension::getCopyright' => ['string'], +'ReflectionZendExtension::getName' => ['string'], +'ReflectionZendExtension::getURL' => ['string'], +'ReflectionZendExtension::getVersion' => ['string'], +'Reflector::__toString' => ['string'], +'Reflector::export' => ['?string'], +'RegexIterator::__construct' => ['void', 'it'=>'iterator', 'regex'=>'string', 'mode='=>'int', 'flags='=>'int', 'preg_flags='=>'int'], +'RegexIterator::accept' => ['bool'], +'RegexIterator::getFlags' => ['int'], +'RegexIterator::getMode' => ['int'], +'RegexIterator::getPregFlags' => ['int'], +'RegexIterator::getRegex' => ['string'], +'RegexIterator::setFlags' => ['bool', 'new_flags'=>'int'], +'RegexIterator::setMode' => ['bool', 'new_mode'=>'int'], +'RegexIterator::setPregFlags' => ['bool', 'new_flags'=>'int'], +'register_event_handler' => ['bool', 'event_handler_func'=>'event_handler_func', 'handler_register_name'=>'handler_register_name', 'event_type_mask'=>'event_type_mask'], +'register_shutdown_function' => ['void', 'function'=>'callable', '...parameter='=>'mixed'], +'register_tick_function' => ['bool', 'function'=>'callable', '...args='=>'mixed'], +'rename' => ['bool', 'old_name'=>'string', 'new_name'=>'string', 'context='=>'resource'], +'rename_function' => ['bool', 'original_name'=>'string', 'new_name'=>'string'], +'reset' => ['mixed', '&rw_array_arg'=>'array|object'], +'ResourceBundle::__construct' => ['void', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'], +'ResourceBundle::count' => ['int'], +'ResourceBundle::create' => ['?ResourceBundle', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'], +'ResourceBundle::get' => ['', 'index'=>'string|int'], +'ResourceBundle::getErrorCode' => ['int'], +'ResourceBundle::getErrorMessage' => ['string'], +'ResourceBundle::getLocales' => ['array', 'bundlename'=>'string'], +'resourcebundle_count' => ['int', 'r'=>'resourcebundle'], +'resourcebundle_create' => ['?ResourceBundle', 'locale'=>'string', 'bundlename'=>'string', 'fallback='=>'bool'], +'resourcebundle_get' => ['', 'r'=>'resourcebundle', 'index'=>'string|int'], +'resourcebundle_get_error_code' => ['int', 'r'=>'resourcebundle'], +'resourcebundle_get_error_message' => ['string', 'r'=>'resourcebundle'], +'resourcebundle_locales' => ['array', 'bundlename'=>'string'], +'restore_error_handler' => ['bool'], +'restore_exception_handler' => ['bool'], +'restore_include_path' => ['void'], +'rewind' => ['bool', 'fp'=>'resource'], +'rewinddir' => ['void', 'dir_handle='=>'resource'], +'rmdir' => ['bool', 'dirname'=>'string', 'context='=>'resource'], +'round' => ['float', 'number'=>'float', 'precision='=>'int', 'mode='=>'int'], +'rpm_close' => ['bool', 'rpmr'=>'resource'], +'rpm_get_tag' => ['mixed', 'rpmr'=>'resource', 'tagnum'=>'int'], +'rpm_is_valid' => ['bool', 'filename'=>'string'], +'rpm_open' => ['resource', 'filename'=>'string'], +'rpm_version' => ['string'], +'rrd_create' => ['bool', 'filename'=>'string', 'options'=>'array'], +'rrd_error' => ['string'], +'rrd_fetch' => ['array', 'filename'=>'string', 'options'=>'array'], +'rrd_first' => ['int', 'file'=>'string', 'raaindex='=>'int'], +'rrd_graph' => ['array', 'filename'=>'string', 'options'=>'array'], +'rrd_info' => ['array', 'filename'=>'string'], +'rrd_last' => ['int', 'filename'=>'string'], +'rrd_lastupdate' => ['array', 'filename'=>'string'], +'rrd_restore' => ['bool', 'xml_file'=>'string', 'rrd_file'=>'string', 'options='=>'array'], +'rrd_tune' => ['bool', 'filename'=>'string', 'options'=>'array'], +'rrd_update' => ['bool', 'filename'=>'string', 'options'=>'array'], +'rrd_version' => ['string'], +'rrd_xport' => ['array', 'options'=>'array'], +'rrdc_disconnect' => ['void'], +'RRDCreator::__construct' => ['void', 'path'=>'string', 'starttime='=>'string', 'step='=>'int'], +'RRDCreator::addArchive' => ['void', 'description'=>'string'], +'RRDCreator::addDataSource' => ['void', 'description'=>'string'], +'RRDCreator::save' => ['bool'], +'RRDGraph::__construct' => ['void', 'path'=>'string'], +'RRDGraph::save' => ['array'], +'RRDGraph::saveVerbose' => ['array'], +'RRDGraph::setOptions' => ['void', 'options'=>'array'], +'RRDUpdater::__construct' => ['void', 'path'=>'string'], +'RRDUpdater::update' => ['bool', 'values'=>'array', 'time='=>'string'], +'rsort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], +'rtrim' => ['string', 'str'=>'string', 'character_mask='=>'string'], +'runkit_class_adopt' => ['bool', 'classname'=>'string', 'parentname'=>'string'], +'runkit_class_emancipate' => ['bool', 'classname'=>'string'], +'runkit_constant_add' => ['bool', 'constname'=>'string', 'value'=>'mixed'], +'runkit_constant_redefine' => ['bool', 'constname'=>'string', 'newvalue'=>'mixed'], +'runkit_constant_remove' => ['bool', 'constname'=>'string'], +'runkit_function_add' => ['bool', 'funcname'=>'string', 'arglist'=>'string', 'code'=>'string', 'doccomment='=>'?string'], +'runkit_function_add\'1' => ['bool', 'funcname'=>'string', 'closure'=>'Closure', 'doccomment='=>'?string'], +'runkit_function_copy' => ['bool', 'funcname'=>'string', 'targetname'=>'string'], +'runkit_function_redefine' => ['bool', 'funcname'=>'string', 'arglist'=>'string', 'code'=>'string', 'doccomment='=>'?string'], +'runkit_function_redefine\'1' => ['bool', 'funcname'=>'string', 'closure'=>'Closure', 'doccomment='=>'?string'], +'runkit_function_remove' => ['bool', 'funcname'=>'string'], +'runkit_function_rename' => ['bool', 'funcname'=>'string', 'newname'=>'string'], +'runkit_import' => ['bool', 'filename'=>'string', 'flags='=>'int'], +'runkit_lint' => ['bool', 'code'=>'string'], +'runkit_lint_file' => ['bool', 'filename'=>'string'], +'runkit_method_add' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int', 'doccomment='=>'?string'], +'runkit_method_add\'1' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'closure'=>'Closure', 'flags='=>'int', 'doccomment='=>'?string'], +'runkit_method_copy' => ['bool', 'dclass'=>'string', 'dmethod'=>'string', 'sclass'=>'string', 'smethod='=>'string'], +'runkit_method_redefine' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'args'=>'string', 'code'=>'string', 'flags='=>'int', 'doccomment='=>'?string'], +'runkit_method_redefine\'1' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'closure'=>'Closure', 'flags='=>'int', 'doccomment='=>'?string'], +'runkit_method_remove' => ['bool', 'classname'=>'string', 'methodname'=>'string'], +'runkit_method_rename' => ['bool', 'classname'=>'string', 'methodname'=>'string', 'newname'=>'string'], +'runkit_return_value_used' => ['bool'], +'Runkit_Sandbox::__construct' => ['void', 'options='=>'array'], +'runkit_sandbox_output_handler' => ['mixed', 'sandbox'=>'object', 'callback='=>'mixed'], +'Runkit_Sandbox_Parent' => [''], +'Runkit_Sandbox_Parent::__construct' => ['void'], +'runkit_superglobals' => ['array'], +'RuntimeException::__clone' => ['void'], +'RuntimeException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?RuntimeException'], +'RuntimeException::__toString' => ['string'], +'RuntimeException::getCode' => ['int'], +'RuntimeException::getFile' => ['string'], +'RuntimeException::getLine' => ['int'], +'RuntimeException::getMessage' => ['string'], +'RuntimeException::getPrevious' => ['Throwable|RuntimeException|null'], +'RuntimeException::getTrace' => ['array'], +'RuntimeException::getTraceAsString' => ['string'], +'SAMConnection::commit' => ['bool'], +'SAMConnection::connect' => ['bool', 'protocol'=>'string', 'properties='=>'array'], +'SAMConnection::disconnect' => ['bool'], +'SAMConnection::errno' => ['int'], +'SAMConnection::error' => ['string'], +'SAMConnection::isConnected' => ['bool'], +'SAMConnection::peek' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'], +'SAMConnection::peekAll' => ['array', 'target'=>'string', 'properties='=>'array'], +'SAMConnection::receive' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'], +'SAMConnection::remove' => ['SAMMessage', 'target'=>'string', 'properties='=>'array'], +'SAMConnection::rollback' => ['bool'], +'SAMConnection::send' => ['string', 'target'=>'string', 'msg'=>'sammessage', 'properties='=>'array'], +'SAMConnection::setDebug' => ['', 'switch'=>'bool'], +'SAMConnection::subscribe' => ['string', 'targettopic'=>'string'], +'SAMConnection::unsubscribe' => ['bool', 'subscriptionid'=>'string', 'targettopic='=>'string'], +'SAMMessage::body' => ['string'], +'SAMMessage::header' => ['object'], +'sapi_windows_cp_conv' => ['string', 'in_codepage'=>'int|string', 'out_codepage'=>'int|string', 'subject'=>'string'], +'sapi_windows_cp_get' => ['int'], +'sapi_windows_cp_is_utf8' => ['bool'], +'sapi_windows_cp_set' => ['bool', 'code_page'=>'int'], +'sapi_windows_vt100_support' => ['bool', 'stream'=>'resource', 'enable='=>'bool'], +'SCA::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'], +'SCA::getService' => ['', 'target'=>'string', 'binding='=>'string', 'config='=>'array'], +'SCA_LocalProxy::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'], +'SCA_SoapProxy::createDataObject' => ['SDO_DataObject', 'type_namespace_uri'=>'string', 'type_name'=>'string'], +'scalebarObj::convertToString' => ['string'], +'scalebarObj::free' => ['void'], +'scalebarObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'scalebarObj::setImageColor' => ['int', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], +'scalebarObj::updateFromString' => ['int', 'snippet'=>'string'], +'scandir' => ['array|false', 'dir'=>'string', 'sorting_order='=>'int', 'context='=>'resource'], +'SDO_DAS_ChangeSummary::beginLogging' => [''], +'SDO_DAS_ChangeSummary::endLogging' => [''], +'SDO_DAS_ChangeSummary::getChangedDataObjects' => ['SDO_List'], +'SDO_DAS_ChangeSummary::getChangeType' => ['int', 'dataobject'=>'sdo_dataobject'], +'SDO_DAS_ChangeSummary::getOldContainer' => ['SDO_DataObject', 'data_object'=>'sdo_dataobject'], +'SDO_DAS_ChangeSummary::getOldValues' => ['SDO_List', 'data_object'=>'sdo_dataobject'], +'SDO_DAS_ChangeSummary::isLogging' => ['bool'], +'SDO_DAS_DataFactory::addPropertyToType' => ['', 'parent_type_namespace_uri'=>'string', 'parent_type_name'=>'string', 'property_name'=>'string', 'type_namespace_uri'=>'string', 'type_name'=>'string', 'options='=>'array'], +'SDO_DAS_DataFactory::addType' => ['', 'type_namespace_uri'=>'string', 'type_name'=>'string', 'options='=>'array'], +'SDO_DAS_DataFactory::getDataFactory' => ['SDO_DAS_DataFactory'], +'SDO_DAS_DataObject::getChangeSummary' => ['SDO_DAS_ChangeSummary'], +'SDO_DAS_Relational::__construct' => ['void', 'database_metadata'=>'array', 'application_root_type='=>'string', 'sdo_containment_references_metadata='=>'array'], +'SDO_DAS_Relational::applyChanges' => ['', 'database_handle'=>'pdo', 'root_data_object'=>'sdodataobject'], +'SDO_DAS_Relational::createRootDataObject' => ['SDODataObject'], +'SDO_DAS_Relational::executePreparedQuery' => ['SDODataObject', 'database_handle'=>'pdo', 'prepared_statement'=>'pdostatement', 'value_list'=>'array', 'column_specifier='=>'array'], +'SDO_DAS_Relational::executeQuery' => ['SDODataObject', 'database_handle'=>'pdo', 'sql_statement'=>'string', 'column_specifier='=>'array'], +'SDO_DAS_Setting::getListIndex' => ['int'], +'SDO_DAS_Setting::getPropertyIndex' => ['int'], +'SDO_DAS_Setting::getPropertyName' => ['string'], +'SDO_DAS_Setting::getValue' => [''], +'SDO_DAS_Setting::isSet' => ['bool'], +'SDO_DAS_XML::addTypes' => ['', 'xsd_file'=>'string'], +'SDO_DAS_XML::create' => ['SDO_DAS_XML', 'xsd_file='=>'mixed', 'key='=>'string'], +'SDO_DAS_XML::createDataObject' => ['SDO_DataObject', 'namespace_uri'=>'string', 'type_name'=>'string'], +'SDO_DAS_XML::createDocument' => ['SDO_DAS_XML_Document', 'document_element_name'=>'string', 'document_element_namespace_uri'=>'string', 'dataobject='=>'sdo_dataobject'], +'SDO_DAS_XML::loadFile' => ['SDO_XMLDocument', 'xml_file'=>'string'], +'SDO_DAS_XML::loadString' => ['SDO_DAS_XML_Document', 'xml_string'=>'string'], +'SDO_DAS_XML::saveFile' => ['', 'xdoc'=>'sdo_xmldocument', 'xml_file'=>'string', 'indent='=>'int'], +'SDO_DAS_XML::saveString' => ['string', 'xdoc'=>'sdo_xmldocument', 'indent='=>'int'], +'SDO_DAS_XML_Document::getRootDataObject' => ['SDO_DataObject'], +'SDO_DAS_XML_Document::getRootElementName' => ['string'], +'SDO_DAS_XML_Document::getRootElementURI' => ['string'], +'SDO_DAS_XML_Document::setEncoding' => ['', 'encoding'=>'string'], +'SDO_DAS_XML_Document::setXMLDeclaration' => ['', 'xmldeclatation'=>'bool'], +'SDO_DAS_XML_Document::setXMLVersion' => ['', 'xmlversion'=>'string'], +'SDO_DataFactory::create' => ['void', 'type_namespace_uri'=>'string', 'type_name'=>'string'], +'SDO_DataObject::clear' => ['void'], +'SDO_DataObject::createDataObject' => ['SDO_DataObject', 'identifier'=>''], +'SDO_DataObject::getContainer' => ['SDO_DataObject'], +'SDO_DataObject::getSequence' => ['SDO_Sequence'], +'SDO_DataObject::getTypeName' => ['string'], +'SDO_DataObject::getTypeNamespaceURI' => ['string'], +'SDO_Exception::getCause' => [''], +'SDO_List::insert' => ['void', 'value'=>'mixed', 'index='=>'int'], +'SDO_Model_Property::getContainingType' => ['SDO_Model_Type'], +'SDO_Model_Property::getDefault' => [''], +'SDO_Model_Property::getName' => ['string'], +'SDO_Model_Property::getType' => ['SDO_Model_Type'], +'SDO_Model_Property::isContainment' => ['bool'], +'SDO_Model_Property::isMany' => ['bool'], +'SDO_Model_ReflectionDataObject::__construct' => ['void', 'data_object'=>'sdo_dataobject'], +'SDO_Model_ReflectionDataObject::export' => ['mixed', 'rdo'=>'sdo_model_reflectiondataobject', 'return='=>'bool'], +'SDO_Model_ReflectionDataObject::getContainmentProperty' => ['SDO_Model_Property'], +'SDO_Model_ReflectionDataObject::getInstanceProperties' => ['array'], +'SDO_Model_ReflectionDataObject::getType' => ['SDO_Model_Type'], +'SDO_Model_Type::getBaseType' => ['SDO_Model_Type'], +'SDO_Model_Type::getName' => ['string'], +'SDO_Model_Type::getNamespaceURI' => ['string'], +'SDO_Model_Type::getProperties' => ['array'], +'SDO_Model_Type::getProperty' => ['SDO_Model_Property', 'identifier'=>''], +'SDO_Model_Type::isAbstractType' => ['bool'], +'SDO_Model_Type::isDataType' => ['bool'], +'SDO_Model_Type::isInstance' => ['bool', 'data_object'=>'sdo_dataobject'], +'SDO_Model_Type::isOpenType' => ['bool'], +'SDO_Model_Type::isSequencedType' => ['bool'], +'SDO_Sequence::getProperty' => ['SDO_Model_Property', 'sequence_index'=>'int'], +'SDO_Sequence::insert' => ['void', 'value'=>'mixed', 'sequenceindex='=>'int', 'propertyidentifier='=>'mixed'], +'SDO_Sequence::move' => ['void', 'toindex'=>'int', 'fromindex'=>'int'], +'SeekableIterator::seek' => ['void', 'position'=>'int'], +'sem_acquire' => ['bool', 'sem_identifier'=>'resource', 'nowait='=>'bool'], +'sem_get' => ['resource', 'key'=>'int', 'max_acquire='=>'int', 'perm='=>'int', 'auto_release='=>'int'], +'sem_release' => ['bool', 'sem_identifier'=>'resource'], +'sem_remove' => ['bool', 'sem_identifier'=>'resource'], +'Serializable::serialize' => ['string'], +'Serializable::unserialize' => ['void', 'serialized'=>'string'], +'serialize' => ['string', 'variable'=>'mixed'], +'ServerRequest::withInput' => ['ServerRequest', 'input'=>'mixed'], +'ServerRequest::withoutParams' => ['ServerRequest', 'params'=>'int|string'], +'ServerRequest::withParam' => ['ServerRequest', 'key'=>'int|string', 'val'=>'mixed'], +'ServerRequest::withParams' => ['ServerRequest', 'params'=>'mixed'], +'ServerRequest::withUrl' => ['ServerRequest', 'url'=>'array'], +'ServerResponse::addHeader' => ['void', 'label'=>'string', 'value'=>'string'], +'ServerResponse::date' => ['string', 'date'=>'string|DateTimeInterface'], +'ServerResponse::getHeader' => ['string', 'label'=>'string'], +'ServerResponse::getHeaders' => ['string[]'], +'ServerResponse::getStatus' => ['int'], +'ServerResponse::getVersion' => ['string'], +'ServerResponse::setHeader' => ['void', 'label'=>'string', 'value'=>'string'], +'ServerResponse::setStatus' => ['void', 'status'=>'int'], +'ServerResponse::setVersion' => ['void', 'version'=>'string'], +'session_abort' => ['bool'], +'session_cache_expire' => ['int', 'new_cache_expire='=>'int'], +'session_cache_limiter' => ['string', 'new_cache_limiter='=>'string'], +'session_commit' => ['bool'], +'session_create_id' => ['string', 'prefix='=>'string'], +'session_decode' => ['bool', 'data'=>'string'], +'session_destroy' => ['bool'], +'session_encode' => ['string'], +'session_gc' => ['int'], +'session_get_cookie_params' => ['array'], +'session_id' => ['string', 'newid='=>'string'], +'session_is_registered' => ['bool', 'name'=>'string'], +'session_module_name' => ['string', 'newname='=>'string'], +'session_name' => ['string', 'newname='=>'string'], +'session_pgsql_add_error' => ['bool', 'error_level'=>'int', 'error_message='=>'string'], +'session_pgsql_get_error' => ['array', 'with_error_message='=>'bool'], +'session_pgsql_get_field' => ['string'], +'session_pgsql_reset' => ['bool'], +'session_pgsql_set_field' => ['bool', 'value'=>'string'], +'session_pgsql_status' => ['array'], +'session_regenerate_id' => ['bool', 'delete_old_session='=>'bool'], +'session_register' => ['bool', 'name'=>'mixed', '...args='=>'mixed'], +'session_register_shutdown' => ['void'], +'session_reset' => ['bool'], +'session_save_path' => ['string', 'newname='=>'string'], +'session_set_cookie_params' => ['bool', 'lifetime'=>'int', 'path='=>'string', 'domain='=>'?string', 'secure='=>'bool', 'httponly='=>'bool'], +'session_set_save_handler' => ['bool', 'open'=>'callable', 'close'=>'callable', 'read'=>'callable', 'write'=>'callable', 'destroy'=>'callable', 'gc'=>'callable', 'create_sid='=>'callable', 'validate_sid='=>'callable', 'update_timestamp='=>'callable'], +'session_set_save_handler\'1' => ['bool', 'sessionhandler'=>'SessionHandlerInterface', 'register_shutdown='=>'bool'], +'session_start' => ['bool', 'options='=>'array'], +'session_status' => ['int'], +'session_unregister' => ['bool', 'name'=>'string'], +'session_unset' => ['bool'], +'session_write_close' => ['bool'], +'SessionHandler::close' => ['bool'], +'SessionHandler::create_sid' => ['char'], +'SessionHandler::destroy' => ['bool', 'id'=>'string'], +'SessionHandler::gc' => ['bool', 'maxlifetime'=>'int'], +'SessionHandler::open' => ['bool', 'save_path'=>'string', 'session_name'=>'string'], +'SessionHandler::read' => ['string', 'id'=>'string'], +'SessionHandler::updateTimestamp' => ['bool', 'session_id'=>'string', 'session_data'=>'string'], +'SessionHandler::validateId' => ['bool', 'session_id'=>'string'], +'SessionHandler::write' => ['bool', 'id'=>'string', 'data'=>'string'], +'SessionHandlerInterface::close' => ['bool'], +'SessionHandlerInterface::destroy' => ['bool', 'session_id'=>'string'], +'SessionHandlerInterface::gc' => ['bool', 'maxlifetime'=>'int'], +'SessionHandlerInterface::open' => ['bool', 'save_path'=>'string', 'name'=>'string'], +'SessionHandlerInterface::read' => ['string', 'session_id'=>'string'], +'SessionHandlerInterface::write' => ['bool', 'session_id'=>'string', 'session_data'=>'string'], +'SessionIdInterface::create_sid' => ['string'], +'SessionUpdateTimestampHandler::updateTimestamp' => ['bool', 'id'=>'string', 'data'=>'string'], +'SessionUpdateTimestampHandler::validateId' => ['char', 'id'=>'string'], +'SessionUpdateTimestampHandlerInterface::updateTimestamp' => ['bool', 'key'=>'string', 'val'=>'string'], +'SessionUpdateTimestampHandlerInterface::validateId' => ['bool', 'key'=>'string'], +'set_error_handler' => ['?callable', 'error_handler'=>'callable', 'error_types='=>'int'], +'set_exception_handler' => ['?callable', 'exception_handler'=>'callable'], +'set_file_buffer' => ['int', 'fp'=>'resource', 'buffer'=>'int'], +'set_include_path' => ['string', 'new_include_path'=>'string'], +'set_magic_quotes_runtime' => ['bool', 'new_setting'=>'bool'], +'set_time_limit' => ['bool', 'seconds'=>'int'], +'setcookie' => ['bool', 'name'=>'string', 'value='=>'string', 'expires='=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool'], +'setLeftFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'setLine' => ['void', 'width'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'setlocale' => ['string|false', 'category'=>'int', 'locale'=>'string', '...args='=>'string'], +'setlocale\'1' => ['string|false', 'category'=>'int', 'locale'=>'?array'], +'setproctitle' => ['void', 'title'=>'string'], +'setrawcookie' => ['bool', 'name'=>'string', 'value='=>'string', 'expires='=>'int', 'path='=>'string', 'domain='=>'string', 'secure='=>'bool', 'httponly='=>'bool'], +'setRightFill' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'setthreadtitle' => ['bool', 'title'=>'string'], +'settype' => ['bool', '&rw_var'=>'mixed', 'type'=>'string'], +'sha1' => ['string', 'str'=>'string', 'raw_output='=>'bool'], +'sha1_file' => ['string|false', 'filename'=>'string', 'raw_output='=>'bool'], +'sha256' => ['string', 'str'=>'string', 'raw_output='=>'bool'], +'sha256_file' => ['string', 'filename'=>'string', 'raw_output='=>'bool'], +'shapefileObj::__construct' => ['void', 'filename'=>'string', 'type'=>'int'], +'shapefileObj::addPoint' => ['int', 'point'=>'pointObj'], +'shapefileObj::addShape' => ['int', 'shape'=>'shapeObj'], +'shapefileObj::free' => ['void'], +'shapefileObj::getExtent' => ['rectObj', 'i'=>'int'], +'shapefileObj::getPoint' => ['shapeObj', 'i'=>'int'], +'shapefileObj::getShape' => ['shapeObj', 'i'=>'int'], +'shapefileObj::getTransformed' => ['shapeObj', 'map'=>'MapObj', 'i'=>'int'], +'shapefileObj::ms_newShapefileObj' => ['shapefileObj', 'filename'=>'string', 'type'=>'int'], +'shapeObj::__construct' => ['void', 'type'=>'int'], +'shapeObj::add' => ['int', 'line'=>'lineObj'], +'shapeObj::boundary' => ['shapeObj'], +'shapeObj::contains' => ['bool', 'point'=>'pointObj'], +'shapeObj::containsShape' => ['int', 'shape2'=>'shapeObj'], +'shapeObj::convexhull' => ['shapeObj'], +'shapeObj::crosses' => ['int', 'shape'=>'shapeObj'], +'shapeObj::difference' => ['shapeObj', 'shape'=>'shapeObj'], +'shapeObj::disjoint' => ['int', 'shape'=>'shapeObj'], +'shapeObj::draw' => ['int', 'map'=>'MapObj', 'layer'=>'layerObj', 'img'=>'imageObj'], +'shapeObj::equals' => ['int', 'shape'=>'shapeObj'], +'shapeObj::free' => ['void'], +'shapeObj::getArea' => ['float'], +'shapeObj::getCentroid' => ['pointObj'], +'shapeObj::getLabelPoint' => ['pointObj'], +'shapeObj::getLength' => ['float'], +'shapeObj::getPointUsingMeasure' => ['pointObj', 'm'=>'float'], +'shapeObj::getValue' => ['string', 'layer'=>'layerObj', 'filedname'=>'string'], +'shapeObj::intersection' => ['shapeObj', 'shape'=>'shapeObj'], +'shapeObj::intersects' => ['bool', 'shape'=>'shapeObj'], +'shapeObj::line' => ['lineObj', 'i'=>'int'], +'shapeObj::ms_shapeObjFromWkt' => ['shapeObj', 'wkt'=>'string'], +'shapeObj::overlaps' => ['int', 'shape'=>'shapeObj'], +'shapeObj::project' => ['int', 'in'=>'projectionObj', 'out'=>'projectionObj'], +'shapeObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'shapeObj::setBounds' => ['int'], +'shapeObj::simplify' => ['shapeObj', 'tolerance'=>'float'], +'shapeObj::symdifference' => ['shapeObj', 'shape'=>'shapeObj'], +'shapeObj::topologyPreservingSimplify' => ['shapeObj', 'tolerance'=>'float'], +'shapeObj::touches' => ['int', 'shape'=>'shapeObj'], +'shapeObj::toWkt' => ['string'], +'shapeObj::union' => ['shapeObj', 'shape'=>'shapeObj'], +'shapeObj::within' => ['int', 'shape2'=>'shapeObj'], +'shell_exec' => ['?string', 'cmd'=>'string'], +'shm_attach' => ['resource', 'key'=>'int', 'memsize='=>'int', 'perm='=>'int'], +'shm_detach' => ['bool', 'shm_identifier'=>'resource'], +'shm_get_var' => ['mixed', 'id'=>'resource', 'variable_key'=>'int'], +'shm_has_var' => ['bool', 'shm_identifier'=>'resource', 'variable_key'=>'int'], +'shm_put_var' => ['bool', 'shm_identifier'=>'resource', 'variable_key'=>'int', 'variable'=>'mixed'], +'shm_remove' => ['bool', 'shm_identifier'=>'resource'], +'shm_remove_var' => ['bool', 'shm_identifier'=>'resource', 'variable_key'=>'int'], +'shmop_close' => ['void', 'shmid'=>'resource'], +'shmop_delete' => ['bool', 'shmid'=>'resource'], +'shmop_open' => ['resource|false', 'key'=>'int', 'flags'=>'string', 'mode'=>'int', 'size'=>'int'], +'shmop_read' => ['string', 'shmid'=>'resource', 'start'=>'int', 'count'=>'int'], +'shmop_size' => ['int', 'shmid'=>'resource'], +'shmop_write' => ['int', 'shmid'=>'resource', 'data'=>'string', 'offset'=>'int'], +'show_source' => ['', 'file_name'=>'', 'return'=>''], +'shuffle' => ['bool', '&rw_array_arg'=>'array'], +'signeurlpaiement' => ['string', 'clent'=>'string', 'data'=>'string'], +'similar_text' => ['int', 'str1'=>'string', 'str2'=>'string', '&w_percent='=>'float'], +'simplexml_import_dom' => ['SimpleXMLElement|false', 'node'=>'DOMNode', 'class_name='=>'string'], +'simplexml_load_file' => ['SimpleXMLElement|false', 'filename'=>'string', 'class_name='=>'string', 'options='=>'int', 'ns='=>'string', 'is_prefix='=>'bool'], +'simplexml_load_string' => ['SimpleXMLElement|false', 'data'=>'string', 'class_name='=>'string', 'options='=>'int', 'ns='=>'string', 'is_prefix='=>'bool'], +'SimpleXMLElement::__construct' => ['void', 'data'=>'string', 'options='=>'int', 'data_is_url='=>'bool', 'ns='=>'string', 'is_prefix='=>'bool'], +'SimpleXMLElement::__toString' => ['string'], +'SimpleXMLElement::__get' => ['SimpleXMLElement', 'name'=>'string'], +'SimpleXMLElement::addAttribute' => ['void', 'name'=>'string', 'value='=>'string', 'ns='=>'string'], +'SimpleXMLElement::addChild' => ['SimpleXMLElement', 'name'=>'string', 'value='=>'string', 'ns='=>'string'], +'SimpleXMLElement::asXML' => ['string|bool', 'filename='=>'string'], +'SimpleXMLElement::attributes' => ['SimpleXMLElement|null', 'ns='=>'string', 'is_prefix='=>'bool'], +'SimpleXMLElement::children' => ['SimpleXMLElement', 'ns='=>'string', 'is_prefix='=>'bool'], +'SimpleXMLElement::count' => ['int'], +'SimpleXMLElement::getDocNamespaces' => ['string[]', 'recursive='=>'bool', 'from_root='=>'bool'], +'SimpleXMLElement::getName' => ['string'], +'SimpleXMLElement::getNamespaces' => ['string[]', 'recursive='=>'bool'], +'SimpleXMLElement::registerXPathNamespace' => ['bool', 'prefix'=>'string', 'ns'=>'string'], +'SimpleXMLElement::xpath' => ['SimpleXMLElement[]|false', 'path'=>'string'], +'SimpleXMLIterator::current' => ['SimpleXMLIterator|null'], +'SimpleXMLIterator::getChildren' => ['SimpleXMLIterator'], +'SimpleXMLIterator::hasChildren' => ['bool'], +'SimpleXMLIterator::key' => ['string|false'], +'SimpleXMLIterator::next' => ['void'], +'SimpleXMLIterator::rewind' => ['void'], +'SimpleXMLIterator::valid' => ['bool'], +'sin' => ['float', 'number'=>'float'], +'sinh' => ['float', 'number'=>'float'], +'sizeof' => ['int', 'var'=>'Countable|array', 'mode='=>'int'], +'sleep' => ['int|false', 'seconds'=>'int'], +'snmp2_get' => ['string|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp2_getnext' => ['string|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp2_real_walk' => ['array|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp2_set' => ['bool', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp2_walk' => ['array|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp3_get' => ['string|false', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp3_getnext' => ['string|false', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp3_real_walk' => ['array|false', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp3_set' => ['bool', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmp3_walk' => ['array|false', 'host'=>'string', 'sec_name'=>'string', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'SNMP::__construct' => ['void', 'version'=>'int', 'hostname'=>'string', 'community'=>'string', 'timeout'=>'int', 'retries'=>'int'], +'SNMP::close' => ['bool'], +'SNMP::get' => ['mixed', 'object_id'=>'mixed', 'preserve_keys'=>'bool'], +'SNMP::getErrno' => ['int'], +'SNMP::getError' => ['int'], +'SNMP::getnext' => ['mixed', 'object_id'=>'mixed'], +'SNMP::set' => ['bool', 'object_id'=>'mixed', 'type'=>'mixed', 'value'=>'mixed'], +'SNMP::setSecurity' => ['bool', 'sec_level'=>'string', 'auth_protocol'=>'string', 'auth_passphrase'=>'string', 'priv_protocol'=>'string', 'priv_passphrase'=>'string', 'contextname'=>'string', 'contextengineid'=>'string'], +'SNMP::walk' => ['array', 'object_id'=>'string', 'suffix_as_key'=>'bool', 'max_repetitions'=>'int', 'non_repeaters'=>'int'], +'snmp_get_quick_print' => ['bool'], +'snmp_get_valueretrieval' => ['int'], +'snmp_read_mib' => ['bool', 'filename'=>'string'], +'snmp_set_enum_print' => ['bool', 'enum_print'=>'int'], +'snmp_set_oid_numeric_print' => ['void', 'oid_format'=>'int'], +'snmp_set_oid_output_format' => ['bool', 'oid_format'=>'int'], +'snmp_set_quick_print' => ['bool', 'quick_print'=>'int'], +'snmp_set_valueretrieval' => ['bool', 'method'=>'int'], +'snmpget' => ['string|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmpgetnext' => ['string|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmprealwalk' => ['array|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmpset' => ['bool', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'type'=>'string', 'value'=>'mixed', 'timeout='=>'int', 'retries='=>'int'], +'snmpwalk' => ['array|false', 'host'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'snmpwalkoid' => ['array|false', 'hostname'=>'string', 'community'=>'string', 'object_id'=>'string', 'timeout='=>'int', 'retries='=>'int'], +'SoapClient::__call' => ['', 'function_name'=>'string', 'arguments'=>'string'], +'SoapClient::__construct' => ['void', 'wsdl'=>'mixed', 'options='=>'array'], +'SoapClient::__doRequest' => ['string', 'request'=>'string', 'location'=>'string', 'action'=>'string', 'version'=>'int', 'one_way='=>'int'], +'SoapClient::__getCookies' => ['array'], +'SoapClient::__getFunctions' => ['array'], +'SoapClient::__getLastRequest' => ['string'], +'SoapClient::__getLastRequestHeaders' => ['string'], +'SoapClient::__getLastResponse' => ['string'], +'SoapClient::__getLastResponseHeaders' => ['string'], +'SoapClient::__getTypes' => ['array'], +'SoapClient::__setCookie' => ['', 'name'=>'string', 'value='=>'string'], +'SoapClient::__setLocation' => ['string', 'new_location='=>'string'], +'SoapClient::__setSoapHeaders' => ['bool', 'soapheaders='=>''], +'SoapClient::__soapCall' => ['', 'function_name'=>'string', 'arguments'=>'array', 'options='=>'array', 'input_headers='=>'', '&w_output_headers='=>'array'], +'SoapClient::SoapClient' => ['object', 'wsdl'=>'mixed', 'options='=>'array'], +'SoapFault::__construct' => ['void', 'faultcode'=>'string', 'faultstring'=>'string', 'faultactor='=>'string', 'detail='=>'string', 'faultname='=>'string', 'headerfault='=>'string'], +'SoapFault::__toString' => ['string'], +'SoapFault::SoapFault' => ['object', 'faultcode'=>'string', 'faultstring'=>'string', 'faultactor='=>'string', 'detail='=>'string', 'faultname='=>'string', 'headerfault='=>'string'], +'SoapHeader::__construct' => ['void', 'namespace'=>'string', 'name'=>'string', 'data='=>'mixed', 'mustunderstand='=>'bool', 'actor='=>'string'], +'SoapHeader::SoapHeader' => ['object', 'namespace'=>'string', 'name'=>'string', 'data='=>'mixed', 'mustunderstand='=>'bool', 'actor='=>'string'], +'SoapParam::__construct' => ['void', 'data'=>'mixed', 'name'=>'string'], +'SoapParam::SoapParam' => ['object', 'data'=>'mixed', 'name'=>'string'], +'SoapServer::__construct' => ['void', 'wsdl'=>'?string', 'options='=>'array'], +'SoapServer::addFunction' => ['void', 'functions'=>'mixed'], +'SoapServer::addSoapHeader' => ['void', 'object'=>'soapheader'], +'SoapServer::fault' => ['void', 'code'=>'string', 'string'=>'string', 'actor='=>'string', 'details='=>'string', 'name='=>'string'], +'SoapServer::getFunctions' => ['array'], +'SoapServer::handle' => ['void', 'soap_request='=>'string'], +'SoapServer::setClass' => ['void', 'class_name'=>'string', '...args='=>'mixed'], +'SoapServer::setObject' => ['void', 'obj'=>'object'], +'SoapServer::setPersistence' => ['void', 'mode'=>'int'], +'SoapServer::SoapServer' => ['object', 'wsdl'=>'?string', 'options'=>'array'], +'SoapVar::__construct' => ['void', 'data'=>'mixed', 'encoding'=>'int', 'type_name='=>'string', 'type_namespace='=>'string', 'node_name='=>'string', 'node_namespace='=>'string'], +'SoapVar::SoapVar' => ['object', 'data'=>'mixed', 'encoding'=>'int', 'type_name='=>'string', 'type_namespace='=>'string', 'node_name='=>'string', 'node_namespace='=>'string'], +'socket_accept' => ['resource|false', 'socket'=>'resource'], +'socket_addrinfo_bind' => ['resource|null', 'addrinfo'=>'resource'], +'socket_addrinfo_connect' => ['resource|null', 'addrinfo'=>'resource'], +'socket_addrinfo_explain' => ['array', 'addrinfo'=>'resource'], +'socket_addrinfo_lookup' => ['resource[]', 'node'=>'string', 'service='=>'mixed', 'hints='=>'array'], +'socket_bind' => ['bool', 'socket'=>'resource', 'addr'=>'string', 'port='=>'int'], +'socket_clear_error' => ['void', 'socket='=>'resource'], +'socket_close' => ['void', 'socket'=>'resource'], +'socket_cmsg_space' => ['int', 'level'=>'int', 'type'=>'int'], +'socket_connect' => ['bool', 'socket'=>'resource', 'addr'=>'string', 'port='=>'int'], +'socket_create' => ['resource|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'], +'socket_create_listen' => ['resource|false', 'port'=>'int', 'backlog='=>'int'], +'socket_create_pair' => ['bool', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int', '&w_fd'=>'resource[]'], +'socket_export_stream' => ['resource|false', 'socket'=>'resource'], +'socket_get_option' => ['mixed', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int'], +'socket_getopt' => ['mixed', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int'], +'socket_getpeername' => ['bool', 'socket'=>'resource', '&w_addr'=>'string', '&w_port='=>'int'], +'socket_getsockname' => ['bool', 'socket'=>'resource', '&w_addr'=>'string', '&w_port='=>'int'], +'socket_import_stream' => ['resource|false', 'stream'=>'resource'], +'socket_last_error' => ['int', 'socket='=>'resource'], +'socket_listen' => ['bool', 'socket'=>'resource', 'backlog='=>'int'], +'socket_read' => ['string|false', 'socket'=>'resource', 'length'=>'int', 'type='=>'int'], +'socket_recv' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'len'=>'int', 'flags'=>'int'], +'socket_recvfrom' => ['int|false', 'socket'=>'resource', '&w_buf'=>'string', 'len'=>'int', 'flags'=>'int', '&w_name'=>'string', '&w_port='=>'int'], +'socket_recvmsg' => ['int|false', 'socket'=>'resource', '&w_message'=>'string', 'flags='=>'int'], +'socket_select' => ['int|false', '&rw_read_fds'=>'resource[]|null', '&rw_write_fds'=>'resource[]|null', '&rw_except_fds'=>'resource[]|null', 'tv_sec'=>'int', 'tv_usec='=>'int'], +'socket_send' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'len'=>'int', 'flags'=>'int'], +'socket_sendmsg' => ['int|false', 'socket'=>'resource', 'message'=>'array', 'flags'=>'int'], +'socket_sendto' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'len'=>'int', 'flags'=>'int', 'addr'=>'string', 'port='=>'int'], +'socket_set_block' => ['bool', 'socket'=>'resource'], +'socket_set_nonblock' => ['bool', 'socket'=>'resource'], +'socket_set_option' => ['bool', 'socket'=>'resource', 'level'=>'int', 'optname'=>'int', 'optval'=>'int|string|array'], +'socket_shutdown' => ['bool', 'socket'=>'resource', 'how='=>'int'], +'socket_strerror' => ['string', 'errno'=>'int'], +'socket_write' => ['int|false', 'socket'=>'resource', 'buf'=>'string', 'length='=>'int'], +'Sodium\add' => ['', '&left'=>'string', 'right'=>'string'], +'Sodium\bin2hex' => ['string', 'binary'=>'string'], +'Sodium\compare' => ['int', 'left'=>'string', 'right'=>'string'], +'Sodium\crypto_aead_aes256gcm_decrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'], +'Sodium\crypto_aead_aes256gcm_encrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'], +'Sodium\crypto_aead_aes256gcm_is_available' => ['bool'], +'Sodium\crypto_aead_chacha20poly1305_decrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'], +'Sodium\crypto_aead_chacha20poly1305_encrypt' => ['string', 'msg'=>'string', 'nonce'=>'string', 'key'=>'string', 'ad='=>'string'], +'Sodium\crypto_auth' => ['string', 'msg'=>'string', 'key'=>'string'], +'Sodium\crypto_auth_verify' => ['bool', 'mac'=>'string', 'msg'=>'string', 'key'=>'string'], +'Sodium\crypto_box' => ['string', 'msg'=>'string', 'nonce'=>'string', 'keypair'=>'string'], +'Sodium\crypto_box_keypair' => ['string'], +'Sodium\crypto_box_keypair_from_secretkey_and_publickey' => ['string', 'secretkey'=>'string', 'publickey'=>'string'], +'Sodium\crypto_box_open' => ['string', 'msg'=>'string', 'nonce'=>'string', 'keypair'=>'string'], +'Sodium\crypto_box_publickey' => ['string', 'keypair'=>'string'], +'Sodium\crypto_box_publickey_from_secretkey' => ['string', 'secretkey'=>'string'], +'Sodium\crypto_box_seal' => ['string', 'message'=>'string', 'publickey'=>'string'], +'Sodium\crypto_box_seal_open' => ['string', 'encrypted'=>'string', 'keypair'=>'string'], +'Sodium\crypto_box_secretkey' => ['string', 'keypair'=>'string'], +'Sodium\crypto_box_seed_keypair' => ['string', 'seed'=>'string'], +'Sodium\crypto_generichash' => ['string', 'input'=>'string', 'key='=>'string', 'length='=>'int'], +'Sodium\crypto_generichash_final' => ['string', 'state'=>'string', 'length='=>'int'], +'Sodium\crypto_generichash_init' => ['string', 'key='=>'string', 'length='=>'int'], +'Sodium\crypto_generichash_update' => ['bool', '&hashState'=>'string', 'append'=>'string'], +'Sodium\crypto_kx' => ['string', 'secretkey'=>'string', 'publickey'=>'string', 'client_publickey'=>'string', 'server_publickey'=>'string'], +'Sodium\crypto_pwhash' => ['string', 'out_len'=>'int', 'passwd'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], +'Sodium\crypto_pwhash_scryptsalsa208sha256' => ['string', 'out_len'=>'int', 'passwd'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], +'Sodium\crypto_pwhash_scryptsalsa208sha256_str' => ['string', 'passwd'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], +'Sodium\crypto_pwhash_scryptsalsa208sha256_str_verify' => ['bool', 'hash'=>'string', 'passwd'=>'string'], +'Sodium\crypto_pwhash_str' => ['string', 'passwd'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], +'Sodium\crypto_pwhash_str_verify' => ['bool', 'hash'=>'string', 'passwd'=>'string'], +'Sodium\crypto_scalarmult' => ['string', 'ecdhA'=>'string', 'ecdhB'=>'string'], +'Sodium\crypto_scalarmult_base' => ['string', 'sk'=>'string'], +'Sodium\crypto_secretbox' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'], +'Sodium\crypto_secretbox_open' => ['string', 'ciphertext'=>'string', 'nonce'=>'string', 'key'=>'string'], +'Sodium\crypto_shorthash' => ['string', 'message'=>'string', 'key'=>'string'], +'Sodium\crypto_sign' => ['string', 'message'=>'string', 'secretkey'=>'string'], +'Sodium\crypto_sign_detached' => ['string', 'message'=>'string', 'secretkey'=>'string'], +'Sodium\crypto_sign_ed25519_pk_to_curve25519' => ['string', 'sign_pk'=>'string'], +'Sodium\crypto_sign_ed25519_sk_to_curve25519' => ['string', 'sign_sk'=>'string'], +'Sodium\crypto_sign_keypair' => ['string'], +'Sodium\crypto_sign_keypair_from_secretkey_and_publickey' => ['string', 'secretkey'=>'string', 'publickey'=>'string'], +'Sodium\crypto_sign_open' => ['string|false', 'signed_message'=>'string', 'publickey'=>'string'], +'Sodium\crypto_sign_publickey' => ['string', 'keypair'=>'string'], +'Sodium\crypto_sign_publickey_from_secretkey' => ['string', 'secretkey'=>'string'], +'Sodium\crypto_sign_secretkey' => ['string', 'keypair'=>'string'], +'Sodium\crypto_sign_seed_keypair' => ['string', 'seed'=>'string'], +'Sodium\crypto_sign_verify_detached' => ['bool', 'signature'=>'string', 'msg'=>'string', 'publickey'=>'string'], +'Sodium\crypto_stream' => ['string', 'length'=>'int', 'nonce'=>'string', 'key'=>'string'], +'Sodium\crypto_stream_xor' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'], +'Sodium\hex2bin' => ['string', 'hex'=>'string'], +'Sodium\increment' => ['string', '&nonce'=>'string'], +'Sodium\library_version_major' => ['int'], +'Sodium\library_version_minor' => ['int'], +'Sodium\memcmp' => ['int', 'left'=>'string', 'right'=>'string'], +'Sodium\memzero' => ['', '&target'=>'string'], +'Sodium\randombytes_buf' => ['string', 'length'=>'int'], +'Sodium\randombytes_random16' => ['int|string'], +'Sodium\randombytes_uniform' => ['int', 'upperBoundNonInclusive'=>'int'], +'Sodium\version_string' => ['string'], +'sodium_add' => ['string', 'string_1'=>'string', 'string_2'=>'string'], +'sodium_base642bin' => ['string', 'base64'=>'string', 'variant'=>'int', 'ignore'=>'string'], +'sodium_bin2base64' => ['string', 'binary'=>'string', 'variant'=>'int'], +'sodium_bin2hex' => ['string', 'binary'=>'string'], +'sodium_compare' => ['int', 'string_1'=>'string', 'string_2'=>'string'], +'sodium_crypto_aead_aes256gcm_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_aead_aes256gcm_encrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_aead_aes256gcm_is_available' => ['bool'], +'sodium_crypto_aead_aes256gcm_keygen' => ['string'], +'sodium_crypto_aead_chacha20poly1305_decrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_aead_chacha20poly1305_encrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_aead_chacha20poly1305_ietf_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_aead_chacha20poly1305_ietf_encrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_aead_chacha20poly1305_ietf_keygen' => ['string'], +'sodium_crypto_aead_chacha20poly1305_keygen' => ['string'], +'sodium_crypto_aead_xchacha20poly1305_ietf_decrypt' => ['string|false', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_aead_xchacha20poly1305_ietf_encrypt' => ['string', 'confidential_message'=>'string', 'public_message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_aead_xchacha20poly1305_ietf_keygen' => ['string'], +'sodium_crypto_auth' => ['string', 'message'=>'string', 'key'=>'string'], +'sodium_crypto_auth_keygen' => ['string'], +'sodium_crypto_auth_verify' => ['bool', 'mac'=>'string', 'message'=>'string', 'key'=>'string'], +'sodium_crypto_box' => ['string', 'string'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_box_keypair' => ['string'], +'sodium_crypto_box_keypair_from_secretkey_and_publickey' => ['string', 'secret_key'=>'string', 'public_key'=>'string'], +'sodium_crypto_box_open' => ['string|false', 'message'=>'string', 'nonce'=>'string', 'message_keypair'=>'string'], +'sodium_crypto_box_publickey' => ['string', 'keypair'=>'string'], +'sodium_crypto_box_publickey_from_secretkey' => ['string', 'secretkey'=>'string'], +'sodium_crypto_box_seal' => ['string', 'message'=>'string', 'publickey'=>'string'], +'sodium_crypto_box_seal_open' => ['string|false', 'message'=>'string', 'recipient_keypair'=>'string'], +'sodium_crypto_box_secretkey' => ['string', 'keypair'=>'string'], +'sodium_crypto_box_seed_keypair' => ['string', 'seed'=>'string'], +'sodium_crypto_generichash' => ['string', 'msg'=>'string', 'key='=>'?string', 'length='=>'?int'], +'sodium_crypto_generichash_final' => ['string', 'state'=>'string', 'length='=>'?int'], +'sodium_crypto_generichash_init' => ['string', 'key='=>'?string', 'length='=>'?int'], +'sodium_crypto_generichash_keygen' => ['string'], +'sodium_crypto_generichash_update' => ['bool', 'state'=>'string', 'string'=>'string'], +'sodium_crypto_kdf_derive_from_key' => ['string', 'subkey_len'=>'int', 'subkey_id'=>'int', 'context'=>'string', 'key'=>'string'], +'sodium_crypto_kdf_keygen' => ['string'], +'sodium_crypto_kx' => ['string', 'secretkey'=>'string', 'publickey'=>'string', 'client_publickey'=>'string', 'server_publickey'=>'string'], +'sodium_crypto_kx_client_session_keys' => ['string', 'client_keypair'=>'string', 'server_key'=>'string'], +'sodium_crypto_kx_keypair' => ['string'], +'sodium_crypto_kx_publickey' => ['string', 'keypair'=>'string'], +'sodium_crypto_kx_secretkey' => ['string', 'keypair'=>'string'], +'sodium_crypto_kx_seed_keypair' => ['string', 'seed'=>'string'], +'sodium_crypto_kx_server_session_keys' => ['string', 'server_keypair'=>'string', 'client_key'=>'string'], +'sodium_crypto_pwhash' => ['string', 'length'=>'int', 'password'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int', 'alg='=>'int'], +'sodium_crypto_pwhash_scryptsalsa208sha256' => ['string', 'length'=>'int', 'password'=>'string', 'salt'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], +'sodium_crypto_pwhash_scryptsalsa208sha256_str' => ['string', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], +'sodium_crypto_pwhash_scryptsalsa208sha256_str_verify' => ['bool', 'hash'=>'string', 'password'=>'string'], +'sodium_crypto_pwhash_str' => ['string', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], +'sodium_crypto_pwhash_str_needs_rehash' => ['bool', 'password'=>'string', 'opslimit'=>'int', 'memlimit'=>'int'], +'sodium_crypto_pwhash_str_verify' => ['bool', 'hash'=>'string', 'password'=>'string'], +'sodium_crypto_scalarmult' => ['string', 'string_1'=>'string', 'string_2'=>'string'], +'sodium_crypto_scalarmult_base' => ['string', 'string_1'=>'string', 'string_2'=>'string'], +'sodium_crypto_secretbox' => ['string', 'plaintext'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_secretbox_keygen' => ['string'], +'sodium_crypto_secretbox_open' => ['string|false', 'ciphertext'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_secretstream_xchacha20poly1305_init_pull' => ['string', 'header'=>'string', 'key'=>'string'], +'sodium_crypto_secretstream_xchacha20poly1305_init_push' => ['array', 'key'=>'string'], +'sodium_crypto_secretstream_xchacha20poly1305_keygen' => ['string'], +'sodium_crypto_secretstream_xchacha20poly1305_pull' => ['array', 'state'=>'string', 'c'=>'string', 'ad='=>'string'], +'sodium_crypto_secretstream_xchacha20poly1305_push' => ['string', 'state'=>'string', 'msg'=>'string', 'ad='=>'string', 'tag='=>'int'], +'sodium_crypto_secretstream_xchacha20poly1305_rekey' => ['void', 'state'=>'string'], +'sodium_crypto_shorthash' => ['string', 'message'=>'string', 'key'=>'string'], +'sodium_crypto_shorthash_keygen' => ['string'], +'sodium_crypto_sign' => ['string', 'message'=>'string', 'secretkey'=>'string'], +'sodium_crypto_sign_detached' => ['string', 'message'=>'string', 'secretkey'=>'string'], +'sodium_crypto_sign_ed25519_pk_to_curve25519' => ['string', 'ed25519pk'=>'string'], +'sodium_crypto_sign_ed25519_sk_to_curve25519' => ['string', 'ed25519sk'=>'string'], +'sodium_crypto_sign_keypair' => ['string'], +'sodium_crypto_sign_keypair_from_secretkey_and_publickey' => ['string', 'secret_key'=>'string', 'public_key'=>'string'], +'sodium_crypto_sign_open' => ['string|false', 'message'=>'string', 'publickey'=>'string'], +'sodium_crypto_sign_publickey' => ['string', 'keypair'=>'string'], +'sodium_crypto_sign_publickey_from_secretkey' => ['string', 'secretkey'=>'string'], +'sodium_crypto_sign_secretkey' => ['string', 'keypair'=>'string'], +'sodium_crypto_sign_seed_keypair' => ['string', 'seed'=>'string'], +'sodium_crypto_sign_verify_detached' => ['bool', 'signature'=>'string', 'message'=>'string', 'publickey'=>'string'], +'sodium_crypto_stream' => ['string', 'length'=>'int', 'nonce'=>'string', 'key'=>'string'], +'sodium_crypto_stream_keygen' => ['string'], +'sodium_crypto_stream_xor' => ['string', 'message'=>'string', 'nonce'=>'string', 'key'=>'string'], +'sodium_hex2bin' => ['string', 'hex'=>'string', 'ignore='=>'string'], +'sodium_increment' => ['string', '&binary_string'=>'string'], +'sodium_library_version_major' => ['int'], +'sodium_library_version_minor' => ['int'], +'sodium_memcmp' => ['int', 'string_1'=>'string', 'string_2'=>'string'], +'sodium_memzero' => ['void', '&secret'=>'string'], +'sodium_pad' => ['string', 'unpadded'=>'string', 'length'=>'int'], +'sodium_randombytes_buf' => ['string', 'length'=>'int'], +'sodium_randombytes_random16' => ['int|string'], +'sodium_randombytes_uniform' => ['int', 'upperBoundNonInclusive'=>'int'], +'sodium_unpad' => ['string', 'padded'=>'string', 'length'=>'int'], +'sodium_version_string' => ['string'], +'solid_fetch_prev' => ['bool', 'result_id'=>''], +'solr_get_version' => ['string'], +'SolrClient::__construct' => ['void', 'clientOptions'=>'array'], +'SolrClient::__destruct' => [''], +'SolrClient::addDocument' => ['SolrUpdateResponse', 'doc'=>'solrinputdocument', 'allowdups='=>'bool', 'commitwithin='=>'int'], +'SolrClient::addDocuments' => ['SolrUpdateResponse', 'docs'=>'array', 'allowdups='=>'bool', 'commitwithin='=>'int'], +'SolrClient::commit' => ['SolrUpdateResponse', 'maxsegments='=>'int', 'waitflush='=>'bool', 'waitsearcher='=>'bool'], +'SolrClient::deleteById' => ['SolrUpdateResponse', 'id'=>'string'], +'SolrClient::deleteByIds' => ['SolrUpdateResponse', 'ids'=>'array'], +'SolrClient::deleteByQueries' => ['SolrUpdateResponse', 'queries'=>'array'], +'SolrClient::deleteByQuery' => ['SolrUpdateResponse', 'query'=>'string'], +'SolrClient::getById' => ['SolrQueryResponse', 'id'=>'string'], +'SolrClient::getByIds' => ['SolrQueryResponse', 'ids'=>'array'], +'SolrClient::getDebug' => ['string'], +'SolrClient::getOptions' => ['array'], +'SolrClient::optimize' => ['SolrUpdateResponse', 'maxsegments='=>'int', 'waitflush='=>'bool', 'waitsearcher='=>'bool'], +'SolrClient::ping' => ['SolrPingResponse'], +'SolrClient::query' => ['SolrQueryResponse', 'query'=>'solrparams'], +'SolrClient::request' => ['SolrUpdateResponse', 'raw_request'=>'string'], +'SolrClient::rollback' => ['SolrUpdateResponse'], +'SolrClient::setResponseWriter' => ['void', 'responsewriter'=>'string'], +'SolrClient::setServlet' => ['bool', 'type'=>'int', 'value'=>'string'], +'SolrClient::system' => ['void'], +'SolrClient::threads' => ['void'], +'SolrClientException::getInternalInfo' => ['array'], +'SolrCollapseFunction::__toString' => ['string'], +'SolrCollapseFunction::getField' => ['string'], +'SolrCollapseFunction::getHint' => ['string'], +'SolrCollapseFunction::getMax' => ['string'], +'SolrCollapseFunction::getMin' => ['string'], +'SolrCollapseFunction::getNullPolicy' => ['string'], +'SolrCollapseFunction::getSize' => ['int'], +'SolrCollapseFunction::setField' => ['SolrCollapseFunction', 'fieldName'=>'string'], +'SolrCollapseFunction::setHint' => ['SolrCollapseFunction', 'hint'=>'string'], +'SolrCollapseFunction::setMax' => ['SolrCollapseFunction', 'max'=>'string'], +'SolrCollapseFunction::setMin' => ['SolrCollapseFunction', 'min'=>'string'], +'SolrCollapseFunction::setNullPolicy' => ['SolrCollapseFunction', 'nullPolicy'=>'string'], +'SolrCollapseFunction::setSize' => ['SolrCollapseFunction', 'size'=>'int'], +'SolrDisMaxQuery::__construct' => ['void', 'q='=>'string'], +'SolrDisMaxQuery::addBigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'], +'SolrDisMaxQuery::addBoostQuery' => ['SolrDisMaxQuery', 'field'=>'string', 'value'=>'string', 'boost='=>'string'], +'SolrDisMaxQuery::addExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'], +'SolrDisMaxQuery::addExpandSortField' => ['SolrQuery', 'field'=>'string', 'order'=>'string'], +'SolrDisMaxQuery::addFacetDateField' => ['SolrQuery', 'dateField'=>'string'], +'SolrDisMaxQuery::addFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::addFacetField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::addFacetQuery' => ['SolrQuery', 'facetQuery'=>'string'], +'SolrDisMaxQuery::addField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::addFilterQuery' => ['SolrQuery', 'fq'=>'string'], +'SolrDisMaxQuery::addGroupField' => ['SolrQuery', 'value'=>'string'], +'SolrDisMaxQuery::addGroupFunction' => ['SolrQuery', 'value'=>'string'], +'SolrDisMaxQuery::addGroupQuery' => ['SolrQuery', 'value'=>'string'], +'SolrDisMaxQuery::addGroupSortField' => ['SolrQuery', 'field'=>'string', 'order'=>'int'], +'SolrDisMaxQuery::addHighlightField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::addMltField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::addMltQueryField' => ['SolrQuery', 'field'=>'string', 'boost'=>'float'], +'SolrDisMaxQuery::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], +'SolrDisMaxQuery::addPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'], +'SolrDisMaxQuery::addQueryField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost='=>'string'], +'SolrDisMaxQuery::addSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'], +'SolrDisMaxQuery::addStatsFacet' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::addStatsField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::addTrigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string', 'boost'=>'string', 'slop='=>'string'], +'SolrDisMaxQuery::addUserField' => ['SolrDisMaxQuery', 'field'=>'string'], +'SolrDisMaxQuery::collapse' => ['SolrQuery', 'collapseFunction'=>'SolrCollapseFunction'], +'SolrDisMaxQuery::get' => ['mixed', 'param_name'=>'string'], +'SolrDisMaxQuery::getExpand' => ['bool'], +'SolrDisMaxQuery::getExpandFilterQueries' => ['array'], +'SolrDisMaxQuery::getExpandQuery' => ['array'], +'SolrDisMaxQuery::getExpandRows' => ['int'], +'SolrDisMaxQuery::getExpandSortFields' => ['array'], +'SolrDisMaxQuery::getFacet' => ['bool'], +'SolrDisMaxQuery::getFacetDateEnd' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetDateFields' => ['array'], +'SolrDisMaxQuery::getFacetDateGap' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetDateHardEnd' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetDateOther' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetDateStart' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetFields' => ['array'], +'SolrDisMaxQuery::getFacetLimit' => ['int', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetMethod' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetMinCount' => ['int', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetMissing' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetOffset' => ['int', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetPrefix' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getFacetQueries' => ['string'], +'SolrDisMaxQuery::getFacetSort' => ['int', 'field_override'=>'string'], +'SolrDisMaxQuery::getFields' => ['string'], +'SolrDisMaxQuery::getFilterQueries' => ['string'], +'SolrDisMaxQuery::getGroup' => ['bool'], +'SolrDisMaxQuery::getGroupCachePercent' => ['int'], +'SolrDisMaxQuery::getGroupFacet' => ['bool'], +'SolrDisMaxQuery::getGroupFields' => ['array'], +'SolrDisMaxQuery::getGroupFormat' => ['string'], +'SolrDisMaxQuery::getGroupFunctions' => ['array'], +'SolrDisMaxQuery::getGroupLimit' => ['int'], +'SolrDisMaxQuery::getGroupMain' => ['bool'], +'SolrDisMaxQuery::getGroupNGroups' => ['bool'], +'SolrDisMaxQuery::getGroupOffset' => ['bool'], +'SolrDisMaxQuery::getGroupQueries' => ['array'], +'SolrDisMaxQuery::getGroupSortFields' => ['array'], +'SolrDisMaxQuery::getGroupTruncate' => ['bool'], +'SolrDisMaxQuery::getHighlight' => ['bool'], +'SolrDisMaxQuery::getHighlightAlternateField' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightFields' => ['array'], +'SolrDisMaxQuery::getHighlightFormatter' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightFragmenter' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightFragsize' => ['int', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightHighlightMultiTerm' => ['bool'], +'SolrDisMaxQuery::getHighlightMaxAlternateFieldLength' => ['int', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightMaxAnalyzedChars' => ['int'], +'SolrDisMaxQuery::getHighlightMergeContiguous' => ['bool', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightRegexMaxAnalyzedChars' => ['int'], +'SolrDisMaxQuery::getHighlightRegexPattern' => ['string'], +'SolrDisMaxQuery::getHighlightRegexSlop' => ['float'], +'SolrDisMaxQuery::getHighlightRequireFieldMatch' => ['bool'], +'SolrDisMaxQuery::getHighlightSimplePost' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightSimplePre' => ['string', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightSnippets' => ['int', 'field_override'=>'string'], +'SolrDisMaxQuery::getHighlightUsePhraseHighlighter' => ['bool'], +'SolrDisMaxQuery::getMlt' => ['bool'], +'SolrDisMaxQuery::getMltBoost' => ['bool'], +'SolrDisMaxQuery::getMltCount' => ['int'], +'SolrDisMaxQuery::getMltFields' => ['array'], +'SolrDisMaxQuery::getMltMaxNumQueryTerms' => ['int'], +'SolrDisMaxQuery::getMltMaxNumTokens' => ['int'], +'SolrDisMaxQuery::getMltMaxWordLength' => ['int'], +'SolrDisMaxQuery::getMltMinDocFrequency' => ['int'], +'SolrDisMaxQuery::getMltMinTermFrequency' => ['int'], +'SolrDisMaxQuery::getMltMinWordLength' => ['int'], +'SolrDisMaxQuery::getMltQueryFields' => ['array'], +'SolrDisMaxQuery::getParam' => ['mixed', 'param_name'=>'string'], +'SolrDisMaxQuery::getParams' => ['array'], +'SolrDisMaxQuery::getPreparedParams' => ['array'], +'SolrDisMaxQuery::getQuery' => ['string'], +'SolrDisMaxQuery::getRows' => ['int'], +'SolrDisMaxQuery::getSortFields' => ['array'], +'SolrDisMaxQuery::getStart' => ['int'], +'SolrDisMaxQuery::getStats' => ['bool'], +'SolrDisMaxQuery::getStatsFacets' => ['array'], +'SolrDisMaxQuery::getStatsFields' => ['array'], +'SolrDisMaxQuery::getTerms' => ['bool'], +'SolrDisMaxQuery::getTermsField' => ['string'], +'SolrDisMaxQuery::getTermsIncludeLowerBound' => ['bool'], +'SolrDisMaxQuery::getTermsIncludeUpperBound' => ['bool'], +'SolrDisMaxQuery::getTermsLimit' => ['int'], +'SolrDisMaxQuery::getTermsLowerBound' => ['string'], +'SolrDisMaxQuery::getTermsMaxCount' => ['int'], +'SolrDisMaxQuery::getTermsMinCount' => ['int'], +'SolrDisMaxQuery::getTermsPrefix' => ['string'], +'SolrDisMaxQuery::getTermsReturnRaw' => ['bool'], +'SolrDisMaxQuery::getTermsSort' => ['int'], +'SolrDisMaxQuery::getTermsUpperBound' => ['string'], +'SolrDisMaxQuery::getTimeAllowed' => ['int'], +'SolrDisMaxQuery::removeBigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeBoostQuery' => ['SolrDisMaxQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'], +'SolrDisMaxQuery::removeExpandSortField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeFacetDateField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::removeFacetField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeFacetQuery' => ['SolrQuery', 'value'=>'string'], +'SolrDisMaxQuery::removeField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeFilterQuery' => ['SolrQuery', 'fq'=>'string'], +'SolrDisMaxQuery::removeHighlightField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeMltField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeMltQueryField' => ['SolrQuery', 'queryField'=>'string'], +'SolrDisMaxQuery::removePhraseField' => ['SolrDisMaxQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeQueryField' => ['SolrDisMaxQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeSortField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeStatsFacet' => ['SolrQuery', 'value'=>'string'], +'SolrDisMaxQuery::removeStatsField' => ['SolrQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeTrigramPhraseField' => ['SolrDisMaxQuery', 'field'=>'string'], +'SolrDisMaxQuery::removeUserField' => ['SolrDisMaxQuery', 'field'=>'string'], +'SolrDisMaxQuery::serialize' => ['string'], +'SolrDisMaxQuery::set' => ['SolrParams', 'name'=>'string', 'value'=>''], +'SolrDisMaxQuery::setBigramPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'], +'SolrDisMaxQuery::setBigramPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'], +'SolrDisMaxQuery::setBoostFunction' => ['SolrDisMaxQuery', 'function'=>'string'], +'SolrDisMaxQuery::setBoostQuery' => ['SolrDisMaxQuery', 'q'=>'string'], +'SolrDisMaxQuery::setEchoHandler' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setEchoParams' => ['SolrQuery', 'type'=>'string'], +'SolrDisMaxQuery::setExpand' => ['SolrQuery', 'value'=>'bool'], +'SolrDisMaxQuery::setExpandQuery' => ['SolrQuery', 'q'=>'string'], +'SolrDisMaxQuery::setExpandRows' => ['SolrQuery', 'value'=>'int'], +'SolrDisMaxQuery::setExplainOther' => ['SolrQuery', 'query'=>'string'], +'SolrDisMaxQuery::setFacet' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setFacetDateEnd' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetDateGap' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetDateHardEnd' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetDateStart' => ['SolrQuery', 'value'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetEnumCacheMinDefaultFrequency' => ['SolrQuery', 'frequency'=>'int', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetLimit' => ['SolrQuery', 'limit'=>'int', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetMethod' => ['SolrQuery', 'method'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetMinCount' => ['SolrQuery', 'mincount'=>'int', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetMissing' => ['SolrQuery', 'flag'=>'bool', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetOffset' => ['SolrQuery', 'offset'=>'int', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetPrefix' => ['SolrQuery', 'prefix'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setFacetSort' => ['SolrQuery', 'facetSort'=>'int', 'field_override'=>'string'], +'SolrDisMaxQuery::setGroup' => ['SolrQuery', 'value'=>'bool'], +'SolrDisMaxQuery::setGroupCachePercent' => ['SolrQuery', 'percent'=>'int'], +'SolrDisMaxQuery::setGroupFacet' => ['SolrQuery', 'value'=>'bool'], +'SolrDisMaxQuery::setGroupFormat' => ['SolrQuery', 'value'=>'string'], +'SolrDisMaxQuery::setGroupLimit' => ['SolrQuery', 'value'=>'int'], +'SolrDisMaxQuery::setGroupMain' => ['SolrQuery', 'value'=>'string'], +'SolrDisMaxQuery::setGroupNGroups' => ['SolrQuery', 'value'=>'bool'], +'SolrDisMaxQuery::setGroupOffset' => ['SolrQuery', 'value'=>'int'], +'SolrDisMaxQuery::setGroupTruncate' => ['SolrQuery', 'value'=>'bool'], +'SolrDisMaxQuery::setHighlight' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setHighlightAlternateField' => ['SolrQuery', 'field'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightFormatter' => ['SolrQuery', 'formatter'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightFragmenter' => ['SolrQuery', 'fragmenter'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightFragsize' => ['SolrQuery', 'size'=>'int', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightHighlightMultiTerm' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setHighlightMaxAlternateFieldLength' => ['SolrQuery', 'fieldLength'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightMaxAnalyzedChars' => ['SolrQuery', 'value'=>'int'], +'SolrDisMaxQuery::setHighlightMergeContiguous' => ['SolrQuery', 'flag'=>'bool', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightRegexMaxAnalyzedChars' => ['SolrQuery', 'maxAnalyzedChars'=>'int'], +'SolrDisMaxQuery::setHighlightRegexPattern' => ['SolrQuery', 'value'=>'string'], +'SolrDisMaxQuery::setHighlightRegexSlop' => ['SolrQuery', 'factor'=>'float'], +'SolrDisMaxQuery::setHighlightRequireFieldMatch' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setHighlightSimplePost' => ['SolrQuery', 'simplePost'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightSimplePre' => ['SolrQuery', 'simplePre'=>'string', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightSnippets' => ['SolrQuery', 'value'=>'int', 'field_override'=>'string'], +'SolrDisMaxQuery::setHighlightUsePhraseHighlighter' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setMinimumMatch' => ['SolrDisMaxQuery', 'value'=>'string'], +'SolrDisMaxQuery::setMlt' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setMltBoost' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setMltCount' => ['SolrQuery', 'count'=>'int'], +'SolrDisMaxQuery::setMltMaxNumQueryTerms' => ['SolrQuery', 'value'=>'int'], +'SolrDisMaxQuery::setMltMaxNumTokens' => ['SolrQuery', 'value'=>'int'], +'SolrDisMaxQuery::setMltMaxWordLength' => ['SolrQuery', 'maxWordLength'=>'int'], +'SolrDisMaxQuery::setMltMinDocFrequency' => ['SolrQuery', 'minDocFrequency'=>'int'], +'SolrDisMaxQuery::setMltMinTermFrequency' => ['SolrQuery', 'minTermFrequency'=>'int'], +'SolrDisMaxQuery::setMltMinWordLength' => ['SolrQuery', 'minWordLength'=>'int'], +'SolrDisMaxQuery::setOmitHeader' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''], +'SolrDisMaxQuery::setPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'], +'SolrDisMaxQuery::setPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'], +'SolrDisMaxQuery::setQuery' => ['SolrQuery', 'query'=>'string'], +'SolrDisMaxQuery::setQueryAlt' => ['SolrDisMaxQuery', 'q'=>'string'], +'SolrDisMaxQuery::setQueryPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'], +'SolrDisMaxQuery::setRows' => ['SolrQuery', 'rows'=>'int'], +'SolrDisMaxQuery::setShowDebugInfo' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setStart' => ['SolrQuery', 'start'=>'int'], +'SolrDisMaxQuery::setStats' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setTerms' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setTermsField' => ['SolrQuery', 'fieldname'=>'string'], +'SolrDisMaxQuery::setTermsIncludeLowerBound' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setTermsIncludeUpperBound' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setTermsLimit' => ['SolrQuery', 'limit'=>'int'], +'SolrDisMaxQuery::setTermsLowerBound' => ['SolrQuery', 'lowerBound'=>'string'], +'SolrDisMaxQuery::setTermsMaxCount' => ['SolrQuery', 'frequency'=>'int'], +'SolrDisMaxQuery::setTermsMinCount' => ['SolrQuery', 'frequency'=>'int'], +'SolrDisMaxQuery::setTermsPrefix' => ['SolrQuery', 'prefix'=>'string'], +'SolrDisMaxQuery::setTermsReturnRaw' => ['SolrQuery', 'flag'=>'bool'], +'SolrDisMaxQuery::setTermsSort' => ['SolrQuery', 'sortType'=>'int'], +'SolrDisMaxQuery::setTermsUpperBound' => ['SolrQuery', 'upperBound'=>'string'], +'SolrDisMaxQuery::setTieBreaker' => ['SolrDisMaxQuery', 'tieBreaker'=>'string'], +'SolrDisMaxQuery::setTimeAllowed' => ['SolrQuery', 'timeAllowed'=>'int'], +'SolrDisMaxQuery::setTrigramPhraseFields' => ['SolrDisMaxQuery', 'fields'=>'string'], +'SolrDisMaxQuery::setTrigramPhraseSlop' => ['SolrDisMaxQuery', 'slop'=>'string'], +'SolrDisMaxQuery::setUserFields' => ['SolrDisMaxQuery', 'fields'=>'string'], +'SolrDisMaxQuery::toString' => ['string', 'url_encode='=>'bool|false'], +'SolrDisMaxQuery::unserialize' => ['void', 'serialized'=>'string'], +'SolrDisMaxQuery::useDisMaxQueryParser' => ['SolrDisMaxQuery'], +'SolrDisMaxQuery::useEDisMaxQueryParser' => ['SolrDisMaxQuery'], +'SolrDocument::__clone' => ['void'], +'SolrDocument::__construct' => ['void'], +'SolrDocument::__destruct' => [''], +'SolrDocument::__get' => ['SolrDocumentField', 'fieldname'=>'string'], +'SolrDocument::__isset' => ['bool', 'fieldname'=>'string'], +'SolrDocument::__set' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string'], +'SolrDocument::__unset' => ['bool', 'fieldname'=>'string'], +'SolrDocument::addField' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string'], +'SolrDocument::clear' => ['bool'], +'SolrDocument::current' => ['SolrDocumentField'], +'SolrDocument::deleteField' => ['bool', 'fieldname'=>'string'], +'SolrDocument::fieldExists' => ['bool', 'fieldname'=>'string'], +'SolrDocument::getChildDocuments' => ['array'], +'SolrDocument::getChildDocumentsCount' => ['int'], +'SolrDocument::getField' => ['SolrDocumentField', 'fieldname'=>'string'], +'SolrDocument::getFieldCount' => ['int'], +'SolrDocument::getFieldNames' => ['array'], +'SolrDocument::getInputDocument' => ['SolrInputDocument'], +'SolrDocument::hasChildDocuments' => ['bool'], +'SolrDocument::key' => ['string'], +'SolrDocument::merge' => ['bool', 'sourcedoc'=>'solrdocument', 'overwrite='=>'bool'], +'SolrDocument::next' => ['void'], +'SolrDocument::offsetExists' => ['bool', 'fieldname'=>'string'], +'SolrDocument::offsetGet' => ['SolrDocumentField', 'fieldname'=>'string'], +'SolrDocument::offsetSet' => ['void', 'fieldname'=>'string', 'fieldvalue'=>'string'], +'SolrDocument::offsetUnset' => ['void', 'fieldname'=>'string'], +'SolrDocument::reset' => ['bool'], +'SolrDocument::rewind' => ['void'], +'SolrDocument::serialize' => ['string'], +'SolrDocument::sort' => ['bool', 'sortorderby'=>'int', 'sortdirection='=>'int'], +'SolrDocument::toArray' => ['array'], +'SolrDocument::unserialize' => ['void', 'serialized'=>'string'], +'SolrDocument::valid' => ['bool'], +'SolrDocumentField::__construct' => ['void'], +'SolrDocumentField::__destruct' => [''], +'SolrException::__clone' => ['void'], +'SolrException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'SolrException::__toString' => ['string'], +'SolrException::__wakeup' => ['void'], +'SolrException::getCode' => ['int'], +'SolrException::getFile' => ['string'], +'SolrException::getInternalInfo' => ['array'], +'SolrException::getLine' => ['int'], +'SolrException::getMessage' => ['string'], +'SolrException::getPrevious' => ['Exception|Throwable'], +'SolrException::getTrace' => ['array'], +'SolrException::getTraceAsString' => ['string'], +'SolrGenericResponse::__construct' => ['void'], +'SolrGenericResponse::__destruct' => [''], +'SolrGenericResponse::getDigestedResponse' => ['string'], +'SolrGenericResponse::getHttpStatus' => ['int'], +'SolrGenericResponse::getHttpStatusMessage' => ['string'], +'SolrGenericResponse::getRawRequest' => ['string'], +'SolrGenericResponse::getRawRequestHeaders' => ['string'], +'SolrGenericResponse::getRawResponse' => ['string'], +'SolrGenericResponse::getRawResponseHeaders' => ['string'], +'SolrGenericResponse::getRequestUrl' => ['string'], +'SolrGenericResponse::getResponse' => ['SolrObject'], +'SolrGenericResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], +'SolrGenericResponse::success' => ['bool'], +'SolrIllegalArgumentException::__clone' => ['void'], +'SolrIllegalArgumentException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'SolrIllegalArgumentException::__toString' => ['string'], +'SolrIllegalArgumentException::__wakeup' => ['void'], +'SolrIllegalArgumentException::getCode' => ['int'], +'SolrIllegalArgumentException::getFile' => ['string'], +'SolrIllegalArgumentException::getInternalInfo' => ['array'], +'SolrIllegalArgumentException::getLine' => ['int'], +'SolrIllegalArgumentException::getMessage' => ['string'], +'SolrIllegalArgumentException::getPrevious' => ['Exception|Throwable'], +'SolrIllegalArgumentException::getTrace' => ['array'], +'SolrIllegalArgumentException::getTraceAsString' => ['string'], +'SolrIllegalOperationException::__clone' => ['void'], +'SolrIllegalOperationException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'SolrIllegalOperationException::__toString' => ['string'], +'SolrIllegalOperationException::__wakeup' => ['void'], +'SolrIllegalOperationException::getCode' => ['int'], +'SolrIllegalOperationException::getFile' => ['string'], +'SolrIllegalOperationException::getInternalInfo' => ['array'], +'SolrIllegalOperationException::getLine' => ['int'], +'SolrIllegalOperationException::getMessage' => ['string'], +'SolrIllegalOperationException::getPrevious' => ['Exception|Throwable'], +'SolrIllegalOperationException::getTrace' => ['array'], +'SolrIllegalOperationException::getTraceAsString' => ['string'], +'SolrInputDocument::__clone' => ['void'], +'SolrInputDocument::__construct' => ['void'], +'SolrInputDocument::__destruct' => [''], +'SolrInputDocument::addChildDocument' => ['void', 'child'=>'SolrInputDocument'], +'SolrInputDocument::addChildDocuments' => ['void', 'docs'=>'array'], +'SolrInputDocument::addField' => ['bool', 'fieldname'=>'string', 'fieldvalue'=>'string', 'fieldboostvalue='=>'float'], +'SolrInputDocument::clear' => ['bool'], +'SolrInputDocument::deleteField' => ['bool', 'fieldname'=>'string'], +'SolrInputDocument::fieldExists' => ['bool', 'fieldname'=>'string'], +'SolrInputDocument::getBoost' => ['float'], +'SolrInputDocument::getChildDocuments' => ['array'], +'SolrInputDocument::getChildDocumentsCount' => ['int'], +'SolrInputDocument::getField' => ['SolrDocumentField', 'fieldname'=>'string'], +'SolrInputDocument::getFieldBoost' => ['float', 'fieldname'=>'string'], +'SolrInputDocument::getFieldCount' => ['int'], +'SolrInputDocument::getFieldNames' => ['array'], +'SolrInputDocument::hasChildDocuments' => ['bool'], +'SolrInputDocument::merge' => ['bool', 'sourcedoc'=>'solrinputdocument', 'overwrite='=>'bool'], +'SolrInputDocument::reset' => ['bool'], +'SolrInputDocument::setBoost' => ['bool', 'documentboostvalue'=>'float'], +'SolrInputDocument::setFieldBoost' => ['bool', 'fieldname'=>'string', 'fieldboostvalue'=>'float'], +'SolrInputDocument::sort' => ['bool', 'sortorderby'=>'int', 'sortdirection='=>'int'], +'SolrInputDocument::toArray' => ['array'], +'SolrModifiableParams::__construct' => ['void'], +'SolrModifiableParams::__destruct' => [''], +'SolrModifiableParams::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'], +'SolrModifiableParams::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], +'SolrModifiableParams::get' => ['mixed', 'param_name'=>'string'], +'SolrModifiableParams::getParam' => ['mixed', 'param_name'=>'string'], +'SolrModifiableParams::getParams' => ['array'], +'SolrModifiableParams::getPreparedParams' => ['array'], +'SolrModifiableParams::serialize' => ['string'], +'SolrModifiableParams::set' => ['SolrParams', 'name'=>'string', 'value'=>''], +'SolrModifiableParams::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''], +'SolrModifiableParams::toString' => ['string', 'url_encode='=>'bool|false'], +'SolrModifiableParams::unserialize' => ['void', 'serialized'=>'string'], +'SolrObject::__construct' => ['void'], +'SolrObject::__destruct' => [''], +'SolrObject::getPropertyNames' => ['array'], +'SolrObject::offsetExists' => ['bool', 'property_name'=>'string'], +'SolrObject::offsetGet' => ['mixed', 'property_name'=>'string'], +'SolrObject::offsetSet' => ['void', 'property_name'=>'string', 'property_value'=>'string'], +'SolrObject::offsetUnset' => ['void', 'property_name'=>'string'], +'SolrParams::__construct' => ['void'], +'SolrParams::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'], +'SolrParams::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], +'SolrParams::get' => ['mixed', 'param_name'=>'string'], +'SolrParams::getParam' => ['mixed', 'param_name='=>'string'], +'SolrParams::getParams' => ['array'], +'SolrParams::getPreparedParams' => ['array'], +'SolrParams::serialize' => ['string'], +'SolrParams::set' => ['void', 'name'=>'string', 'value'=>'string'], +'SolrParams::setParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], +'SolrParams::toString' => ['string', 'url_encode='=>'bool'], +'SolrParams::unserialize' => ['void', 'serialized'=>'string'], +'SolrPingResponse::__construct' => ['void'], +'SolrPingResponse::__destruct' => [''], +'SolrPingResponse::getDigestedResponse' => ['string'], +'SolrPingResponse::getHttpStatus' => ['int'], +'SolrPingResponse::getHttpStatusMessage' => ['string'], +'SolrPingResponse::getRawRequest' => ['string'], +'SolrPingResponse::getRawRequestHeaders' => ['string'], +'SolrPingResponse::getRawResponse' => ['string'], +'SolrPingResponse::getRawResponseHeaders' => ['string'], +'SolrPingResponse::getRequestUrl' => ['string'], +'SolrPingResponse::getResponse' => ['string'], +'SolrPingResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], +'SolrPingResponse::success' => ['bool'], +'SolrQuery::__construct' => ['void', 'q='=>'string'], +'SolrQuery::__destruct' => [''], +'SolrQuery::add' => ['SolrParams', 'name'=>'string', 'value'=>'string'], +'SolrQuery::addExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'], +'SolrQuery::addExpandSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'string'], +'SolrQuery::addFacetDateField' => ['SolrQuery', 'datefield'=>'string'], +'SolrQuery::addFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], +'SolrQuery::addFacetField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::addFacetQuery' => ['SolrQuery', 'facetquery'=>'string'], +'SolrQuery::addField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::addFilterQuery' => ['SolrQuery', 'fq'=>'string'], +'SolrQuery::addGroupField' => ['SolrQuery', 'value'=>'string'], +'SolrQuery::addGroupFunction' => ['SolrQuery', 'value'=>'string'], +'SolrQuery::addGroupQuery' => ['SolrQuery', 'value'=>'string'], +'SolrQuery::addGroupSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'], +'SolrQuery::addHighlightField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::addMltField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::addMltQueryField' => ['SolrQuery', 'field'=>'string', 'boost'=>'float'], +'SolrQuery::addParam' => ['SolrParams', 'name'=>'string', 'value'=>'string'], +'SolrQuery::addSortField' => ['SolrQuery', 'field'=>'string', 'order='=>'int'], +'SolrQuery::addStatsFacet' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::addStatsField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::collapse' => ['SolrQuery', 'collapseFunction'=>'SolrCollapseFunction'], +'SolrQuery::get' => ['mixed', 'param_name'=>'string'], +'SolrQuery::getExpand' => ['bool'], +'SolrQuery::getExpandFilterQueries' => ['array'], +'SolrQuery::getExpandQuery' => ['array'], +'SolrQuery::getExpandRows' => ['int'], +'SolrQuery::getExpandSortFields' => ['array'], +'SolrQuery::getFacet' => ['bool'], +'SolrQuery::getFacetDateEnd' => ['string', 'field_override='=>'string'], +'SolrQuery::getFacetDateFields' => ['array'], +'SolrQuery::getFacetDateGap' => ['string', 'field_override='=>'string'], +'SolrQuery::getFacetDateHardEnd' => ['string', 'field_override='=>'string'], +'SolrQuery::getFacetDateOther' => ['array', 'field_override='=>'string'], +'SolrQuery::getFacetDateStart' => ['string', 'field_override='=>'string'], +'SolrQuery::getFacetFields' => ['array'], +'SolrQuery::getFacetLimit' => ['int', 'field_override='=>'string'], +'SolrQuery::getFacetMethod' => ['string', 'field_override='=>'string'], +'SolrQuery::getFacetMinCount' => ['int', 'field_override='=>'string'], +'SolrQuery::getFacetMissing' => ['bool', 'field_override='=>'string'], +'SolrQuery::getFacetOffset' => ['int', 'field_override='=>'string'], +'SolrQuery::getFacetPrefix' => ['string', 'field_override='=>'string'], +'SolrQuery::getFacetQueries' => ['array'], +'SolrQuery::getFacetSort' => ['int', 'field_override='=>'string'], +'SolrQuery::getFields' => ['array'], +'SolrQuery::getFilterQueries' => ['array'], +'SolrQuery::getGroup' => ['bool'], +'SolrQuery::getGroupCachePercent' => ['int'], +'SolrQuery::getGroupFacet' => ['bool'], +'SolrQuery::getGroupFields' => ['array'], +'SolrQuery::getGroupFormat' => ['string'], +'SolrQuery::getGroupFunctions' => ['array'], +'SolrQuery::getGroupLimit' => ['int'], +'SolrQuery::getGroupMain' => ['bool'], +'SolrQuery::getGroupNGroups' => ['bool'], +'SolrQuery::getGroupOffset' => ['int'], +'SolrQuery::getGroupQueries' => ['array'], +'SolrQuery::getGroupSortFields' => ['array'], +'SolrQuery::getGroupTruncate' => ['bool'], +'SolrQuery::getHighlight' => ['bool'], +'SolrQuery::getHighlightAlternateField' => ['string', 'field_override='=>'string'], +'SolrQuery::getHighlightFields' => ['array'], +'SolrQuery::getHighlightFormatter' => ['string', 'field_override='=>'string'], +'SolrQuery::getHighlightFragmenter' => ['string', 'field_override='=>'string'], +'SolrQuery::getHighlightFragsize' => ['int', 'field_override='=>'string'], +'SolrQuery::getHighlightHighlightMultiTerm' => ['bool'], +'SolrQuery::getHighlightMaxAlternateFieldLength' => ['int', 'field_override='=>'string'], +'SolrQuery::getHighlightMaxAnalyzedChars' => ['int'], +'SolrQuery::getHighlightMergeContiguous' => ['bool', 'field_override='=>'string'], +'SolrQuery::getHighlightRegexMaxAnalyzedChars' => ['int'], +'SolrQuery::getHighlightRegexPattern' => ['string'], +'SolrQuery::getHighlightRegexSlop' => ['float'], +'SolrQuery::getHighlightRequireFieldMatch' => ['bool'], +'SolrQuery::getHighlightSimplePost' => ['string', 'field_override='=>'string'], +'SolrQuery::getHighlightSimplePre' => ['string', 'field_override='=>'string'], +'SolrQuery::getHighlightSnippets' => ['int', 'field_override='=>'string'], +'SolrQuery::getHighlightUsePhraseHighlighter' => ['bool'], +'SolrQuery::getMlt' => ['bool'], +'SolrQuery::getMltBoost' => ['bool'], +'SolrQuery::getMltCount' => ['int'], +'SolrQuery::getMltFields' => ['array'], +'SolrQuery::getMltMaxNumQueryTerms' => ['int'], +'SolrQuery::getMltMaxNumTokens' => ['int'], +'SolrQuery::getMltMaxWordLength' => ['int'], +'SolrQuery::getMltMinDocFrequency' => ['int'], +'SolrQuery::getMltMinTermFrequency' => ['int'], +'SolrQuery::getMltMinWordLength' => ['int'], +'SolrQuery::getMltQueryFields' => ['array'], +'SolrQuery::getParam' => ['mixed', 'param_name'=>'string'], +'SolrQuery::getParams' => ['array'], +'SolrQuery::getPreparedParams' => ['array'], +'SolrQuery::getQuery' => ['string'], +'SolrQuery::getRows' => ['int'], +'SolrQuery::getSortFields' => ['array'], +'SolrQuery::getStart' => ['int'], +'SolrQuery::getStats' => ['bool'], +'SolrQuery::getStatsFacets' => ['array'], +'SolrQuery::getStatsFields' => ['array'], +'SolrQuery::getTerms' => ['bool'], +'SolrQuery::getTermsField' => ['string'], +'SolrQuery::getTermsIncludeLowerBound' => ['bool'], +'SolrQuery::getTermsIncludeUpperBound' => ['bool'], +'SolrQuery::getTermsLimit' => ['int'], +'SolrQuery::getTermsLowerBound' => ['string'], +'SolrQuery::getTermsMaxCount' => ['int'], +'SolrQuery::getTermsMinCount' => ['int'], +'SolrQuery::getTermsPrefix' => ['string'], +'SolrQuery::getTermsReturnRaw' => ['bool'], +'SolrQuery::getTermsSort' => ['int'], +'SolrQuery::getTermsUpperBound' => ['string'], +'SolrQuery::getTimeAllowed' => ['int'], +'SolrQuery::removeExpandFilterQuery' => ['SolrQuery', 'fq'=>'string'], +'SolrQuery::removeExpandSortField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::removeFacetDateField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::removeFacetDateOther' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], +'SolrQuery::removeFacetField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::removeFacetQuery' => ['SolrQuery', 'value'=>'string'], +'SolrQuery::removeField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::removeFilterQuery' => ['SolrQuery', 'fq'=>'string'], +'SolrQuery::removeHighlightField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::removeMltField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::removeMltQueryField' => ['SolrQuery', 'queryfield'=>'string'], +'SolrQuery::removeSortField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::removeStatsFacet' => ['SolrQuery', 'value'=>'string'], +'SolrQuery::removeStatsField' => ['SolrQuery', 'field'=>'string'], +'SolrQuery::serialize' => ['string'], +'SolrQuery::set' => ['SolrParams', 'name'=>'string', 'value'=>''], +'SolrQuery::setEchoHandler' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setEchoParams' => ['SolrQuery', 'type'=>'string'], +'SolrQuery::setExpand' => ['SolrQuery', 'value'=>'bool'], +'SolrQuery::setExpandQuery' => ['SolrQuery', 'q'=>'string'], +'SolrQuery::setExpandRows' => ['SolrQuery', 'value'=>'int'], +'SolrQuery::setExplainOther' => ['SolrQuery', 'query'=>'string'], +'SolrQuery::setFacet' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setFacetDateEnd' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], +'SolrQuery::setFacetDateGap' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], +'SolrQuery::setFacetDateHardEnd' => ['SolrQuery', 'value'=>'bool', 'field_override='=>'string'], +'SolrQuery::setFacetDateStart' => ['SolrQuery', 'value'=>'string', 'field_override='=>'string'], +'SolrQuery::setFacetEnumCacheMinDefaultFrequency' => ['SolrQuery', 'frequency'=>'int', 'field_override='=>'string'], +'SolrQuery::setFacetLimit' => ['SolrQuery', 'limit'=>'int', 'field_override='=>'string'], +'SolrQuery::setFacetMethod' => ['SolrQuery', 'method'=>'string', 'field_override='=>'string'], +'SolrQuery::setFacetMinCount' => ['SolrQuery', 'mincount'=>'int', 'field_override='=>'string'], +'SolrQuery::setFacetMissing' => ['SolrQuery', 'flag'=>'bool', 'field_override='=>'string'], +'SolrQuery::setFacetOffset' => ['SolrQuery', 'offset'=>'int', 'field_override='=>'string'], +'SolrQuery::setFacetPrefix' => ['SolrQuery', 'prefix'=>'string', 'field_override='=>'string'], +'SolrQuery::setFacetSort' => ['SolrQuery', 'facetsort'=>'int', 'field_override='=>'string'], +'SolrQuery::setGroup' => ['SolrQuery', 'value'=>'bool'], +'SolrQuery::setGroupCachePercent' => ['SolrQuery', 'percent'=>'int'], +'SolrQuery::setGroupFacet' => ['SolrQuery', 'value'=>'bool'], +'SolrQuery::setGroupFormat' => ['SolrQuery', 'value'=>'string'], +'SolrQuery::setGroupLimit' => ['SolrQuery', 'value'=>'int'], +'SolrQuery::setGroupMain' => ['SolrQuery', 'value'=>'string'], +'SolrQuery::setGroupNGroups' => ['SolrQuery', 'value'=>'bool'], +'SolrQuery::setGroupOffset' => ['SolrQuery', 'value'=>'int'], +'SolrQuery::setGroupTruncate' => ['SolrQuery', 'value'=>'bool'], +'SolrQuery::setHighlight' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setHighlightAlternateField' => ['SolrQuery', 'field'=>'string', 'field_override='=>'string'], +'SolrQuery::setHighlightFormatter' => ['SolrQuery', 'formatter'=>'string', 'field_override='=>'string'], +'SolrQuery::setHighlightFragmenter' => ['SolrQuery', 'fragmenter'=>'string', 'field_override='=>'string'], +'SolrQuery::setHighlightFragsize' => ['SolrQuery', 'size'=>'int', 'field_override='=>'string'], +'SolrQuery::setHighlightHighlightMultiTerm' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setHighlightMaxAlternateFieldLength' => ['SolrQuery', 'fieldlength'=>'int', 'field_override='=>'string'], +'SolrQuery::setHighlightMaxAnalyzedChars' => ['SolrQuery', 'value'=>'int'], +'SolrQuery::setHighlightMergeContiguous' => ['SolrQuery', 'flag'=>'bool', 'field_override='=>'string'], +'SolrQuery::setHighlightRegexMaxAnalyzedChars' => ['SolrQuery', 'maxanalyzedchars'=>'int'], +'SolrQuery::setHighlightRegexPattern' => ['SolrQuery', 'value'=>'string'], +'SolrQuery::setHighlightRegexSlop' => ['SolrQuery', 'factor'=>'float'], +'SolrQuery::setHighlightRequireFieldMatch' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setHighlightSimplePost' => ['SolrQuery', 'simplepost'=>'string', 'field_override='=>'string'], +'SolrQuery::setHighlightSimplePre' => ['SolrQuery', 'simplepre'=>'string', 'field_override='=>'string'], +'SolrQuery::setHighlightSnippets' => ['SolrQuery', 'value'=>'int', 'field_override='=>'string'], +'SolrQuery::setHighlightUsePhraseHighlighter' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setMlt' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setMltBoost' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setMltCount' => ['SolrQuery', 'count'=>'int'], +'SolrQuery::setMltMaxNumQueryTerms' => ['SolrQuery', 'value'=>'int'], +'SolrQuery::setMltMaxNumTokens' => ['SolrQuery', 'value'=>'int'], +'SolrQuery::setMltMaxWordLength' => ['SolrQuery', 'maxwordlength'=>'int'], +'SolrQuery::setMltMinDocFrequency' => ['SolrQuery', 'mindocfrequency'=>'int'], +'SolrQuery::setMltMinTermFrequency' => ['SolrQuery', 'mintermfrequency'=>'int'], +'SolrQuery::setMltMinWordLength' => ['SolrQuery', 'minwordlength'=>'int'], +'SolrQuery::setOmitHeader' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setParam' => ['SolrParams', 'name'=>'string', 'value'=>''], +'SolrQuery::setQuery' => ['SolrQuery', 'query'=>'string'], +'SolrQuery::setRows' => ['SolrQuery', 'rows'=>'int'], +'SolrQuery::setShowDebugInfo' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setStart' => ['SolrQuery', 'start'=>'int'], +'SolrQuery::setStats' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setTerms' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setTermsField' => ['SolrQuery', 'fieldname'=>'string'], +'SolrQuery::setTermsIncludeLowerBound' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setTermsIncludeUpperBound' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setTermsLimit' => ['SolrQuery', 'limit'=>'int'], +'SolrQuery::setTermsLowerBound' => ['SolrQuery', 'lowerbound'=>'string'], +'SolrQuery::setTermsMaxCount' => ['SolrQuery', 'frequency'=>'int'], +'SolrQuery::setTermsMinCount' => ['SolrQuery', 'frequency'=>'int'], +'SolrQuery::setTermsPrefix' => ['SolrQuery', 'prefix'=>'string'], +'SolrQuery::setTermsReturnRaw' => ['SolrQuery', 'flag'=>'bool'], +'SolrQuery::setTermsSort' => ['SolrQuery', 'sorttype'=>'int'], +'SolrQuery::setTermsUpperBound' => ['SolrQuery', 'upperbound'=>'string'], +'SolrQuery::setTimeAllowed' => ['SolrQuery', 'timeallowed'=>'int'], +'SolrQuery::toString' => ['string', 'url_encode='=>'bool|false'], +'SolrQuery::unserialize' => ['void', 'serialized'=>'string'], +'SolrQueryResponse::__construct' => ['void'], +'SolrQueryResponse::__destruct' => [''], +'SolrQueryResponse::getDigestedResponse' => ['string'], +'SolrQueryResponse::getHttpStatus' => ['int'], +'SolrQueryResponse::getHttpStatusMessage' => ['string'], +'SolrQueryResponse::getRawRequest' => ['string'], +'SolrQueryResponse::getRawRequestHeaders' => ['string'], +'SolrQueryResponse::getRawResponse' => ['string'], +'SolrQueryResponse::getRawResponseHeaders' => ['string'], +'SolrQueryResponse::getRequestUrl' => ['string'], +'SolrQueryResponse::getResponse' => ['SolrObject'], +'SolrQueryResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], +'SolrQueryResponse::success' => ['bool'], +'SolrResponse::getDigestedResponse' => ['string'], +'SolrResponse::getHttpStatus' => ['int'], +'SolrResponse::getHttpStatusMessage' => ['string'], +'SolrResponse::getRawRequest' => ['string'], +'SolrResponse::getRawRequestHeaders' => ['string'], +'SolrResponse::getRawResponse' => ['string'], +'SolrResponse::getRawResponseHeaders' => ['string'], +'SolrResponse::getRequestUrl' => ['string'], +'SolrResponse::getResponse' => ['SolrObject'], +'SolrResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], +'SolrResponse::success' => ['bool'], +'SolrServerException::__clone' => ['void'], +'SolrServerException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'SolrServerException::__toString' => ['string'], +'SolrServerException::__wakeup' => ['void'], +'SolrServerException::getCode' => ['int'], +'SolrServerException::getFile' => ['string'], +'SolrServerException::getInternalInfo' => ['array'], +'SolrServerException::getLine' => ['int'], +'SolrServerException::getMessage' => ['string'], +'SolrServerException::getPrevious' => ['Exception|Throwable'], +'SolrServerException::getTrace' => ['array'], +'SolrServerException::getTraceAsString' => ['string'], +'SolrUpdateResponse::__construct' => ['void'], +'SolrUpdateResponse::__destruct' => [''], +'SolrUpdateResponse::getDigestedResponse' => ['string'], +'SolrUpdateResponse::getHttpStatus' => ['int'], +'SolrUpdateResponse::getHttpStatusMessage' => ['string'], +'SolrUpdateResponse::getRawRequest' => ['string'], +'SolrUpdateResponse::getRawRequestHeaders' => ['string'], +'SolrUpdateResponse::getRawResponse' => ['string'], +'SolrUpdateResponse::getRawResponseHeaders' => ['string'], +'SolrUpdateResponse::getRequestUrl' => ['string'], +'SolrUpdateResponse::getResponse' => ['SolrObject'], +'SolrUpdateResponse::setParseMode' => ['bool', 'parser_mode='=>'int'], +'SolrUpdateResponse::success' => ['bool'], +'SolrUtils::digestXmlResponse' => ['SolrObject', 'xmlresponse'=>'string', 'parse_mode='=>'int'], +'SolrUtils::escapeQueryChars' => ['string', 'str'=>'string'], +'SolrUtils::getSolrVersion' => ['string'], +'SolrUtils::queryPhrase' => ['string', 'str'=>'string'], +'sort' => ['bool', '&rw_array_arg'=>'array', 'sort_flags='=>'int'], +'soundex' => ['string', 'str'=>'string'], +'SphinxClient::__construct' => ['void'], +'SphinxClient::addQuery' => ['int', 'query'=>'string', 'index='=>'string', 'comment='=>'string'], +'SphinxClient::buildExcerpts' => ['array', 'docs'=>'array', 'index'=>'string', 'words'=>'string', 'opts='=>'array'], +'SphinxClient::buildKeywords' => ['array', 'query'=>'string', 'index'=>'string', 'hits'=>'bool'], +'SphinxClient::close' => ['bool'], +'SphinxClient::escapeString' => ['string', 'string'=>'string'], +'SphinxClient::getLastError' => ['string'], +'SphinxClient::getLastWarning' => ['string'], +'SphinxClient::open' => ['bool'], +'SphinxClient::query' => ['array', 'query'=>'string', 'index='=>'string', 'comment='=>'string'], +'SphinxClient::resetFilters' => ['void'], +'SphinxClient::resetGroupBy' => ['void'], +'SphinxClient::runQueries' => ['array'], +'SphinxClient::setArrayResult' => ['bool', 'array_result'=>'bool'], +'SphinxClient::setConnectTimeout' => ['bool', 'timeout'=>'float'], +'SphinxClient::setFieldWeights' => ['bool', 'weights'=>'array'], +'SphinxClient::setFilter' => ['bool', 'attribute'=>'string', 'values'=>'array', 'exclude='=>'bool'], +'SphinxClient::setFilterFloatRange' => ['bool', 'attribute'=>'string', 'min'=>'float', 'max'=>'float', 'exclude='=>'bool'], +'SphinxClient::setFilterRange' => ['bool', 'attribute'=>'string', 'min'=>'int', 'max'=>'int', 'exclude='=>'bool'], +'SphinxClient::setGeoAnchor' => ['bool', 'attrlat'=>'string', 'attrlong'=>'string', 'latitude'=>'float', 'longitude'=>'float'], +'SphinxClient::setGroupBy' => ['bool', 'attribute'=>'string', 'func'=>'int', 'groupsort='=>'string'], +'SphinxClient::setGroupDistinct' => ['bool', 'attribute'=>'string'], +'SphinxClient::setIDRange' => ['bool', 'min'=>'int', 'max'=>'int'], +'SphinxClient::setIndexWeights' => ['bool', 'weights'=>'array'], +'SphinxClient::setLimits' => ['bool', 'offset'=>'int', 'limit'=>'int', 'max_matches='=>'int', 'cutoff='=>'int'], +'SphinxClient::setMatchMode' => ['bool', 'mode'=>'int'], +'SphinxClient::setMaxQueryTime' => ['bool', 'qtime'=>'int'], +'SphinxClient::setOverride' => ['bool', 'attribute'=>'string', 'type'=>'int', 'values'=>'array'], +'SphinxClient::setRankingMode' => ['bool', 'ranker'=>'int'], +'SphinxClient::setRetries' => ['bool', 'count'=>'int', 'delay='=>'int'], +'SphinxClient::setSelect' => ['bool', 'clause'=>'string'], +'SphinxClient::setServer' => ['bool', 'server'=>'string', 'port'=>'int'], +'SphinxClient::setSortMode' => ['bool', 'mode'=>'int', 'sortby='=>'string'], +'SphinxClient::status' => ['array'], +'SphinxClient::updateAttributes' => ['int', 'index'=>'string', 'attributes'=>'array', 'values'=>'array', 'mva='=>'bool'], +'spl_autoload' => ['void', 'class_name'=>'string', 'file_extensions='=>'string'], +'spl_autoload_call' => ['void', 'class_name'=>'string'], +'spl_autoload_extensions' => ['string', 'file_extensions='=>'string'], +'spl_autoload_functions' => ['false|array'], +'spl_autoload_register' => ['bool', 'autoload_function='=>'callable', 'throw='=>'bool', 'prepend='=>'bool'], +'spl_autoload_unregister' => ['bool', 'autoload_function'=>'mixed'], +'spl_classes' => ['array'], +'spl_object_hash' => ['string', 'obj'=>'object'], +'spl_object_id' => ['int', 'obj'=>'object'], +'SplDoublyLinkedList::add' => ['void', 'index'=>'mixed', 'newval'=>'mixed'], +'SplDoublyLinkedList::bottom' => ['mixed'], +'SplDoublyLinkedList::count' => ['int'], +'SplDoublyLinkedList::current' => ['mixed'], +'SplDoublyLinkedList::getIteratorMode' => ['int'], +'SplDoublyLinkedList::isEmpty' => ['bool'], +'SplDoublyLinkedList::key' => ['mixed'], +'SplDoublyLinkedList::next' => ['void'], +'SplDoublyLinkedList::offsetExists' => ['bool', 'index'=>'mixed'], +'SplDoublyLinkedList::offsetGet' => ['mixed', 'index'=>'mixed'], +'SplDoublyLinkedList::offsetSet' => ['void', 'index'=>'mixed', 'newval'=>'mixed'], +'SplDoublyLinkedList::offsetUnset' => ['void', 'index'=>'mixed'], +'SplDoublyLinkedList::pop' => ['mixed'], +'SplDoublyLinkedList::prev' => ['void'], +'SplDoublyLinkedList::push' => ['void', 'value'=>'mixed'], +'SplDoublyLinkedList::rewind' => ['void'], +'SplDoublyLinkedList::serialize' => ['string'], +'SplDoublyLinkedList::setIteratorMode' => ['int', 'flags'=>'int'], +'SplDoublyLinkedList::shift' => ['mixed'], +'SplDoublyLinkedList::top' => ['mixed'], +'SplDoublyLinkedList::unserialize' => ['void', 'serialized'=>'string'], +'SplDoublyLinkedList::unshift' => ['bool', 'value'=>'mixed'], +'SplDoublyLinkedList::valid' => ['bool'], +'SplEnum::__construct' => ['void', 'initial_value='=>'mixed', 'strict='=>'bool|true'], +'SplEnum::getConstList' => ['array', 'include_default='=>'bool'], +'SplFileInfo::__construct' => ['void', 'file_name'=>'string'], +'SplFileInfo::__toString' => ['string'], +'SplFileInfo::getATime' => ['int'], +'SplFileInfo::getBasename' => ['string', 'suffix='=>'string'], +'SplFileInfo::getCTime' => ['int'], +'SplFileInfo::getExtension' => ['string'], +'SplFileInfo::getFileInfo' => ['SplFileInfo', 'class_name='=>'string'], +'SplFileInfo::getFilename' => ['string'], +'SplFileInfo::getGroup' => ['int'], +'SplFileInfo::getInode' => ['int'], +'SplFileInfo::getLinkTarget' => ['string'], +'SplFileInfo::getMTime' => ['int'], +'SplFileInfo::getOwner' => ['int'], +'SplFileInfo::getPath' => ['string'], +'SplFileInfo::getPathInfo' => ['SplFileInfo', 'class_name='=>'string'], +'SplFileInfo::getPathname' => ['string'], +'SplFileInfo::getPerms' => ['int'], +'SplFileInfo::getRealPath' => ['string|false'], +'SplFileInfo::getSize' => ['int'], +'SplFileInfo::getType' => ['string'], +'SplFileInfo::isDir' => ['bool'], +'SplFileInfo::isExecutable' => ['bool'], +'SplFileInfo::isFile' => ['bool'], +'SplFileInfo::isLink' => ['bool'], +'SplFileInfo::isReadable' => ['bool'], +'SplFileInfo::isWritable' => ['bool'], +'SplFileInfo::openFile' => ['SplFileObject', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>'resource'], +'SplFileInfo::setFileClass' => ['void', 'class_name='=>'string'], +'SplFileInfo::setInfoClass' => ['void', 'class_name='=>'string'], +'SplFileObject::__construct' => ['void', 'filename'=>'string', 'mode='=>'string', 'use_include_path='=>'bool', 'context='=>''], +'SplFileObject::__toString' => ['string'], +'SplFileObject::current' => ['string|array|false'], +'SplFileObject::eof' => ['bool'], +'SplFileObject::fflush' => ['bool'], +'SplFileObject::fgetc' => ['string|false'], +'SplFileObject::fgetcsv' => ['?array|false', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], +'SplFileObject::fgets' => ['string'], +'SplFileObject::fgetss' => ['string', 'allowable_tags='=>'string'], +'SplFileObject::flock' => ['bool', 'operation'=>'int', '&w_wouldblock='=>'int'], +'SplFileObject::fpassthru' => ['int'], +'SplFileObject::fputcsv' => ['int|false', 'fields'=>'array', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], +'SplFileObject::fread' => ['string|false', 'length'=>'int'], +'SplFileObject::fscanf' => ['bool', 'format'=>'string', '&...w_vars='=>'string|int|float'], +'SplFileObject::fseek' => ['int', 'pos'=>'int', 'whence='=>'int'], +'SplFileObject::fstat' => ['array|false'], +'SplFileObject::ftell' => ['int|false'], +'SplFileObject::ftruncate' => ['bool', 'size'=>'int'], +'SplFileObject::fwrite' => ['int', 'str'=>'string', 'length='=>'int'], +'SplFileObject::getChildren' => ['bool'], +'SplFileObject::getCsvControl' => ['array'], +'SplFileObject::getFlags' => ['int'], +'SplFileObject::getMaxLineLen' => ['int'], +'SplFileObject::hasChildren' => ['bool'], +'SplFileObject::key' => ['int'], +'SplFileObject::next' => ['void'], +'SplFileObject::rewind' => ['void'], +'SplFileObject::seek' => ['void', 'line_pos'=>'int'], +'SplFileObject::setCsvControl' => ['void', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], +'SplFileObject::setFlags' => ['void', 'flags'=>'int'], +'SplFileObject::setMaxLineLen' => ['void', 'max_len'=>'int'], +'SplFileObject::valid' => ['bool'], +'SplFixedArray::__construct' => ['void', 'size='=>'int'], +'SplFixedArray::__wakeup' => ['void'], +'SplFixedArray::count' => ['int'], +'SplFixedArray::current' => ['mixed'], +'SplFixedArray::fromArray' => ['SplFixedArray', 'data'=>'array', 'save_indexes='=>'bool'], +'SplFixedArray::getSize' => ['int'], +'SplFixedArray::key' => ['int'], +'SplFixedArray::next' => ['void'], +'SplFixedArray::offsetExists' => ['bool', 'index'=>'int'], +'SplFixedArray::offsetGet' => ['mixed', 'index'=>'int'], +'SplFixedArray::offsetSet' => ['void', 'index'=>'int', 'newval'=>'mixed'], +'SplFixedArray::offsetUnset' => ['void', 'index'=>'int'], +'SplFixedArray::rewind' => ['void'], +'SplFixedArray::setSize' => ['bool', 'size'=>'int'], +'SplFixedArray::toArray' => ['array'], +'SplFixedArray::valid' => ['bool'], +'SplHeap::compare' => ['int', 'value1'=>'mixed', 'value2'=>'mixed'], +'SplHeap::count' => ['int'], +'SplHeap::current' => ['mixed'], +'SplHeap::extract' => ['mixed'], +'SplHeap::insert' => ['bool', 'value'=>'mixed'], +'SplHeap::isCorrupted' => ['int'], +'SplHeap::isEmpty' => ['bool'], +'SplHeap::key' => ['int'], +'SplHeap::next' => ['void'], +'SplHeap::recoverFromCorruption' => ['int'], +'SplHeap::rewind' => ['void'], +'SplHeap::top' => ['mixed'], +'SplHeap::valid' => ['bool'], +'split' => ['array', 'pattern'=>'string', 'string'=>'string', 'limit='=>'int'], +'spliti' => ['array', 'pattern'=>'string', 'string'=>'string', 'limit='=>'int'], +'SplMaxHeap::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'], +'SplMinHeap::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'], +'SplObjectStorage::addAll' => ['void', 'os'=>'splobjectstorage'], +'SplObjectStorage::attach' => ['void', 'obj'=>'object', 'inf='=>'mixed'], +'SplObjectStorage::contains' => ['bool', 'obj'=>'object'], +'SplObjectStorage::count' => ['int'], +'SplObjectStorage::current' => ['object'], +'SplObjectStorage::detach' => ['void', 'obj'=>'object'], +'SplObjectStorage::getHash' => ['string', 'obj'=>'object'], +'SplObjectStorage::getInfo' => ['mixed'], +'SplObjectStorage::key' => ['int'], +'SplObjectStorage::next' => ['void'], +'SplObjectStorage::offsetExists' => ['bool', 'object'=>'object'], +'SplObjectStorage::offsetGet' => ['mixed', 'obj'=>'object'], +'SplObjectStorage::offsetSet' => ['object', 'object'=>'object', 'data='=>'mixed'], +'SplObjectStorage::offsetUnset' => ['object', 'object'=>'object'], +'SplObjectStorage::removeAll' => ['void', 'os'=>'splobjectstorage'], +'SplObjectStorage::removeAllExcept' => ['void', 'os'=>'splobjectstorage'], +'SplObjectStorage::rewind' => ['void'], +'SplObjectStorage::serialize' => ['string'], +'SplObjectStorage::setInfo' => ['void', 'inf'=>'mixed'], +'SplObjectStorage::unserialize' => ['void', 'serialized'=>'string'], +'SplObjectStorage::valid' => ['bool'], +'SplObserver::update' => ['void', 'subject'=>'splsubject'], +'SplPriorityQueue::compare' => ['int', 'a'=>'mixed', 'b'=>'mixed'], +'SplPriorityQueue::count' => ['int'], +'SplPriorityQueue::current' => ['mixed'], +'SplPriorityQueue::extract' => ['mixed'], +'SplPriorityQueue::getExtractFlags' => ['int'], +'SplPriorityQueue::insert' => ['bool', 'value'=>'mixed', 'priority'=>'mixed'], +'SplPriorityQueue::isEmpty' => ['bool'], +'SplPriorityQueue::key' => ['mixed'], +'SplPriorityQueue::next' => ['void'], +'SplPriorityQueue::recoverFromCorruption' => ['void'], +'SplPriorityQueue::rewind' => ['void'], +'SplPriorityQueue::setExtractFlags' => ['void', 'flags'=>'int'], +'SplPriorityQueue::top' => ['mixed'], +'SplPriorityQueue::valid' => ['bool'], +'SplQueue::dequeue' => ['mixed'], +'SplQueue::enqueue' => ['void', 'value'=>'mixed'], +'SplQueue::setIteratorMode' => ['void', 'mode'=>'int'], +'SplStack::setIteratorMode' => ['void', 'mode'=>'int'], +'SplSubject::attach' => ['void', 'observer'=>'splobserver'], +'SplSubject::detach' => ['void', 'observer'=>'splobserver'], +'SplSubject::notify' => ['void'], +'SplTempFileObject::__construct' => ['void', 'max_memory='=>'int'], +'SplType::__construct' => ['void', 'initial_value='=>'mixed', 'strict='=>'bool'], +'Spoofchecker::__construct' => ['void'], +'Spoofchecker::areConfusable' => ['bool', 's1'=>'string', 's2'=>'string', '&w_error='=>'string'], +'Spoofchecker::isSuspicious' => ['bool', 'text'=>'string', '&w_error='=>'string'], +'Spoofchecker::setAllowedLocales' => ['void', 'locale_list'=>'string'], +'Spoofchecker::setChecks' => ['void', 'checks'=>'long'], +'sprintf' => ['string', 'format'=>'string', '...args='=>'string|int|float'], +'sql_regcase' => ['string', 'string'=>'string'], +'SQLite3::__construct' => ['void', 'filename'=>'string', 'flags='=>'int', 'encryption_key='=>'string|null'], +'SQLite3::busyTimeout' => ['bool', 'msecs'=>'int'], +'SQLite3::changes' => ['int'], +'SQLite3::close' => ['bool'], +'SQLite3::createAggregate' => ['bool', 'name'=>'string', 'step_callback'=>'callable', 'final_callback'=>'callable', 'argument_count='=>'int'], +'SQLite3::createCollation' => ['bool', 'name'=>'string', 'callback'=>'callable'], +'SQLite3::createFunction' => ['bool', 'name'=>'string', 'callback'=>'callable', 'argument_count='=>'int', 'flags='=>'int'], +'SQLite3::enableExceptions' => ['bool', 'enableexceptions='=>'bool'], +'SQLite3::escapeString' => ['string', 'value'=>'string'], +'SQLite3::exec' => ['bool', 'query'=>'string'], +'SQLite3::lastErrorCode' => ['int'], +'SQLite3::lastErrorMsg' => ['string'], +'SQLite3::lastInsertRowID' => ['int'], +'SQLite3::loadExtension' => ['bool', 'shared_library'=>'string'], +'SQLite3::open' => ['void', 'filename'=>'string', 'flags='=>'int', 'encryption_key='=>'string|null'], +'SQLite3::openBlob' => ['resource', 'table'=>'string', 'column'=>'string', 'rowid'=>'int', 'dbname'=>'string', 'flags='=>'int'], +'SQLite3::prepare' => ['SQLite3Stmt|false', 'query'=>'string'], +'SQLite3::query' => ['SQLite3Result|false', 'query'=>'string'], +'SQLite3::querySingle' => ['array|int|string|bool|float|null|false', 'query'=>'string', 'entire_row='=>'bool'], +'SQLite3::version' => ['array'], +'SQLite3Result::__construct' => ['void'], +'SQLite3Result::columnName' => ['string', 'column_number'=>'int'], +'SQLite3Result::columnType' => ['int', 'column_number'=>'int'], +'SQLite3Result::fetchArray' => ['array', 'mode='=>'int'], +'SQLite3Result::finalize' => ['bool'], +'SQLite3Result::numColumns' => ['int'], +'SQLite3Result::reset' => ['bool'], +'SQLite3Stmt::__construct' => ['void', 'dbobject'=>'sqlite3', 'statement'=>'string'], +'SQLite3Stmt::bindParam' => ['bool', 'parameter_name_or_number'=>'string|int', '&rw_parameter'=>'mixed', 'type='=>'int'], +'SQLite3Stmt::bindValue' => ['bool', 'parameter_name_or_number'=>'string|int', 'parameter'=>'mixed', 'type='=>'int'], +'SQLite3Stmt::clear' => ['bool'], +'SQLite3Stmt::close' => ['bool'], +'SQLite3Stmt::execute' => ['SQLite3Result'], +'SQLite3Stmt::paramCount' => ['int'], +'SQLite3Stmt::readOnly' => ['bool'], +'SQLite3Stmt::reset' => ['bool'], +'sqlite_array_query' => ['array', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'decode_binary='=>'bool'], +'sqlite_busy_timeout' => ['', 'dbhandle'=>'', 'milliseconds'=>'int'], +'sqlite_changes' => ['int', 'dbhandle'=>''], +'sqlite_close' => ['void', 'dbhandle'=>'resource'], +'sqlite_column' => ['', 'result'=>'', 'index_or_name'=>'', 'decode_binary='=>'bool'], +'sqlite_create_aggregate' => ['', 'dbhandle'=>'', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'], +'sqlite_create_function' => ['', 'dbhandle'=>'', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'], +'sqlite_current' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'sqlite_error_string' => ['string', 'error_code'=>'int'], +'sqlite_escape_string' => ['string', 'item'=>'string'], +'sqlite_exec' => ['bool', 'dbhandle'=>'', 'query'=>'string', 'error_msg='=>'string'], +'sqlite_factory' => ['SQLiteDatabase', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'], +'sqlite_fetch_all' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'sqlite_fetch_array' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'sqlite_fetch_column_types' => ['array', 'table_name'=>'string', 'dbhandle'=>'', 'result_type='=>'int'], +'sqlite_fetch_object' => ['object', 'result'=>'', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'], +'sqlite_fetch_single' => ['string', 'result'=>'', 'decode_binary='=>'bool'], +'sqlite_field_name' => ['string', 'result'=>'', 'field_index'=>'int'], +'sqlite_has_more' => ['bool', 'result'=>'resource'], +'sqlite_has_prev' => ['bool', 'result'=>''], +'sqlite_key' => ['int', 'result'=>''], +'sqlite_last_error' => ['int', 'dbhandle'=>''], +'sqlite_last_insert_rowid' => ['int', 'dbhandle'=>''], +'sqlite_libencoding' => ['string'], +'sqlite_libversion' => ['string'], +'sqlite_next' => ['bool', 'result'=>''], +'sqlite_num_fields' => ['int', 'result'=>''], +'sqlite_num_rows' => ['int', 'result'=>''], +'sqlite_open' => ['resource', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'], +'sqlite_popen' => ['resource', 'filename'=>'string', 'mode='=>'int', 'error_message='=>'string'], +'sqlite_prev' => ['bool', 'result'=>''], +'sqlite_query' => ['SQLiteResult', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'], +'sqlite_rewind' => ['bool', 'result'=>''], +'sqlite_seek' => ['bool', 'result'=>'', 'rownum'=>'int'], +'sqlite_single_query' => ['array', 'db'=>'', 'query'=>'string', 'first_row_only='=>'bool', 'decode_binary='=>'bool'], +'sqlite_udf_decode_binary' => ['string', 'data'=>'string'], +'sqlite_udf_encode_binary' => ['string', 'data'=>'string'], +'sqlite_unbuffered_query' => ['SQLiteUnbuffered', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'], +'sqlite_valid' => ['bool', 'result'=>''], +'SQLiteDatabase::arrayQuery' => ['array', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'decode_binary='=>'bool'], +'SQLiteDatabase::busyTimeout' => ['', 'dbhandle'=>'', 'milliseconds'=>'int'], +'SQLiteDatabase::changes' => ['int', 'dbhandle'=>''], +'SQLiteDatabase::createAggregate' => ['', 'dbhandle'=>'', 'function_name'=>'string', 'step_func'=>'callable', 'finalize_func'=>'callable', 'num_args='=>'int'], +'SQLiteDatabase::createFunction' => ['', 'dbhandle'=>'', 'function_name'=>'string', 'callback'=>'callable', 'num_args='=>'int'], +'SQLiteDatabase::exec' => ['bool', 'dbhandle'=>'', 'query'=>'string', 'error_msg='=>'string'], +'SQLiteDatabase::fetchColumnTypes' => ['array', 'table_name'=>'string', 'dbhandle'=>'', 'result_type='=>'int'], +'SQLiteDatabase::lastError' => ['int', 'dbhandle'=>''], +'SQLiteDatabase::lastInsertRowid' => ['int', 'dbhandle'=>''], +'SQLiteDatabase::query' => ['SQLiteResult', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'], +'SQLiteDatabase::queryExec' => ['bool', 'query'=>'string', '&w_error_msg='=>'string'], +'SQLiteDatabase::singleQuery' => ['array', 'db'=>'', 'query'=>'string', 'first_row_only='=>'bool', 'decode_binary='=>'bool'], +'SQLiteDatabase::unbufferedQuery' => ['SQLiteUnbuffered', 'dbhandle'=>'', 'query'=>'string', 'result_type='=>'int', 'error_msg='=>'string'], +'SQLiteResult::column' => ['', 'result'=>'', 'index_or_name'=>'', 'decode_binary='=>'bool'], +'SQLiteResult::current' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'SQLiteResult::fetch' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'SQLiteResult::fetchAll' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'SQLiteResult::fetchObject' => ['object', 'result'=>'', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'], +'SQLiteResult::fetchSingle' => ['string', 'result'=>'', 'decode_binary='=>'bool'], +'SQLiteResult::fieldName' => ['string', 'result'=>'', 'field_index'=>'int'], +'SQLiteResult::hasPrev' => ['bool', 'result'=>''], +'SQLiteResult::key' => ['int', 'result'=>''], +'SQLiteResult::next' => ['bool', 'result'=>''], +'SQLiteResult::numFields' => ['int', 'result'=>''], +'SQLiteResult::numRows' => ['int', 'result'=>''], +'SQLiteResult::prev' => ['bool', 'result'=>''], +'SQLiteResult::rewind' => ['bool', 'result'=>''], +'SQLiteResult::seek' => ['bool', 'result'=>'', 'rownum'=>'int'], +'SQLiteResult::valid' => ['bool', 'result'=>''], +'SQLiteUnbuffered::column' => ['', 'result'=>'', 'index_or_name'=>'', 'decode_binary='=>'bool'], +'SQLiteUnbuffered::current' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'SQLiteUnbuffered::fetch' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'SQLiteUnbuffered::fetchAll' => ['array', 'result'=>'', 'result_type='=>'int', 'decode_binary='=>'bool'], +'SQLiteUnbuffered::fetchObject' => ['object', 'result'=>'', 'class_name='=>'string', 'ctor_params='=>'array', 'decode_binary='=>'bool'], +'SQLiteUnbuffered::fetchSingle' => ['string', 'result'=>'', 'decode_binary='=>'bool'], +'SQLiteUnbuffered::fieldName' => ['string', 'result'=>'', 'field_index'=>'int'], +'SQLiteUnbuffered::next' => ['bool', 'result'=>''], +'SQLiteUnbuffered::numFields' => ['int', 'result'=>''], +'SQLiteUnbuffered::valid' => ['bool', 'result'=>''], +'sqlsrv_begin_transaction' => ['bool', 'conn'=>'resource'], +'sqlsrv_cancel' => ['bool', 'stmt'=>'resource'], +'sqlsrv_client_info' => ['array|false', 'conn'=>'resource'], +'sqlsrv_close' => ['bool', 'conn'=>'resource'], +'sqlsrv_commit' => ['bool', 'conn'=>'resource'], +'sqlsrv_configure' => ['bool', 'setting'=>'string', 'value'=>'mixed'], +'sqlsrv_connect' => ['resource|false', 'serverName'=>'string', 'connectionInfo='=>'array'], +'sqlsrv_errors' => ['array|null', 'errorsOrWarnings='=>'int'], +'sqlsrv_execute' => ['bool', 'stmt'=>'resource'], +'sqlsrv_fetch' => ['bool|null', 'stmt'=>'resource', 'row='=>'int', 'offset='=>'int'], +'sqlsrv_fetch_array' => ['array|null|false', 'stmt'=>'resource', 'fetchType='=>'int', 'row='=>'int', 'offset='=>'int'], +'sqlsrv_fetch_object' => ['object|null|false', 'stmt'=>'resource', 'className='=>'string', 'ctorParams='=>'array', 'row='=>'int', 'offset='=>'int'], +'sqlsrv_field_metadata' => ['array|false', 'stmt'=>'resource'], +'sqlsrv_free_stmt' => ['bool', 'stmt'=>'resource'], +'sqlsrv_get_config' => ['mixed', 'setting'=>'string'], +'sqlsrv_get_field' => ['mixed', 'stmt'=>'resource', 'fieldIndex'=>'int', 'getAsType='=>'int'], +'sqlsrv_has_rows' => ['bool', 'stmt'=>'resource'], +'sqlsrv_next_result' => ['bool|null', 'stmt'=>'resource'], +'sqlsrv_num_fields' => ['int|false', 'stmt'=>'resource'], +'sqlsrv_num_rows' => ['int|false', 'stmt'=>'resource'], +'sqlsrv_prepare' => ['resource|false', 'conn'=>'resource', 'sql'=>'string', 'params='=>'array', 'options='=>'array'], +'sqlsrv_query' => ['resource|false', 'conn'=>'resource', 'sql'=>'string', 'params='=>'array', 'options='=>'array'], +'sqlsrv_rollback' => ['bool', 'conn'=>'resource'], +'sqlsrv_rows_affected' => ['int|false', 'stmt'=>'resource'], +'sqlsrv_send_stream_data' => ['bool', 'stmt'=>'resource'], +'sqlsrv_server_info' => ['array', 'conn'=>'resource'], +'sqrt' => ['float', 'number'=>'float'], +'srand' => ['void', 'seed='=>'int', 'mode='=>'int'], +'sscanf' => ['mixed', 'str'=>'string', 'format'=>'string', '&...w_vars='=>'string|int|float|null'], +'ssdeep_fuzzy_compare' => ['int', 'signature1'=>'string', 'signature2'=>'string'], +'ssdeep_fuzzy_hash' => ['string', 'to_hash'=>'string'], +'ssdeep_fuzzy_hash_filename' => ['string', 'file_name'=>'string'], +'ssh2_auth_agent' => ['bool', 'session'=>'resource', 'username'=>'string'], +'ssh2_auth_hostbased_file' => ['bool', 'session'=>'resource', 'username'=>'string', 'hostname'=>'string', 'pubkeyfile'=>'string', 'privkeyfile'=>'string', 'passphrase='=>'string', 'local_username='=>'string'], +'ssh2_auth_none' => ['true|string[]', 'session'=>'resource', 'username'=>'string'], +'ssh2_auth_password' => ['bool', 'session'=>'resource', 'username'=>'string', 'password'=>'string'], +'ssh2_auth_pubkey_file' => ['bool', 'session'=>'resource', 'username'=>'string', 'pubkeyfile'=>'string', 'privkeyfile'=>'string', 'passphrase='=>'string'], +'ssh2_connect' => ['resource|false', 'host'=>'string', 'port='=>'int', 'methods='=>'array', 'callbacks='=>'array'], +'ssh2_disconnect' => ['bool', 'session'=>'resource'], +'ssh2_exec' => ['resource|false', 'session'=>'resource', 'command'=>'string', 'pty='=>'string', 'env='=>'array', 'width='=>'int', 'height='=>'int', 'width_height_type='=>'int'], +'ssh2_fetch_stream' => ['resource', 'channel'=>'resource', 'streamid'=>'int'], +'ssh2_fingerprint' => ['string', 'session'=>'resource', 'flags='=>'int'], +'ssh2_methods_negotiated' => ['array', 'session'=>'resource'], +'ssh2_publickey_add' => ['bool', 'pkey'=>'resource', 'algoname'=>'string', 'blob'=>'string', 'overwrite='=>'bool', 'attributes='=>'array'], +'ssh2_publickey_init' => ['resource|false', 'session'=>'resource'], +'ssh2_publickey_list' => ['array', 'pkey'=>'resource'], +'ssh2_publickey_remove' => ['bool', 'pkey'=>'resource', 'algoname'=>'string', 'blob'=>'string'], +'ssh2_scp_recv' => ['bool', 'session'=>'resource', 'remote_file'=>'string', 'local_file'=>'string'], +'ssh2_scp_send' => ['bool', 'session'=>'resource', 'local_file'=>'string', 'remote_file'=>'string', 'create_mode='=>'int'], +'ssh2_sftp' => ['resource', 'session'=>'resource'], +'ssh2_sftp_chmod' => ['bool', 'sftp'=>'resource', 'filename'=>'string', 'mode'=>'int'], +'ssh2_sftp_lstat' => ['array', 'sftp'=>'resource', 'path'=>'string'], +'ssh2_sftp_mkdir' => ['bool', 'sftp'=>'resource', 'dirname'=>'string', 'mode='=>'int', 'recursive='=>'bool'], +'ssh2_sftp_readlink' => ['string', 'sftp'=>'resource', 'link'=>'string'], +'ssh2_sftp_realpath' => ['string', 'sftp'=>'resource', 'filename'=>'string'], +'ssh2_sftp_rename' => ['bool', 'sftp'=>'resource', 'from'=>'string', 'to'=>'string'], +'ssh2_sftp_rmdir' => ['bool', 'sftp'=>'resource', 'dirname'=>'string'], +'ssh2_sftp_stat' => ['array|false', 'sftp'=>'resource', 'path'=>'string'], +'ssh2_sftp_symlink' => ['bool', 'sftp'=>'resource', 'target'=>'string', 'link'=>'string'], +'ssh2_sftp_unlink' => ['bool', 'sftp'=>'resource', 'filename'=>'string'], +'ssh2_shell' => ['resource', 'session'=>'resource', 'term_type='=>'string', 'env='=>'array', 'width='=>'int', 'height='=>'int', 'width_height_type='=>'int'], +'ssh2_tunnel' => ['resource', 'session'=>'resource', 'host'=>'string', 'port'=>'int'], +'stat' => ['array|false', 'filename'=>'string'], +'stats_absolute_deviation' => ['float', 'a'=>'array'], +'stats_cdf_beta' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_binomial' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_cauchy' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_chisquare' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'], +'stats_cdf_exponential' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'], +'stats_cdf_f' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_gamma' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_laplace' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_logistic' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_negative_binomial' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_noncentral_chisquare' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_noncentral_f' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'par4'=>'float', 'which'=>'int'], +'stats_cdf_noncentral_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_normal' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_poisson' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'], +'stats_cdf_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'which'=>'int'], +'stats_cdf_uniform' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_cdf_weibull' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_covariance' => ['float', 'a'=>'array', 'b'=>'array'], +'stats_den_uniform' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'], +'stats_dens_beta' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'], +'stats_dens_cauchy' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'], +'stats_dens_chisquare' => ['float', 'x'=>'float', 'dfr'=>'float'], +'stats_dens_exponential' => ['float', 'x'=>'float', 'scale'=>'float'], +'stats_dens_f' => ['float', 'x'=>'float', 'dfr1'=>'float', 'dfr2'=>'float'], +'stats_dens_gamma' => ['float', 'x'=>'float', 'shape'=>'float', 'scale'=>'float'], +'stats_dens_laplace' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'], +'stats_dens_logistic' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'], +'stats_dens_negative_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'], +'stats_dens_normal' => ['float', 'x'=>'float', 'ave'=>'float', 'stdev'=>'float'], +'stats_dens_pmf_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'], +'stats_dens_pmf_hypergeometric' => ['float', 'n1'=>'float', 'n2'=>'float', 'N1'=>'float', 'N2'=>'float'], +'stats_dens_pmf_negative_binomial' => ['float', 'x'=>'float', 'n'=>'float', 'pi'=>'float'], +'stats_dens_pmf_poisson' => ['float', 'x'=>'float', 'lb'=>'float'], +'stats_dens_t' => ['float', 'x'=>'float', 'dfr'=>'float'], +'stats_dens_uniform' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'], +'stats_dens_weibull' => ['float', 'x'=>'float', 'a'=>'float', 'b'=>'float'], +'stats_harmonic_mean' => ['float', 'a'=>'array'], +'stats_kurtosis' => ['float', 'a'=>'array'], +'stats_rand_gen_beta' => ['float', 'a'=>'float', 'b'=>'float'], +'stats_rand_gen_chisquare' => ['float', 'df'=>'float'], +'stats_rand_gen_exponential' => ['float', 'av'=>'float'], +'stats_rand_gen_f' => ['float', 'dfn'=>'float', 'dfd'=>'float'], +'stats_rand_gen_funiform' => ['float', 'low'=>'float', 'high'=>'float'], +'stats_rand_gen_gamma' => ['float', 'a'=>'float', 'r'=>'float'], +'stats_rand_gen_ibinomial' => ['int', 'n'=>'int', 'pp'=>'float'], +'stats_rand_gen_ibinomial_negative' => ['int', 'n'=>'int', 'p'=>'float'], +'stats_rand_gen_int' => ['int'], +'stats_rand_gen_ipoisson' => ['int', 'mu'=>'float'], +'stats_rand_gen_iuniform' => ['int', 'low'=>'int', 'high'=>'int'], +'stats_rand_gen_noncenral_chisquare' => ['float', 'df'=>'float', 'xnonc'=>'float'], +'stats_rand_gen_noncentral_chisquare' => ['float', 'df'=>'float', 'xnonc'=>'float'], +'stats_rand_gen_noncentral_f' => ['float', 'dfn'=>'float', 'dfd'=>'float', 'xnonc'=>'float'], +'stats_rand_gen_noncentral_t' => ['float', 'df'=>'float', 'xnonc'=>'float'], +'stats_rand_gen_normal' => ['float', 'av'=>'float', 'sd'=>'float'], +'stats_rand_gen_t' => ['float', 'df'=>'float'], +'stats_rand_get_seeds' => ['array'], +'stats_rand_phrase_to_seeds' => ['array', 'phrase'=>'string'], +'stats_rand_ranf' => ['float'], +'stats_rand_setall' => ['void', 'iseed1'=>'int', 'iseed2'=>'int'], +'stats_skew' => ['float', 'a'=>'array'], +'stats_standard_deviation' => ['float', 'a'=>'array', 'sample='=>'bool'], +'stats_stat_binomial_coef' => ['float', 'x'=>'int', 'n'=>'int'], +'stats_stat_correlation' => ['float', 'arr1'=>'array', 'arr2'=>'array'], +'stats_stat_factorial' => ['float', 'n'=>'int'], +'stats_stat_gennch' => ['float', 'n'=>'int'], +'stats_stat_independent_t' => ['float', 'arr1'=>'array', 'arr2'=>'array'], +'stats_stat_innerproduct' => ['float', 'arr1'=>'array', 'arr2'=>'array'], +'stats_stat_noncentral_t' => ['float', 'par1'=>'float', 'par2'=>'float', 'par3'=>'float', 'which'=>'int'], +'stats_stat_paired_t' => ['float', 'arr1'=>'array', 'arr2'=>'array'], +'stats_stat_percentile' => ['float', 'df'=>'float', 'xnonc'=>'float'], +'stats_stat_powersum' => ['float', 'arr'=>'array', 'power'=>'float'], +'stats_variance' => ['float', 'a'=>'array', 'sample='=>'bool'], +'Stomp::__construct' => ['void', 'broker='=>'string', 'username='=>'string', 'password='=>'string', 'headers='=>'array'], +'Stomp::__destruct' => ['bool', 'link'=>''], +'Stomp::abort' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], +'Stomp::ack' => ['bool', 'msg'=>'', 'headers='=>'array', 'link='=>''], +'Stomp::begin' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], +'Stomp::commit' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], +'Stomp::error' => ['string', 'link'=>''], +'Stomp::getReadTimeout' => ['array', 'link'=>''], +'Stomp::getSessionId' => ['string', 'link'=>''], +'Stomp::hasFrame' => ['bool', 'link'=>''], +'Stomp::readFrame' => ['array', 'class_name='=>'string', 'link='=>''], +'Stomp::send' => ['bool', 'destination'=>'string', 'msg'=>'', 'headers='=>'array', 'link='=>''], +'Stomp::setReadTimeout' => ['', 'seconds'=>'int', 'microseconds='=>'int', 'link='=>''], +'Stomp::subscribe' => ['bool', 'destination'=>'string', 'headers='=>'array', 'link='=>''], +'Stomp::unsubscribe' => ['bool', 'destination'=>'string', 'headers='=>'array', 'link='=>''], +'stomp_abort' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], +'stomp_ack' => ['bool', 'msg'=>'', 'headers='=>'array', 'link='=>''], +'stomp_begin' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], +'stomp_close' => ['bool', 'link'=>''], +'stomp_commit' => ['bool', 'transaction_id'=>'string', 'headers='=>'array', 'link='=>''], +'stomp_connect' => ['resource', 'broker='=>'string', 'username='=>'string', 'password='=>'string', 'headers='=>'array'], +'stomp_connect_error' => ['string'], +'stomp_error' => ['string', 'link'=>''], +'stomp_get_read_timeout' => ['array', 'link'=>''], +'stomp_get_session_id' => ['string', 'link'=>''], +'stomp_has_frame' => ['bool', 'link'=>''], +'stomp_read_frame' => ['array', 'class_name='=>'string', 'link='=>''], +'stomp_send' => ['bool', 'destination'=>'string', 'msg'=>'', 'headers='=>'array', 'link='=>''], +'stomp_set_read_timeout' => ['', 'seconds'=>'int', 'microseconds='=>'int', 'link='=>''], +'stomp_subscribe' => ['bool', 'destination'=>'string', 'headers='=>'array', 'link='=>''], +'stomp_unsubscribe' => ['bool', 'destination'=>'string', 'headers='=>'array', 'link='=>''], +'stomp_version' => ['string'], +'StompException::getDetails' => ['string'], +'StompFrame::__construct' => ['void', 'command='=>'string', 'headers='=>'array', 'body='=>'string'], +'str_getcsv' => ['array', 'input'=>'string', 'delimiter='=>'string', 'enclosure='=>'string', 'escape='=>'string'], +'str_ireplace' => ['string|string[]', 'search'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', '&w_replace_count='=>'int'], +'str_pad' => ['string', 'input'=>'string', 'pad_length'=>'int', 'pad_string='=>'string', 'pad_type='=>'int'], +'str_repeat' => ['string', 'input'=>'string', 'multiplier'=>'int'], +'str_replace' => ['string|array', 'search'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', '&w_replace_count='=>'int'], +'str_rot13' => ['string', 'str'=>'string'], +'str_shuffle' => ['string', 'str'=>'string'], +'str_split' => ['array|false', 'str'=>'string', 'split_length='=>'int'], +'str_word_count' => ['array|int', 'string'=>'string', 'format='=>'int', 'charlist='=>'string'], +'strcasecmp' => ['int', 'str1'=>'string', 'str2'=>'string'], +'strchr' => ['string|false', 'haystack'=>'string', 'needle'=>'string', 'before_needle='=>'bool'], +'strcmp' => ['int', 'str1'=>'string', 'str2'=>'string'], +'strcoll' => ['int', 'str1'=>'string', 'str2'=>'string'], +'strcspn' => ['int', 'str'=>'string', 'mask'=>'string', 'start='=>'int', 'length='=>'int'], +'stream_bucket_append' => ['void', 'brigade'=>'resource', 'bucket'=>'object'], +'stream_bucket_make_writeable' => ['object', 'brigade'=>'resource'], +'stream_bucket_new' => ['resource', 'stream'=>'resource', 'buffer'=>'string'], +'stream_bucket_prepend' => ['void', 'brigade'=>'resource', 'bucket'=>'object'], +'stream_context_create' => ['resource', 'options='=>'array', 'params='=>'array'], +'stream_context_get_default' => ['resource', 'options='=>'array'], +'stream_context_get_options' => ['array', 'context'=>'resource'], +'stream_context_get_params' => ['array', 'context'=>'resource'], +'stream_context_set_default' => ['resource', 'options'=>'array'], +'stream_context_set_option' => ['bool', 'context'=>'', 'wrappername'=>'string', 'optionname'=>'string', 'value'=>''], +'stream_context_set_option\'1' => ['bool', 'context'=>'', 'options'=>'array'], +'stream_context_set_params' => ['bool', 'context'=>'resource', 'options'=>'array'], +'stream_copy_to_stream' => ['int|false', 'source'=>'resource', 'dest'=>'resource', 'maxlen='=>'int', 'pos='=>'int'], +'stream_encoding' => ['bool', 'stream'=>'resource', 'encoding='=>'string'], +'stream_filter_append' => ['resource|false', 'stream'=>'resource', 'filtername'=>'string', 'read_write='=>'int', 'filterparams='=>'array'], +'stream_filter_prepend' => ['resource|false', 'stream'=>'resource', 'filtername'=>'string', 'read_write='=>'int', 'filterparams='=>'array'], +'stream_filter_register' => ['bool', 'filtername'=>'string', 'classname'=>'string'], +'stream_filter_remove' => ['bool', 'stream_filter'=>'resource'], +'stream_get_contents' => ['string|false', 'source'=>'resource', 'maxlen='=>'int', 'offset='=>'int'], +'stream_get_filters' => ['array'], +'stream_get_line' => ['string|false', 'stream'=>'resource', 'maxlen'=>'int', 'ending='=>'string'], +'stream_get_meta_data' => ['array', 'fp'=>'resource'], +'stream_get_transports' => ['array'], +'stream_get_wrappers' => ['array'], +'stream_is_local' => ['bool', 'stream'=>'resource|string'], +'stream_isatty' => ['bool', 'stream'=>'resource'], +'stream_notification_callback' => ['callback', 'notification_code'=>'int', 'severity'=>'int', 'message'=>'string', 'message_code'=>'int', 'bytes_transferred'=>'int', 'bytes_max'=>'int'], +'stream_resolve_include_path' => ['string|false', 'filename'=>'string'], +'stream_select' => ['int|false', '&rw_read_streams'=>'resource[]', '&rw_write_streams'=>'?resource[]', '&rw_except_streams'=>'?resource[]', 'tv_sec'=>'?int', 'tv_usec='=>'?int'], +'stream_set_blocking' => ['bool', 'socket'=>'resource', 'mode'=>'bool'], +'stream_set_chunk_size' => ['int|false', 'fp'=>'resource', 'chunk_size'=>'int'], +'stream_set_read_buffer' => ['int', 'fp'=>'resource', 'buffer'=>'int'], +'stream_set_timeout' => ['bool', 'stream'=>'resource', 'seconds'=>'int', 'microseconds='=>'int'], +'stream_set_write_buffer' => ['int', 'fp'=>'resource', 'buffer'=>'int'], +'stream_socket_accept' => ['resource|false', 'serverstream'=>'resource', 'timeout='=>'float', '&w_peername='=>'string'], +'stream_socket_client' => ['resource|false', 'remoteaddress'=>'string', '&w_errcode='=>'int', '&w_errstring='=>'string', 'timeout='=>'float', 'flags='=>'int', 'context='=>'resource'], +'stream_socket_enable_crypto' => ['int', 'stream'=>'resource', 'enable'=>'bool', 'cryptokind='=>'int', 'sessionstream='=>'resource'], +'stream_socket_get_name' => ['string', 'stream'=>'resource', 'want_peer'=>'bool'], +'stream_socket_pair' => ['resource[]|false', 'domain'=>'int', 'type'=>'int', 'protocol'=>'int'], +'stream_socket_recvfrom' => ['string', 'stream'=>'resource', 'amount'=>'int', 'flags='=>'int', '&w_remote_addr='=>'string'], +'stream_socket_sendto' => ['int', 'stream'=>'resource', 'data'=>'string', 'flags='=>'int', 'target_addr='=>'string'], +'stream_socket_server' => ['resource|false', 'localaddress'=>'string', '&w_errcode='=>'int', '&w_errstring='=>'string', 'flags='=>'int', 'context='=>'resource'], +'stream_socket_shutdown' => ['bool', 'stream'=>'resource', 'how'=>'int'], +'stream_supports_lock' => ['bool', 'stream'=>'resource'], +'stream_wrapper_register' => ['bool', 'protocol'=>'string', 'classname'=>'string', 'flags='=>'int'], +'stream_wrapper_restore' => ['bool', 'protocol'=>'string'], +'stream_wrapper_unregister' => ['bool', 'protocol'=>'string'], +'streamWrapper::__construct' => ['void'], +'streamWrapper::__destruct' => [''], +'streamWrapper::dir_closedir' => ['bool'], +'streamWrapper::dir_opendir' => ['bool', 'path'=>'string', 'options'=>'int'], +'streamWrapper::dir_readdir' => ['string'], +'streamWrapper::dir_rewinddir' => ['bool'], +'streamWrapper::mkdir' => ['bool', 'path'=>'string', 'mode'=>'int', 'options'=>'int'], +'streamWrapper::rename' => ['bool', 'path_from'=>'string', 'path_to'=>'string'], +'streamWrapper::rmdir' => ['bool', 'path'=>'string', 'options'=>'int'], +'streamWrapper::stream_cast' => ['resource', 'cast_as'=>'int'], +'streamWrapper::stream_close' => ['void'], +'streamWrapper::stream_eof' => ['bool'], +'streamWrapper::stream_flush' => ['bool'], +'streamWrapper::stream_lock' => ['bool', 'operation'=>'mode'], +'streamWrapper::stream_metadata' => ['bool', 'path'=>'string', 'option'=>'int', 'value'=>'mixed'], +'streamWrapper::stream_open' => ['bool', 'path'=>'string', 'mode'=>'string', 'options'=>'int', 'opened_path'=>'string'], +'streamWrapper::stream_read' => ['string', 'count'=>'int'], +'streamWrapper::stream_seek' => ['bool', 'offset'=>'int', 'whence'=>'int'], +'streamWrapper::stream_set_option' => ['bool', 'option'=>'int', 'arg1'=>'int', 'arg2'=>'int'], +'streamWrapper::stream_stat' => ['array'], +'streamWrapper::stream_tell' => ['int'], +'streamWrapper::stream_truncate' => ['bool', 'new_size'=>'int'], +'streamWrapper::stream_write' => ['int', 'data'=>'string'], +'streamWrapper::unlink' => ['bool', 'path'=>'string'], +'streamWrapper::url_stat' => ['array', 'path'=>'string', 'flags'=>'int'], +'strftime' => ['string', 'format'=>'string', 'timestamp='=>'int'], +'strip_tags' => ['string', 'str'=>'string', 'allowable_tags='=>'string'], +'stripcslashes' => ['string', 'str'=>'string'], +'stripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], +'stripslashes' => ['string', 'str'=>'string'], +'stristr' => ['string|false', 'haystack'=>'string', 'needle'=>'mixed', 'before_needle='=>'bool'], +'strlen' => ['int', 'string'=>'string'], +'strnatcasecmp' => ['int', 's1'=>'string', 's2'=>'string'], +'strnatcmp' => ['int', 's1'=>'string', 's2'=>'string'], +'strncasecmp' => ['int', 'str1'=>'string', 'str2'=>'string', 'len'=>'int'], +'strncmp' => ['int', 'str1'=>'string', 'str2'=>'string', 'len'=>'int'], +'strpbrk' => ['string|false', 'haystack'=>'string', 'char_list'=>'string'], +'strpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], +'strptime' => ['array|false', 'datestr'=>'string', 'format'=>'string'], +'strrchr' => ['string|false', 'haystack'=>'string', 'needle'=>'mixed'], +'strrev' => ['string', 'str'=>'string'], +'strripos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], +'strrpos' => ['int|false', 'haystack'=>'string', 'needle'=>'string|int', 'offset='=>'int'], +'strspn' => ['int', 'str'=>'string', 'mask'=>'string', 'start='=>'int', 'len='=>'int'], +'strstr' => ['string|false', 'haystack'=>'string', 'needle'=>'mixed', 'before_needle='=>'bool'], +'strtok' => ['string|false', 'str'=>'string', 'token'=>'string'], +'strtok\'1' => ['string|false', 'token'=>'string'], +'strtolower' => ['string', 'str'=>'string'], +'strtotime' => ['int|false', 'time'=>'string', 'now='=>'int'], +'strtoupper' => ['string', 'str'=>'string'], +'strtr' => ['string', 'str'=>'string', 'from'=>'string', 'to'=>'string'], +'strtr\'1' => ['string', 'str'=>'string', 'replace_pairs'=>'array'], +'strval' => ['string', 'var'=>'mixed'], +'substr' => ['string', 'str'=>'string', 'start'=>'int', 'length='=>'int'], +'substr_compare' => ['int|false', 'main_str'=>'string', 'str'=>'string', 'offset'=>'int', 'length='=>'int', 'case_sensitivity='=>'bool'], +'substr_count' => ['int', 'haystack'=>'string', 'needle'=>'string', 'offset='=>'int', 'length='=>'int'], +'substr_replace' => ['string|array', 'str'=>'string|array', 'repl'=>'mixed', 'start'=>'mixed', 'length='=>'mixed'], +'suhosin_encrypt_cookie' => ['string', 'name'=>'string', 'value'=>'string'], +'suhosin_get_raw_cookies' => ['array'], +'SVM::__construct' => ['void'], +'svm::crossvalidate' => ['float', 'problem'=>'array', 'number_of_folds'=>'int'], +'SVM::getOptions' => ['array'], +'SVM::setOptions' => ['bool', 'params'=>'array'], +'svm::train' => ['SVMModel', 'problem'=>'array', 'weights='=>'array'], +'SVMModel::__construct' => ['void', 'filename='=>'string'], +'SVMModel::checkProbabilityModel' => ['bool'], +'SVMModel::getLabels' => ['array'], +'SVMModel::getNrClass' => ['int'], +'SVMModel::getSvmType' => ['int'], +'SVMModel::getSvrProbability' => ['float'], +'SVMModel::load' => ['bool', 'filename'=>'string'], +'SVMModel::predict' => ['float', 'data'=>'array'], +'SVMModel::predict_probability' => ['float', 'data'=>'array'], +'SVMModel::save' => ['bool', 'filename'=>'string'], +'svn_add' => ['bool', 'path'=>'string', 'recursive='=>'bool', 'force='=>'bool'], +'svn_auth_get_parameter' => ['string', 'key'=>'string'], +'svn_auth_set_parameter' => ['void', 'key'=>'string', 'value'=>'string'], +'svn_blame' => ['array', 'repository_url'=>'string', 'revision_no='=>'int'], +'svn_cat' => ['string', 'repos_url'=>'string', 'revision_no='=>'int'], +'svn_checkout' => ['bool', 'repos'=>'string', 'targetpath'=>'string', 'revision='=>'int', 'flags='=>'int'], +'svn_cleanup' => ['bool', 'workingdir'=>'string'], +'svn_client_version' => ['string'], +'svn_commit' => ['array', 'log'=>'string', 'targets'=>'array', 'dontrecurse='=>'bool'], +'svn_delete' => ['bool', 'path'=>'string', 'force='=>'bool'], +'svn_diff' => ['array', 'path1'=>'string', 'rev1'=>'int', 'path2'=>'string', 'rev2'=>'int'], +'svn_export' => ['bool', 'frompath'=>'string', 'topath'=>'string', 'working_copy='=>'bool', 'revision_no='=>'int'], +'svn_fs_abort_txn' => ['bool', 'txn'=>'resource'], +'svn_fs_apply_text' => ['resource', 'root'=>'resource', 'path'=>'string'], +'svn_fs_begin_txn2' => ['resource', 'repos'=>'resource', 'rev'=>'int'], +'svn_fs_change_node_prop' => ['bool', 'root'=>'resource', 'path'=>'string', 'name'=>'string', 'value'=>'string'], +'svn_fs_check_path' => ['int', 'fsroot'=>'resource', 'path'=>'string'], +'svn_fs_contents_changed' => ['bool', 'root1'=>'resource', 'path1'=>'string', 'root2'=>'resource', 'path2'=>'string'], +'svn_fs_copy' => ['bool', 'from_root'=>'resource', 'from_path'=>'string', 'to_root'=>'resource', 'to_path'=>'string'], +'svn_fs_delete' => ['bool', 'root'=>'resource', 'path'=>'string'], +'svn_fs_dir_entries' => ['array', 'fsroot'=>'resource', 'path'=>'string'], +'svn_fs_file_contents' => ['resource', 'fsroot'=>'resource', 'path'=>'string'], +'svn_fs_file_length' => ['int', 'fsroot'=>'resource', 'path'=>'string'], +'svn_fs_is_dir' => ['bool', 'root'=>'resource', 'path'=>'string'], +'svn_fs_is_file' => ['bool', 'root'=>'resource', 'path'=>'string'], +'svn_fs_make_dir' => ['bool', 'root'=>'resource', 'path'=>'string'], +'svn_fs_make_file' => ['bool', 'root'=>'resource', 'path'=>'string'], +'svn_fs_node_created_rev' => ['int', 'fsroot'=>'resource', 'path'=>'string'], +'svn_fs_node_prop' => ['string', 'fsroot'=>'resource', 'path'=>'string', 'propname'=>'string'], +'svn_fs_props_changed' => ['bool', 'root1'=>'resource', 'path1'=>'string', 'root2'=>'resource', 'path2'=>'string'], +'svn_fs_revision_prop' => ['string', 'fs'=>'resource', 'revnum'=>'int', 'propname'=>'string'], +'svn_fs_revision_root' => ['resource', 'fs'=>'resource', 'revnum'=>'int'], +'svn_fs_txn_root' => ['resource', 'txn'=>'resource'], +'svn_fs_youngest_rev' => ['int', 'fs'=>'resource'], +'svn_import' => ['bool', 'path'=>'string', 'url'=>'string', 'nonrecursive'=>'bool'], +'svn_log' => ['array', 'repos_url'=>'string', 'start_revision='=>'int', 'end_revision='=>'int', 'limit='=>'int', 'flags='=>'int'], +'svn_ls' => ['array', 'repos_url'=>'string', 'revision_no='=>'int', 'recurse='=>'bool', 'peg='=>'bool'], +'svn_mkdir' => ['bool', 'path'=>'string', 'log_message='=>'string'], +'svn_move' => ['mixed', 'src_path'=>'string', 'dst_path'=>'string', 'force='=>'bool|false'], +'svn_propget' => ['mixed', 'path'=>'string', 'property_name'=>'string', 'recurse='=>'bool|false', 'revision'=>'int'], +'svn_proplist' => ['mixed', 'path'=>'string', 'recurse='=>'bool|false', 'revision'=>'int'], +'svn_repos_create' => ['resource', 'path'=>'string', 'config='=>'array', 'fsconfig='=>'array'], +'svn_repos_fs' => ['resource', 'repos'=>'resource'], +'svn_repos_fs_begin_txn_for_commit' => ['resource', 'repos'=>'resource', 'rev'=>'int', 'author'=>'string', 'log_msg'=>'string'], +'svn_repos_fs_commit_txn' => ['int', 'txn'=>'resource'], +'svn_repos_hotcopy' => ['bool', 'repospath'=>'string', 'destpath'=>'string', 'cleanlogs'=>'bool'], +'svn_repos_open' => ['resource', 'path'=>'string'], +'svn_repos_recover' => ['bool', 'path'=>'string'], +'svn_revert' => ['bool', 'path'=>'string', 'recursive='=>'bool'], +'svn_status' => ['array', 'path'=>'string', 'flags='=>'int'], +'svn_update' => ['int', 'path'=>'string', 'revno='=>'int', 'recurse='=>'bool'], +'swf_actiongeturl' => ['', 'url'=>'string', 'target'=>'string'], +'swf_actiongotoframe' => ['', 'framenumber'=>'int'], +'swf_actiongotolabel' => ['', 'label'=>'string'], +'swf_actionnextframe' => [''], +'swf_actionplay' => [''], +'swf_actionprevframe' => [''], +'swf_actionsettarget' => ['', 'target'=>'string'], +'swf_actionstop' => [''], +'swf_actiontogglequality' => [''], +'swf_actionwaitforframe' => ['', 'framenumber'=>'int', 'skipcount'=>'int'], +'swf_addbuttonrecord' => ['', 'states'=>'int', 'shapeid'=>'int', 'depth'=>'int'], +'swf_addcolor' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'], +'swf_closefile' => ['', 'return_file='=>'int'], +'swf_definebitmap' => ['', 'objid'=>'int', 'image_name'=>'string'], +'swf_definefont' => ['', 'fontid'=>'int', 'fontname'=>'string'], +'swf_defineline' => ['', 'objid'=>'int', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'width'=>'float'], +'swf_definepoly' => ['', 'objid'=>'int', 'coords'=>'array', 'npoints'=>'int', 'width'=>'float'], +'swf_definerect' => ['', 'objid'=>'int', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'width'=>'float'], +'swf_definetext' => ['', 'objid'=>'int', 'str'=>'string', 'docenter'=>'int'], +'swf_endbutton' => [''], +'swf_enddoaction' => [''], +'swf_endshape' => [''], +'swf_endsymbol' => [''], +'swf_fontsize' => ['', 'size'=>'float'], +'swf_fontslant' => ['', 'slant'=>'float'], +'swf_fonttracking' => ['', 'tracking'=>'float'], +'swf_getbitmapinfo' => ['array', 'bitmapid'=>'int'], +'swf_getfontinfo' => ['array'], +'swf_getframe' => ['int'], +'swf_labelframe' => ['', 'name'=>'string'], +'swf_lookat' => ['', 'view_x'=>'float', 'view_y'=>'float', 'view_z'=>'float', 'reference_x'=>'float', 'reference_y'=>'float', 'reference_z'=>'float', 'twist'=>'float'], +'swf_modifyobject' => ['', 'depth'=>'int', 'how'=>'int'], +'swf_mulcolor' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'], +'swf_nextid' => ['int'], +'swf_oncondition' => ['', 'transition'=>'int'], +'swf_openfile' => ['', 'filename'=>'string', 'width'=>'float', 'height'=>'float', 'framerate'=>'float', 'r'=>'float', 'g'=>'float', 'b'=>'float'], +'swf_ortho' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float', 'zmin'=>'float', 'zmax'=>'float'], +'swf_ortho2' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float'], +'swf_perspective' => ['', 'fovy'=>'float', 'aspect'=>'float', 'near'=>'float', 'far'=>'float'], +'swf_placeobject' => ['', 'objid'=>'int', 'depth'=>'int'], +'swf_polarview' => ['', 'dist'=>'float', 'azimuth'=>'float', 'incidence'=>'float', 'twist'=>'float'], +'swf_popmatrix' => [''], +'swf_posround' => ['', 'round'=>'int'], +'swf_pushmatrix' => [''], +'swf_removeobject' => ['', 'depth'=>'int'], +'swf_rotate' => ['', 'angle'=>'float', 'axis'=>'string'], +'swf_scale' => ['', 'x'=>'float', 'y'=>'float', 'z'=>'float'], +'swf_setfont' => ['', 'fontid'=>'int'], +'swf_setframe' => ['', 'framenumber'=>'int'], +'swf_shapearc' => ['', 'x'=>'float', 'y'=>'float', 'r'=>'float', 'ang1'=>'float', 'ang2'=>'float'], +'swf_shapecurveto' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float'], +'swf_shapecurveto3' => ['', 'x1'=>'float', 'y1'=>'float', 'x2'=>'float', 'y2'=>'float', 'x3'=>'float', 'y3'=>'float'], +'swf_shapefillbitmapclip' => ['', 'bitmapid'=>'int'], +'swf_shapefillbitmaptile' => ['', 'bitmapid'=>'int'], +'swf_shapefilloff' => [''], +'swf_shapefillsolid' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float'], +'swf_shapelinesolid' => ['', 'r'=>'float', 'g'=>'float', 'b'=>'float', 'a'=>'float', 'width'=>'float'], +'swf_shapelineto' => ['', 'x'=>'float', 'y'=>'float'], +'swf_shapemoveto' => ['', 'x'=>'float', 'y'=>'float'], +'swf_showframe' => [''], +'swf_startbutton' => ['', 'objid'=>'int', 'type'=>'int'], +'swf_startdoaction' => [''], +'swf_startshape' => ['', 'objid'=>'int'], +'swf_startsymbol' => ['', 'objid'=>'int'], +'swf_textwidth' => ['float', 'str'=>'string'], +'swf_translate' => ['', 'x'=>'float', 'y'=>'float', 'z'=>'float'], +'swf_viewport' => ['', 'xmin'=>'float', 'xmax'=>'float', 'ymin'=>'float', 'ymax'=>'float'], +'SWFAction::__construct' => ['void', 'script'=>'string'], +'SWFBitmap::__construct' => ['void', 'file'=>'', 'alphafile='=>''], +'SWFBitmap::getHeight' => ['float'], +'SWFBitmap::getWidth' => ['float'], +'SWFButton::__construct' => ['void'], +'SWFButton::addAction' => ['void', 'action'=>'swfaction', 'flags'=>'int'], +'SWFButton::addASound' => ['SWFSoundInstance', 'sound'=>'swfsound', 'flags'=>'int'], +'SWFButton::addShape' => ['void', 'shape'=>'swfshape', 'flags'=>'int'], +'SWFButton::setAction' => ['void', 'action'=>'swfaction'], +'SWFButton::setDown' => ['void', 'shape'=>'swfshape'], +'SWFButton::setHit' => ['void', 'shape'=>'swfshape'], +'SWFButton::setMenu' => ['void', 'flag'=>'int'], +'SWFButton::setOver' => ['void', 'shape'=>'swfshape'], +'SWFButton::setUp' => ['void', 'shape'=>'swfshape'], +'SWFDisplayItem::addAction' => ['void', 'action'=>'swfaction', 'flags'=>'int'], +'SWFDisplayItem::addColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'SWFDisplayItem::endMask' => ['void'], +'SWFDisplayItem::getRot' => ['float'], +'SWFDisplayItem::getX' => ['float'], +'SWFDisplayItem::getXScale' => ['float'], +'SWFDisplayItem::getXSkew' => ['float'], +'SWFDisplayItem::getY' => ['float'], +'SWFDisplayItem::getYScale' => ['float'], +'SWFDisplayItem::getYSkew' => ['float'], +'SWFDisplayItem::move' => ['void', 'dx'=>'float', 'dy'=>'float'], +'SWFDisplayItem::moveTo' => ['void', 'x'=>'float', 'y'=>'float'], +'SWFDisplayItem::multColor' => ['void', 'red'=>'float', 'green'=>'float', 'blue'=>'float', 'a='=>'float'], +'SWFDisplayItem::remove' => ['void'], +'SWFDisplayItem::rotate' => ['void', 'angle'=>'float'], +'SWFDisplayItem::rotateTo' => ['void', 'angle'=>'float'], +'SWFDisplayItem::scale' => ['void', 'dx'=>'float', 'dy'=>'float'], +'SWFDisplayItem::scaleTo' => ['void', 'x'=>'float', 'y='=>'float'], +'SWFDisplayItem::setDepth' => ['void', 'depth'=>'int'], +'SWFDisplayItem::setMaskLevel' => ['void', 'level'=>'int'], +'SWFDisplayItem::setMatrix' => ['void', 'a'=>'float', 'b'=>'float', 'c'=>'float', 'd'=>'float', 'x'=>'float', 'y'=>'float'], +'SWFDisplayItem::setName' => ['void', 'name'=>'string'], +'SWFDisplayItem::setRatio' => ['void', 'ratio'=>'float'], +'SWFDisplayItem::skewX' => ['void', 'ddegrees'=>'float'], +'SWFDisplayItem::skewXTo' => ['void', 'degrees'=>'float'], +'SWFDisplayItem::skewY' => ['void', 'ddegrees'=>'float'], +'SWFDisplayItem::skewYTo' => ['void', 'degrees'=>'float'], +'SWFFill::moveTo' => ['void', 'x'=>'float', 'y'=>'float'], +'SWFFill::rotateTo' => ['void', 'angle'=>'float'], +'SWFFill::scaleTo' => ['void', 'x'=>'float', 'y='=>'float'], +'SWFFill::skewXTo' => ['void', 'x'=>'float'], +'SWFFill::skewYTo' => ['void', 'y'=>'float'], +'SWFFont::__construct' => ['void', 'filename'=>'string'], +'SWFFont::getAscent' => ['float'], +'SWFFont::getDescent' => ['float'], +'SWFFont::getLeading' => ['float'], +'SWFFont::getShape' => ['string', 'code'=>'int'], +'SWFFont::getUTF8Width' => ['float', 'string'=>'string'], +'SWFFont::getWidth' => ['float', 'string'=>'string'], +'SWFFontChar::addChars' => ['void', 'char'=>'string'], +'SWFFontChar::addUTF8Chars' => ['void', 'char'=>'string'], +'SWFGradient::__construct' => ['void'], +'SWFGradient::addEntry' => ['void', 'ratio'=>'float', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int'], +'SWFMorph::__construct' => ['void'], +'SWFMorph::getShape1' => ['SWFShape'], +'SWFMorph::getShape2' => ['SWFShape'], +'SWFMovie::__construct' => ['void', 'version='=>'int'], +'SWFMovie::add' => ['mixed', 'instance'=>'object'], +'SWFMovie::addExport' => ['void', 'char'=>'swfcharacter', 'name'=>'string'], +'SWFMovie::addFont' => ['mixed', 'font'=>'swffont'], +'SWFMovie::importChar' => ['SWFSprite', 'libswf'=>'string', 'name'=>'string'], +'SWFMovie::importFont' => ['SWFFontChar', 'libswf'=>'string', 'name'=>'string'], +'SWFMovie::labelFrame' => ['void', 'label'=>'string'], +'SWFMovie::nextFrame' => ['void'], +'SWFMovie::output' => ['int', 'compression='=>'int'], +'SWFMovie::remove' => ['void', 'instance'=>'object'], +'SWFMovie::save' => ['int', 'filename'=>'string', 'compression='=>'int'], +'SWFMovie::saveToFile' => ['int', 'x'=>'resource', 'compression='=>'int'], +'SWFMovie::setbackground' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int'], +'SWFMovie::setDimension' => ['void', 'width'=>'float', 'height'=>'float'], +'SWFMovie::setFrames' => ['void', 'number'=>'int'], +'SWFMovie::setRate' => ['void', 'rate'=>'float'], +'SWFMovie::startSound' => ['SWFSoundInstance', 'sound'=>'swfsound'], +'SWFMovie::stopSound' => ['void', 'sound'=>'swfsound'], +'SWFMovie::streamMP3' => ['int', 'mp3file'=>'mixed', 'skip='=>'float'], +'SWFMovie::writeExports' => ['void'], +'SWFPrebuiltClip::__construct' => ['void', 'file'=>''], +'SWFShape::__construct' => ['void'], +'SWFShape::addFill' => ['SWFFill', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'alpha='=>'int', 'bitmap='=>'swfbitmap', 'flags='=>'int', 'gradient='=>'swfgradient'], +'SWFShape::addFill\'1' => ['SWFFill', 'bitmap'=>'SWFBitmap', 'flags='=>'int'], +'SWFShape::addFill\'2' => ['SWFFill', 'gradient'=>'SWFGradient', 'flags='=>'int'], +'SWFShape::drawArc' => ['void', 'r'=>'float', 'startangle'=>'float', 'endangle'=>'float'], +'SWFShape::drawCircle' => ['void', 'r'=>'float'], +'SWFShape::drawCubic' => ['int', 'bx'=>'float', 'by'=>'float', 'cx'=>'float', 'cy'=>'float', 'dx'=>'float', 'dy'=>'float'], +'SWFShape::drawCubicTo' => ['int', 'bx'=>'float', 'by'=>'float', 'cx'=>'float', 'cy'=>'float', 'dx'=>'float', 'dy'=>'float'], +'SWFShape::drawCurve' => ['int', 'controldx'=>'float', 'controldy'=>'float', 'anchordx'=>'float', 'anchordy'=>'float', 'targetdx='=>'float', 'targetdy='=>'float'], +'SWFShape::drawCurveTo' => ['int', 'controlx'=>'float', 'controly'=>'float', 'anchorx'=>'float', 'anchory'=>'float', 'targetx='=>'float', 'targety='=>'float'], +'SWFShape::drawGlyph' => ['void', 'font'=>'swffont', 'character'=>'string', 'size='=>'int'], +'SWFShape::drawLine' => ['void', 'dx'=>'float', 'dy'=>'float'], +'SWFShape::drawLineTo' => ['void', 'x'=>'float', 'y'=>'float'], +'SWFShape::movePen' => ['void', 'dx'=>'float', 'dy'=>'float'], +'SWFShape::movePenTo' => ['void', 'x'=>'float', 'y'=>'float'], +'SWFShape::setLeftFill' => ['', 'fill'=>'swfgradient', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'SWFShape::setLine' => ['', 'shape'=>'swfshape', 'width'=>'int', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'SWFShape::setRightFill' => ['', 'fill'=>'swfgradient', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'SWFSound' => ['SWFSound', 'filename'=>'string', 'flags='=>'int'], +'SWFSound::__construct' => ['void', 'filename'=>'string', 'flags='=>'int'], +'SWFSoundInstance::loopCount' => ['void', 'point'=>'int'], +'SWFSoundInstance::loopInPoint' => ['void', 'point'=>'int'], +'SWFSoundInstance::loopOutPoint' => ['void', 'point'=>'int'], +'SWFSoundInstance::noMultiple' => ['void'], +'SWFSprite::__construct' => ['void'], +'SWFSprite::add' => ['void', 'object'=>'object'], +'SWFSprite::labelFrame' => ['void', 'label'=>'string'], +'SWFSprite::nextFrame' => ['void'], +'SWFSprite::remove' => ['void', 'object'=>'object'], +'SWFSprite::setFrames' => ['void', 'number'=>'int'], +'SWFSprite::startSound' => ['SWFSoundInstance', 'sount'=>'swfsound'], +'SWFSprite::stopSound' => ['void', 'sount'=>'swfsound'], +'SWFText::__construct' => ['void'], +'SWFText::addString' => ['void', 'string'=>'string'], +'SWFText::addUTF8String' => ['void', 'text'=>'string'], +'SWFText::getAscent' => ['float'], +'SWFText::getDescent' => ['float'], +'SWFText::getLeading' => ['float'], +'SWFText::getUTF8Width' => ['float', 'string'=>'string'], +'SWFText::getWidth' => ['float', 'string'=>'string'], +'SWFText::moveTo' => ['void', 'x'=>'float', 'y'=>'float'], +'SWFText::setColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'SWFText::setFont' => ['void', 'font'=>'swffont'], +'SWFText::setHeight' => ['void', 'height'=>'float'], +'SWFText::setSpacing' => ['void', 'spacing'=>'float'], +'SWFTextField::__construct' => ['void', 'flags='=>'int'], +'SWFTextField::addChars' => ['void', 'chars'=>'string'], +'SWFTextField::addString' => ['void', 'string'=>'string'], +'SWFTextField::align' => ['void', 'alignement'=>'int'], +'SWFTextField::setBounds' => ['void', 'width'=>'float', 'height'=>'float'], +'SWFTextField::setColor' => ['void', 'red'=>'int', 'green'=>'int', 'blue'=>'int', 'a='=>'int'], +'SWFTextField::setFont' => ['void', 'font'=>'swffont'], +'SWFTextField::setHeight' => ['void', 'height'=>'float'], +'SWFTextField::setIndentation' => ['void', 'width'=>'float'], +'SWFTextField::setLeftMargin' => ['void', 'width'=>'float'], +'SWFTextField::setLineSpacing' => ['void', 'height'=>'float'], +'SWFTextField::setMargins' => ['void', 'left'=>'float', 'right'=>'float'], +'SWFTextField::setName' => ['void', 'name'=>'string'], +'SWFTextField::setPadding' => ['void', 'padding'=>'float'], +'SWFTextField::setRightMargin' => ['void', 'width'=>'float'], +'SWFVideoStream::__construct' => ['void', 'file='=>'string'], +'SWFVideoStream::getNumFrames' => ['int'], +'SWFVideoStream::setDimension' => ['void', 'x'=>'int', 'y'=>'int'], +'Swish::__construct' => ['void', 'index_names'=>'string'], +'Swish::getMetaList' => ['array', 'index_name'=>'string'], +'Swish::getPropertyList' => ['array', 'index_name'=>'string'], +'Swish::prepare' => ['object', 'query='=>'string'], +'Swish::query' => ['object', 'query'=>'string'], +'SwishResult::getMetaList' => ['array'], +'SwishResult::stem' => ['array', 'word'=>'string'], +'SwishResults::getParsedWords' => ['array', 'index_name'=>'string'], +'SwishResults::getRemovedStopwords' => ['array', 'index_name'=>'string'], +'SwishResults::nextResult' => ['object'], +'SwishResults::seekResult' => ['int', 'position'=>'int'], +'SwishSearch::execute' => ['object', 'query='=>'string'], +'SwishSearch::resetLimit' => [''], +'SwishSearch::setLimit' => ['', 'property'=>'string', 'low'=>'string', 'high'=>'string'], +'SwishSearch::setPhraseDelimiter' => ['', 'delimiter'=>'string'], +'SwishSearch::setSort' => ['', 'sort'=>'string'], +'SwishSearch::setStructure' => ['', 'structure'=>'int'], +'swoole_async_dns_lookup' => ['bool', 'hostname'=>'string', 'callback'=>'callable'], +'swoole_async_read' => ['bool', 'filename'=>'string', 'callback'=>'callable', 'chunk_size='=>'int', 'offset='=>'int'], +'swoole_async_readfile' => ['bool', 'filename'=>'string', 'callback'=>'string'], +'swoole_async_set' => ['void', 'settings'=>'array'], +'swoole_async_write' => ['bool', 'filename'=>'string', 'content'=>'string', 'offset='=>'int', 'callback='=>'callable'], +'swoole_async_writefile' => ['bool', 'filename'=>'string', 'content'=>'string', 'callback='=>'string', 'flags='=>'int'], +'swoole_client_select' => ['int', 'read_array'=>'array', 'write_array'=>'array', 'error_array'=>'array', 'timeout='=>'float'], +'swoole_cpu_num' => ['int'], +'swoole_errno' => ['int'], +'swoole_event_add' => ['int', 'fd'=>'int', 'read_callback='=>'callable', 'write_callback='=>'callable', 'events='=>'int'], +'swoole_event_defer' => ['bool', 'callback'=>'callable'], +'swoole_event_del' => ['bool', 'fd'=>'int'], +'swoole_event_exit' => ['void'], +'swoole_event_set' => ['bool', 'fd'=>'int', 'read_callback='=>'callable', 'write_callback='=>'callable', 'events='=>'int'], +'swoole_event_wait' => ['void'], +'swoole_event_write' => ['bool', 'fd'=>'int', 'data'=>'string'], +'swoole_get_local_ip' => ['array'], +'swoole_last_error' => ['int'], +'swoole_load_module' => ['mixed', 'filename'=>'string'], +'swoole_select' => ['int', 'read_array'=>'array', 'write_array'=>'array', 'error_array'=>'array', 'timeout='=>'float'], +'swoole_set_process_name' => ['void', 'process_name'=>'string', 'size='=>'int'], +'swoole_strerror' => ['string', 'errno'=>'int', 'error_type='=>'int'], +'swoole_timer_after' => ['int', 'ms'=>'int', 'callback'=>'callable', 'param='=>'mixed'], +'swoole_timer_exists' => ['bool', 'timer_id'=>'int'], +'swoole_timer_tick' => ['int', 'ms'=>'int', 'callback'=>'callable', 'param='=>'mixed'], +'swoole_version' => ['string'], +'sybase_affected_rows' => ['int', 'link_identifier='=>'resource'], +'sybase_close' => ['bool', 'link_identifier='=>'resource'], +'sybase_connect' => ['resource', 'servername='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'appname='=>'string', 'new='=>'bool'], +'sybase_data_seek' => ['bool', 'result_identifier'=>'resource', 'row_number'=>'int'], +'sybase_deadlock_retry_count' => ['void', 'retry_count'=>'int'], +'sybase_fetch_array' => ['array', 'result'=>'resource'], +'sybase_fetch_assoc' => ['array', 'result'=>'resource'], +'sybase_fetch_field' => ['object', 'result'=>'resource', 'field_offset='=>'int'], +'sybase_fetch_object' => ['object', 'result'=>'resource', 'object='=>'mixed'], +'sybase_fetch_row' => ['array', 'result'=>'resource'], +'sybase_field_seek' => ['bool', 'result'=>'resource', 'field_offset'=>'int'], +'sybase_free_result' => ['bool', 'result'=>'resource'], +'sybase_get_last_message' => ['string'], +'sybase_min_client_severity' => ['void', 'severity'=>'int'], +'sybase_min_error_severity' => ['void', 'severity'=>'int'], +'sybase_min_message_severity' => ['void', 'severity'=>'int'], +'sybase_min_server_severity' => ['void', 'severity'=>'int'], +'sybase_num_fields' => ['int', 'result'=>'resource'], +'sybase_num_rows' => ['int', 'result'=>'resource'], +'sybase_pconnect' => ['resource', 'servername='=>'string', 'username='=>'string', 'password='=>'string', 'charset='=>'string', 'appname='=>'string'], +'sybase_query' => ['mixed', 'query'=>'string', 'link_identifier='=>'resource'], +'sybase_result' => ['string', 'result'=>'resource', 'row'=>'int', 'field'=>'mixed'], +'sybase_select_db' => ['bool', 'database_name'=>'string', 'link_identifier='=>'resource'], +'sybase_set_message_handler' => ['bool', 'handler'=>'callable', 'connection='=>'resource'], +'sybase_unbuffered_query' => ['resource', 'query'=>'string', 'link_identifier'=>'resource', 'store_result='=>'bool'], +'symbolObj::__construct' => ['void', 'map'=>'MapObj', 'symbolname'=>'string'], +'symbolObj::free' => ['void'], +'symbolObj::getPatternArray' => ['array'], +'symbolObj::getPointsArray' => ['array'], +'symbolObj::ms_newSymbolObj' => ['int', 'map'=>'MapObj', 'symbolname'=>'string'], +'symbolObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'symbolObj::setImagePath' => ['int', 'filename'=>'string'], +'symbolObj::setPattern' => ['int', 'int'=>'array'], +'symbolObj::setPoints' => ['int', 'double'=>'array'], +'symlink' => ['bool', 'target'=>'string', 'link'=>'string'], +'SyncEvent::__construct' => ['void', 'name='=>'string', 'manual='=>'bool'], +'SyncEvent::fire' => ['bool'], +'SyncEvent::reset' => ['bool'], +'SyncEvent::wait' => ['bool', 'wait='=>'int'], +'SyncMutex::__construct' => ['void', 'name='=>'string'], +'SyncMutex::lock' => ['bool', 'wait='=>'int'], +'SyncMutex::unlock' => ['bool', 'all='=>'bool'], +'SyncReaderWriter::__construct' => ['void', 'name='=>'string', 'autounlock='=>'bool'], +'SyncReaderWriter::readlock' => ['bool', 'wait='=>'int'], +'SyncReaderWriter::readunlock' => ['bool'], +'SyncReaderWriter::writelock' => ['bool', 'wait='=>'int'], +'SyncReaderWriter::writeunlock' => ['bool'], +'SyncSemaphore::__construct' => ['void', 'name='=>'string', 'initialval='=>'int', 'autounlock='=>'bool'], +'SyncSemaphore::lock' => ['bool', 'wait='=>'int'], +'SyncSemaphore::unlock' => ['bool', '&w_prevcount='=>'int'], +'SyncSharedMemory::__construct' => ['void', 'name'=>'string', 'size'=>'int'], +'SyncSharedMemory::first' => ['bool'], +'SyncSharedMemory::read' => ['', 'start='=>'int', 'length='=>'int'], +'SyncSharedMemory::size' => ['bool'], +'SyncSharedMemory::write' => ['', 'string='=>'string', 'start='=>'int'], +'sys_get_temp_dir' => ['string'], +'sys_getloadavg' => ['array'], +'syslog' => ['bool', 'priority'=>'int', 'message'=>'string'], +'system' => ['string', 'command'=>'string', '&w_return_value='=>'int'], +'taint' => ['bool', '&rw_string'=>'string', '&...w_other_strings='=>'string'], +'tan' => ['float', 'number'=>'float'], +'tanh' => ['float', 'number'=>'float'], +'tcpwrap_check' => ['bool', 'daemon'=>'string', 'address'=>'string', 'user='=>'string', 'nodns='=>'bool'], +'tempnam' => ['string|false', 'dir'=>'string', 'prefix'=>'string'], +'textdomain' => ['string', 'domain'=>'string'], +'Thread::__construct' => ['void'], +'Thread::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'], +'Thread::count' => ['int'], +'Thread::detach' => ['void'], +'Thread::getCreatorId' => ['int'], +'Thread::getCurrentThread' => ['Thread'], +'Thread::getCurrentThreadId' => ['int'], +'Thread::getTerminationInfo' => ['array'], +'Thread::getThreadId' => ['int'], +'Thread::globally' => ['mixed'], +'Thread::isJoined' => ['bool'], +'Thread::isRunning' => ['bool'], +'Thread::isStarted' => ['bool'], +'Thread::isTerminated' => ['bool'], +'Thread::isWaiting' => ['bool'], +'Thread::join' => ['bool'], +'Thread::kill' => ['void'], +'Thread::lock' => ['bool'], +'Thread::merge' => ['bool', 'from'=>'', 'overwrite='=>'mixed'], +'Thread::notify' => ['bool'], +'Thread::offsetExists' => ['bool', 'offset'=>'mixed'], +'Thread::offsetGet' => ['mixed', 'offset'=>'mixed'], +'Thread::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], +'Thread::offsetUnset' => ['void', 'offset'=>'mixed'], +'Thread::pop' => ['bool'], +'Thread::run' => ['void'], +'Thread::shift' => ['bool'], +'Thread::start' => ['bool', 'options='=>'int'], +'Thread::synchronized' => ['mixed', 'block'=>'Closure', '_='=>'mixed'], +'Thread::unlock' => ['bool'], +'Thread::wait' => ['bool', 'timeout='=>'int'], +'Threaded::__construct' => ['void'], +'Threaded::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'], +'Threaded::count' => ['int'], +'Threaded::extend' => ['bool', 'class'=>'string'], +'Threaded::from' => ['Threaded', 'run'=>'Closure', 'construct='=>'Closure', 'args='=>'array'], +'Threaded::getTerminationInfo' => ['array'], +'Threaded::isRunning' => ['bool'], +'Threaded::isTerminated' => ['bool'], +'Threaded::isWaiting' => ['bool'], +'Threaded::lock' => ['bool'], +'Threaded::merge' => ['bool', 'from'=>'mixed', 'overwrite='=>'bool'], +'Threaded::notify' => ['bool'], +'Threaded::notifyOne' => ['bool'], +'Threaded::offsetExists' => ['bool', 'offset'=>'mixed'], +'Threaded::offsetGet' => ['mixed', 'offset'=>'mixed'], +'Threaded::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], +'Threaded::offsetUnset' => ['void', 'offset'=>'mixed'], +'Threaded::pop' => ['bool'], +'Threaded::run' => ['void'], +'Threaded::shift' => ['mixed'], +'Threaded::synchronized' => ['mixed', 'block'=>'Closure', '...args='=>'mixed'], +'Threaded::unlock' => ['bool'], +'Threaded::wait' => ['bool', 'timeout='=>'int'], +'Throwable::__toString' => ['string'], +'Throwable::getCode' => ['mixed'], +'Throwable::getFile' => ['string'], +'Throwable::getLine' => ['int'], +'Throwable::getMessage' => ['string'], +'Throwable::getPrevious' => ['Throwable|null'], +'Throwable::getTrace' => ['array'], +'Throwable::getTraceAsString' => ['string'], +'tidy::__construct' => ['void', 'filename='=>'string', 'config='=>'', 'encoding='=>'string', 'use_include_path='=>'bool'], +'tidy::body' => ['tidyNode'], +'tidy::cleanRepair' => ['bool'], +'tidy::diagnose' => ['bool'], +'tidy::getConfig' => ['array'], +'tidy::getHtmlVer' => ['int'], +'tidy::getOpt' => ['', 'option'=>'string'], +'tidy::getOptDoc' => ['string', 'optname'=>'string'], +'tidy::getRelease' => ['string'], +'tidy::getStatus' => ['int'], +'tidy::head' => ['tidyNode'], +'tidy::html' => ['tidyNode'], +'tidy::htmlver' => ['int'], +'tidy::isXhtml' => ['bool'], +'tidy::isXml' => ['bool'], +'tidy::parseFile' => ['bool', 'filename'=>'string', 'config='=>'', 'encoding='=>'string', 'use_include_path='=>'bool'], +'tidy::parseString' => ['bool', 'input'=>'string', 'config='=>'', 'encoding='=>'string'], +'tidy::repairFile' => ['string', 'filename'=>'string', 'config='=>'', 'encoding='=>'string', 'use_include_path='=>'bool'], +'tidy::repairString' => ['string', 'data'=>'string', 'config='=>'', 'encoding='=>'string'], +'tidy::root' => ['tidyNode'], +'tidy_access_count' => ['int', 'obj'=>'tidy'], +'tidy_clean_repair' => ['bool', 'obj'=>'tidy'], +'tidy_config_count' => ['int', 'obj'=>'tidy'], +'tidy_diagnose' => ['bool', 'obj'=>'tidy'], +'tidy_error_count' => ['int', 'obj'=>'tidy'], +'tidy_get_body' => ['tidyNode', 'obj'=>'tidy'], +'tidy_get_config' => ['array', 'obj'=>'tidy'], +'tidy_get_error_buffer' => ['string', 'obj'=>'tidy'], +'tidy_get_head' => ['tidyNode', 'obj'=>'tidy'], +'tidy_get_html' => ['tidyNode', 'obj'=>'tidy'], +'tidy_get_html_ver' => ['int', 'obj'=>'tidy'], +'tidy_get_opt_doc' => ['string', 'obj'=>'tidy', 'optname'=>'string'], +'tidy_get_output' => ['string', 'obj'=>'tidy'], +'tidy_get_release' => ['string'], +'tidy_get_root' => ['tidyNode', 'obj'=>'tidy'], +'tidy_get_status' => ['int', 'obj'=>'tidy'], +'tidy_getopt' => ['', 'option'=>'string', 'obj'=>'tidy'], +'tidy_is_xhtml' => ['bool', 'obj'=>'tidy'], +'tidy_is_xml' => ['bool', 'obj'=>'tidy'], +'tidy_load_config' => ['void', 'filename'=>'string', 'encoding'=>'string'], +'tidy_parse_file' => ['tidy', 'file'=>'string', 'config_options='=>'', 'encoding='=>'string', 'use_include_path='=>'bool'], +'tidy_parse_string' => ['tidy', 'input'=>'string', 'config_options='=>'', 'encoding='=>'string'], +'tidy_repair_file' => ['string', 'filename'=>'string', 'config_file='=>'', 'encoding='=>'string', 'use_include_path='=>'bool'], +'tidy_repair_string' => ['string', 'data'=>'string', 'config_file='=>'', 'encoding='=>'string'], +'tidy_reset_config' => ['bool'], +'tidy_save_config' => ['bool', 'filename'=>'string'], +'tidy_set_encoding' => ['bool', 'encoding'=>'string'], +'tidy_setopt' => ['bool', 'option'=>'string', 'value'=>'mixed'], +'tidy_warning_count' => ['int', 'obj'=>'tidy'], +'tidyNode::__construct' => ['void'], +'tidyNode::getParent' => ['tidyNode'], +'tidyNode::hasChildren' => ['bool'], +'tidyNode::hasSiblings' => ['bool'], +'tidyNode::isAsp' => ['bool'], +'tidyNode::isComment' => ['bool'], +'tidyNode::isHtml' => ['bool'], +'tidyNode::isJste' => ['bool'], +'tidyNode::isPhp' => ['bool'], +'tidyNode::isText' => ['bool'], +'time' => ['int'], +'time_nanosleep' => ['array|bool', 'seconds'=>'int', 'nanoseconds'=>'int'], +'time_sleep_until' => ['bool', 'timestamp'=>'float'], +'timezone_abbreviations_list' => ['array'], +'timezone_identifiers_list' => ['array', 'what='=>'int', 'country='=>'?string'], +'timezone_location_get' => ['array|false', 'object'=>'DateTimeZone'], +'timezone_name_from_abbr' => ['string|false', 'abbr'=>'string', 'gmtoffset='=>'int', 'isdst='=>'int'], +'timezone_name_get' => ['string', 'object'=>'DateTimeZone'], +'timezone_offset_get' => ['int', 'object'=>'DateTimeZone', 'datetime'=>'DateTime'], +'timezone_open' => ['DateTimeZone', 'timezone'=>'string'], +'timezone_transitions_get' => ['array|false', 'object'=>'DateTimeZone', 'timestamp_begin='=>'int', 'timestamp_end='=>'int'], +'timezone_version_get' => ['string'], +'tmpfile' => ['resource|false'], +'token_get_all' => ['array', 'source'=>'string', 'flags='=>'int'], +'token_name' => ['string', 'type'=>'int'], +'TokyoTyrant::__construct' => ['void', 'host='=>'string', 'port='=>'int', 'options='=>'array'], +'TokyoTyrant::add' => ['int|float', 'key'=>'string', 'increment'=>'float', 'type='=>'int'], +'TokyoTyrant::connect' => ['TokyoTyrant', 'host'=>'string', 'port='=>'int', 'options='=>'array'], +'TokyoTyrant::connectUri' => ['TokyoTyrant', 'uri'=>'string'], +'TokyoTyrant::copy' => ['TokyoTyrant', 'path'=>'string'], +'TokyoTyrant::ext' => ['string', 'name'=>'string', 'options'=>'int', 'key'=>'string', 'value'=>'string'], +'TokyoTyrant::fwmKeys' => ['array', 'prefix'=>'string', 'max_recs'=>'int'], +'TokyoTyrant::get' => ['array', 'keys'=>'mixed'], +'TokyoTyrant::getIterator' => ['TokyoTyrantIterator'], +'TokyoTyrant::num' => ['int'], +'TokyoTyrant::out' => ['string', 'keys'=>'mixed'], +'TokyoTyrant::put' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'], +'TokyoTyrant::putCat' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'], +'TokyoTyrant::putKeep' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'], +'TokyoTyrant::putNr' => ['TokyoTyrant', 'keys'=>'mixed', 'value='=>'string'], +'TokyoTyrant::putShl' => ['mixed', 'key'=>'string', 'value'=>'string', 'width'=>'int'], +'TokyoTyrant::restore' => ['mixed', 'log_dir'=>'string', 'timestamp'=>'int', 'check_consistency='=>'bool'], +'TokyoTyrant::setMaster' => ['mixed', 'host'=>'string', 'port'=>'int', 'timestamp'=>'int', 'check_consistency='=>'bool'], +'TokyoTyrant::size' => ['int', 'key'=>'string'], +'TokyoTyrant::stat' => ['array'], +'TokyoTyrant::sync' => ['mixed'], +'TokyoTyrant::tune' => ['TokyoTyrant', 'timeout'=>'float', 'options='=>'int'], +'TokyoTyrant::vanish' => ['mixed'], +'TokyoTyrantIterator::__construct' => ['void', 'object'=>'mixed'], +'TokyoTyrantIterator::current' => ['mixed'], +'TokyoTyrantIterator::key' => ['mixed'], +'TokyoTyrantIterator::next' => ['mixed'], +'TokyoTyrantIterator::rewind' => ['void'], +'TokyoTyrantIterator::valid' => ['bool'], +'TokyoTyrantQuery::__construct' => ['void', 'table'=>'TokyoTyrantTable'], +'TokyoTyrantQuery::addCond' => ['mixed', 'name'=>'string', 'op'=>'int', 'expr'=>'string'], +'TokyoTyrantQuery::count' => ['int'], +'TokyoTyrantQuery::current' => ['array'], +'TokyoTyrantQuery::hint' => ['string'], +'TokyoTyrantQuery::key' => ['string'], +'TokyoTyrantQuery::metaSearch' => ['array', 'queries'=>'array', 'type'=>'int'], +'TokyoTyrantQuery::next' => ['array'], +'TokyoTyrantQuery::out' => ['TokyoTyrantQuery'], +'TokyoTyrantQuery::rewind' => ['bool'], +'TokyoTyrantQuery::search' => ['array'], +'TokyoTyrantQuery::setLimit' => ['mixed', 'max='=>'int', 'skip='=>'int'], +'TokyoTyrantQuery::setOrder' => ['mixed', 'name'=>'string', 'type'=>'int'], +'TokyoTyrantQuery::valid' => ['bool'], +'TokyoTyrantTable::add' => ['void', 'key'=>'string', 'increment'=>'mixed', 'type='=>'string'], +'TokyoTyrantTable::genUid' => ['int'], +'TokyoTyrantTable::get' => ['array', 'keys'=>'mixed'], +'TokyoTyrantTable::getIterator' => ['TokyoTyrantIterator'], +'TokyoTyrantTable::getQuery' => ['TokyoTyrantQuery'], +'TokyoTyrantTable::out' => ['void', 'keys'=>'mixed'], +'TokyoTyrantTable::put' => ['int', 'key'=>'string', 'columns'=>'array'], +'TokyoTyrantTable::putCat' => ['void', 'key'=>'string', 'columns'=>'array'], +'TokyoTyrantTable::putKeep' => ['void', 'key'=>'string', 'columns'=>'array'], +'TokyoTyrantTable::putNr' => ['void', 'keys'=>'mixed', 'value='=>'string'], +'TokyoTyrantTable::putShl' => ['void', 'key'=>'string', 'value'=>'string', 'width'=>'int'], +'TokyoTyrantTable::setIndex' => ['mixed', 'column'=>'string', 'type'=>'int'], +'touch' => ['bool', 'filename'=>'string', 'time='=>'int', 'atime='=>'int'], +'trader_acos' => ['array', 'real'=>'array'], +'trader_ad' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array'], +'trader_add' => ['array', 'real0'=>'array', 'real1'=>'array'], +'trader_adosc' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int'], +'trader_adx' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_adxr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_apo' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'mAType='=>'int'], +'trader_aroon' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], +'trader_aroonosc' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], +'trader_asin' => ['array', 'real'=>'array'], +'trader_atan' => ['array', 'real'=>'array'], +'trader_atr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_avgprice' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_bbands' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDevUp='=>'float', 'nbDevDn='=>'float', 'mAType='=>'int'], +'trader_beta' => ['array', 'real0'=>'array', 'real1'=>'array', 'timePeriod='=>'int'], +'trader_bop' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cci' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_cdl2crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdl3blackcrows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdl3inside' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdl3linestrike' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdl3outside' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdl3starsinsouth' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdl3whitesoldiers' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlabandonedbaby' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], +'trader_cdladvanceblock' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlbelthold' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlbreakaway' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlclosingmarubozu' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlconcealbabyswall' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlcounterattack' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdldarkcloudcover' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], +'trader_cdldoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdldojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdldragonflydoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlengulfing' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdleveningdojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], +'trader_cdleveningstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], +'trader_cdlgapsidesidewhite' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlgravestonedoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlhammer' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlhangingman' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlharami' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlharamicross' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlhighwave' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlhikkake' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlhikkakemod' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlhomingpigeon' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlidentical3crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlinneck' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlinvertedhammer' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlkicking' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlkickingbylength' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlladderbottom' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdllongleggeddoji' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdllongline' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlmarubozu' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlmatchinglow' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlmathold' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], +'trader_cdlmorningdojistar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], +'trader_cdlmorningstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'penetration='=>'float'], +'trader_cdlonneck' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlpiercing' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlrickshawman' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlrisefall3methods' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlseparatinglines' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlshootingstar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlshortline' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlspinningtop' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlstalledpattern' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlsticksandwich' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdltakuri' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdltasukigap' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlthrusting' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdltristar' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlunique3river' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlupsidegap2crows' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_cdlxsidegap3methods' => ['array', 'open'=>'array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_ceil' => ['array', 'real'=>'array'], +'trader_cmo' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_correl' => ['array', 'real0'=>'array', 'real1'=>'array', 'timePeriod='=>'int'], +'trader_cos' => ['array', 'real'=>'array'], +'trader_cosh' => ['array', 'real'=>'array'], +'trader_dema' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_div' => ['array', 'real0'=>'array', 'real1'=>'array'], +'trader_dx' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_ema' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_errno' => ['int'], +'trader_exp' => ['array', 'real'=>'array'], +'trader_floor' => ['array', 'real'=>'array'], +'trader_get_compat' => ['int'], +'trader_get_unstable_period' => ['int', 'functionId'=>'int'], +'trader_ht_dcperiod' => ['array', 'real'=>'array'], +'trader_ht_dcphase' => ['array', 'real'=>'array'], +'trader_ht_phasor' => ['array', 'real'=>'array'], +'trader_ht_sine' => ['array', 'real'=>'array'], +'trader_ht_trendline' => ['array', 'real'=>'array'], +'trader_ht_trendmode' => ['array', 'real'=>'array'], +'trader_kama' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_linearreg' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_linearreg_angle' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_linearreg_intercept' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_linearreg_slope' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_ln' => ['array', 'real'=>'array'], +'trader_log10' => ['array', 'real'=>'array'], +'trader_ma' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'mAType='=>'int'], +'trader_macd' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'signalPeriod='=>'int'], +'trader_macdext' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'fastMAType='=>'int', 'slowPeriod='=>'int', 'slowMAType='=>'int', 'signalPeriod='=>'int', 'signalMAType='=>'int'], +'trader_macdfix' => ['array', 'real'=>'array', 'signalPeriod='=>'int'], +'trader_mama' => ['array', 'real'=>'array', 'fastLimit='=>'float', 'slowLimit='=>'float'], +'trader_mavp' => ['array', 'real'=>'array', 'periods'=>'array', 'minPeriod='=>'int', 'maxPeriod='=>'int', 'mAType='=>'int'], +'trader_max' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_maxindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_medprice' => ['array', 'high'=>'array', 'low'=>'array'], +'trader_mfi' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'volume'=>'array', 'timePeriod='=>'int'], +'trader_midpoint' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_midprice' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], +'trader_min' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_minindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_minmax' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_minmaxindex' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_minus_di' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_minus_dm' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], +'trader_mom' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_mult' => ['array', 'real0'=>'array', 'real1'=>'array'], +'trader_natr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_obv' => ['array', 'real'=>'array', 'volume'=>'array'], +'trader_plus_di' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_plus_dm' => ['array', 'high'=>'array', 'low'=>'array', 'timePeriod='=>'int'], +'trader_ppo' => ['array', 'real'=>'array', 'fastPeriod='=>'int', 'slowPeriod='=>'int', 'mAType='=>'int'], +'trader_roc' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_rocp' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_rocr' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_rocr100' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_rsi' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_sar' => ['array', 'high'=>'array', 'low'=>'array', 'acceleration='=>'float', 'maximum='=>'float'], +'trader_sarext' => ['array', 'high'=>'array', 'low'=>'array', 'startValue='=>'float', 'offsetOnReverse='=>'float', 'accelerationInitLong='=>'float', 'accelerationLong='=>'float', 'accelerationMaxLong='=>'float', 'accelerationInitShort='=>'float', 'accelerationShort='=>'float', 'accelerationMaxShort='=>'float'], +'trader_set_compat' => ['void', 'compatId'=>'int'], +'trader_set_unstable_period' => ['void', 'functionId'=>'int', 'timePeriod'=>'int'], +'trader_sin' => ['array', 'real'=>'array'], +'trader_sinh' => ['array', 'real'=>'array'], +'trader_sma' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_sqrt' => ['array', 'real'=>'array'], +'trader_stddev' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDev='=>'float'], +'trader_stoch' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'fastK_Period='=>'int', 'slowK_Period='=>'int', 'slowK_MAType='=>'int', 'slowD_Period='=>'int', 'slowD_MAType='=>'int'], +'trader_stochf' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'fastK_Period='=>'int', 'fastD_Period='=>'int', 'fastD_MAType='=>'int'], +'trader_stochrsi' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'fastK_Period='=>'int', 'fastD_Period='=>'int', 'fastD_MAType='=>'int'], +'trader_sub' => ['array', 'real0'=>'array', 'real1'=>'array'], +'trader_sum' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_t3' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'vFactor='=>'float'], +'trader_tan' => ['array', 'real'=>'array'], +'trader_tanh' => ['array', 'real'=>'array'], +'trader_tema' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_trange' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_trima' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_trix' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_tsf' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trader_typprice' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_ultosc' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod1='=>'int', 'timePeriod2='=>'int', 'timePeriod3='=>'int'], +'trader_var' => ['array', 'real'=>'array', 'timePeriod='=>'int', 'nbDev='=>'float'], +'trader_wclprice' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array'], +'trader_willr' => ['array', 'high'=>'array', 'low'=>'array', 'close'=>'array', 'timePeriod='=>'int'], +'trader_wma' => ['array', 'real'=>'array', 'timePeriod='=>'int'], +'trait_exists' => ['bool', 'traitname'=>'string', 'autoload='=>'bool'], +'Transliterator::create' => ['?Transliterator', 'id'=>'string', 'direction='=>'int'], +'Transliterator::createFromRules' => ['?Transliterator', 'rules'=>'string', 'direction='=>'int'], +'Transliterator::createInverse' => ['Transliterator'], +'Transliterator::getErrorCode' => ['int'], +'Transliterator::getErrorMessage' => ['string'], +'Transliterator::listIDs' => ['array'], +'Transliterator::transliterate' => ['string|false', 'subject'=>'string', 'start='=>'int', 'end='=>'int'], +'transliterator_create' => ['?Transliterator', 'id'=>'string', 'direction='=>'int'], +'transliterator_create_from_rules' => ['?Transliterator', 'rules'=>'string', 'direction='=>'int'], +'transliterator_create_inverse' => ['Transliterator', 'obj'=>'Transliterator'], +'transliterator_get_error_code' => ['int', 'obj'=>'Transliterator'], +'transliterator_get_error_message' => ['string', 'obj'=>'Transliterator'], +'transliterator_list_ids' => ['array'], +'transliterator_transliterate' => ['string|false', 'obj'=>'Transliterator|string', 'subject'=>'string', 'start='=>'int', 'end='=>'int'], +'trigger_error' => ['bool', 'message'=>'string', 'error_type='=>'int'], +'trim' => ['string', 'str'=>'string', 'character_mask='=>'string'], +'TypeError::__clone' => ['void'], +'TypeError::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?TypeError'], +'TypeError::__toString' => ['string'], +'TypeError::getCode' => ['int'], +'TypeError::getFile' => ['string'], +'TypeError::getLine' => ['int'], +'TypeError::getMessage' => ['string'], +'TypeError::getPrevious' => ['Throwable|TypeError|null'], +'TypeError::getTrace' => ['array'], +'TypeError::getTraceAsString' => ['string'], +'uasort' => ['bool', '&rw_array_arg'=>'array', 'cmp_function'=>'callable'], +'ucfirst' => ['string', 'str'=>'string'], +'UConverter::__construct' => ['void', 'destination_encoding'=>'string', 'source_encoding='=>'string'], +'UConverter::convert' => ['string', 'str'=>'string', 'reverse='=>'bool'], +'UConverter::fromUCallback' => ['mixed', 'reason'=>'int', 'source'=>'string', 'codePoint'=>'string', '&w_error'=>'int'], +'UConverter::getAliases' => ['array', 'name='=>'string'], +'UConverter::getAvailable' => ['array'], +'UConverter::getDestinationEncoding' => ['string'], +'UConverter::getDestinationType' => ['int'], +'UConverter::getErrorCode' => ['int'], +'UConverter::getErrorMessage' => ['string'], +'UConverter::getSourceEncoding' => ['string'], +'UConverter::getSourceType' => ['int'], +'UConverter::getStandards' => ['array'], +'UConverter::getSubstChars' => ['string'], +'UConverter::reasonText' => ['string', 'reason='=>'int'], +'UConverter::setDestinationEncoding' => ['bool', 'encoding'=>'string'], +'UConverter::setSourceEncoding' => ['bool', 'encoding'=>'string'], +'UConverter::setSubstChars' => ['bool', 'chars'=>'string'], +'UConverter::toUCallback' => ['mixed', 'reason'=>'int', 'source'=>'string', 'codeUnits'=>'string', '&w_error'=>'int'], +'UConverter::transcode' => ['string', 'str'=>'string', 'toEncoding'=>'string', 'fromEncoding'=>'string', 'options='=>'array'], +'ucwords' => ['string', 'str'=>'string', 'delims='=>'string'], +'udm_add_search_limit' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val'=>'string'], +'udm_alloc_agent' => ['resource', 'dbaddr'=>'string', 'dbmode='=>'string'], +'udm_alloc_agent_array' => ['resource', 'databases'=>'array'], +'udm_api_version' => ['int'], +'udm_cat_list' => ['array', 'agent'=>'resource', 'category'=>'string'], +'udm_cat_path' => ['array', 'agent'=>'resource', 'category'=>'string'], +'udm_check_charset' => ['bool', 'agent'=>'resource', 'charset'=>'string'], +'udm_check_stored' => ['int', 'agent'=>'', 'link'=>'int', 'doc_id'=>'string'], +'udm_clear_search_limits' => ['bool', 'agent'=>'resource'], +'udm_close_stored' => ['int', 'agent'=>'', 'link'=>'int'], +'udm_crc32' => ['int', 'agent'=>'resource', 'str'=>'string'], +'udm_errno' => ['int', 'agent'=>'resource'], +'udm_error' => ['string', 'agent'=>'resource'], +'udm_find' => ['resource', 'agent'=>'resource', 'query'=>'string'], +'udm_free_agent' => ['int', 'agent'=>'resource'], +'udm_free_ispell_data' => ['bool', 'agent'=>'int'], +'udm_free_res' => ['bool', 'res'=>'resource'], +'udm_get_doc_count' => ['int', 'agent'=>'resource'], +'udm_get_res_field' => ['string', 'res'=>'resource', 'row'=>'int', 'field'=>'int'], +'udm_get_res_param' => ['string', 'res'=>'resource', 'param'=>'int'], +'udm_hash32' => ['int', 'agent'=>'resource', 'str'=>'string'], +'udm_load_ispell_data' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val1'=>'string', 'val2'=>'string', 'flag'=>'int'], +'udm_open_stored' => ['int', 'agent'=>'', 'storedaddr'=>'string'], +'udm_set_agent_param' => ['bool', 'agent'=>'resource', 'var'=>'int', 'val'=>'string'], +'ui\draw\text\font\fontfamilies' => ['array'], +'ui\quit' => ['void'], +'ui\run' => ['void', 'flags='=>'int'], +'uksort' => ['bool', '&rw_array_arg'=>'array', 'cmp_function'=>'callable'], +'umask' => ['int', 'mask='=>'int'], +'UnderflowException::__clone' => ['void'], +'UnderflowException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?UnderflowException'], +'UnderflowException::__toString' => ['string'], +'UnderflowException::getCode' => ['int'], +'UnderflowException::getFile' => ['string'], +'UnderflowException::getLine' => ['int'], +'UnderflowException::getMessage' => ['string'], +'UnderflowException::getPrevious' => ['Throwable|UnderflowException|null'], +'UnderflowException::getTrace' => ['array'], +'UnderflowException::getTraceAsString' => ['string'], +'UnexpectedValueException::__clone' => ['void'], +'UnexpectedValueException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?Throwable|?UnexpectedValueException'], +'UnexpectedValueException::__toString' => ['string'], +'UnexpectedValueException::getCode' => ['int'], +'UnexpectedValueException::getFile' => ['string'], +'UnexpectedValueException::getLine' => ['int'], +'UnexpectedValueException::getMessage' => ['string'], +'UnexpectedValueException::getPrevious' => ['Throwable|UnexpectedValueException|null'], +'UnexpectedValueException::getTrace' => ['array'], +'UnexpectedValueException::getTraceAsString' => ['string'], +'uniqid' => ['string', 'prefix='=>'string', 'more_entropy='=>'bool'], +'unixtojd' => ['int', 'timestamp='=>'int'], +'unlink' => ['bool', 'filename'=>'string', 'context='=>'resource'], +'unpack' => ['array', 'format'=>'string', 'data'=>'string', 'offset='=>'int'], +'unregister_tick_function' => ['void', 'function_name'=>'string'], +'unserialize' => ['mixed', 'variable_representation'=>'string', 'allowed_classes='=>'array'], +'unset' => ['void', 'var='=>'mixed', '...args='=>'mixed'], +'untaint' => ['bool', '&rw_string'=>'string', '&...rw_strings='=>'string'], +'uopz_allow_exit' => ['void', 'allow'=>'bool'], +'uopz_backup' => ['void', 'class'=>'string', 'function'=>'string'], +'uopz_backup\'1' => ['void', 'function'=>'string'], +'uopz_compose' => ['void', 'name'=>'string', 'classes'=>'array', 'methods='=>'array', 'properties='=>'array', 'flags='=>'int'], +'uopz_copy' => ['Closure', 'class'=>'string', 'function'=>'string'], +'uopz_copy\'1' => ['Closure', 'function'=>'string'], +'uopz_delete' => ['void', 'class'=>'string', 'function'=>'string'], +'uopz_delete\'1' => ['void', 'function'=>'string'], +'uopz_extend' => ['void', 'class'=>'string', 'parent'=>'string'], +'uopz_flags' => ['int', 'class'=>'string', 'function'=>'string', 'flags'=>'int'], +'uopz_flags\'1' => ['int', 'function'=>'string', 'flags'=>'int'], +'uopz_function' => ['void', 'class'=>'string', 'function'=>'string', 'handler'=>'Closure', 'modifiers='=>'int'], +'uopz_function\'1' => ['void', 'function'=>'string', 'handler'=>'Closure', 'modifiers='=>'int'], +'uopz_get_exit_status' => ['mixed'], +'uopz_get_mock' => ['mixed', 'class'=>'string'], +'uopz_get_return' => ['mixed', 'class='=>'string', 'function'=>'string'], +'uopz_implement' => ['void', 'class'=>'string', 'interface'=>'string'], +'uopz_overload' => ['void', 'opcode'=>'int', 'callable'=>'Callable'], +'uopz_redefine' => ['void', 'class'=>'string', 'constant'=>'string', 'value'=>'mixed'], +'uopz_redefine\'1' => ['void', 'constant'=>'string', 'value'=>'mixed'], +'uopz_rename' => ['void', 'class'=>'string', 'function'=>'string', 'rename'=>'string'], +'uopz_rename\'1' => ['void', 'function'=>'string', 'rename'=>'string'], +'uopz_restore' => ['void', 'class'=>'string', 'function'=>'string'], +'uopz_restore\'1' => ['void', 'function'=>'string'], +'uopz_set_mock' => ['void', 'class'=>'string', 'mock'=>'object|string'], +'uopz_set_return' => ['bool', 'class='=>'string', 'function'=>'string', 'value'=>'mixed', 'execute='=>'bool'], +'uopz_set_return\'1' => ['bool', 'function'=>'string', 'value'=>'mixed', 'execute='=>'bool'], +'uopz_undefine' => ['void', 'class'=>'string', 'constant'=>'string'], +'uopz_undefine\'1' => ['void', 'constant'=>'string'], +'uopz_unset_mock' => ['void', 'class'=>'string'], +'uopz_unset_return' => ['bool', 'class='=>'string', 'function'=>'string'], +'uopz_unset_return\'1' => ['bool', 'function'=>'string'], +'urldecode' => ['string', 'str'=>'string'], +'urlencode' => ['string', 'str'=>'string'], +'use_soap_error_handler' => ['bool', 'handler='=>'bool'], +'usleep' => ['void', 'micro_seconds'=>'int'], +'usort' => ['bool', '&rw_array_arg'=>'array', 'cmp_function'=>'callable'], +'utf8_decode' => ['string', 'data'=>'string'], +'utf8_encode' => ['string', 'data'=>'string'], +'V8Js::__construct' => ['void', 'object_name='=>'string', 'variables='=>'array', 'extensions='=>'array', 'report_uncaught_exceptions='=>'bool', 'snapshot_blob='=>'string'], +'V8Js::clearPendingException' => [''], +'V8Js::compileString' => ['resource', 'script'=>'', 'identifier='=>'string'], +'V8Js::createSnapshot' => ['false|string', 'embed_source'=>'string'], +'V8Js::executeScript' => ['', 'script'=>'resource', 'flags='=>'int', 'time_limit='=>'int', 'memory_limit='=>'int'], +'V8Js::executeString' => ['mixed', 'script'=>'string', 'identifier='=>'string', 'flags='=>'int'], +'V8Js::getExtensions' => ['array'], +'V8Js::getPendingException' => ['V8JsException'], +'V8Js::registerExtension' => ['bool', 'extension_name'=>'string', 'script'=>'string', 'dependencies='=>'array', 'auto_enable='=>'bool'], +'V8Js::setAverageObjectSize' => ['', 'average_object_size'=>'int'], +'V8Js::setMemoryLimit' => ['', 'limit'=>'int'], +'V8Js::setModuleLoader' => ['', 'loader'=>'callable'], +'V8Js::setModuleNormaliser' => ['', 'normaliser'=>'callable'], +'V8Js::setTimeLimit' => ['', 'limit'=>'int'], +'V8JsException::getJsFileName' => ['string'], +'V8JsException::getJsLineNumber' => ['int'], +'V8JsException::getJsSourceLine' => ['int'], +'V8JsException::getJsTrace' => ['string'], +'V8JsScriptException::__clone' => ['void'], +'V8JsScriptException::__construct' => ['void', 'message='=>'string', 'code='=>'int', 'previous='=>'?\Exception|?\Throwable'], +'V8JsScriptException::__toString' => ['string'], +'V8JsScriptException::__wakeup' => ['void'], +'V8JsScriptException::getCode' => ['int'], +'V8JsScriptException::getFile' => ['string'], +'V8JsScriptException::getJsEndColumn' => ['int'], +'V8JsScriptException::getJsFileName' => ['string'], +'V8JsScriptException::getJsLineNumber' => ['int'], +'V8JsScriptException::getJsSourceLine' => ['string'], +'V8JsScriptException::getJsStartColumn' => ['int'], +'V8JsScriptException::getJsTrace' => ['string'], +'V8JsScriptException::getLine' => ['int'], +'V8JsScriptException::getMessage' => ['string'], +'V8JsScriptException::getPrevious' => ['Exception|Throwable'], +'V8JsScriptException::getTrace' => ['array'], +'V8JsScriptException::getTraceAsString' => ['string'], +'var_dump' => ['void', 'var'=>'mixed', '...args='=>'mixed'], +'var_export' => ['string|null', 'var'=>'mixed', 'return='=>'bool'], +'VARIANT::__construct' => ['void', 'value='=>'mixed', 'type='=>'int', 'codepage='=>'int'], +'variant_abs' => ['mixed', 'left'=>'mixed'], +'variant_add' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_and' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_cast' => ['object', 'variant'=>'object', 'type'=>'int'], +'variant_cat' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_cmp' => ['int', 'left'=>'mixed', 'right'=>'mixed', 'lcid='=>'int', 'flags='=>'int'], +'variant_date_from_timestamp' => ['object', 'timestamp'=>'int'], +'variant_date_to_timestamp' => ['int', 'variant'=>'object'], +'variant_div' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_eqv' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_fix' => ['mixed', 'left'=>'mixed'], +'variant_get_type' => ['int', 'variant'=>'object'], +'variant_idiv' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_imp' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_int' => ['mixed', 'left'=>'mixed'], +'variant_mod' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_mul' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_neg' => ['mixed', 'left'=>'mixed'], +'variant_not' => ['mixed', 'left'=>'mixed'], +'variant_or' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_pow' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_round' => ['mixed', 'left'=>'mixed', 'decimals'=>'int'], +'variant_set' => ['void', 'variant'=>'object', 'value'=>'mixed'], +'variant_set_type' => ['void', 'variant'=>'object', 'type'=>'int'], +'variant_sub' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'variant_xor' => ['mixed', 'left'=>'mixed', 'right'=>'mixed'], +'VarnishAdmin::__construct' => ['void', 'args='=>'array'], +'VarnishAdmin::auth' => ['bool'], +'VarnishAdmin::ban' => ['int', 'vcl_regex'=>'string'], +'VarnishAdmin::banUrl' => ['int', 'vcl_regex'=>'string'], +'VarnishAdmin::clearPanic' => ['int'], +'VarnishAdmin::connect' => ['bool'], +'VarnishAdmin::disconnect' => ['bool'], +'VarnishAdmin::getPanic' => ['string'], +'VarnishAdmin::getParams' => ['array'], +'VarnishAdmin::isRunning' => ['bool'], +'VarnishAdmin::setCompat' => ['void', 'compat'=>'int'], +'VarnishAdmin::setHost' => ['void', 'host'=>'string'], +'VarnishAdmin::setIdent' => ['void', 'ident'=>'string'], +'VarnishAdmin::setParam' => ['int', 'name'=>'string', 'value'=>'string|int'], +'VarnishAdmin::setPort' => ['void', 'port'=>'int'], +'VarnishAdmin::setSecret' => ['void', 'secret'=>'string'], +'VarnishAdmin::setTimeout' => ['void', 'timeout'=>'int'], +'VarnishAdmin::start' => ['int'], +'VarnishAdmin::stop' => ['int'], +'VarnishLog::__construct' => ['void', 'args='=>'array'], +'VarnishLog::getLine' => ['array'], +'VarnishLog::getTagName' => ['string', 'index'=>'int'], +'VarnishStat::__construct' => ['void', 'args='=>'array'], +'VarnishStat::getSnapshot' => ['array'], +'version_compare' => ['int', 'version1'=>'string', 'version2'=>'string'], +'version_compare\'1' => ['bool', 'version1'=>'string', 'version2'=>'string', 'operator'=>'string'], +'vfprintf' => ['int', 'stream'=>'resource', 'format'=>'string', 'args'=>'array'], +'virtual' => ['bool', 'uri'=>'string'], +'vpopmail_add_alias_domain' => ['bool', 'domain'=>'string', 'aliasdomain'=>'string'], +'vpopmail_add_alias_domain_ex' => ['bool', 'olddomain'=>'string', 'newdomain'=>'string'], +'vpopmail_add_domain' => ['bool', 'domain'=>'string', 'dir'=>'string', 'uid'=>'int', 'gid'=>'int'], +'vpopmail_add_domain_ex' => ['bool', 'domain'=>'string', 'passwd'=>'string', 'quota='=>'string', 'bounce='=>'string', 'apop='=>'bool'], +'vpopmail_add_user' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'gecos='=>'string', 'apop='=>'bool'], +'vpopmail_alias_add' => ['bool', 'user'=>'string', 'domain'=>'string', 'alias'=>'string'], +'vpopmail_alias_del' => ['bool', 'user'=>'string', 'domain'=>'string'], +'vpopmail_alias_del_domain' => ['bool', 'domain'=>'string'], +'vpopmail_alias_get' => ['array', 'alias'=>'string', 'domain'=>'string'], +'vpopmail_alias_get_all' => ['array', 'domain'=>'string'], +'vpopmail_auth_user' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'apop='=>'string'], +'vpopmail_del_domain' => ['bool', 'domain'=>'string'], +'vpopmail_del_domain_ex' => ['bool', 'domain'=>'string'], +'vpopmail_del_user' => ['bool', 'user'=>'string', 'domain'=>'string'], +'vpopmail_error' => ['string'], +'vpopmail_passwd' => ['bool', 'user'=>'string', 'domain'=>'string', 'password'=>'string', 'apop='=>'bool'], +'vpopmail_set_user_quota' => ['bool', 'user'=>'string', 'domain'=>'string', 'quota'=>'string'], +'vprintf' => ['int', 'format'=>'string', 'args'=>'array'], +'vsprintf' => ['string', 'format'=>'string', 'args'=>'array'], +'w32api_deftype' => ['bool', 'typename'=>'string', 'member1_type'=>'string', 'member1_name'=>'string', '...args='=>'string'], +'w32api_init_dtype' => ['resource', 'typename'=>'string', 'value'=>'', '...args='=>''], +'w32api_invoke_function' => ['', 'funcname'=>'string', 'argument'=>'', '...args='=>''], +'w32api_register_function' => ['bool', 'library'=>'string', 'function_name'=>'string', 'return_type'=>'string'], +'w32api_set_call_method' => ['', 'method'=>'int'], +'wddx_add_vars' => ['bool', 'packet_id'=>'resource', 'var_names'=>'mixed', '...vars='=>'mixed'], +'wddx_deserialize' => ['mixed', 'packet'=>'string'], +'wddx_packet_end' => ['string', 'packet_id'=>'resource'], +'wddx_packet_start' => ['resource', 'comment='=>'string'], +'wddx_serialize_value' => ['string', 'var'=>'mixed', 'comment='=>'string'], +'wddx_serialize_vars' => ['string', 'var_name'=>'mixed', '...vars='=>'mixed'], +'WeakMap::__construct' => ['void'], +'WeakMap::count' => ['int'], +'WeakMap::current' => ['mixed'], +'WeakMap::key' => ['object'], +'WeakMap::next' => ['void'], +'WeakMap::offsetExists' => ['bool', 'object'=>'object'], +'WeakMap::offsetGet' => ['mixed', 'object'=>'object'], +'WeakMap::offsetSet' => ['void', 'object'=>'object', 'value'=>'mixed'], +'WeakMap::offsetUnset' => ['void', 'object'=>'object'], +'WeakMap::rewind' => ['void'], +'WeakMap::valid' => ['bool'], +'Weakref::acquire' => ['bool'], +'Weakref::get' => ['object'], +'Weakref::release' => ['bool'], +'Weakref::valid' => ['bool'], +'webObj::convertToString' => ['string'], +'webObj::free' => ['void'], +'webObj::set' => ['int', 'property_name'=>'string', 'new_value'=>''], +'webObj::updateFromString' => ['int', 'snippet'=>'string'], +'win32_continue_service' => ['int', 'servicename'=>'string', 'machine='=>'string'], +'win32_create_service' => ['mixed', 'details'=>'array', 'machine='=>'string'], +'win32_delete_service' => ['mixed', 'servicename'=>'string', 'machine='=>'string'], +'win32_get_last_control_message' => ['int'], +'win32_pause_service' => ['int', 'servicename'=>'string', 'machine='=>'string'], +'win32_ps_list_procs' => ['array'], +'win32_ps_stat_mem' => ['array'], +'win32_ps_stat_proc' => ['array', 'pid='=>'int'], +'win32_query_service_status' => ['mixed', 'servicename'=>'string', 'machine='=>'string'], +'win32_set_service_status' => ['bool', 'status'=>'int', 'checkpoint='=>'int'], +'win32_start_service' => ['int', 'servicename'=>'string', 'machine='=>'string'], +'win32_start_service_ctrl_dispatcher' => ['mixed', 'name'=>'string'], +'win32_stop_service' => ['int', 'servicename'=>'string', 'machine='=>'string'], +'wincache_fcache_fileinfo' => ['array', 'summaryonly='=>'bool'], +'wincache_fcache_meminfo' => ['array'], +'wincache_lock' => ['bool', 'key'=>'string', 'isglobal='=>'bool'], +'wincache_ocache_fileinfo' => ['array', 'summaryonly='=>'bool'], +'wincache_ocache_meminfo' => ['array'], +'wincache_refresh_if_changed' => ['bool', 'files='=>'array'], +'wincache_rplist_fileinfo' => ['array', 'summaryonly='=>'bool'], +'wincache_rplist_meminfo' => ['array'], +'wincache_scache_info' => ['array', 'summaryonly='=>'bool'], +'wincache_scache_meminfo' => ['array'], +'wincache_ucache_add' => ['bool', 'key'=>'string', 'value'=>'', 'ttl='=>'int'], +'wincache_ucache_add\'1' => ['bool', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], +'wincache_ucache_cas' => ['bool', 'key'=>'string', 'old_value'=>'int', 'new_value'=>'int'], +'wincache_ucache_clear' => ['bool'], +'wincache_ucache_dec' => ['mixed', 'key'=>'string', 'dec_by='=>'int', 'success='=>'bool'], +'wincache_ucache_delete' => ['bool', 'key'=>'mixed'], +'wincache_ucache_exists' => ['bool', 'key'=>'string'], +'wincache_ucache_get' => ['mixed', 'key'=>'mixed', '&w_success='=>'bool'], +'wincache_ucache_inc' => ['mixed', 'key'=>'string', 'inc_by='=>'int', 'success='=>'bool'], +'wincache_ucache_info' => ['array', 'summaryonly='=>'bool', 'key='=>'string'], +'wincache_ucache_meminfo' => ['array'], +'wincache_ucache_set' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int'], +'wincache_ucache_set\'1' => ['bool', 'values'=>'array', 'unused='=>'', 'ttl='=>'int'], +'wincache_unlock' => ['bool', 'key'=>'string'], +'wordwrap' => ['string', 'str'=>'string', 'width='=>'int', 'break='=>'string', 'cut='=>'bool'], +'Worker::__construct' => ['void'], +'Worker::chunk' => ['array', 'size'=>'int', 'preserve'=>'bool'], +'Worker::collect' => ['int', 'collector='=>'Callable'], +'Worker::count' => ['int'], +'Worker::detach' => ['void'], +'Worker::getCreatorId' => ['int'], +'Worker::getCurrentThread' => ['Thread'], +'Worker::getCurrentThreadId' => ['int'], +'Worker::getStacked' => ['int'], +'Worker::getTerminationInfo' => ['array'], +'Worker::getThreadId' => ['int'], +'Worker::globally' => ['mixed'], +'Worker::isJoined' => ['bool'], +'Worker::isRunning' => ['bool'], +'Worker::isShutdown' => ['bool'], +'Worker::isStarted' => ['bool'], +'Worker::isTerminated' => ['bool'], +'Worker::isWaiting' => ['bool'], +'Worker::isWorking' => ['bool'], +'Worker::join' => ['bool'], +'Worker::kill' => ['bool'], +'Worker::lock' => ['bool'], +'Worker::merge' => ['bool', 'from'=>'', 'overwrite='=>'mixed'], +'Worker::notify' => ['bool'], +'Worker::offsetExists' => ['bool', 'offset'=>'mixed'], +'Worker::offsetGet' => ['mixed', 'offset'=>'mixed'], +'Worker::offsetSet' => ['void', 'offset'=>'mixed', 'value'=>'mixed'], +'Worker::offsetUnset' => ['void', 'offset'=>'mixed'], +'Worker::pop' => ['bool'], +'Worker::run' => ['void'], +'Worker::shift' => ['bool'], +'Worker::shutdown' => ['bool'], +'Worker::stack' => ['int', '&rw_work'=>'Threaded'], +'Worker::start' => ['bool', 'options='=>'int'], +'Worker::synchronized' => ['mixed', 'block'=>'Closure', '_='=>'mixed'], +'Worker::unlock' => ['bool'], +'Worker::unstack' => ['int', '&rw_work='=>'Threaded'], +'Worker::wait' => ['bool', 'timeout='=>'int'], +'xattr_get' => ['string', 'filename'=>'string', 'name'=>'string', 'flags='=>'int'], +'xattr_list' => ['array', 'filename'=>'string', 'flags='=>'int'], +'xattr_remove' => ['bool', 'filename'=>'string', 'name'=>'string', 'flags='=>'int'], +'xattr_set' => ['bool', 'filename'=>'string', 'name'=>'string', 'value'=>'string', 'flags='=>'int'], +'xattr_supported' => ['bool', 'filename'=>'string', 'flags='=>'int'], +'xcache_asm' => ['string', 'filename'=>'string'], +'xcache_clear_cache' => ['void', 'type'=>'int', 'id='=>'int'], +'xcache_coredump' => ['string', 'op_type'=>'int'], +'xcache_count' => ['int', 'type'=>'int'], +'xcache_coverager_decode' => ['array', 'data'=>'string'], +'xcache_coverager_get' => ['array', 'clean='=>'bool|false'], +'xcache_coverager_start' => ['void', 'clean='=>'bool|true'], +'xcache_coverager_stop' => ['void', 'clean='=>'bool|false'], +'xcache_dasm_file' => ['string', 'filename'=>'string'], +'xcache_dasm_string' => ['string', 'code'=>'string'], +'xcache_dec' => ['int', 'name'=>'string', 'value='=>'int|mixed', 'ttl='=>'int'], +'xcache_decode' => ['bool', 'filename'=>'string'], +'xcache_encode' => ['string', 'filename'=>'string'], +'xcache_get' => ['mixed', 'name'=>'string'], +'xcache_get_data_type' => ['string', 'type'=>'int'], +'xcache_get_op_spec' => ['string', 'op_type'=>'int'], +'xcache_get_op_type' => ['string', 'op_type'=>'int'], +'xcache_get_opcode' => ['string', 'opcode'=>'int'], +'xcache_get_opcode_spec' => ['string', 'opcode'=>'int'], +'xcache_inc' => ['int', 'name'=>'string', 'value='=>'int|mixed', 'ttl='=>'int'], +'xcache_info' => ['array', 'type'=>'int', 'id'=>'int'], +'xcache_is_autoglobal' => ['string', 'name'=>'string'], +'xcache_isset' => ['bool', 'name'=>'string'], +'xcache_list' => ['array', 'type'=>'int', 'id'=>'int'], +'xcache_set' => ['bool', 'name'=>'string', 'value'=>'mixed', 'ttl='=>'int'], +'xcache_unset' => ['bool', 'name'=>'string'], +'xcache_unset_by_prefix' => ['bool', 'prefix'=>'string'], +'Xcom::__construct' => ['void', 'fabric_url='=>'string', 'fabric_token='=>'string', 'capability_token='=>'string'], +'Xcom::decode' => ['object', 'avro_msg'=>'string', 'json_schema'=>'string'], +'Xcom::encode' => ['string', 'data'=>'stdClass', 'avro_schema'=>'string'], +'Xcom::getDebugOutput' => ['string'], +'Xcom::getLastResponse' => ['string'], +'Xcom::getLastResponseInfo' => ['array'], +'Xcom::getOnboardingURL' => ['string', 'capability_name'=>'string', 'agreement_url'=>'string'], +'Xcom::send' => ['int', 'topic'=>'string', 'data'=>'mixed', 'json_schema='=>'string', 'http_headers='=>'array'], +'Xcom::sendAsync' => ['int', 'topic'=>'string', 'data'=>'mixed', 'json_schema='=>'string', 'http_headers='=>'array'], +'xdebug_break' => ['bool'], +'xdebug_call_class' => ['string', 'depth=' => 'int'], +'xdebug_call_file' => ['string', 'depth=' => 'int'], +'xdebug_call_function' => ['string', 'depth=' => 'int'], +'xdebug_call_line' => ['int', 'depth=' => 'int'], +'xdebug_clear_aggr_profiling_data' => ['bool'], +'xdebug_code_coverage_started' => ['bool'], +'xdebug_debug_zval' => ['void', '...varName'=>'string'], +'xdebug_debug_zval_stdout' => ['void', '...varName'=>'string'], +'xdebug_disable' => ['void'], +'xdebug_dump_aggr_profiling_data' => ['bool'], +'xdebug_dump_superglobals' => ['void'], +'xdebug_enable' => ['void'], +'xdebug_get_code_coverage' => ['array'], +'xdebug_get_collected_errors' => ['string', 'clean='=>'bool|false'], +'xdebug_get_declared_vars' => ['array'], +'xdebug_get_formatted_function_stack' => [''], +'xdebug_get_function_count' => ['int'], +'xdebug_get_function_stack' => ['array', 'message='=>'string', 'options='=>'int'], +'xdebug_get_headers' => ['array'], +'xdebug_get_monitored_functions' => ['array'], +'xdebug_get_profiler_filename' => ['string'], +'xdebug_get_stack_depth' => ['int'], +'xdebug_get_tracefile_name' => ['string'], +'xdebug_is_debugger_active' => ['bool'], +'xdebug_is_enabled' => ['bool'], +'xdebug_memory_usage' => ['int'], +'xdebug_peak_memory_usage' => ['int'], +'xdebug_print_function_stack' => ['array', 'message='=>'string', 'options=' => 'int'], +'xdebug_set_filter' => ['void', 'group' => 'int', 'list_type' => 'int', 'configuration' => 'array'], +'xdebug_start_code_coverage' => ['void', 'options='=>'int'], +'xdebug_start_error_collection' => ['void'], +'xdebug_start_function_monitor' => ['void', 'list_of_functions_to_monitor'=>'string[]'], +'xdebug_start_trace' => ['void', 'trace_file'=>'', 'options='=>'int|mixed'], +'xdebug_stop_code_coverage' => ['void', 'cleanup='=>'bool|true'], +'xdebug_stop_error_collection' => ['void'], +'xdebug_stop_function_monitor' => ['void'], +'xdebug_stop_trace' => ['void'], +'xdebug_time_index' => ['float'], +'xdebug_var_dump' => ['void', '...var'=>''], +'xdiff_file_bdiff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'], +'xdiff_file_bdiff_size' => ['int', 'file'=>'string'], +'xdiff_file_bpatch' => ['bool', 'file'=>'string', 'patch'=>'string', 'dest'=>'string'], +'xdiff_file_diff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string', 'context='=>'int', 'minimal='=>'bool'], +'xdiff_file_diff_binary' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'], +'xdiff_file_merge3' => ['mixed', 'old_file'=>'string', 'new_file1'=>'string', 'new_file2'=>'string', 'dest'=>'string'], +'xdiff_file_patch' => ['mixed', 'file'=>'string', 'patch'=>'string', 'dest'=>'string', 'flags='=>'int'], +'xdiff_file_patch_binary' => ['bool', 'file'=>'string', 'patch'=>'string', 'dest'=>'string'], +'xdiff_file_rabdiff' => ['bool', 'old_file'=>'string', 'new_file'=>'string', 'dest'=>'string'], +'xdiff_string_bdiff' => ['string', 'old_data'=>'string', 'new_data'=>'string'], +'xdiff_string_bdiff_size' => ['int', 'patch'=>'string'], +'xdiff_string_bpatch' => ['string', 'str'=>'string', 'patch'=>'string'], +'xdiff_string_diff' => ['string', 'old_data'=>'string', 'new_data'=>'string', 'context='=>'int', 'minimal='=>'bool'], +'xdiff_string_diff_binary' => ['string', 'old_data'=>'string', 'new_data'=>'string'], +'xdiff_string_merge3' => ['mixed', 'old_data'=>'string', 'new_data1'=>'string', 'new_data2'=>'string', 'error='=>'string'], +'xdiff_string_patch' => ['string', 'str'=>'string', 'patch'=>'string', 'flags='=>'int', 'error='=>'string'], +'xdiff_string_patch_binary' => ['string', 'str'=>'string', 'patch'=>'string'], +'xdiff_string_rabdiff' => ['string', 'old_data'=>'string', 'new_data'=>'string'], +'xhprof_disable' => ['array'], +'xhprof_enable' => ['void', 'flags='=>'int', 'options='=>'array'], +'xhprof_sample_disable' => ['array'], +'xhprof_sample_enable' => ['void'], +'xml_error_string' => ['string', 'code'=>'int'], +'xml_get_current_byte_index' => ['int', 'parser'=>'resource'], +'xml_get_current_column_number' => ['int', 'parser'=>'resource'], +'xml_get_current_line_number' => ['int', 'parser'=>'resource'], +'xml_get_error_code' => ['int', 'parser'=>'resource'], +'xml_parse' => ['int', 'parser'=>'resource', 'data'=>'string', 'isfinal='=>'bool'], +'xml_parse_into_struct' => ['int', 'parser'=>'resource', 'data'=>'string', '&w_values'=>'array', '&w_index='=>'array'], +'xml_parser_create' => ['resource', 'encoding='=>'string'], +'xml_parser_create_ns' => ['resource', 'encoding='=>'string', 'sep='=>'string'], +'xml_parser_free' => ['bool', 'parser'=>'resource'], +'xml_parser_get_option' => ['mixed', 'parser'=>'resource', 'option'=>'int'], +'xml_parser_set_option' => ['bool', 'parser'=>'resource', 'option'=>'int', 'value'=>'mixed'], +'xml_set_character_data_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'string'], +'xml_set_default_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'string'], +'xml_set_element_handler' => ['bool', 'parser'=>'resource', 'shdl'=>'string', 'ehdl'=>'string'], +'xml_set_end_namespace_decl_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'string'], +'xml_set_external_entity_ref_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'string'], +'xml_set_notation_decl_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'string'], +'xml_set_object' => ['bool', 'parser'=>'resource', 'obj'=>'object'], +'xml_set_processing_instruction_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'string'], +'xml_set_start_namespace_decl_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'string'], +'xml_set_unparsed_entity_decl_handler' => ['bool', 'parser'=>'resource', 'hdl'=>'string'], +'XMLDiff\Base::__construct' => ['void', 'nsname'=>'string'], +'XMLDiff\Base::diff' => ['mixed', 'from'=>'mixed', 'to'=>'mixed'], +'XMLDiff\Base::merge' => ['mixed', 'src'=>'mixed', 'diff'=>'mixed'], +'XMLDiff\DOM::diff' => ['DOMDocument', 'from'=>'DOMDocument', 'to'=>'DOMDocument'], +'XMLDiff\DOM::merge' => ['DOMDocument', 'src'=>'DOMDocument', 'diff'=>'DOMDocument'], +'XMLDiff\File::diff' => ['string', 'from'=>'string', 'to'=>'string'], +'XMLDiff\File::merge' => ['string', 'src'=>'string', 'diff'=>'string'], +'XMLDiff\Memory::diff' => ['string', 'from'=>'string', 'to'=>'string'], +'XMLDiff\Memory::merge' => ['string', 'src'=>'string', 'diff'=>'string'], +'XMLReader::close' => ['bool'], +'XMLReader::expand' => ['DOMNode', 'basenode='=>'DOMNode'], +'XMLReader::getAttribute' => ['string|null', 'name'=>'string'], +'XMLReader::getAttributeNo' => ['string|null', 'index'=>'int'], +'XMLReader::getAttributeNs' => ['string|null', 'name'=>'string', 'namespaceuri'=>'string'], +'XMLReader::getParserProperty' => ['bool', 'property'=>'int'], +'XMLReader::isValid' => ['bool'], +'XMLReader::lookupNamespace' => ['?string', 'prefix'=>'string'], +'XMLReader::moveToAttribute' => ['bool', 'name'=>'string'], +'XMLReader::moveToAttributeNo' => ['bool', 'index'=>'int'], +'XMLReader::moveToAttributeNs' => ['bool', 'localname'=>'string', 'namespaceuri'=>'string'], +'XMLReader::moveToElement' => ['bool'], +'XMLReader::moveToFirstAttribute' => ['bool'], +'XMLReader::moveToNextAttribute' => ['bool'], +'XMLReader::next' => ['bool', 'localname='=>'string'], +'XMLReader::open' => ['bool', 'uri'=>'string', 'encoding='=>'?string', 'options='=>'int'], +'XMLReader::read' => ['bool'], +'XMLReader::readInnerXML' => ['string'], +'XMLReader::readOuterXML' => ['string'], +'XMLReader::readString' => ['string'], +'XMLReader::setParserProperty' => ['bool', 'property'=>'int', 'value'=>'bool'], +'XMLReader::setRelaxNGSchema' => ['bool', 'filename'=>'string'], +'XMLReader::setRelaxNGSchemaSource' => ['bool', 'source'=>'string'], +'XMLReader::setSchema' => ['bool', 'filename'=>'string'], +'XMLReader::XML' => ['bool', 'source'=>'string', 'encoding='=>'?string', 'options='=>'int'], +'xmlrpc_decode' => ['?array', 'xml'=>'string', 'encoding='=>'string'], +'xmlrpc_decode_request' => ['?array', 'xml'=>'string', '&w_method'=>'string', 'encoding='=>'string'], +'xmlrpc_encode' => ['string', 'value'=>'mixed'], +'xmlrpc_encode_request' => ['string', 'method'=>'string', 'params'=>'mixed', 'output_options='=>'array'], +'xmlrpc_get_type' => ['string', 'value'=>'mixed'], +'xmlrpc_is_fault' => ['bool', 'arg'=>'array'], +'xmlrpc_parse_method_descriptions' => ['array', 'xml'=>'string'], +'xmlrpc_server_add_introspection_data' => ['int', 'server'=>'resource', 'desc'=>'array'], +'xmlrpc_server_call_method' => ['string', 'server'=>'resource', 'xml'=>'string', 'user_data'=>'mixed', 'output_options='=>'array'], +'xmlrpc_server_create' => ['resource'], +'xmlrpc_server_destroy' => ['int', 'server'=>'resource'], +'xmlrpc_server_register_introspection_callback' => ['bool', 'server'=>'resource', 'function'=>'string'], +'xmlrpc_server_register_method' => ['bool', 'server'=>'resource', 'method_name'=>'string', 'function'=>'string'], +'xmlrpc_set_type' => ['bool', '&rw_value'=>'string|DateTime', 'type'=>'string'], +'XMLWriter::endAttribute' => ['bool'], +'XMLWriter::endCData' => ['bool'], +'XMLWriter::endComment' => ['bool'], +'XMLWriter::endDocument' => ['bool'], +'XMLWriter::endDTD' => ['bool', 'xmlwriter='=>''], +'XMLWriter::endDTDAttlist' => ['bool'], +'XMLWriter::endDTDElement' => ['bool'], +'XMLWriter::endDTDEntity' => ['bool'], +'XMLWriter::endElement' => ['bool'], +'XMLWriter::endPI' => ['bool'], +'XMLWriter::flush' => ['', 'empty='=>'bool', 'xmlwriter='=>''], +'XMLWriter::fullEndElement' => ['bool'], +'XMLWriter::openMemory' => ['resource'], +'XMLWriter::openURI' => ['resource', 'uri'=>'string'], +'XMLWriter::outputMemory' => ['string', 'flush='=>'bool', 'xmlwriter='=>''], +'XMLWriter::setIndent' => ['bool', 'indent'=>'bool'], +'XMLWriter::setIndentString' => ['bool', 'indentstring'=>'string'], +'XMLWriter::startAttribute' => ['bool', 'name'=>'string'], +'XMLWriter::startAttributeNS' => ['bool', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string'], +'XMLWriter::startCData' => ['bool'], +'XMLWriter::startComment' => ['bool'], +'XMLWriter::startDocument' => ['bool', 'version='=>'string', 'encoding='=>'string', 'standalone='=>'string'], +'XMLWriter::startDTD' => ['bool', 'qualifiedname'=>'string', 'publicid='=>'string', 'systemid='=>'string'], +'XMLWriter::startDTDAttlist' => ['bool', 'name'=>'string'], +'XMLWriter::startDTDElement' => ['bool', 'qualifiedname'=>'string'], +'XMLWriter::startDTDEntity' => ['bool', 'name'=>'string', 'isparam'=>'bool'], +'XMLWriter::startElement' => ['bool', 'name'=>'string'], +'XMLWriter::startElementNS' => ['bool', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string'], +'XMLWriter::startPI' => ['bool', 'target'=>'string'], +'XMLWriter::text' => ['bool', 'content'=>'string'], +'XMLWriter::writeAttribute' => ['bool', 'name'=>'string', 'value'=>'string'], +'XMLWriter::writeAttributeNS' => ['bool', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], +'XMLWriter::writeCData' => ['bool', 'content'=>'string'], +'XMLWriter::writeComment' => ['bool', 'content'=>'string'], +'XMLWriter::writeDTD' => ['bool', 'name'=>'string', 'publicid='=>'string', 'systemid='=>'string', 'subset='=>'string'], +'XMLWriter::writeDTDAttlist' => ['bool', 'name'=>'string', 'content'=>'string'], +'XMLWriter::writeDTDElement' => ['bool', 'name'=>'string', 'content'=>'string'], +'XMLWriter::writeDTDEntity' => ['bool', 'name'=>'string', 'content'=>'string', 'pe'=>'bool', 'pubid'=>'string', 'sysid'=>'string', 'ndataid'=>'string'], +'XMLWriter::writeElement' => ['bool', 'name'=>'string', 'content='=>'string|null'], +'XMLWriter::writeElementNS' => ['bool', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string', 'content='=>'string|null'], +'XMLWriter::writePI' => ['bool', 'target'=>'string', 'content'=>'string'], +'XMLWriter::writeRaw' => ['bool', 'content'=>'string'], +'xmlwriter_end_attribute' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_cdata' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_comment' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_document' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_dtd' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_dtd_attlist' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_dtd_element' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_dtd_entity' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_element' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_end_pi' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_flush' => ['', 'xmlwriter'=>'resource', 'empty='=>'bool'], +'xmlwriter_full_end_element' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_open_memory' => ['resource'], +'xmlwriter_open_uri' => ['resource', 'source'=>'string'], +'xmlwriter_output_memory' => ['string', 'xmlwriter'=>'resource', 'flush='=>'bool'], +'xmlwriter_set_indent' => ['bool', 'xmlwriter'=>'resource', 'indent'=>'bool'], +'xmlwriter_set_indent_string' => ['bool', 'xmlwriter'=>'resource', 'indentstring'=>'string'], +'xmlwriter_start_attribute' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], +'xmlwriter_start_attribute_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string'], +'xmlwriter_start_cdata' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_start_comment' => ['bool', 'xmlwriter'=>'resource'], +'xmlwriter_start_document' => ['bool', 'xmlwriter'=>'resource', 'version'=>'string', 'encoding'=>'string', 'standalone'=>'string'], +'xmlwriter_start_dtd' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'pubid'=>'string', 'sysid'=>'string'], +'xmlwriter_start_dtd_attlist' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], +'xmlwriter_start_dtd_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], +'xmlwriter_start_dtd_entity' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'isparam'=>'bool'], +'xmlwriter_start_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string'], +'xmlwriter_start_element_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string'], +'xmlwriter_start_pi' => ['bool', 'xmlwriter'=>'resource', 'target'=>'string'], +'xmlwriter_text' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], +'xmlwriter_write_attribute' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], +'xmlwriter_write_attribute_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], +'xmlwriter_write_cdata' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], +'xmlwriter_write_comment' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], +'xmlwriter_write_dtd' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'pubid'=>'string', 'sysid'=>'string', 'subset'=>'string'], +'xmlwriter_write_dtd_attlist' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], +'xmlwriter_write_dtd_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], +'xmlwriter_write_dtd_entity' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string', 'pe'=>'int', 'pubid'=>'string', 'sysid'=>'string', 'ndataid'=>'string'], +'xmlwriter_write_element' => ['bool', 'xmlwriter'=>'resource', 'name'=>'string', 'content'=>'string'], +'xmlwriter_write_element_ns' => ['bool', 'xmlwriter'=>'resource', 'prefix'=>'string', 'name'=>'string', 'uri'=>'string', 'content'=>'string'], +'xmlwriter_write_pi' => ['bool', 'xmlwriter'=>'resource', 'target'=>'string', 'content'=>'string'], +'xmlwriter_write_raw' => ['bool', 'xmlwriter'=>'resource', 'content'=>'string'], +'xpath_new_context' => ['XPathContext', 'dom_document'=>'DOMDocument'], +'xpath_register_ns' => ['bool', 'xpath_context'=>'xpathcontext', 'prefix'=>'string', 'uri'=>'string'], +'xpath_register_ns_auto' => ['bool', 'xpath_context'=>'xpathcontext', 'context_node='=>'object'], +'xptr_new_context' => ['XPathContext'], +'xsl_xsltprocessor_get_parameter' => ['string', 'namespace'=>'string', 'name'=>'string'], +'xsl_xsltprocessor_get_security_prefs' => ['int'], +'xsl_xsltprocessor_has_exslt_support' => ['bool'], +'xsl_xsltprocessor_register_php_functions' => ['', 'restrict'=>''], +'xsl_xsltprocessor_remove_parameter' => ['bool', 'namespace'=>'string', 'name'=>'string'], +'xsl_xsltprocessor_set_parameter' => ['bool', 'namespace'=>'string', 'name'=>'', 'value'=>'string'], +'xsl_xsltprocessor_set_profiling' => ['bool', 'filename'=>'string'], +'xsl_xsltprocessor_set_security_prefs' => ['int', 'securityprefs'=>'int'], +'xsl_xsltprocessor_transform_to_uri' => ['int', 'doc'=>'DOMDocument', 'uri'=>'string'], +'xsl_xsltprocessor_transform_to_xml' => ['string', 'doc'=>'DOMDocument'], +'xslt_backend_info' => ['string'], +'xslt_backend_name' => ['string'], +'xslt_backend_version' => ['string'], +'xslt_create' => ['resource'], +'xslt_errno' => ['int', 'xh'=>''], +'xslt_error' => ['string', 'xh'=>''], +'xslt_free' => ['', 'xh'=>''], +'xslt_getopt' => ['int', 'processor'=>''], +'xslt_process' => ['', 'xh'=>'', 'xmlcontainer'=>'string', 'xslcontainer'=>'string', 'resultcontainer='=>'string', 'arguments='=>'array', 'parameters='=>'array'], +'xslt_set_base' => ['', 'xh'=>'', 'uri'=>'string'], +'xslt_set_encoding' => ['', 'xh'=>'', 'encoding'=>'string'], +'xslt_set_error_handler' => ['', 'xh'=>'', 'handler'=>''], +'xslt_set_log' => ['', 'xh'=>'', 'log='=>''], +'xslt_set_object' => ['bool', 'processor'=>'', 'obj'=>'object'], +'xslt_set_sax_handler' => ['', 'xh'=>'', 'handlers'=>'array'], +'xslt_set_sax_handlers' => ['', 'processor'=>'', 'handlers'=>'array'], +'xslt_set_scheme_handler' => ['', 'xh'=>'', 'handlers'=>'array'], +'xslt_set_scheme_handlers' => ['', 'xh'=>'', 'handlers'=>'array'], +'xslt_setopt' => ['', 'processor'=>'', 'newmask'=>'int'], +'XSLTProcessor::getParameter' => ['string', 'namespaceuri'=>'string', 'localname'=>'string'], +'XsltProcessor::getSecurityPrefs' => ['int'], +'XSLTProcessor::hasExsltSupport' => ['bool'], +'XSLTProcessor::importStylesheet' => ['bool', 'stylesheet'=>'object'], +'XSLTProcessor::registerPHPFunctions' => ['void', 'restrict='=>'mixed'], +'XSLTProcessor::removeParameter' => ['bool', 'namespaceuri'=>'string', 'localname'=>'string'], +'XSLTProcessor::setParameter' => ['bool', 'namespace'=>'string', 'name'=>'string', 'value'=>'string'], +'XSLTProcessor::setParameter\'1' => ['bool', 'namespace'=>'string', 'options'=>'array'], +'XSLTProcessor::setProfiling' => ['bool', 'filename'=>'string'], +'XsltProcessor::setSecurityPrefs' => ['int', 'securityPrefs'=>'int'], +'XSLTProcessor::transformToDoc' => ['DOMDocument', 'doc'=>'DOMNode'], +'XSLTProcessor::transformToURI' => ['int', 'doc'=>'DOMDocument', 'uri'=>'string'], +'XSLTProcessor::transformToXML' => ['string', 'doc'=>'DOMDocument'], +'Yaconf::get' => ['mixed', 'name'=>'string', 'default_value='=>'mixed'], +'Yaconf::has' => ['bool', 'name'=>'string'], +'Yaf_Action_Abstract::__construct' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract', 'view'=>'Yaf_View_Interface', 'invokeArgs='=>'?array'], +'Yaf_Action_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'?array'], +'Yaf_Action_Abstract::execute' => ['mixed', 'arg='=>'mixed', '...args='=>'mixed'], +'Yaf_Action_Abstract::forward' => ['bool', 'module'=>'string', 'controller='=>'string', 'action='=>'string', 'parameters='=>'?array'], +'Yaf_Action_Abstract::getController' => ['Yaf_Controller_Abstract'], +'Yaf_Action_Abstract::getInvokeArg' => ['mixed|null', 'name'=>'string'], +'Yaf_Action_Abstract::getInvokeArgs' => ['array'], +'Yaf_Action_Abstract::getModuleName' => ['string'], +'Yaf_Action_Abstract::getRequest' => ['Yaf_Request_Abstract'], +'Yaf_Action_Abstract::getResponse' => ['Yaf_Response_Abstract'], +'Yaf_Action_Abstract::getView' => ['Yaf_View_Interface'], +'Yaf_Action_Abstract::getViewpath' => ['string'], +'Yaf_Action_Abstract::init' => [''], +'Yaf_Action_Abstract::initView' => ['Yaf_Response_Abstract', 'options='=>'?array'], +'Yaf_Action_Abstract::redirect' => ['bool', 'url'=>'string'], +'Yaf_Action_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'?array'], +'Yaf_Action_Abstract::setViewpath' => ['bool', 'view_directory'=>'string'], +'Yaf_Application::__clone' => ['void'], +'Yaf_Application::__construct' => ['void', 'config'=>'mixed', 'envrion='=>'string'], +'Yaf_Application::__destruct' => ['void'], +'Yaf_Application::__sleep' => ['void'], +'Yaf_Application::__wakeup' => ['void'], +'Yaf_Application::app' => ['void'], +'Yaf_Application::bootstrap' => ['void', 'bootstrap='=>'Yaf_Bootstrap_Abstract'], +'Yaf_Application::clearLastError' => ['Yaf_Application'], +'Yaf_Application::environ' => ['void'], +'Yaf_Application::execute' => ['void', 'entry'=>'callable', '...args'=>'string'], +'Yaf_Application::getAppDirectory' => ['Yaf_Application'], +'Yaf_Application::getConfig' => ['Yaf_Config_Abstract'], +'Yaf_Application::getDispatcher' => ['Yaf_Dispatcher'], +'Yaf_Application::getLastErrorMsg' => ['string'], +'Yaf_Application::getLastErrorNo' => ['int'], +'Yaf_Application::getModules' => ['array'], +'Yaf_Application::run' => ['void'], +'Yaf_Application::setAppDirectory' => ['Yaf_Application', 'directory'=>'string'], +'Yaf_Config_Abstract::get' => ['mixed', 'name'=>'string', 'value'=>'mixed'], +'Yaf_Config_Abstract::readonly' => ['bool'], +'Yaf_Config_Abstract::set' => ['Yaf_Config_Abstract'], +'Yaf_Config_Abstract::toArray' => ['array'], +'Yaf_Config_Ini::__construct' => ['void', 'config_file'=>'string', 'section='=>'string'], +'Yaf_Config_Ini::__get' => ['void', 'name='=>'string'], +'Yaf_Config_Ini::__isset' => ['void', 'name'=>'string'], +'Yaf_Config_Ini::__set' => ['void', 'name'=>'string', 'value'=>'mixed'], +'Yaf_Config_Ini::count' => ['void'], +'Yaf_Config_Ini::current' => ['void'], +'Yaf_Config_Ini::get' => ['mixed', 'name='=>'mixed'], +'Yaf_Config_Ini::key' => ['void'], +'Yaf_Config_Ini::next' => ['void'], +'Yaf_Config_Ini::offsetExists' => ['void', 'name'=>'string'], +'Yaf_Config_Ini::offsetGet' => ['void', 'name'=>'string'], +'Yaf_Config_Ini::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'], +'Yaf_Config_Ini::offsetUnset' => ['void', 'name'=>'string'], +'Yaf_Config_Ini::readonly' => ['void'], +'Yaf_Config_Ini::rewind' => ['void'], +'Yaf_Config_Ini::set' => ['Yaf_Config_Abstract', 'name'=>'string', 'value'=>'mixed'], +'Yaf_Config_Ini::toArray' => ['array'], +'Yaf_Config_Ini::valid' => ['void'], +'Yaf_Config_Simple::__construct' => ['void', 'config_file'=>'string', 'section='=>'string'], +'Yaf_Config_Simple::__get' => ['void', 'name='=>'string'], +'Yaf_Config_Simple::__isset' => ['void', 'name'=>'string'], +'Yaf_Config_Simple::__set' => ['void', 'name'=>'string', 'value'=>'string'], +'Yaf_Config_Simple::count' => ['void'], +'Yaf_Config_Simple::current' => ['void'], +'Yaf_Config_Simple::get' => ['mixed', 'name='=>'mixed'], +'Yaf_Config_Simple::key' => ['void'], +'Yaf_Config_Simple::next' => ['void'], +'Yaf_Config_Simple::offsetExists' => ['void', 'name'=>'string'], +'Yaf_Config_Simple::offsetGet' => ['void', 'name'=>'string'], +'Yaf_Config_Simple::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'], +'Yaf_Config_Simple::offsetUnset' => ['void', 'name'=>'string'], +'Yaf_Config_Simple::readonly' => ['void'], +'Yaf_Config_Simple::rewind' => ['void'], +'Yaf_Config_Simple::set' => ['Yaf_Config_Abstract', 'name'=>'string', 'value'=>'mixed'], +'Yaf_Config_Simple::toArray' => ['array'], +'Yaf_Config_Simple::valid' => ['void'], +'Yaf_Controller_Abstract::__clone' => ['void'], +'Yaf_Controller_Abstract::__construct' => ['void'], +'Yaf_Controller_Abstract::display' => ['bool', 'tpl'=>'string', 'parameters='=>'array'], +'Yaf_Controller_Abstract::forward' => ['void', 'action'=>'string', 'parameters='=>'array'], +'Yaf_Controller_Abstract::forward\'1' => ['void', 'controller'=>'string', 'action'=>'string', 'parameters='=>'array'], +'Yaf_Controller_Abstract::forward\'2' => ['void', 'module'=>'string', 'controller'=>'string', 'action'=>'string', 'parameters='=>'array'], +'Yaf_Controller_Abstract::getInvokeArg' => ['void', 'name'=>'string'], +'Yaf_Controller_Abstract::getInvokeArgs' => ['void'], +'Yaf_Controller_Abstract::getModuleName' => ['string'], +'Yaf_Controller_Abstract::getRequest' => ['Yaf_Request_Abstract'], +'Yaf_Controller_Abstract::getResponse' => ['Yaf_Response_Abstract'], +'Yaf_Controller_Abstract::getView' => ['Yaf_View_Interface'], +'Yaf_Controller_Abstract::getViewpath' => ['void'], +'Yaf_Controller_Abstract::init' => ['void'], +'Yaf_Controller_Abstract::initView' => ['void', 'options='=>'array'], +'Yaf_Controller_Abstract::redirect' => ['bool', 'url'=>'string'], +'Yaf_Controller_Abstract::render' => ['string', 'tpl'=>'string', 'parameters='=>'array'], +'Yaf_Controller_Abstract::setViewpath' => ['void', 'view_directory'=>'string'], +'Yaf_Dispatcher::__clone' => ['void'], +'Yaf_Dispatcher::__construct' => ['void'], +'Yaf_Dispatcher::__sleep' => ['void'], +'Yaf_Dispatcher::__wakeup' => ['void'], +'Yaf_Dispatcher::autoRender' => ['Yaf_Dispatcher', 'flag='=>'bool'], +'Yaf_Dispatcher::catchException' => ['Yaf_Dispatcher', 'flag='=>'bool'], +'Yaf_Dispatcher::disableView' => ['bool'], +'Yaf_Dispatcher::dispatch' => ['Yaf_Response_Abstract', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Dispatcher::enableView' => ['Yaf_Dispatcher'], +'Yaf_Dispatcher::flushInstantly' => ['Yaf_Dispatcher', 'flag='=>'bool'], +'Yaf_Dispatcher::getApplication' => ['Yaf_Application'], +'Yaf_Dispatcher::getInstance' => ['Yaf_Dispatcher'], +'Yaf_Dispatcher::getRequest' => ['Yaf_Request_Abstract'], +'Yaf_Dispatcher::getRouter' => ['Yaf_Router'], +'Yaf_Dispatcher::initView' => ['Yaf_View_Interface', 'templates_dir'=>'string', 'options='=>'array'], +'Yaf_Dispatcher::registerPlugin' => ['Yaf_Dispatcher', 'plugin'=>'Yaf_Plugin_Abstract'], +'Yaf_Dispatcher::returnResponse' => ['Yaf_Dispatcher', 'flag'=>'bool'], +'Yaf_Dispatcher::setDefaultAction' => ['Yaf_Dispatcher', 'action'=>'string'], +'Yaf_Dispatcher::setDefaultController' => ['Yaf_Dispatcher', 'controller'=>'string'], +'Yaf_Dispatcher::setDefaultModule' => ['Yaf_Dispatcher', 'module'=>'string'], +'Yaf_Dispatcher::setErrorHandler' => ['Yaf_Dispatcher', 'callback'=>'call', 'error_types'=>'int'], +'Yaf_Dispatcher::setRequest' => ['Yaf_Dispatcher', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Dispatcher::setView' => ['Yaf_Dispatcher', 'view'=>'Yaf_View_Interface'], +'Yaf_Dispatcher::throwException' => ['Yaf_Dispatcher', 'flag='=>'bool'], +'Yaf_Exception::__construct' => ['void'], +'Yaf_Exception::getPrevious' => ['void'], +'Yaf_Loader::__clone' => ['void'], +'Yaf_Loader::__construct' => ['void'], +'Yaf_Loader::__sleep' => ['void'], +'Yaf_Loader::__wakeup' => ['void'], +'Yaf_Loader::autoload' => ['void'], +'Yaf_Loader::clearLocalNamespace' => ['void'], +'Yaf_Loader::getInstance' => ['void'], +'Yaf_Loader::getLibraryPath' => ['Yaf_Loader', 'is_global='=>'bool'], +'Yaf_Loader::getLocalNamespace' => ['void'], +'Yaf_Loader::import' => ['void'], +'Yaf_Loader::isLocalName' => ['void'], +'Yaf_Loader::registerLocalNamespace' => ['void', 'prefix'=>'mixed'], +'Yaf_Loader::setLibraryPath' => ['Yaf_Loader', 'directory'=>'string', 'is_global='=>'bool'], +'Yaf_Plugin_Abstract::dispatchLoopShutdown' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], +'Yaf_Plugin_Abstract::dispatchLoopStartup' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], +'Yaf_Plugin_Abstract::postDispatch' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], +'Yaf_Plugin_Abstract::preDispatch' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], +'Yaf_Plugin_Abstract::preResponse' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], +'Yaf_Plugin_Abstract::routerShutdown' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], +'Yaf_Plugin_Abstract::routerStartup' => ['void', 'request'=>'Yaf_Request_Abstract', 'response'=>'Yaf_Response_Abstract'], +'Yaf_Registry::__clone' => ['void'], +'Yaf_Registry::__construct' => ['void'], +'Yaf_Registry::del' => ['void', 'name'=>'string'], +'Yaf_Registry::get' => ['mixed', 'name'=>'string'], +'Yaf_Registry::has' => ['bool', 'name'=>'string'], +'Yaf_Registry::set' => ['bool', 'name'=>'string', 'value'=>'string'], +'Yaf_Request_Abstract::getActionName' => ['void'], +'Yaf_Request_Abstract::getBaseUri' => ['void'], +'Yaf_Request_Abstract::getControllerName' => ['void'], +'Yaf_Request_Abstract::getEnv' => ['void', 'name'=>'string', 'default='=>'string'], +'Yaf_Request_Abstract::getException' => ['void'], +'Yaf_Request_Abstract::getLanguage' => ['void'], +'Yaf_Request_Abstract::getMethod' => ['void'], +'Yaf_Request_Abstract::getModuleName' => ['void'], +'Yaf_Request_Abstract::getParam' => ['void', 'name'=>'string', 'default='=>'string'], +'Yaf_Request_Abstract::getParams' => ['void'], +'Yaf_Request_Abstract::getRequestUri' => ['void'], +'Yaf_Request_Abstract::getServer' => ['void', 'name'=>'string', 'default='=>'string'], +'Yaf_Request_Abstract::isCli' => ['void'], +'Yaf_Request_Abstract::isDispatched' => ['void'], +'Yaf_Request_Abstract::isGet' => ['void'], +'Yaf_Request_Abstract::isHead' => ['void'], +'Yaf_Request_Abstract::isOptions' => ['void'], +'Yaf_Request_Abstract::isPost' => ['void'], +'Yaf_Request_Abstract::isPut' => ['void'], +'Yaf_Request_Abstract::isRouted' => ['void'], +'Yaf_Request_Abstract::isXmlHttpRequest' => ['void'], +'Yaf_Request_Abstract::setActionName' => ['void', 'action'=>'string'], +'Yaf_Request_Abstract::setBaseUri' => ['bool', 'uir'=>'string'], +'Yaf_Request_Abstract::setControllerName' => ['void', 'controller'=>'string'], +'Yaf_Request_Abstract::setDispatched' => ['void'], +'Yaf_Request_Abstract::setModuleName' => ['void', 'module'=>'string'], +'Yaf_Request_Abstract::setParam' => ['void', 'name'=>'string', 'value='=>'string'], +'Yaf_Request_Abstract::setRequestUri' => ['void', 'uir'=>'string'], +'Yaf_Request_Abstract::setRouted' => ['void', 'flag='=>'string'], +'Yaf_Request_Http::__clone' => ['void'], +'Yaf_Request_Http::__construct' => ['void'], +'Yaf_Request_Http::get' => ['mixed', 'name'=>'string', 'default='=>'string'], +'Yaf_Request_Http::getActionName' => ['string'], +'Yaf_Request_Http::getBaseUri' => ['string'], +'Yaf_Request_Http::getControllerName' => ['string'], +'Yaf_Request_Http::getCookie' => ['mixed', 'name'=>'string', 'default='=>'string'], +'Yaf_Request_Http::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'], +'Yaf_Request_Http::getException' => ['Yaf_Exception'], +'Yaf_Request_Http::getFiles' => ['void'], +'Yaf_Request_Http::getLanguage' => ['string'], +'Yaf_Request_Http::getMethod' => ['string'], +'Yaf_Request_Http::getModuleName' => ['string'], +'Yaf_Request_Http::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'], +'Yaf_Request_Http::getParams' => ['array'], +'Yaf_Request_Http::getPost' => ['mixed', 'name'=>'string', 'default='=>'string'], +'Yaf_Request_Http::getQuery' => ['mixed', 'name'=>'string', 'default='=>'string'], +'Yaf_Request_Http::getRaw' => ['mixed'], +'Yaf_Request_Http::getRequest' => ['void'], +'Yaf_Request_Http::getRequestUri' => ['string'], +'Yaf_Request_Http::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'], +'Yaf_Request_Http::isCli' => ['bool'], +'Yaf_Request_Http::isDispatched' => ['bool'], +'Yaf_Request_Http::isGet' => ['bool'], +'Yaf_Request_Http::isHead' => ['bool'], +'Yaf_Request_Http::isOptions' => ['bool'], +'Yaf_Request_Http::isPost' => ['bool'], +'Yaf_Request_Http::isPut' => ['bool'], +'Yaf_Request_Http::isRouted' => ['bool'], +'Yaf_Request_Http::isXmlHttpRequest' => ['bool'], +'Yaf_Request_Http::setActionName' => ['Yaf_Request_Abstract|bool', 'action'=>'string'], +'Yaf_Request_Http::setBaseUri' => ['bool', 'uri'=>'string'], +'Yaf_Request_Http::setControllerName' => ['Yaf_Request_Abstract|bool', 'controller'=>'string'], +'Yaf_Request_Http::setDispatched' => ['bool'], +'Yaf_Request_Http::setModuleName' => ['Yaf_Request_Abstract|bool', 'module'=>'string'], +'Yaf_Request_Http::setParam' => ['Yaf_Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'], +'Yaf_Request_Http::setRequestUri' => ['', 'uri'=>'string'], +'Yaf_Request_Http::setRouted' => ['Yaf_Request_Abstract|bool'], +'Yaf_Request_Simple::__clone' => ['void'], +'Yaf_Request_Simple::__construct' => ['void'], +'Yaf_Request_Simple::get' => ['void'], +'Yaf_Request_Simple::getActionName' => ['string'], +'Yaf_Request_Simple::getBaseUri' => ['string'], +'Yaf_Request_Simple::getControllerName' => ['string'], +'Yaf_Request_Simple::getCookie' => ['void'], +'Yaf_Request_Simple::getEnv' => ['mixed', 'name='=>'string', 'default='=>'mixed'], +'Yaf_Request_Simple::getException' => ['Yaf_Exception'], +'Yaf_Request_Simple::getFiles' => ['void'], +'Yaf_Request_Simple::getLanguage' => ['string'], +'Yaf_Request_Simple::getMethod' => ['string'], +'Yaf_Request_Simple::getModuleName' => ['string'], +'Yaf_Request_Simple::getParam' => ['mixed', 'name'=>'string', 'default='=>'mixed'], +'Yaf_Request_Simple::getParams' => ['array'], +'Yaf_Request_Simple::getPost' => ['void'], +'Yaf_Request_Simple::getQuery' => ['void'], +'Yaf_Request_Simple::getRequest' => ['void'], +'Yaf_Request_Simple::getRequestUri' => ['string'], +'Yaf_Request_Simple::getServer' => ['mixed', 'name='=>'string', 'default='=>'mixed'], +'Yaf_Request_Simple::isCli' => ['bool'], +'Yaf_Request_Simple::isDispatched' => ['bool'], +'Yaf_Request_Simple::isGet' => ['bool'], +'Yaf_Request_Simple::isHead' => ['bool'], +'Yaf_Request_Simple::isOptions' => ['bool'], +'Yaf_Request_Simple::isPost' => ['bool'], +'Yaf_Request_Simple::isPut' => ['bool'], +'Yaf_Request_Simple::isRouted' => ['bool'], +'Yaf_Request_Simple::isXmlHttpRequest' => ['void'], +'Yaf_Request_Simple::setActionName' => ['Yaf_Request_Abstract|bool', 'action'=>'string'], +'Yaf_Request_Simple::setBaseUri' => ['bool', 'uri'=>'string'], +'Yaf_Request_Simple::setControllerName' => ['Yaf_Request_Abstract|bool', 'controller'=>'string'], +'Yaf_Request_Simple::setDispatched' => ['bool'], +'Yaf_Request_Simple::setModuleName' => ['Yaf_Request_Abstract|bool', 'module'=>'string'], +'Yaf_Request_Simple::setParam' => ['Yaf_Request_Abstract|bool', 'name'=>'array|string', 'value='=>'string'], +'Yaf_Request_Simple::setRequestUri' => ['', 'uri'=>'string'], +'Yaf_Request_Simple::setRouted' => ['Yaf_Request_Abstract|bool'], +'Yaf_Response_Abstract::__clone' => ['void'], +'Yaf_Response_Abstract::__construct' => ['void'], +'Yaf_Response_Abstract::__destruct' => ['void'], +'Yaf_Response_Abstract::__toString' => ['string'], +'Yaf_Response_Abstract::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Abstract::clearBody' => ['bool', 'key='=>'string'], +'Yaf_Response_Abstract::clearHeaders' => ['void'], +'Yaf_Response_Abstract::getBody' => ['mixed', 'key='=>'string'], +'Yaf_Response_Abstract::getHeader' => ['void'], +'Yaf_Response_Abstract::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Abstract::response' => ['void'], +'Yaf_Response_Abstract::setAllHeaders' => ['void'], +'Yaf_Response_Abstract::setBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Abstract::setHeader' => ['void'], +'Yaf_Response_Abstract::setRedirect' => ['void'], +'Yaf_Response_Cli::__clone' => [''], +'Yaf_Response_Cli::__construct' => ['void'], +'Yaf_Response_Cli::__destruct' => [''], +'Yaf_Response_Cli::__toString' => ['string'], +'Yaf_Response_Cli::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Cli::clearBody' => ['bool', 'key='=>'string'], +'Yaf_Response_Cli::getBody' => ['mixed', 'key='=>'null|string'], +'Yaf_Response_Cli::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Cli::setBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Http::__clone' => [''], +'Yaf_Response_Http::__construct' => ['void'], +'Yaf_Response_Http::__destruct' => [''], +'Yaf_Response_Http::__toString' => ['string'], +'Yaf_Response_Http::appendBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Http::clearBody' => ['bool', 'key='=>'string'], +'Yaf_Response_Http::clearHeaders' => ['Yaf_Response_Abstract|false', 'name='=>'string'], +'Yaf_Response_Http::getBody' => ['mixed', 'key='=>'null|string'], +'Yaf_Response_Http::getHeader' => ['mixed', 'name='=>'string'], +'Yaf_Response_Http::prependBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Http::response' => ['bool'], +'Yaf_Response_Http::setAllHeaders' => ['bool', 'headers'=>'array'], +'Yaf_Response_Http::setBody' => ['bool', 'content'=>'string', 'key='=>'string'], +'Yaf_Response_Http::setHeader' => ['bool', 'name'=>'string', 'value'=>'string', 'replace='=>'bool|false', 'response_code='=>'int'], +'Yaf_Response_Http::setRedirect' => ['bool', 'url'=>'string'], +'Yaf_Route_Interface::__construct' => ['void'], +'Yaf_Route_Interface::assemble' => ['string', 'info'=>'array', 'query='=>'array'], +'Yaf_Route_Interface::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Route_Map::__construct' => ['void', 'controller_prefer='=>'string', 'delimiter='=>'string'], +'Yaf_Route_Map::assemble' => ['string', 'info'=>'array', 'query='=>'array'], +'Yaf_Route_Map::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Route_Regex::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'map='=>'array', 'verify='=>'array', 'reverse='=>'string'], +'Yaf_Route_Regex::addConfig' => ['Yaf_Router|bool', 'config'=>'Yaf_Config_Abstract'], +'Yaf_Route_Regex::addRoute' => ['Yaf_Router|bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'], +'Yaf_Route_Regex::assemble' => ['string', 'info'=>'array', 'query='=>'array'], +'Yaf_Route_Regex::getCurrentRoute' => ['string'], +'Yaf_Route_Regex::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'], +'Yaf_Route_Regex::getRoutes' => ['Yaf_Route_Interface[]'], +'Yaf_Route_Regex::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Route_Rewrite::__construct' => ['void', 'match'=>'string', 'route'=>'array', 'verify='=>'array'], +'Yaf_Route_Rewrite::addConfig' => ['Yaf_Router|bool', 'config'=>'Yaf_Config_Abstract'], +'Yaf_Route_Rewrite::addRoute' => ['Yaf_Router|bool', 'name'=>'string', 'route'=>'Yaf_Route_Interface'], +'Yaf_Route_Rewrite::assemble' => ['string', 'info'=>'array', 'query='=>'array'], +'Yaf_Route_Rewrite::getCurrentRoute' => ['string'], +'Yaf_Route_Rewrite::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'], +'Yaf_Route_Rewrite::getRoutes' => ['Yaf_Route_Interface[]'], +'Yaf_Route_Rewrite::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Route_Simple::__construct' => ['void', 'module_name'=>'string', 'controller_name'=>'string', 'action_name'=>'string'], +'Yaf_Route_Simple::assemble' => ['string', 'info'=>'array', 'query='=>'array'], +'Yaf_Route_Simple::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Route_Static::assemble' => ['string', 'info'=>'array', 'query='=>'array'], +'Yaf_Route_Static::match' => ['void', 'uri'=>'string'], +'Yaf_Route_Static::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Route_Supervar::__construct' => ['void', 'supervar_name'=>'string'], +'Yaf_Route_Supervar::assemble' => ['string', 'info'=>'array', 'query='=>'array'], +'Yaf_Route_Supervar::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Router::__construct' => ['void'], +'Yaf_Router::addConfig' => ['bool', 'config'=>'Yaf_Config_Abstract'], +'Yaf_Router::addRoute' => ['bool', 'name'=>'string', 'route'=>'Yaf_Route_Abstract'], +'Yaf_Router::getCurrentRoute' => ['string'], +'Yaf_Router::getRoute' => ['Yaf_Route_Interface', 'name'=>'string'], +'Yaf_Router::getRoutes' => ['mixed'], +'Yaf_Router::route' => ['bool', 'request'=>'Yaf_Request_Abstract'], +'Yaf_Session::__clone' => ['void'], +'Yaf_Session::__construct' => ['void'], +'Yaf_Session::__get' => ['void', 'name'=>'string'], +'Yaf_Session::__isset' => ['void', 'name'=>'string'], +'Yaf_Session::__set' => ['void', 'name'=>'string', 'value'=>'string'], +'Yaf_Session::__sleep' => ['void'], +'Yaf_Session::__unset' => ['void', 'name'=>'string'], +'Yaf_Session::__wakeup' => ['void'], +'Yaf_Session::count' => ['void'], +'Yaf_Session::current' => ['void'], +'Yaf_Session::del' => ['void', 'name'=>'string'], +'Yaf_Session::get' => ['mixed', 'name'=>'string'], +'Yaf_Session::getInstance' => ['void'], +'Yaf_Session::has' => ['void', 'name'=>'string'], +'Yaf_Session::key' => ['void'], +'Yaf_Session::next' => ['void'], +'Yaf_Session::offsetExists' => ['void', 'name'=>'string'], +'Yaf_Session::offsetGet' => ['void', 'name'=>'string'], +'Yaf_Session::offsetSet' => ['void', 'name'=>'string', 'value'=>'string'], +'Yaf_Session::offsetUnset' => ['void', 'name'=>'string'], +'Yaf_Session::rewind' => ['void'], +'Yaf_Session::set' => ['Yaf_Session|bool', 'name'=>'string', 'value'=>'mixed'], +'Yaf_Session::start' => ['void'], +'Yaf_Session::valid' => ['void'], +'Yaf_View_Interface::assign' => ['bool', 'name'=>'string', 'value='=>'string'], +'Yaf_View_Interface::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'array'], +'Yaf_View_Interface::getScriptPath' => ['void'], +'Yaf_View_Interface::render' => ['string', 'tpl'=>'string', 'tpl_vars='=>'array'], +'Yaf_View_Interface::setScriptPath' => ['void', 'template_dir'=>'string'], +'Yaf_View_Simple::__construct' => ['void', 'tempalte_dir'=>'string', 'options='=>'array'], +'Yaf_View_Simple::__get' => ['void', 'name='=>'string'], +'Yaf_View_Simple::__isset' => ['void', 'name'=>'string'], +'Yaf_View_Simple::__set' => ['void', 'name'=>'string', 'value'=>'mixed'], +'Yaf_View_Simple::assign' => ['bool', 'name'=>'string', 'value='=>'mixed'], +'Yaf_View_Simple::assignRef' => ['bool', 'name'=>'string', '&rw_value'=>'mixed'], +'Yaf_View_Simple::clear' => ['bool', 'name='=>'string'], +'Yaf_View_Simple::display' => ['bool', 'tpl'=>'string', 'tpl_vars='=>'array'], +'Yaf_View_Simple::eval' => ['string', 'tpl_content'=>'string', 'tpl_vars='=>'array'], +'Yaf_View_Simple::getScriptPath' => ['string'], +'Yaf_View_Simple::render' => ['string', 'tpl'=>'string', 'tpl_vars='=>'array'], +'Yaf_View_Simple::setScriptPath' => ['bool', 'template_dir'=>'string'], +'yaml_emit' => ['string', 'data'=>'mixed', 'encoding='=>'int', 'linebreak='=>'int'], +'yaml_emit_file' => ['bool', 'filename'=>'string', 'data'=>'mixed', 'encoding='=>'int', 'linebreak='=>'int'], +'yaml_parse' => ['mixed', 'input'=>'string', 'pos='=>'int', 'ndocs='=>'int', 'callbacks='=>'array'], +'yaml_parse_file' => ['mixed', 'filename'=>'string', 'pos='=>'int', 'ndocs='=>'int', 'callbacks='=>'array'], +'yaml_parse_url' => ['mixed', 'url'=>'string', 'pos='=>'int', 'ndocs='=>'int', 'callbacks='=>'array'], +'Yar_Client::__call' => ['void', 'method'=>'string', 'parameters'=>'array'], +'Yar_Client::__construct' => ['void', 'url'=>'string'], +'Yar_Client::setOpt' => ['bool', 'name'=>'int', 'value'=>'mixed'], +'Yar_Client_Exception::getType' => ['void'], +'Yar_Concurrent_Client::call' => ['int', 'uri'=>'string', 'method'=>'string', 'parameters'=>'array', 'callback='=>'callable'], +'Yar_Concurrent_Client::loop' => ['bool', 'callback='=>'callable', 'error_callback='=>'callable'], +'Yar_Concurrent_Client::reset' => ['bool'], +'Yar_Server::__construct' => ['void', 'obj'=>'Object'], +'Yar_Server::handle' => ['bool'], +'Yar_Server_Exception::getType' => ['string'], +'yaz_addinfo' => ['string', 'id'=>'resource'], +'yaz_ccl_conf' => ['void', 'id'=>'resource', 'config'=>'array'], +'yaz_ccl_parse' => ['bool', 'id'=>'resource', 'query'=>'string', 'result'=>'array'], +'yaz_close' => ['bool', 'id'=>'resource'], +'yaz_connect' => ['mixed', 'zurl'=>'string', 'options='=>'mixed'], +'yaz_database' => ['bool', 'id'=>'resource', 'databases'=>'string'], +'yaz_element' => ['bool', 'id'=>'resource', 'elementset'=>'string'], +'yaz_errno' => ['int', 'id'=>'resource'], +'yaz_error' => ['string', 'id'=>'resource'], +'yaz_es' => ['void', 'id'=>'resource', 'type'=>'string', 'args'=>'array'], +'yaz_es_result' => ['array', 'id'=>'resource'], +'yaz_get_option' => ['string', 'id'=>'resource', 'name'=>'string'], +'yaz_hits' => ['int', 'id'=>'resource', 'searchresult='=>'array'], +'yaz_itemorder' => ['void', 'id'=>'resource', 'args'=>'array'], +'yaz_present' => ['bool', 'id'=>'resource'], +'yaz_range' => ['void', 'id'=>'resource', 'start'=>'int', 'number'=>'int'], +'yaz_record' => ['string', 'id'=>'resource', 'pos'=>'int', 'type'=>'string'], +'yaz_scan' => ['void', 'id'=>'resource', 'type'=>'string', 'startterm'=>'string', 'flags='=>'array'], +'yaz_scan_result' => ['array', 'id'=>'resource', 'result='=>'array'], +'yaz_schema' => ['void', 'id'=>'resource', 'schema'=>'string'], +'yaz_search' => ['bool', 'id'=>'resource', 'type'=>'string', 'query'=>'string'], +'yaz_set_option' => ['', 'id'=>'', 'name'=>'string', 'value'=>'string', 'options'=>'array'], +'yaz_sort' => ['void', 'id'=>'resource', 'criteria'=>'string'], +'yaz_syntax' => ['void', 'id'=>'resource', 'syntax'=>'string'], +'yaz_wait' => ['mixed', 'options='=>'array'], +'yp_all' => ['void', 'domain'=>'string', 'map'=>'string', 'callback'=>'string'], +'yp_cat' => ['array', 'domain'=>'string', 'map'=>'string'], +'yp_err_string' => ['string', 'errorcode'=>'int'], +'yp_errno' => ['int'], +'yp_first' => ['array', 'domain'=>'string', 'map'=>'string'], +'yp_get_default_domain' => ['string'], +'yp_master' => ['string', 'domain'=>'string', 'map'=>'string'], +'yp_match' => ['string', 'domain'=>'string', 'map'=>'string', 'key'=>'string'], +'yp_next' => ['array', 'domain'=>'string', 'map'=>'string', 'key'=>'string'], +'yp_order' => ['int', 'domain'=>'string', 'map'=>'string'], +'zem_get_extension_info_by_id' => [''], +'zem_get_extension_info_by_name' => [''], +'zem_get_extensions_info' => [''], +'zem_get_license_info' => [''], +'zend_current_obfuscation_level' => ['int'], +'zend_disk_cache_clear' => ['bool', 'namespace='=>'mixed|string'], +'zend_disk_cache_delete' => ['mixed|null', 'key'=>''], +'zend_disk_cache_fetch' => ['mixed|null', 'key'=>''], +'zend_disk_cache_store' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int|mixed'], +'zend_get_id' => ['array', 'all_ids='=>'all_ids|false'], +'zend_is_configuration_changed' => [''], +'zend_loader_current_file' => ['string'], +'zend_loader_enabled' => ['bool'], +'zend_loader_file_encoded' => ['bool'], +'zend_loader_file_licensed' => ['array'], +'zend_loader_install_license' => ['bool', 'license_file'=>'license_file', 'override'=>'override'], +'zend_logo_guid' => ['string'], +'zend_obfuscate_class_name' => ['string', 'class_name'=>'class_name'], +'zend_obfuscate_function_name' => ['string', 'function_name'=>'function_name'], +'zend_optimizer_version' => ['string'], +'zend_runtime_obfuscate' => ['void'], +'zend_send_buffer' => ['bool', 'buffer'=>'buffer', 'mime_type'=>'mime_type', 'custom_headers'=>'custom_headers'], +'zend_send_file' => ['bool', 'filename'=>'filename', 'mime_type'=>'mime_type', 'custom_headers'=>'custom_headers'], +'zend_set_configuration_changed' => [''], +'zend_shm_cache_clear' => ['bool', 'namespace='=>'mixed|string'], +'zend_shm_cache_delete' => ['mixed|null', 'key'=>''], +'zend_shm_cache_fetch' => ['mixed|null', 'key'=>''], +'zend_shm_cache_store' => ['bool', 'key'=>'', 'value'=>'', 'ttl='=>'int|mixed'], +'zend_thread_id' => ['int'], +'zend_version' => ['string'], +'ZendAPI_Job::addJobToQueue' => ['int', 'jobqueue_url'=>'string', 'password'=>'string'], +'ZendAPI_Job::getApplicationID' => [''], +'ZendAPI_Job::getEndTime' => [''], +'ZendAPI_Job::getGlobalVariables' => [''], +'ZendAPI_Job::getHost' => [''], +'ZendAPI_Job::getID' => [''], +'ZendAPI_Job::getInterval' => [''], +'ZendAPI_Job::getJobDependency' => [''], +'ZendAPI_Job::getJobName' => [''], +'ZendAPI_Job::getJobPriority' => [''], +'ZendAPI_Job::getJobStatus' => ['int'], +'ZendAPI_Job::getLastPerformedStatus' => ['int'], +'ZendAPI_Job::getOutput' => ['An'], +'ZendAPI_Job::getPreserved' => [''], +'ZendAPI_Job::getProperties' => ['array'], +'ZendAPI_Job::getScheduledTime' => [''], +'ZendAPI_Job::getScript' => [''], +'ZendAPI_Job::getTimeToNextRepeat' => ['int'], +'ZendAPI_Job::getUserVariables' => [''], +'ZendAPI_Job::setApplicationID' => ['', 'app_id'=>''], +'ZendAPI_Job::setGlobalVariables' => ['', 'vars'=>''], +'ZendAPI_Job::setJobDependency' => ['', 'job_id'=>''], +'ZendAPI_Job::setJobName' => ['', 'name'=>''], +'ZendAPI_Job::setJobPriority' => ['', 'priority'=>'int'], +'ZendAPI_Job::setPreserved' => ['', 'preserved'=>''], +'ZendAPI_Job::setRecurrenceData' => ['', 'interval'=>'', 'end_time='=>'mixed'], +'ZendAPI_Job::setScheduledTime' => ['', 'timestamp'=>''], +'ZendAPI_Job::setScript' => ['', 'script'=>''], +'ZendAPI_Job::setUserVariables' => ['', 'vars'=>''], +'ZendAPI_Job::ZendAPI_Job' => ['Job', 'script'=>'script'], +'ZendAPI_Queue::addJob' => ['int', '&job'=>'Job'], +'ZendAPI_Queue::getAllApplicationIDs' => ['array'], +'ZendAPI_Queue::getAllhosts' => ['array'], +'ZendAPI_Queue::getHistoricJobs' => ['array', 'status'=>'int', 'start_time'=>'', 'end_time'=>'', 'index'=>'int', 'count'=>'int', '&total'=>'int'], +'ZendAPI_Queue::getJob' => ['Job', 'job_id'=>'int'], +'ZendAPI_Queue::getJobsInQueue' => ['array', 'filter_options='=>'array', 'max_jobs='=>'int', 'with_globals_and_output='=>'bool|false'], +'ZendAPI_Queue::getLastError' => ['string'], +'ZendAPI_Queue::getNumOfJobsInQueue' => ['int', 'filter_options='=>'array'], +'ZendAPI_Queue::getStatistics' => ['array'], +'ZendAPI_Queue::isScriptExists' => ['bool', 'path'=>'string'], +'ZendAPI_Queue::isSuspend' => ['bool'], +'ZendAPI_Queue::login' => ['bool', 'password'=>'string', 'application_id='=>'int'], +'ZendAPI_Queue::removeJob' => ['bool', 'job_id'=>'array|int'], +'ZendAPI_Queue::requeueJob' => ['bool', 'job'=>'Job'], +'ZendAPI_Queue::resumeJob' => ['bool', 'job_id'=>'array|int'], +'ZendAPI_Queue::resumeQueue' => ['bool'], +'ZendAPI_Queue::setMaxHistoryTime' => ['bool'], +'ZendAPI_Queue::suspendJob' => ['bool', 'job_id'=>'array|int'], +'ZendAPI_Queue::suspendQueue' => ['bool'], +'ZendAPI_Queue::updateJob' => ['int', '&job'=>'Job'], +'ZendAPI_Queue::zendapi_queue' => ['ZendAPI_Queue', 'queue_url'=>'string'], +'zip_close' => ['void', 'zip'=>'resource'], +'zip_entry_close' => ['bool', 'zip_ent'=>'resource'], +'zip_entry_compressedsize' => ['int', 'zip_entry'=>'resource'], +'zip_entry_compressionmethod' => ['string', 'zip_entry'=>'resource'], +'zip_entry_filesize' => ['int', 'zip_entry'=>'resource'], +'zip_entry_name' => ['string', 'zip_entry'=>'resource'], +'zip_entry_open' => ['bool', 'zip_dp'=>'resource', 'zip_entry'=>'resource', 'mode='=>'string'], +'zip_entry_read' => ['string', 'zip_entry'=>'resource', 'len='=>'int'], +'zip_open' => ['resource', 'filename'=>'string'], +'zip_read' => ['resource', 'zip'=>'resource'], +'ZipArchive::addEmptyDir' => ['bool', 'dirname'=>'string'], +'ZipArchive::addFile' => ['bool', 'filepath'=>'string', 'entryname='=>'string', 'start='=>'int', 'length='=>'int'], +'ZipArchive::addFromString' => ['bool', 'entryname'=>'string', 'content'=>'string'], +'ZipArchive::addGlob' => ['bool', 'pattern'=>'string', 'flags='=>'int', 'options='=>'array'], +'ZipArchive::addPattern' => ['bool', 'pattern'=>'string', 'path='=>'string', 'options='=>'array'], +'ZipArchive::close' => ['bool'], +'ZipArchive::count' => ['int'], +'ZipArchive::createEmptyDir' => ['bool', 'dirname'=>'string'], +'ZipArchive::deleteIndex' => ['bool', 'index'=>'int'], +'ZipArchive::deleteName' => ['bool', 'name'=>'string'], +'ZipArchive::extractTo' => ['bool', 'pathto'=>'string', 'files='=>'string[]|string'], +'ZipArchive::getArchiveComment' => ['string', 'flags='=>'int'], +'ZipArchive::getCommentIndex' => ['string', 'index'=>'int', 'flags='=>'int'], +'ZipArchive::getCommentName' => ['string', 'name'=>'string', 'flags='=>'int'], +'ZipArchive::getExternalAttributesIndex' => ['bool', 'index'=>'int', '&w_opsys'=>'int', '&w_attr'=>'int', 'flags='=>'int'], +'ZipArchive::getExternalAttributesName' => ['bool', 'name'=>'string', '&w_opsys'=>'int', '&w_attr'=>'int', 'flags='=>'int'], +'ZipArchive::getFromIndex' => ['string', 'index'=>'int', 'len='=>'int', 'flags='=>'int'], +'ZipArchive::getFromName' => ['string|false', 'entryname'=>'string', 'len='=>'int', 'flags='=>'int'], +'ZipArchive::getNameIndex' => ['string', 'index'=>'int', 'flags='=>'int'], +'ZipArchive::getStatusString' => ['string'], +'ZipArchive::getStream' => ['resource', 'entryname'=>'string'], +'ZipArchive::locateName' => ['int', 'filename'=>'string', 'flags='=>'int'], +'ZipArchive::open' => ['mixed', 'source'=>'string', 'flags='=>'int'], +'ZipArchive::renameIndex' => ['bool', 'index'=>'int', 'new_name'=>'string'], +'ZipArchive::renameName' => ['bool', 'name'=>'string', 'new_name'=>'string'], +'ZipArchive::setArchiveComment' => ['bool', 'comment'=>'string'], +'ZipArchive::setCommentIndex' => ['bool', 'index'=>'int', 'comment'=>'string'], +'ZipArchive::setCommentName' => ['bool', 'name'=>'string', 'comment'=>'string'], +'ZipArchive::setCompressionIndex' => ['bool', 'index'=>'int', 'comp_method'=>'int', 'comp_flags='=>'int'], +'ZipArchive::setCompressionName' => ['bool', 'name'=>'string', 'comp_method'=>'int', 'comp_flags='=>'int'], +'ZipArchive::setEncryptionIndex' => ['bool', 'index'=>'int', 'method'=>'string', 'password='=>'string'], +'ZipArchive::setEncryptionName' => ['bool', 'name'=>'string', 'method'=>'int', 'password='=>'string'], +'ZipArchive::setExternalAttributesIndex' => ['bool', 'index'=>'int', 'opsys'=>'int', 'attr'=>'int', 'flags='=>'int'], +'ZipArchive::setExternalAttributesName' => ['bool', 'name'=>'string', 'opsys'=>'int', 'attr'=>'int', 'flags='=>'int'], +'ZipArchive::setPassword' => ['bool', 'password'=>'string'], +'ZipArchive::statIndex' => ['array|false', 'index'=>'int', 'flags='=>'int'], +'ZipArchive::statName' => ['array|false', 'filename'=>'string', 'flags='=>'int'], +'ZipArchive::unchangeAll' => ['bool'], +'ZipArchive::unchangeArchive' => ['bool'], +'ZipArchive::unchangeIndex' => ['bool', 'index'=>'int'], +'ZipArchive::unchangeName' => ['bool', 'name'=>'string'], +'zlib_decode' => ['string', 'data'=>'string', 'max_decoded_len='=>'int'], +'zlib_encode' => ['string', 'data'=>'string', 'encoding'=>'int', 'level='=>'string|int'], +'zlib_get_coding_type' => ['string|false'], +'ZMQ::__construct' => ['void'], +'ZMQContext::__construct' => ['void', 'io_threads='=>'int', 'is_persistent='=>'bool'], +'ZMQContext::getOpt' => ['mixed', 'key'=>'string'], +'ZMQContext::getSocket' => ['ZMQSocket', 'type'=>'int', 'persistent_id='=>'string', 'on_new_socket='=>'callable'], +'ZMQContext::isPersistent' => ['bool'], +'ZMQContext::setOpt' => ['ZMQContext', 'key'=>'int', 'value'=>'mixed'], +'ZMQDevice::__construct' => ['void', 'frontend'=>'ZMQSocket', 'backend'=>'ZMQSocket', 'listener='=>'ZMQSocket'], +'ZMQDevice::getIdleTimeout' => ['ZMQDevice'], +'ZMQDevice::getTimerTimeout' => ['ZMQDevice'], +'ZMQDevice::run' => ['void'], +'ZMQDevice::setIdleCallback' => ['ZMQDevice', 'cb_func'=>'callable', 'timeout'=>'int', 'user_data='=>'mixed'], +'ZMQDevice::setIdleTimeout' => ['ZMQDevice', 'timeout'=>'int'], +'ZMQDevice::setTimerCallback' => ['ZMQDevice', 'cb_func'=>'callable', 'timeout'=>'int', 'user_data='=>'mixed'], +'ZMQDevice::setTimerTimeout' => ['ZMQDevice', 'timeout'=>'int'], +'ZMQPoll::add' => ['string', 'entry'=>'mixed', 'type'=>'int'], +'ZMQPoll::clear' => ['ZMQPoll'], +'ZMQPoll::count' => ['int'], +'ZMQPoll::getLastErrors' => ['array'], +'ZMQPoll::poll' => ['int', '&w_readable'=>'array', '&w_writable'=>'array', 'timeout='=>'int'], +'ZMQPoll::remove' => ['bool', 'item'=>'mixed'], +'ZMQSocket::__construct' => ['void', 'context'=>'ZMQContext', 'type'=>'int', 'persistent_id='=>'string', 'on_new_socket='=>'callable'], +'ZMQSocket::bind' => ['ZMQSocket', 'dsn'=>'string', 'force='=>'bool'], +'ZMQSocket::connect' => ['ZMQSocket', 'dsn'=>'string', 'force='=>'bool'], +'ZMQSocket::disconnect' => ['ZMQSocket', 'dsn'=>'string'], +'ZMQSocket::getEndpoints' => ['array'], +'ZMQSocket::getPersistentId' => ['string'], +'ZMQSocket::getSocketType' => ['int'], +'ZMQSocket::getSockOpt' => ['mixed', 'key'=>'string'], +'ZMQSocket::isPersistent' => ['bool'], +'ZMQSocket::recv' => ['string', 'mode='=>'int'], +'ZMQSocket::recvMulti' => ['string', 'mode='=>'int'], +'ZMQSocket::send' => ['ZMQSocket', 'message'=>'array', 'mode='=>'int'], +'ZMQSocket::send\'1' => ['ZMQSocket', 'message'=>'string', 'mode='=>'int'], +'ZMQSocket::sendmulti' => ['ZMQSocket', 'message'=>'array', 'mode='=>'int'], +'ZMQSocket::setSockOpt' => ['ZMQSocket', 'key'=>'int', 'value'=>'mixed'], +'ZMQSocket::unbind' => ['ZMQSocket', 'dsn'=>'string'], +'Zookeeper::addAuth' => ['bool', 'scheme'=>'string', 'cert'=>'string', 'completion_cb='=>'callable'], +'Zookeeper::connect' => ['void', 'host'=>'string', 'watcher_cb='=>'callable', 'recv_timeout='=>'int'], +'Zookeeper::create' => ['string', 'path'=>'string', 'value'=>'string', 'acls'=>'array', 'flags='=>'int'], +'Zookeeper::delete' => ['bool', 'path'=>'string', 'version='=>'int'], +'Zookeeper::exists' => ['bool', 'path'=>'string', 'watcher_cb='=>'callable'], +'Zookeeper::get' => ['string', 'path'=>'string', 'watcher_cb='=>'callable', 'stat='=>'array', 'max_size='=>'int'], +'Zookeeper::getAcl' => ['array', 'path'=>'string'], +'Zookeeper::getChildren' => ['array', 'path'=>'string', 'watcher_cb='=>'callable'], +'Zookeeper::getClientId' => ['int'], +'Zookeeper::getRecvTimeout' => ['int'], +'Zookeeper::getState' => ['int'], +'Zookeeper::isRecoverable' => ['bool'], +'Zookeeper::set' => ['bool', 'path'=>'string', 'value'=>'string', 'version='=>'int', 'stat='=>'array'], +'Zookeeper::setAcl' => ['bool', 'path'=>'string', 'version'=>'int', 'acl'=>'array'], +'Zookeeper::setDebugLevel' => ['bool', 'logLevel'=>'int'], +'Zookeeper::setDeterministicConnOrder' => ['bool', 'yesOrNo'=>'bool'], +'Zookeeper::setLogStream' => ['bool', 'stream'=>'resource'], +'Zookeeper::setWatcher' => ['bool', 'watcher_cb'=>'callable'], +'zookeeper_dispatch' => ['void'], +]; diff --git a/vendor/phpstan/phpstan/src/Reflection/ThrowableReflection.php b/vendor/phpstan/phpstan/src/Reflection/ThrowableReflection.php new file mode 100644 index 00000000..8846162e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Reflection/ThrowableReflection.php @@ -0,0 +1,12 @@ + + */ + public function getParameters(): array + { + return []; + } + + public function isVariadic(): bool + { + return true; + } + + public function getReturnType(): Type + { + return new MixedType(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/AllowedArrayKeysTypes.php b/vendor/phpstan/phpstan/src/Rules/Arrays/AllowedArrayKeysTypes.php new file mode 100644 index 00000000..6a2cc625 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/AllowedArrayKeysTypes.php @@ -0,0 +1,27 @@ +propertyReflectionFinder = $propertyReflectionFinder; + $this->ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr::class; + } + + /** + * @param \PhpParser\Node\Expr $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if ( + !$node instanceof Assign + && !$node instanceof AssignOp + ) { + return []; + } + + if (!($node->var instanceof ArrayDimFetch)) { + return []; + } + + if ( + !$node->var->var instanceof \PhpParser\Node\Expr\PropertyFetch + && !$node->var->var instanceof \PhpParser\Node\Expr\StaticPropertyFetch + ) { + return []; + } + + $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node->var->var, $scope); + if ($propertyReflection === null) { + return []; + } + + $assignedToType = $propertyReflection->getType(); + if (!($assignedToType instanceof ArrayType)) { + return []; + } + + if ($node instanceof Assign) { + $assignedValueType = $scope->getType($node->expr); + } else { + $assignedValueType = $scope->getType($node); + } + + $itemType = $assignedToType->getItemType(); + if (!$this->ruleLevelHelper->accepts($itemType, $assignedValueType, $scope->isDeclareStrictTypes())) { + $verbosityLevel = $itemType->isCallable()->and($assignedValueType->isCallable())->yes() ? VerbosityLevel::value() : VerbosityLevel::typeOnly(); + return [ + sprintf( + 'Array (%s) does not accept %s.', + $assignedToType->describe($verbosityLevel), + $assignedValueType->describe($verbosityLevel) + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/AppendedArrayKeyTypeRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/AppendedArrayKeyTypeRule.php new file mode 100644 index 00000000..323db17d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/AppendedArrayKeyTypeRule.php @@ -0,0 +1,94 @@ +propertyReflectionFinder = $propertyReflectionFinder; + $this->checkUnionTypes = $checkUnionTypes; + } + + public function getNodeType(): string + { + return Assign::class; + } + + /** + * @param \PhpParser\Node\Expr\Assign $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if (!($node->var instanceof ArrayDimFetch)) { + return []; + } + + if ( + !$node->var->var instanceof \PhpParser\Node\Expr\PropertyFetch + && !$node->var->var instanceof \PhpParser\Node\Expr\StaticPropertyFetch + ) { + return []; + } + + $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node->var->var, $scope); + if ($propertyReflection === null) { + return []; + } + + $arrayType = $propertyReflection->getType(); + if (!$arrayType instanceof ArrayType) { + return []; + } + + if ($node->var->dim !== null) { + $dimensionType = $scope->getType($node->var->dim); + $isValidKey = AllowedArrayKeysTypes::getType()->isSuperTypeOf($dimensionType); + if (!$isValidKey->yes()) { + // already handled by InvalidKeyInArrayDimFetchRule + return []; + } + + $keyType = ArrayType::castToArrayKeyType($dimensionType); + if (!$this->checkUnionTypes && $keyType instanceof UnionType) { + return []; + } + } else { + $keyType = new IntegerType(); + } + + if (!$arrayType->getIterableKeyType()->isSuperTypeOf($keyType)->yes()) { + return [ + sprintf( + 'Array (%s) does not accept key %s.', + $arrayType->describe(VerbosityLevel::typeOnly()), + $keyType->describe(VerbosityLevel::value()) + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/DeadForeachRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/DeadForeachRule.php new file mode 100644 index 00000000..afc7d04b --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/DeadForeachRule.php @@ -0,0 +1,38 @@ +getType($node->expr); + if ($iterableType->isIterable()->no()) { + return []; + } + + if (!$iterableType->isIterableAtLeastOnce()->no()) { + return []; + } + + return [ + 'Empty array passed to foreach.', + ]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/DuplicateKeysInLiteralArraysRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/DuplicateKeysInLiteralArraysRule.php new file mode 100644 index 00000000..175f57cd --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/DuplicateKeysInLiteralArraysRule.php @@ -0,0 +1,86 @@ +printer = $printer; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\Array_::class; + } + + /** + * @param \PhpParser\Node\Expr\Array_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + $values = []; + $duplicateKeys = []; + $printedValues = []; + $valueLines = []; + foreach ($node->items as $item) { + if ($item === null) { + continue; + } + if ($item->key === null) { + continue; + } + + $key = $item->key; + $keyType = $scope->getType($key); + if ( + !$keyType instanceof ConstantScalarType + ) { + continue; + } + + $printedValue = $this->printer->prettyPrintExpr($key); + $value = $keyType->getValue(); + $printedValues[$value][] = $printedValue; + + if (!isset($valueLines[$value])) { + $valueLines[$value] = $item->getLine(); + } + + $previousCount = count($values); + $values[$value] = $printedValue; + if ($previousCount !== count($values)) { + continue; + } + + $duplicateKeys[$value] = true; + } + + $messages = []; + foreach (array_keys($duplicateKeys) as $value) { + $messages[] = RuleErrorBuilder::message(sprintf( + 'Array has %d %s with value %s (%s).', + count($printedValues[$value]), + count($printedValues[$value]) === 1 ? 'duplicate key' : 'duplicate keys', + var_export($value, true), + implode(', ', $printedValues[$value]) + ))->line($valueLines[$value])->build(); + } + + return $messages; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/InvalidKeyInArrayDimFetchRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/InvalidKeyInArrayDimFetchRule.php new file mode 100644 index 00000000..eae58ddd --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/InvalidKeyInArrayDimFetchRule.php @@ -0,0 +1,57 @@ +reportMaybes = $reportMaybes; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\ArrayDimFetch::class; + } + + /** + * @param \PhpParser\Node\Expr\ArrayDimFetch $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if ($node->dim === null) { + return []; + } + + $varType = $scope->getType($node->var); + if (count(TypeUtils::getArrays($varType)) === 0) { + return []; + } + + $dimensionType = $scope->getType($node->dim); + $isSuperType = AllowedArrayKeysTypes::getType()->isSuperTypeOf($dimensionType); + if ($isSuperType->no()) { + return [ + sprintf('Invalid array key type %s.', $dimensionType->describe(VerbosityLevel::typeOnly())), + ]; + } elseif ($this->reportMaybes && $isSuperType->maybe() && !$dimensionType instanceof MixedType) { + return [ + sprintf('Possibly invalid array key type %s.', $dimensionType->describe(VerbosityLevel::typeOnly())), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/InvalidKeyInArrayItemRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/InvalidKeyInArrayItemRule.php new file mode 100644 index 00000000..3e4aba0f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/InvalidKeyInArrayItemRule.php @@ -0,0 +1,51 @@ +reportMaybes = $reportMaybes; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\ArrayItem::class; + } + + /** + * @param \PhpParser\Node\Expr\ArrayItem $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if ($node->key === null) { + return []; + } + + $dimensionType = $scope->getType($node->key); + $isSuperType = AllowedArrayKeysTypes::getType()->isSuperTypeOf($dimensionType); + if ($isSuperType->no()) { + return [ + sprintf('Invalid array key type %s.', $dimensionType->describe(VerbosityLevel::typeOnly())), + ]; + } elseif ($this->reportMaybes && $isSuperType->maybe() && !$dimensionType instanceof MixedType) { + return [ + sprintf('Possibly invalid array key type %s.', $dimensionType->describe(VerbosityLevel::typeOnly())), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/IterableInForeachRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/IterableInForeachRule.php new file mode 100644 index 00000000..c402bcc3 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/IterableInForeachRule.php @@ -0,0 +1,61 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Stmt\Foreach_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Foreach_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->expr, + 'Iterating over an object of an unknown class %s.', + static function (Type $type): bool { + return $type->isIterable()->yes(); + } + ); + $type = $typeResult->getType(); + if ($type instanceof ErrorType) { + return $typeResult->getUnknownClassErrors(); + } + if ($type->isIterable()->yes()) { + return []; + } + + return [ + RuleErrorBuilder::message(sprintf( + 'Argument of an invalid type %s supplied for foreach, only iterables are supported.', + $type->describe(VerbosityLevel::typeOnly()) + ))->line($node->expr->getLine())->build(), + ]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/NonexistentOffsetInArrayDimFetchRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/NonexistentOffsetInArrayDimFetchRule.php new file mode 100644 index 00000000..2dc7c766 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/NonexistentOffsetInArrayDimFetchRule.php @@ -0,0 +1,140 @@ +ruleLevelHelper = $ruleLevelHelper; + $this->reportMaybes = $reportMaybes; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\ArrayDimFetch::class; + } + + /** + * @param \PhpParser\Node\Expr\ArrayDimFetch $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if ($node->dim !== null) { + $dimType = $scope->getType($node->dim); + $unknownClassPattern = sprintf('Access to offset %s on an unknown class %%s.', $dimType->describe(VerbosityLevel::value())); + } else { + $dimType = null; + $unknownClassPattern = 'Access to an offset on an unknown class %s.'; + } + + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->var, + $unknownClassPattern, + static function (Type $type) use ($dimType): bool { + if ($dimType === null) { + return $type->isOffsetAccessible()->yes(); + } + + return $type->isOffsetAccessible()->yes() && $type->hasOffsetValueType($dimType)->yes(); + } + ); + $type = $typeResult->getType(); + if ($type instanceof ErrorType) { + return $typeResult->getUnknownClassErrors(); + } + + $isOffsetAccessible = $type->isOffsetAccessible(); + + if ($scope->isInExpressionAssign($node) && !$isOffsetAccessible->no()) { + return []; + } + + if (!$isOffsetAccessible->yes()) { + if ($dimType !== null) { + return [ + RuleErrorBuilder::message(sprintf( + 'Cannot access offset %s on %s.', + $dimType->describe(VerbosityLevel::value()), + $type->describe(VerbosityLevel::value()) + ))->build(), + ]; + } + + return [ + RuleErrorBuilder::message(sprintf( + 'Cannot access an offset on %s.', + $type->describe(VerbosityLevel::typeOnly()) + ))->build(), + ]; + } + + if ($dimType === null) { + return []; + } + + $hasOffsetValueType = $type->hasOffsetValueType($dimType); + $report = $hasOffsetValueType->no(); + if ($hasOffsetValueType->maybe()) { + $constantArrays = TypeUtils::getConstantArrays($type); + if (count($constantArrays) > 0) { + foreach ($constantArrays as $constantArray) { + if ($constantArray->hasOffsetValueType($dimType)->no()) { + $report = true; + break; + } + } + } + } + + if (!$report && $this->reportMaybes) { + foreach (TypeUtils::flattenTypes($type) as $innerType) { + if ($dimType instanceof UnionType) { + if ($innerType->hasOffsetValueType($dimType)->no()) { + $report = true; + break; + } + continue; + } + foreach (TypeUtils::flattenTypes($dimType) as $innerDimType) { + if ($innerType->hasOffsetValueType($innerDimType)->no()) { + $report = true; + break; + } + } + } + } + + if ($report) { + return [ + RuleErrorBuilder::message(sprintf('Offset %s does not exist on %s.', $dimType->describe(VerbosityLevel::value()), $type->describe(VerbosityLevel::value())))->build(), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessAssignOpRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessAssignOpRule.php new file mode 100644 index 00000000..ebff85e0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessAssignOpRule.php @@ -0,0 +1,95 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\AssignOp::class; + } + + /** + * @param \PhpParser\Node\Expr\AssignOp $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if (!$node->var instanceof ArrayDimFetch) { + return []; + } + + $arrayDimFetch = $node->var; + + $potentialDimType = null; + if ($arrayDimFetch->dim !== null) { + $potentialDimType = $scope->getType($arrayDimFetch->dim); + } + + $varTypeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $arrayDimFetch->var, + '', + static function (Type $varType) use ($potentialDimType): bool { + $arrayDimType = $varType->setOffsetValueType($potentialDimType, new MixedType()); + return !($arrayDimType instanceof ErrorType); + } + ); + $varType = $varTypeResult->getType(); + + if ($arrayDimFetch->dim !== null) { + $dimTypeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $arrayDimFetch->dim, + '', + static function (Type $dimType) use ($varType): bool { + $arrayDimType = $varType->setOffsetValueType($dimType, new MixedType()); + return !($arrayDimType instanceof ErrorType); + } + ); + $dimType = $dimTypeResult->getType(); + if ($varType->hasOffsetValueType($dimType)->no()) { + return []; + } + } else { + $dimType = $potentialDimType; + } + + $resultType = $varType->setOffsetValueType($dimType, new MixedType()); + if (!($resultType instanceof ErrorType)) { + return []; + } + + if ($dimType === null) { + return [sprintf( + 'Cannot assign new offset to %s.', + $varType->describe(VerbosityLevel::typeOnly()) + )]; + } + + return [sprintf( + 'Cannot assign offset %s to %s.', + $dimType->describe(VerbosityLevel::value()), + $varType->describe(VerbosityLevel::typeOnly()) + )]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessAssignmentRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessAssignmentRule.php new file mode 100644 index 00000000..ee1050a5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessAssignmentRule.php @@ -0,0 +1,89 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\ArrayDimFetch::class; + } + + /** + * @param \PhpParser\Node\Expr\ArrayDimFetch $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if (!$scope->isInExpressionAssign($node)) { + return []; + } + + $potentialDimType = null; + if ($node->dim !== null) { + $potentialDimType = $scope->getType($node->dim); + } + + $varTypeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->var, + '', + static function (Type $varType) use ($potentialDimType): bool { + $arrayDimType = $varType->setOffsetValueType($potentialDimType, new MixedType()); + return !($arrayDimType instanceof ErrorType); + } + ); + $varType = $varTypeResult->getType(); + + if ($node->dim !== null) { + $dimTypeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->dim, + '', + static function (Type $dimType) use ($varType): bool { + $arrayDimType = $varType->setOffsetValueType($dimType, new MixedType()); + return !($arrayDimType instanceof ErrorType); + } + ); + $dimType = $dimTypeResult->getType(); + } else { + $dimType = $potentialDimType; + } + + $resultType = $varType->setOffsetValueType($dimType, new MixedType()); + if (!($resultType instanceof ErrorType)) { + return []; + } + + if ($dimType === null) { + return [sprintf( + 'Cannot assign new offset to %s.', + $varType->describe(VerbosityLevel::typeOnly()) + )]; + } + + return [sprintf( + 'Cannot assign offset %s to %s.', + $dimType->describe(VerbosityLevel::value()), + $varType->describe(VerbosityLevel::typeOnly()) + )]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessWithoutDimForReadingRule.php b/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessWithoutDimForReadingRule.php new file mode 100644 index 00000000..f7a015cf --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Arrays/OffsetAccessWithoutDimForReadingRule.php @@ -0,0 +1,33 @@ +isInExpressionAssign($node)) { + return []; + } + + if ($node->dim !== null) { + return []; + } + + return ['Cannot use [] for reading.']; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Cast/EchoRule.php b/vendor/phpstan/phpstan/src/Rules/Cast/EchoRule.php new file mode 100644 index 00000000..fff0b0f3 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Cast/EchoRule.php @@ -0,0 +1,63 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return Node\Stmt\Echo_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Echo_ $node + * @param Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + $messages = []; + + foreach ($node->exprs as $key => $expr) { + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $expr, + '', + static function (Type $type): bool { + return !$type->toString() instanceof ErrorType; + } + ); + + if ($typeResult->getType() instanceof ErrorType + || !$typeResult->getType()->toString() instanceof ErrorType + ) { + continue; + } + + $messages[] = sprintf( + 'Parameter #%d (%s) of echo cannot be converted to string.', + $key + 1, + $typeResult->getType()->describe(VerbosityLevel::value()) + ); + } + return $messages; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Cast/InvalidCastRule.php b/vendor/phpstan/phpstan/src/Rules/Cast/InvalidCastRule.php new file mode 100644 index 00000000..27b1d845 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Cast/InvalidCastRule.php @@ -0,0 +1,100 @@ +broker = $broker; + $this->ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\Cast::class; + } + + /** + * @param \PhpParser\Node\Expr\Cast $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + $castTypeCallback = static function (Type $type) use ($node): ?Type { + if ($node instanceof \PhpParser\Node\Expr\Cast\Int_) { + return $type->toInteger(); + } elseif ($node instanceof \PhpParser\Node\Expr\Cast\Bool_) { + return $type->toBoolean(); + } elseif ($node instanceof \PhpParser\Node\Expr\Cast\Double) { + return $type->toFloat(); + } elseif ($node instanceof \PhpParser\Node\Expr\Cast\String_) { + return $type->toString(); + } + + return null; + }; + + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->expr, + '', + static function (Type $type) use ($castTypeCallback): bool { + $castType = $castTypeCallback($type); + if ($castType === null) { + return true; + } + + return !$castType instanceof ErrorType; + } + ); + $type = $typeResult->getType(); + if ($type instanceof ErrorType) { + return []; + } + + $castType = $castTypeCallback($type); + if ($castType instanceof ErrorType) { + $classReflection = $this->broker->getClass(get_class($node)); + $shortName = $classReflection->getNativeReflection()->getShortName(); + $shortName = strtolower($shortName); + if ($shortName === 'double') { + $shortName = 'float'; + } else { + $shortName = substr($shortName, 0, -1); + } + + return [ + RuleErrorBuilder::message(sprintf( + 'Cannot cast %s to %s.', + $scope->getType($node->expr)->describe(VerbosityLevel::value()), + $shortName + ))->build(), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Cast/InvalidPartOfEncapsedStringRule.php b/vendor/phpstan/phpstan/src/Rules/Cast/InvalidPartOfEncapsedStringRule.php new file mode 100644 index 00000000..be759d80 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Cast/InvalidPartOfEncapsedStringRule.php @@ -0,0 +1,76 @@ +printer = $printer; + $this->ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Scalar\Encapsed::class; + } + + /** + * @param \PhpParser\Node\Scalar\Encapsed $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] errors + */ + public function processNode(Node $node, Scope $scope): array + { + $messages = []; + foreach ($node->parts as $part) { + if ($part instanceof Node\Scalar\EncapsedStringPart) { + continue; + } + + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $part, + '', + static function (Type $type): bool { + return !$type->toString() instanceof ErrorType; + } + ); + $partType = $typeResult->getType(); + if ($partType instanceof ErrorType) { + continue; + } + + $stringPartType = $partType->toString(); + if (!$stringPartType instanceof ErrorType) { + continue; + } + + $messages[] = sprintf( + 'Part %s (%s) of encapsed string cannot be cast to string.', + $this->printer->prettyPrintExpr($part), + $partType->describe(VerbosityLevel::value()) + ); + } + + return $messages; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Cast/PrintRule.php b/vendor/phpstan/phpstan/src/Rules/Cast/PrintRule.php new file mode 100644 index 00000000..99fe0913 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Cast/PrintRule.php @@ -0,0 +1,58 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return Node\Expr\Print_::class; + } + + /** + * @param \PhpParser\Node\Expr\Print_ $node + * @param Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + /** @var Node\Expr\Print_ $node */ + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->expr, + '', + static function (Type $type): bool { + return !$type->toString() instanceof ErrorType; + } + ); + + if (!$typeResult->getType() instanceof ErrorType + && $typeResult->getType()->toString() instanceof ErrorType + ) { + return [sprintf( + 'Parameter %s of print cannot be converted to string.', + $typeResult->getType()->describe(VerbosityLevel::value()) + )]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/ClassCaseSensitivityCheck.php b/vendor/phpstan/phpstan/src/Rules/ClassCaseSensitivityCheck.php new file mode 100644 index 00000000..290379b0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/ClassCaseSensitivityCheck.php @@ -0,0 +1,62 @@ +broker = $broker; + } + + /** + * @param ClassNameNodePair[] $pairs + * @return RuleError[] + */ + public function checkClassNames(array $pairs): array + { + $errors = []; + foreach ($pairs as $pair) { + $className = $pair->getClassName(); + if (!$this->broker->hasClass($className)) { + continue; + } + $classReflection = $this->broker->getClass($className); + $realClassName = $classReflection->getName(); + if (strtolower($realClassName) !== strtolower($className)) { + continue; // skip class alias + } + if ($realClassName === $className) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf( + '%s %s referenced with incorrect case: %s.', + $this->getTypeName($classReflection), + $realClassName, + $className + ))->line($pair->getNode()->getLine())->build(); + } + + return $errors; + } + + private function getTypeName(ClassReflection $classReflection): string + { + if ($classReflection->isInterface()) { + return 'Interface'; + } elseif ($classReflection->isTrait()) { + return 'Trait'; + } + + return 'Class'; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/ClassNameNodePair.php b/vendor/phpstan/phpstan/src/Rules/ClassNameNodePair.php new file mode 100644 index 00000000..310ed45d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/ClassNameNodePair.php @@ -0,0 +1,32 @@ +className = $className; + $this->node = $node; + } + + public function getClassName(): string + { + return $this->className; + } + + public function getNode(): Node + { + return $this->node; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/ClassConstantDeclarationRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/ClassConstantDeclarationRule.php new file mode 100644 index 00000000..0e2c9c7b --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/ClassConstantDeclarationRule.php @@ -0,0 +1,36 @@ +isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + $classReflection = $scope->getClassReflection(); + + foreach ($node->consts as $const) { + $classReflection->getConstant($const->name->name); + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/ClassConstantRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/ClassConstantRule.php new file mode 100644 index 00000000..684b4dda --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/ClassConstantRule.php @@ -0,0 +1,165 @@ +broker = $broker; + $this->ruleLevelHelper = $ruleLevelHelper; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + } + + public function getNodeType(): string + { + return ClassConstFetch::class; + } + + /** + * @param \PhpParser\Node\Expr\ClassConstFetch $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\Identifier) { + return []; + } + $constantName = $node->name->name; + + $class = $node->class; + $messages = []; + if ($class instanceof \PhpParser\Node\Name) { + $className = (string) $class; + $lowercasedClassName = strtolower($className); + if (in_array($lowercasedClassName, ['self', 'static'], true)) { + if (!$scope->isInClass()) { + return [ + sprintf('Using %s outside of class scope.', $className), + ]; + } + + $className = $scope->getClassReflection()->getName(); + } elseif ($lowercasedClassName === 'parent') { + if (!$scope->isInClass()) { + return [ + sprintf('Using %s outside of class scope.', $className), + ]; + } + $currentClassReflection = $scope->getClassReflection(); + if ($currentClassReflection->getParentClass() === false) { + return [ + sprintf( + 'Access to parent::%s but %s does not extend any class.', + $constantName, + $currentClassReflection->getDisplayName() + ), + ]; + } + $className = $currentClassReflection->getParentClass()->getName(); + } else { + if (!$this->broker->hasClass($className)) { + if (strtolower($constantName) === 'class') { + return [ + sprintf('Class %s not found.', $className), + ]; + } + + return [ + sprintf('Access to constant %s on an unknown class %s.', $constantName, $className), + ]; + } else { + $messages = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($className, $class)]); + } + + $className = $this->broker->getClass($className)->getName(); + } + + $classType = new ObjectType($className); + } else { + $classTypeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $class, + sprintf('Access to constant %s on an unknown class %%s.', $constantName), + static function (Type $type) use ($constantName): bool { + return $type->canAccessConstants()->yes() && $type->hasConstant($constantName)->yes(); + } + ); + $classType = $classTypeResult->getType(); + if ($classType instanceof ErrorType) { + return $classTypeResult->getUnknownClassErrors(); + } + } + + if ((new StringType())->isSuperTypeOf($classType)->yes()) { + return $messages; + } + + $typeForDescribe = $classType; + $classType = TypeCombinator::remove($classType, new StringType()); + + if (!$classType->canAccessConstants()->yes()) { + return array_merge($messages, [ + sprintf('Cannot access constant %s on %s.', $constantName, $typeForDescribe->describe(VerbosityLevel::typeOnly())), + ]); + } + + if (strtolower($constantName) === 'class') { + return $messages; + } + + if (!$classType->hasConstant($constantName)->yes()) { + return array_merge($messages, [ + sprintf( + 'Access to undefined constant %s::%s.', + $typeForDescribe->describe(VerbosityLevel::typeOnly()), + $constantName + ), + ]); + } + + $constantReflection = $classType->getConstant($constantName); + if (!$scope->canAccessConstant($constantReflection)) { + return array_merge($messages, [ + sprintf( + 'Access to %s constant %s of class %s.', + $constantReflection->isPrivate() ? 'private' : 'protected', + $constantName, + $constantReflection->getDeclaringClass()->getDisplayName() + ), + ]); + } + + return $messages; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInClassExtendsRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInClassExtendsRule.php new file mode 100644 index 00000000..0aebdb83 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInClassExtendsRule.php @@ -0,0 +1,40 @@ +classCaseSensitivityCheck = $classCaseSensitivityCheck; + } + + public function getNodeType(): string + { + return Node\Stmt\Class_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Class_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ($node->extends === null) { + return []; + } + return $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair((string) $node->extends, $node->extends)]); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInInstanceOfRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInInstanceOfRule.php new file mode 100644 index 00000000..63e969b7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInInstanceOfRule.php @@ -0,0 +1,82 @@ +broker = $broker; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; + } + + public function getNodeType(): string + { + return Instanceof_::class; + } + + /** + * @param \PhpParser\Node\Expr\Instanceof_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + $class = $node->class; + if (!($class instanceof \PhpParser\Node\Name)) { + return []; + } + + $name = (string) $class; + $lowercaseName = strtolower($name); + + if (in_array($lowercaseName, [ + 'self', + 'static', + 'parent', + ], true)) { + if (!$scope->isInClass()) { + return [ + RuleErrorBuilder::message(sprintf('Using %s outside of class scope.', $lowercaseName))->line($class->getLine())->build(), + ]; + } + + return []; + } + + if (!$this->broker->hasClass($name)) { + return [ + RuleErrorBuilder::message(sprintf('Class %s not found.', $name))->line($class->getLine())->build(), + ]; + } elseif ($this->checkClassCaseSensitivity) { + return $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($name, $class)]); + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInTraitUseRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInTraitUseRule.php new file mode 100644 index 00000000..e8454870 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassInTraitUseRule.php @@ -0,0 +1,41 @@ +classCaseSensitivityCheck = $classCaseSensitivityCheck; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Stmt\TraitUse::class; + } + + /** + * @param \PhpParser\Node\Stmt\TraitUse $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + return $this->classCaseSensitivityCheck->checkClassNames( + array_map(static function (Node\Name $traitName): ClassNameNodePair { + return new ClassNameNodePair((string) $traitName, $traitName); + }, $node->traits) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassesInClassImplementsRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassesInClassImplementsRule.php new file mode 100644 index 00000000..642c50da --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassesInClassImplementsRule.php @@ -0,0 +1,41 @@ +classCaseSensitivityCheck = $classCaseSensitivityCheck; + } + + public function getNodeType(): string + { + return Node\Stmt\Class_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Class_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + return $this->classCaseSensitivityCheck->checkClassNames( + array_map(static function (Node\Name $interfaceName): ClassNameNodePair { + return new ClassNameNodePair((string) $interfaceName, $interfaceName); + }, $node->implements) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassesInInterfaceExtendsRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassesInInterfaceExtendsRule.php new file mode 100644 index 00000000..6001e366 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/ExistingClassesInInterfaceExtendsRule.php @@ -0,0 +1,41 @@ +classCaseSensitivityCheck = $classCaseSensitivityCheck; + } + + public function getNodeType(): string + { + return Node\Stmt\Interface_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Interface_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + return $this->classCaseSensitivityCheck->checkClassNames( + array_map(static function (Node\Name $interfaceName): ClassNameNodePair { + return new ClassNameNodePair((string) $interfaceName, $interfaceName); + }, $node->extends) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/ImpossibleInstanceOfRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/ImpossibleInstanceOfRule.php new file mode 100644 index 00000000..a2d5c50c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/ImpossibleInstanceOfRule.php @@ -0,0 +1,69 @@ +checkAlwaysTrueInstanceof = $checkAlwaysTrueInstanceof; + } + + public function getNodeType(): string + { + return Node\Expr\Instanceof_::class; + } + + /** + * @param \PhpParser\Node\Expr\Instanceof_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + $instanceofType = $scope->getType($node); + + if (!$instanceofType instanceof ConstantBooleanType) { + return []; + } + + $expressionType = $scope->getType($node->expr); + if ($node->class instanceof Node\Name) { + $className = $scope->resolveName($node->class); + $type = new ObjectType($className); + } else { + $type = $scope->getType($node->class); + } + + if (!$instanceofType->getValue()) { + return [ + sprintf( + 'Instanceof between %s and %s will always evaluate to false.', + $expressionType->describe(VerbosityLevel::typeOnly()), + $type->describe(VerbosityLevel::typeOnly()) + ), + ]; + } elseif ($this->checkAlwaysTrueInstanceof) { + return [ + sprintf( + 'Instanceof between %s and %s will always evaluate to true.', + $expressionType->describe(VerbosityLevel::typeOnly()), + $type->describe(VerbosityLevel::typeOnly()) + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/InstantiationRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/InstantiationRule.php new file mode 100644 index 00000000..6f4c0f52 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/InstantiationRule.php @@ -0,0 +1,168 @@ +broker = $broker; + $this->check = $check; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + } + + public function getNodeType(): string + { + return New_::class; + } + + /** + * @param \PhpParser\Node\Expr\New_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ($node->class instanceof \PhpParser\Node\Name) { + $class = (string) $node->class; + } elseif ($node->class instanceof Node\Stmt\Class_) { + $anonymousClassType = $scope->getType($node); + if (!$anonymousClassType instanceof ObjectType) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $class = $anonymousClassType->getClassName(); + } else { + return []; + } + + $lowercasedClass = strtolower($class); + $messages = []; + if ($lowercasedClass === 'static') { + if (!$scope->isInClass()) { + return [ + sprintf('Using %s outside of class scope.', $class), + ]; + } + return []; + } elseif ($lowercasedClass === 'self') { + if (!$scope->isInClass()) { + return [ + sprintf('Using %s outside of class scope.', $class), + ]; + } + $classReflection = $scope->getClassReflection(); + } elseif ($lowercasedClass === 'parent') { + if (!$scope->isInClass()) { + return [ + sprintf('Using %s outside of class scope.', $class), + ]; + } + if ($scope->getClassReflection()->getParentClass() === false) { + return [ + sprintf( + '%s::%s() calls new parent but %s does not extend any class.', + $scope->getClassReflection()->getDisplayName(), + $scope->getFunctionName(), + $scope->getClassReflection()->getDisplayName() + ), + ]; + } + $classReflection = $scope->getClassReflection()->getParentClass(); + } else { + if (!$this->broker->hasClass($class)) { + return [ + sprintf('Instantiated class %s not found.', $class), + ]; + } else { + $messages = $this->classCaseSensitivityCheck->checkClassNames([ + new ClassNameNodePair($class, $node->class), + ]); + } + + $classReflection = $this->broker->getClass($class); + } + + if ($classReflection->isInterface()) { + return [ + sprintf('Cannot instantiate interface %s.', $classReflection->getDisplayName()), + ]; + } + + if ($classReflection->isAbstract()) { + return [ + sprintf('Instantiated class %s is abstract.', $classReflection->getDisplayName()), + ]; + } + + if (!$classReflection->hasConstructor()) { + if (count($node->args) > 0) { + return array_merge($messages, [ + sprintf( + 'Class %s does not have a constructor and must be instantiated without any parameters.', + $classReflection->getDisplayName() + ), + ]); + } + + return $messages; + } + + $constructorReflection = $classReflection->getConstructor(); + if (!$scope->canCallMethod($constructorReflection)) { + $messages[] = sprintf( + 'Cannot instantiate class %s via %s constructor %s::%s().', + $classReflection->getDisplayName(), + $constructorReflection->isPrivate() ? 'private' : 'protected', + $constructorReflection->getDeclaringClass()->getDisplayName(), + $constructorReflection->getName() + ); + } + + return array_merge($messages, $this->check->check( + ParametersAcceptorSelector::selectFromArgs( + $scope, + $node->args, + $constructorReflection->getVariants() + ), + $scope, + $node, + [ + 'Class ' . $classReflection->getDisplayName() . ' constructor invoked with %d parameter, %d required.', + 'Class ' . $classReflection->getDisplayName() . ' constructor invoked with %d parameters, %d required.', + 'Class ' . $classReflection->getDisplayName() . ' constructor invoked with %d parameter, at least %d required.', + 'Class ' . $classReflection->getDisplayName() . ' constructor invoked with %d parameters, at least %d required.', + 'Class ' . $classReflection->getDisplayName() . ' constructor invoked with %d parameter, %d-%d required.', + 'Class ' . $classReflection->getDisplayName() . ' constructor invoked with %d parameters, %d-%d required.', + 'Parameter #%d %s of class ' . $classReflection->getDisplayName() . ' constructor expects %s, %s given.', + '', // constructor does not have a return type + 'Parameter #%d %s of class ' . $classReflection->getDisplayName() . ' constructor is passed by reference, so it expects variables only', + ] + )); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/RequireParentConstructCallRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/RequireParentConstructCallRule.php new file mode 100644 index 00000000..f4021ab1 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/RequireParentConstructCallRule.php @@ -0,0 +1,146 @@ +isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ($scope->isInTrait()) { + return []; + } + + if ($node->name->name !== '__construct') { + return []; + } + + $classReflection = $scope->getClassReflection()->getNativeReflection(); + if ($classReflection->isInterface() || $classReflection->isAnonymous()) { + return []; + } + + if ($this->callsParentConstruct($node)) { + if ($classReflection->getParentClass() === false) { + return [ + sprintf( + '%s::__construct() calls parent constructor but does not extend any class.', + $classReflection->getName() + ), + ]; + } + + if ($this->getParentConstructorClass($classReflection) === false) { + return [ + sprintf( + '%s::__construct() calls parent constructor but parent does not have one.', + $classReflection->getName() + ), + ]; + } + } else { + $parentClass = $this->getParentConstructorClass($classReflection); + if ($parentClass !== false) { + return [ + sprintf( + '%s::__construct() does not call parent constructor from %s.', + $classReflection->getName(), + $parentClass->getName() + ), + ]; + } + } + + return []; + } + + private function callsParentConstruct(Node $parserNode): bool + { + if (!isset($parserNode->stmts)) { + return false; + } + + foreach ($parserNode->stmts as $statement) { + if ($statement instanceof Node\Stmt\Expression) { + $statement = $statement->expr; + } + + $statement = $this->ignoreErrorSuppression($statement); + if ($statement instanceof \PhpParser\Node\Expr\StaticCall) { + if ( + $statement->class instanceof Name + && ((string) $statement->class === 'parent') + && $statement->name instanceof Node\Identifier + && $statement->name->name === '__construct' + ) { + return true; + } + } else { + if ($this->callsParentConstruct($statement)) { + return true; + } + } + } + + return false; + } + + /** + * @param \ReflectionClass $classReflection + * @return \ReflectionClass|false + */ + private function getParentConstructorClass(\ReflectionClass $classReflection) + { + while ($classReflection->getParentClass() !== false) { + $constructor = $classReflection->getParentClass()->hasMethod('__construct') ? $classReflection->getParentClass()->getMethod('__construct') : null; + $constructorWithClassName = $classReflection->getParentClass()->hasMethod($classReflection->getParentClass()->getName()) ? $classReflection->getParentClass()->getMethod($classReflection->getParentClass()->getName()) : null; + if ( + ( + $constructor !== null + && $constructor->getDeclaringClass()->getName() === $classReflection->getParentClass()->getName() + && !$constructor->isAbstract() + ) || ( + $constructorWithClassName !== null + && $constructorWithClassName->getDeclaringClass()->getName() === $classReflection->getParentClass()->getName() + && !$constructorWithClassName->isAbstract() + ) + ) { + return $classReflection->getParentClass(); + } + + $classReflection = $classReflection->getParentClass(); + } + + return false; + } + + private function ignoreErrorSuppression(Node $statement): Node + { + if ($statement instanceof Node\Expr\ErrorSuppress) { + + return $statement->expr; + } + + return $statement; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Classes/UnusedConstructorParametersRule.php b/vendor/phpstan/phpstan/src/Rules/Classes/UnusedConstructorParametersRule.php new file mode 100644 index 00000000..37699502 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Classes/UnusedConstructorParametersRule.php @@ -0,0 +1,65 @@ +check = $check; + } + + public function getNodeType(): string + { + return ClassMethod::class; + } + + /** + * @param \PhpParser\Node\Stmt\ClassMethod $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$scope->isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ($node->name->name !== '__construct' || $node->stmts === null) { + return []; + } + + if (count($node->params) === 0) { + return []; + } + + $message = sprintf('Constructor of class %s has an unused parameter $%%s.', $scope->getClassReflection()->getDisplayName()); + if ($scope->getClassReflection()->isAnonymous()) { + $message = 'Constructor of an anonymous class has an unused parameter $%s.'; + } + + return $this->check->getUnusedParameters( + $scope, + array_map(static function (Param $parameter): string { + if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + return $parameter->var->name; + }, $node->params), + $node->stmts, + $message + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanAndConstantConditionRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanAndConstantConditionRule.php new file mode 100644 index 00000000..c08c5cad --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanAndConstantConditionRule.php @@ -0,0 +1,70 @@ +helper = $helper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\BinaryOp\BooleanAnd::class; + } + + /** + * @param \PhpParser\Node\Expr\BinaryOp\BooleanAnd $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode( + \PhpParser\Node $node, + \PHPStan\Analyser\Scope $scope + ): array + { + $errors = []; + $leftType = $this->helper->getBooleanType($scope, $node->left); + if ($leftType instanceof ConstantBooleanType) { + $errors[] = RuleErrorBuilder::message(sprintf( + 'Left side of && is always %s.', + $leftType->getValue() ? 'true' : 'false' + ))->line($node->left->getLine())->build(); + } + + $rightType = $this->helper->getBooleanType( + $scope->filterByTruthyValue($node->left), + $node->right + ); + if ($rightType instanceof ConstantBooleanType) { + $errors[] = RuleErrorBuilder::message(sprintf( + 'Right side of && is always %s.', + $rightType->getValue() ? 'true' : 'false' + ))->line($node->right->getLine())->build(); + } + + if (count($errors) === 0) { + $nodeType = $scope->getType($node); + if ($nodeType instanceof ConstantBooleanType) { + $errors[] = RuleErrorBuilder::message(sprintf( + 'Result of && is always %s.', + $nodeType->getValue() ? 'true' : 'false' + ))->build(); + } + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanNotConstantConditionRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanNotConstantConditionRule.php new file mode 100644 index 00000000..dd3344e2 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanNotConstantConditionRule.php @@ -0,0 +1,50 @@ +helper = $helper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\BooleanNot::class; + } + + /** + * @param \PhpParser\Node\Expr\BooleanNot $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode( + \PhpParser\Node $node, + \PHPStan\Analyser\Scope $scope + ): array + { + $exprType = $this->helper->getBooleanType($scope, $node->expr); + if ($exprType instanceof ConstantBooleanType) { + return [ + RuleErrorBuilder::message(sprintf( + 'Negated boolean expression is always %s.', + $exprType->getValue() ? 'false' : 'true' + ))->line($node->expr->getLine())->build(), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanOrConstantConditionRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanOrConstantConditionRule.php new file mode 100644 index 00000000..26c449ee --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/BooleanOrConstantConditionRule.php @@ -0,0 +1,70 @@ +helper = $helper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\BinaryOp\BooleanOr::class; + } + + /** + * @param \PhpParser\Node\Expr\BinaryOp\BooleanOr $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode( + \PhpParser\Node $node, + \PHPStan\Analyser\Scope $scope + ): array + { + $messages = []; + $leftType = $this->helper->getBooleanType($scope, $node->left); + if ($leftType instanceof ConstantBooleanType) { + $messages[] = RuleErrorBuilder::message(sprintf( + 'Left side of || is always %s.', + $leftType->getValue() ? 'true' : 'false' + ))->line($node->left->getLine())->build(); + } + + $rightType = $this->helper->getBooleanType( + $scope->filterByFalseyValue($node->left), + $node->right + ); + if ($rightType instanceof ConstantBooleanType) { + $messages[] = RuleErrorBuilder::message(sprintf( + 'Right side of || is always %s.', + $rightType->getValue() ? 'true' : 'false' + ))->line($node->right->getLine())->build(); + } + + if (count($messages) === 0) { + $nodeType = $scope->getType($node); + if ($nodeType instanceof ConstantBooleanType) { + $messages[] = RuleErrorBuilder::message(sprintf( + 'Result of || is always %s.', + $nodeType->getValue() ? 'true' : 'false' + ))->build(); + } + } + + return $messages; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/ConstantConditionRuleHelper.php b/vendor/phpstan/phpstan/src/Rules/Comparison/ConstantConditionRuleHelper.php new file mode 100644 index 00000000..6e98e242 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/ConstantConditionRuleHelper.php @@ -0,0 +1,70 @@ +impossibleCheckTypeHelper = $impossibleCheckTypeHelper; + } + + public function shouldReportAlwaysTrueByDefault(Expr $expr): bool + { + return $expr instanceof Expr\BooleanNot + || $expr instanceof Expr\BinaryOp\BooleanOr + || $expr instanceof Expr\BinaryOp\BooleanAnd + || $expr instanceof Expr\Ternary + || $expr instanceof Expr\Isset_; + } + + public function shouldSkip(Scope $scope, Expr $expr): bool + { + if ( + $expr instanceof Expr\Instanceof_ + || $expr instanceof Expr\BinaryOp\Identical + || $expr instanceof Expr\BinaryOp\NotIdentical + || $expr instanceof Expr\BooleanNot + || $expr instanceof Expr\BinaryOp\BooleanOr + || $expr instanceof Expr\BinaryOp\BooleanAnd + || $expr instanceof Expr\Ternary + || $expr instanceof Expr\Isset_ + ) { + // already checked by different rules + return true; + } + + if ( + $expr instanceof FuncCall + || $expr instanceof MethodCall + || $expr instanceof Expr\StaticCall + ) { + $isAlways = $this->impossibleCheckTypeHelper->findSpecifiedType($scope, $expr); + if ($isAlways !== null) { + return true; + } + } + + return false; + } + + public function getBooleanType(Scope $scope, Expr $expr): BooleanType + { + if ($this->shouldSkip($scope, $expr)) { + return new BooleanType(); + } + + return $scope->getType($expr)->toBoolean(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/ElseIfConstantConditionRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/ElseIfConstantConditionRule.php new file mode 100644 index 00000000..62590d1c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/ElseIfConstantConditionRule.php @@ -0,0 +1,50 @@ +helper = $helper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Stmt\ElseIf_::class; + } + + /** + * @param \PhpParser\Node\Stmt\ElseIf_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode( + \PhpParser\Node $node, + \PHPStan\Analyser\Scope $scope + ): array + { + $exprType = $this->helper->getBooleanType($scope, $node->cond); + if ($exprType instanceof ConstantBooleanType) { + return [ + RuleErrorBuilder::message(sprintf( + 'Elseif condition is always %s.', + $exprType->getValue() ? 'true' : 'false' + ))->line($node->cond->getLine())->build(), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/IfConstantConditionRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/IfConstantConditionRule.php new file mode 100644 index 00000000..d9fd5d80 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/IfConstantConditionRule.php @@ -0,0 +1,50 @@ +helper = $helper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Stmt\If_::class; + } + + /** + * @param \PhpParser\Node\Stmt\If_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode( + \PhpParser\Node $node, + \PHPStan\Analyser\Scope $scope + ): array + { + $exprType = $this->helper->getBooleanType($scope, $node->cond); + if ($exprType instanceof ConstantBooleanType) { + return [ + RuleErrorBuilder::message(sprintf( + 'If condition is always %s.', + $exprType->getValue() ? 'true' : 'false' + ))->line($node->cond->getLine())->build(), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeFunctionCallRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeFunctionCallRule.php new file mode 100644 index 00000000..b058e1d1 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeFunctionCallRule.php @@ -0,0 +1,68 @@ +impossibleCheckTypeHelper = $impossibleCheckTypeHelper; + $this->checkAlwaysTrueCheckTypeFunctionCall = $checkAlwaysTrueCheckTypeFunctionCall; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\FuncCall::class; + } + + /** + * @param \PhpParser\Node\Expr\FuncCall $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] errors + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\Name) { + return []; + } + + $functionName = (string) $node->name; + if (strtolower($functionName) === 'is_a') { + return []; + } + $isAlways = $this->impossibleCheckTypeHelper->findSpecifiedType($scope, $node); + if ($isAlways === null) { + return []; + } + + if (!$isAlways) { + return [sprintf( + 'Call to function %s()%s will always evaluate to false.', + $functionName, + $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->args) + )]; + } elseif ($this->checkAlwaysTrueCheckTypeFunctionCall) { + return [sprintf( + 'Call to function %s()%s will always evaluate to true.', + $functionName, + $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->args) + )]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeHelper.php b/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeHelper.php new file mode 100644 index 00000000..2f1fc045 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeHelper.php @@ -0,0 +1,245 @@ +broker = $broker; + $this->typeSpecifier = $typeSpecifier; + } + + public function findSpecifiedType( + Scope $scope, + Expr $node + ): ?bool + { + if ( + $node instanceof FuncCall + && count($node->args) > 0 + ) { + if ($node->name instanceof \PhpParser\Node\Name) { + $functionName = strtolower((string) $node->name); + if ($functionName === 'count') { + return null; + } elseif ($functionName === 'is_numeric') { + $argType = $scope->getType($node->args[0]->value); + if (count(TypeUtils::getConstantScalars($argType)) > 0) { + return !$argType->toNumber() instanceof ErrorType; + } + + if (!(new StringType())->isSuperTypeOf($argType)->no()) { + return null; + } + } elseif ($functionName === 'defined') { + return null; + } elseif ( + $functionName === 'in_array' + && count($node->args) >= 3 + ) { + $haystackType = $scope->getType($node->args[1]->value); + if ($haystackType instanceof MixedType) { + return null; + } + + if (!$haystackType instanceof ConstantArrayType || count($haystackType->getValueTypes()) > 1) { + $needleType = $scope->getType($node->args[0]->value); + + $haystackArrayTypes = TypeUtils::getArrays($haystackType); + if (count($haystackArrayTypes) === 1 && $haystackArrayTypes[0]->getIterableValueType() instanceof NeverType) { + return null; + } + + $valueType = TypeCombinator::union(...$haystackArrayTypes)->getIterableValueType(); + $isNeedleSupertype = $needleType->isSuperTypeOf($valueType); + + if ($isNeedleSupertype->maybe() || $isNeedleSupertype->yes()) { + foreach ($haystackArrayTypes as $haystackArrayType) { + foreach (TypeUtils::getConstantScalars($haystackArrayType->getIterableValueType()) as $constantScalarType) { + if ($needleType->isSuperTypeOf($constantScalarType)->yes()) { + continue 2; + } + } + + return null; + } + } + + if ($isNeedleSupertype->yes()) { + $hasConstantNeedleTypes = count(TypeUtils::getConstantScalars($needleType)) > 0; + $hasConstantHaystackTypes = count(TypeUtils::getConstantScalars($valueType)) > 0; + if ( + ( + !$hasConstantNeedleTypes + && !$hasConstantHaystackTypes + ) + || $hasConstantNeedleTypes !== $hasConstantHaystackTypes + ) { + return null; + } + } + } + } elseif ( + $functionName === 'property_exists' + && count($node->args) >= 2 + ) { + $classNames = TypeUtils::getDirectClassNames( + $scope->getType($node->args[0]->value) + ); + foreach ($classNames as $className) { + if (!$this->broker->hasClass($className)) { + continue; + } + + if (UniversalObjectCratesClassReflectionExtension::isUniversalObjectCrate( + $this->broker, + $this->broker->getUniversalObjectCratesClasses(), + $this->broker->getClass($className) + )) { + return null; + } + } + } + } + } + + $specifiedTypes = $this->typeSpecifier->specifyTypesInCondition($scope, $node, TypeSpecifierContext::createTruthy()); + $sureTypes = $specifiedTypes->getSureTypes(); + $sureNotTypes = $specifiedTypes->getSureNotTypes(); + + $isSpecified = static function (Expr $expr) use ($scope, $node): bool { + return ( + $node instanceof FuncCall + || $node instanceof MethodCall + || $node instanceof Expr\StaticCall + ) && $scope->isSpecified($expr); + }; + + if (count($sureTypes) === 1) { + $sureType = reset($sureTypes); + if ($isSpecified($sureType[0])) { + return null; + } + + $argumentType = $scope->getType($sureType[0]); + + /** @var \PHPStan\Type\Type $resultType */ + $resultType = $sureType[1]; + + $isSuperType = $resultType->isSuperTypeOf($argumentType); + if ($isSuperType->yes()) { + return true; + } elseif ($isSuperType->no()) { + return false; + } + + return null; + } elseif (count($sureNotTypes) === 1) { + $sureNotType = reset($sureNotTypes); + if ($isSpecified($sureNotType[0])) { + return null; + } + + $argumentType = $scope->getType($sureNotType[0]); + + /** @var \PHPStan\Type\Type $resultType */ + $resultType = $sureNotType[1]; + + $isSuperType = $resultType->isSuperTypeOf($argumentType); + if ($isSuperType->yes()) { + return false; + } elseif ($isSuperType->no()) { + return true; + } + + return null; + } elseif (count($sureTypes) > 0) { + foreach ($sureTypes as $sureType) { + if ($isSpecified($sureType[0])) { + return null; + } + } + $types = TypeCombinator::union(...array_map(static function ($sureType) { + return $sureType[1]; + }, array_values($sureTypes))); + if ($types instanceof NeverType) { + return false; + } + } elseif (count($sureNotTypes) > 0) { + foreach ($sureNotTypes as $sureNotType) { + if ($isSpecified($sureNotType[0])) { + return null; + } + } + $types = TypeCombinator::union(...array_map(static function ($sureNotType) { + return $sureNotType[1]; + }, array_values($sureNotTypes))); + if ($types instanceof NeverType) { + return true; + } + } + + return null; + } + + /** + * @param Scope $scope + * @param \PhpParser\Node\Arg[] $args + * @return string + */ + public function getArgumentsDescription( + Scope $scope, + array $args + ): string + { + if (count($args) === 0) { + return ''; + } + + $descriptions = array_map(static function (Arg $arg) use ($scope): string { + return $scope->getType($arg->value)->describe(VerbosityLevel::value()); + }, $args); + + if (count($descriptions) < 3) { + return sprintf(' with %s', implode(' and ', $descriptions)); + } + + $lastDescription = array_pop($descriptions); + + return sprintf( + ' with arguments %s and %s', + implode(', ', $descriptions), + $lastDescription + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeMethodCallRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeMethodCallRule.php new file mode 100644 index 00000000..b90f6e86 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeMethodCallRule.php @@ -0,0 +1,84 @@ +impossibleCheckTypeHelper = $impossibleCheckTypeHelper; + $this->checkAlwaysTrueCheckTypeFunctionCall = $checkAlwaysTrueCheckTypeFunctionCall; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\MethodCall::class; + } + + /** + * @param \PhpParser\Node\Expr\MethodCall $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] errors + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\Identifier) { + return []; + } + + $isAlways = $this->impossibleCheckTypeHelper->findSpecifiedType($scope, $node); + if ($isAlways === null) { + return []; + } + + if (!$isAlways) { + $method = $this->getMethod($node->var, $node->name->name, $scope); + return [sprintf( + 'Call to method %s::%s()%s will always evaluate to false.', + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->args) + )]; + } elseif ($this->checkAlwaysTrueCheckTypeFunctionCall) { + $method = $this->getMethod($node->var, $node->name->name, $scope); + return [sprintf( + 'Call to method %s::%s()%s will always evaluate to true.', + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->args) + )]; + } + + return []; + } + + private function getMethod( + Expr $var, + string $methodName, + Scope $scope + ): MethodReflection + { + $calledOnType = $scope->getType($var); + if (!$calledOnType->hasMethod($methodName)->yes()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $calledOnType->getMethod($methodName, $scope); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeStaticMethodCallRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeStaticMethodCallRule.php new file mode 100644 index 00000000..6b7bb7f0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/ImpossibleCheckTypeStaticMethodCallRule.php @@ -0,0 +1,99 @@ +impossibleCheckTypeHelper = $impossibleCheckTypeHelper; + $this->checkAlwaysTrueCheckTypeFunctionCall = $checkAlwaysTrueCheckTypeFunctionCall; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\StaticCall::class; + } + + /** + * @param \PhpParser\Node\Expr\StaticCall $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] errors + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\Identifier) { + return []; + } + + $isAlways = $this->impossibleCheckTypeHelper->findSpecifiedType($scope, $node); + if ($isAlways === null) { + return []; + } + + if (!$isAlways) { + $method = $this->getMethod($node->class, $node->name->name, $scope); + + return [sprintf( + 'Call to static method %s::%s()%s will always evaluate to false.', + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->args) + )]; + } elseif ($this->checkAlwaysTrueCheckTypeFunctionCall) { + $method = $this->getMethod($node->class, $node->name->name, $scope); + + return [sprintf( + 'Call to static method %s::%s()%s will always evaluate to true.', + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + $this->impossibleCheckTypeHelper->getArgumentsDescription($scope, $node->args) + )]; + } + + return []; + } + + /** + * @param Node\Name|Expr $class + * @param string $methodName + * @param Scope $scope + * @return MethodReflection + * @throws \PHPStan\ShouldNotHappenException + */ + private function getMethod( + $class, + string $methodName, + Scope $scope + ): MethodReflection + { + if ($class instanceof Node\Name) { + $calledOnType = new ObjectType($scope->resolveName($class)); + } else { + $calledOnType = $scope->getType($class); + } + + if (!$calledOnType->hasMethod($methodName)->yes()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $calledOnType->getMethod($methodName, $scope); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/StrictComparisonOfDifferentTypesRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/StrictComparisonOfDifferentTypesRule.php new file mode 100644 index 00000000..3cf9ce1f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/StrictComparisonOfDifferentTypesRule.php @@ -0,0 +1,85 @@ +checkAlwaysTrueStrictComparison = $checkAlwaysTrueStrictComparison; + } + + public function getNodeType(): string + { + return Node\Expr\BinaryOp::class; + } + + /** + * @param \PhpParser\Node\Expr\BinaryOp $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] errors + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$node instanceof Node\Expr\BinaryOp\Identical && !$node instanceof Node\Expr\BinaryOp\NotIdentical) { + return []; + } + + if ( + $this->isSpecifiedFunctionCall($scope, $node->left) + || $this->isSpecifiedFunctionCall($scope, $node->right) + ) { + return []; + } + + $nodeType = $scope->getType($node); + if (!$nodeType instanceof ConstantBooleanType) { + return []; + } + + $leftType = $scope->getType($node->left); + $rightType = $scope->getType($node->right); + + if (!$nodeType->getValue()) { + return [ + sprintf( + 'Strict comparison using %s between %s and %s will always evaluate to false.', + $node instanceof Node\Expr\BinaryOp\Identical ? '===' : '!==', + $leftType->describe(VerbosityLevel::value()), + $rightType->describe(VerbosityLevel::value()) + ), + ]; + } elseif ($this->checkAlwaysTrueStrictComparison) { + return [ + sprintf( + 'Strict comparison using %s between %s and %s will always evaluate to true.', + $node instanceof Node\Expr\BinaryOp\Identical ? '===' : '!==', + $leftType->describe(VerbosityLevel::value()), + $rightType->describe(VerbosityLevel::value()) + ), + ]; + } + + return []; + } + + private function isSpecifiedFunctionCall(Scope $scope, Expr $node): bool + { + return ( + $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\StaticCall + ) && $scope->isSpecified($node); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/TernaryOperatorConstantConditionRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/TernaryOperatorConstantConditionRule.php new file mode 100644 index 00000000..34390c66 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/TernaryOperatorConstantConditionRule.php @@ -0,0 +1,48 @@ +helper = $helper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\Ternary::class; + } + + /** + * @param \PhpParser\Node\Expr\Ternary $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode( + \PhpParser\Node $node, + \PHPStan\Analyser\Scope $scope + ): array + { + $exprType = $this->helper->getBooleanType($scope, $node->cond); + if ($exprType instanceof ConstantBooleanType) { + return [ + sprintf( + 'Ternary operator condition is always %s.', + $exprType->getValue() ? 'true' : 'false' + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/UnreachableIfBranchesRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/UnreachableIfBranchesRule.php new file mode 100644 index 00000000..b0ced8eb --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/UnreachableIfBranchesRule.php @@ -0,0 +1,57 @@ +helper = $helper; + } + + public function getNodeType(): string + { + return Node\Stmt\If_::class; + } + + /** + * @param \PhpParser\Node\Stmt\If_ $node + * @param Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + $errors = []; + $conditionType = $scope->getType($node->cond)->toBoolean(); + $nextBranchIsDead = $conditionType instanceof ConstantBooleanType && $conditionType->getValue() && $this->helper->shouldSkip($scope, $node->cond) && !$this->helper->shouldReportAlwaysTrueByDefault($node->cond); + + foreach ($node->elseifs as $elseif) { + if ($nextBranchIsDead) { + $errors[] = RuleErrorBuilder::message('Elseif branch is unreachable because previous condition is always true.')->line($elseif->getLine())->build(); + continue; + } + + $elseIfConditionType = $scope->getType($elseif->cond)->toBoolean(); + $nextBranchIsDead = $elseIfConditionType instanceof ConstantBooleanType && $elseIfConditionType->getValue() && $this->helper->shouldSkip($scope, $elseif->cond) && !$this->helper->shouldReportAlwaysTrueByDefault($elseif->cond); + } + + if ($node->else !== null && $nextBranchIsDead) { + $errors[] = RuleErrorBuilder::message('Else branch is unreachable because previous condition is always true.')->line($node->else->getLine())->build(); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Comparison/UnreachableTernaryElseBranchRule.php b/vendor/phpstan/phpstan/src/Rules/Comparison/UnreachableTernaryElseBranchRule.php new file mode 100644 index 00000000..c6e052af --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Comparison/UnreachableTernaryElseBranchRule.php @@ -0,0 +1,52 @@ +helper = $helper; + } + + public function getNodeType(): string + { + return Node\Expr\Ternary::class; + } + + /** + * @param \PhpParser\Node\Expr\Ternary $node + * @param Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + $conditionType = $scope->getType($node->cond)->toBoolean(); + if ( + $conditionType instanceof ConstantBooleanType + && $conditionType->getValue() + && $this->helper->shouldSkip($scope, $node->cond) + && !$this->helper->shouldReportAlwaysTrueByDefault($node->cond) + ) { + return [ + RuleErrorBuilder::message('Else branch is unreachable because ternary operator condition is always true.')->line($node->else->getLine())->build(), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Constants/ConstantRule.php b/vendor/phpstan/phpstan/src/Rules/Constants/ConstantRule.php new file mode 100644 index 00000000..b8a359f4 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Constants/ConstantRule.php @@ -0,0 +1,35 @@ +hasConstant($node->name)) { + return [ + sprintf( + 'Constant %s not found.', + (string) $node->name + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Exceptions/CaughtExceptionExistenceRule.php b/vendor/phpstan/phpstan/src/Rules/Exceptions/CaughtExceptionExistenceRule.php new file mode 100644 index 00000000..759aa319 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Exceptions/CaughtExceptionExistenceRule.php @@ -0,0 +1,75 @@ +broker = $broker; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; + } + + public function getNodeType(): string + { + return Catch_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Catch_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + $errors = []; + foreach ($node->types as $class) { + $className = (string) $class; + if (!$this->broker->hasClass($className)) { + $errors[] = RuleErrorBuilder::message(sprintf('Caught class %s not found.', $className))->line($class->getLine())->build(); + continue; + } + + $classReflection = $this->broker->getClass($className); + if (!$classReflection->isInterface() && !$classReflection->getNativeReflection()->implementsInterface(\Throwable::class)) { + $errors[] = RuleErrorBuilder::message(sprintf('Caught class %s is not an exception.', $classReflection->getDisplayName()))->line($class->getLine())->build(); + } + + if (!$this->checkClassCaseSensitivity) { + continue; + } + + $errors = array_merge( + $errors, + $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($className, $class)]) + ); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/FileRuleError.php b/vendor/phpstan/phpstan/src/Rules/FileRuleError.php new file mode 100644 index 00000000..7f5cd7fc --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/FileRuleError.php @@ -0,0 +1,10 @@ +type = $type; + $this->referencedClasses = $referencedClasses; + $this->unknownClassErrors = $unknownClassErrors; + } + + public function getType(): Type + { + return $this->type; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return $this->referencedClasses; + } + + /** + * @return RuleError[] + */ + public function getUnknownClassErrors(): array + { + return $this->unknownClassErrors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/FunctionCallParametersCheck.php b/vendor/phpstan/phpstan/src/Rules/FunctionCallParametersCheck.php new file mode 100644 index 00000000..9d45b4bb --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/FunctionCallParametersCheck.php @@ -0,0 +1,189 @@ +ruleLevelHelper = $ruleLevelHelper; + $this->checkArgumentTypes = $checkArgumentTypes; + $this->checkArgumentsPassedByReference = $checkArgumentsPassedByReference; + } + + /** + * @param \PHPStan\Reflection\ParametersAcceptor $parametersAcceptor + * @param \PHPStan\Analyser\Scope $scope + * @param \PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall|\PhpParser\Node\Expr\New_ $funcCall + * @param string[] $messages Eight message templates + * @return string[] + */ + public function check( + ParametersAcceptor $parametersAcceptor, + Scope $scope, + $funcCall, + array $messages + ): array + { + $functionParametersMinCount = 0; + $functionParametersMaxCount = 0; + foreach ($parametersAcceptor->getParameters() as $parameter) { + if (!$parameter->isOptional()) { + $functionParametersMinCount++; + } + + $functionParametersMaxCount++; + } + + if ($parametersAcceptor->isVariadic()) { + $functionParametersMaxCount = -1; + } + + $errors = []; + $invokedParametersCount = count($funcCall->args); + foreach ($funcCall->args as $arg) { + if ($arg->unpack) { + $invokedParametersCount = max($functionParametersMinCount, $functionParametersMaxCount); + break; + } + } + + if ($invokedParametersCount < $functionParametersMinCount || $invokedParametersCount > $functionParametersMaxCount) { + if ($functionParametersMinCount === $functionParametersMaxCount) { + $errors[] = sprintf( + $invokedParametersCount === 1 ? $messages[0] : $messages[1], + $invokedParametersCount, + $functionParametersMinCount + ); + } elseif ($functionParametersMaxCount === -1 && $invokedParametersCount < $functionParametersMinCount) { + $errors[] = sprintf( + $invokedParametersCount === 1 ? $messages[2] : $messages[3], + $invokedParametersCount, + $functionParametersMinCount + ); + } elseif ($functionParametersMaxCount !== -1) { + $errors[] = sprintf( + $invokedParametersCount === 1 ? $messages[4] : $messages[5], + $invokedParametersCount, + $functionParametersMinCount, + $functionParametersMaxCount + ); + } + } + + if ( + $scope->getType($funcCall) instanceof VoidType + && !$scope->isInFirstLevelStatement() + && !$funcCall instanceof \PhpParser\Node\Expr\New_ + ) { + $errors[] = $messages[7]; + } + + if (!$this->checkArgumentTypes && !$this->checkArgumentsPassedByReference) { + return $errors; + } + + $parameters = $parametersAcceptor->getParameters(); + + /** @var array $args */ + $args = $funcCall->args; + foreach ($args as $i => $argument) { + if (!isset($parameters[$i])) { + if (!$parametersAcceptor->isVariadic() || count($parameters) === 0) { + break; + } + + $parameter = $parameters[count($parameters) - 1]; + $parameterType = $parameter->getType(); + if (!($parameterType instanceof ArrayType)) { + break; + } + + if (!$argument->unpack) { + $parameterType = $parameterType->getItemType(); + } + } else { + $parameter = $parameters[$i]; + $parameterType = $parameter->getType(); + if ($parameter->isVariadic()) { + if ($parameterType instanceof ArrayType && !$argument->unpack) { + $parameterType = $parameterType->getItemType(); + } + } elseif ($argument->unpack) { + continue; + } + } + + $argumentValueType = $scope->getType($argument->value); + $secondAccepts = null; + if ($parameterType->isIterable()->yes() && $parameter->isVariadic()) { + $secondAccepts = $this->ruleLevelHelper->accepts( + new IterableType( + new MixedType(), + $parameterType->getIterableValueType() + ), + $argumentValueType, + $scope->isDeclareStrictTypes() + ); + } + + if ( + $this->checkArgumentTypes + && !$parameter->passedByReference()->createsNewVariable() + && !$this->ruleLevelHelper->accepts($parameterType, $argumentValueType, $scope->isDeclareStrictTypes()) + && ($secondAccepts === null || !$secondAccepts) + ) { + $verbosityLevel = $parameterType->isCallable()->yes() ? VerbosityLevel::value() : VerbosityLevel::typeOnly(); + $errors[] = sprintf( + $messages[6], + $i + 1, + sprintf('%s$%s', $parameter->isVariadic() ? '...' : '', $parameter->getName()), + $parameterType->describe($verbosityLevel), + $argumentValueType->describe($verbosityLevel) + ); + } + + if ( + !$this->checkArgumentsPassedByReference + || !$parameter->passedByReference()->yes() + || $argument->value instanceof \PhpParser\Node\Expr\Variable + || $argument->value instanceof \PhpParser\Node\Expr\ArrayDimFetch + || $argument->value instanceof \PhpParser\Node\Expr\PropertyFetch + || $argument->value instanceof \PhpParser\Node\Expr\StaticPropertyFetch + ) { + continue; + } + + $errors[] = sprintf( + $messages[8], + $i + 1, + sprintf('%s$%s', $parameter->isVariadic() ? '...' : '', $parameter->getName()) + ); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/FunctionDefinitionCheck.php b/vendor/phpstan/phpstan/src/Rules/FunctionDefinitionCheck.php new file mode 100644 index 00000000..772bb666 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/FunctionDefinitionCheck.php @@ -0,0 +1,302 @@ +broker = $broker; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; + $this->checkThisOnly = $checkThisOnly; + } + + /** + * @param \PhpParser\Node\FunctionLike $function + * @param string $parameterMessage + * @param string $returnMessage + * @return RuleError[] + */ + public function checkFunction( + FunctionLike $function, + string $parameterMessage, + string $returnMessage + ): array + { + if ($function instanceof ClassMethod) { + throw new \PHPStan\ShouldNotHappenException('Use FunctionDefinitionCheck::checkClassMethod() instead.'); + } + if ($function instanceof Function_) { + $functionName = $function->name->name; + if (isset($function->namespacedName)) { + $functionName = (string) $function->namespacedName; + } + $functionNameName = new Name($functionName); + if (!$this->broker->hasCustomFunction($functionNameName, null)) { + return []; + } + + $functionReflection = $this->broker->getCustomFunction($functionNameName, null); + + /** @var \PHPStan\Reflection\ParametersAcceptorWithPhpDocs $parametersAcceptor */ + $parametersAcceptor = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants()); + + return $this->checkParametersAcceptor( + $parametersAcceptor, + $function, + $parameterMessage, + $returnMessage + ); + } + + $errors = []; + foreach ($function->getParams() as $param) { + if ($param->type === null) { + continue; + } + $class = $param->type instanceof NullableType + ? (string) $param->type->type + : (string) $param->type; + $lowercasedClass = strtolower($class); + if ($lowercasedClass === '' || in_array($lowercasedClass, self::VALID_TYPEHINTS, true)) { + continue; + } + + if (!$this->broker->hasClass($class) || $this->broker->getClass($class)->isTrait()) { + if (!$param->var instanceof Variable || !is_string($param->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $errors[] = RuleErrorBuilder::message(sprintf($parameterMessage, $param->var->name, $class))->line($param->type->getLine())->build(); + } elseif ($this->checkClassCaseSensitivity) { + $errors = array_merge( + $errors, + $this->classCaseSensitivityCheck->checkClassNames([ + new ClassNameNodePair($class, $param->type), + ]) + ); + } + } + + $returnTypeNode = $function->getReturnType(); + if ($returnTypeNode === null) { + return $errors; + } + + $returnType = $returnTypeNode instanceof NullableType + ? (string) $returnTypeNode->type + : (string) $returnTypeNode; + + $lowercasedReturnType = strtolower($returnType); + + if ( + $lowercasedReturnType !== '' + && !in_array($lowercasedReturnType, self::VALID_TYPEHINTS, true) + ) { + if (!$this->broker->hasClass($returnType) || $this->broker->getClass($returnType)->isTrait()) { + $errors[] = RuleErrorBuilder::message(sprintf($returnMessage, $returnType))->line($returnTypeNode->getLine())->build(); + } elseif ($this->checkClassCaseSensitivity) { + $errors = array_merge( + $errors, + $this->classCaseSensitivityCheck->checkClassNames([ + new ClassNameNodePair($returnType, $returnTypeNode), + ]) + ); + } + } + + return $errors; + } + + /** + * @param PhpMethodFromParserNodeReflection $methodReflection + * @param ClassMethod $methodNode + * @param string $parameterMessage + * @param string $returnMessage + * @return RuleError[] + */ + public function checkClassMethod( + PhpMethodFromParserNodeReflection $methodReflection, + ClassMethod $methodNode, + string $parameterMessage, + string $returnMessage + ): array + { + /** @var \PHPStan\Reflection\ParametersAcceptorWithPhpDocs $parametersAcceptor */ + $parametersAcceptor = ParametersAcceptorSelector::selectSingle($methodReflection->getVariants()); + + return $this->checkParametersAcceptor( + $parametersAcceptor, + $methodNode, + $parameterMessage, + $returnMessage + ); + } + + /** + * @param ParametersAcceptorWithPhpDocs $parametersAcceptor + * @param FunctionLike $functionNode + * @param string $parameterMessage + * @param string $returnMessage + * @return RuleError[] + */ + private function checkParametersAcceptor( + ParametersAcceptorWithPhpDocs $parametersAcceptor, + FunctionLike $functionNode, + string $parameterMessage, + string $returnMessage + ): array + { + $errors = []; + $parameterNodes = $functionNode->getParams(); + $returnTypeNode = $functionNode->getReturnType() ?? $functionNode; + foreach ($parametersAcceptor->getParameters() as $parameter) { + if ($this->checkThisOnly) { + $referencedClasses = $parameter->getType()->getReferencedClasses(); + } else { + $referencedClasses = array_merge( + $parameter->getNativeType()->getReferencedClasses(), + $parameter->getPhpDocType()->getReferencedClasses() + ); + } + $parameterNode = null; + $parameterNodeCallback = function () use ($parameter, $parameterNodes, &$parameterNode): Param { + if ($parameterNode === null) { + $parameterNode = $this->getParameterNode($parameter->getName(), $parameterNodes); + } + + return $parameterNode; + }; + foreach ($referencedClasses as $class) { + if ($this->broker->hasClass($class) && !$this->broker->getClass($class)->isTrait()) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf( + $parameterMessage, + $parameter->getName(), + $class + ))->line($parameterNodeCallback()->getLine())->build(); + } + + if ($this->checkClassCaseSensitivity) { + $errors = array_merge( + $errors, + $this->classCaseSensitivityCheck->checkClassNames(array_map(static function (string $class) use ($parameterNodeCallback): ClassNameNodePair { + return new ClassNameNodePair($class, $parameterNodeCallback()); + }, $referencedClasses)) + ); + } + if (!($parameter->getType() instanceof NonexistentParentClassType)) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf($parameterMessage, $parameter->getName(), $parameter->getType()->describe(VerbosityLevel::typeOnly())))->line($parameterNodeCallback()->getLine())->build(); + } + + if ($this->checkThisOnly) { + $returnTypeReferencedClasses = $parametersAcceptor->getReturnType()->getReferencedClasses(); + } else { + $returnTypeReferencedClasses = array_merge( + $parametersAcceptor->getNativeReturnType()->getReferencedClasses(), + $parametersAcceptor->getPhpDocReturnType()->getReferencedClasses() + ); + } + + foreach ($returnTypeReferencedClasses as $class) { + if ($this->broker->hasClass($class) && !$this->broker->getClass($class)->isTrait()) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf($returnMessage, $class))->line($returnTypeNode->getLine())->build(); + } + + if ($this->checkClassCaseSensitivity) { + $errors = array_merge( + $errors, + $this->classCaseSensitivityCheck->checkClassNames(array_map(static function (string $class) use ($returnTypeNode): ClassNameNodePair { + return new ClassNameNodePair($class, $returnTypeNode); + }, $returnTypeReferencedClasses)) + ); + } + if ($parametersAcceptor->getReturnType() instanceof NonexistentParentClassType) { + $errors[] = RuleErrorBuilder::message(sprintf($returnMessage, $parametersAcceptor->getReturnType()->describe(VerbosityLevel::typeOnly())))->line($returnTypeNode->getLine())->build(); + } + + return $errors; + } + + /** + * @param string $parameterName + * @param Param[] $parameterNodes + * @return Param + */ + private function getParameterNode( + string $parameterName, + array $parameterNodes + ): Param + { + foreach ($parameterNodes as $param) { + if ($param->var instanceof \PhpParser\Node\Expr\Error) { + continue; + } + + if (!is_string($param->var->name)) { + continue; + } + + if ($param->var->name === $parameterName) { + return $param; + } + } + + throw new \PHPStan\ShouldNotHappenException(sprintf('Parameter %s not found.', $parameterName)); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/FunctionReturnTypeCheck.php b/vendor/phpstan/phpstan/src/Rules/FunctionReturnTypeCheck.php new file mode 100644 index 00000000..303ff70f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/FunctionReturnTypeCheck.php @@ -0,0 +1,84 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + /** + * @param \PHPStan\Analyser\Scope $scope + * @param \PHPStan\Type\Type $returnType + * @param \PhpParser\Node\Expr|null $returnValue + * @param string $emptyReturnStatementMessage + * @param string $voidMessage + * @param string $typeMismatchMessage + * @param bool $isGenerator + * @return string[] + */ + public function checkReturnType( + Scope $scope, + Type $returnType, + ?Expr $returnValue, + string $emptyReturnStatementMessage, + string $voidMessage, + string $typeMismatchMessage, + bool $isGenerator + ): array + { + if ($isGenerator) { + return []; + } + + $isVoidSuperType = (new VoidType())->isSuperTypeOf($returnType); + if ($returnValue === null) { + if (!$isVoidSuperType->no()) { + return []; + } + + return [ + sprintf( + $emptyReturnStatementMessage, + $returnType->describe(VerbosityLevel::typeOnly()) + ), + ]; + } + + $returnValueType = $scope->getType($returnValue); + + if ($isVoidSuperType->yes()) { + return [ + sprintf( + $voidMessage, + $returnValueType->describe(VerbosityLevel::typeOnly()) + ), + ]; + } + + if (!$this->ruleLevelHelper->accepts($returnType, $returnValueType, $scope->isDeclareStrictTypes())) { + return [ + sprintf( + $typeMismatchMessage, + $returnType->describe(VerbosityLevel::typeOnly()), + $returnValueType->describe(VerbosityLevel::typeOnly()) + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/CallCallablesRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/CallCallablesRule.php new file mode 100644 index 00000000..cb761683 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/CallCallablesRule.php @@ -0,0 +1,131 @@ +check = $check; + $this->ruleLevelHelper = $ruleLevelHelper; + $this->reportMaybes = $reportMaybes; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr\FuncCall::class; + } + + /** + * @param \PhpParser\Node\Expr\FuncCall $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode( + \PhpParser\Node $node, + Scope $scope + ): array + { + if (!$node->name instanceof \PhpParser\Node\Expr) { + return []; + } + + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->name, + 'Invoking callable on an unknown class %s.', + static function (Type $type): bool { + return $type->isCallable()->yes(); + } + ); + $type = $typeResult->getType(); + if ($type instanceof ErrorType) { + return $typeResult->getUnknownClassErrors(); + } + + $isCallable = $type->isCallable(); + if ($isCallable->no()) { + return [ + sprintf('Trying to invoke %s but it\'s not a callable.', $type->describe(VerbosityLevel::value())), + ]; + } + if ($this->reportMaybes && $isCallable->maybe()) { + return [ + sprintf('Trying to invoke %s but it might not be a callable.', $type->describe(VerbosityLevel::value())), + ]; + } + + $parametersAcceptors = $type->getCallableParametersAcceptors($scope); + $messages = []; + + if ( + count($parametersAcceptors) === 1 + && $parametersAcceptors[0] instanceof InaccessibleMethod + ) { + $method = $parametersAcceptors[0]->getMethod(); + $messages[] = sprintf( + 'Call to %s method %s() of class %s.', + $method->isPrivate() ? 'private' : 'protected', + $method->getName(), + $method->getDeclaringClass()->getDisplayName() + ); + } + + $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs( + $scope, + $node->args, + $parametersAcceptors + ); + + if ($type instanceof ClosureType) { + $callableDescription = 'closure'; + } else { + $callableDescription = sprintf('callable %s', $type->describe(VerbosityLevel::value())); + } + + return array_merge( + $messages, + $this->check->check( + $parametersAcceptor, + $scope, + $node, + [ + ucfirst($callableDescription) . ' invoked with %d parameter, %d required.', + ucfirst($callableDescription) . ' invoked with %d parameters, %d required.', + ucfirst($callableDescription) . ' invoked with %d parameter, at least %d required.', + ucfirst($callableDescription) . ' invoked with %d parameters, at least %d required.', + ucfirst($callableDescription) . ' invoked with %d parameter, %d-%d required.', + ucfirst($callableDescription) . ' invoked with %d parameters, %d-%d required.', + 'Parameter #%d %s of ' . $callableDescription . ' expects %s, %s given.', + 'Result of ' . $callableDescription . ' (void) is used.', + 'Parameter #%d %s of ' . $callableDescription . ' is passed by reference, so it expects variables only.', + ] + ) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/CallToFunctionParametersRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/CallToFunctionParametersRule.php new file mode 100644 index 00000000..7093e9af --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/CallToFunctionParametersRule.php @@ -0,0 +1,71 @@ +broker = $broker; + $this->check = $check; + } + + public function getNodeType(): string + { + return FuncCall::class; + } + + /** + * @param \PhpParser\Node\Expr\FuncCall $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!($node->name instanceof \PhpParser\Node\Name)) { + return []; + } + + if (!$this->broker->hasFunction($node->name, $scope)) { + return []; + } + + $function = $this->broker->getFunction($node->name, $scope); + + return $this->check->check( + ParametersAcceptorSelector::selectFromArgs( + $scope, + $node->args, + $function->getVariants() + ), + $scope, + $node, + [ + 'Function ' . $function->getName() . ' invoked with %d parameter, %d required.', + 'Function ' . $function->getName() . ' invoked with %d parameters, %d required.', + 'Function ' . $function->getName() . ' invoked with %d parameter, at least %d required.', + 'Function ' . $function->getName() . ' invoked with %d parameters, at least %d required.', + 'Function ' . $function->getName() . ' invoked with %d parameter, %d-%d required.', + 'Function ' . $function->getName() . ' invoked with %d parameters, %d-%d required.', + 'Parameter #%d %s of function ' . $function->getName() . ' expects %s, %s given.', + 'Result of function ' . $function->getName() . ' (void) is used.', + 'Parameter #%d %s of function ' . $function->getName() . ' is passed by reference, so it expects variables only.', + ] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/CallToNonExistentFunctionRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/CallToNonExistentFunctionRule.php new file mode 100644 index 00000000..47557d2f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/CallToNonExistentFunctionRule.php @@ -0,0 +1,65 @@ +broker = $broker; + $this->checkFunctionNameCase = $checkFunctionNameCase; + } + + public function getNodeType(): string + { + return FuncCall::class; + } + + /** + * @param \PhpParser\Node\Expr\FuncCall $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!($node->name instanceof \PhpParser\Node\Name)) { + return []; + } + + if (!$this->broker->hasFunction($node->name, $scope)) { + return [sprintf('Function %s not found.', (string) $node->name)]; + } + + $function = $this->broker->getFunction($node->name, $scope); + $name = (string) $node->name; + + if ($this->checkFunctionNameCase) { + /** @var string $calledFunctionName */ + $calledFunctionName = $this->broker->resolveFunctionName($node->name, $scope); + if ( + strtolower($function->getName()) === strtolower($calledFunctionName) + && $function->getName() !== $calledFunctionName + ) { + return [sprintf('Call to function %s() with incorrect case: %s', $function->getName(), $name)]; + } + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/ClosureReturnTypeRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/ClosureReturnTypeRule.php new file mode 100644 index 00000000..8d77ad66 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/ClosureReturnTypeRule.php @@ -0,0 +1,53 @@ +returnTypeCheck = $returnTypeCheck; + } + + public function getNodeType(): string + { + return Return_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Return_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$scope->isInAnonymousFunction()) { + return []; + } + + /** @var \PHPStan\Type\Type $returnType */ + $returnType = $scope->getAnonymousFunctionReturnType(); + $generatorType = new ObjectType(\Generator::class); + + return $this->returnTypeCheck->checkReturnType( + $scope, + $returnType, + $node->expr, + 'Anonymous function should return %s but empty return statement found.', + 'Anonymous function with return type void returns %s but should not return anything.', + 'Anonymous function should return %s but returns %s.', + $generatorType->isSuperTypeOf($returnType)->yes() + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/ExistingClassesInClosureTypehintsRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/ExistingClassesInClosureTypehintsRule.php new file mode 100644 index 00000000..b4871966 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/ExistingClassesInClosureTypehintsRule.php @@ -0,0 +1,41 @@ +check = $check; + } + + public function getNodeType(): string + { + return Closure::class; + } + + /** + * @param \PhpParser\Node\Expr\Closure $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + return $this->check->checkFunction( + $node, + 'Parameter $%s of anonymous function has invalid typehint type %s.', + 'Return typehint of anonymous function has invalid type %s.' + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/ExistingClassesInTypehintsRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/ExistingClassesInTypehintsRule.php new file mode 100644 index 00000000..2386636c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/ExistingClassesInTypehintsRule.php @@ -0,0 +1,47 @@ +check = $check; + } + + public function getNodeType(): string + { + return Function_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Function_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + return $this->check->checkFunction( + $node, + sprintf( + 'Parameter $%%s of function %s() has invalid typehint type %%s.', + (string) $node->namespacedName + ), + sprintf( + 'Return typehint of function %s() has invalid type %%s.', + (string) $node->namespacedName + ) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/IncompatibleDefaultParameterTypeRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/IncompatibleDefaultParameterTypeRule.php new file mode 100644 index 00000000..ef9d3194 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/IncompatibleDefaultParameterTypeRule.php @@ -0,0 +1,83 @@ +broker = $broker; + } + + public function getNodeType(): string + { + return FunctionLike::class; + } + + /** + * @param FunctionLike $node + * @param Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!($node instanceof Function_)) { + return []; + } + + $name = $node->namespacedName; + if (!$this->broker->hasFunction($name, $scope)) { + return []; + } + + $function = $this->broker->getFunction($name, $scope); + $parameters = ParametersAcceptorSelector::selectSingle($function->getVariants()); + + $errors = []; + foreach ($node->getParams() as $paramI => $param) { + if ($param->default === null) { + continue; + } + if ( + $param->var instanceof Node\Expr\Error + || !is_string($param->var->name) + ) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $defaultValueType = $scope->getType($param->default); + $parameterType = $parameters->getParameters()[$paramI]->getType(); + + if ($parameterType->isSuperTypeOf($defaultValueType)->yes()) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf( + 'Default value of the parameter #%d $%s (%s) of function %s() is incompatible with type %s.', + $paramI + 1, + $param->var->name, + $defaultValueType->describe(VerbosityLevel::value()), + $function->getName(), + $parameterType->describe(VerbosityLevel::value()) + ))->line($param->getLine())->build(); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/InnerFunctionRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/InnerFunctionRule.php new file mode 100644 index 00000000..fc43ab61 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/InnerFunctionRule.php @@ -0,0 +1,33 @@ +getFunction() === null) { + return []; + } + + return [ + 'Inner named functions are not supported by PHPStan. Consider refactoring to an anonymous function, class method, or a top-level-defined function. See issue #165 (https://github.com/phpstan/phpstan/issues/165) for more details.', + ]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/NonExistentDefinedFunctionRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/NonExistentDefinedFunctionRule.php new file mode 100644 index 00000000..4f99bbfd --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/NonExistentDefinedFunctionRule.php @@ -0,0 +1,51 @@ +broker = $broker; + } + + public function getNodeType(): string + { + return Function_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Function_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + $functionName = $node->name->name; + if (isset($node->namespacedName)) { + $functionName = (string) $node->namespacedName; + } + $functionNameName = new Name($functionName); + if ($this->broker->hasFunction($functionNameName, null)) { + return []; + } + + return [ + sprintf( + 'Function %s not found while trying to analyse it - autoloading is probably not configured properly.', + $functionName + ), + ]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/PrintfParametersRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/PrintfParametersRule.php new file mode 100644 index 00000000..7679049d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/PrintfParametersRule.php @@ -0,0 +1,120 @@ +name instanceof \PhpParser\Node\Name)) { + return []; + } + + $functionsArgumentPositions = [ + 'printf' => 0, + 'sprintf' => 0, + 'sscanf' => 1, + 'fscanf' => 1, + ]; + $minimumNumberOfArguments = [ + 'printf' => 1, + 'sprintf' => 1, + 'sscanf' => 3, + 'fscanf' => 3, + ]; + + $name = strtolower((string) $node->name); + if (!isset($functionsArgumentPositions[$name])) { + return []; + } + + $formatArgumentPosition = $functionsArgumentPositions[$name]; + + $args = $node->args; + $argsCount = count($args); + if ($argsCount < $minimumNumberOfArguments[$name]) { + return []; // caught by CallToFunctionParametersRule + } + + $formatArgType = $scope->getType($args[$formatArgumentPosition]->value); + if (!($formatArgType instanceof ConstantStringType)) { + return []; // inspect only literal string format + } + + foreach ($node->args as $arg) { + if ($arg->unpack) { + return []; + } + } + + $format = $formatArgType->getValue(); + $placeHoldersCount = $this->getPlaceholdersCount($name, $format); + $argsCount -= $formatArgumentPosition; + + if ($argsCount !== $placeHoldersCount + 1) { + return [ + sprintf( + sprintf( + '%s, %s.', + $placeHoldersCount === 1 ? 'Call to %s contains %d placeholder' : 'Call to %s contains %d placeholders', + $argsCount - 1 === 1 ? '%d value given' : '%d values given' + ), + $name, + $placeHoldersCount, + $argsCount - 1 + ), + ]; + } + + return []; + } + + private function getPlaceholdersCount(string $functionName, string $format): int + { + $specifiers = in_array($functionName, ['sprintf', 'printf'], true) ? '[bcdeEfFgGosuxX]' : '(?:[cdDeEfinosuxX]|\[[^\]]+\])'; + $pattern = '~(?%*)%(?:(?\d+)\$)?[-+]?(?:[ 0]|(?:\'[^%]))?-?\d*(?:\.\d*)?' . $specifiers . '~'; + + $matches = \Nette\Utils\Strings::matchAll($format, $pattern, PREG_SET_ORDER); + + if (count($matches) === 0) { + return 0; + } + + $placeholders = array_filter($matches, static function (array $match): bool { + return strlen($match['before']) % 2 === 0; + }); + + if (count($placeholders) === 0) { + return 0; + } + + $maxPositionedNumber = 0; + $maxOrdinaryNumber = 0; + foreach ($placeholders as $placeholder) { + if (isset($placeholder['position']) && $placeholder['position'] !== '') { + $maxPositionedNumber = max((int) $placeholder['position'], $maxPositionedNumber); + } else { + $maxOrdinaryNumber++; + } + } + + return max($maxPositionedNumber, $maxOrdinaryNumber); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/ReturnTypeRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/ReturnTypeRule.php new file mode 100644 index 00000000..5d6f8419 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/ReturnTypeRule.php @@ -0,0 +1,77 @@ +returnTypeCheck = $returnTypeCheck; + } + + public function getNodeType(): string + { + return Return_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Return_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ($scope->getFunction() === null) { + return []; + } + + if ($scope->isInAnonymousFunction()) { + return []; + } + + $function = $scope->getFunction(); + if ( + !($function instanceof PhpFunctionFromParserNodeReflection) + || $function instanceof PhpMethodFromParserNodeReflection + ) { + return []; + } + + $reflection = null; + if (function_exists($function->getName())) { + $reflection = new \ReflectionFunction($function->getName()); + } + + return $this->returnTypeCheck->checkReturnType( + $scope, + ParametersAcceptorSelector::selectSingle($function->getVariants())->getReturnType(), + $node->expr, + sprintf( + 'Function %s() should return %%s but empty return statement found.', + $function->getName() + ), + sprintf( + 'Function %s() with return type void returns %%s but should not return anything.', + $function->getName() + ), + sprintf( + 'Function %s() should return %%s but returns %%s.', + $function->getName() + ), + $reflection !== null && $reflection->isGenerator() + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Functions/UnusedClosureUsesRule.php b/vendor/phpstan/phpstan/src/Rules/Functions/UnusedClosureUsesRule.php new file mode 100644 index 00000000..2c2aa2fc --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Functions/UnusedClosureUsesRule.php @@ -0,0 +1,49 @@ +check = $check; + } + + public function getNodeType(): string + { + return Node\Expr\Closure::class; + } + + /** + * @param \PhpParser\Node\Expr\Closure $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (count($node->uses) === 0) { + return []; + } + + return $this->check->getUnusedParameters( + $scope, + array_map(static function (Node\Expr\ClosureUse $use): string { + if (!is_string($use->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + return $use->var->name; + }, $node->uses), + $node->stmts, + 'Anonymous function has an unused use $%s.' + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/LineRuleError.php b/vendor/phpstan/phpstan/src/Rules/LineRuleError.php new file mode 100644 index 00000000..0388b7fc --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/LineRuleError.php @@ -0,0 +1,10 @@ +broker = $broker; + $this->check = $check; + $this->ruleLevelHelper = $ruleLevelHelper; + $this->checkFunctionNameCase = $checkFunctionNameCase; + $this->reportMagicMethods = $reportMagicMethods; + } + + public function getNodeType(): string + { + return MethodCall::class; + } + + /** + * @param \PhpParser\Node\Expr\MethodCall $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\Identifier) { + return []; + } + + $name = $node->name->name; + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->var, + sprintf('Call to method %s() on an unknown class %%s.', $name), + static function (Type $type) use ($name): bool { + return $type->canCallMethods()->yes() && $type->hasMethod($name)->yes(); + } + ); + $type = $typeResult->getType(); + if ($type instanceof ErrorType) { + return $typeResult->getUnknownClassErrors(); + } + if (!$type->canCallMethods()->yes()) { + return [ + sprintf('Cannot call method %s() on %s.', $name, $type->describe(VerbosityLevel::typeOnly())), + ]; + } + + if (!$type->hasMethod($name)->yes()) { + $directClassNames = $typeResult->getReferencedClasses(); + if (!$this->reportMagicMethods) { + foreach ($directClassNames as $className) { + if (!$this->broker->hasClass($className)) { + continue; + } + + $classReflection = $this->broker->getClass($className); + if ($classReflection->hasNativeMethod('__call')) { + return []; + } + } + } + + if (count($directClassNames) === 1) { + $referencedClass = $directClassNames[0]; + $methodClassReflection = $this->broker->getClass($referencedClass); + $parentClassReflection = $methodClassReflection->getParentClass(); + while ($parentClassReflection !== false) { + if ($parentClassReflection->hasMethod($name)) { + return [ + sprintf( + 'Call to private method %s() of parent class %s.', + $parentClassReflection->getMethod($name, $scope)->getName(), + $parentClassReflection->getDisplayName() + ), + ]; + } + + $parentClassReflection = $parentClassReflection->getParentClass(); + } + } + + return [ + sprintf( + 'Call to an undefined method %s::%s().', + $type->describe(VerbosityLevel::typeOnly()), + $name + ), + ]; + } + + $methodReflection = $type->getMethod($name, $scope); + $messagesMethodName = $methodReflection->getDeclaringClass()->getDisplayName() . '::' . $methodReflection->getName() . '()'; + $errors = []; + if (!$scope->canCallMethod($methodReflection)) { + $errors[] = sprintf( + 'Call to %s method %s() of class %s.', + $methodReflection->isPrivate() ? 'private' : 'protected', + $methodReflection->getName(), + $methodReflection->getDeclaringClass()->getDisplayName() + ); + } + + $errors = array_merge($errors, $this->check->check( + ParametersAcceptorSelector::selectFromArgs( + $scope, + $node->args, + $methodReflection->getVariants() + ), + $scope, + $node, + [ + 'Method ' . $messagesMethodName . ' invoked with %d parameter, %d required.', + 'Method ' . $messagesMethodName . ' invoked with %d parameters, %d required.', + 'Method ' . $messagesMethodName . ' invoked with %d parameter, at least %d required.', + 'Method ' . $messagesMethodName . ' invoked with %d parameters, at least %d required.', + 'Method ' . $messagesMethodName . ' invoked with %d parameter, %d-%d required.', + 'Method ' . $messagesMethodName . ' invoked with %d parameters, %d-%d required.', + 'Parameter #%d %s of method ' . $messagesMethodName . ' expects %s, %s given.', + 'Result of method ' . $messagesMethodName . ' (void) is used.', + 'Parameter #%d %s of method ' . $messagesMethodName . ' is passed by reference, so it expects variables only.', + ] + )); + + if ( + $this->checkFunctionNameCase + && strtolower($methodReflection->getName()) === strtolower($name) + && $methodReflection->getName() !== $name + ) { + $errors[] = sprintf('Call to method %s with incorrect case: %s', $messagesMethodName, $name); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Methods/CallStaticMethodsRule.php b/vendor/phpstan/phpstan/src/Rules/Methods/CallStaticMethodsRule.php new file mode 100644 index 00000000..d60584a1 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Methods/CallStaticMethodsRule.php @@ -0,0 +1,279 @@ +broker = $broker; + $this->check = $check; + $this->ruleLevelHelper = $ruleLevelHelper; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + $this->checkFunctionNameCase = $checkFunctionNameCase; + $this->reportMagicMethods = $reportMagicMethods; + } + + public function getNodeType(): string + { + return StaticCall::class; + } + + /** + * @param \PhpParser\Node\Expr\StaticCall $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\Identifier) { + return []; + } + $methodName = $node->name->name; + + $class = $node->class; + $errors = []; + $isInterface = false; + if ($class instanceof Name) { + $className = (string) $class; + $lowercasedClassName = strtolower($className); + if (in_array($lowercasedClassName, ['self', 'static'], true)) { + if (!$scope->isInClass()) { + return [ + sprintf( + 'Calling %s::%s() outside of class scope.', + $className, + $methodName + ), + ]; + } + $className = $scope->getClassReflection()->getName(); + } elseif ($lowercasedClassName === 'parent') { + if (!$scope->isInClass()) { + return [ + sprintf( + 'Calling %s::%s() outside of class scope.', + $className, + $methodName + ), + ]; + } + $currentClassReflection = $scope->getClassReflection(); + if ($currentClassReflection->getParentClass() === false) { + return [ + sprintf( + '%s::%s() calls parent::%s() but %s does not extend any class.', + $scope->getClassReflection()->getDisplayName(), + $scope->getFunctionName(), + $methodName, + $scope->getClassReflection()->getDisplayName() + ), + ]; + } + + if ($scope->getFunctionName() === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $className = $currentClassReflection->getParentClass()->getName(); + } else { + if (!$this->broker->hasClass($className)) { + return [ + sprintf('Call to static method %s() on an unknown class %s.', $methodName, $className), + ]; + } else { + $errors = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($className, $class)]); + } + + $classReflection = $this->broker->getClass($className); + $isInterface = $classReflection->isInterface(); + $className = $classReflection->getName(); + } + + $classType = new ObjectType($className); + } else { + $classTypeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $class, + sprintf('Call to static method %s() on an unknown class %%s.', $methodName), + static function (Type $type) use ($methodName): bool { + return $type->canCallMethods()->yes() && $type->hasMethod($methodName)->yes(); + } + ); + $classType = $classTypeResult->getType(); + if ($classType instanceof ErrorType) { + return $classTypeResult->getUnknownClassErrors(); + } + } + + if ((new StringType())->isSuperTypeOf($classType)->yes()) { + return []; + } + + $typeForDescribe = $classType; + $classType = TypeCombinator::remove($classType, new StringType()); + + if (!$classType->canCallMethods()->yes()) { + return array_merge($errors, [ + sprintf('Cannot call static method %s() on %s.', $methodName, $typeForDescribe->describe(VerbosityLevel::typeOnly())), + ]); + } + + if (!$classType->hasMethod($methodName)->yes()) { + if (!$this->reportMagicMethods) { + $directClassNames = TypeUtils::getDirectClassNames($classType); + foreach ($directClassNames as $className) { + if (!$this->broker->hasClass($className)) { + continue; + } + + $classReflection = $this->broker->getClass($className); + if ($classReflection->hasNativeMethod('__callStatic')) { + return []; + } + } + } + + return array_merge($errors, [ + sprintf( + 'Call to an undefined static method %s::%s().', + $typeForDescribe->describe(VerbosityLevel::typeOnly()), + $methodName + ), + ]); + } + + $method = $classType->getMethod($methodName, $scope); + if (!$method->isStatic()) { + $function = $scope->getFunction(); + if ( + !$function instanceof MethodReflection + || $function->isStatic() + || !$scope->isInClass() + || ( + $classType instanceof TypeWithClassName + && $scope->getClassReflection()->getName() !== $classType->getClassName() + && !$scope->getClassReflection()->isSubclassOf($classType->getClassName()) + ) + ) { + return array_merge($errors, [ + sprintf( + 'Static call to instance method %s::%s().', + $method->getDeclaringClass()->getDisplayName(), + $method->getName() + ), + ]); + } + } + + if (!$scope->canCallMethod($method)) { + $errors = array_merge($errors, [ + sprintf( + 'Call to %s %s %s() of class %s.', + $method->isPrivate() ? 'private' : 'protected', + $method->isStatic() ? 'static method' : 'method', + $method->getName(), + $method->getDeclaringClass()->getDisplayName() + ), + ]); + } + + if ($isInterface && $method->isStatic()) { + return [ + sprintf( + 'Cannot call static method %s() on interface %s.', + $method->getName(), + $classType->describe(VerbosityLevel::typeOnly()) + ), + ]; + } + + $lowercasedMethodName = sprintf( + '%s %s', + $method->isStatic() ? 'static method' : 'method', + $method->getDeclaringClass()->getDisplayName() . '::' . $method->getName() . '()' + ); + $displayMethodName = sprintf( + '%s %s', + $method->isStatic() ? 'Static method' : 'Method', + $method->getDeclaringClass()->getDisplayName() . '::' . $method->getName() . '()' + ); + + $errors = array_merge($errors, $this->check->check( + ParametersAcceptorSelector::selectFromArgs( + $scope, + $node->args, + $method->getVariants() + ), + $scope, + $node, + [ + $displayMethodName . ' invoked with %d parameter, %d required.', + $displayMethodName . ' invoked with %d parameters, %d required.', + $displayMethodName . ' invoked with %d parameter, at least %d required.', + $displayMethodName . ' invoked with %d parameters, at least %d required.', + $displayMethodName . ' invoked with %d parameter, %d-%d required.', + $displayMethodName . ' invoked with %d parameters, %d-%d required.', + 'Parameter #%d %s of ' . $lowercasedMethodName . ' expects %s, %s given.', + 'Result of ' . $lowercasedMethodName . ' (void) is used.', + 'Parameter #%d %s of ' . $lowercasedMethodName . ' is passed by reference, so it expects variables only.', + ] + )); + + if ( + $this->checkFunctionNameCase + && $method->getName() !== $methodName + ) { + $errors[] = sprintf('Call to %s with incorrect case: %s', $lowercasedMethodName, $methodName); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Methods/ExistingClassesInTypehintsRule.php b/vendor/phpstan/phpstan/src/Rules/Methods/ExistingClassesInTypehintsRule.php new file mode 100644 index 00000000..9cffefc6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Methods/ExistingClassesInTypehintsRule.php @@ -0,0 +1,59 @@ +check = $check; + } + + public function getNodeType(): string + { + return InClassMethodNode::class; + } + + /** + * @param \PHPStan\Node\InClassMethodNode $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + $methodReflection = $scope->getFunction(); + if (!$methodReflection instanceof PhpMethodFromParserNodeReflection) { + throw new \PHPStan\ShouldNotHappenException(); + } + if (!$scope->isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->check->checkClassMethod( + $methodReflection, + $node->getOriginalNode(), + sprintf( + 'Parameter $%%s of method %s::%s() has invalid typehint type %%s.', + $scope->getClassReflection()->getDisplayName(), + $methodReflection->getName() + ), + sprintf( + 'Return typehint of method %s::%s() has invalid type %%s.', + $scope->getClassReflection()->getDisplayName(), + $methodReflection->getName() + ) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Methods/IncompatibleDefaultParameterTypeRule.php b/vendor/phpstan/phpstan/src/Rules/Methods/IncompatibleDefaultParameterTypeRule.php new file mode 100644 index 00000000..1115ec4f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Methods/IncompatibleDefaultParameterTypeRule.php @@ -0,0 +1,70 @@ +getFunction(); + if (!$method instanceof PhpMethodFromParserNodeReflection) { + return []; + } + + $parameters = ParametersAcceptorSelector::selectSingle($method->getVariants()); + + $errors = []; + foreach ($node->getOriginalNode()->getParams() as $paramI => $param) { + if ($param->default === null) { + continue; + } + if ( + $param->var instanceof Node\Expr\Error + || !is_string($param->var->name) + ) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $defaultValueType = $scope->getType($param->default); + $parameterType = $parameters->getParameters()[$paramI]->getType(); + + if ($parameterType->isSuperTypeOf($defaultValueType)->yes()) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf( + 'Default value of the parameter #%d $%s (%s) of method %s::%s() is incompatible with type %s.', + $paramI + 1, + $param->var->name, + $defaultValueType->describe(VerbosityLevel::value()), + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + $parameterType->describe(VerbosityLevel::value()) + ))->line($param->getLine())->build(); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Methods/MethodSignatureRule.php b/vendor/phpstan/phpstan/src/Rules/Methods/MethodSignatureRule.php new file mode 100644 index 00000000..d62acd1d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Methods/MethodSignatureRule.php @@ -0,0 +1,188 @@ +reportMaybes = $reportMaybes; + $this->reportStatic = $reportStatic; + } + + public function getNodeType(): string + { + return ClassMethod::class; + } + + /** + * @param \PhpParser\Node\Stmt\ClassMethod $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + $methodName = (string) $node->name; + + if ($methodName === '__construct') { + return []; + } + + $class = $scope->getClassReflection(); + if ($class === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + $method = $class->getNativeMethod($methodName); + if (!$this->reportStatic && $method->isStatic()) { + return []; + } + if ($method->isPrivate()) { + return []; + } + $parameters = ParametersAcceptorSelector::selectSingle($method->getVariants()); + + $errors = []; + foreach ($this->collectParentMethods($methodName, $class, $scope) as $parentMethod) { + $parentParameters = ParametersAcceptorSelector::selectFromTypes(array_map(static function (ParameterReflection $parameter): Type { + return $parameter->getType(); + }, $parameters->getParameters()), $parentMethod->getVariants(), false); + + $returnTypeCompatibility = $this->checkReturnTypeCompatibility($parameters->getReturnType(), $parentParameters->getReturnType()); + if ($returnTypeCompatibility->no() || (!$returnTypeCompatibility->yes() && $this->reportMaybes)) { + $errors[] = sprintf( + 'Return type (%s) of method %s::%s() should be %s with return type (%s) of method %s::%s()', + $parameters->getReturnType()->describe(VerbosityLevel::typeOnly()), + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + $returnTypeCompatibility->no() ? 'compatible' : 'covariant', + $parentParameters->getReturnType()->describe(VerbosityLevel::typeOnly()), + $parentMethod->getDeclaringClass()->getDisplayName(), + $parentMethod->getName() + ); + } + + $parameterResults = $this->checkParameterTypeCompatibility($parameters->getParameters(), $parentParameters->getParameters()); + foreach ($parameterResults as $parameterIndex => $parameterResult) { + if ($parameterResult->yes()) { + continue; + } + if (!$parameterResult->no() && !$this->reportMaybes) { + continue; + } + $parameter = $parameters->getParameters()[$parameterIndex]; + $parentParameter = $parentParameters->getParameters()[$parameterIndex]; + $errors[] = sprintf( + 'Parameter #%d $%s (%s) of method %s::%s() should be %s with parameter $%s (%s) of method %s::%s()', + $parameterIndex + 1, + $parameter->getName(), + $parameter->getType()->describe(VerbosityLevel::typeOnly()), + $method->getDeclaringClass()->getDisplayName(), + $method->getName(), + $parameterResult->no() ? 'compatible' : 'contravariant', + $parentParameter->getName(), + $parentParameter->getType()->describe(VerbosityLevel::typeOnly()), + $parentMethod->getDeclaringClass()->getDisplayName(), + $parentMethod->getName() + ); + } + } + + return $errors; + } + + /** + * @param string $methodName + * @param \PHPStan\Reflection\ClassReflection $class + * @param \PHPStan\Analyser\Scope $scope + * @return \PHPStan\Reflection\MethodReflection[] + */ + private function collectParentMethods(string $methodName, ClassReflection $class, Scope $scope): array + { + $parentMethods = []; + + $parentClass = $class->getParentClass(); + if ($parentClass !== false && $parentClass->hasMethod($methodName)) { + $parentMethod = $parentClass->getMethod($methodName, $scope); + if (!$parentMethod->isPrivate()) { + $parentMethods[] = $parentMethod; + } + } + + foreach ($class->getInterfaces() as $interface) { + if (!$interface->hasMethod($methodName)) { + continue; + } + + $parentMethods[] = $interface->getMethod($methodName, $scope); + } + + return $parentMethods; + } + + private function checkReturnTypeCompatibility( + Type $returnType, + Type $parentReturnType + ): TrinaryLogic + { + // Allow adding `void` return type hints when the parent defines no return type + if ($returnType instanceof VoidType && $parentReturnType instanceof MixedType) { + return TrinaryLogic::createYes(); + } + + // We can return anything + if ($parentReturnType instanceof VoidType) { + return TrinaryLogic::createYes(); + } + + return $parentReturnType->isSuperTypeOf($returnType); + } + + /** + * @param \PHPStan\Reflection\ParameterReflection[] $parameters + * @param \PHPStan\Reflection\ParameterReflection[] $parentParameters + * @return array + */ + private function checkParameterTypeCompatibility( + array $parameters, + array $parentParameters + ): array + { + $parameterResults = []; + + $numberOfParameters = min(count($parameters), count($parentParameters)); + for ($i = 0; $i < $numberOfParameters; $i++) { + $parameter = $parameters[$i]; + $parentParameter = $parentParameters[$i]; + + $parameterType = $parameter->getType(); + $parentParameterType = $parentParameter->getType(); + + $parameterResults[] = $parameterType->isSuperTypeOf($parentParameterType); + } + + return $parameterResults; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Methods/ReturnTypeRule.php b/vendor/phpstan/phpstan/src/Rules/Methods/ReturnTypeRule.php new file mode 100644 index 00000000..2c68c209 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Methods/ReturnTypeRule.php @@ -0,0 +1,76 @@ +returnTypeCheck = $returnTypeCheck; + } + + public function getNodeType(): string + { + return Return_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Return_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ($scope->getFunction() === null) { + return []; + } + + if ($scope->isInAnonymousFunction()) { + return []; + } + + $method = $scope->getFunction(); + if (!($method instanceof MethodReflection)) { + return []; + } + + $reflection = null; + if ($method->getDeclaringClass()->getNativeReflection()->hasMethod($method->getName())) { + $reflection = $method->getDeclaringClass()->getNativeReflection()->getMethod($method->getName()); + } + + return $this->returnTypeCheck->checkReturnType( + $scope, + ParametersAcceptorSelector::selectSingle($method->getVariants())->getReturnType(), + $node->expr, + sprintf( + 'Method %s::%s() should return %%s but empty return statement found.', + $method->getDeclaringClass()->getDisplayName(), + $method->getName() + ), + sprintf( + 'Method %s::%s() with return type void returns %%s but should not return anything.', + $method->getDeclaringClass()->getDisplayName(), + $method->getName() + ), + sprintf( + 'Method %s::%s() should return %%s but returns %%s.', + $method->getDeclaringClass()->getDisplayName(), + $method->getName() + ), + $reflection !== null && $reflection->isGenerator() + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Namespaces/ExistingNamesInGroupUseRule.php b/vendor/phpstan/phpstan/src/Rules/Namespaces/ExistingNamesInGroupUseRule.php new file mode 100644 index 00000000..15e5a810 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Namespaces/ExistingNamesInGroupUseRule.php @@ -0,0 +1,129 @@ +broker = $broker; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + $this->checkFunctionNameCase = $checkFunctionNameCase; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Stmt\GroupUse::class; + } + + /** + * @param \PhpParser\Node\Stmt\GroupUse $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + $errors = []; + foreach ($node->uses as $use) { + $error = null; + + /** @var Node\Name $name */ + $name = Node\Name::concat($node->prefix, $use->name); + if ( + $node->type === Use_::TYPE_CONSTANT + || $use->type === Use_::TYPE_CONSTANT + ) { + $error = $this->checkConstant($name); + } elseif ( + $node->type === Use_::TYPE_FUNCTION + || $use->type === Use_::TYPE_FUNCTION + ) { + $error = $this->checkFunction($name); + } elseif ($use->type === Use_::TYPE_NORMAL) { + $error = $this->checkClass($name); + } else { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ($error === null) { + continue; + } + + $errors[] = $error; + } + + return $errors; + } + + private function checkConstant(Node\Name $name): ?RuleError + { + if (!$this->broker->hasConstant($name, null)) { + return RuleErrorBuilder::message(sprintf('Used constant %s not found.', (string) $name))->build(); + } + + return null; + } + + private function checkFunction(Node\Name $name): ?RuleError + { + if (!$this->broker->hasFunction($name, null)) { + return RuleErrorBuilder::message(sprintf('Used function %s not found.', (string) $name))->build(); + } + + if ($this->checkFunctionNameCase) { + $functionReflection = $this->broker->getFunction($name, null); + $realName = $functionReflection->getName(); + $usedName = (string) $name; + if ( + strtolower($realName) === strtolower($usedName) + && $realName !== $usedName + ) { + return RuleErrorBuilder::message(sprintf( + 'Function %s used with incorrect case: %s.', + $realName, + $usedName + ))->build(); + } + } + + return null; + } + + private function checkClass(Node\Name $name): ?RuleError + { + $errors = $this->classCaseSensitivityCheck->checkClassNames([ + new ClassNameNodePair((string) $name, $name), + ]); + if (count($errors) === 0) { + return null; + } elseif (count($errors) === 1) { + return $errors[0]; + } + + throw new \PHPStan\ShouldNotHappenException(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Namespaces/ExistingNamesInUseRule.php b/vendor/phpstan/phpstan/src/Rules/Namespaces/ExistingNamesInUseRule.php new file mode 100644 index 00000000..a1b8ba2b --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Namespaces/ExistingNamesInUseRule.php @@ -0,0 +1,130 @@ +broker = $broker; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + $this->checkFunctionNameCase = $checkFunctionNameCase; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Stmt\Use_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Use_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ($node->type === Node\Stmt\Use_::TYPE_UNKNOWN) { + throw new \PHPStan\ShouldNotHappenException(); + } + + foreach ($node->uses as $use) { + if ($use->type !== Node\Stmt\Use_::TYPE_UNKNOWN) { + throw new \PHPStan\ShouldNotHappenException(); + } + } + + if ($node->type === Node\Stmt\Use_::TYPE_CONSTANT) { + return $this->checkConstants($node->uses); + } + + if ($node->type === Node\Stmt\Use_::TYPE_FUNCTION) { + return $this->checkFunctions($node->uses); + } + + return $this->checkClasses($node->uses); + } + + /** + * @param \PhpParser\Node\Stmt\UseUse[] $uses + * @return RuleError[] + */ + private function checkConstants(array $uses): array + { + $errors = []; + foreach ($uses as $use) { + if ($this->broker->hasConstant($use->name, null)) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf('Used constant %s not found.', (string) $use->name))->line($use->name->getLine())->build(); + } + + return $errors; + } + + /** + * @param \PhpParser\Node\Stmt\UseUse[] $uses + * @return RuleError[] + */ + private function checkFunctions(array $uses): array + { + $errors = []; + foreach ($uses as $use) { + if (!$this->broker->hasFunction($use->name, null)) { + $errors[] = RuleErrorBuilder::message(sprintf('Used function %s not found.', (string) $use->name))->line($use->name->getLine())->build(); + } elseif ($this->checkFunctionNameCase) { + $functionReflection = $this->broker->getFunction($use->name, null); + $realName = $functionReflection->getName(); + $usedName = (string) $use->name; + if ( + strtolower($realName) === strtolower($usedName) + && $realName !== $usedName + ) { + $errors[] = RuleErrorBuilder::message(sprintf( + 'Function %s used with incorrect case: %s.', + $realName, + $usedName + ))->line($use->name->getLine())->build(); + } + } + } + + return $errors; + } + + /** + * @param \PhpParser\Node\Stmt\UseUse[] $uses + * @return RuleError[] + */ + private function checkClasses(array $uses): array + { + return $this->classCaseSensitivityCheck->checkClassNames( + array_map(static function (\PhpParser\Node\Stmt\UseUse $use): ClassNameNodePair { + return new ClassNameNodePair((string) $use->name, $use->name); + }, $uses) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Operators/InvalidBinaryOperationRule.php b/vendor/phpstan/phpstan/src/Rules/Operators/InvalidBinaryOperationRule.php new file mode 100644 index 00000000..d12b8408 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Operators/InvalidBinaryOperationRule.php @@ -0,0 +1,119 @@ +printer = $printer; + $this->ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return Node\Expr::class; + } + + /** + * @param \PhpParser\Node\Expr $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if ( + !$node instanceof Node\Expr\BinaryOp + && !$node instanceof Node\Expr\AssignOp + ) { + return []; + } + + if ($scope->getType($node) instanceof ErrorType) { + $leftName = '__PHPSTAN__LEFT__'; + $rightName = '__PHPSTAN__RIGHT__'; + $leftVariable = new Node\Expr\Variable($leftName); + $rightVariable = new Node\Expr\Variable($rightName); + if ($node instanceof Node\Expr\AssignOp) { + $newNode = clone $node; + $left = $node->var; + $right = $node->expr; + $newNode->var = $leftVariable; + $newNode->expr = $rightVariable; + } else { + $newNode = clone $node; + $left = $node->left; + $right = $node->right; + $newNode->left = $leftVariable; + $newNode->right = $rightVariable; + } + + if ($node instanceof Node\Expr\AssignOp\Concat || $node instanceof Node\Expr\BinaryOp\Concat) { + $callback = static function (Type $type): bool { + return !$type->toString() instanceof ErrorType; + }; + } else { + $callback = static function (Type $type): bool { + return !$type->toNumber() instanceof ErrorType; + }; + } + + $leftType = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $left, + '', + $callback + )->getType(); + if ($leftType instanceof ErrorType) { + return []; + } + + $rightType = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $right, + '', + $callback + )->getType(); + if ($rightType instanceof ErrorType) { + return []; + } + + $scope = $scope + ->assignVariable($leftName, $leftType, \PHPStan\TrinaryLogic::createYes()) + ->assignVariable($rightName, $rightType, \PHPStan\TrinaryLogic::createYes()); + + if (!$scope->getType($newNode) instanceof ErrorType) { + return []; + } + + return [ + sprintf( + 'Binary operation "%s" between %s and %s results in an error.', + substr(substr($this->printer->prettyPrintExpr($newNode), strlen($leftName) + 2), 0, -(strlen($rightName) + 2)), + $scope->getType($left)->describe(VerbosityLevel::value()), + $scope->getType($right)->describe(VerbosityLevel::value()) + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Operators/InvalidComparisonOperationRule.php b/vendor/phpstan/phpstan/src/Rules/Operators/InvalidComparisonOperationRule.php new file mode 100644 index 00000000..086e43f7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Operators/InvalidComparisonOperationRule.php @@ -0,0 +1,116 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + + public function getNodeType(): string + { + return Node\Expr\BinaryOp::class; + } + + /** + * @param Node $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ( + !$node instanceof Node\Expr\BinaryOp\Equal + && !$node instanceof Node\Expr\BinaryOp\NotEqual + && !$node instanceof Node\Expr\BinaryOp\Smaller + && !$node instanceof Node\Expr\BinaryOp\SmallerOrEqual + && !$node instanceof Node\Expr\BinaryOp\Greater + && !$node instanceof Node\Expr\BinaryOp\GreaterOrEqual + && !$node instanceof Node\Expr\BinaryOp\Spaceship + ) { + return []; + } + + $isNumericLeft = $this->isNumberType($scope, $node->left); + $isObjectLeft = $this->isObjectType($scope, $node->left); + $isNumericRight = $this->isNumberType($scope, $node->right); + $isObjectRight = $this->isObjectType($scope, $node->right); + + if (($isNumericLeft && $isObjectRight) || ($isObjectLeft && $isNumericRight)) { + return [ + sprintf( + 'Comparison operation "%s" between %s and %s results in an error.', + $node->getOperatorSigil(), + $scope->getType($node->left)->describe(VerbosityLevel::value()), + $scope->getType($node->right)->describe(VerbosityLevel::value()) + ), + ]; + } + + return []; + } + + private function isNumberType(Scope $scope, Node\Expr $expr): bool + { + $acceptedType = new UnionType([new IntegerType(), new FloatType()]); + $onlyNumber = static function (Type $type) use ($acceptedType): bool { + return $acceptedType->accepts($type, true)->yes(); + }; + + $type = $this->ruleLevelHelper->findTypeToCheck($scope, $expr, '', $onlyNumber)->getType(); + + if ( + $type instanceof ErrorType + || !$type->equals($scope->getType($expr)) + ) { + return false; + } + + return !$acceptedType->isSuperTypeOf($type)->no(); + } + + + private function isObjectType(Scope $scope, Node\Expr $expr): bool + { + $acceptedType = new ObjectWithoutClassType(); + + $type = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $expr, + '', + static function (Type $type) use ($acceptedType): bool { + return $acceptedType->isSuperTypeOf($type)->yes(); + } + )->getType(); + + if ($type instanceof ErrorType) { + return false; + } + + $isSuperType = $acceptedType->isSuperTypeOf($type); + if ($type instanceof \PHPStan\Type\BenevolentUnionType) { + return !$isSuperType->no(); + } + + return $isSuperType->yes(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Operators/InvalidIncDecOperationRule.php b/vendor/phpstan/phpstan/src/Rules/Operators/InvalidIncDecOperationRule.php new file mode 100644 index 00000000..bf41e4de --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Operators/InvalidIncDecOperationRule.php @@ -0,0 +1,77 @@ +checkThisOnly = $checkThisOnly; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr::class; + } + + /** + * @param \PhpParser\Node\Expr $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(\PhpParser\Node $node, \PHPStan\Analyser\Scope $scope): array + { + if ( + !$node instanceof \PhpParser\Node\Expr\PreInc + && !$node instanceof \PhpParser\Node\Expr\PostInc + && !$node instanceof \PhpParser\Node\Expr\PreDec + && !$node instanceof \PhpParser\Node\Expr\PostDec + ) { + return []; + } + + $operatorString = $node instanceof \PhpParser\Node\Expr\PreInc || $node instanceof \PhpParser\Node\Expr\PostInc ? '++' : '--'; + + if ( + !$node->var instanceof \PhpParser\Node\Expr\Variable + && !$node->var instanceof \PhpParser\Node\Expr\ArrayDimFetch + && !$node->var instanceof \PhpParser\Node\Expr\PropertyFetch + && !$node->var instanceof \PhpParser\Node\Expr\StaticPropertyFetch + ) { + return [ + sprintf( + 'Cannot use %s on a non-variable.', + $operatorString + ), + ]; + } + + if (!$this->checkThisOnly) { + $varType = $scope->getType($node->var); + if (!$varType->toString() instanceof ErrorType) { + return []; + } + if (!$varType->toNumber() instanceof ErrorType) { + return []; + } + + return [ + sprintf( + 'Cannot use %s on %s.', + $operatorString, + $varType->describe(VerbosityLevel::value()) + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Operators/InvalidUnaryOperationRule.php b/vendor/phpstan/phpstan/src/Rules/Operators/InvalidUnaryOperationRule.php new file mode 100644 index 00000000..09a5820b --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Operators/InvalidUnaryOperationRule.php @@ -0,0 +1,44 @@ +getType($node) instanceof ErrorType) { + return [ + sprintf( + 'Unary operation "%s" on %s results in an error.', + $node instanceof \PhpParser\Node\Expr\UnaryPlus ? '+' : '-', + $scope->getType($node->expr)->describe(VerbosityLevel::value()) + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/PhpDoc/IncompatiblePhpDocTypeRule.php b/vendor/phpstan/phpstan/src/Rules/PhpDoc/IncompatiblePhpDocTypeRule.php new file mode 100644 index 00000000..4de66058 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/PhpDoc/IncompatiblePhpDocTypeRule.php @@ -0,0 +1,155 @@ +fileTypeMapper = $fileTypeMapper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\FunctionLike::class; + } + + /** + * @param \PhpParser\Node\FunctionLike $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + $docComment = $node->getDocComment(); + if ($docComment === null) { + return []; + } + + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc( + $scope->getFile(), + $scope->isInClass() ? $scope->getClassReflection()->getName() : null, + $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, + $docComment->getText() + ); + $nativeParameterTypes = $this->getNativeParameterTypes($node, $scope); + $nativeReturnType = $this->getNativeReturnType($node, $scope); + + $errors = []; + + foreach ($resolvedPhpDoc->getParamTags() as $parameterName => $phpDocParamTag) { + $phpDocParamType = $phpDocParamTag->getType(); + if (!isset($nativeParameterTypes[$parameterName])) { + $errors[] = sprintf( + 'PHPDoc tag @param references unknown parameter: $%s', + $parameterName + ); + + } elseif ($phpDocParamType instanceof ErrorType || $phpDocParamType instanceof NeverType) { + $errors[] = sprintf( + 'PHPDoc tag @param for parameter $%s contains unresolvable type.', + $parameterName + ); + + } else { + $nativeParamType = $nativeParameterTypes[$parameterName]; + $isParamSuperType = $nativeParamType->isSuperTypeOf($phpDocParamType); + + if ( + $phpDocParamTag->isVariadic() + && $nativeParamType instanceof ArrayType + && $nativeParamType->getItemType() instanceof ArrayType + ) { + continue; + } + + if ($isParamSuperType->no()) { + $errors[] = sprintf( + 'PHPDoc tag @param for parameter $%s with type %s is incompatible with native type %s.', + $parameterName, + $phpDocParamType->describe(VerbosityLevel::typeOnly()), + $nativeParamType->describe(VerbosityLevel::typeOnly()) + ); + + } elseif ($isParamSuperType->maybe()) { + $errors[] = sprintf( + 'PHPDoc tag @param for parameter $%s with type %s is not subtype of native type %s.', + $parameterName, + $phpDocParamType->describe(VerbosityLevel::typeOnly()), + $nativeParamType->describe(VerbosityLevel::typeOnly()) + ); + } + } + } + + if ($resolvedPhpDoc->getReturnTag() !== null) { + $phpDocReturnType = $resolvedPhpDoc->getReturnTag()->getType(); + + if ($phpDocReturnType instanceof ErrorType || $phpDocReturnType instanceof NeverType) { + $errors[] = 'PHPDoc tag @return contains unresolvable type.'; + + } else { + $isReturnSuperType = $nativeReturnType->isSuperTypeOf($phpDocReturnType); + if ($isReturnSuperType->no()) { + $errors[] = sprintf( + 'PHPDoc tag @return with type %s is incompatible with native type %s.', + $phpDocReturnType->describe(VerbosityLevel::typeOnly()), + $nativeReturnType->describe(VerbosityLevel::typeOnly()) + ); + + } elseif ($isReturnSuperType->maybe()) { + $errors[] = sprintf( + 'PHPDoc tag @return with type %s is not subtype of native type %s.', + $phpDocReturnType->describe(VerbosityLevel::typeOnly()), + $nativeReturnType->describe(VerbosityLevel::typeOnly()) + ); + } + } + } + + return $errors; + } + + /** + * @param Node\FunctionLike $node + * @param Scope $scope + * @return Type[] + */ + private function getNativeParameterTypes(\PhpParser\Node\FunctionLike $node, Scope $scope): array + { + $nativeParameterTypes = []; + foreach ($node->getParams() as $parameter) { + $isNullable = $scope->isParameterValueNullable($parameter); + if (!$parameter->var instanceof Variable || !is_string($parameter->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $nativeParameterTypes[$parameter->var->name] = $scope->getFunctionType( + $parameter->type, + $isNullable, + $parameter->variadic + ); + } + + return $nativeParameterTypes; + } + + private function getNativeReturnType(\PhpParser\Node\FunctionLike $node, Scope $scope): Type + { + return $scope->getFunctionType($node->getReturnType(), false, false); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/PhpDoc/IncompatiblePropertyPhpDocTypeRule.php b/vendor/phpstan/phpstan/src/Rules/PhpDoc/IncompatiblePropertyPhpDocTypeRule.php new file mode 100644 index 00000000..c2e829bb --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/PhpDoc/IncompatiblePropertyPhpDocTypeRule.php @@ -0,0 +1,48 @@ +isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $propertyName = $node->name->toString(); + $propertyReflection = $scope->getClassReflection()->getNativeProperty($propertyName); + if ( + $propertyReflection->getType() instanceof ErrorType + || $propertyReflection->getType() instanceof NeverType + ) { + return [ + sprintf( + 'PHPDoc tag @var for property %s::$%s contains unresolvable type.', + $propertyReflection->getDeclaringClass()->getName(), + $propertyName + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/PhpDoc/InvalidPhpDocTagValueRule.php b/vendor/phpstan/phpstan/src/Rules/PhpDoc/InvalidPhpDocTagValueRule.php new file mode 100644 index 00000000..5d645827 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/PhpDoc/InvalidPhpDocTagValueRule.php @@ -0,0 +1,76 @@ +phpDocLexer = $phpDocLexer; + $this->phpDocParser = $phpDocParser; + } + + public function getNodeType(): string + { + return \PhpParser\Node::class; + } + + /** + * @param \PhpParser\Node $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ( + !$node instanceof Node\Stmt\ClassLike + && !$node instanceof Node\FunctionLike + && !$node instanceof Node\Stmt\Foreach_ + && !$node instanceof Node\Stmt\Property + && !$node instanceof Node\Expr\Assign + && !$node instanceof Node\Expr\AssignRef + ) { + return []; + } + + $docComment = $node->getDocComment(); + if ($docComment === null) { + return []; + } + + $phpDocString = $docComment->getText(); + $tokens = new TokenIterator($this->phpDocLexer->tokenize($phpDocString)); + $phpDocNode = $this->phpDocParser->parse($tokens); + + $errors = []; + foreach ($phpDocNode->getTags() as $phpDocTag) { + if (!($phpDocTag->value instanceof InvalidTagValueNode)) { + continue; + } + + $errors[] = sprintf( + 'PHPDoc tag %s has invalid value (%s): %s', + $phpDocTag->name, + $phpDocTag->value->value, + $phpDocTag->value->exception->getMessage() + ); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/PhpDoc/InvalidThrowsPhpDocValueRule.php b/vendor/phpstan/phpstan/src/Rules/PhpDoc/InvalidThrowsPhpDocValueRule.php new file mode 100644 index 00000000..0894cb73 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/PhpDoc/InvalidThrowsPhpDocValueRule.php @@ -0,0 +1,63 @@ +fileTypeMapper = $fileTypeMapper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\FunctionLike::class; + } + + /** + * @param \PhpParser\Node\FunctionLike $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + $docComment = $node->getDocComment(); + if ($docComment === null) { + return []; + } + + $resolvedPhpDoc = $this->fileTypeMapper->getResolvedPhpDoc( + $scope->getFile(), + $scope->isInClass() ? $scope->getClassReflection()->getName() : null, + $scope->isInTrait() ? $scope->getTraitReflection()->getName() : null, + $docComment->getText() + ); + + if ($resolvedPhpDoc->getThrowsTag() === null) { + return []; + } + + $phpDocThrowsType = $resolvedPhpDoc->getThrowsTag()->getType(); + + $isThrowsSuperType = (new ObjectType(\Throwable::class))->isSuperTypeOf($phpDocThrowsType); + if ($isThrowsSuperType->yes()) { + return []; + } + + return [sprintf( + 'PHPDoc tag @throws with type %s is not subtype of Throwable', + $phpDocThrowsType->describe(VerbosityLevel::typeOnly()) + )]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/AccessPropertiesRule.php b/vendor/phpstan/phpstan/src/Rules/Properties/AccessPropertiesRule.php new file mode 100644 index 00000000..eb304862 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/AccessPropertiesRule.php @@ -0,0 +1,137 @@ +broker = $broker; + $this->ruleLevelHelper = $ruleLevelHelper; + $this->reportMagicProperties = $reportMagicProperties; + } + + public function getNodeType(): string + { + return PropertyFetch::class; + } + + /** + * @param \PhpParser\Node\Expr\PropertyFetch $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode(\PhpParser\Node $node, Scope $scope): array + { + if (!$node->name instanceof \PhpParser\Node\Identifier) { + return []; + } + + $name = $node->name->name; + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->var, + sprintf('Access to property $%s on an unknown class %%s.', $name), + static function (Type $type) use ($name): bool { + return $type->canAccessProperties()->yes() && $type->hasProperty($name)->yes(); + } + ); + $type = $typeResult->getType(); + if ($type instanceof ErrorType) { + return $typeResult->getUnknownClassErrors(); + } + + if (!$type->canAccessProperties()->yes()) { + return [ + sprintf('Cannot access property $%s on %s.', $name, $type->describe(VerbosityLevel::typeOnly())), + ]; + } + + if (!$type->hasProperty($name)->yes()) { + if ($scope->isSpecified($node)) { + return []; + } + + $classNames = $typeResult->getReferencedClasses(); + if (!$this->reportMagicProperties) { + foreach ($classNames as $className) { + if (!$this->broker->hasClass($className)) { + continue; + } + + $classReflection = $this->broker->getClass($className); + if ( + $classReflection->hasNativeMethod('__get') + || $classReflection->hasNativeMethod('__set') + ) { + return []; + } + } + } + + if (count($classNames) === 1) { + $referencedClass = $typeResult->getReferencedClasses()[0]; + $propertyClassReflection = $this->broker->getClass($referencedClass); + $parentClassReflection = $propertyClassReflection->getParentClass(); + while ($parentClassReflection !== false) { + if ($parentClassReflection->hasProperty($name)) { + return [ + sprintf( + 'Access to private property $%s of parent class %s.', + $name, + $parentClassReflection->getDisplayName() + ), + ]; + } + + $parentClassReflection = $parentClassReflection->getParentClass(); + } + } + + return [ + sprintf( + 'Access to an undefined property %s::$%s.', + $type->describe(VerbosityLevel::typeOnly()), + $name + ), + ]; + } + + $propertyReflection = $type->getProperty($name, $scope); + if (!$scope->canAccessProperty($propertyReflection)) { + return [ + sprintf( + 'Access to %s property %s::$%s.', + $propertyReflection->isPrivate() ? 'private' : 'protected', + $type->describe(VerbosityLevel::typeOnly()), + $name + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/AccessStaticPropertiesRule.php b/vendor/phpstan/phpstan/src/Rules/Properties/AccessStaticPropertiesRule.php new file mode 100644 index 00000000..63ee7e8f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/AccessStaticPropertiesRule.php @@ -0,0 +1,199 @@ +broker = $broker; + $this->ruleLevelHelper = $ruleLevelHelper; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + } + + public function getNodeType(): string + { + return StaticPropertyFetch::class; + } + + /** + * @param \PhpParser\Node\Expr\StaticPropertyFetch $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$node->name instanceof Node\VarLikeIdentifier) { + return []; + } + + $name = $node->name->name; + $messages = []; + if ($node->class instanceof Name) { + $class = (string) $node->class; + $lowercasedClass = strtolower($class); + if (in_array($lowercasedClass, ['self', 'static'], true)) { + if (!$scope->isInClass()) { + return [ + sprintf( + 'Accessing %s::$%s outside of class scope.', + $class, + $name + ), + ]; + } + $className = $scope->getClassReflection()->getName(); + } elseif ($lowercasedClass === 'parent') { + if (!$scope->isInClass()) { + return [ + sprintf( + 'Accessing %s::$%s outside of class scope.', + $class, + $name + ), + ]; + } + if ($scope->getClassReflection()->getParentClass() === false) { + return [ + sprintf( + '%s::%s() accesses parent::$%s but %s does not extend any class.', + $scope->getClassReflection()->getDisplayName(), + $scope->getFunctionName(), + $name, + $scope->getClassReflection()->getDisplayName() + ), + ]; + } + + if ($scope->getFunctionName() === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $currentMethodReflection = $scope->getClassReflection()->getNativeMethod($scope->getFunctionName()); + if (!$currentMethodReflection->isStatic()) { + // calling parent::method() from instance method + return []; + } + + $className = $scope->getClassReflection()->getParentClass()->getName(); + } else { + if (!$this->broker->hasClass($class)) { + return [ + sprintf( + 'Access to static property $%s on an unknown class %s.', + $name, + $class + ), + ]; + } else { + $messages = $this->classCaseSensitivityCheck->checkClassNames([new ClassNameNodePair($class, $node->class)]); + } + $className = $this->broker->getClass($class)->getName(); + } + + $classType = new ObjectType($className); + } else { + $classTypeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->class, + sprintf('Access to static property $%s on an unknown class %%s.', $name), + static function (Type $type) use ($name): bool { + return $type->canAccessProperties()->yes() && $type->hasProperty($name)->yes(); + } + ); + $classType = $classTypeResult->getType(); + if ($classType instanceof ErrorType) { + return $classTypeResult->getUnknownClassErrors(); + } + } + + if ((new StringType())->isSuperTypeOf($classType)->yes()) { + return []; + } + + $typeForDescribe = $classType; + $classType = TypeCombinator::remove($classType, new StringType()); + + if (!$classType->canAccessProperties()->yes()) { + return array_merge($messages, [ + sprintf('Cannot access static property $%s on %s.', $name, $typeForDescribe->describe(VerbosityLevel::typeOnly())), + ]); + } + + if (!$classType->hasProperty($name)->yes()) { + if ($scope->isSpecified($node)) { + return $messages; + } + + return array_merge($messages, [ + sprintf( + 'Access to an undefined static property %s::$%s.', + $typeForDescribe->describe(VerbosityLevel::typeOnly()), + $name + ), + ]); + } + + $property = $classType->getProperty($name, $scope); + if (!$property->isStatic()) { + $hasPropertyTypes = TypeUtils::getHasPropertyTypes($classType); + foreach ($hasPropertyTypes as $hasPropertyType) { + if ($hasPropertyType->getPropertyName() === $name) { + return []; + } + } + + return array_merge($messages, [ + sprintf( + 'Static access to instance property %s::$%s.', + $property->getDeclaringClass()->getDisplayName(), + $name + ), + ]); + } + + if (!$scope->canAccessProperty($property)) { + return array_merge($messages, [ + sprintf( + 'Access to %s property $%s of class %s.', + $property->isPrivate() ? 'private' : 'protected', + $name, + $property->getDeclaringClass()->getDisplayName() + ), + ]); + } + + return $messages; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/DefaultValueTypesAssignedToPropertiesRule.php b/vendor/phpstan/phpstan/src/Rules/Properties/DefaultValueTypesAssignedToPropertiesRule.php new file mode 100644 index 00000000..76d709be --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/DefaultValueTypesAssignedToPropertiesRule.php @@ -0,0 +1,70 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return Property::class; + } + + /** + * @param \PhpParser\Node\Stmt\Property $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$scope->isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $classReflection = $scope->getClassReflection(); + + $errors = []; + foreach ($node->props as $property) { + if ($property->default === null) { + continue; + } + + if ($property->default instanceof Node\Expr\ConstFetch && (string) $property->default->name === 'null') { + continue; + } + + $propertyReflection = $classReflection->getNativeProperty($property->name->name); + $propertyType = $propertyReflection->getType(); + $defaultValueType = $scope->getType($property->default); + if ($this->ruleLevelHelper->accepts($propertyType, $defaultValueType, $scope->isDeclareStrictTypes())) { + continue; + } + + $errors[] = sprintf( + '%s %s::$%s (%s) does not accept default value of type %s.', + $node->isStatic() ? 'Static property' : 'Property', + $classReflection->getDisplayName(), + $property->name->name, + $propertyType->describe(VerbosityLevel::typeOnly()), + $defaultValueType->describe(VerbosityLevel::typeOnly()) + ); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/ExistingClassesInPropertiesRule.php b/vendor/phpstan/phpstan/src/Rules/Properties/ExistingClassesInPropertiesRule.php new file mode 100644 index 00000000..cdbcf9ff --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/ExistingClassesInPropertiesRule.php @@ -0,0 +1,90 @@ +broker = $broker; + $this->classCaseSensitivityCheck = $classCaseSensitivityCheck; + $this->checkClassCaseSensitivity = $checkClassCaseSensitivity; + } + + public function getNodeType(): string + { + return PropertyProperty::class; + } + + /** + * @param \PhpParser\Node\Stmt\PropertyProperty $node + * @param \PHPStan\Analyser\Scope $scope + * @return RuleError[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!$scope->isInClass()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $propertyReflection = $scope->getClassReflection()->getNativeProperty($node->name->name); + $propertyType = $propertyReflection->getType(); + + $errors = []; + foreach ($propertyType->getReferencedClasses() as $referencedClass) { + if ($this->broker->hasClass($referencedClass)) { + if ($this->broker->getClass($referencedClass)->isTrait()) { + $errors[] = RuleErrorBuilder::message(sprintf( + 'Property %s::$%s has invalid type %s.', + $propertyReflection->getDeclaringClass()->getDisplayName(), + $node->name->name, + $referencedClass + ))->build(); + } + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf( + 'Property %s::$%s has unknown class %s as its type.', + $propertyReflection->getDeclaringClass()->getDisplayName(), + $node->name->name, + $referencedClass + ))->build(); + } + + if ($this->checkClassCaseSensitivity) { + $errors = array_merge( + $errors, + $this->classCaseSensitivityCheck->checkClassNames(array_map(static function (string $class) use ($node): ClassNameNodePair { + return new ClassNameNodePair($class, $node); + }, $propertyType->getReferencedClasses())) + ); + } + + return $errors; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/PropertyDescriptor.php b/vendor/phpstan/phpstan/src/Rules/Properties/PropertyDescriptor.php new file mode 100644 index 00000000..7f526bb6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/PropertyDescriptor.php @@ -0,0 +1,26 @@ +name; + if ($propertyFetch instanceof \PhpParser\Node\Expr\PropertyFetch) { + return sprintf('Property %s::$%s', $property->getDeclaringClass()->getDisplayName(), $name->name); + } + + return sprintf('Static property %s::$%s', $property->getDeclaringClass()->getDisplayName(), $name->name); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/PropertyReflectionFinder.php b/vendor/phpstan/phpstan/src/Rules/Properties/PropertyReflectionFinder.php new file mode 100644 index 00000000..21567c50 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/PropertyReflectionFinder.php @@ -0,0 +1,49 @@ +name instanceof \PhpParser\Node\Identifier) { + return null; + } + $propertyHolderType = $scope->getType($propertyFetch->var); + return $this->findPropertyReflection($propertyHolderType, $propertyFetch->name->name, $scope); + } + + if (!$propertyFetch->name instanceof \PhpParser\Node\Identifier) { + return null; + } + + if ($propertyFetch->class instanceof \PhpParser\Node\Name) { + $propertyHolderType = new ObjectType($scope->resolveName($propertyFetch->class)); + } else { + $propertyHolderType = $scope->getType($propertyFetch->class); + } + + return $this->findPropertyReflection($propertyHolderType, $propertyFetch->name->name, $scope); + } + + private function findPropertyReflection(Type $propertyHolderType, string $propertyName, Scope $scope): ?\PHPStan\Reflection\PropertyReflection + { + if (!$propertyHolderType->hasProperty($propertyName)->yes()) { + return null; + } + + return $propertyHolderType->getProperty($propertyName, $scope); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/ReadingWriteOnlyPropertiesRule.php b/vendor/phpstan/phpstan/src/Rules/Properties/ReadingWriteOnlyPropertiesRule.php new file mode 100644 index 00000000..0c2307b7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/ReadingWriteOnlyPropertiesRule.php @@ -0,0 +1,90 @@ +propertyDescriptor = $propertyDescriptor; + $this->propertyReflectionFinder = $propertyReflectionFinder; + $this->ruleLevelHelper = $ruleLevelHelper; + $this->checkThisOnly = $checkThisOnly; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr::class; + } + + /** + * @param \PhpParser\Node\Expr $node + * @param Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ( + !($node instanceof Node\Expr\PropertyFetch) + && !($node instanceof Node\Expr\StaticPropertyFetch) + ) { + return []; + } + + if ( + $node instanceof Node\Expr\PropertyFetch + && $this->checkThisOnly + && !$this->ruleLevelHelper->isThis($node->var) + ) { + return []; + } + + if ($scope->isInExpressionAssign($node)) { + return []; + } + + $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($node, $scope); + if ($propertyReflection === null) { + return []; + } + if (!$scope->canAccessProperty($propertyReflection)) { + return []; + } + + if (!$propertyReflection->isReadable()) { + $propertyDescription = $this->propertyDescriptor->describeProperty($propertyReflection, $node); + + return [ + sprintf( + '%s is not readable.', + $propertyDescription + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/TypesAssignedToPropertiesRule.php b/vendor/phpstan/phpstan/src/Rules/Properties/TypesAssignedToPropertiesRule.php new file mode 100644 index 00000000..c67692ed --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/TypesAssignedToPropertiesRule.php @@ -0,0 +1,89 @@ +ruleLevelHelper = $ruleLevelHelper; + $this->propertyDescriptor = $propertyDescriptor; + $this->propertyReflectionFinder = $propertyReflectionFinder; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr::class; + } + + /** + * @param \PhpParser\Node\Expr $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ( + !$node instanceof Node\Expr\Assign + && !$node instanceof Node\Expr\AssignOp + ) { + return []; + } + + if ( + !($node->var instanceof Node\Expr\PropertyFetch) + && !($node->var instanceof Node\Expr\StaticPropertyFetch) + ) { + return []; + } + + /** @var \PhpParser\Node\Expr\PropertyFetch|\PhpParser\Node\Expr\StaticPropertyFetch $propertyFetch */ + $propertyFetch = $node->var; + $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($propertyFetch, $scope); + if ($propertyReflection === null) { + return []; + } + + $propertyType = $propertyReflection->getType(); + + if ($node instanceof Node\Expr\Assign) { + $assignedValueType = $scope->getType($node->expr); + } else { + $assignedValueType = $scope->getType($node); + } + if (!$this->ruleLevelHelper->accepts($propertyType, $assignedValueType, $scope->isDeclareStrictTypes())) { + $propertyDescription = $this->propertyDescriptor->describeProperty($propertyReflection, $propertyFetch); + + return [ + sprintf( + '%s (%s) does not accept %s.', + $propertyDescription, + $propertyType->describe(VerbosityLevel::typeOnly()), + $assignedValueType->describe(VerbosityLevel::typeOnly()) + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Properties/WritingToReadOnlyPropertiesRule.php b/vendor/phpstan/phpstan/src/Rules/Properties/WritingToReadOnlyPropertiesRule.php new file mode 100644 index 00000000..0feea7e0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Properties/WritingToReadOnlyPropertiesRule.php @@ -0,0 +1,96 @@ +ruleLevelHelper = $ruleLevelHelper; + $this->propertyDescriptor = $propertyDescriptor; + $this->propertyReflectionFinder = $propertyReflectionFinder; + $this->checkThisOnly = $checkThisOnly; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Expr::class; + } + + /** + * @param \PhpParser\Node\Expr $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ( + !$node instanceof Node\Expr\Assign + && !$node instanceof Node\Expr\AssignOp + ) { + return []; + } + + if ( + !($node->var instanceof Node\Expr\PropertyFetch) + && !($node->var instanceof Node\Expr\StaticPropertyFetch) + ) { + return []; + } + + if ( + $node->var instanceof Node\Expr\PropertyFetch + && $this->checkThisOnly + && !$this->ruleLevelHelper->isThis($node->var->var) + ) { + return []; + } + + /** @var \PhpParser\Node\Expr\PropertyFetch|\PhpParser\Node\Expr\StaticPropertyFetch $propertyFetch */ + $propertyFetch = $node->var; + $propertyReflection = $this->propertyReflectionFinder->findPropertyReflectionFromNode($propertyFetch, $scope); + if ($propertyReflection === null) { + return []; + } + + if (!$scope->canAccessProperty($propertyReflection)) { + return []; + } + + if (!$propertyReflection->isWritable()) { + $propertyDescription = $this->propertyDescriptor->describeProperty($propertyReflection, $propertyFetch); + + return [ + sprintf( + '%s is not writable.', + $propertyDescription + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Regexp/RegularExpressionPatternRule.php b/vendor/phpstan/phpstan/src/Rules/Regexp/RegularExpressionPatternRule.php new file mode 100644 index 00000000..d9451b6e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Regexp/RegularExpressionPatternRule.php @@ -0,0 +1,126 @@ +extractPatterns($node, $scope); + + $errors = []; + foreach ($patterns as $pattern) { + $errorMessage = $this->validatePattern($pattern); + if ($errorMessage === null) { + continue; + } + + $errors[] = sprintf('Regex pattern is invalid: %s', $errorMessage); + } + + return $errors; + } + + /** + * @param FuncCall $functionCall + * @param Scope $scope + * @return string[] + */ + private function extractPatterns(FuncCall $functionCall, Scope $scope): array + { + if (!$functionCall->name instanceof Node\Name) { + return []; + } + $functionName = strtolower((string) $functionCall->name); + if (!\Nette\Utils\Strings::startsWith($functionName, 'preg_')) { + return []; + } + + if (!isset($functionCall->args[0])) { + return []; + } + $patternNode = $functionCall->args[0]->value; + $patternType = $scope->getType($patternNode); + + $patternStrings = []; + + foreach (TypeUtils::getConstantStrings($patternType) as $constantStringType) { + if ( + !in_array($functionName, [ + 'preg_match', + 'preg_match_all', + 'preg_split', + 'preg_grep', + 'preg_replace', + 'preg_replace_callback', + 'preg_filter', + ], true) + ) { + continue; + } + + $patternStrings[] = $constantStringType->getValue(); + } + + foreach (TypeUtils::getConstantArrays($patternType) as $constantArrayType) { + if ( + in_array($functionName, [ + 'preg_replace', + 'preg_replace_callback', + 'preg_filter', + ], true) + ) { + foreach ($constantArrayType->getValueTypes() as $arrayKeyType) { + if (!$arrayKeyType instanceof ConstantStringType) { + continue; + } + + $patternStrings[] = $arrayKeyType->getValue(); + } + } + + if ($functionName !== 'preg_replace_callback_array') { + continue; + } + + foreach ($constantArrayType->getKeyTypes() as $arrayKeyType) { + if (!$arrayKeyType instanceof ConstantStringType) { + continue; + } + + $patternStrings[] = $arrayKeyType->getValue(); + } + } + + return $patternStrings; + } + + private function validatePattern(string $pattern): ?string + { + try { + \Nette\Utils\Strings::match('', $pattern); + } catch (\Nette\Utils\RegexpException $e) { + return $e->getMessage(); + } + + return null; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Registry.php b/vendor/phpstan/phpstan/src/Rules/Registry.php new file mode 100644 index 00000000..cf1c2906 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Registry.php @@ -0,0 +1,46 @@ +rules[$rule->getNodeType()][] = $rule; + } + } + + /** + * @param string $nodeType + * @return \PHPStan\Rules\Rule[] + */ + public function getRules(string $nodeType): array + { + if (!isset($this->cache[$nodeType])) { + $parentNodeTypes = [$nodeType] + class_parents($nodeType) + class_implements($nodeType); + + $rules = []; + foreach ($parentNodeTypes as $parentNodeType) { + foreach ($this->rules[$parentNodeType] ?? [] as $rule) { + $rules[] = $rule; + } + } + + $this->cache[$nodeType] = $rules; + } + + return $this->cache[$nodeType]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/RegistryFactory.php b/vendor/phpstan/phpstan/src/Rules/RegistryFactory.php new file mode 100644 index 00000000..1b556ae3 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/RegistryFactory.php @@ -0,0 +1,31 @@ +container = $container; + } + + public function create(): Registry + { + $tagToService = function (array $tags) { + return array_map(function (string $serviceName) { + return $this->container->getService($serviceName); + }, array_keys($tags)); + }; + + return new Registry( + $tagToService($this->container->findByTag(self::RULE_TAG)) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Rule.php b/vendor/phpstan/phpstan/src/Rules/Rule.php new file mode 100644 index 00000000..db2c668a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Rule.php @@ -0,0 +1,23 @@ +message = $message; + + return $self; + } + + public function line(int $line): self + { + $this->line = $line; + + return $this; + } + + public function file(string $file): self + { + $this->file = $file; + + return $this; + } + + public function build(): RuleError + { + if ($this->line !== null && $this->file !== null) { + return new RuleErrorWithMessageAndLineAndFile($this->message, $this->line, $this->file); + } + if ($this->line !== null && $this->file === null) { + return new RuleErrorWithMessageAndLine($this->message, $this->line); + } + if ($this->line === null && $this->file !== null) { + return new RuleErrorWithMessageAndFile($this->message, $this->file); + } + + return new RuleErrorWithMessage($this->message); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessage.php b/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessage.php new file mode 100644 index 00000000..822a68af --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessage.php @@ -0,0 +1,23 @@ +message = $message; + } + + public function getMessage(): string + { + return $this->message; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndFile.php b/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndFile.php new file mode 100644 index 00000000..68032abe --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndFile.php @@ -0,0 +1,32 @@ +message = $message; + $this->file = $file; + } + + public function getMessage(): string + { + return $this->message; + } + + public function getFile(): string + { + return $this->file; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndLine.php b/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndLine.php new file mode 100644 index 00000000..0431445c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndLine.php @@ -0,0 +1,32 @@ +message = $message; + $this->line = $line; + } + + public function getMessage(): string + { + return $this->message; + } + + public function getLine(): int + { + return $this->line; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndLineAndFile.php b/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndLineAndFile.php new file mode 100644 index 00000000..5edb9aa9 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/RuleErrors/RuleErrorWithMessageAndLineAndFile.php @@ -0,0 +1,42 @@ +message = $message; + $this->line = $line; + $this->file = $file; + } + + public function getMessage(): string + { + return $this->message; + } + + public function getLine(): int + { + return $this->line; + } + + public function getFile(): string + { + return $this->file; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/RuleLevelHelper.php b/vendor/phpstan/phpstan/src/Rules/RuleLevelHelper.php new file mode 100644 index 00000000..f5e62ec0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/RuleLevelHelper.php @@ -0,0 +1,199 @@ +broker = $broker; + $this->checkNullables = $checkNullables; + $this->checkThisOnly = $checkThisOnly; + $this->checkUnionTypes = $checkUnionTypes; + } + + public function isThis(Expr $expression): bool + { + return $expression instanceof Expr\Variable && $expression->name === 'this'; + } + + public function accepts(Type $acceptingType, Type $acceptedType, bool $strictTypes): bool + { + if ( + !$this->checkNullables + && !$acceptingType instanceof NullType + && !$acceptedType instanceof NullType + && !$acceptedType instanceof BenevolentUnionType + ) { + $acceptedType = TypeCombinator::removeNull($acceptedType); + } + + $acceptedArrays = TypeUtils::getArrays($acceptedType); + if ($acceptingType instanceof ArrayType && count($acceptedArrays) > 0) { + foreach ($acceptedArrays as $acceptedArray) { + if ($acceptedArray instanceof ConstantArrayType) { + foreach ($acceptedArray->getKeyTypes() as $i => $keyType) { + $valueType = $acceptedArray->getValueTypes()[$i]; + if ( + !self::accepts( + $acceptingType->getKeyType(), + $keyType, + $strictTypes + ) || !self::accepts( + $acceptingType->getItemType(), + $valueType, + $strictTypes + ) + ) { + return false; + } + } + } else { + if ( + !self::accepts( + $acceptingType->getKeyType(), + $acceptedArray->getKeyType(), + $strictTypes + ) || !self::accepts( + $acceptingType->getItemType(), + $acceptedArray->getItemType(), + $strictTypes + ) + ) { + return false; + } + } + } + + return true; + } + + if ($acceptingType instanceof UnionType && !$acceptedType instanceof CompoundType) { + foreach ($acceptingType->getTypes() as $innerType) { + if (self::accepts($innerType, $acceptedType, $strictTypes)) { + return true; + } + } + + return false; + } + + if ($acceptedType instanceof ArrayType && $acceptingType instanceof ArrayType) { + return self::accepts( + $acceptingType->getKeyType(), + $acceptedType->getKeyType(), + $strictTypes + ) && self::accepts( + $acceptingType->getItemType(), + $acceptedType->getItemType(), + $strictTypes + ); + } + + $accepts = $acceptingType->accepts($acceptedType, $strictTypes); + + return $this->checkUnionTypes ? $accepts->yes() : !$accepts->no(); + } + + /** + * @param Scope $scope + * @param Expr $var + * @param string $unknownClassErrorPattern + * @param callable(Type $type): bool $unionTypeCriteriaCallback + * @return FoundTypeResult + */ + public function findTypeToCheck( + Scope $scope, + Expr $var, + string $unknownClassErrorPattern, + callable $unionTypeCriteriaCallback + ): FoundTypeResult + { + if ($this->checkThisOnly && !$this->isThis($var)) { + return new FoundTypeResult(new ErrorType(), [], []); + } + $type = $scope->getType($var); + if (!$this->checkNullables && !$type instanceof NullType) { + $type = \PHPStan\Type\TypeCombinator::removeNull($type); + } + if ($type instanceof MixedType || $type instanceof NeverType) { + return new FoundTypeResult(new ErrorType(), [], []); + } + if ($type instanceof StaticType) { + $type = $type->resolveStatic($type->getBaseClass()); + } + + $errors = []; + $directClassNames = TypeUtils::getDirectClassNames($type); + foreach ($directClassNames as $referencedClass) { + if ($this->broker->hasClass($referencedClass)) { + continue; + } + + $errors[] = RuleErrorBuilder::message(sprintf($unknownClassErrorPattern, $referencedClass))->line($var->getLine())->build(); + } + + if (count($errors) > 0) { + return new FoundTypeResult(new ErrorType(), [], $errors); + } + + if (!$this->checkUnionTypes) { + if ($type instanceof ObjectWithoutClassType) { + return new FoundTypeResult(new ErrorType(), [], []); + } + if ($type instanceof UnionType) { + $newTypes = []; + foreach ($type->getTypes() as $innerType) { + if (!$unionTypeCriteriaCallback($innerType)) { + continue; + } + + $newTypes[] = $innerType; + } + + if (count($newTypes) > 0) { + return new FoundTypeResult(TypeCombinator::union(...$newTypes), $directClassNames, []); + } + } + } + + return new FoundTypeResult($type, $directClassNames, []); + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/UnusedFunctionParametersCheck.php b/vendor/phpstan/phpstan/src/Rules/UnusedFunctionParametersCheck.php new file mode 100644 index 00000000..5154500a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/UnusedFunctionParametersCheck.php @@ -0,0 +1,87 @@ +getUsedVariables($scope, $statements) as $variableName) { + if (!isset($unusedParameters[$variableName])) { + continue; + } + + unset($unusedParameters[$variableName]); + } + $errors = []; + foreach (array_keys($unusedParameters) as $name) { + $errors[] = sprintf($unusedParameterMessage, $name); + } + + return $errors; + } + + /** + * @param \PHPStan\Analyser\Scope $scope + * @param \PhpParser\Node[]|\PhpParser\Node|scalar $node + * @return string[] + */ + private function getUsedVariables(Scope $scope, $node): array + { + $variableNames = []; + if ($node instanceof Node) { + if ($node instanceof Node\Expr\Variable && is_string($node->name) && $node->name !== 'this') { + return [$node->name]; + } + if ($node instanceof Node\Expr\ClosureUse && is_string($node->var->name)) { + return [$node->var->name]; + } + if ( + $node instanceof Node\Expr\FuncCall + && $node->name instanceof Node\Name + && (string) $node->name === 'compact' + ) { + foreach ($node->args as $arg) { + $argType = $scope->getType($arg->value); + if (!($argType instanceof ConstantStringType)) { + continue; + } + + $variableNames[] = $argType->getValue(); + } + } + foreach ($node->getSubNodeNames() as $subNodeName) { + if ($node instanceof Node\Expr\Closure && $subNodeName !== 'uses') { + continue; + } + $subNode = $node->{$subNodeName}; + $variableNames = array_merge($variableNames, $this->getUsedVariables($scope, $subNode)); + } + } elseif (is_array($node)) { + foreach ($node as $subNode) { + $variableNames = array_merge($variableNames, $this->getUsedVariables($scope, $subNode)); + } + } + + return $variableNames; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Variables/DefinedVariableInAnonymousFunctionUseRule.php b/vendor/phpstan/phpstan/src/Rules/Variables/DefinedVariableInAnonymousFunctionUseRule.php new file mode 100644 index 00000000..cacd4f68 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Variables/DefinedVariableInAnonymousFunctionUseRule.php @@ -0,0 +1,54 @@ +checkMaybeUndefinedVariables = $checkMaybeUndefinedVariables; + } + + public function getNodeType(): string + { + return ClosureUse::class; + } + + /** + * @param \PhpParser\Node\Expr\ClosureUse $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if ($node->byRef || !is_string($node->var->name)) { + return []; + } + + if ($scope->hasVariableType($node->var->name)->no()) { + return [ + sprintf('Undefined variable: $%s', $node->var->name), + ]; + } elseif ( + $this->checkMaybeUndefinedVariables + && !$scope->hasVariableType($node->var->name)->yes() + ) { + return [ + sprintf('Variable $%s might not be defined.', $node->var->name), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Variables/DefinedVariableRule.php b/vendor/phpstan/phpstan/src/Rules/Variables/DefinedVariableRule.php new file mode 100644 index 00000000..25932a2d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Variables/DefinedVariableRule.php @@ -0,0 +1,73 @@ +cliArgumentsVariablesRegistered = $cliArgumentsVariablesRegistered; + $this->checkMaybeUndefinedVariables = $checkMaybeUndefinedVariables; + } + + public function getNodeType(): string + { + return Variable::class; + } + + /** + * @param \PhpParser\Node\Expr\Variable $node + * @param \PHPStan\Analyser\Scope $scope + * @return string[] + */ + public function processNode(Node $node, Scope $scope): array + { + if (!is_string($node->name)) { + return []; + } + + if ($this->cliArgumentsVariablesRegistered && in_array($node->name, [ + 'argc', + 'argv', + ], true)) { + $isInMain = !$scope->isInClass() && !$scope->isInAnonymousFunction() && $scope->getFunction() === null; + if ($isInMain) { + return []; + } + } + + if ($scope->isInExpressionAssign($node)) { + return []; + } + + if ($scope->hasVariableType($node->name)->no()) { + return [ + sprintf('Undefined variable: $%s', $node->name), + ]; + } elseif ( + $this->checkMaybeUndefinedVariables + && !$scope->hasVariableType($node->name)->yes() + ) { + return [ + sprintf('Variable $%s might not be defined.', $node->name), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Variables/ThisVariableRule.php b/vendor/phpstan/phpstan/src/Rules/Variables/ThisVariableRule.php new file mode 100644 index 00000000..c68ff4af --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Variables/ThisVariableRule.php @@ -0,0 +1,57 @@ +name) || $node->name !== 'this') { + return []; + } + + if ($scope->isInClosureBind()) { + return []; + } + + if (!$scope->isInClass()) { + return [ + 'Using $this outside a class.', + ]; + } + + $function = $scope->getFunction(); + if (!$function instanceof MethodReflection) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ($function->isStatic()) { + return [ + sprintf( + 'Using $this in static method %s::%s().', + $scope->getClassReflection()->getDisplayName(), + $function->getName() + ), + ]; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Variables/ThrowTypeRule.php b/vendor/phpstan/phpstan/src/Rules/Variables/ThrowTypeRule.php new file mode 100644 index 00000000..65dbe25a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Variables/ThrowTypeRule.php @@ -0,0 +1,63 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return \PhpParser\Node\Stmt\Throw_::class; + } + + /** + * @param \PhpParser\Node\Stmt\Throw_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode(Node $node, Scope $scope): array + { + $throwableType = new ObjectType(\Throwable::class); + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->expr, + 'Throwing object of an unknown class %s.', + static function (Type $type) use ($throwableType): bool { + return $throwableType->isSuperTypeOf($type)->yes(); + } + ); + + $foundType = $typeResult->getType(); + if ($foundType instanceof ErrorType) { + return $typeResult->getUnknownClassErrors(); + } + + $isSuperType = $throwableType->isSuperTypeOf($foundType); + if ($isSuperType->yes()) { + return []; + } + + return [ + sprintf('Invalid type %s to throw.', $foundType->describe(VerbosityLevel::typeOnly())), + ]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Variables/VariableCertaintyInIssetRule.php b/vendor/phpstan/phpstan/src/Rules/Variables/VariableCertaintyInIssetRule.php new file mode 100644 index 00000000..306719d3 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Variables/VariableCertaintyInIssetRule.php @@ -0,0 +1,66 @@ +vars as $var) { + $isSubNode = false; + while ( + $var instanceof Node\Expr\ArrayDimFetch + || $var instanceof Node\Expr\PropertyFetch + || ( + $var instanceof Node\Expr\StaticPropertyFetch + && $var->class instanceof Node\Expr + ) + ) { + if ($var instanceof Node\Expr\StaticPropertyFetch) { + $var = $var->class; + } else { + $var = $var->var; + } + $isSubNode = true; + } + + if (!$var instanceof Node\Expr\Variable || !is_string($var->name)) { + continue; + } + + $certainty = $scope->hasVariableType($var->name); + if ($certainty->no()) { + if ( + $scope->getFunction() !== null + || $scope->isInAnonymousFunction() + ) { + $messages[] = sprintf('Variable $%s in isset() is never defined.', $var->name); + } + } elseif ($certainty->yes() && !$isSubNode) { + $variableType = $scope->getVariableType($var->name); + if ($variableType->isSuperTypeOf(new NullType())->no()) { + $messages[] = sprintf('Variable $%s in isset() always exists and is not nullable.', $var->name); + } + } + } + + return $messages; + } + +} diff --git a/vendor/phpstan/phpstan/src/Rules/Variables/VariableCloningRule.php b/vendor/phpstan/phpstan/src/Rules/Variables/VariableCloningRule.php new file mode 100644 index 00000000..0da080b0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Rules/Variables/VariableCloningRule.php @@ -0,0 +1,68 @@ +ruleLevelHelper = $ruleLevelHelper; + } + + public function getNodeType(): string + { + return Clone_::class; + } + + /** + * @param \PhpParser\Node\Expr\Clone_ $node + * @param \PHPStan\Analyser\Scope $scope + * @return (string|\PHPStan\Rules\RuleError)[] + */ + public function processNode(Node $node, Scope $scope): array + { + $typeResult = $this->ruleLevelHelper->findTypeToCheck( + $scope, + $node->expr, + 'Cloning object of an unknown class %s.', + static function (Type $type): bool { + return $type->isCloneable()->yes(); + } + ); + $type = $typeResult->getType(); + if ($type instanceof ErrorType) { + return $typeResult->getUnknownClassErrors(); + } + if ($type->isCloneable()->yes()) { + return []; + } + + if ($node->expr instanceof Variable && is_string($node->expr->name)) { + return [ + sprintf( + 'Cannot clone non-object variable $%s of type %s.', + $node->expr->name, + $type->describe(VerbosityLevel::typeOnly()) + ), + ]; + } + + return [ + sprintf('Cannot clone %s.', $type->describe(VerbosityLevel::typeOnly())), + ]; + } + +} diff --git a/vendor/phpstan/phpstan/src/ShouldNotHappenException.php b/vendor/phpstan/phpstan/src/ShouldNotHappenException.php new file mode 100644 index 00000000..99575886 --- /dev/null +++ b/vendor/phpstan/phpstan/src/ShouldNotHappenException.php @@ -0,0 +1,13 @@ +getDataPath(), $topic); + $command = escapeshellcmd($this->getPhpStanExecutablePath()); + $configPath = $this->getPhpStanConfigPath(); + $fileHelper = new FileHelper(__DIR__ . '/../..'); + + $previousMessages = []; + + $exceptions = []; + + foreach (range(0, 7) as $level) { + unset($outputLines); + exec(sprintf('php %s analyse --no-progress --error-format=prettyJson --level=%d %s --autoload-file %s %s', $command, $level, $configPath !== null ? '--configuration ' . escapeshellarg($configPath) : '', escapeshellarg($file), escapeshellarg($file)), $outputLines); + + $output = implode("\n", $outputLines); + + try { + $actualJson = \Nette\Utils\Json::decode($output, \Nette\Utils\Json::FORCE_ARRAY); + } catch (\Nette\Utils\JsonException $e) { + throw new \Nette\Utils\JsonException(sprintf('Cannot decode: %s', $output)); + } + if (count($actualJson['files']) > 0) { + $messagesBeforeDiffing = $actualJson['files'][$fileHelper->normalizePath($file)]['messages']; + } else { + $messagesBeforeDiffing = []; + } + + $messages = []; + foreach ($messagesBeforeDiffing as $message) { + foreach ($previousMessages as $lastMessage) { + if ( + $message['message'] === $lastMessage['message'] + && $message['line'] === $lastMessage['line'] + ) { + continue 2; + } + } + + $messages[] = $message; + } + + $missingMessages = []; + foreach ($previousMessages as $previousMessage) { + foreach ($messagesBeforeDiffing as $message) { + if ( + $previousMessage['message'] === $message['message'] + && $previousMessage['line'] === $message['line'] + ) { + continue 2; + } + } + + $missingMessages[] = $previousMessage; + } + + $previousMessages = array_merge($previousMessages, $messages); + $expectedJsonFile = sprintf('%s/%s-%d%s.json', $this->getDataPath(), $topic, $level, $this->getResultSuffix()); + + $exception = $this->compareFiles($expectedJsonFile, $messages); + if ($exception !== null) { + $exceptions[] = $exception; + } + + $expectedJsonMissingFile = sprintf('%s/%s-%d-missing%s.json', $this->getDataPath(), $topic, $level, $this->getResultSuffix()); + $exception = $this->compareFiles($expectedJsonMissingFile, $missingMessages); + if ($exception === null) { + continue; + } + + $exceptions[] = $exception; + } + + if (count($exceptions) > 0) { + throw $exceptions[0]; + } + } + + private function compareFiles(string $expectedJsonFile, array $expectedMessages): ?\PHPUnit\Framework\AssertionFailedError + { + if (count($expectedMessages) === 0) { + try { + $this->assertFileNotExists($expectedJsonFile); + return null; + } catch (\PHPUnit\Framework\AssertionFailedError $e) { + unlink($expectedJsonFile); + return $e; + } + } + + $actualOutput = \Nette\Utils\Json::encode($expectedMessages, \Nette\Utils\Json::PRETTY); + + try { + $this->assertJsonStringEqualsJsonFile( + $expectedJsonFile, + $actualOutput + ); + } catch (\PHPUnit\Framework\AssertionFailedError $e) { + file_put_contents($expectedJsonFile, $actualOutput); + return $e; + } + + return null; + } + +} diff --git a/vendor/phpstan/phpstan/src/Testing/RuleTestCase.php b/vendor/phpstan/phpstan/src/Testing/RuleTestCase.php new file mode 100644 index 00000000..fb263d41 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Testing/RuleTestCase.php @@ -0,0 +1,153 @@ +createTypeSpecifier( + new \PhpParser\PrettyPrinter\Standard(), + $this->createBroker(), + $this->getMethodTypeSpecifyingExtensions(), + $this->getStaticMethodTypeSpecifyingExtensions() + ); + } + + private function getAnalyser(): Analyser + { + if ($this->analyser === null) { + $registry = new Registry([ + $this->getRule(), + ]); + + $broker = $this->createBroker(); + $printer = new \PhpParser\PrettyPrinter\Standard(); + $fileHelper = $this->getFileHelper(); + $typeSpecifier = $this->createTypeSpecifier( + $printer, + $broker, + $this->getMethodTypeSpecifyingExtensions(), + $this->getStaticMethodTypeSpecifyingExtensions() + ); + $currentWorkingDirectory = $this->getCurrentWorkingDirectory(); + $this->analyser = new Analyser( + $this->createScopeFactory($broker, $typeSpecifier), + $this->getParser(), + $registry, + new NodeScopeResolver( + $broker, + $this->getParser(), + new FileTypeMapper($this->getParser(), self::getContainer()->getByType(PhpDocStringResolver::class), $this->createMock(Cache::class), new AnonymousClassNameHelper(new FileHelper($currentWorkingDirectory), new RelativePathHelper($currentWorkingDirectory, DIRECTORY_SEPARATOR, [])), new \PHPStan\PhpDoc\TypeNodeResolver($this->getTypeNodeResolverExtensions())), + $fileHelper, + $typeSpecifier, + $this->shouldPolluteScopeWithLoopInitialAssignments(), + $this->shouldPolluteCatchScopeWithTryAssignments(), + $this->shouldPolluteScopeWithAlwaysIterableForeach(), + [] + ), + $fileHelper, + [], + true, + 50 + ); + } + + return $this->analyser; + } + + /** + * @return \PHPStan\Type\MethodTypeSpecifyingExtension[] + */ + protected function getMethodTypeSpecifyingExtensions(): array + { + return []; + } + + /** + * @return \PHPStan\Type\StaticMethodTypeSpecifyingExtension[] + */ + protected function getStaticMethodTypeSpecifyingExtensions(): array + { + return []; + } + + /** + * @return \PHPStan\PhpDoc\TypeNodeResolverExtension[] + */ + protected function getTypeNodeResolverExtensions(): array + { + return []; + } + + /** + * @param string[] $files + * @param mixed[] $expectedErrors + */ + public function analyse(array $files, array $expectedErrors): void + { + $files = array_map([$this->getFileHelper(), 'normalizePath'], $files); + $actualErrors = $this->getAnalyser()->analyse($files, false); + + $strictlyTypedSprintf = static function (int $line, string $message): string { + return sprintf('%02d: %s', $line, $message); + }; + + $expectedErrors = array_map( + static function (array $error) use ($strictlyTypedSprintf): string { + if (!isset($error[0])) { + throw new \InvalidArgumentException('Missing expected error message.'); + } + if (!isset($error[1])) { + throw new \InvalidArgumentException('Missing expected file line.'); + } + return $strictlyTypedSprintf($error[1], $error[0]); + }, + $expectedErrors + ); + + $actualErrors = array_map( + static function (Error $error): string { + return sprintf('%02d: %s', $error->getLine(), $error->getMessage()); + }, + $actualErrors + ); + + $this->assertSame(implode("\n", $expectedErrors), implode("\n", $actualErrors)); + } + + protected function shouldPolluteScopeWithLoopInitialAssignments(): bool + { + return false; + } + + protected function shouldPolluteCatchScopeWithTryAssignments(): bool + { + return false; + } + + protected function shouldPolluteScopeWithAlwaysIterableForeach(): bool + { + return true; + } + +} diff --git a/vendor/phpstan/phpstan/src/Testing/TestCase.php b/vendor/phpstan/phpstan/src/Testing/TestCase.php new file mode 100644 index 00000000..f40bba3c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Testing/TestCase.php @@ -0,0 +1,351 @@ +create($rootDir . '/tmp', [ + $containerFactory->getConfigDirectory() . '/config.level7.neon', + ], []); + } + + return self::$container; + } + + public function getParser(): \PHPStan\Parser\Parser + { + /** @var \PHPStan\Parser\Parser $parser */ + $parser = self::getContainer()->getService('directParser'); + return $parser; + } + + /** + * @param \PHPStan\Type\DynamicMethodReturnTypeExtension[] $dynamicMethodReturnTypeExtensions + * @param \PHPStan\Type\DynamicStaticMethodReturnTypeExtension[] $dynamicStaticMethodReturnTypeExtensions + * @return \PHPStan\Broker\Broker + */ + public function createBroker( + array $dynamicMethodReturnTypeExtensions = [], + array $dynamicStaticMethodReturnTypeExtensions = [] + ): Broker + { + $functionCallStatementFinder = new FunctionCallStatementFinder(); + $parser = $this->getParser(); + $cache = new Cache(new MemoryCacheStorage()); + $methodReflectionFactory = new class($parser, $functionCallStatementFinder, $cache) implements PhpMethodReflectionFactory { + + /** @var \PHPStan\Parser\Parser */ + private $parser; + + /** @var \PHPStan\Parser\FunctionCallStatementFinder */ + private $functionCallStatementFinder; + + /** @var \PHPStan\Cache\Cache */ + private $cache; + + /** @var \PHPStan\Broker\Broker */ + public $broker; + + public function __construct( + Parser $parser, + FunctionCallStatementFinder $functionCallStatementFinder, + Cache $cache + ) + { + $this->parser = $parser; + $this->functionCallStatementFinder = $functionCallStatementFinder; + $this->cache = $cache; + } + + /** + * @param ClassReflection $declaringClass + * @param ClassReflection|null $declaringTrait + * @param \PHPStan\Reflection\Php\BuiltinMethodReflection $reflection + * @param Type[] $phpDocParameterTypes + * @param Type|null $phpDocReturnType + * @param Type|null $phpDocThrowType + * @param bool $isDeprecated + * @param bool $isInternal + * @param bool $isFinal + * @return PhpMethodReflection + */ + public function create( + ClassReflection $declaringClass, + ?ClassReflection $declaringTrait, + \PHPStan\Reflection\Php\BuiltinMethodReflection $reflection, + array $phpDocParameterTypes, + ?Type $phpDocReturnType, + ?Type $phpDocThrowType, + bool $isDeprecated, + bool $isInternal, + bool $isFinal + ): PhpMethodReflection + { + return new PhpMethodReflection( + $declaringClass, + $declaringTrait, + $reflection, + $this->broker, + $this->parser, + $this->functionCallStatementFinder, + $this->cache, + $phpDocParameterTypes, + $phpDocReturnType, + $phpDocThrowType, + $isDeprecated, + $isInternal, + $isFinal + ); + } + + }; + $phpDocStringResolver = self::getContainer()->getByType(PhpDocStringResolver::class); + $currentWorkingDirectory = $this->getCurrentWorkingDirectory(); + $fileTypeMapper = new FileTypeMapper($parser, $phpDocStringResolver, $cache, new AnonymousClassNameHelper(new FileHelper($currentWorkingDirectory), new RelativePathHelper($currentWorkingDirectory, DIRECTORY_SEPARATOR, [])), self::getContainer()->getByType(\PHPStan\PhpDoc\TypeNodeResolver::class)); + $annotationsMethodsClassReflectionExtension = new AnnotationsMethodsClassReflectionExtension($fileTypeMapper); + $annotationsPropertiesClassReflectionExtension = new AnnotationsPropertiesClassReflectionExtension($fileTypeMapper); + $signatureMapProvider = self::getContainer()->getByType(SignatureMapProvider::class); + $phpExtension = new PhpClassReflectionExtension($methodReflectionFactory, $fileTypeMapper, $annotationsMethodsClassReflectionExtension, $annotationsPropertiesClassReflectionExtension, $signatureMapProvider); + $functionReflectionFactory = new class($this->getParser(), $functionCallStatementFinder, $cache) implements FunctionReflectionFactory { + + /** @var \PHPStan\Parser\Parser */ + private $parser; + + /** @var \PHPStan\Parser\FunctionCallStatementFinder */ + private $functionCallStatementFinder; + + /** @var \PHPStan\Cache\Cache */ + private $cache; + + public function __construct( + Parser $parser, + FunctionCallStatementFinder $functionCallStatementFinder, + Cache $cache + ) + { + $this->parser = $parser; + $this->functionCallStatementFinder = $functionCallStatementFinder; + $this->cache = $cache; + } + + /** + * @param \ReflectionFunction $function + * @param Type[] $phpDocParameterTypes + * @param Type|null $phpDocReturnType + * @param Type|null $phpDocThrowType + * @param bool $isDeprecated + * @param bool $isInternal + * @param bool $isFinal + * @param string|false $filename + * @return PhpFunctionReflection + */ + public function create( + \ReflectionFunction $function, + array $phpDocParameterTypes, + ?Type $phpDocReturnType, + ?Type $phpDocThrowType, + bool $isDeprecated, + bool $isInternal, + bool $isFinal, + $filename + ): PhpFunctionReflection + { + return new PhpFunctionReflection( + $function, + $this->parser, + $this->functionCallStatementFinder, + $this->cache, + $phpDocParameterTypes, + $phpDocReturnType, + $phpDocThrowType, + $isDeprecated, + $isInternal, + $isFinal, + $filename + ); + } + + }; + + $tagToService = static function (array $tags) { + return array_map(static function (string $serviceName) { + return self::getContainer()->getService($serviceName); + }, array_keys($tags)); + }; + + $currentWorkingDirectory = $this->getCurrentWorkingDirectory(); + $anonymousClassNameHelper = new AnonymousClassNameHelper(new FileHelper($currentWorkingDirectory), new RelativePathHelper($currentWorkingDirectory, DIRECTORY_SEPARATOR, [])); + $broker = new Broker( + [ + $phpExtension, + new PhpDefectClassReflectionExtension(self::getContainer()->getByType(TypeStringResolver::class), $annotationsPropertiesClassReflectionExtension), + new UniversalObjectCratesClassReflectionExtension([\stdClass::class]), + $annotationsPropertiesClassReflectionExtension, + ], + [ + $phpExtension, + $annotationsMethodsClassReflectionExtension, + ], + array_merge($dynamicMethodReturnTypeExtensions, $this->getDynamicMethodReturnTypeExtensions()), + array_merge($dynamicStaticMethodReturnTypeExtensions, $this->getDynamicStaticMethodReturnTypeExtensions()), + array_merge($tagToService(self::getContainer()->findByTag(BrokerFactory::DYNAMIC_FUNCTION_RETURN_TYPE_EXTENSION_TAG)), $this->getDynamicFunctionReturnTypeExtensions()), + $functionReflectionFactory, + new FileTypeMapper($this->getParser(), $phpDocStringResolver, $cache, $anonymousClassNameHelper, self::getContainer()->getByType(\PHPStan\PhpDoc\TypeNodeResolver::class)), + $signatureMapProvider, + self::getContainer()->getByType(Standard::class), + $anonymousClassNameHelper, + self::getContainer()->getByType(Parser::class), + new RelativePathHelper($this->getCurrentWorkingDirectory(), DIRECTORY_SEPARATOR, []), + self::getContainer()->parameters['universalObjectCratesClasses'] + ); + $methodReflectionFactory->broker = $broker; + + return $broker; + } + + /** + * @param Broker $broker + * @param TypeSpecifier $typeSpecifier + * @param string[] $dynamicConstantNames + * + * @return ScopeFactory + */ + public function createScopeFactory(Broker $broker, TypeSpecifier $typeSpecifier, array $dynamicConstantNames = []): ScopeFactory + { + $container = self::getContainer(); + + if (count($dynamicConstantNames) > 0) { + $container->parameters['dynamicConstantNames'] = array_merge($container->parameters['dynamicConstantNames'], $dynamicConstantNames); + } + + return new ScopeFactory( + Scope::class, + $broker, + new \PhpParser\PrettyPrinter\Standard(), + $typeSpecifier, + $container + ); + } + + public function getCurrentWorkingDirectory(): string + { + return $this->getFileHelper()->normalizePath(__DIR__ . '/../..'); + } + + /** + * @return \PHPStan\Type\DynamicMethodReturnTypeExtension[] + */ + public function getDynamicMethodReturnTypeExtensions(): array + { + return []; + } + + /** + * @return \PHPStan\Type\DynamicStaticMethodReturnTypeExtension[] + */ + public function getDynamicStaticMethodReturnTypeExtensions(): array + { + return []; + } + + /** + * @return \PHPStan\Type\DynamicFunctionReturnTypeExtension[] + */ + public function getDynamicFunctionReturnTypeExtensions(): array + { + return []; + } + + /** + * @param \PhpParser\PrettyPrinter\Standard $printer + * @param \PHPStan\Broker\Broker $broker + * @param \PHPStan\Type\MethodTypeSpecifyingExtension[] $methodTypeSpecifyingExtensions + * @param \PHPStan\Type\StaticMethodTypeSpecifyingExtension[] $staticMethodTypeSpecifyingExtensions + * @return \PHPStan\Analyser\TypeSpecifier + */ + public function createTypeSpecifier( + Standard $printer, + Broker $broker, + array $methodTypeSpecifyingExtensions = [], + array $staticMethodTypeSpecifyingExtensions = [] + ): TypeSpecifier + { + $tagToService = static function (array $tags) { + return array_map(static function (string $serviceName) { + return self::getContainer()->getService($serviceName); + }, array_keys($tags)); + }; + + return new TypeSpecifier( + $printer, + $broker, + $tagToService(self::getContainer()->findByTag(TypeSpecifierFactory::FUNCTION_TYPE_SPECIFYING_EXTENSION_TAG)), + $methodTypeSpecifyingExtensions, + $staticMethodTypeSpecifyingExtensions + ); + } + + public function getFileHelper(): FileHelper + { + return self::getContainer()->getByType(FileHelper::class); + } + + protected function skipIfNotOnWindows(): void + { + if (DIRECTORY_SEPARATOR === '\\') { + return; + } + + self::markTestSkipped(); + } + + protected function skipIfNotOnUnix(): void + { + if (DIRECTORY_SEPARATOR === '/') { + return; + } + + self::markTestSkipped(); + } + +} diff --git a/vendor/phpstan/phpstan/src/TrinaryLogic.php b/vendor/phpstan/phpstan/src/TrinaryLogic.php new file mode 100644 index 00000000..41aa5a89 --- /dev/null +++ b/vendor/phpstan/phpstan/src/TrinaryLogic.php @@ -0,0 +1,148 @@ +value = $value; + } + + public static function createYes(): self + { + return self::create(self::YES); + } + + public static function createNo(): self + { + return self::create(self::NO); + } + + public static function createMaybe(): self + { + return self::create(self::MAYBE); + } + + public static function createFromBoolean(bool $value): self + { + return self::create($value ? self::YES : self::NO); + } + + private static function create(int $value): self + { + self::$registry[$value] = self::$registry[$value] ?? new self($value); + return self::$registry[$value]; + } + + public function yes(): bool + { + return $this->value === self::YES; + } + + public function maybe(): bool + { + return $this->value === self::MAYBE; + } + + public function no(): bool + { + return $this->value === self::NO; + } + + public function toBooleanType(): BooleanType + { + if ($this->value === self::MAYBE) { + return new BooleanType(); + } + + return new ConstantBooleanType($this->value === self::YES); + } + + public function and(self ...$operands): self + { + $operandValues = array_column($operands, 'value'); + $operandValues[] = $this->value; + return self::create(min($operandValues)); + } + + public function or(self ...$operands): self + { + $operandValues = array_column($operands, 'value'); + $operandValues[] = $this->value; + return self::create(max($operandValues)); + } + + public static function extremeIdentity(self ...$operands): self + { + $operandValues = array_column($operands, 'value'); + $min = min($operandValues); + $max = max($operandValues); + return self::create($min === $max ? $min : self::MAYBE); + } + + public static function maxMin(self ...$operands): self + { + $operandValues = array_column($operands, 'value'); + return self::create(max($operandValues) > 0 ? max($operandValues) : min($operandValues)); + } + + public function negate(): self + { + return self::create(-$this->value); + } + + public function equals(self $other): bool + { + return $this === $other; + } + + public function compareTo(self $other): ?self + { + if ($this->value > $other->value) { + return $this; + } elseif ($other->value > $this->value) { + return $other; + } + + return null; + } + + public function describe(): string + { + static $labels = [ + self::NO => 'No', + self::MAYBE => 'Maybe', + self::YES => 'Yes', + ]; + + return $labels[$this->value]; + } + + /** + * @param mixed[] $properties + * @return self + */ + public static function __set_state(array $properties): self + { + return self::create($properties['value']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Accessory/AccessoryType.php b/vendor/phpstan/phpstan/src/Type/Accessory/AccessoryType.php new file mode 100644 index 00000000..734ee437 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Accessory/AccessoryType.php @@ -0,0 +1,10 @@ +methodName = $methodName; + } + + public function getReferencedClasses(): array + { + return []; + } + + private function getCanonicalMethodName(): string + { + return strtolower($this->methodName); + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + return TrinaryLogic::createFromBoolean($this->equals($type)); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + return $type->hasMethod($this->methodName); + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { + return $otherType->isSuperTypeOf($this); + } + + if ($otherType instanceof self) { + $limit = TrinaryLogic::createYes(); + } else { + $limit = TrinaryLogic::createMaybe(); + } + + return $limit->and($otherType->hasMethod($this->methodName)); + } + + public function equals(Type $type): bool + { + return $type instanceof self + && $this->getCanonicalMethodName() === $type->getCanonicalMethodName(); + } + + public function describe(\PHPStan\Type\VerbosityLevel $level): string + { + return sprintf('hasMethod(%s)', $this->methodName); + } + + public function hasMethod(string $methodName): TrinaryLogic + { + if ($this->getCanonicalMethodName() === strtolower($methodName)) { + return TrinaryLogic::createYes(); + } + + return TrinaryLogic::createMaybe(); + } + + public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection + { + return new DummyMethodReflection($this->methodName); + } + + public function isCallable(): TrinaryLogic + { + if ($this->getCanonicalMethodName() === '__invoke') { + return TrinaryLogic::createYes(); + } + + return TrinaryLogic::createMaybe(); + } + + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + return [ + new TrivialParametersAcceptor(), + ]; + } + + public static function __set_state(array $properties): Type + { + return new self($properties['methodName']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Accessory/HasOffsetType.php b/vendor/phpstan/phpstan/src/Type/Accessory/HasOffsetType.php new file mode 100644 index 00000000..2a4e252a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Accessory/HasOffsetType.php @@ -0,0 +1,140 @@ +offsetType = $offsetType; + } + + public function getReferencedClasses(): array + { + return []; + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + return $type->isOffsetAccessible() + ->and($type->hasOffsetValueType($this->offsetType)); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($this->equals($type)) { + return TrinaryLogic::createYes(); + } + return $type->isOffsetAccessible() + ->and($type->hasOffsetValueType($this->offsetType)); + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { + return $otherType->isSuperTypeOf($this); + } + + return $otherType->isOffsetAccessible() + ->and($otherType->hasOffsetValueType($this->offsetType)) + ->and($otherType instanceof self ? TrinaryLogic::createYes() : TrinaryLogic::createMaybe()); + } + + public function equals(Type $type): bool + { + return $type instanceof self + && $this->offsetType->equals($type->offsetType); + } + + public function describe(\PHPStan\Type\VerbosityLevel $level): string + { + return sprintf('hasOffset(%s)', $this->offsetType->describe($level)); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + if ($offsetType instanceof ConstantScalarType && $offsetType->equals($this->offsetType)) { + return TrinaryLogic::createYes(); + } + + return TrinaryLogic::createMaybe(); + } + + public function getOffsetValueType(Type $offsetType): Type + { + return new MixedType(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return $this; + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toInteger(): Type + { + return new ErrorType(); + } + + public function toFloat(): Type + { + return new ErrorType(); + } + + public function toString(): Type + { + return new ErrorType(); + } + + public function toArray(): Type + { + return new MixedType(); + } + + public static function __set_state(array $properties): Type + { + return new self($properties['offsetType']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Accessory/HasPropertyType.php b/vendor/phpstan/phpstan/src/Type/Accessory/HasPropertyType.php new file mode 100644 index 00000000..54ed9c76 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Accessory/HasPropertyType.php @@ -0,0 +1,95 @@ +propertyName = $propertyName; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return []; + } + + public function getPropertyName(): string + { + return $this->propertyName; + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + return TrinaryLogic::createFromBoolean($this->equals($type)); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + return $type->hasProperty($this->propertyName); + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { + return $otherType->isSuperTypeOf($this); + } + + if ($otherType instanceof self) { + $limit = TrinaryLogic::createYes(); + } else { + $limit = TrinaryLogic::createMaybe(); + } + + return $limit->and($otherType->hasProperty($this->propertyName)); + } + + public function equals(Type $type): bool + { + return $type instanceof self + && $this->propertyName === $type->propertyName; + } + + public function describe(\PHPStan\Type\VerbosityLevel $level): string + { + return sprintf('hasProperty(%s)', $this->propertyName); + } + + public function hasProperty(string $propertyName): TrinaryLogic + { + if ($this->propertyName === $propertyName) { + return TrinaryLogic::createYes(); + } + + return TrinaryLogic::createMaybe(); + } + + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + return [new TrivialParametersAcceptor()]; + } + + public static function __set_state(array $properties): Type + { + return new self($properties['propertyName']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Accessory/NonEmptyArrayType.php b/vendor/phpstan/phpstan/src/Type/Accessory/NonEmptyArrayType.php new file mode 100644 index 00000000..83b5e364 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Accessory/NonEmptyArrayType.php @@ -0,0 +1,144 @@ +isSuperTypeOf($type) + ->and($type->isIterableAtLeastOnce()); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($this->equals($type)) { + return TrinaryLogic::createYes(); + } + + return (new ArrayType(new MixedType(), new MixedType())) + ->isSuperTypeOf($type) + ->and($type->isIterableAtLeastOnce()); + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof UnionType || $otherType instanceof IntersectionType) { + return $otherType->isSuperTypeOf($this); + } + + return (new ArrayType(new MixedType(), new MixedType())) + ->isSuperTypeOf($otherType) + ->and($otherType->isIterableAtLeastOnce()) + ->and($otherType instanceof self ? TrinaryLogic::createYes() : TrinaryLogic::createMaybe()); + } + + public function equals(Type $type): bool + { + return $type instanceof self; + } + + public function describe(\PHPStan\Type\VerbosityLevel $level): string + { + return 'nonEmpty'; + } + + public function isOffsetAccessible(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + return TrinaryLogic::createMaybe(); + } + + public function getOffsetValueType(Type $offsetType): Type + { + return new MixedType(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return $this; + } + + public function isIterable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function getIterableKeyType(): Type + { + return new MixedType(); + } + + public function getIterableValueType(): Type + { + return new MixedType(); + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toInteger(): Type + { + return new ErrorType(); + } + + public function toFloat(): Type + { + return new ErrorType(); + } + + public function toString(): Type + { + return new ErrorType(); + } + + public function toArray(): Type + { + return new MixedType(); + } + + public static function __set_state(array $properties): Type + { + return new self(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/ArrayType.php b/vendor/phpstan/phpstan/src/Type/ArrayType.php new file mode 100644 index 00000000..8a351d68 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/ArrayType.php @@ -0,0 +1,303 @@ +describe(VerbosityLevel::value()) === '(int|string)') { + $keyType = new MixedType(); + } + $this->keyType = $keyType; + $this->itemType = $itemType; + } + + public function getKeyType(): Type + { + return $this->keyType; + } + + public function getItemType(): Type + { + return $this->itemType; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return array_merge( + $this->keyType->getReferencedClasses(), + $this->getItemType()->getReferencedClasses() + ); + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + $arrays = TypeUtils::getArrays($type); + if (count($arrays) > 0) { + $result = TrinaryLogic::createYes(); + foreach ($arrays as $array) { + $result = $result + ->and($this->getItemType()->accepts($array->getItemType(), $strictTypes)) + ->and($this->keyType->accepts($array->keyType, $strictTypes)); + } + + return $result; + } + + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + return TrinaryLogic::createNo(); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($type instanceof self) { + return $this->getItemType()->isSuperTypeOf($type->getItemType()) + ->and($this->keyType->isSuperTypeOf($type->keyType)); + } + + if ($type instanceof CompoundType) { + return $type->isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $type instanceof self + && $this->getItemType()->equals($type->getItemType()) + && $this->keyType->equals($type->keyType); + } + + public function describe(VerbosityLevel $level): string + { + if ($this->keyType instanceof MixedType || $this->keyType instanceof NeverType) { + if ($this->itemType instanceof MixedType || $this->itemType instanceof NeverType) { + return 'array'; + } + + return sprintf('array<%s>', $this->itemType->describe($level)); + } + + return sprintf('array<%s, %s>', $this->keyType->describe($level), $this->itemType->describe($level)); + } + + public function generalizeValues(): self + { + return new self($this->keyType, TypeUtils::generalizeType($this->itemType)); + } + + public function getKeysArray(): self + { + return new self(new IntegerType(), $this->keyType); + } + + public function getValuesArray(): self + { + return new self(new IntegerType(), $this->itemType); + } + + public function resolveStatic(string $className): Type + { + if ($this->getItemType() instanceof StaticResolvableType) { + return new self( + $this->keyType, + $this->getItemType()->resolveStatic($className) + ); + } + + return $this; + } + + public function changeBaseClass(string $className): StaticResolvableType + { + if ($this->getItemType() instanceof StaticResolvableType) { + return new self( + $this->keyType, + $this->getItemType()->changeBaseClass($className) + ); + } + + return $this; + } + + public function isIterable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return TrinaryLogic::createMaybe(); + } + + public function getIterableKeyType(): Type + { + $keyType = $this->keyType; + if ($keyType instanceof MixedType) { + return new BenevolentUnionType([new IntegerType(), new StringType()]); + } + + return $keyType; + } + + public function getIterableValueType(): Type + { + return $this->getItemType(); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + $offsetType = self::castToArrayKeyType($offsetType); + if ($this->getKeyType()->isSuperTypeOf($offsetType)->no()) { + return TrinaryLogic::createNo(); + } + + return TrinaryLogic::createMaybe(); + } + + public function getOffsetValueType(Type $offsetType): Type + { + $offsetType = self::castToArrayKeyType($offsetType); + if ($this->getKeyType()->isSuperTypeOf($offsetType)->no()) { + return new ErrorType(); + } + + $type = $this->getItemType(); + if ($type instanceof ErrorType) { + return new MixedType(); + } + + return $type; + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + if ($offsetType === null) { + $offsetType = new IntegerType(); + } + + return new ArrayType( + TypeCombinator::union($this->keyType, self::castToArrayKeyType($offsetType)), + TypeCombinator::union($this->itemType, $valueType) + ); + } + + public function isCallable(): TrinaryLogic + { + return TrinaryLogic::createMaybe()->and((new StringType())->isSuperTypeOf($this->itemType)); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + if ($this->isCallable()->no()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return [new TrivialParametersAcceptor()]; + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toString(): Type + { + return new ErrorType(); + } + + public function toInteger(): Type + { + return new ErrorType(); + } + + public function toFloat(): Type + { + return new ErrorType(); + } + + public function toArray(): Type + { + return $this; + } + + public function count(): Type + { + return new IntegerType(); + } + + public static function castToArrayKeyType(Type $offsetType): Type + { + if ($offsetType instanceof UnionType) { + return TypeCombinator::union(...array_map(static function (Type $type): Type { + return self::castToArrayKeyType($type); + }, $offsetType->getTypes())); + } + + if ($offsetType instanceof ConstantScalarType) { + /** @var int|string $offsetValue */ + $offsetValue = key([$offsetType->getValue() => null]); + return is_int($offsetValue) ? new ConstantIntegerType($offsetValue) : new ConstantStringType($offsetValue); + } + + if ($offsetType instanceof IntegerType || $offsetType instanceof FloatType || $offsetType instanceof BooleanType) { + return new IntegerType(); + } + + if ($offsetType instanceof StringType) { + return new StringType(); + } + + return new UnionType([new IntegerType(), new StringType()]); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self( + $properties['keyType'], + $properties['itemType'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/BenevolentUnionType.php b/vendor/phpstan/phpstan/src/Type/BenevolentUnionType.php new file mode 100644 index 00000000..045dd934 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/BenevolentUnionType.php @@ -0,0 +1,32 @@ +getTypes() as $type) { + $result = $getType($type); + if ($result instanceof ErrorType) { + continue; + } + + $resultTypes[] = $result; + } + + if (count($resultTypes) === 0) { + return new ErrorType(); + } + + return TypeCombinator::union(...$resultTypes); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/BooleanType.php b/vendor/phpstan/phpstan/src/Type/BooleanType.php new file mode 100644 index 00000000..96944673 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/BooleanType.php @@ -0,0 +1,96 @@ +toInteger(); + } + + public function toString(): Type + { + return TypeCombinator::union( + new ConstantStringType(''), + new ConstantStringType('1') + ); + } + + public function toInteger(): Type + { + return TypeCombinator::union( + new ConstantIntegerType(0), + new ConstantIntegerType(1) + ); + } + + public function toFloat(): Type + { + return TypeCombinator::union( + new ConstantFloatType(0.0), + new ConstantFloatType(1.0) + ); + } + + public function toArray(): Type + { + return new ConstantArrayType( + [new ConstantIntegerType(0)], + [$this], + 1 + ); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function getOffsetValueType(Type $offsetType): Type + { + return new NullType(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return new ErrorType(); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new static(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/CallableType.php b/vendor/phpstan/phpstan/src/Type/CallableType.php new file mode 100644 index 00000000..ba397c2d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/CallableType.php @@ -0,0 +1,208 @@ + */ + private $parameters; + + /** @var Type */ + private $returnType; + + /** @var bool */ + private $variadic; + + /** @var bool */ + private $isCommonCallable; + + /** + * @param array $parameters + * @param Type $returnType + * @param bool $variadic + */ + public function __construct( + ?array $parameters = null, + ?Type $returnType = null, + bool $variadic = true + ) + { + if ($returnType === null) { + $returnType = new MixedType(); + } + + $this->parameters = $parameters ?? []; + $this->returnType = $returnType; + $this->variadic = $variadic; + $this->isCommonCallable = $parameters === null; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return []; + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + return $this->isSuperTypeOf($type); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + $isCallable = $type->isCallable(); + if ($isCallable->no() || $this->isCommonCallable) { + return $isCallable; + } + + static $scope; + if ($scope === null) { + $scope = new OutOfClassScope(); + } + + $variantsResult = null; + foreach ($type->getCallableParametersAcceptors($scope) as $variant) { + $isSuperType = CallableTypeHelper::isParametersAcceptorSuperTypeOf($this, $variant); + if ($variantsResult === null) { + $variantsResult = $isSuperType; + } else { + $variantsResult = $variantsResult->or($isSuperType); + } + } + + if ($variantsResult === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $isCallable->and($variantsResult); + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof IntersectionType || $otherType instanceof UnionType) { + return $otherType->isSuperTypeOf($this); + } + + return $otherType->isCallable() + ->and($otherType instanceof self ? TrinaryLogic::createYes() : TrinaryLogic::createMaybe()); + } + + public function equals(Type $type): bool + { + return $type instanceof self; + } + + public function describe(VerbosityLevel $level): string + { + return $level->handle( + static function (): string { + return 'callable'; + }, + function () use ($level): string { + return sprintf( + 'callable(%s): %s', + implode(', ', array_map( + static function (NativeParameterReflection $param) use ($level) { + return $param->getType()->describe($level); + }, + $this->getParameters() + )), + $this->returnType->describe($level) + ); + } + ); + } + + public function isCallable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + return [$this]; + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toString(): Type + { + return new ErrorType(); + } + + public function toInteger(): Type + { + return new ErrorType(); + } + + public function toFloat(): Type + { + return new ErrorType(); + } + + public function toArray(): Type + { + return new ArrayType(new MixedType(), new MixedType()); + } + + /** + * @return array + */ + public function getParameters(): array + { + return $this->parameters; + } + + public function isVariadic(): bool + { + return $this->variadic; + } + + public function getReturnType(): Type + { + return $this->returnType; + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self( + (bool) $properties['isCommonCallable'] ? null : $properties['parameters'], + $properties['returnType'], + $properties['variadic'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/CallableTypeHelper.php b/vendor/phpstan/phpstan/src/Type/CallableTypeHelper.php new file mode 100644 index 00000000..e2c28fde --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/CallableTypeHelper.php @@ -0,0 +1,43 @@ +getParameters(); + $ourParameters = $ours->getParameters(); + if (count($theirParameters) > count($ourParameters)) { + return TrinaryLogic::createNo(); + } + + $result = null; + foreach ($theirParameters as $i => $theirParameter) { + $ourParameter = $ourParameters[$i]; + $isSuperType = $theirParameter->getType()->isSuperTypeOf($ourParameter->getType()); + if ($result === null) { + $result = $isSuperType; + } else { + $result = $result->and($isSuperType); + } + } + + $isReturnTypeSuperType = $ours->getReturnType()->isSuperTypeOf($theirs->getReturnType()); + if ($result === null) { + $result = $isReturnTypeSuperType; + } else { + $result = $result->and($isReturnTypeSuperType); + } + + return $result; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/ClosureType.php b/vendor/phpstan/phpstan/src/Type/ClosureType.php new file mode 100644 index 00000000..ace72a1a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/ClosureType.php @@ -0,0 +1,290 @@ + */ + private $parameters; + + /** @var Type */ + private $returnType; + + /** @var bool */ + private $variadic; + + /** + * @param array $parameters + * @param Type $returnType + * @param bool $variadic + */ + public function __construct( + array $parameters, + Type $returnType, + bool $variadic + ) + { + $this->objectType = new ObjectType(\Closure::class); + $this->parameters = $parameters; + $this->returnType = $returnType; + $this->variadic = $variadic; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + $classes = $this->objectType->getReferencedClasses(); + foreach ($this->parameters as $parameter) { + $classes = array_merge($classes, $parameter->getType()->getReferencedClasses()); + } + + return array_merge($classes, $this->returnType->getReferencedClasses()); + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + if (!$type instanceof ClosureType) { + return $this->objectType->accepts($type, $strictTypes); + } + + return $this->isSuperTypeOf($type); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($type instanceof self) { + return CallableTypeHelper::isParametersAcceptorSuperTypeOf( + $this, + $type + ); + } + + if ($type instanceof CompoundType) { + return $type->isSubTypeOf($this); + } + + if ($type instanceof ObjectWithoutClassType) { + return TrinaryLogic::createMaybe(); + } + + if ( + $type instanceof TypeWithClassName + && $type->getClassName() === \Closure::class + ) { + return TrinaryLogic::createMaybe(); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + if (!$type instanceof self) { + return false; + } + + return $this->returnType->equals($type->returnType); + } + + public function describe(VerbosityLevel $level): string + { + return sprintf( + 'Closure(%s): %s', + implode(', ', array_map(static function (ParameterReflection $parameter) use ($level): string { + return $parameter->getType()->describe($level); + }, $this->parameters)), + $this->returnType->describe($level) + ); + } + + public function canAccessProperties(): TrinaryLogic + { + return $this->objectType->canAccessProperties(); + } + + public function hasProperty(string $propertyName): TrinaryLogic + { + return $this->objectType->hasProperty($propertyName); + } + + public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection + { + return $this->objectType->getProperty($propertyName, $scope); + } + + public function canCallMethods(): TrinaryLogic + { + return $this->objectType->canCallMethods(); + } + + public function hasMethod(string $methodName): TrinaryLogic + { + return $this->objectType->hasMethod($methodName); + } + + public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection + { + return $this->objectType->getMethod($methodName, $scope); + } + + public function canAccessConstants(): TrinaryLogic + { + return $this->objectType->canAccessConstants(); + } + + public function hasConstant(string $constantName): TrinaryLogic + { + return $this->objectType->hasConstant($constantName); + } + + public function getConstant(string $constantName): ConstantReflection + { + return $this->objectType->getConstant($constantName); + } + + public function isIterable(): TrinaryLogic + { + return TrinaryLogic::createNo(); + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return TrinaryLogic::createNo(); + } + + public function getIterableKeyType(): Type + { + return new ErrorType(); + } + + public function getIterableValueType(): Type + { + return new ErrorType(); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return TrinaryLogic::createNo(); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + return TrinaryLogic::createNo(); + } + + public function getOffsetValueType(Type $offsetType): Type + { + return new ErrorType(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return new ErrorType(); + } + + public function isCallable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + return [$this]; + } + + public function isCloneable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function toBoolean(): BooleanType + { + return new ConstantBooleanType(true); + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toInteger(): Type + { + return new ErrorType(); + } + + public function toFloat(): Type + { + return new ErrorType(); + } + + public function toString(): Type + { + return new ErrorType(); + } + + public function toArray(): Type + { + return new ConstantArrayType( + [new ConstantIntegerType(0)], + [$this], + 1 + ); + } + + /** + * @return array + */ + public function getParameters(): array + { + return $this->parameters; + } + + public function isVariadic(): bool + { + return $this->variadic; + } + + public function getReturnType(): Type + { + return $this->returnType; + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self( + $properties['parameters'], + $properties['returnType'], + $properties['variadic'] + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/CommentHelper.php b/vendor/phpstan/phpstan/src/Type/CommentHelper.php new file mode 100644 index 00000000..7681e75a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/CommentHelper.php @@ -0,0 +1,20 @@ +getDocComment(); + if ($phpDoc !== null) { + return $phpDoc->getText(); + } + + return null; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/CompoundType.php b/vendor/phpstan/phpstan/src/Type/CompoundType.php new file mode 100644 index 00000000..10165f36 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/CompoundType.php @@ -0,0 +1,12 @@ +getTypes() as $innerType) { + if ($otherType->accepts($innerType, $strictTypes)->yes()) { + return TrinaryLogic::createYes(); + } + } + + return TrinaryLogic::createNo(); + } + + return $compoundType->isSubTypeOf($otherType); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayType.php b/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayType.php new file mode 100644 index 00000000..bc1b8fc3 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayType.php @@ -0,0 +1,507 @@ + */ + private $keyTypes; + + /** @var array */ + private $valueTypes; + + /** @var int */ + private $nextAutoIndex; + + /** + * @param array $keyTypes + * @param array $valueTypes + * @param int $nextAutoIndex + */ + public function __construct(array $keyTypes, array $valueTypes, int $nextAutoIndex = 0) + { + assert(count($keyTypes) === count($valueTypes)); + + parent::__construct( + count($keyTypes) > 0 ? TypeCombinator::union(...$keyTypes) : new NeverType(), + count($valueTypes) > 0 ? TypeCombinator::union(...$valueTypes) : new NeverType() + ); + + $this->keyTypes = $keyTypes; + $this->valueTypes = $valueTypes; + $this->nextAutoIndex = $nextAutoIndex; + } + + public function getNextAutoIndex(): int + { + return $this->nextAutoIndex; + } + + public function getKeyType(): Type + { + if (count($this->keyTypes) > 1) { + return new UnionType($this->keyTypes); + } + + return parent::getKeyType(); + } + + /** + * @return array + */ + public function getKeyTypes(): array + { + return $this->keyTypes; + } + + /** + * @return array + */ + public function getValueTypes(): array + { + return $this->valueTypes; + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof self) { + if (count($this->keyTypes) !== count($type->keyTypes)) { + return TrinaryLogic::createNo(); + } + + $result = TrinaryLogic::createYes(); + foreach (array_keys($this->keyTypes) as $i) { + $result = $result + ->and($this->keyTypes[$i]->accepts($type->keyTypes[$i], $strictTypes)) + ->and($this->valueTypes[$i]->accepts($type->valueTypes[$i], $strictTypes)); + } + + return $result; + } + + return TrinaryLogic::createNo(); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($type instanceof self) { + if (count($this->keyTypes) !== count($type->keyTypes)) { + return TrinaryLogic::createNo(); + } + + $results = []; + foreach (array_keys($this->keyTypes) as $i) { + $results[] = $this->keyTypes[$i]->isSuperTypeOf($type->keyTypes[$i]); + $results[] = $this->valueTypes[$i]->isSuperTypeOf($type->valueTypes[$i]); + } + + return TrinaryLogic::createYes()->and(...$results); + } + + if ($type instanceof ArrayType) { + $result = TrinaryLogic::createMaybe(); + if (count($this->keyTypes) === 0) { + return $result; + } + + return $result->and( + $this->getKeyType()->isSuperTypeOf($type->getKeyType()), + $this->getItemType()->isSuperTypeOf($type->getItemType()) + ); + } + + if ($type instanceof CompoundType) { + return $type->isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + if (!$type instanceof self) { + return false; + } + + if (count($this->keyTypes) !== count($type->keyTypes)) { + return false; + } + + foreach ($this->keyTypes as $i => $keyType) { + $valueType = $this->valueTypes[$i]; + if (!$valueType->equals($type->valueTypes[$i])) { + return false; + } + if (!$keyType->equals($type->keyTypes[$i])) { + return false; + } + } + + return true; + } + + public function isCallable(): TrinaryLogic + { + $typeAndMethod = $this->findTypeAndMethodName(); + if ($typeAndMethod === null) { + return TrinaryLogic::createNo(); + } + + return $typeAndMethod->getCertainty(); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + $typeAndMethodName = $this->findTypeAndMethodName(); + if ($typeAndMethodName === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + if ($typeAndMethodName->isUnknown() || !$typeAndMethodName->getCertainty()->yes()) { + return [new TrivialParametersAcceptor()]; + } + + $method = $typeAndMethodName->getType() + ->getMethod($typeAndMethodName->getMethod(), $scope); + + if (!$scope->canCallMethod($method)) { + return [new InaccessibleMethod($method)]; + } + + return $method->getVariants(); + } + + private function findTypeAndMethodName(): ?ConstantArrayTypeAndMethod + { + if (count($this->keyTypes) !== 2) { + return null; + } + + if ($this->keyTypes[0]->isSuperTypeOf(new ConstantIntegerType(0))->no()) { + return null; + } + + if ($this->keyTypes[1]->isSuperTypeOf(new ConstantIntegerType(1))->no()) { + return null; + } + + [$classOrObject, $method] = $this->valueTypes; + + if (!$method instanceof ConstantStringType) { + return ConstantArrayTypeAndMethod::createUnknown(); + } + + if ($classOrObject instanceof ConstantStringType) { + $broker = Broker::getInstance(); + if (!$broker->hasClass($classOrObject->getValue())) { + return ConstantArrayTypeAndMethod::createUnknown(); + } + $type = new ObjectType($broker->getClass($classOrObject->getValue())->getName()); + } elseif ((new \PHPStan\Type\ObjectWithoutClassType())->isSuperTypeOf($classOrObject)->yes()) { + $type = $classOrObject; + } else { + return ConstantArrayTypeAndMethod::createUnknown(); + } + + $has = $type->hasMethod($method->getValue()); + if (!$has->no()) { + return ConstantArrayTypeAndMethod::createConcrete($type, $method->getValue(), $has); + } + + return null; + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + $offsetType = ArrayType::castToArrayKeyType($offsetType); + if ($offsetType instanceof UnionType) { + $results = []; + foreach ($offsetType->getTypes() as $innerType) { + $results[] = $this->hasOffsetValueType($innerType); + } + + return TrinaryLogic::extremeIdentity(...$results); + } + + return $this->getKeyType()->isSuperTypeOf($offsetType); + } + + public function getOffsetValueType(Type $offsetType): Type + { + $offsetType = ArrayType::castToArrayKeyType($offsetType); + $matchingValueTypes = []; + foreach ($this->keyTypes as $i => $keyType) { + if ($keyType->isSuperTypeOf($offsetType)->no()) { + continue; + } + + $matchingValueTypes[] = $this->valueTypes[$i]; + } + + if (count($matchingValueTypes) > 0) { + $type = TypeCombinator::union(...$matchingValueTypes); + if ($type instanceof ErrorType) { + return new MixedType(); + } + + return $type; + } + + return new ErrorType(); // undefined offset + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + $builder = ConstantArrayTypeBuilder::createFromConstantArray($this); + $builder->setOffsetValueType($offsetType, $valueType); + + return $builder->getArray(); + } + + public function unsetOffset(Type $offsetType): self + { + $offsetType = ArrayType::castToArrayKeyType($offsetType); + if ($offsetType instanceof ConstantIntegerType || $offsetType instanceof ConstantStringType) { + foreach ($this->keyTypes as $i => $keyType) { + if ($keyType->getValue() === $offsetType->getValue()) { + $newKeyTypes = $this->keyTypes; + unset($newKeyTypes[$i]); + $newValueTypes = $this->valueTypes; + unset($newValueTypes[$i]); + return new self(array_values($newKeyTypes), array_values($newValueTypes), $this->nextAutoIndex); + } + } + } + + return $this; + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return TrinaryLogic::createFromBoolean(count($this->keyTypes) > 0); + } + + public function removeLast(): self + { + if (count($this->keyTypes) === 0) { + return $this; + } + + $keyTypes = $this->keyTypes; + $valueTypes = $this->valueTypes; + + $removedKeyType = array_pop($keyTypes); + array_pop($valueTypes); + $nextAutoindex = $removedKeyType instanceof ConstantIntegerType + ? $removedKeyType->getValue() + : $this->nextAutoIndex; + + return new self( + $keyTypes, + $valueTypes, + $nextAutoindex + ); + } + + public function removeFirst(): ArrayType + { + $builder = ConstantArrayTypeBuilder::createEmpty(); + foreach ($this->keyTypes as $i => $keyType) { + if ($i === 0) { + continue; + } + + $valueType = $this->valueTypes[$i]; + if ($keyType instanceof ConstantIntegerType) { + $keyType = null; + } + + $builder->setOffsetValueType($keyType, $valueType); + } + + return $builder->getArray(); + } + + public function slice(int $offset, ?int $limit, bool $preserveKeys = false): self + { + if (count($this->keyTypes) === 0) { + return $this; + } + + $keyTypes = array_slice($this->keyTypes, $offset, $limit); + $valueTypes = array_slice($this->valueTypes, $offset, $limit); + + if (!$preserveKeys) { + $i = 0; + $keyTypes = array_map(static function (ConstantScalarType $keyType) use (&$i): ConstantScalarType { + if ($keyType instanceof ConstantIntegerType) { + $i++; + return new ConstantIntegerType($i - 1); + } + + return $keyType; + }, $keyTypes); + } + + $nextAutoIndex = 0; + foreach ($keyTypes as $keyType) { + if (!$keyType instanceof ConstantIntegerType) { + continue; + } + + $nextAutoIndex = max($nextAutoIndex, $keyType->getValue() + 1); + } + + return new self( + $keyTypes, + $valueTypes, + (int) $nextAutoIndex + ); + } + + public function toBoolean(): BooleanType + { + return new ConstantBooleanType(count($this->keyTypes) > 0); + } + + public function generalize(): Type + { + return new ArrayType( + TypeUtils::generalizeType($this->getKeyType()), + $this->getItemType() + ); + } + + /** + * @return static + */ + public function generalizeValues(): ArrayType + { + $valueTypes = []; + foreach ($this->valueTypes as $valueType) { + $valueTypes[] = TypeUtils::generalizeType($valueType); + } + + return new self($this->keyTypes, $valueTypes, $this->nextAutoIndex); + } + + /** + * @return static + */ + public function getKeysArray(): ArrayType + { + $keyTypes = []; + $valueTypes = []; + $autoIndex = 0; + + foreach ($this->keyTypes as $i => $keyType) { + $keyTypes[] = new ConstantIntegerType($i); + $valueTypes[] = $keyType; + $autoIndex++; + } + + return new self($keyTypes, $valueTypes, $autoIndex); + } + + /** + * @return static + */ + public function getValuesArray(): ArrayType + { + $keyTypes = []; + $valueTypes = []; + $autoIndex = 0; + + foreach ($this->valueTypes as $i => $valueType) { + $keyTypes[] = new ConstantIntegerType($i); + $valueTypes[] = $valueType; + $autoIndex++; + } + + return new self($keyTypes, $valueTypes, $autoIndex); + } + + public function count(): Type + { + return new ConstantIntegerType(count($this->getKeyTypes())); + } + + public function describe(VerbosityLevel $level): string + { + $describeValue = function (bool $truncate) use ($level): string { + $items = []; + $values = []; + $exportValuesOnly = true; + foreach ($this->keyTypes as $i => $keyType) { + $valueType = $this->valueTypes[$i]; + if ($keyType->getValue() !== $i) { + $exportValuesOnly = false; + } + + $items[] = sprintf('%s => %s', var_export($keyType->getValue(), true), $valueType->describe($level)); + $values[] = $valueType->describe($level); + } + + $append = ''; + if ($truncate && count($items) > self::DESCRIBE_LIMIT) { + $items = array_slice($items, 0, self::DESCRIBE_LIMIT); + $values = array_slice($values, 0, self::DESCRIBE_LIMIT); + $append = ', ...'; + } + + return sprintf( + 'array(%s%s)', + implode(', ', $exportValuesOnly ? $values : $items), + $append + ); + }; + return $level->handle( + function () use ($level): string { + return parent::describe($level); + }, + static function () use ($describeValue): string { + return $describeValue(true); + }, + static function () use ($describeValue): string { + return $describeValue(false); + } + ); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['keyTypes'], $properties['valueTypes'], $properties['nextAutoIndex']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayTypeAndMethod.php b/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayTypeAndMethod.php new file mode 100644 index 00000000..f390a9da --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayTypeAndMethod.php @@ -0,0 +1,76 @@ +type = $type; + $this->method = $method; + $this->certainty = $certainty; + } + + public static function createConcrete( + Type $type, + string $method, + TrinaryLogic $certainty + ): self + { + if ($certainty->no()) { + throw new \PHPStan\ShouldNotHappenException(); + } + return new self($type, $method, $certainty); + } + + public static function createUnknown(): self + { + return new self(null, null, TrinaryLogic::createMaybe()); + } + + public function isUnknown(): bool + { + return $this->type === null; + } + + public function getType(): Type + { + if ($this->type === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->type; + } + + public function getMethod(): string + { + if ($this->method === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->method; + } + + public function getCertainty(): TrinaryLogic + { + return $this->certainty; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayTypeBuilder.php b/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayTypeBuilder.php new file mode 100644 index 00000000..e3bdf423 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Constant/ConstantArrayTypeBuilder.php @@ -0,0 +1,106 @@ + */ + private $keyTypes = []; + + /** @var array */ + private $valueTypes = []; + + /** @var int */ + private $nextAutoIndex; + + /** @var bool */ + private $degradeToGeneralArray = false; + + /** + * @param array $keyTypes + * @param array $valueTypes + * @param int $nextAutoIndex + */ + private function __construct( + array $keyTypes, + array $valueTypes, + int $nextAutoIndex + ) + { + $this->keyTypes = $keyTypes; + $this->valueTypes = $valueTypes; + $this->nextAutoIndex = $nextAutoIndex; + } + + public static function createEmpty(): self + { + return new self([], [], 0); + } + + public static function createFromConstantArray(ConstantArrayType $startArrayType): self + { + return new self( + $startArrayType->getKeyTypes(), + $startArrayType->getValueTypes(), + $startArrayType->getNextAutoIndex() + ); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): void + { + if ($offsetType === null) { + $offsetType = new ConstantIntegerType($this->nextAutoIndex); + } else { + $offsetType = ArrayType::castToArrayKeyType($offsetType); + } + + if ( + !$this->degradeToGeneralArray + && ($offsetType instanceof ConstantIntegerType || $offsetType instanceof ConstantStringType) + ) { + /** @var ConstantIntegerType|ConstantStringType $keyType */ + foreach ($this->keyTypes as $i => $keyType) { + if ($keyType->getValue() === $offsetType->getValue()) { + $this->valueTypes[$i] = $valueType; + return; + } + } + + $this->keyTypes[] = $offsetType; + $this->valueTypes[] = $valueType; + + /** @var int|float $newNextAutoIndex */ + $newNextAutoIndex = $offsetType instanceof ConstantIntegerType + ? max($this->nextAutoIndex, $offsetType->getValue() + 1) + : $this->nextAutoIndex; + if (!is_float($newNextAutoIndex)) { + $this->nextAutoIndex = $newNextAutoIndex; + } + return; + } + + $this->keyTypes[] = $offsetType; + $this->valueTypes[] = $valueType; + $this->degradeToGeneralArray = true; + } + + public function getArray(): ArrayType + { + if (!$this->degradeToGeneralArray) { + /** @var array $keyTypes */ + $keyTypes = $this->keyTypes; + return new ConstantArrayType($keyTypes, $this->valueTypes, $this->nextAutoIndex); + } + + return new ArrayType( + TypeCombinator::union(...$this->keyTypes), + TypeCombinator::union(...$this->valueTypes) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Constant/ConstantBooleanType.php b/vendor/phpstan/phpstan/src/Type/Constant/ConstantBooleanType.php new file mode 100644 index 00000000..c0bb6e21 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Constant/ConstantBooleanType.php @@ -0,0 +1,68 @@ +value = $value; + } + + public function getValue(): bool + { + return $this->value; + } + + public function describe(VerbosityLevel $level): string + { + return $this->value ? 'true' : 'false'; + } + + public function toBoolean(): BooleanType + { + return $this; + } + + public function toNumber(): Type + { + return new ConstantIntegerType((int) $this->value); + } + + public function toString(): Type + { + return new ConstantStringType((string) $this->value); + } + + public function toInteger(): Type + { + return new ConstantIntegerType((int) $this->value); + } + + public function toFloat(): Type + { + return new ConstantFloatType((float) $this->value); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['value']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Constant/ConstantFloatType.php b/vendor/phpstan/phpstan/src/Type/Constant/ConstantFloatType.php new file mode 100644 index 00000000..c067574b --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Constant/ConstantFloatType.php @@ -0,0 +1,93 @@ +value = $value; + } + + public function getValue(): float + { + return $this->value; + } + + public function describe(VerbosityLevel $level): string + { + return $level->handle( + static function (): string { + return 'float'; + }, + function (): string { + $formatted = (string) $this->value; + if (strpos($formatted, '.') === false) { + $formatted .= '.0'; + } + + return $formatted; + } + ); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($type instanceof self) { + if (!$this->equals($type)) { + if ($this->describe(VerbosityLevel::value()) === $type->describe(VerbosityLevel::value())) { + return TrinaryLogic::createMaybe(); + } + + return TrinaryLogic::createNo(); + } + + return TrinaryLogic::createYes(); + } + + if ($type instanceof parent) { + return TrinaryLogic::createMaybe(); + } + + if ($type instanceof CompoundType) { + return $type->isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function toString(): Type + { + return new ConstantStringType((string) $this->value); + } + + public function toInteger(): Type + { + return new ConstantIntegerType((int) $this->value); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['value']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Constant/ConstantIntegerType.php b/vendor/phpstan/phpstan/src/Type/Constant/ConstantIntegerType.php new file mode 100644 index 00000000..9deb65c2 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Constant/ConstantIntegerType.php @@ -0,0 +1,61 @@ +value = $value; + } + + public function getValue(): int + { + return $this->value; + } + + public function describe(VerbosityLevel $level): string + { + return $level->handle( + static function (): string { + return 'int'; + }, + function (): string { + return sprintf('%s', $this->value); + } + ); + } + + public function toFloat(): Type + { + return new ConstantFloatType($this->value); + } + + public function toString(): Type + { + return new ConstantStringType((string) $this->value); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['value']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Constant/ConstantScalarToBooleanTrait.php b/vendor/phpstan/phpstan/src/Type/Constant/ConstantScalarToBooleanTrait.php new file mode 100644 index 00000000..4b2e0ff6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Constant/ConstantScalarToBooleanTrait.php @@ -0,0 +1,15 @@ +value); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Constant/ConstantStringType.php b/vendor/phpstan/phpstan/src/Type/Constant/ConstantStringType.php new file mode 100644 index 00000000..e5e580c0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Constant/ConstantStringType.php @@ -0,0 +1,224 @@ +value = $value; + } + + public function getValue(): string + { + return $this->value; + } + + public function describe(VerbosityLevel $level): string + { + return $level->handle( + static function (): string { + return 'string'; + }, + function (): string { + return var_export( + \Nette\Utils\Strings::truncate($this->value, self::DESCRIBE_LIMIT), + true + ); + }, + function (): string { + return var_export($this->value, true); + } + ); + } + + public function isCallable(): TrinaryLogic + { + if ($this->value === '') { + return TrinaryLogic::createNo(); + } + + $broker = Broker::getInstance(); + + // 'my_function' + if ($broker->hasFunction(new Name($this->value), null)) { + return TrinaryLogic::createYes(); + } + + // 'MyClass::myStaticFunction' + $matches = \Nette\Utils\Strings::match($this->value, '#^([a-zA-Z_\\x7f-\\xff\\\\][a-zA-Z0-9_\\x7f-\\xff\\\\]*)::([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)\z#'); + if ($matches !== null) { + if (!$broker->hasClass($matches[1])) { + return TrinaryLogic::createMaybe(); + } + + $classRef = $broker->getClass($matches[1]); + if ($classRef->hasMethod($matches[2])) { + return TrinaryLogic::createYes(); + } + + if (!$classRef->getNativeReflection()->isFinal()) { + return TrinaryLogic::createMaybe(); + } + + return TrinaryLogic::createNo(); + } + + return TrinaryLogic::createNo(); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + $broker = Broker::getInstance(); + + // 'my_function' + $functionName = new Name($this->value); + if ($broker->hasFunction($functionName, null)) { + return $broker->getFunction($functionName, null)->getVariants(); + } + + // 'MyClass::myStaticFunction' + $matches = \Nette\Utils\Strings::match($this->value, '#^([a-zA-Z_\\x7f-\\xff\\\\][a-zA-Z0-9_\\x7f-\\xff\\\\]*)::([a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)\z#'); + if ($matches !== null) { + if (!$broker->hasClass($matches[1])) { + return [new TrivialParametersAcceptor()]; + } + + $classReflection = $broker->getClass($matches[1]); + if ($classReflection->hasMethod($matches[2])) { + $method = $classReflection->getMethod($matches[2], $scope); + if (!$scope->canCallMethod($method)) { + return [new InaccessibleMethod($method)]; + } + + return $method->getVariants(); + } + + if (!$classReflection->getNativeReflection()->isFinal()) { + return [new TrivialParametersAcceptor()]; + } + } + + throw new \PHPStan\ShouldNotHappenException(); + } + + public function toNumber(): Type + { + if (is_numeric($this->value)) { + /** @var mixed $value */ + $value = $this->value; + $value = +$value; + if (is_float($value)) { + return new ConstantFloatType($value); + } + + return new ConstantIntegerType($value); + } + + return new ErrorType(); + } + + public function toInteger(): Type + { + $type = $this->toNumber(); + if ($type instanceof ErrorType) { + return $type; + } + + return $type->toInteger(); + } + + public function toFloat(): Type + { + $type = $this->toNumber(); + if ($type instanceof ErrorType) { + return $type; + } + + return $type->toFloat(); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + if ($offsetType instanceof ConstantIntegerType) { + return TrinaryLogic::createFromBoolean( + $offsetType->getValue() < strlen($this->value) + ); + } + + return parent::hasOffsetValueType($offsetType); + } + + public function getOffsetValueType(Type $offsetType): Type + { + if ($offsetType instanceof ConstantIntegerType) { + if ($offsetType->getValue() < strlen($this->value)) { + return new self($this->value[$offsetType->getValue()]); + } + + return new ErrorType(); + } + + return parent::getOffsetValueType($offsetType); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + $valueStringType = $valueType->toString(); + if ($valueStringType instanceof ErrorType) { + return new ErrorType(); + } + if ( + $offsetType instanceof ConstantIntegerType + && $valueStringType instanceof ConstantStringType + ) { + $value = $this->value; + $value[$offsetType->getValue()] = $valueStringType->getValue(); + + return new self($value); + } + + return parent::setOffsetValueType($offsetType, $valueType); + } + + public function append(self $otherString): self + { + return new self($this->getValue() . $otherString->getValue()); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['value']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/ConstantScalarType.php b/vendor/phpstan/phpstan/src/Type/ConstantScalarType.php new file mode 100644 index 00000000..1e06686e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/ConstantScalarType.php @@ -0,0 +1,13 @@ +phpParser = $phpParser; + $this->phpDocStringResolver = $phpDocStringResolver; + $this->cache = $cache; + $this->anonymousClassNameHelper = $anonymousClassNameHelper; + $this->typeNodeResolver = $typeNodeResolver; + } + + public function getResolvedPhpDoc( + string $fileName, + ?string $className, + ?string $traitName, + string $docComment + ): ResolvedPhpDocBlock + { + if ($className === null && $traitName !== null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $phpDocKey = $this->getPhpDocKey($className, $traitName, $docComment); + $phpDocMap = []; + + if (!isset($this->inProcess[$fileName])) { + $phpDocMap = $this->getResolvedPhpDocMap($fileName); + } + + if (isset($phpDocMap[$phpDocKey])) { + return $phpDocMap[$phpDocKey]; + } + + if (!isset($this->inProcess[$fileName][$phpDocKey])) { // wrong $fileName due to traits + return ResolvedPhpDocBlock::createEmpty(); + } + + if ($this->inProcess[$fileName][$phpDocKey] === false) { // PHPDoc has cyclic dependency + return ResolvedPhpDocBlock::createEmpty(); + } + + if (is_callable($this->inProcess[$fileName][$phpDocKey])) { + $resolveCallback = $this->inProcess[$fileName][$phpDocKey]; + $this->inProcess[$fileName][$phpDocKey] = false; + $this->inProcess[$fileName][$phpDocKey] = $resolveCallback(); + } + + assert($this->inProcess[$fileName][$phpDocKey] instanceof ResolvedPhpDocBlock); + return $this->inProcess[$fileName][$phpDocKey]; + } + + /** + * @param string $fileName + * @return \PHPStan\PhpDoc\ResolvedPhpDocBlock[] + */ + private function getResolvedPhpDocMap(string $fileName): array + { + if (!isset($this->memoryCache[$fileName])) { + $modifiedTime = filemtime($fileName); + if ($modifiedTime === false) { + $modifiedTime = time(); + } + $cacheKey = sprintf('%s-%d-%s', $fileName, $modifiedTime, $this->typeNodeResolver->getCacheKey()); + $map = $this->cache->load($cacheKey); + + if ($map === null) { + $map = $this->createResolvedPhpDocMap($fileName); + $this->cache->save($cacheKey, $map); + } + + $this->memoryCache[$fileName] = $map; + } + + return $this->memoryCache[$fileName]; + } + + /** + * @param string $fileName + * @return \PHPStan\PhpDoc\ResolvedPhpDocBlock[] + */ + private function createResolvedPhpDocMap(string $fileName): array + { + $phpDocMap = $this->createFilePhpDocMap($fileName, null, null); + + try { + $this->inProcess[$fileName] = $phpDocMap; + + foreach ($phpDocMap as $phpDocKey => $resolveCallback) { + $this->inProcess[$fileName][$phpDocKey] = false; + $this->inProcess[$fileName][$phpDocKey] = $data = $resolveCallback(); + $phpDocMap[$phpDocKey] = $data; + } + + } finally { + unset($this->inProcess[$fileName]); + } + + return $phpDocMap; + } + + /** + * @param string $fileName + * @param string|null $lookForTrait + * @param string|null $traitUseClass + * @return callable[] + */ + private function createFilePhpDocMap( + string $fileName, + ?string $lookForTrait, + ?string $traitUseClass + ): array + { + /** @var callable[] $phpDocMap */ + $phpDocMap = []; + + /** @var string[] $classStack */ + $classStack = []; + if ($lookForTrait !== null && $traitUseClass !== null) { + $classStack[] = $traitUseClass; + } + $namespace = null; + $uses = []; + $this->processNodes( + $this->phpParser->parseFile($fileName), + function (\PhpParser\Node $node) use ($fileName, $lookForTrait, &$phpDocMap, &$classStack, &$namespace, &$uses) { + if ($node instanceof Node\Stmt\ClassLike) { + if ($lookForTrait !== null) { + if (!$node instanceof Node\Stmt\Trait_) { + return false; + } + if ((string) $node->namespacedName !== $lookForTrait) { + return false; + } + } else { + if ($node->name === null) { + if (!$node instanceof Node\Stmt\Class_) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $className = $this->anonymousClassNameHelper->getAnonymousClassName( + new Node\Expr\New_($node), + $fileName + ); + } else { + $className = ltrim(sprintf('%s\\%s', $namespace, $node->name->name), '\\'); + } + $classStack[] = $className; + } + } elseif ($node instanceof Node\Stmt\TraitUse) { + foreach ($node->traits as $traitName) { + $traitName = (string) $traitName; + if (!trait_exists($traitName)) { + continue; + } + + $traitReflection = new \ReflectionClass($traitName); + if ($traitReflection->getFileName() === false) { + continue; + } + + $className = $classStack[count($classStack) - 1] ?? null; + if ($className === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $traitPhpDocMap = $this->createFilePhpDocMap( + $traitReflection->getFileName(), + $traitName, + $className + ); + $phpDocMap = array_merge($phpDocMap, $traitPhpDocMap); + } + return; + } elseif ($node instanceof \PhpParser\Node\Stmt\Namespace_) { + $namespace = (string) $node->name; + return; + } elseif ($node instanceof \PhpParser\Node\Stmt\Use_ && $node->type === \PhpParser\Node\Stmt\Use_::TYPE_NORMAL) { + foreach ($node->uses as $use) { + $uses[strtolower($use->getAlias()->name)] = (string) $use->name; + } + return; + } elseif ($node instanceof \PhpParser\Node\Stmt\GroupUse) { + $prefix = (string) $node->prefix; + foreach ($node->uses as $use) { + if ($node->type !== \PhpParser\Node\Stmt\Use_::TYPE_NORMAL && $use->type !== \PhpParser\Node\Stmt\Use_::TYPE_NORMAL) { + continue; + } + + $uses[strtolower($use->getAlias()->name)] = sprintf('%s\\%s', $prefix, (string) $use->name); + } + return; + } elseif (!in_array(get_class($node), [ + Node\Stmt\Property::class, + Node\Stmt\ClassMethod::class, + Node\Stmt\Function_::class, + Node\Stmt\Foreach_::class, + Node\Expr\Assign::class, + Node\Expr\AssignRef::class, + Node\Stmt\Class_::class, + Node\Stmt\ClassConst::class, + ], true)) { + return; + } + + $phpDocString = CommentHelper::getDocComment($node); + if ($phpDocString === null) { + return; + } + + $className = $classStack[count($classStack) - 1] ?? null; + $nameScope = new NameScope($namespace, $uses, $className); + $phpDocKey = $this->getPhpDocKey($className, $lookForTrait, $phpDocString); + $phpDocMap[$phpDocKey] = function () use ($phpDocString, $nameScope): ResolvedPhpDocBlock { + return $this->phpDocStringResolver->resolve($phpDocString, $nameScope); + }; + }, + static function (\PhpParser\Node $node) use ($lookForTrait, &$namespace, &$classStack, &$uses): void { + if ($node instanceof Node\Stmt\ClassLike && $lookForTrait === null) { + if (count($classStack) === 0) { + throw new \PHPStan\ShouldNotHappenException(); + } + array_pop($classStack); + } elseif ($node instanceof \PhpParser\Node\Stmt\Namespace_) { + $namespace = null; + $uses = []; + } + } + ); + + return $phpDocMap; + } + + /** + * @param \PhpParser\Node[]|\PhpParser\Node|scalar $node + * @param \Closure(\PhpParser\Node $node): mixed $nodeCallback + * @param \Closure(\PhpParser\Node $node): void $endNodeCallback + */ + private function processNodes($node, \Closure $nodeCallback, \Closure $endNodeCallback): void + { + if ($node instanceof Node) { + $callbackResult = $nodeCallback($node); + if ($callbackResult === false) { + return; + } + foreach ($node->getSubNodeNames() as $subNodeName) { + $subNode = $node->{$subNodeName}; + $this->processNodes($subNode, $nodeCallback, $endNodeCallback); + } + $endNodeCallback($node); + } elseif (is_array($node)) { + foreach ($node as $subNode) { + $this->processNodes($subNode, $nodeCallback, $endNodeCallback); + } + } + } + + private function getPhpDocKey( + ?string $class, + ?string $trait, + string $docComment + ): string + { + $docComment = \Nette\Utils\Strings::replace($docComment, '#\s+#', ' '); + + return md5(sprintf('%s-%s-%s', $class, $trait, $docComment)); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/FloatType.php b/vendor/phpstan/phpstan/src/Type/FloatType.php new file mode 100644 index 00000000..32eeda0e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/FloatType.php @@ -0,0 +1,126 @@ +isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $type instanceof self; + } + + public function describe(VerbosityLevel $level): string + { + return 'float'; + } + + public function toNumber(): Type + { + return $this; + } + + public function toFloat(): Type + { + return $this; + } + + public function toInteger(): Type + { + return new IntegerType(); + } + + public function toString(): Type + { + return new StringType(); + } + + public function toArray(): Type + { + return new ConstantArrayType( + [new ConstantIntegerType(0)], + [$this], + 1 + ); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function getOffsetValueType(Type $offsetType): Type + { + return new NullType(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return new ErrorType(); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/FunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/FunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..d9bbd6c0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/FunctionTypeSpecifyingExtension.php @@ -0,0 +1,18 @@ +types = UnionTypeHelper::sortTypes($types); + } + + /** + * @return Type[] + */ + public function getTypes(): array + { + return $this->types; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return UnionTypeHelper::getReferencedClasses($this->types); + } + + public function accepts(Type $otherType, bool $strictTypes): TrinaryLogic + { + foreach ($this->types as $type) { + if (!$type->accepts($otherType, $strictTypes)->yes()) { + return TrinaryLogic::createNo(); + } + } + + return TrinaryLogic::createYes(); + } + + public function isSuperTypeOf(Type $otherType): TrinaryLogic + { + $results = []; + foreach ($this->getTypes() as $innerType) { + $results[] = $innerType->isSuperTypeOf($otherType); + } + + return TrinaryLogic::createYes()->and(...$results); + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof self || $otherType instanceof UnionType) { + return $otherType->isSuperTypeOf($this); + } + + $results = []; + foreach ($this->getTypes() as $innerType) { + $results[] = $otherType->isSuperTypeOf($innerType); + } + + return TrinaryLogic::maxMin(...$results); + } + + public function equals(Type $type): bool + { + if (!$type instanceof self) { + return false; + } + + if (count($this->types) !== count($type->types)) { + return false; + } + + foreach ($this->types as $i => $innerType) { + if (!$innerType->equals($type->types[$i])) { + return false; + } + } + + return true; + } + + public function describe(VerbosityLevel $level): string + { + return $level->handle( + function () use ($level): string { + $typeNames = []; + foreach ($this->types as $type) { + if ($type instanceof AccessoryType) { + continue; + } + $typeNames[] = TypeUtils::generalizeType($type)->describe($level); + } + + return implode('&', $typeNames); + }, + function () use ($level): string { + $typeNames = []; + foreach ($this->types as $type) { + if ($type instanceof AccessoryType) { + continue; + } + $typeNames[] = $type->describe($level); + } + + return implode('&', $typeNames); + }, + function () use ($level): string { + $typeNames = []; + foreach ($this->types as $type) { + $typeNames[] = $type->describe($level); + } + + return implode('&', $typeNames); + } + ); + } + + public function canAccessProperties(): TrinaryLogic + { + return $this->intersectResults(static function (Type $type): TrinaryLogic { + return $type->canAccessProperties(); + }); + } + + public function hasProperty(string $propertyName): TrinaryLogic + { + return $this->intersectResults(static function (Type $type) use ($propertyName): TrinaryLogic { + return $type->hasProperty($propertyName); + }); + } + + public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection + { + foreach ($this->types as $type) { + if ($type->hasProperty($propertyName)->yes()) { + return $type->getProperty($propertyName, $scope); + } + } + + throw new \PHPStan\ShouldNotHappenException(); + } + + public function canCallMethods(): TrinaryLogic + { + return $this->intersectResults(static function (Type $type): TrinaryLogic { + return $type->canCallMethods(); + }); + } + + public function hasMethod(string $methodName): TrinaryLogic + { + return $this->intersectResults(static function (Type $type) use ($methodName): TrinaryLogic { + return $type->hasMethod($methodName); + }); + } + + public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection + { + foreach ($this->types as $type) { + if ($type->hasMethod($methodName)->yes()) { + return $type->getMethod($methodName, $scope); + } + } + + throw new \PHPStan\ShouldNotHappenException(); + } + + public function canAccessConstants(): TrinaryLogic + { + return $this->intersectResults(static function (Type $type): TrinaryLogic { + return $type->canAccessConstants(); + }); + } + + public function hasConstant(string $constantName): TrinaryLogic + { + return $this->intersectResults(static function (Type $type) use ($constantName): TrinaryLogic { + return $type->hasConstant($constantName); + }); + } + + public function getConstant(string $constantName): ConstantReflection + { + foreach ($this->types as $type) { + if ($type->hasConstant($constantName)->yes()) { + return $type->getConstant($constantName); + } + } + + throw new \PHPStan\ShouldNotHappenException(); + } + + public function isIterable(): TrinaryLogic + { + return $this->intersectResults(static function (Type $type): TrinaryLogic { + return $type->isIterable(); + }); + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return $this->intersectResults(static function (Type $type): TrinaryLogic { + return $type->isIterableAtLeastOnce(); + }); + } + + public function getIterableKeyType(): Type + { + return $this->intersectTypes(static function (Type $type): Type { + return $type->getIterableKeyType(); + }); + } + + public function getIterableValueType(): Type + { + return $this->intersectTypes(static function (Type $type): Type { + return $type->getIterableValueType(); + }); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return $this->intersectResults(static function (Type $type): TrinaryLogic { + return $type->isOffsetAccessible(); + }); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + return $this->intersectResults(static function (Type $type) use ($offsetType): TrinaryLogic { + return $type->hasOffsetValueType($offsetType); + }); + } + + public function getOffsetValueType(Type $offsetType): Type + { + return $this->intersectTypes(static function (Type $type) use ($offsetType): Type { + return $type->getOffsetValueType($offsetType); + }); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return $this->intersectTypes(static function (Type $type) use ($offsetType, $valueType): Type { + return $type->setOffsetValueType($offsetType, $valueType); + }); + } + + public function isCallable(): TrinaryLogic + { + return $this->intersectResults(static function (Type $type): TrinaryLogic { + return $type->isCallable(); + }); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + if ($this->isCallable()->no()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return [new TrivialParametersAcceptor()]; + } + + public function isCloneable(): TrinaryLogic + { + return $this->intersectResults(static function (Type $type): TrinaryLogic { + return $type->isCloneable(); + }); + } + + public function toBoolean(): BooleanType + { + /** @var BooleanType $type */ + $type = $this->intersectTypes(static function (Type $type): BooleanType { + return $type->toBoolean(); + }); + + return $type; + } + + public function toNumber(): Type + { + $type = $this->intersectTypes(static function (Type $type): Type { + return $type->toNumber(); + }); + + return $type; + } + + public function toString(): Type + { + $type = $this->intersectTypes(static function (Type $type): Type { + return $type->toString(); + }); + + return $type; + } + + public function toInteger(): Type + { + $type = $this->intersectTypes(static function (Type $type): Type { + return $type->toInteger(); + }); + + return $type; + } + + public function toFloat(): Type + { + $type = $this->intersectTypes(static function (Type $type): Type { + return $type->toFloat(); + }); + + return $type; + } + + public function toArray(): Type + { + $type = $this->intersectTypes(static function (Type $type): Type { + return $type->toArray(); + }); + + return $type; + } + + public function resolveStatic(string $className): Type + { + return new self(UnionTypeHelper::resolveStatic($className, $this->getTypes())); + } + + public function changeBaseClass(string $className): StaticResolvableType + { + return new self(UnionTypeHelper::changeBaseClass($className, $this->getTypes())); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['types']); + } + + /** + * @param callable(Type $type): TrinaryLogic $getResult + * @return TrinaryLogic + */ + private function intersectResults(callable $getResult): TrinaryLogic + { + $operands = array_map($getResult, $this->types); + return TrinaryLogic::maxMin(...$operands); + } + + /** + * @param callable(Type $type): Type $getType + * @return Type + */ + private function intersectTypes(callable $getType): Type + { + $operands = array_map($getType, $this->types); + return TypeCombinator::intersect(...$operands); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/IterableType.php b/vendor/phpstan/phpstan/src/Type/IterableType.php new file mode 100644 index 00000000..a7d82fa0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/IterableType.php @@ -0,0 +1,197 @@ +keyType = $keyType; + $this->itemType = $itemType; + } + + public function getItemType(): Type + { + return $this->itemType; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return array_merge( + $this->keyType->getReferencedClasses(), + $this->getItemType()->getReferencedClasses() + ); + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + if ($type->isIterable()->yes()) { + return $this->getIterableValueType()->accepts($type->getIterableValueType(), $strictTypes) + ->and($this->getIterableKeyType()->accepts($type->getIterableKeyType(), $strictTypes)); + } + + return TrinaryLogic::createNo(); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + return $type->isIterable() + ->and($this->getIterableValueType()->isSuperTypeOf($type->getIterableValueType())) + ->and($this->getIterableKeyType()->isSuperTypeOf($type->getIterableKeyType())); + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof IntersectionType || $otherType instanceof UnionType) { + return $otherType->isSuperTypeOf(new UnionType([ + new ArrayType($this->keyType, $this->itemType), + new IntersectionType([ + new ObjectType(\Traversable::class), + $this, + ]), + ])); + } + + if ($otherType instanceof self) { + $limit = TrinaryLogic::createYes(); + } else { + $limit = TrinaryLogic::createMaybe(); + } + + return $limit->and( + $otherType->isIterable(), + $otherType->getIterableValueType()->isSuperTypeOf($this->itemType), + $otherType->getIterableKeyType()->isSuperTypeOf($this->keyType) + ); + } + + public function equals(Type $type): bool + { + if (!$type instanceof self) { + return false; + } + + return $this->keyType->equals($type->keyType) + && $this->itemType->equals($type->itemType); + } + + public function describe(VerbosityLevel $level): string + { + if ($this->keyType instanceof MixedType) { + if ($this->itemType instanceof MixedType) { + return 'iterable'; + } + + return sprintf('iterable<%s>', $this->itemType->describe($level)); + } + + return sprintf('iterable<%s, %s>', $this->keyType->describe($level), $this->itemType->describe($level)); + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toString(): Type + { + return new ErrorType(); + } + + public function toInteger(): Type + { + return new ErrorType(); + } + + public function toFloat(): Type + { + return new ErrorType(); + } + + public function toArray(): Type + { + return new ArrayType($this->keyType, $this->getItemType()); + } + + public function resolveStatic(string $className): Type + { + if ($this->getItemType() instanceof StaticResolvableType) { + return new self( + $this->keyType, + $this->getItemType()->resolveStatic($className) + ); + } + + return $this; + } + + public function changeBaseClass(string $className): StaticResolvableType + { + if ($this->getItemType() instanceof StaticResolvableType) { + return new self( + $this->keyType, + $this->getItemType()->changeBaseClass($className) + ); + } + + return $this; + } + + public function isIterable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return TrinaryLogic::createMaybe(); + } + + public function getIterableKeyType(): Type + { + return $this->keyType; + } + + public function getIterableValueType(): Type + { + return $this->getItemType(); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['keyType'], $properties['itemType']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/JustNullableTypeTrait.php b/vendor/phpstan/phpstan/src/Type/JustNullableTypeTrait.php new file mode 100644 index 00000000..ca6786b1 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/JustNullableTypeTrait.php @@ -0,0 +1,49 @@ +isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $type instanceof self; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/MethodTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/MethodTypeSpecifyingExtension.php new file mode 100644 index 00000000..2776d8db --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/MethodTypeSpecifyingExtension.php @@ -0,0 +1,20 @@ +isExplicitMixed = $isExplicitMixed; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return []; + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return new MixedType(); + } + + public function equals(Type $type): bool + { + return $type instanceof self; + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof self) { + return TrinaryLogic::createYes(); + } + + return TrinaryLogic::createMaybe(); + } + + public function canAccessProperties(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasProperty(string $propertyName): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection + { + return new DummyPropertyReflection(); + } + + public function canCallMethods(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasMethod(string $methodName): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection + { + return new DummyMethodReflection($methodName); + } + + public function canAccessConstants(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasConstant(string $constantName): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function getConstant(string $constantName): ConstantReflection + { + return new DummyConstantReflection($constantName); + } + + public function isCloneable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function describe(VerbosityLevel $level): string + { + return 'mixed'; + } + + public function toNumber(): Type + { + return new UnionType([ + $this->toInteger(), + $this->toFloat(), + ]); + } + + public function toInteger(): Type + { + return new IntegerType(); + } + + public function toFloat(): Type + { + return new FloatType(); + } + + public function toString(): Type + { + return new StringType(); + } + + public function toArray(): Type + { + return new ArrayType(new MixedType(), new MixedType()); + } + + public function isExplicitMixed(): bool + { + return $this->isExplicitMixed; + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['isExplicitMixed']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/NeverType.php b/vendor/phpstan/phpstan/src/Type/NeverType.php new file mode 100644 index 00000000..3b909ef5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/NeverType.php @@ -0,0 +1,193 @@ +isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $type instanceof self; + } + + public function describe(VerbosityLevel $level): string + { + return 'null'; + } + + public function toNumber(): Type + { + return new ConstantIntegerType(0); + } + + public function toString(): Type + { + return new ConstantStringType(''); + } + + public function toInteger(): Type + { + return $this->toNumber(); + } + + public function toFloat(): Type + { + return $this->toNumber()->toFloat(); + } + + public function toArray(): Type + { + return new ConstantArrayType([], []); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function getOffsetValueType(Type $offsetType): Type + { + return new NullType(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + $array = new ConstantArrayType([], []); + return $array->setOffsetValueType($offsetType, $valueType); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/ObjectType.php b/vendor/phpstan/phpstan/src/Type/ObjectType.php new file mode 100644 index 00000000..6105caf6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/ObjectType.php @@ -0,0 +1,605 @@ + true, + 'DOMNodeList' => true, + ]; + + /** @var string */ + private $className; + + public function __construct(string $className) + { + $this->className = $className; + } + + public function getClassName(): string + { + return $this->className; + } + + public function hasProperty(string $propertyName): TrinaryLogic + { + $broker = Broker::getInstance(); + if (!$broker->hasClass($this->className)) { + return TrinaryLogic::createMaybe(); + } + + $classReflection = $broker->getClass($this->className); + if ($classReflection->hasProperty($propertyName)) { + return TrinaryLogic::createYes(); + } + + if ($classReflection->isFinal()) { + return TrinaryLogic::createNo(); + } + + return TrinaryLogic::createMaybe(); + } + + public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection + { + $broker = Broker::getInstance(); + return $broker->getClass($this->className)->getProperty($propertyName, $scope); + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return [$this->className]; + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof StaticType) { + return $this->checkSubclassAcceptability($type->getBaseClass()); + } + + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + if ($type instanceof ClosureType) { + return $this->isInstanceOf(\Closure::class); + } + + if ( + $this->isInstanceOf('SimpleXMLElement')->yes() + && $type->isSuperTypeOf($this)->no() + ) { + return (new UnionType([ + new IntegerType(), + new FloatType(), + new StringType(), + new BooleanType(), + ]))->accepts($type, $strictTypes); + } + + if (!$type instanceof TypeWithClassName) { + return TrinaryLogic::createNo(); + } + + return $this->checkSubclassAcceptability($type->getClassName()); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($type instanceof CompoundType) { + return $type->isSubTypeOf($this); + } + + if ($type instanceof ObjectWithoutClassType) { + return TrinaryLogic::createMaybe(); + } + + if ($type instanceof ClosureType) { + return $this->isInstanceOf(\Closure::class); + } + + if (!$type instanceof TypeWithClassName) { + return TrinaryLogic::createNo(); + } + + $thisClassName = $this->className; + $thatClassName = $type->getClassName(); + + if ($thatClassName === $thisClassName) { + return TrinaryLogic::createYes(); + } + + $broker = Broker::getInstance(); + + if (!$broker->hasClass($thisClassName) || !$broker->hasClass($thatClassName)) { + return TrinaryLogic::createMaybe(); + } + + $thisClassReflection = $broker->getClass($thisClassName); + $thatClassReflection = $broker->getClass($thatClassName); + + if ($thisClassReflection->getName() === $thatClassReflection->getName()) { + return TrinaryLogic::createYes(); + } + + if ($thatClassReflection->isSubclassOf($thisClassName)) { + return TrinaryLogic::createYes(); + } + + if ($thisClassReflection->isSubclassOf($thatClassName)) { + return TrinaryLogic::createMaybe(); + } + + if ($thisClassReflection->isInterface() && !$thatClassReflection->getNativeReflection()->isFinal()) { + return TrinaryLogic::createMaybe(); + } + + if ($thatClassReflection->isInterface() && !$thisClassReflection->getNativeReflection()->isFinal()) { + return TrinaryLogic::createMaybe(); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $type instanceof self && $this->className === $type->className; + } + + private function checkSubclassAcceptability(string $thatClass): TrinaryLogic + { + if ($this->className === $thatClass) { + return TrinaryLogic::createYes(); + } + + $broker = Broker::getInstance(); + + if (!$broker->hasClass($this->className) || !$broker->hasClass($thatClass)) { + return TrinaryLogic::createNo(); + } + + $thisReflection = $broker->getClass($this->className); + $thatReflection = $broker->getClass($thatClass); + + if ($thisReflection->getName() === $thatReflection->getName()) { + // class alias + return TrinaryLogic::createYes(); + } + + if ($thisReflection->isInterface() && $thatReflection->isInterface()) { + return TrinaryLogic::createFromBoolean( + $thatReflection->getNativeReflection()->implementsInterface($this->className) + ); + } + + return TrinaryLogic::createFromBoolean( + $thatReflection->isSubclassOf($this->className) + ); + } + + public function describe(VerbosityLevel $level): string + { + return $level->handle( + function (): string { + $broker = Broker::getInstance(); + if (!$broker->hasClass($this->className)) { + return $this->className; + } + + return $broker->getClass($this->className)->getDisplayName(); + }, + function (): string { + return $this->className; + } + ); + } + + public function toNumber(): Type + { + if ($this->isInstanceOf('SimpleXMLElement')->yes()) { + return new UnionType([ + new FloatType(), + new IntegerType(), + ]); + } + + return new ErrorType(); + } + + public function toInteger(): Type + { + if ($this->isInstanceOf('SimpleXMLElement')->yes()) { + return new IntegerType(); + } + + return new ErrorType(); + } + + public function toFloat(): Type + { + if ($this->isInstanceOf('SimpleXMLElement')->yes()) { + return new FloatType(); + } + return new ErrorType(); + } + + public function toString(): Type + { + $broker = Broker::getInstance(); + if (!$broker->hasClass($this->className)) { + return new ErrorType(); + } + + $classReflection = $broker->getClass($this->className); + if ($classReflection->hasNativeMethod('__toString')) { + return new StringType(); + } + + return new ErrorType(); + } + + public function toArray(): Type + { + $broker = Broker::getInstance(); + if (!$broker->hasClass($this->className)) { + return new ArrayType(new MixedType(), new MixedType()); + } + + $classReflection = $broker->getClass($this->className); + if ( + !$classReflection->getNativeReflection()->isUserDefined() + || UniversalObjectCratesClassReflectionExtension::isUniversalObjectCrate( + $broker, + $broker->getUniversalObjectCratesClasses(), + $classReflection + ) + ) { + return new ArrayType(new MixedType(), new MixedType()); + } + $arrayKeys = []; + $arrayValues = []; + + do { + foreach ($classReflection->getNativeReflection()->getProperties() as $nativeProperty) { + if ($nativeProperty->isStatic()) { + continue; + } + + $declaringClass = $broker->getClass($nativeProperty->getDeclaringClass()->getName()); + $property = $declaringClass->getNativeProperty($nativeProperty->getName()); + + $keyName = $nativeProperty->getName(); + if ($nativeProperty->isPrivate()) { + $keyName = sprintf( + "\0%s\0%s", + $declaringClass->getName(), + $keyName + ); + } elseif ($nativeProperty->isProtected()) { + $keyName = sprintf( + "\0*\0%s", + $keyName + ); + } + + $arrayKeys[] = new ConstantStringType($keyName); + $arrayValues[] = $property->getType(); + } + + $classReflection = $classReflection->getParentClass(); + } while ($classReflection !== false); + + return new ConstantArrayType($arrayKeys, $arrayValues); + } + + public function canAccessProperties(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function canCallMethods(): TrinaryLogic + { + if (strtolower($this->className) === 'stdclass') { + return TrinaryLogic::createNo(); + } + + return TrinaryLogic::createYes(); + } + + public function hasMethod(string $methodName): TrinaryLogic + { + $broker = Broker::getInstance(); + if (!$broker->hasClass($this->className)) { + return TrinaryLogic::createMaybe(); + } + + $classReflection = $broker->getClass($this->className); + if ($classReflection->hasMethod($methodName)) { + return TrinaryLogic::createYes(); + } + + if ($classReflection->isFinal()) { + return TrinaryLogic::createNo(); + } + + return TrinaryLogic::createMaybe(); + } + + public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection + { + $broker = Broker::getInstance(); + return $broker->getClass($this->className)->getMethod($methodName, $scope); + } + + public function canAccessConstants(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function hasConstant(string $constantName): TrinaryLogic + { + $broker = Broker::getInstance(); + if (!$broker->hasClass($this->className)) { + return TrinaryLogic::createNo(); + } + + return TrinaryLogic::createFromBoolean( + $broker->getClass($this->className)->hasConstant($constantName) + ); + } + + public function getConstant(string $constantName): ConstantReflection + { + $broker = Broker::getInstance(); + return $broker->getClass($this->className)->getConstant($constantName); + } + + public function isIterable(): TrinaryLogic + { + return $this->isInstanceOf(\Traversable::class); + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return $this->isInstanceOf(\Traversable::class) + ->and(TrinaryLogic::createMaybe()); + } + + public function getIterableKeyType(): Type + { + $broker = Broker::getInstance(); + + if (!$broker->hasClass($this->className)) { + return new ErrorType(); + } + + $classReflection = $broker->getClass($this->className); + + if ($this->isInstanceOf(\Iterator::class)->yes()) { + return ParametersAcceptorSelector::selectSingle($classReflection->getNativeMethod('key')->getVariants())->getReturnType(); + } + + if ($this->isInstanceOf(\IteratorAggregate::class)->yes()) { + return RecursionGuard::run($this, static function () use ($classReflection) { + return ParametersAcceptorSelector::selectSingle( + $classReflection->getNativeMethod('getIterator')->getVariants() + )->getReturnType()->getIterableKeyType(); + }); + } + + if ($this->isInstanceOf(\Traversable::class)->yes()) { + return new MixedType(); + } + + return new ErrorType(); + } + + public function getIterableValueType(): Type + { + $broker = Broker::getInstance(); + + if (!$broker->hasClass($this->className)) { + return new ErrorType(); + } + + $classReflection = $broker->getClass($this->className); + + if ($this->isInstanceOf(\Iterator::class)->yes()) { + return ParametersAcceptorSelector::selectSingle( + $classReflection->getNativeMethod('current')->getVariants() + )->getReturnType(); + } + + if ($this->isInstanceOf(\IteratorAggregate::class)->yes()) { + return RecursionGuard::run($this, static function () use ($classReflection) { + return ParametersAcceptorSelector::selectSingle( + $classReflection->getNativeMethod('getIterator')->getVariants() + )->getReturnType()->getIterableValueType(); + }); + } + + if ($this->isInstanceOf(\Traversable::class)->yes()) { + return new MixedType(); + } + + return new ErrorType(); + } + + private function isExtraOffsetAccessibleClass(): TrinaryLogic + { + $broker = Broker::getInstance(); + if (!$broker->hasClass($this->className)) { + return TrinaryLogic::createMaybe(); + } + + $classReflection = $broker->getClass($this->className); + + if (array_key_exists($classReflection->getName(), self::EXTRA_OFFSET_CLASSES)) { + return TrinaryLogic::createYes(); + } + + return TrinaryLogic::createNo(); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return $this->isInstanceOf(\ArrayAccess::class)->or( + $this->isExtraOffsetAccessibleClass() + ); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + $broker = Broker::getInstance(); + if (!$broker->hasClass($this->className)) { + return TrinaryLogic::createNo(); + } + + return $this->isExtraOffsetAccessibleClass() + ->or($this->isInstanceOf(\ArrayAccess::class)); + } + + public function getOffsetValueType(Type $offsetType): Type + { + $broker = Broker::getInstance(); + + if (!$broker->hasClass($this->className)) { + return new ErrorType(); + } + + if (!$this->isExtraOffsetAccessibleClass()->no()) { + return new MixedType(); + } + + if ($this->isInstanceOf(\ArrayAccess::class)->yes()) { + $classReflection = $broker->getClass($this->className); + return RecursionGuard::run($this, static function () use ($classReflection) { + return ParametersAcceptorSelector::selectSingle($classReflection->getNativeMethod('offsetGet')->getVariants())->getReturnType(); + }); + } + + return new ErrorType(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + if ($this->isOffsetAccessible()->no()) { + return new ErrorType(); + } + + // in the future we may return intersection of $this and OffsetAccessibleType() + return $this; + } + + public function isCallable(): TrinaryLogic + { + $parametersAcceptors = $this->findCallableParametersAcceptors(); + if ($parametersAcceptors === null) { + return TrinaryLogic::createNo(); + } + + if ( + count($parametersAcceptors) === 1 + && $parametersAcceptors[0] instanceof TrivialParametersAcceptor + ) { + return TrinaryLogic::createMaybe(); + } + + return TrinaryLogic::createYes(); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + if ($this->className === \Closure::class) { + return [new TrivialParametersAcceptor()]; + } + $parametersAcceptors = $this->findCallableParametersAcceptors(); + if ($parametersAcceptors === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $parametersAcceptors; + } + + /** + * @return \PHPStan\Reflection\ParametersAcceptor[]|null + */ + private function findCallableParametersAcceptors(): ?array + { + $broker = Broker::getInstance(); + + if (!$broker->hasClass($this->className)) { + return [new TrivialParametersAcceptor()]; + } + + $classReflection = $broker->getClass($this->className); + if ($classReflection->hasNativeMethod('__invoke')) { + return $classReflection->getNativeMethod('__invoke')->getVariants(); + } + + if (!$classReflection->getNativeReflection()->isFinal()) { + return [new TrivialParametersAcceptor()]; + } + + return null; + } + + public function isCloneable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['className']); + } + + public function isInstanceOf(string $className): TrinaryLogic + { + $broker = Broker::getInstance(); + + if (!$broker->hasClass($this->className)) { + return TrinaryLogic::createMaybe(); + } + + $classReflection = $broker->getClass($this->className); + if ($classReflection->isSubclassOf($className) || $classReflection->getName() === $className) { + return TrinaryLogic::createYes(); + } + + if ($classReflection->isInterface()) { + return TrinaryLogic::createMaybe(); + } + + return TrinaryLogic::createNo(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/ObjectWithoutClassType.php b/vendor/phpstan/phpstan/src/Type/ObjectWithoutClassType.php new file mode 100644 index 00000000..908ec7ed --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/ObjectWithoutClassType.php @@ -0,0 +1,68 @@ +isSubTypeOf($this); + } + + if ($type instanceof self || $type instanceof TypeWithClassName) { + return TrinaryLogic::createYes(); + } + + if ($type instanceof ClosureType) { + return TrinaryLogic::createYes(); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $type instanceof self; + } + + public function describe(VerbosityLevel $level): string + { + return 'object'; + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php new file mode 100644 index 00000000..7f7dc103 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php @@ -0,0 +1,67 @@ + 0, + 'array_reverse' => 0, + 'array_change_key_case' => 0, + 'array_diff_assoc' => 0, + 'array_diff_key' => 0, + 'array_diff_uassoc' => 0, + 'array_diff_ukey' => 0, + 'array_diff' => 0, + 'array_udiff_assoc' => 0, + 'array_udiff_uassoc' => 0, + 'array_udiff' => 0, + 'array_intersect_assoc' => 0, + 'array_intersect_key' => 0, + 'array_intersect_uassoc' => 0, + 'array_intersect_ukey' => 0, + 'array_intersect' => 0, + 'array_uintersect_assoc' => 0, + 'array_uintersect_uassoc' => 0, + 'array_uintersect' => 0, + ]; + + public function isFunctionSupported(FunctionReflection $functionReflection): bool + { + return isset($this->functionNames[$functionReflection->getName()]); + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $argumentPosition = $this->functionNames[$functionReflection->getName()]; + + if (!isset($functionCall->args[$argumentPosition])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $argument = $functionCall->args[$argumentPosition]; + $argumentType = $scope->getType($argument->value); + $argumentKeyType = $argumentType->getIterableKeyType(); + $argumentValueType = $argumentType->getIterableValueType(); + if ($argument->unpack) { + $argumentKeyType = TypeUtils::generalizeType($argumentKeyType); + $argumentValueType = TypeUtils::generalizeType($argumentValueType->getIterableValueType()); + } + + return new ArrayType( + $argumentKeyType, + $argumentValueType + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayFillFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayFillFunctionReturnTypeExtension.php new file mode 100644 index 00000000..e86486e7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayFillFunctionReturnTypeExtension.php @@ -0,0 +1,57 @@ +getName() === 'array_fill'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (count($functionCall->args) < 3) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $valueType = $scope->getType($functionCall->args[2]->value); + $startIndexType = $scope->getType($functionCall->args[0]->value); + if (!$startIndexType instanceof ConstantIntegerType) { + return new ArrayType(new IntegerType(), $valueType); + } + + $numberType = $scope->getType($functionCall->args[1]->value); + if (!$numberType instanceof ConstantIntegerType) { + return new ArrayType(new IntegerType(), $valueType); + } + + $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); + $nextIndex = $startIndexType->getValue(); + for ($i = 0; $i < $numberType->getValue(); $i++) { + $arrayBuilder->setOffsetValueType( + new ConstantIntegerType($nextIndex), + $valueType + ); + if ($nextIndex < 0) { + $nextIndex = 0; + } else { + $nextIndex++; + } + } + + return $arrayBuilder->getArray(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayFillKeysFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayFillKeysFunctionReturnTypeExtension.php new file mode 100644 index 00000000..28ffedb1 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayFillKeysFunctionReturnTypeExtension.php @@ -0,0 +1,48 @@ +getName() === 'array_fill_keys'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (count($functionCall->args) < 2) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $valueType = $scope->getType($functionCall->args[1]->value); + $keysType = $scope->getType($functionCall->args[0]->value); + $constantArrays = TypeUtils::getConstantArrays($keysType); + if (count($constantArrays) === 0) { + return new ArrayType($keysType->getIterableValueType(), $valueType); + } + + $arrayTypes = []; + foreach ($constantArrays as $constantArray) { + $arrayBuilder = ConstantArrayTypeBuilder::createEmpty(); + foreach ($constantArray->getValueTypes() as $keyType) { + $arrayBuilder->setOffsetValueType($keyType, $valueType); + } + $arrayTypes[] = $arrayBuilder->getArray(); + } + + return TypeCombinator::union(...$arrayTypes); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayFilterFunctionReturnTypeReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayFilterFunctionReturnTypeReturnTypeExtension.php new file mode 100644 index 00000000..50078340 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayFilterFunctionReturnTypeReturnTypeExtension.php @@ -0,0 +1,125 @@ +getName() === 'array_filter'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $arrayArg = $functionCall->args[0]->value ?? null; + $callbackArg = $functionCall->args[1]->value ?? null; + $flagArg = $functionCall->args[2]->value ?? null; + + if ($arrayArg !== null) { + $arrayArgType = $scope->getType($arrayArg); + $keyType = $arrayArgType->getIterableKeyType(); + $itemType = $arrayArgType->getIterableValueType(); + + if ($arrayArgType instanceof MixedType) { + return new BenevolentUnionType([ + new ArrayType(new MixedType(), new MixedType()), + new NullType(), + ]); + } + + if ($callbackArg === null) { + return TypeCombinator::union( + ...array_map([$this, 'removeFalsey'], TypeUtils::getArrays($arrayArgType)) + ); + } + + if ($flagArg === null && $callbackArg instanceof Closure && count($callbackArg->stmts) === 1) { + $statement = $callbackArg->stmts[0]; + if ($statement instanceof Return_ && $statement->expr !== null && count($callbackArg->params) > 0) { + if (!$callbackArg->params[0]->var instanceof Variable || !is_string($callbackArg->params[0]->var->name)) { + throw new \PHPStan\ShouldNotHappenException(); + } + $itemVariableName = $callbackArg->params[0]->var->name; + $scope = $scope->assignVariable($itemVariableName, $itemType, TrinaryLogic::createYes()); + $scope = $scope->filterByTruthyValue($statement->expr); + $itemType = $scope->getVariableType($itemVariableName); + } + } + + } else { + $keyType = new MixedType(); + $itemType = new MixedType(); + } + + return new ArrayType($keyType, $itemType); + } + + public function removeFalsey(Type $type): Type + { + $falseyTypes = new UnionType([ + new NullType(), + new ConstantBooleanType(false), + new ConstantIntegerType(0), + new ConstantFloatType(0.0), + new ConstantStringType(''), + new ConstantArrayType([], []), + ]); + + if ($type instanceof ConstantArrayType) { + $keys = $type->getKeyTypes(); + $values = $type->getValueTypes(); + + $generalize = false; + + foreach ($values as $offset => $value) { + $isFalsey = $falseyTypes->isSuperTypeOf($value); + + if ($isFalsey->yes()) { + unset($keys[$offset], $values[$offset]); + } elseif ($isFalsey->maybe()) { + $values[$offset] = TypeCombinator::remove($values[$offset], $falseyTypes); + $generalize = true; + } + } + + $filteredArray = new ConstantArrayType(array_values($keys), array_values($values)); + + return $generalize ? $filteredArray->generalize() : $filteredArray; + } + + $keyType = $type->getIterableKeyType(); + $valueType = $type->getIterableValueType(); + + $valueType = TypeCombinator::remove($valueType, $falseyTypes); + + if ($valueType instanceof NeverType) { + return new ConstantArrayType([], []); + } + + return new ArrayType($keyType, $valueType); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyDynamicReturnTypeExtension.php new file mode 100644 index 00000000..08cb3013 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyDynamicReturnTypeExtension.php @@ -0,0 +1,41 @@ +getName() === 'key'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (!isset($functionCall->args[0])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $argType = $scope->getType($functionCall->args[0]->value); + $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); + if ($iterableAtLeastOnce->no()) { + return new NullType(); + } + + $keyType = $argType->getIterableKeyType(); + if ($iterableAtLeastOnce->yes()) { + return $keyType; + } + + return TypeCombinator::union($keyType, new NullType()); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyExistsFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyExistsFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..d2612221 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyExistsFunctionTypeSpecifyingExtension.php @@ -0,0 +1,59 @@ +typeSpecifier = $typeSpecifier; + } + + public function isFunctionSupported( + FunctionReflection $functionReflection, + FuncCall $node, + TypeSpecifierContext $context + ): bool + { + return $functionReflection->getName() === 'array_key_exists' + && count($node->args) >= 2 + && !$context->null(); + } + + public function specifyTypes( + FunctionReflection $functionReflection, + FuncCall $node, + Scope $scope, + TypeSpecifierContext $context + ): SpecifiedTypes + { + $keyType = $scope->getType($node->args[0]->value); + + return $this->typeSpecifier->create( + $node->args[1]->value, + TypeCombinator::intersect( + new ArrayType(new MixedType(), new MixedType()), + new HasOffsetType($keyType) + ), + $context + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyFirstDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyFirstDynamicReturnTypeExtension.php new file mode 100644 index 00000000..c868e7a3 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyFirstDynamicReturnTypeExtension.php @@ -0,0 +1,58 @@ +getName() === 'array_key_first'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (!isset($functionCall->args[0])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $argType = $scope->getType($functionCall->args[0]->value); + $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); + if ($iterableAtLeastOnce->no()) { + return new NullType(); + } + + $constantArrays = TypeUtils::getConstantArrays($argType); + if (count($constantArrays) > 0) { + $keyTypes = []; + foreach ($constantArrays as $constantArray) { + $arrayKeyTypes = $constantArray->getKeyTypes(); + if (count($arrayKeyTypes) === 0) { + $keyTypes[] = new NullType(); + continue; + } + + $keyTypes[] = $arrayKeyTypes[0]; + } + + return TypeCombinator::union(...$keyTypes); + } + + $keyType = $argType->getIterableKeyType(); + if ($iterableAtLeastOnce->yes()) { + return $keyType; + } + + return TypeCombinator::union($keyType, new NullType()); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyLastDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyLastDynamicReturnTypeExtension.php new file mode 100644 index 00000000..25bec781 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeyLastDynamicReturnTypeExtension.php @@ -0,0 +1,58 @@ +getName() === 'array_key_last'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (!isset($functionCall->args[0])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $argType = $scope->getType($functionCall->args[0]->value); + $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); + if ($iterableAtLeastOnce->no()) { + return new NullType(); + } + + $constantArrays = TypeUtils::getConstantArrays($argType); + if (count($constantArrays) > 0) { + $keyTypes = []; + foreach ($constantArrays as $constantArray) { + $arrayKeyTypes = $constantArray->getKeyTypes(); + if (count($arrayKeyTypes) === 0) { + $keyTypes[] = new NullType(); + continue; + } + + $keyTypes[] = $arrayKeyTypes[count($arrayKeyTypes) - 1]; + } + + return TypeCombinator::union(...$keyTypes); + } + + $keyType = $argType->getIterableKeyType(); + if ($iterableAtLeastOnce->yes()) { + return $keyType; + } + + return TypeCombinator::union($keyType, new NullType()); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayKeysFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeysFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..2bf5f7ab --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayKeysFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,38 @@ +getName() === 'array_keys'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $arrayArg = $functionCall->args[0]->value ?? null; + if ($arrayArg !== null) { + $valueType = $scope->getType($arrayArg); + if ($valueType instanceof ArrayType) { + return $valueType->getKeysArray(); + } + } + + return new ArrayType( + new IntegerType(), + new UnionType([new StringType(), new IntegerType()]) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayMapFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayMapFunctionReturnTypeExtension.php new file mode 100644 index 00000000..fd899afe --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayMapFunctionReturnTypeExtension.php @@ -0,0 +1,69 @@ +getName() === 'array_map'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (count($functionCall->args) < 2) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $valueType = new MixedType(); + $callableType = $scope->getType($functionCall->args[0]->value); + if (!$callableType->isCallable()->no()) { + $valueType = ParametersAcceptorSelector::selectFromArgs( + $scope, + $functionCall->args, + $callableType->getCallableParametersAcceptors($scope) + )->getReturnType(); + } + + $arrayType = $scope->getType($functionCall->args[1]->value); + $constantArrays = TypeUtils::getConstantArrays($arrayType); + if (count($constantArrays) > 0) { + $arrayTypes = []; + foreach ($constantArrays as $constantArray) { + $returnedArrayBuilder = ConstantArrayTypeBuilder::createEmpty(); + foreach ($constantArray->getKeyTypes() as $keyType) { + $returnedArrayBuilder->setOffsetValueType( + $keyType, + $valueType + ); + } + $arrayTypes[] = $returnedArrayBuilder->getArray(); + } + + return TypeCombinator::union(...$arrayTypes); + } elseif ($arrayType instanceof ArrayType) { + return new ArrayType( + $arrayType->getIterableKeyType(), + $valueType + ); + } + + return new ArrayType( + new MixedType(), + $valueType + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..38bb6b31 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayMergeFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,52 @@ +getName() === 'array_merge'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (!isset($functionCall->args[0])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $keyTypes = []; + $valueTypes = []; + foreach ($functionCall->args as $arg) { + $argType = $scope->getType($arg->value); + if ($arg->unpack) { + $argType = $argType->getIterableValueType(); + if ($argType instanceof UnionType) { + foreach ($argType->getTypes() as $innerType) { + $argType = $innerType; + } + } + } + + $keyTypes[] = TypeUtils::generalizeType($argType->getIterableKeyType()); + $valueTypes[] = $argType->getIterableValueType(); + } + + return new ArrayType( + TypeCombinator::union(...$keyTypes), + TypeCombinator::union(...$valueTypes) + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayPointerFunctionsDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayPointerFunctionsDynamicReturnTypeExtension.php new file mode 100644 index 00000000..747d174c --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayPointerFunctionsDynamicReturnTypeExtension.php @@ -0,0 +1,72 @@ +getName(), $this->functions, true); + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + if (count($functionCall->args) === 0) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $argType = $scope->getType($functionCall->args[0]->value); + $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); + if ($iterableAtLeastOnce->no()) { + return new ConstantBooleanType(false); + } + + $constantArrays = TypeUtils::getConstantArrays($argType); + if (count($constantArrays) > 0) { + $keyTypes = []; + foreach ($constantArrays as $constantArray) { + $arrayKeyTypes = $constantArray->getKeyTypes(); + if (count($arrayKeyTypes) === 0) { + $keyTypes[] = new ConstantBooleanType(false); + continue; + } + + $valueOffset = $functionReflection->getName() === 'reset' + ? $arrayKeyTypes[0] + : $arrayKeyTypes[count($arrayKeyTypes) - 1]; + + $keyTypes[] = $constantArray->getOffsetValueType($valueOffset); + } + + return TypeCombinator::union(...$keyTypes); + } + + $itemType = $argType->getIterableValueType(); + if ($iterableAtLeastOnce->yes()) { + return $itemType; + } + + return TypeCombinator::union($itemType, new ConstantBooleanType(false)); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayPopFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayPopFunctionReturnTypeExtension.php new file mode 100644 index 00000000..2e26f43a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayPopFunctionReturnTypeExtension.php @@ -0,0 +1,58 @@ +getName() === 'array_pop'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (!isset($functionCall->args[0])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $argType = $scope->getType($functionCall->args[0]->value); + $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); + if ($iterableAtLeastOnce->no()) { + return new NullType(); + } + + $constantArrays = TypeUtils::getConstantArrays($argType); + if (count($constantArrays) > 0) { + $valueTypes = []; + foreach ($constantArrays as $constantArray) { + $arrayKeyTypes = $constantArray->getKeyTypes(); + if (count($arrayKeyTypes) === 0) { + $valueTypes[] = new NullType(); + continue; + } + + $valueTypes[] = $constantArray->getOffsetValueType($arrayKeyTypes[count($arrayKeyTypes) - 1]); + } + + return TypeCombinator::union(...$valueTypes); + } + + $itemType = $argType->getIterableValueType(); + if ($iterableAtLeastOnce->yes()) { + return $itemType; + } + + return TypeCombinator::union($itemType, new NullType()); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayReduceFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayReduceFunctionReturnTypeExtension.php new file mode 100644 index 00000000..ec876b45 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayReduceFunctionReturnTypeExtension.php @@ -0,0 +1,67 @@ +getName() === 'array_reduce'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (!isset($functionCall->args[1])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $callbackType = $scope->getType($functionCall->args[1]->value); + if ($callbackType->isCallable()->no()) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $callbackReturnType = ParametersAcceptorSelector::selectFromArgs( + $scope, + $functionCall->args, + $callbackType->getCallableParametersAcceptors($scope) + )->getReturnType(); + + if (isset($functionCall->args[2])) { + $initialType = $scope->getType($functionCall->args[2]->value); + } else { + $initialType = new NullType(); + } + + $arraysType = $scope->getType($functionCall->args[0]->value); + $constantArrays = TypeUtils::getConstantArrays($arraysType); + if (count($constantArrays) > 0) { + $onlyEmpty = true; + $onlyNonEmpty = true; + foreach ($constantArrays as $constantArray) { + $isEmpty = count($constantArray->getValueTypes()) === 0; + $onlyEmpty = $onlyEmpty && $isEmpty; + $onlyNonEmpty = $onlyNonEmpty && !$isEmpty; + } + + if ($onlyEmpty) { + return $initialType; + } + if ($onlyNonEmpty) { + return $callbackReturnType; + } + } + + return TypeCombinator::union($callbackReturnType, $initialType); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArraySearchFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArraySearchFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..21f616e7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArraySearchFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,165 @@ +getName() === 'array_search'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $argsCount = count($functionCall->args); + if ($argsCount < 2) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $haystackArgType = $scope->getType($functionCall->args[1]->value); + $haystackIsArray = (new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($haystackArgType); + if ($haystackIsArray->no()) { + return new NullType(); + } + + if ($argsCount < 3) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $strictArgType = $scope->getType($functionCall->args[2]->value); + if (!($strictArgType instanceof ConstantBooleanType) || $strictArgType->getValue() === false) { + return TypeCombinator::union($haystackArgType->getIterableKeyType(), new ConstantBooleanType(false), new NullType()); + } + + $needleArgType = $scope->getType($functionCall->args[0]->value); + if ($haystackArgType->getIterableValueType()->isSuperTypeOf($needleArgType)->no()) { + return new ConstantBooleanType(false); + } + + $typesFromConstantArrays = []; + if ($haystackIsArray->maybe()) { + $typesFromConstantArrays[] = new NullType(); + } + + $haystackArrays = $this->pickArrays($haystackArgType); + if (count($haystackArrays) === 0) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $arrays = []; + $typesFromConstantArraysCount = 0; + foreach ($haystackArrays as $haystackArray) { + if (!$haystackArray instanceof ConstantArrayType) { + $arrays[] = $haystackArray; + continue; + } + + $typesFromConstantArrays[] = $this->resolveTypeFromConstantHaystackAndNeedle($needleArgType, $haystackArray); + $typesFromConstantArraysCount++; + } + + if ( + $typesFromConstantArraysCount > 0 + && count($haystackArrays) === $typesFromConstantArraysCount + ) { + return TypeCombinator::union(...$typesFromConstantArrays); + } + + $iterableKeyType = TypeCombinator::union(...$arrays)->getIterableKeyType(); + if ($iterableKeyType instanceof BenevolentUnionType) { + $iterableKeyType = new MixedType(); + } + + return TypeCombinator::union( + $iterableKeyType, + new ConstantBooleanType(false), + ...$typesFromConstantArrays + ); + } + + private function resolveTypeFromConstantHaystackAndNeedle(Type $needle, ConstantArrayType $haystack): Type + { + $matchesByType = []; + + foreach ($haystack->getValueTypes() as $index => $valueType) { + $isNeedleSuperType = $valueType->isSuperTypeOf($needle); + if ($isNeedleSuperType->no()) { + $matchesByType[] = new ConstantBooleanType(false); + continue; + } + + if ($needle instanceof ConstantScalarType && $valueType instanceof ConstantScalarType + && $needle->getValue() === $valueType->getValue() + ) { + return $haystack->getKeyTypes()[$index]; + } + + $matchesByType[] = $haystack->getKeyTypes()[$index]; + if (!$isNeedleSuperType->maybe()) { + continue; + } + + $matchesByType[] = new ConstantBooleanType(false); + } + + if (count($matchesByType) > 0) { + if ( + $haystack->getIterableValueType()->accepts($needle, true)->yes() + && $needle->isSuperTypeOf(new ObjectWithoutClassType())->no() + ) { + return TypeCombinator::union(...$matchesByType); + } + + return TypeCombinator::union(new ConstantBooleanType(false), ...$matchesByType); + } + + return new ConstantBooleanType(false); + } + + /** + * @param Type $type + * @return Type[] + */ + private function pickArrays(Type $type): array + { + if ($type instanceof ArrayType) { + return [$type]; + } + + if ($type instanceof UnionType || $type instanceof IntersectionType) { + $arrayTypes = []; + + foreach ($type->getTypes() as $innerType) { + if (!($innerType instanceof ArrayType)) { + continue; + } + + $arrayTypes[] = $innerType; + } + + return $arrayTypes; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayShiftFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayShiftFunctionReturnTypeExtension.php new file mode 100644 index 00000000..b7feab7e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayShiftFunctionReturnTypeExtension.php @@ -0,0 +1,58 @@ +getName() === 'array_shift'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (!isset($functionCall->args[0])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $argType = $scope->getType($functionCall->args[0]->value); + $iterableAtLeastOnce = $argType->isIterableAtLeastOnce(); + if ($iterableAtLeastOnce->no()) { + return new NullType(); + } + + $constantArrays = TypeUtils::getConstantArrays($argType); + if (count($constantArrays) > 0) { + $valueTypes = []; + foreach ($constantArrays as $constantArray) { + $arrayKeyTypes = $constantArray->getKeyTypes(); + if (count($arrayKeyTypes) === 0) { + $valueTypes[] = new NullType(); + continue; + } + + $valueTypes[] = $constantArray->getOffsetValueType($arrayKeyTypes[0]); + } + + return TypeCombinator::union(...$valueTypes); + } + + $itemType = $argType->getIterableValueType(); + if ($iterableAtLeastOnce->yes()) { + return $itemType; + } + + return TypeCombinator::union($itemType, new NullType()); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArraySliceFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArraySliceFunctionReturnTypeExtension.php new file mode 100644 index 00000000..6ef6b6ae --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArraySliceFunctionReturnTypeExtension.php @@ -0,0 +1,88 @@ +getName() === 'array_slice'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + $arrayArg = $functionCall->args[0]->value ?? null; + + if ($arrayArg === null) { + return new ArrayType( + new IntegerType(), + new MixedType() + ); + } + + $valueType = $scope->getType($arrayArg); + + if (isset($functionCall->args[1])) { + $offset = $scope->getType($functionCall->args[1]->value); + if (!$offset instanceof ConstantIntegerType) { + $offset = new ConstantIntegerType(0); + } + } else { + $offset = new ConstantIntegerType(0); + } + + if (isset($functionCall->args[2])) { + $limit = $scope->getType($functionCall->args[2]->value); + if (!$limit instanceof ConstantIntegerType) { + $limit = new NullType(); + } + } else { + $limit = new NullType(); + } + + $constantArrays = TypeUtils::getConstantArrays($valueType); + if (count($constantArrays) === 0) { + if (!$valueType instanceof ArrayType) { + return new ArrayType( + new MixedType(), + new MixedType() + ); + } + + return $valueType; + } + + if (isset($functionCall->args[3])) { + $preserveKeys = $scope->getType($functionCall->args[3]->value); + $preserveKeys = (new ConstantBooleanType(true))->isSuperTypeOf($preserveKeys)->yes(); + } else { + $preserveKeys = false; + } + + $arrayTypes = array_map(static function (ConstantArrayType $constantArray) use ($offset, $limit, $preserveKeys): ConstantArrayType { + return $constantArray->slice($offset->getValue(), $limit->getValue(), $preserveKeys); + }, $constantArrays); + + return TypeCombinator::union(...$arrayTypes); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ArrayValuesFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ArrayValuesFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..53b9c842 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ArrayValuesFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,37 @@ +getName() === 'array_values'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $arrayArg = $functionCall->args[0]->value ?? null; + if ($arrayArg !== null) { + $valueType = $scope->getType($arrayArg); + if ($valueType instanceof ArrayType) { + return $valueType->getValuesArray(); + } + } + + return new ArrayType( + new IntegerType(), + new MixedType() + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/AssertFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/AssertFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..1e838fe6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/AssertFunctionTypeSpecifyingExtension.php @@ -0,0 +1,36 @@ +getName() === 'assert' + && isset($node->args[0]); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + return $this->typeSpecifier->specifyTypesInCondition($scope, $node->args[0]->value, TypeSpecifierContext::createTruthy()); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/CountFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/CountFunctionReturnTypeExtension.php new file mode 100644 index 00000000..20f78ee5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/CountFunctionReturnTypeExtension.php @@ -0,0 +1,43 @@ +getName() === 'count'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + if (count($functionCall->args) < 1) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $arrays = TypeUtils::getArrays($scope->getType($functionCall->args[0]->value)); + if (count($arrays) === 0) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + $countTypes = []; + foreach ($arrays as $array) { + $countTypes[] = $array->count(); + } + + return TypeCombinator::union(...$countTypes); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/CountFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/CountFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..a2fd9a88 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/CountFunctionTypeSpecifyingExtension.php @@ -0,0 +1,53 @@ +null() + && count($node->args) === 1 + && $functionReflection->getName() === 'count'; + } + + public function specifyTypes( + FunctionReflection $functionReflection, + FuncCall $node, + Scope $scope, + TypeSpecifierContext $context + ): SpecifiedTypes + { + if (!(new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($scope->getType($node->args[0]->value))->yes()) { + return new SpecifiedTypes([], []); + } + + return $this->typeSpecifier->create($node->args[0]->value, new NonEmptyArrayType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/CurlInitReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/CurlInitReturnTypeExtension.php new file mode 100644 index 00000000..885707c8 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/CurlInitReturnTypeExtension.php @@ -0,0 +1,37 @@ +getName() === 'curl_init'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + \PhpParser\Node\Expr\FuncCall $functionCall, + Scope $scope + ): Type + { + $argsCount = count($functionCall->args); + if ($argsCount === 0) { + return new ResourceType(); + } + + return new UnionType([ + new ResourceType(), + new ConstantBooleanType(false), + ]); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/DefineConstantTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/DefineConstantTypeSpecifyingExtension.php new file mode 100644 index 00000000..4da869b8 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/DefineConstantTypeSpecifyingExtension.php @@ -0,0 +1,61 @@ +typeSpecifier = $typeSpecifier; + } + + public function isFunctionSupported( + FunctionReflection $functionReflection, + FuncCall $node, + TypeSpecifierContext $context + ): bool + { + return $functionReflection->getName() === 'define' + && $context->null() + && count($node->args) >= 2; + } + + public function specifyTypes( + FunctionReflection $functionReflection, + FuncCall $node, + Scope $scope, + TypeSpecifierContext $context + ): SpecifiedTypes + { + $constantName = $scope->getType($node->args[0]->value); + if ( + !$constantName instanceof ConstantStringType + || $constantName->getValue() === '' + ) { + return new SpecifiedTypes([], []); + } + + return $this->typeSpecifier->create( + new \PhpParser\Node\Expr\ConstFetch( + new \PhpParser\Node\Name\FullyQualified($constantName->getValue()) + ), + $scope->getType($node->args[1]->value), + TypeSpecifierContext::createTruthy() + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/DefinedConstantTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/DefinedConstantTypeSpecifyingExtension.php new file mode 100644 index 00000000..ac6e590a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/DefinedConstantTypeSpecifyingExtension.php @@ -0,0 +1,62 @@ +typeSpecifier = $typeSpecifier; + } + + public function isFunctionSupported( + FunctionReflection $functionReflection, + FuncCall $node, + TypeSpecifierContext $context + ): bool + { + return $functionReflection->getName() === 'defined' + && count($node->args) >= 1 + && !$context->null(); + } + + public function specifyTypes( + FunctionReflection $functionReflection, + FuncCall $node, + Scope $scope, + TypeSpecifierContext $context + ): SpecifiedTypes + { + $constantName = $scope->getType($node->args[0]->value); + if ( + !$constantName instanceof ConstantStringType + || $constantName->getValue() === '' + ) { + return new SpecifiedTypes([], []); + } + + return $this->typeSpecifier->create( + new \PhpParser\Node\Expr\ConstFetch( + new \PhpParser\Node\Name\FullyQualified($constantName->getValue()) + ), + new MixedType(), + $context + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/DioStatDynamicFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/DioStatDynamicFunctionReturnTypeExtension.php new file mode 100644 index 00000000..a134c6d4 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/DioStatDynamicFunctionReturnTypeExtension.php @@ -0,0 +1,49 @@ +getName() === 'dio_stat'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $valueType = new IntegerType(); + $builder = ConstantArrayTypeBuilder::createEmpty(); + $keys = [ + 'device', + 'inode', + 'mode', + 'nlink', + 'uid', + 'gid', + 'device_type', + 'size', + 'blocksize', + 'blocks', + 'atime', + 'mtime', + 'ctime', + ]; + + foreach ($keys as $key) { + $builder->setOffsetValueType(new ConstantStringType($key), $valueType); + } + + return TypeCombinator::addNull($builder->getArray()); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ExplodeFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ExplodeFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..fdead7b7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ExplodeFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,52 @@ +getName() === 'explode'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + if (count($functionCall->args) < 2) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $delimiterType = $scope->getType($functionCall->args[0]->value); + $isSuperset = (new ConstantStringType(''))->isSuperTypeOf($delimiterType); + if ($isSuperset->yes()) { + return new ConstantBooleanType(false); + } elseif ($isSuperset->no()) { + return new ArrayType(new IntegerType(), new StringType()); + } + + $returnType = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + if ($delimiterType instanceof MixedType) { + return TypeUtils::toBenevolentUnion($returnType); + } + + return $returnType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/GetParentClassDynamicFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/GetParentClassDynamicFunctionReturnTypeExtension.php new file mode 100644 index 00000000..15ec7544 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/GetParentClassDynamicFunctionReturnTypeExtension.php @@ -0,0 +1,104 @@ +broker = $broker; + } + + public function isFunctionSupported( + FunctionReflection $functionReflection + ): bool + { + return $functionReflection->getName() === 'get_parent_class'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + $defaultReturnType = ParametersAcceptorSelector::selectSingle( + $functionReflection->getVariants() + )->getReturnType(); + if (count($functionCall->args) === 0) { + if ($scope->isInTrait()) { + return $defaultReturnType; + } + if ($scope->isInClass()) { + return $this->findParentClassType( + $scope->getClassReflection() + ); + } + + return new ConstantBooleanType(false); + } + + $argType = $scope->getType($functionCall->args[0]->value); + if ($scope->isInTrait() && TypeUtils::findThisType($argType) !== null) { + return $defaultReturnType; + } + + $constantStrings = TypeUtils::getConstantStrings($argType); + if (count($constantStrings) > 0) { + return \PHPStan\Type\TypeCombinator::union(...array_map(function (ConstantStringType $stringType): Type { + return $this->findParentClassNameType($stringType->getValue()); + }, $constantStrings)); + } + + $classNames = TypeUtils::getDirectClassNames($argType); + if (count($classNames) > 0) { + return \PHPStan\Type\TypeCombinator::union(...array_map(function (string $classNames): Type { + return $this->findParentClassNameType($classNames); + }, $classNames)); + } + + return $defaultReturnType; + } + + private function findParentClassNameType(string $className): Type + { + if (!$this->broker->hasClass($className)) { + return new UnionType([ + new StringType(), + new ConstantBooleanType(false), + ]); + } + + return $this->findParentClassType($this->broker->getClass($className)); + } + + private function findParentClassType( + ClassReflection $classReflection + ): Type + { + $parentClass = $classReflection->getParentClass(); + if ($parentClass === false) { + return new ConstantBooleanType(false); + } + + return new ConstantStringType($parentClass->getName()); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/GettimeofdayDynamicFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/GettimeofdayDynamicFunctionReturnTypeExtension.php new file mode 100644 index 00000000..8fdb9106 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/GettimeofdayDynamicFunctionReturnTypeExtension.php @@ -0,0 +1,63 @@ +getName() === 'gettimeofday'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $arrayType = new ConstantArrayType([ + new ConstantStringType('sec'), + new ConstantStringType('usec'), + new ConstantStringType('minuteswest'), + new ConstantStringType('dsttime'), + ], [ + new IntegerType(), + new IntegerType(), + new IntegerType(), + new IntegerType(), + ]); + $floatType = new FloatType(); + + if (!isset($functionCall->args[0])) { + return $arrayType; + } + + $argType = $scope->getType($functionCall->args[0]->value); + $isTrueType = (new ConstantBooleanType(true))->isSuperTypeOf($argType); + $isFalseType = (new ConstantBooleanType(false))->isSuperTypeOf($argType); + $compareTypes = $isTrueType->compareTo($isFalseType); + if ($compareTypes === $isTrueType) { + return $floatType; + } + if ($compareTypes === $isFalseType) { + return $arrayType; + } + + if ($argType instanceof MixedType) { + return new BenevolentUnionType([$arrayType, $floatType]); + } + + return new UnionType([$arrayType, $floatType]); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/HrtimeFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/HrtimeFunctionReturnTypeExtension.php new file mode 100644 index 00000000..37b255b5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/HrtimeFunctionReturnTypeExtension.php @@ -0,0 +1,47 @@ +getName() === 'hrtime'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $arrayType = new ConstantArrayType([new ConstantIntegerType(0), new ConstantIntegerType(1)], [new IntegerType(), new IntegerType()], 2); + $numberType = TypeCombinator::union(new IntegerType(), new FloatType()); + + if (count($functionCall->args) < 1) { + return $arrayType; + } + + $argType = $scope->getType($functionCall->args[0]->value); + $isTrueType = (new ConstantBooleanType(true))->isSuperTypeOf($argType); + $isFalseType = (new ConstantBooleanType(false))->isSuperTypeOf($argType); + $compareTypes = $isTrueType->compareTo($isFalseType); + if ($compareTypes === $isTrueType) { + return $numberType; + } + if ($compareTypes === $isFalseType) { + return $arrayType; + } + + return TypeCombinator::union($arrayType, $numberType); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/InArrayFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/InArrayFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..acfa8cd7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/InArrayFunctionTypeSpecifyingExtension.php @@ -0,0 +1,57 @@ +typeSpecifier = $typeSpecifier; + } + + public function isFunctionSupported(FunctionReflection $functionReflection, FuncCall $node, TypeSpecifierContext $context): bool + { + return strtolower($functionReflection->getName()) === 'in_array' + && count($node->args) >= 3 + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + $strictNodeType = $scope->getType($node->args[2]->value); + if (!(new ConstantBooleanType(true))->isSuperTypeOf($strictNodeType)->yes()) { + return new SpecifiedTypes([], []); + } + + $arrayValueType = $scope->getType($node->args[1]->value)->getIterableValueType(); + + if ( + $context->truthy() + || count(TypeUtils::getConstantScalars($arrayValueType)) > 0 + ) { + return $this->typeSpecifier->create( + $node->args[0]->value, + $arrayValueType, + $context + ); + } + + return new SpecifiedTypes([], []); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsAFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsAFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..020b0c3a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsAFunctionTypeSpecifyingExtension.php @@ -0,0 +1,81 @@ +getName()) === 'is_a' + && isset($node->args[0]) + && isset($node->args[1]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $classNameArgExpr = $node->args[1]->value; + $classNameArgExprType = $scope->getType($classNameArgExpr); + if ( + $classNameArgExpr instanceof ClassConstFetch + && $classNameArgExpr->class instanceof Name + && $classNameArgExpr->name instanceof \PhpParser\Node\Identifier + && strtolower($classNameArgExpr->name->name) === 'class' + ) { + $className = $scope->resolveName($classNameArgExpr->class); + if (strtolower($classNameArgExpr->class->toString()) === 'static') { + $objectType = new StaticType($className); + } else { + $objectType = new ObjectType($className); + } + $types = $this->typeSpecifier->create($node->args[0]->value, $objectType, $context); + } elseif ($classNameArgExprType instanceof ConstantStringType) { + $objectType = new ObjectType($classNameArgExprType->getValue()); + $types = $this->typeSpecifier->create($node->args[0]->value, $objectType, $context); + } elseif ($context->true()) { + $objectType = new ObjectWithoutClassType(); + $types = $this->typeSpecifier->create($node->args[0]->value, $objectType, $context); + } else { + $types = new SpecifiedTypes(); + } + + if (isset($node->args[2]) && $context->true()) { + if (!$scope->getType($node->args[2]->value)->isSuperTypeOf(new ConstantBooleanType(true))->no()) { + $types = $types->intersectWith($this->typeSpecifier->create($node->args[0]->value, new StringType(), $context)); + } + } + + return $types; + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsArrayFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsArrayFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..e5e1a5e7 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsArrayFunctionTypeSpecifyingExtension.php @@ -0,0 +1,43 @@ +getName()) === 'is_array' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new ArrayType(new MixedType(), new MixedType()), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsBoolFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsBoolFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..0b513e8d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsBoolFunctionTypeSpecifyingExtension.php @@ -0,0 +1,42 @@ +getName()) === 'is_bool' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new BooleanType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsCallableFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsCallableFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..ab7f5f7b --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsCallableFunctionTypeSpecifyingExtension.php @@ -0,0 +1,42 @@ +getName()) === 'is_callable' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new CallableType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsCountableFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsCountableFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..0e6886c1 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsCountableFunctionTypeSpecifyingExtension.php @@ -0,0 +1,52 @@ +getName()) === 'is_countable' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create( + $node->args[0]->value, + new UnionType([ + new ArrayType(new MixedType(), new MixedType()), + new ObjectType(\Countable::class), + ]), + $context + ); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsFloatFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsFloatFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..3577d0a3 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsFloatFunctionTypeSpecifyingExtension.php @@ -0,0 +1,46 @@ +getName()), [ + 'is_float', + 'is_double', + 'is_real', + ], true) + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new FloatType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsIntFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsIntFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..e492cebb --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsIntFunctionTypeSpecifyingExtension.php @@ -0,0 +1,46 @@ +getName()), [ + 'is_int', + 'is_integer', + 'is_long', + ], true) + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new IntegerType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsIterableFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsIterableFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..1a6646da --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsIterableFunctionTypeSpecifyingExtension.php @@ -0,0 +1,43 @@ +getName()) === 'is_iterable' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new IterableType(new MixedType(), new MixedType()), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsNullFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsNullFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..620f350a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsNullFunctionTypeSpecifyingExtension.php @@ -0,0 +1,42 @@ +getName()) === 'is_null' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new NullType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsNumericFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsNumericFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..2810aa71 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsNumericFunctionTypeSpecifyingExtension.php @@ -0,0 +1,54 @@ +getName() === 'is_numeric' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + $numericTypes = [ + new IntegerType(), + new FloatType(), + ]; + + if ($context->truthy()) { + $numericTypes[] = new StringType(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new UnionType($numericTypes), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsObjectFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsObjectFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..64342118 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsObjectFunctionTypeSpecifyingExtension.php @@ -0,0 +1,42 @@ +getName()) === 'is_object' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new ObjectWithoutClassType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsResourceFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsResourceFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..0d8b153a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsResourceFunctionTypeSpecifyingExtension.php @@ -0,0 +1,42 @@ +getName()) === 'is_resource' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new ResourceType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsScalarFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsScalarFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..5594454f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsScalarFunctionTypeSpecifyingExtension.php @@ -0,0 +1,51 @@ +getName() === 'is_scalar' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new UnionType([ + new StringType(), + new IntegerType(), + new FloatType(), + new BooleanType(), + ]), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsStringFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsStringFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..b8cea610 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsStringFunctionTypeSpecifyingExtension.php @@ -0,0 +1,42 @@ +getName()) === 'is_string' + && isset($node->args[0]) + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + if ($context->null()) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $this->typeSpecifier->create($node->args[0]->value, new StringType(), $context); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/IsSubclassOfFunctionTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/IsSubclassOfFunctionTypeSpecifyingExtension.php new file mode 100644 index 00000000..1cd98a88 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/IsSubclassOfFunctionTypeSpecifyingExtension.php @@ -0,0 +1,61 @@ +getName()) === 'is_subclass_of' + && count($node->args) >= 2 + && !$context->null(); + } + + public function specifyTypes(FunctionReflection $functionReflection, FuncCall $node, Scope $scope, TypeSpecifierContext $context): SpecifiedTypes + { + $objectType = $scope->getType($node->args[0]->value); + $stringType = new StringType(); + if ( + !$objectType instanceof MixedType + && !$stringType->isSuperTypeOf($objectType)->no() + ) { + return new SpecifiedTypes(); + } + + $classType = $scope->getType($node->args[1]->value); + if (!$classType instanceof ConstantStringType || $classType->getValue() === '') { + return new SpecifiedTypes(); + } + + return $this->typeSpecifier->specifyTypesInCondition( + $scope, + new \PhpParser\Node\Expr\Instanceof_( + $node->args[0]->value, + new \PhpParser\Node\Name($classType->getValue()) + ), + $context + ); + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/JsonThrowOnErrorDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/JsonThrowOnErrorDynamicReturnTypeExtension.php new file mode 100644 index 00000000..bdc94bc6 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/JsonThrowOnErrorDynamicReturnTypeExtension.php @@ -0,0 +1,62 @@ + */ + private $argumentPositions = [ + 'json_encode' => 1, + 'json_decode' => 3, + ]; + + public function isFunctionSupported( + FunctionReflection $functionReflection + ): bool + { + return defined('JSON_THROW_ON_ERROR') && in_array( + $functionReflection->getName(), + [ + 'json_encode', + 'json_decode', + ], + true + ); + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + $argumentPosition = $this->argumentPositions[$functionReflection->getName()]; + $defaultReturnType = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + if (!isset($functionCall->args[$argumentPosition])) { + return $defaultReturnType; + } + + $valueType = $scope->getType($functionCall->args[$argumentPosition]->value); + if (!$valueType instanceof ConstantIntegerType) { + return $defaultReturnType; + } + + $value = $valueType->getValue(); + if (($value & JSON_THROW_ON_ERROR) !== JSON_THROW_ON_ERROR) { + return $defaultReturnType; + } + + return TypeCombinator::remove($defaultReturnType, new ConstantBooleanType(false)); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/MbFunctionsReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/MbFunctionsReturnTypeExtension.php new file mode 100644 index 00000000..256d1ebc --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/MbFunctionsReturnTypeExtension.php @@ -0,0 +1,87 @@ + 1, + 'mb_regex_encoding' => 1, + 'mb_internal_encoding' => 1, + 'mb_encoding_aliases' => 1, + 'mb_strlen' => 2, + 'mb_chr' => 2, + 'mb_ord' => 2, + ]; + + public function __construct() + { + $supportedEncodings = []; + if (function_exists('mb_list_encodings')) { + foreach (mb_list_encodings() as $encoding) { + $aliases = mb_encoding_aliases($encoding); + if ($aliases === false) { + throw new \PHPStan\ShouldNotHappenException(); + } + $supportedEncodings = array_merge($supportedEncodings, $aliases, [$encoding]); + } + } + $this->supportedEncodings = array_map('strtoupper', $supportedEncodings); + } + + public function isFunctionSupported(FunctionReflection $functionReflection): bool + { + return array_key_exists($functionReflection->getName(), $this->encodingPositionMap); + } + + private function isSupportedEncoding(string $encoding): bool + { + return in_array(strtoupper($encoding), $this->supportedEncodings, true); + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $returnType = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + $positionEncodingParam = $this->encodingPositionMap[$functionReflection->getName()]; + + if (count($functionCall->args) < $positionEncodingParam) { + return TypeCombinator::remove($returnType, new BooleanType()); + } + + $strings = TypeUtils::getConstantStrings($scope->getType($functionCall->args[$positionEncodingParam - 1]->value)); + $results = array_unique(array_map(function (ConstantStringType $encoding): bool { + return $this->isSupportedEncoding($encoding->getValue()); + }, $strings)); + + if ($returnType->equals(new UnionType([new StringType(), new BooleanType()]))) { + return count($results) === 1 ? new ConstantBooleanType($results[0]) : new BooleanType(); + } + + if (count($results) === 1) { + return $results[0] + ? TypeCombinator::remove($returnType, new ConstantBooleanType(false)) + : new ConstantBooleanType(false); + } + + return $returnType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/MethodExistsTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/MethodExistsTypeSpecifyingExtension.php new file mode 100644 index 00000000..e25e7d91 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/MethodExistsTypeSpecifyingExtension.php @@ -0,0 +1,62 @@ +typeSpecifier = $typeSpecifier; + } + + public function isFunctionSupported( + FunctionReflection $functionReflection, + FuncCall $node, + TypeSpecifierContext $context + ): bool + { + return $functionReflection->getName() === 'method_exists' + && $context->truthy() + && count($node->args) >= 2; + } + + public function specifyTypes( + FunctionReflection $functionReflection, + FuncCall $node, + Scope $scope, + TypeSpecifierContext $context + ): SpecifiedTypes + { + $methodNameType = $scope->getType($node->args[1]->value); + if (!$methodNameType instanceof ConstantStringType) { + return new SpecifiedTypes([], []); + } + + return $this->typeSpecifier->create( + $node->args[0]->value, + new IntersectionType([ + new ObjectWithoutClassType(), + new HasMethodType($methodNameType->getValue()), + ]), + $context + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/MicrotimeFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/MicrotimeFunctionReturnTypeExtension.php new file mode 100644 index 00000000..15ef4772 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/MicrotimeFunctionReturnTypeExtension.php @@ -0,0 +1,48 @@ +getName() === 'microtime'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (count($functionCall->args) < 1) { + return new StringType(); + } + + $argType = $scope->getType($functionCall->args[0]->value); + $isTrueType = (new ConstantBooleanType(true))->isSuperTypeOf($argType); + $isFalseType = (new ConstantBooleanType(false))->isSuperTypeOf($argType); + $compareTypes = $isTrueType->compareTo($isFalseType); + if ($compareTypes === $isTrueType) { + return new FloatType(); + } + if ($compareTypes === $isFalseType) { + return new StringType(); + } + + if ($argType instanceof MixedType) { + return new BenevolentUnionType([new StringType(), new FloatType()]); + } + + return new UnionType([new StringType(), new FloatType()]); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/MinMaxFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/MinMaxFunctionReturnTypeExtension.php new file mode 100644 index 00000000..3d3083d5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/MinMaxFunctionReturnTypeExtension.php @@ -0,0 +1,184 @@ + '', + 'max' => '', + ]; + + public function isFunctionSupported(FunctionReflection $functionReflection): bool + { + return isset($this->functionNames[$functionReflection->getName()]); + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (!isset($functionCall->args[0])) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + if (count($functionCall->args) === 1) { + $argType = $scope->getType($functionCall->args[0]->value); + if ($argType instanceof ArrayType) { + $iterableValueType = $argType->getIterableValueType(); + $argumentTypes = []; + if ($iterableValueType instanceof UnionType) { + foreach ($iterableValueType->getTypes() as $innerType) { + $argumentTypes[] = $innerType; + } + } else { + $argumentTypes[] = $iterableValueType; + } + + return $this->processType( + $functionReflection->getName(), + $argumentTypes + ); + } + + return new ErrorType(); + } + + $argumentTypes = []; + foreach ($functionCall->args as $arg) { + $argType = $scope->getType($arg->value); + if ($arg->unpack) { + $iterableValueType = $argType->getIterableValueType(); + if ($iterableValueType instanceof UnionType) { + foreach ($iterableValueType->getTypes() as $innerType) { + $argumentTypes[] = $innerType; + } + } else { + $argumentTypes[] = $iterableValueType; + } + continue; + } + + $argumentTypes[] = $argType; + } + + return $this->processType( + $functionReflection->getName(), + $argumentTypes + ); + } + + /** + * @param string $functionName + * @param \PHPStan\Type\Type[] $types + * @return Type + */ + private function processType( + string $functionName, + array $types + ): Type + { + $resultType = null; + foreach ($types as $type) { + if (!$type instanceof ConstantType) { + return TypeCombinator::union(...$types); + } + + if ($resultType === null) { + $resultType = $type; + continue; + } + + $compareResult = $this->compareTypes($resultType, $type); + if ($functionName === 'min') { + if ($compareResult === $type) { + $resultType = $type; + } + } elseif ($functionName === 'max') { + if ($compareResult === $resultType) { + $resultType = $type; + } + } + } + + if ($resultType === null) { + return new ErrorType(); + } + + return $resultType; + } + + private function compareTypes( + Type $firstType, + Type $secondType + ): ?Type + { + if ( + $firstType instanceof ConstantArrayType + && $secondType instanceof ConstantScalarType + ) { + return $secondType; + } + + if ( + $firstType instanceof ConstantScalarType + && $secondType instanceof ConstantArrayType + ) { + return $firstType; + } + + if ( + $firstType instanceof ConstantArrayType + && $secondType instanceof ConstantArrayType + ) { + if ($secondType->count() < $firstType->count()) { + return $secondType; + } elseif ($firstType->count() < $secondType->count()) { + return $firstType; + } + + foreach ($firstType->getValueTypes() as $i => $firstValueType) { + $secondValueType = $secondType->getValueTypes()[$i]; + $compareResult = $this->compareTypes($firstValueType, $secondValueType); + if ($compareResult === $firstValueType) { + return $firstType; + } + + if ($compareResult === $secondValueType) { + return $secondType; + } + } + + return null; + } + + if ( + $firstType instanceof ConstantScalarType + && $secondType instanceof ConstantScalarType + ) { + if ($secondType->getValue() < $firstType->getValue()) { + return $secondType; + } + + if ($firstType->getValue() < $secondType->getValue()) { + return $firstType; + } + } + + return null; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ParseUrlFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ParseUrlFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..266b4128 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ParseUrlFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,137 @@ + */ + private $componentTypesPairedConstants; + + /** @var array */ + private $componentTypesPairedStrings; + + /** @var Type */ + private $allComponentsTogetherType; + + public function isFunctionSupported(FunctionReflection $functionReflection): bool + { + return $functionReflection->getName() === 'parse_url'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $defaultReturnType = ParametersAcceptorSelector::selectSingle( + $functionReflection->getVariants() + )->getReturnType(); + + if (count($functionCall->args) < 1) { + return $defaultReturnType; + } + + $this->cacheReturnTypes(); + + $urlType = $scope->getType($functionCall->args[0]->value); + if (count($functionCall->args) > 1) { + $componentType = $scope->getType($functionCall->args[1]->value); + + if (!$componentType instanceof ConstantType) { + return $this->createAllComponentsReturnType(); + } + + $componentType = $componentType->toInteger(); + + if (!$componentType instanceof ConstantIntegerType) { + throw new \PHPStan\ShouldNotHappenException(); + } + } else { + $componentType = new ConstantIntegerType(-1); + } + + if ($urlType instanceof ConstantStringType) { + $result = @parse_url($urlType->getValue(), $componentType->getValue()); + + return $scope->getTypeFromValue($result); + } + + if ($componentType->getValue() === -1) { + return $this->createAllComponentsReturnType(); + } + + return $this->componentTypesPairedConstants[$componentType->getValue()] ?? new ConstantBooleanType(false); + } + + private function createAllComponentsReturnType(): Type + { + if ($this->allComponentsTogetherType === null) { + $returnTypes = [ + new ConstantBooleanType(false), + new ConstantArrayType([], []), + ]; + + $builder = ConstantArrayTypeBuilder::createEmpty(); + + foreach ($this->componentTypesPairedStrings as $componentName => $componentValueType) { + $builder->setOffsetValueType(new ConstantStringType($componentName), $componentValueType); + } + + $returnTypes[] = $builder->getArray(); + + $this->allComponentsTogetherType = TypeCombinator::union(...$returnTypes); + } + + return $this->allComponentsTogetherType; + } + + private function cacheReturnTypes(): void + { + if ($this->componentTypesPairedConstants !== null) { + return; + } + + $string = new StringType(); + $integer = new IntegerType(); + + $stringOrNull = TypeCombinator::addNull($string); + $integerOrNull = TypeCombinator::addNull($integer); + + $this->componentTypesPairedConstants = [ + PHP_URL_SCHEME => $stringOrNull, + PHP_URL_HOST => $stringOrNull, + PHP_URL_PORT => $integerOrNull, + PHP_URL_USER => $stringOrNull, + PHP_URL_PASS => $stringOrNull, + PHP_URL_PATH => $stringOrNull, + PHP_URL_QUERY => $stringOrNull, + PHP_URL_FRAGMENT => $stringOrNull, + ]; + + $this->componentTypesPairedStrings = [ + 'scheme' => $string, + 'host' => $string, + 'port' => $integer, + 'user' => $string, + 'pass' => $string, + 'path' => $string, + 'query' => $string, + 'fragment' => $string, + ]; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/PathinfoFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/PathinfoFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..2f3ca6cf --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/PathinfoFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,54 @@ +getName() === 'pathinfo'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + \PhpParser\Node\Expr\FuncCall $functionCall, + Scope $scope + ): Type + { + $argsCount = count($functionCall->args); + if ($argsCount === 0) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } elseif ($argsCount === 1) { + $stringType = new StringType(); + + $dirname = new ConstantStringType('dirname'); + $basename = new ConstantStringType('basename'); + $extension = new ConstantStringType('extension'); + $filename = new ConstantStringType('filename'); + + return new UnionType([ + new ConstantArrayType( + [$dirname, $basename, $filename], + [$stringType, $stringType, $stringType] + ), + new ConstantArrayType( + [$dirname, $basename, $extension, $filename], + [$stringType, $stringType, $stringType, $stringType] + ), + ]); + } + + return new StringType(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/PropertyExistsTypeSpecifyingExtension.php b/vendor/phpstan/phpstan/src/Type/Php/PropertyExistsTypeSpecifyingExtension.php new file mode 100644 index 00000000..194a3766 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/PropertyExistsTypeSpecifyingExtension.php @@ -0,0 +1,62 @@ +typeSpecifier = $typeSpecifier; + } + + public function isFunctionSupported( + FunctionReflection $functionReflection, + FuncCall $node, + TypeSpecifierContext $context + ): bool + { + return $functionReflection->getName() === 'property_exists' + && $context->truthy() + && count($node->args) >= 2; + } + + public function specifyTypes( + FunctionReflection $functionReflection, + FuncCall $node, + Scope $scope, + TypeSpecifierContext $context + ): SpecifiedTypes + { + $propertyNameType = $scope->getType($node->args[1]->value); + if (!$propertyNameType instanceof ConstantStringType) { + return new SpecifiedTypes([], []); + } + + return $this->typeSpecifier->create( + $node->args[0]->value, + new IntersectionType([ + new ObjectWithoutClassType(), + new HasPropertyType($propertyNameType->getValue()), + ]), + $context + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/RangeFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/RangeFunctionReturnTypeExtension.php new file mode 100644 index 00000000..65a7ab32 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/RangeFunctionReturnTypeExtension.php @@ -0,0 +1,106 @@ +getName() === 'range'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + if (count($functionCall->args) < 2) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $startType = $scope->getType($functionCall->args[0]->value); + $endType = $scope->getType($functionCall->args[1]->value); + $stepType = count($functionCall->args) >= 3 ? $scope->getType($functionCall->args[2]->value) : new ConstantIntegerType(1); + + $constantReturnTypes = []; + + $startConstants = TypeUtils::getConstantScalars($startType); + foreach ($startConstants as $startConstant) { + if (!$startConstant instanceof ConstantIntegerType && !$startConstant instanceof ConstantFloatType) { + continue; + } + + $endConstants = TypeUtils::getConstantScalars($endType); + foreach ($endConstants as $endConstant) { + if (!$endConstant instanceof ConstantIntegerType && !$endConstant instanceof ConstantFloatType) { + continue; + } + + $stepConstants = TypeUtils::getConstantScalars($stepType); + foreach ($stepConstants as $stepConstant) { + if (!$stepConstant instanceof ConstantIntegerType && !$stepConstant instanceof ConstantFloatType) { + continue; + } + + $rangeLength = (int) ceil(abs($startConstant->getValue() - $endConstant->getValue()) / $stepConstant->getValue()) + 1; + if ($rangeLength > self::RANGE_LENGTH_THRESHOLD) { + continue; + } + + $keyTypes = []; + $valueTypes = []; + + $rangeValues = range($startConstant->getValue(), $endConstant->getValue(), $stepConstant->getValue()); + foreach ($rangeValues as $key => $value) { + $keyTypes[] = new ConstantIntegerType($key); + $valueTypes[] = $scope->getTypeFromValue($value); + } + + $constantReturnTypes[] = new ConstantArrayType($keyTypes, $valueTypes, $rangeLength); + } + } + } + + if (count($constantReturnTypes) > 0) { + return TypeCombinator::union(...$constantReturnTypes); + } + + $startType = TypeUtils::generalizeType($startType); + $endType = TypeUtils::generalizeType($endType); + $stepType = TypeUtils::generalizeType($stepType); + + if ( + $startType instanceof IntegerType + && $endType instanceof IntegerType + && $stepType instanceof IntegerType + ) { + return new ArrayType(new IntegerType(), new IntegerType()); + } + + if ( + $startType instanceof FloatType + || $endType instanceof FloatType + || $stepType instanceof FloatType + ) { + return new ArrayType(new IntegerType(), new FloatType()); + } + + return new ArrayType(new IntegerType(), new UnionType([new IntegerType(), new FloatType()])); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/ReplaceFunctionsDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/ReplaceFunctionsDynamicReturnTypeExtension.php new file mode 100644 index 00000000..ace448b0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/ReplaceFunctionsDynamicReturnTypeExtension.php @@ -0,0 +1,86 @@ + */ + private $functions = [ + 'preg_replace' => 2, + 'preg_replace_callback' => 2, + 'preg_replace_callback_array' => 1, + 'str_replace' => 2, + 'str_ireplace' => 2, + 'substr_replace' => 0, + ]; + + public function isFunctionSupported(FunctionReflection $functionReflection): bool + { + return array_key_exists($functionReflection->getName(), $this->functions); + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + $type = $this->getPreliminarilyResolvedTypeFromFunctionCall($functionReflection, $functionCall, $scope); + + $possibleTypes = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + + if (TypeCombinator::containsNull($possibleTypes)) { + $type = TypeCombinator::addNull($type); + } + + return $type; + } + + private function getPreliminarilyResolvedTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + $argumentPosition = $this->functions[$functionReflection->getName()]; + if (count($functionCall->args) <= $argumentPosition) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $subjectArgumentType = $scope->getType($functionCall->args[$argumentPosition]->value); + $defaultReturnType = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + if ($subjectArgumentType instanceof MixedType) { + return TypeUtils::toBenevolentUnion($defaultReturnType); + } + $stringType = new StringType(); + $arrayType = new ArrayType(new MixedType(), new MixedType()); + + $isStringSuperType = $stringType->isSuperTypeOf($subjectArgumentType); + $isArraySuperType = $arrayType->isSuperTypeOf($subjectArgumentType); + $compareSuperTypes = $isStringSuperType->compareTo($isArraySuperType); + if ($compareSuperTypes === $isStringSuperType) { + return $stringType; + } elseif ($compareSuperTypes === $isArraySuperType) { + if ($subjectArgumentType instanceof ArrayType) { + return $subjectArgumentType->generalizeValues(); + } + return $subjectArgumentType; + } + + return $defaultReturnType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/StatDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/StatDynamicReturnTypeExtension.php new file mode 100644 index 00000000..ccc97ff5 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/StatDynamicReturnTypeExtension.php @@ -0,0 +1,76 @@ +getName(), ['stat', 'lstat', 'fstat', 'ssh2_sftp_stat'], true); + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + return $this->getReturnType(); + } + + public function getClass(): string + { + return \SplFileObject::class; + } + + public function isMethodSupported(MethodReflection $methodReflection): bool + { + return $methodReflection->getName() === 'fstat'; + } + + public function getTypeFromMethodCall(MethodReflection $methodReflection, MethodCall $methodCall, Scope $scope): Type + { + return $this->getReturnType(); + } + + private function getReturnType(): Type + { + $valueType = new IntegerType(); + $builder = ConstantArrayTypeBuilder::createEmpty(); + $keys = [ + 'dev', + 'ino', + 'mode', + 'nlink', + 'uid', + 'gid', + 'rdev', + 'size', + 'atime', + 'mtime', + 'ctime', + 'blksize', + 'blocks', + ]; + + foreach ($keys as $key) { + $builder->setOffsetValueType(null, $valueType); + } + + foreach ($keys as $key) { + $builder->setOffsetValueType(new ConstantStringType($key), $valueType); + } + + return TypeCombinator::union($builder->getArray(), new ConstantBooleanType(false)); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/StrSplitFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/StrSplitFunctionReturnTypeExtension.php new file mode 100644 index 00000000..c62efd1e --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/StrSplitFunctionReturnTypeExtension.php @@ -0,0 +1,84 @@ +getName() === 'str_split'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $defaultReturnType = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + + if (count($functionCall->args) < 1) { + return $defaultReturnType; + } + + $splitLength = 1; + if (count($functionCall->args) >= 2) { + $splitLengthType = $scope->getType($functionCall->args[1]->value); + if (!$splitLengthType instanceof ConstantIntegerType) { + return $defaultReturnType; + } + $splitLength = $splitLengthType->getValue(); + if ($splitLength < 1) { + return new ConstantBooleanType(false); + } + } + + $stringType = $scope->getType($functionCall->args[0]->value); + if (!$stringType instanceof ConstantStringType) { + return new ArrayType(new IntegerType(), new StringType()); + } + $stringValue = $stringType->getValue(); + + $items = str_split($stringValue, $splitLength); + if (!is_array($items)) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return self::createConstantArrayFrom($items, $scope); + } + + private static function createConstantArrayFrom(array $constantArray, Scope $scope): ConstantArrayType + { + $keyTypes = []; + $valueTypes = []; + $isList = true; + $i = 0; + + foreach ($constantArray as $key => $value) { + $keyType = $scope->getTypeFromValue($key); + if (!$keyType instanceof ConstantIntegerType) { + throw new \PHPStan\ShouldNotHappenException(); + } + $keyTypes[] = $keyType; + + $valueTypes[] = $scope->getTypeFromValue($value); + + $isList = $isList && $key === $i; + $i++; + } + + return new ConstantArrayType($keyTypes, $valueTypes, $isList ? $i : 0); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/StrtotimeFunctionReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/StrtotimeFunctionReturnTypeExtension.php new file mode 100644 index 00000000..767c1413 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/StrtotimeFunctionReturnTypeExtension.php @@ -0,0 +1,45 @@ +getName() === 'strtotime'; + } + + public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): Type + { + $defaultReturnType = ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + if (count($functionCall->args) === 0) { + return $defaultReturnType; + } + $argType = $scope->getType($functionCall->args[0]->value); + if ($argType instanceof MixedType) { + return TypeUtils::toBenevolentUnion($defaultReturnType); + } + $result = array_unique(array_map(static function (ConstantStringType $string): bool { + return is_int(strtotime($string->getValue())); + }, TypeUtils::getConstantStrings($argType))); + + if (count($result) !== 1) { + return $defaultReturnType; + } + + return $result[0] ? new IntegerType() : new ConstantBooleanType(false); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/TypeSpecifyingFunctionsDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/TypeSpecifyingFunctionsDynamicReturnTypeExtension.php new file mode 100644 index 00000000..e83ab824 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/TypeSpecifyingFunctionsDynamicReturnTypeExtension.php @@ -0,0 +1,93 @@ +broker = $broker; + } + + public function setTypeSpecifier(TypeSpecifier $typeSpecifier): void + { + $this->typeSpecifier = $typeSpecifier; + } + + public function isFunctionSupported(FunctionReflection $functionReflection): bool + { + return in_array($functionReflection->getName(), [ + 'array_key_exists', + 'in_array', + 'is_numeric', + 'is_int', + 'is_array', + 'is_bool', + 'is_callable', + 'is_float', + 'is_double', + 'is_real', + 'is_iterable', + 'is_null', + 'is_object', + 'is_resource', + 'is_scalar', + 'is_string', + 'is_subclass_of', + ], true); + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + if (count($functionCall->args) === 0) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + $isAlways = $this->getHelper()->findSpecifiedType( + $scope, + $functionCall + ); + if ($isAlways === null) { + return ParametersAcceptorSelector::selectSingle($functionReflection->getVariants())->getReturnType(); + } + + return new ConstantBooleanType($isAlways); + } + + private function getHelper(): ImpossibleCheckTypeHelper + { + if ($this->helper === null) { + $this->helper = new ImpossibleCheckTypeHelper($this->broker, $this->typeSpecifier); + } + + return $this->helper; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/VarExportFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/VarExportFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..b90055cd --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/VarExportFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,58 @@ +getName(), + [ + 'var_export', + 'highlight_file', + 'highlight_string', + 'print_r', + ], + true + ); + } + + public function getTypeFromFunctionCall(\PHPStan\Reflection\FunctionReflection $functionReflection, \PhpParser\Node\Expr\FuncCall $functionCall, \PHPStan\Analyser\Scope $scope): \PHPStan\Type\Type + { + if ($functionReflection->getName() === 'var_export') { + $fallbackReturnType = new NullType(); + } elseif ($functionReflection->getName() === 'print_r') { + $fallbackReturnType = new ConstantBooleanType(true); + } else { + $fallbackReturnType = new BooleanType(); + } + + if (count($functionCall->args) < 1) { + return TypeCombinator::union( + new StringType(), + $fallbackReturnType + ); + } + + if (count($functionCall->args) < 2) { + return $fallbackReturnType; + } + + $returnArgumentType = $scope->getType($functionCall->args[1]->value); + if ((new ConstantBooleanType(true))->isSuperTypeOf($returnArgumentType)->yes()) { + return new StringType(); + } + + return $fallbackReturnType; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php b/vendor/phpstan/phpstan/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php new file mode 100644 index 00000000..d0a6c377 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Php/VersionCompareFunctionDynamicReturnTypeExtension.php @@ -0,0 +1,82 @@ +getName() === 'version_compare'; + } + + public function getTypeFromFunctionCall( + FunctionReflection $functionReflection, + FuncCall $functionCall, + Scope $scope + ): Type + { + if (count($functionCall->args) < 2) { + return ParametersAcceptorSelector::selectFromArgs($scope, $functionCall->args, $functionReflection->getVariants())->getReturnType(); + } + + $version1Strings = TypeUtils::getConstantStrings($scope->getType($functionCall->args[0]->value)); + $version2Strings = TypeUtils::getConstantStrings($scope->getType($functionCall->args[1]->value)); + $counts = [ + count($version1Strings), + count($version2Strings), + ]; + + if (isset($functionCall->args[2])) { + $operatorStrings = TypeUtils::getConstantStrings($scope->getType($functionCall->args[2]->value)); + $counts[] = count($operatorStrings); + $returnType = new BooleanType(); + } else { + $returnType = TypeCombinator::union( + new ConstantIntegerType(-1), + new ConstantIntegerType(0), + new ConstantIntegerType(1) + ); + } + + if (count(array_filter($counts, static function (int $count): bool { + return $count === 0; + })) > 0) { + return $returnType; // one of the arguments is not a constant string + } + + if (count(array_filter($counts, static function (int $count): bool { + return $count > 1; + })) > 1) { + return $returnType; // more than one argument can have multiple possibilities, avoid combinatorial explosion + } + + $types = []; + foreach ($version1Strings as $version1String) { + foreach ($version2Strings as $version2String) { + if (isset($operatorStrings)) { + foreach ($operatorStrings as $operatorString) { + $value = version_compare($version1String->getValue(), $version2String->getValue(), $operatorString->getValue()); + $types[$value] = new ConstantBooleanType($value); + } + } else { + $value = version_compare($version1String->getValue(), $version2String->getValue()); + $types[$value] = new ConstantIntegerType($value); + } + } + } + return TypeCombinator::union(...$types); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/RecursionGuard.php b/vendor/phpstan/phpstan/src/Type/RecursionGuard.php new file mode 100644 index 00000000..1c109fa0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/RecursionGuard.php @@ -0,0 +1,26 @@ +describe(VerbosityLevel::value()); + if (isset(self::$context[$key])) { + return new ErrorType(); + } + + try { + self::$context[$key] = true; + return $callback(); + } finally { + unset(self::$context[$key]); + } + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/ResourceType.php b/vendor/phpstan/phpstan/src/Type/ResourceType.php new file mode 100644 index 00000000..da4f2e61 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/ResourceType.php @@ -0,0 +1,85 @@ +baseClass = $baseClass; + $this->staticObjectType = new ObjectType($baseClass); + } + + public function getClassName(): string + { + return $this->baseClass; + } + + protected function getStaticObjectType(): ObjectType + { + return $this->staticObjectType; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return $this->staticObjectType->getReferencedClasses(); + } + + public function getBaseClass(): string + { + return $this->baseClass; + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + return $this->staticObjectType->accepts($type, $strictTypes); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($type instanceof self) { + return $this->staticObjectType->isSuperTypeOf($type); + } + + if ($type instanceof ObjectWithoutClassType) { + return TrinaryLogic::createMaybe(); + } + + if ($type instanceof ObjectType) { + return TrinaryLogic::createMaybe()->and($this->staticObjectType->isSuperTypeOf($type)); + } + + if ($type instanceof CompoundType) { + return $type->isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $this->staticObjectType->equals($type); + } + + public function describe(VerbosityLevel $level): string + { + return sprintf('static(%s)', $this->staticObjectType->describe($level)); + } + + public function canAccessProperties(): TrinaryLogic + { + return $this->staticObjectType->canAccessProperties(); + } + + public function hasProperty(string $propertyName): TrinaryLogic + { + return $this->staticObjectType->hasProperty($propertyName); + } + + public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection + { + return $this->staticObjectType->getProperty($propertyName, $scope); + } + + public function canCallMethods(): TrinaryLogic + { + return $this->staticObjectType->canCallMethods(); + } + + public function hasMethod(string $methodName): TrinaryLogic + { + return $this->staticObjectType->hasMethod($methodName); + } + + public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection + { + return $this->staticObjectType->getMethod($methodName, $scope); + } + + public function canAccessConstants(): TrinaryLogic + { + return $this->staticObjectType->canAccessConstants(); + } + + public function hasConstant(string $constantName): TrinaryLogic + { + return $this->staticObjectType->hasConstant($constantName); + } + + public function getConstant(string $constantName): ConstantReflection + { + return $this->staticObjectType->getConstant($constantName); + } + + public function resolveStatic(string $className): Type + { + return new ObjectType($className); + } + + public function changeBaseClass(string $className): StaticResolvableType + { + $thisClass = static::class; + return new $thisClass($className); + } + + public function isIterable(): TrinaryLogic + { + return $this->staticObjectType->isIterable(); + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return $this->staticObjectType->isIterableAtLeastOnce(); + } + + public function getIterableKeyType(): Type + { + return $this->staticObjectType->getIterableKeyType(); + } + + public function getIterableValueType(): Type + { + return $this->staticObjectType->getIterableValueType(); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return $this->staticObjectType->isInstanceOf(\ArrayAccess::class); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + return $this->staticObjectType->hasOffsetValueType($offsetType); + } + + public function getOffsetValueType(Type $offsetType): Type + { + return $this->staticObjectType->getOffsetValueType($offsetType); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return $this->staticObjectType->setOffsetValueType($offsetType, $valueType); + } + + public function isCallable(): TrinaryLogic + { + return $this->staticObjectType->isCallable(); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + return $this->staticObjectType->getCallableParametersAcceptors($scope); + } + + public function isCloneable(): TrinaryLogic + { + return TrinaryLogic::createYes(); + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toString(): Type + { + return $this->staticObjectType->toString(); + } + + public function toInteger(): Type + { + return new ErrorType(); + } + + public function toFloat(): Type + { + return new ErrorType(); + } + + public function toArray(): Type + { + return $this->staticObjectType->toArray(); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new static($properties['baseClass']); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/StringAlwaysAcceptingObjectWithToStringType.php b/vendor/phpstan/phpstan/src/Type/StringAlwaysAcceptingObjectWithToStringType.php new file mode 100644 index 00000000..1be51648 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/StringAlwaysAcceptingObjectWithToStringType.php @@ -0,0 +1,28 @@ +hasClass($type->getClassName())) { + return TrinaryLogic::createNo(); + } + + $typeClass = $broker->getClass($type->getClassName()); + return TrinaryLogic::createFromBoolean( + $typeClass->hasNativeMethod('__toString') + ); + } + + return parent::accepts($type, $strictTypes); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/StringType.php b/vendor/phpstan/phpstan/src/Type/StringType.php new file mode 100644 index 00000000..2db4264f --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/StringType.php @@ -0,0 +1,128 @@ +isSuperTypeOf($offsetType)->and(TrinaryLogic::createMaybe()); + } + + public function getOffsetValueType(Type $offsetType): Type + { + if ($this->hasOffsetValueType($offsetType)->no()) { + return new ErrorType(); + } + + return new StringType(); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + if ($offsetType === null) { + return new ErrorType(); + } + + $valueStringType = $valueType->toString(); + if ($valueStringType instanceof ErrorType) { + return new ErrorType(); + } + + if ((new IntegerType())->isSuperTypeOf($offsetType)->yes()) { + return new StringType(); + } + + return new ErrorType(); + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof self) { + return TrinaryLogic::createYes(); + } + + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + if ($type instanceof TypeWithClassName && !$strictTypes) { + $broker = Broker::getInstance(); + if (!$broker->hasClass($type->getClassName())) { + return TrinaryLogic::createNo(); + } + + $typeClass = $broker->getClass($type->getClassName()); + return TrinaryLogic::createFromBoolean( + $typeClass->hasNativeMethod('__toString') + ); + } + + return TrinaryLogic::createNo(); + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toInteger(): Type + { + return new IntegerType(); + } + + public function toFloat(): Type + { + return new FloatType(); + } + + public function toString(): Type + { + return $this; + } + + public function toArray(): Type + { + return new ConstantArrayType( + [new ConstantIntegerType(0)], + [$this], + 1 + ); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/ThisType.php b/vendor/phpstan/phpstan/src/Type/ThisType.php new file mode 100644 index 00000000..8c8dc5f9 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/ThisType.php @@ -0,0 +1,27 @@ +getStaticObjectType()->describe($level)); + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + return TrinaryLogic::createFromBoolean( + $type instanceof self + && $type->getBaseClass() === $this->getBaseClass() + ); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Traits/ConstantScalarTypeTrait.php b/vendor/phpstan/phpstan/src/Type/Traits/ConstantScalarTypeTrait.php new file mode 100644 index 00000000..7fd1f9af --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Traits/ConstantScalarTypeTrait.php @@ -0,0 +1,53 @@ +value === $type->value); + } + + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + return TrinaryLogic::createNo(); + } + + public function isSuperTypeOf(Type $type): TrinaryLogic + { + if ($type instanceof self) { + return $this->value === $type->value ? TrinaryLogic::createYes() : TrinaryLogic::createNo(); + } + + if ($type instanceof parent) { + return TrinaryLogic::createMaybe(); + } + + if ($type instanceof CompoundType) { + return $type->isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $type instanceof self && $this->value === $type->value; + } + + public function generalize(): Type + { + return new parent(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/Traits/FalseyBooleanTypeTrait.php b/vendor/phpstan/phpstan/src/Type/Traits/FalseyBooleanTypeTrait.php new file mode 100644 index 00000000..ca1e75ef --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/Traits/FalseyBooleanTypeTrait.php @@ -0,0 +1,16 @@ +getTypes() as $unionTypeToRemove) { + $fromType = self::remove($fromType, $unionTypeToRemove); + } + return $fromType; + } + + if ($fromType instanceof UnionType) { + $innerTypes = []; + foreach ($fromType->getTypes() as $innerType) { + $innerTypes[] = self::remove($innerType, $typeToRemove); + } + + return self::union(...$innerTypes); + } + + if ($fromType instanceof BooleanType && $fromType->isSuperTypeOf(new BooleanType())->yes()) { + if ($typeToRemove instanceof ConstantBooleanType) { + return new ConstantBooleanType(!$typeToRemove->getValue()); + } + } elseif ($fromType instanceof IterableType) { + $traversableType = new ObjectType(\Traversable::class); + $arrayType = new ArrayType(new MixedType(), new MixedType()); + if ($typeToRemove->isSuperTypeOf($arrayType)->yes()) { + return $traversableType; + } + if ($typeToRemove->isSuperTypeOf($traversableType)->yes()) { + return $arrayType; + } + } + + if ($typeToRemove->isSuperTypeOf($fromType)->yes()) { + return new NeverType(); + } + + if ( + (new ArrayType(new MixedType(), new MixedType()))->isSuperTypeOf($fromType)->yes() + ) { + if ($typeToRemove instanceof ConstantArrayType + && $typeToRemove->isIterableAtLeastOnce()->no()) { + return self::intersect($fromType, new NonEmptyArrayType()); + } + + if ($typeToRemove instanceof NonEmptyArrayType) { + return new ConstantArrayType([], []); + } + } + + return $fromType; + } + + public static function removeNull(Type $type): Type + { + return self::remove($type, new NullType()); + } + + public static function containsNull(Type $type): bool + { + if ($type instanceof UnionType) { + foreach ($type->getTypes() as $innerType) { + if ($innerType instanceof NullType) { + return true; + } + } + + return false; + } + + return $type instanceof NullType; + } + + public static function union(Type ...$types): Type + { + // transform A | (B | C) to A | B | C + for ($i = 0; $i < count($types); $i++) { + if (!($types[$i] instanceof UnionType)) { + continue; + } + + array_splice($types, $i, 1, $types[$i]->getTypes()); + } + + $typesCount = count($types); + $arrayTypes = []; + $arrayAccessoryTypes = []; + $scalarTypes = []; + $hasGenericScalarTypes = []; + for ($i = 0; $i < $typesCount; $i++) { + if ($types[$i] instanceof NeverType) { + unset($types[$i]); + continue; + } + if ($types[$i] instanceof MixedType) { + return $types[$i]; + } + if ($types[$i] instanceof ConstantScalarType) { + $type = $types[$i]; + $scalarTypes[get_class($type)][md5($type->describe(VerbosityLevel::precise()))] = $type; + unset($types[$i]); + continue; + } + if ($types[$i] instanceof BooleanType) { + $hasGenericScalarTypes[ConstantBooleanType::class] = true; + } + if ($types[$i] instanceof FloatType) { + $hasGenericScalarTypes[ConstantFloatType::class] = true; + } + if ($types[$i] instanceof IntegerType) { + $hasGenericScalarTypes[ConstantIntegerType::class] = true; + } + if ($types[$i] instanceof StringType) { + $hasGenericScalarTypes[ConstantStringType::class] = true; + } + if ($types[$i] instanceof IntersectionType) { + $intermediateArrayType = null; + $intermediateAccessoryTypes = []; + foreach ($types[$i]->getTypes() as $innerType) { + if ($innerType instanceof ArrayType) { + $intermediateArrayType = $innerType; + continue; + } + if ($innerType instanceof AccessoryType || $innerType instanceof CallableType) { + $intermediateAccessoryTypes[] = $innerType; + continue; + } + } + + if ($intermediateArrayType !== null) { + $arrayTypes[] = $intermediateArrayType; + $arrayAccessoryTypes = array_merge($arrayAccessoryTypes, $intermediateAccessoryTypes); + unset($types[$i]); + continue; + } + } + if (!$types[$i] instanceof ArrayType) { + continue; + } + + $arrayTypes[] = $types[$i]; + unset($types[$i]); + } + + /** @var ArrayType[] $arrayTypes */ + $arrayTypes = $arrayTypes; + + $types = array_values( + array_merge($types, self::processArrayTypes($arrayTypes, $arrayAccessoryTypes)) + ); + + // simplify string[] | int[] to (string|int)[] + for ($i = 0; $i < count($types); $i++) { + for ($j = $i + 1; $j < count($types); $j++) { + if ($types[$i] instanceof IterableType && $types[$j] instanceof IterableType) { + $types[$i] = new IterableType( + self::union($types[$i]->getIterableKeyType(), $types[$j]->getIterableKeyType()), + self::union($types[$i]->getIterableValueType(), $types[$j]->getIterableValueType()) + ); + array_splice($types, $j, 1); + continue 2; + } + } + } + + // transform A | A to A + // transform A | never to A + for ($i = 0; $i < count($types); $i++) { + for ($j = $i + 1; $j < count($types); $j++) { + if ( + !$types[$j] instanceof ConstantArrayType + && $types[$j]->isSuperTypeOf($types[$i])->yes() + ) { + array_splice($types, $i--, 1); + continue 2; + } + + if ( + !$types[$i] instanceof ConstantArrayType + && $types[$i]->isSuperTypeOf($types[$j])->yes() + ) { + array_splice($types, $j--, 1); + continue 1; + } + } + } + + foreach ($scalarTypes as $classType => $scalarTypeItems) { + if (isset($hasGenericScalarTypes[$classType])) { + continue; + } + if ($classType === ConstantBooleanType::class && count($scalarTypeItems) === 2) { + $types[] = new BooleanType(); + continue; + } + foreach ($scalarTypeItems as $type) { + if (count($scalarTypeItems) > self::CONSTANT_SCALAR_UNION_THRESHOLD) { + $types[] = $type->generalize(); + break; + } + $types[] = $type; + } + } + + if (count($types) === 0) { + return new NeverType(); + + } elseif (count($types) === 1) { + return $types[0]; + } + + return new UnionType($types); + } + + /** + * @param ArrayType[] $arrayTypes + * @param Type[] $accessoryTypes + * @return Type[] + */ + private static function processArrayTypes(array $arrayTypes, array $accessoryTypes): array + { + foreach ($arrayTypes as $arrayType) { + if (!$arrayType instanceof ConstantArrayType) { + continue; + } + if (count($arrayType->getKeyTypes()) > 0) { + continue; + } + + foreach ($accessoryTypes as $i => $accessoryType) { + if (!$accessoryType instanceof NonEmptyArrayType) { + continue; + } + + unset($accessoryTypes[$i]); + break 2; + } + } + if (count($arrayTypes) === 0) { + return []; + } elseif (count($arrayTypes) === 1) { + return [ + self::intersect($arrayTypes[0], ...$accessoryTypes), + ]; + } + + $keyTypesForGeneralArray = []; + $valueTypesForGeneralArray = []; + $generalArrayOcurred = false; + $constantKeyTypesNumbered = []; + + /** @var int|float $nextConstantKeyTypeIndex */ + $nextConstantKeyTypeIndex = 1; + + foreach ($arrayTypes as $arrayType) { + if (!$arrayType instanceof ConstantArrayType || $generalArrayOcurred) { + $keyTypesForGeneralArray[] = $arrayType->getKeyType(); + $valueTypesForGeneralArray[] = $arrayType->getItemType(); + $generalArrayOcurred = true; + continue; + } + + foreach ($arrayType->getKeyTypes() as $i => $keyType) { + $keyTypesForGeneralArray[] = $keyType; + $valueTypesForGeneralArray[] = $arrayType->getValueTypes()[$i]; + + $keyTypeValue = $keyType->getValue(); + if (array_key_exists($keyTypeValue, $constantKeyTypesNumbered)) { + continue; + } + + $constantKeyTypesNumbered[$keyTypeValue] = $nextConstantKeyTypeIndex; + $nextConstantKeyTypeIndex *= 2; + if (!is_int($nextConstantKeyTypeIndex)) { + $generalArrayOcurred = true; + continue; + } + } + } + + $createGeneralArray = static function () use ($keyTypesForGeneralArray, $valueTypesForGeneralArray, $accessoryTypes): Type { + return TypeCombinator::intersect(new ArrayType( + self::union(...$keyTypesForGeneralArray), + self::union(...$valueTypesForGeneralArray) + ), ...$accessoryTypes); + }; + + if ($generalArrayOcurred) { + return [ + $createGeneralArray(), + ]; + } + + /** @var ConstantArrayType[] $arrayTypes */ + $arrayTypes = $arrayTypes; + + /** @var int[] $constantKeyTypesNumbered */ + $constantKeyTypesNumbered = $constantKeyTypesNumbered; + + $constantArraysBuckets = []; + foreach ($arrayTypes as $arrayType) { + $arrayIndex = 0; + foreach ($arrayType->getKeyTypes() as $keyType) { + $arrayIndex += $constantKeyTypesNumbered[$keyType->getValue()]; + } + + if (!array_key_exists($arrayIndex, $constantArraysBuckets)) { + $bucket = []; + foreach ($arrayType->getKeyTypes() as $i => $keyType) { + $bucket[$keyType->getValue()] = [ + 'keyType' => $keyType, + 'valueType' => $arrayType->getValueTypes()[$i], + ]; + } + $constantArraysBuckets[$arrayIndex] = $bucket; + continue; + } + + $bucket = $constantArraysBuckets[$arrayIndex]; + foreach ($arrayType->getKeyTypes() as $i => $keyType) { + $bucket[$keyType->getValue()]['valueType'] = self::union( + $bucket[$keyType->getValue()]['valueType'], + $arrayType->getValueTypes()[$i] + ); + } + + $constantArraysBuckets[$arrayIndex] = $bucket; + } + + if (count($constantArraysBuckets) > self::CONSTANT_ARRAY_UNION_THRESHOLD) { + return [ + $createGeneralArray(), + ]; + } + + $resultArrays = []; + foreach ($constantArraysBuckets as $bucket) { + $builder = ConstantArrayTypeBuilder::createEmpty(); + foreach ($bucket as $data) { + $builder->setOffsetValueType($data['keyType'], $data['valueType']); + } + + $resultArrays[] = self::intersect($builder->getArray(), ...$accessoryTypes); + } + + return $resultArrays; + } + + public static function intersect(Type ...$types): Type + { + // transform A & (B | C) to (A & B) | (A & C) + foreach ($types as $i => $type) { + if ($type instanceof UnionType) { + $topLevelUnionSubTypes = []; + foreach ($type->getTypes() as $innerUnionSubType) { + $topLevelUnionSubTypes[] = self::intersect( + $innerUnionSubType, + ...array_slice($types, 0, $i), + ...array_slice($types, $i + 1) + ); + } + + return self::union(...$topLevelUnionSubTypes); + } + } + + // transform A & (B & C) to A & B & C + foreach ($types as $i => &$type) { + if (!($type instanceof IntersectionType)) { + continue; + } + + array_splice($types, $i, 1, $type->getTypes()); + } + + // transform IntegerType & ConstantIntegerType to ConstantIntegerType + // transform Child & Parent to Child + // transform Object & ~null to Object + // transform A & A to A + // transform int[] & string to never + // transform callable & int to never + // transform A & ~A to never + // transform int & string to never + for ($i = 0; $i < count($types); $i++) { + for ($j = $i + 1; $j < count($types); $j++) { + $isSuperTypeA = $types[$j]->isSuperTypeOf($types[$i]); + if ($isSuperTypeA->no()) { + return new NeverType(); + + } elseif ($isSuperTypeA->yes()) { + array_splice($types, $j--, 1); + continue; + } + + $isSuperTypeB = $types[$i]->isSuperTypeOf($types[$j]); + if ($isSuperTypeB->maybe()) { + continue; + + } + + if ($isSuperTypeB->yes()) { + array_splice($types, $i--, 1); + continue 2; + } + } + } + + if (count($types) === 1) { + return $types[0]; + + } + + return new IntersectionType($types); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/TypeUtils.php b/vendor/phpstan/phpstan/src/Type/TypeUtils.php new file mode 100644 index 00000000..b24d06bf --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/TypeUtils.php @@ -0,0 +1,206 @@ +generalize(); + } elseif ($type instanceof UnionType) { + return TypeCombinator::union(...array_map(static function (Type $innerType): Type { + return self::generalizeType($innerType); + }, $type->getTypes())); + } + + return $type; + } + + /** + * @param Type $type + * @return string[] + */ + public static function getDirectClassNames(Type $type): array + { + if ($type instanceof TypeWithClassName) { + return [$type->getClassName()]; + } + + if ($type instanceof UnionType || $type instanceof IntersectionType) { + $classNames = []; + foreach ($type->getTypes() as $innerType) { + if (!$innerType instanceof TypeWithClassName) { + continue; + } + + $classNames[] = $innerType->getClassName(); + } + + return $classNames; + } + + return []; + } + + /** + * @param Type $type + * @return \PHPStan\Type\ConstantScalarType[] + */ + public static function getConstantScalars(Type $type): array + { + return self::map(ConstantScalarType::class, $type, false); + } + + /** + * @param string $typeClass + * @param Type $type + * @param bool $inspectIntersections + * @return mixed[] + */ + private static function map( + string $typeClass, + Type $type, + bool $inspectIntersections + ): array + { + if ($type instanceof $typeClass) { + return [$type]; + } + + if ($type instanceof UnionType) { + $matchingTypes = []; + foreach ($type->getTypes() as $innerType) { + if (!$innerType instanceof $typeClass) { + return []; + } + + $matchingTypes[] = $innerType; + } + + return $matchingTypes; + } + + if ($inspectIntersections && $type instanceof IntersectionType) { + $matchingTypes = []; + foreach ($type->getTypes() as $innerType) { + if (!$innerType instanceof $typeClass) { + continue; + } + + $matchingTypes[] = $innerType; + } + + return $matchingTypes; + } + + return []; + } + + public static function toBenevolentUnion(Type $type): Type + { + if ($type instanceof BenevolentUnionType) { + return $type; + } + + if ($type instanceof UnionType) { + return new BenevolentUnionType($type->getTypes()); + } + + return $type; + } + + /** + * @param Type $type + * @return Type[] + */ + public static function flattenTypes(Type $type): array + { + if ($type instanceof UnionType) { + return $type->getTypes(); + } + + return [$type]; + } + + public static function findThisType(Type $type): ?ThisType + { + if ($type instanceof ThisType) { + return $type; + } + + if ($type instanceof UnionType || $type instanceof IntersectionType) { + foreach ($type->getTypes() as $innerType) { + $thisType = self::findThisType($innerType); + if ($thisType !== null) { + return $thisType; + } + } + } + + return null; + } + + /** + * @param Type $type + * @return HasPropertyType[] + */ + public static function getHasPropertyTypes(Type $type): array + { + if ($type instanceof HasPropertyType) { + return [$type]; + } + + if ($type instanceof UnionType || $type instanceof IntersectionType) { + $hasPropertyTypes = []; + foreach ($type->getTypes() as $innerType) { + $hasPropertyTypes = array_merge($hasPropertyTypes, self::getHasPropertyTypes($innerType)); + } + return $hasPropertyTypes; + } + + return []; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/TypeWithClassName.php b/vendor/phpstan/phpstan/src/Type/TypeWithClassName.php new file mode 100644 index 00000000..be37ae6d --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/TypeWithClassName.php @@ -0,0 +1,10 @@ +hasClass($selfClass)) { + $classReflection = $broker->getClass($selfClass); + if ($classReflection->getParentClass() !== false) { + return new ObjectType($classReflection->getParentClass()->getName()); + } + } + return new NonexistentParentClassType(); + default: + return new ObjectType($typeString); + } + } + + public static function decideTypeFromReflection( + ?\ReflectionType $reflectionType, + ?Type $phpDocType = null, + ?string $selfClass = null, + bool $isVariadic = false + ): Type + { + if ($reflectionType === null) { + return $phpDocType ?? new MixedType(); + } + + $reflectionTypeString = (string) $reflectionType; + if (\Nette\Utils\Strings::endsWith(strtolower($reflectionTypeString), '\\object')) { + $reflectionTypeString = 'object'; + } + $type = self::getTypeObjectFromTypehint($reflectionTypeString, $selfClass); + if ($reflectionType->allowsNull()) { + $type = TypeCombinator::addNull($type); + } + + if ($isVariadic) { + $type = new ArrayType(new IntegerType(), $type); + } + + return self::decideType($type, $phpDocType); + } + + public static function decideType( + Type $type, + ?Type $phpDocType = null + ): Type + { + if ($phpDocType !== null && !$phpDocType instanceof ErrorType) { + if ($type instanceof VoidType || $phpDocType instanceof VoidType) { + return new VoidType(); + } + + if (TypeCombinator::removeNull($type) instanceof IterableType) { + if ($phpDocType instanceof UnionType) { + $innerTypes = []; + foreach ($phpDocType->getTypes() as $innerType) { + if ($innerType instanceof ArrayType) { + $innerTypes[] = new IterableType( + $innerType->getKeyType(), + $innerType->getItemType() + ); + } else { + $innerTypes[] = $innerType; + } + } + $phpDocType = new UnionType($innerTypes); + } elseif ($phpDocType instanceof ArrayType) { + $phpDocType = new IterableType( + $phpDocType->getKeyType(), + $phpDocType->getItemType() + ); + } + } + + $resultType = $type->isSuperTypeOf($phpDocType)->yes() ? $phpDocType : $type; + if (TypeCombinator::containsNull($type)) { + $type = TypeCombinator::addNull($resultType); + } else { + $type = $resultType; + } + } + + return $type; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/UnionType.php b/vendor/phpstan/phpstan/src/Type/UnionType.php new file mode 100644 index 00000000..fde1f056 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/UnionType.php @@ -0,0 +1,561 @@ +describe(VerbosityLevel::value()); + }, $types)) + )); + }; + if (count($types) < 2) { + $throwException(); + } + foreach ($types as $type) { + if (!($type instanceof UnionType)) { + continue; + } + + $throwException(); + } + $this->types = UnionTypeHelper::sortTypes($types); + } + + /** + * @return \PHPStan\Type\Type[] + */ + public function getTypes(): array + { + return $this->types; + } + + /** + * @return string[] + */ + public function getReferencedClasses(): array + { + return UnionTypeHelper::getReferencedClasses($this->getTypes()); + } + + public function accepts(Type $type, bool $strictTypes): TrinaryLogic + { + if ($type instanceof CompoundType) { + return CompoundTypeHelper::accepts($type, $this, $strictTypes); + } + + $results = []; + foreach ($this->getTypes() as $innerType) { + $results[] = $innerType->accepts($type, $strictTypes); + } + + return TrinaryLogic::createNo()->or(...$results); + } + + public function isSuperTypeOf(Type $otherType): TrinaryLogic + { + if ($otherType instanceof self || $otherType instanceof IterableType) { + return $otherType->isSubTypeOf($this); + } + + $results = []; + foreach ($this->getTypes() as $innerType) { + $results[] = $innerType->isSuperTypeOf($otherType); + } + + return TrinaryLogic::createNo()->or(...$results); + } + + public function isSubTypeOf(Type $otherType): TrinaryLogic + { + $results = []; + foreach ($this->getTypes() as $innerType) { + $results[] = $otherType->isSuperTypeOf($innerType); + } + + return TrinaryLogic::extremeIdentity(...$results); + } + + public function equals(Type $type): bool + { + if (!$type instanceof self) { + return false; + } + + if (count($this->types) !== count($type->types)) { + return false; + } + + foreach ($this->types as $i => $innerType) { + if (!$innerType->equals($type->types[$i])) { + return false; + } + } + + return true; + } + + public function describe(VerbosityLevel $level): string + { + $joinTypes = static function (array $types) use ($level): string { + $typeNames = []; + foreach ($types as $type) { + if ($type instanceof IntersectionType || $type instanceof ClosureType || $type instanceof CallableType) { + $typeNames[] = sprintf('(%s)', $type->describe($level)); + } else { + $typeNames[] = $type->describe($level); + } + } + + return implode('|', $typeNames); + }; + + return $level->handle( + function () use ($joinTypes): string { + $types = TypeCombinator::union(...array_map(static function (Type $type): Type { + if ( + $type instanceof ConstantType + && !$type instanceof ConstantBooleanType + ) { + return $type->generalize(); + } + + return $type; + }, $this->types)); + + if ($types instanceof UnionType) { + return $joinTypes($types->getTypes()); + } + + return $joinTypes([$types]); + }, + function () use ($joinTypes): string { + $arrayDescription = []; + $constantArrays = []; + $commonTypes = []; + + foreach ($this->types as $type) { + if (!$type instanceof ConstantArrayType) { + $commonTypes[] = $type; + continue; + } + + $constantArrays[] = $type; + foreach ($type->getKeyTypes() as $i => $keyType) { + if (!isset($arrayDescription[$keyType->getValue()])) { + $arrayDescription[$keyType->getValue()] = [ + 'key' => $keyType, + 'value' => $type->getValueTypes()[$i], + 'count' => 1, + ]; + continue; + } + + $arrayDescription[$keyType->getValue()] = [ + 'key' => $keyType, + 'value' => TypeCombinator::union( + $arrayDescription[$keyType->getValue()]['value'], + $type->getValueTypes()[$i] + ), + 'count' => $arrayDescription[$keyType->getValue()]['count'] + 1, + ]; + } + } + + $someKeyCountIsHigherThanOne = false; + foreach ($arrayDescription as $value) { + if ($value['count'] > 1) { + $someKeyCountIsHigherThanOne = true; + break; + } + } + + if (!$someKeyCountIsHigherThanOne) { + return $joinTypes(UnionTypeHelper::sortTypes(array_merge( + $commonTypes, + $constantArrays + ))); + } + + $constantArraysCount = count($constantArrays); + $constantArraysDescriptions = []; + foreach ($arrayDescription as $value) { + $constantArraysDescriptions[] = sprintf( + '%s%s => %s', + $value['count'] < $constantArraysCount ? '?' : '', + $value['key']->describe(VerbosityLevel::value()), + $value['value']->describe(VerbosityLevel::value()) + ); + } + + $description = ''; + if (count($commonTypes) > 0) { + $description = $joinTypes($commonTypes); + if (count($constantArraysDescriptions) > 0) { + $description .= '|'; + } + } + + if (count($constantArraysDescriptions) > 0) { + $description .= 'array(' . implode(', ', $constantArraysDescriptions) . ')'; + } + + return $description; + } + ); + } + + /** + * @param callable(Type $type): TrinaryLogic $canCallback + * @param callable(Type $type): TrinaryLogic $hasCallback + * @return TrinaryLogic + */ + private function hasInternal( + callable $canCallback, + callable $hasCallback + ): TrinaryLogic + { + $results = []; + foreach ($this->types as $type) { + if ($canCallback($type)->no()) { + $results[] = TrinaryLogic::createNo(); + continue; + } + $results[] = $hasCallback($type); + } + + return TrinaryLogic::extremeIdentity(...$results); + } + + /** + * @param callable(Type $type): TrinaryLogic $hasCallback + * @param callable(Type $type): object $getCallback + * @return object + */ + private function getInternal( + callable $hasCallback, + callable $getCallback + ) + { + /** @var TrinaryLogic|null $result */ + $result = null; + + /** @var object|null $object */ + $object = null; + foreach ($this->types as $type) { + $has = $hasCallback($type); + if (!$has->yes()) { + continue; + } + if ($result !== null && $result->compareTo($has) !== $has) { + continue; + } + + $get = $getCallback($type); + $result = $has; + $object = $get; + } + + if ($object === null) { + throw new \PHPStan\ShouldNotHappenException(); + } + + return $object; + } + + public function canAccessProperties(): TrinaryLogic + { + return $this->unionResults(static function (Type $type): TrinaryLogic { + return $type->canAccessProperties(); + }); + } + + public function hasProperty(string $propertyName): TrinaryLogic + { + return $this->unionResults(static function (Type $type) use ($propertyName): TrinaryLogic { + return $type->hasProperty($propertyName); + }); + } + + public function getProperty(string $propertyName, ClassMemberAccessAnswerer $scope): PropertyReflection + { + return $this->getInternal( + static function (Type $type) use ($propertyName): TrinaryLogic { + return $type->hasProperty($propertyName); + }, + static function (Type $type) use ($propertyName, $scope): PropertyReflection { + return $type->getProperty($propertyName, $scope); + } + ); + } + + public function canCallMethods(): TrinaryLogic + { + return $this->unionResults(static function (Type $type): TrinaryLogic { + return $type->canCallMethods(); + }); + } + + public function hasMethod(string $methodName): TrinaryLogic + { + return $this->unionResults(static function (Type $type) use ($methodName): TrinaryLogic { + return $type->hasMethod($methodName); + }); + } + + public function getMethod(string $methodName, ClassMemberAccessAnswerer $scope): MethodReflection + { + return $this->getInternal( + static function (Type $type) use ($methodName): TrinaryLogic { + return $type->hasMethod($methodName); + }, + static function (Type $type) use ($methodName, $scope): MethodReflection { + return $type->getMethod($methodName, $scope); + } + ); + } + + public function canAccessConstants(): TrinaryLogic + { + return $this->unionResults(static function (Type $type): TrinaryLogic { + return $type->canAccessConstants(); + }); + } + + public function hasConstant(string $constantName): TrinaryLogic + { + return $this->hasInternal( + static function (Type $type): TrinaryLogic { + return $type->canAccessConstants(); + }, + static function (Type $type) use ($constantName): TrinaryLogic { + return $type->hasConstant($constantName); + } + ); + } + + public function getConstant(string $constantName): ConstantReflection + { + return $this->getInternal( + static function (Type $type) use ($constantName): TrinaryLogic { + return $type->hasConstant($constantName); + }, + static function (Type $type) use ($constantName): ConstantReflection { + return $type->getConstant($constantName); + } + ); + } + + public function resolveStatic(string $className): Type + { + return new self(UnionTypeHelper::resolveStatic($className, $this->getTypes())); + } + + public function changeBaseClass(string $className): StaticResolvableType + { + return new self(UnionTypeHelper::changeBaseClass($className, $this->getTypes())); + } + + public function isIterable(): TrinaryLogic + { + return $this->unionResults(static function (Type $type): TrinaryLogic { + return $type->isIterable(); + }); + } + + public function isIterableAtLeastOnce(): TrinaryLogic + { + return $this->unionResults(static function (Type $type): TrinaryLogic { + return $type->isIterableAtLeastOnce(); + }); + } + + public function getIterableKeyType(): Type + { + return $this->unionTypes(static function (Type $type): Type { + return $type->getIterableKeyType(); + }); + } + + public function getIterableValueType(): Type + { + return $this->unionTypes(static function (Type $type): Type { + return $type->getIterableValueType(); + }); + } + + public function isOffsetAccessible(): TrinaryLogic + { + return $this->unionResults(static function (Type $type): TrinaryLogic { + return $type->isOffsetAccessible(); + }); + } + + public function hasOffsetValueType(Type $offsetType): TrinaryLogic + { + return $this->unionResults(static function (Type $type) use ($offsetType): TrinaryLogic { + return $type->hasOffsetValueType($offsetType); + }); + } + + public function getOffsetValueType(Type $offsetType): Type + { + $types = []; + foreach ($this->types as $innerType) { + $valueType = $innerType->getOffsetValueType($offsetType); + if ($valueType instanceof ErrorType) { + continue; + } + + $types[] = $valueType; + } + + if (count($types) === 0) { + return new ErrorType(); + } + + return TypeCombinator::union(...$types); + } + + public function setOffsetValueType(?Type $offsetType, Type $valueType): Type + { + return $this->unionTypes(static function (Type $type) use ($offsetType, $valueType): Type { + return $type->setOffsetValueType($offsetType, $valueType); + }); + } + + public function isCallable(): TrinaryLogic + { + return $this->unionResults(static function (Type $type): TrinaryLogic { + return $type->isCallable(); + }); + } + + /** + * @param \PHPStan\Reflection\ClassMemberAccessAnswerer $scope + * @return \PHPStan\Reflection\ParametersAcceptor[] + */ + public function getCallableParametersAcceptors(ClassMemberAccessAnswerer $scope): array + { + foreach ($this->types as $type) { + if ($type->isCallable()->no()) { + continue; + } + + return $type->getCallableParametersAcceptors($scope); + } + + throw new \PHPStan\ShouldNotHappenException(); + } + + public function isCloneable(): TrinaryLogic + { + return $this->unionResults(static function (Type $type): TrinaryLogic { + return $type->isCloneable(); + }); + } + + public function toBoolean(): BooleanType + { + /** @var BooleanType $type */ + $type = $this->unionTypes(static function (Type $type): BooleanType { + return $type->toBoolean(); + }); + + return $type; + } + + public function toNumber(): Type + { + $type = $this->unionTypes(static function (Type $type): Type { + return $type->toNumber(); + }); + + return $type; + } + + public function toString(): Type + { + $type = $this->unionTypes(static function (Type $type): Type { + return $type->toString(); + }); + + return $type; + } + + public function toInteger(): Type + { + $type = $this->unionTypes(static function (Type $type): Type { + return $type->toInteger(); + }); + + return $type; + } + + public function toFloat(): Type + { + $type = $this->unionTypes(static function (Type $type): Type { + return $type->toFloat(); + }); + + return $type; + } + + public function toArray(): Type + { + $type = $this->unionTypes(static function (Type $type): Type { + return $type->toArray(); + }); + + return $type; + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self($properties['types']); + } + + /** + * @param callable(Type $type): TrinaryLogic $getResult + * @return TrinaryLogic + */ + private function unionResults(callable $getResult): TrinaryLogic + { + return TrinaryLogic::extremeIdentity(...array_map($getResult, $this->types)); + } + + /** + * @param callable(Type $type): Type $getType + * @return Type + */ + protected function unionTypes(callable $getType): Type + { + return TypeCombinator::union(...array_map($getType, $this->types)); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/UnionTypeHelper.php b/vendor/phpstan/phpstan/src/Type/UnionTypeHelper.php new file mode 100644 index 00000000..49ab895a --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/UnionTypeHelper.php @@ -0,0 +1,123 @@ + $type) { + if (!($type instanceof StaticResolvableType)) { + continue; + } + + $types[$i] = $type->resolveStatic($className); + } + + return $types; + } + + /** + * @param string $className + * @param \PHPStan\Type\Type[] $types + * @return \PHPStan\Type\Type[] + */ + public static function changeBaseClass(string $className, array $types): array + { + foreach ($types as $i => $type) { + if (!($type instanceof StaticResolvableType)) { + continue; + } + + $types[$i] = $type->changeBaseClass($className); + } + + return $types; + } + + /** + * @param \PHPStan\Type\Type[] $types + * @return string[] + */ + public static function getReferencedClasses(array $types): array + { + $subTypeClasses = []; + foreach ($types as $type) { + $subTypeClasses[] = $type->getReferencedClasses(); + } + + return array_merge(...$subTypeClasses); + } + + /** + * @param \PHPStan\Type\Type[] $types + * @return \PHPStan\Type\Type[] + */ + public static function sortTypes(array $types): array + { + usort($types, static function (Type $a, Type $b): float { + if ($a instanceof NullType) { + return 1; + } elseif ($b instanceof NullType) { + return -1; + } + + if ($a instanceof AccessoryType) { + if ($b instanceof AccessoryType) { + return strcasecmp($a->describe(VerbosityLevel::value()), $b->describe(VerbosityLevel::value())); + } + + return 1; + } + if ($b instanceof AccessoryType) { + return -1; + } + + $aIsNullOrBool = ($a instanceof NullType || $a instanceof ConstantBooleanType); + $bIsNullOrBool = ($b instanceof NullType || $b instanceof ConstantBooleanType); + if ($aIsNullOrBool && !$bIsNullOrBool) { + return 1; + } elseif ($bIsNullOrBool && !$aIsNullOrBool) { + return -1; + } + if ($a instanceof ConstantScalarType && !$b instanceof ConstantScalarType) { + return -1; + } elseif (!$a instanceof ConstantScalarType && $b instanceof ConstantScalarType) { + return 1; + } + + if ( + ( + $a instanceof ConstantIntegerType + || $a instanceof ConstantFloatType + ) + && ( + $b instanceof ConstantIntegerType + || $b instanceof ConstantFloatType + ) + ) { + return $a->getValue() - $b->getValue(); + } + + if ($a instanceof ConstantStringType && $b instanceof ConstantStringType) { + return strcasecmp($a->getValue(), $b->getValue()); + } + + return strcasecmp($a->describe(VerbosityLevel::typeOnly()), $b->describe(VerbosityLevel::typeOnly())); + }); + return $types; + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/VerbosityLevel.php b/vendor/phpstan/phpstan/src/Type/VerbosityLevel.php new file mode 100644 index 00000000..467d0506 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/VerbosityLevel.php @@ -0,0 +1,67 @@ +value = $value; + } + + private static function create(int $value): self + { + self::$registry[$value] = self::$registry[$value] ?? new self($value); + return self::$registry[$value]; + } + + public static function typeOnly(): self + { + return self::create(self::TYPE_ONLY); + } + + public static function value(): self + { + return self::create(self::VALUE); + } + + public static function precise(): self + { + return self::create(self::PRECISE); + } + + /** + * @param callable(): string $typeOnlyCallback + * @param callable(): string $valueCallback + * @param callable(): string|null $preciseCallback + * @return string + */ + public function handle( + callable $typeOnlyCallback, + callable $valueCallback, + ?callable $preciseCallback = null + ): string + { + if ($this->value === self::TYPE_ONLY) { + return $typeOnlyCallback(); + } + + if ($this->value === self::VALUE || $preciseCallback === null) { + return $valueCallback(); + } + + return $preciseCallback(); + } + +} diff --git a/vendor/phpstan/phpstan/src/Type/VoidType.php b/vendor/phpstan/phpstan/src/Type/VoidType.php new file mode 100644 index 00000000..b2b016d0 --- /dev/null +++ b/vendor/phpstan/phpstan/src/Type/VoidType.php @@ -0,0 +1,91 @@ +isSubTypeOf($this); + } + + return TrinaryLogic::createNo(); + } + + public function equals(Type $type): bool + { + return $type instanceof self; + } + + public function describe(VerbosityLevel $level): string + { + return 'void'; + } + + public function toNumber(): Type + { + return new ErrorType(); + } + + public function toString(): Type + { + return new ErrorType(); + } + + public function toInteger(): Type + { + return new ErrorType(); + } + + public function toFloat(): Type + { + return new ErrorType(); + } + + public function toArray(): Type + { + return new ErrorType(); + } + + /** + * @param mixed[] $properties + * @return Type + */ + public static function __set_state(array $properties): Type + { + return new self(); + } + +} diff --git a/vendor/phpstan/phpstan/tmp/.gitignore b/vendor/phpstan/phpstan/tmp/.gitignore new file mode 100644 index 00000000..1945e318 --- /dev/null +++ b/vendor/phpstan/phpstan/tmp/.gitignore @@ -0,0 +1,4 @@ +* +!/cache +!/generated +!.* diff --git a/vendor/phpstan/phpstan/tmp/cache/.gitignore b/vendor/phpstan/phpstan/tmp/cache/.gitignore new file mode 100644 index 00000000..125e3429 --- /dev/null +++ b/vendor/phpstan/phpstan/tmp/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.* diff --git a/vendor/phpstan/phpstan/tmp/generated/.gitignore b/vendor/phpstan/phpstan/tmp/generated/.gitignore new file mode 100644 index 00000000..125e3429 --- /dev/null +++ b/vendor/phpstan/phpstan/tmp/generated/.gitignore @@ -0,0 +1,2 @@ +* +!.* diff --git a/vendor/psr/log/LICENSE b/vendor/psr/log/LICENSE new file mode 100644 index 00000000..474c952b --- /dev/null +++ b/vendor/psr/log/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012 PHP Framework Interoperability Group + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/psr/log/Psr/Log/AbstractLogger.php b/vendor/psr/log/Psr/Log/AbstractLogger.php new file mode 100644 index 00000000..90e721af --- /dev/null +++ b/vendor/psr/log/Psr/Log/AbstractLogger.php @@ -0,0 +1,128 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/vendor/psr/log/Psr/Log/InvalidArgumentException.php b/vendor/psr/log/Psr/Log/InvalidArgumentException.php new file mode 100644 index 00000000..67f852d1 --- /dev/null +++ b/vendor/psr/log/Psr/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/vendor/psr/log/Psr/Log/LoggerInterface.php b/vendor/psr/log/Psr/Log/LoggerInterface.php new file mode 100644 index 00000000..5ea72438 --- /dev/null +++ b/vendor/psr/log/Psr/Log/LoggerInterface.php @@ -0,0 +1,123 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function alert($message, array $context = array()) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function critical($message, array $context = array()) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function error($message, array $context = array()) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function warning($message, array $context = array()) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function notice($message, array $context = array()) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function info($message, array $context = array()) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return void + */ + public function debug($message, array $context = array()) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + */ + abstract public function log($level, $message, array $context = array()); +} diff --git a/vendor/psr/log/Psr/Log/NullLogger.php b/vendor/psr/log/Psr/Log/NullLogger.php new file mode 100644 index 00000000..d8cd682c --- /dev/null +++ b/vendor/psr/log/Psr/Log/NullLogger.php @@ -0,0 +1,28 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return void + */ + public function log($level, $message, array $context = array()) + { + // noop + } +} diff --git a/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php new file mode 100644 index 00000000..4b861c3e --- /dev/null +++ b/vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php @@ -0,0 +1,144 @@ + ". + * + * Example ->error('Foo') would yield "error Foo". + * + * @return string[] + */ + abstract public function getLogs(); + + public function testImplements() + { + $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); + } + + /** + * @dataProvider provideLevelsAndMessages + */ + public function testLogsAtAllLevels($level, $message) + { + $logger = $this->getLogger(); + $logger->{$level}($message, array('user' => 'Bob')); + $logger->log($level, $message, array('user' => 'Bob')); + + $expected = array( + $level.' message of level '.$level.' with context: Bob', + $level.' message of level '.$level.' with context: Bob', + ); + $this->assertEquals($expected, $this->getLogs()); + } + + public function provideLevelsAndMessages() + { + return array( + LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), + LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), + LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), + LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), + LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), + LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), + LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), + LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), + ); + } + + /** + * @expectedException \Psr\Log\InvalidArgumentException + */ + public function testThrowsOnInvalidLevel() + { + $logger = $this->getLogger(); + $logger->log('invalid level', 'Foo'); + } + + public function testContextReplacement() + { + $logger = $this->getLogger(); + $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); + + $expected = array('info {Message {nothing} Bob Bar a}'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testObjectCastToString() + { + if (method_exists($this, 'createPartialMock')) { + $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); + } else { + $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); + } + $dummy->expects($this->once()) + ->method('__toString') + ->will($this->returnValue('DUMMY')); + + $this->getLogger()->warning($dummy); + + $expected = array('warning DUMMY'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextCanContainAnything() + { + $closed = fopen('php://memory', 'r'); + fclose($closed); + + $context = array( + 'bool' => true, + 'null' => null, + 'string' => 'Foo', + 'int' => 0, + 'float' => 0.5, + 'nested' => array('with object' => new DummyTest), + 'object' => new \DateTime, + 'resource' => fopen('php://memory', 'r'), + 'closed' => $closed, + ); + + $this->getLogger()->warning('Crazy context data', $context); + + $expected = array('warning Crazy context data'); + $this->assertEquals($expected, $this->getLogs()); + } + + public function testContextExceptionKeyCanBeExceptionOrOtherValues() + { + $logger = $this->getLogger(); + $logger->warning('Random message', array('exception' => 'oops')); + $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); + + $expected = array( + 'warning Random message', + 'critical Uncaught Exception!' + ); + $this->assertEquals($expected, $this->getLogs()); + } +} + +class DummyTest +{ + public function __toString() + { + } +} diff --git a/vendor/psr/log/Psr/Log/Test/TestLogger.php b/vendor/psr/log/Psr/Log/Test/TestLogger.php new file mode 100644 index 00000000..0cdffe4f --- /dev/null +++ b/vendor/psr/log/Psr/Log/Test/TestLogger.php @@ -0,0 +1,146 @@ + $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + return false; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function reset() + { + $this->records = []; + } +} diff --git a/vendor/psr/log/README.md b/vendor/psr/log/README.md new file mode 100644 index 00000000..5571a25e --- /dev/null +++ b/vendor/psr/log/README.md @@ -0,0 +1,52 @@ +PSR Log +======= + +This repository holds all interfaces/classes/traits related to +[PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md). + +Note that this is not a logger of its own. It is merely an interface that +describes a logger. See the specification for more details. + +Installation +------------ + +```bash +composer require psr/log +``` + +Usage +----- + +If you need a logger, you can use the interface like this: + +```php +logger = $logger; + } + + public function doSomething() + { + if ($this->logger) { + $this->logger->info('Doing work'); + } + + // do something useful + } +} +``` + +You can then pick one of the implementations of the interface to get a logger. + +If you want to implement the interface, you can require this package and +implement `Psr\Log\LoggerInterface` in your code. Please read the +[specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) +for details. diff --git a/vendor/psr/log/composer.json b/vendor/psr/log/composer.json new file mode 100644 index 00000000..87934d70 --- /dev/null +++ b/vendor/psr/log/composer.json @@ -0,0 +1,26 @@ +{ + "name": "psr/log", + "description": "Common interface for logging libraries", + "keywords": ["psr", "psr-3", "log"], + "homepage": "https://github.com/php-fig/log", + "license": "MIT", + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "require": { + "php": ">=5.3.0" + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/vendor/symfony/console/Application.php b/vendor/symfony/console/Application.php new file mode 100644 index 00000000..f96d6905 --- /dev/null +++ b/vendor/symfony/console/Application.php @@ -0,0 +1,1174 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Command\HelpCommand; +use Symfony\Component\Console\Command\ListCommand; +use Symfony\Component\Console\CommandLoader\CommandLoaderInterface; +use Symfony\Component\Console\Event\ConsoleCommandEvent; +use Symfony\Component\Console\Event\ConsoleErrorEvent; +use Symfony\Component\Console\Event\ConsoleTerminateEvent; +use Symfony\Component\Console\Exception\CommandNotFoundException; +use Symfony\Component\Console\Exception\ExceptionInterface; +use Symfony\Component\Console\Exception\LogicException; +use Symfony\Component\Console\Exception\NamespaceNotFoundException; +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Helper\DebugFormatterHelper; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Helper\Helper; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Helper\ProcessHelper; +use Symfony\Component\Console\Helper\QuestionHelper; +use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputAwareInterface; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\StreamableInputInterface; +use Symfony\Component\Console\Output\ConsoleOutput; +use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Debug\ErrorHandler; +use Symfony\Component\Debug\Exception\FatalThrowableError; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; + +/** + * An Application is the container for a collection of commands. + * + * It is the main entry point of a Console application. + * + * This class is optimized for a standard CLI environment. + * + * Usage: + * + * $app = new Application('myapp', '1.0 (stable)'); + * $app->add(new SimpleCommand()); + * $app->run(); + * + * @author Fabien Potencier + */ +class Application +{ + private $commands = []; + private $wantHelps = false; + private $runningCommand; + private $name; + private $version; + private $commandLoader; + private $catchExceptions = true; + private $autoExit = true; + private $definition; + private $helperSet; + private $dispatcher; + private $terminal; + private $defaultCommand; + private $singleCommand = false; + private $initialized; + + /** + * @param string $name The name of the application + * @param string $version The version of the application + */ + public function __construct(string $name = 'UNKNOWN', string $version = 'UNKNOWN') + { + $this->name = $name; + $this->version = $version; + $this->terminal = new Terminal(); + $this->defaultCommand = 'list'; + } + + public function setDispatcher(EventDispatcherInterface $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + public function setCommandLoader(CommandLoaderInterface $commandLoader) + { + $this->commandLoader = $commandLoader; + } + + /** + * Runs the current application. + * + * @return int 0 if everything went fine, or an error code + * + * @throws \Exception When running fails. Bypass this when {@link setCatchExceptions()}. + */ + public function run(InputInterface $input = null, OutputInterface $output = null) + { + putenv('LINES='.$this->terminal->getHeight()); + putenv('COLUMNS='.$this->terminal->getWidth()); + + if (null === $input) { + $input = new ArgvInput(); + } + + if (null === $output) { + $output = new ConsoleOutput(); + } + + $renderException = function ($e) use ($output) { + if (!$e instanceof \Exception) { + $e = class_exists(FatalThrowableError::class) ? new FatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()); + } + if ($output instanceof ConsoleOutputInterface) { + $this->renderException($e, $output->getErrorOutput()); + } else { + $this->renderException($e, $output); + } + }; + if ($phpHandler = set_exception_handler($renderException)) { + restore_exception_handler(); + if (!\is_array($phpHandler) || !$phpHandler[0] instanceof ErrorHandler) { + $debugHandler = true; + } elseif ($debugHandler = $phpHandler[0]->setExceptionHandler($renderException)) { + $phpHandler[0]->setExceptionHandler($debugHandler); + } + } + + $this->configureIO($input, $output); + + try { + $exitCode = $this->doRun($input, $output); + } catch (\Exception $e) { + if (!$this->catchExceptions) { + throw $e; + } + + $renderException($e); + + $exitCode = $e->getCode(); + if (is_numeric($exitCode)) { + $exitCode = (int) $exitCode; + if (0 === $exitCode) { + $exitCode = 1; + } + } else { + $exitCode = 1; + } + } finally { + // if the exception handler changed, keep it + // otherwise, unregister $renderException + if (!$phpHandler) { + if (set_exception_handler($renderException) === $renderException) { + restore_exception_handler(); + } + restore_exception_handler(); + } elseif (!$debugHandler) { + $finalHandler = $phpHandler[0]->setExceptionHandler(null); + if ($finalHandler !== $renderException) { + $phpHandler[0]->setExceptionHandler($finalHandler); + } + } + } + + if ($this->autoExit) { + if ($exitCode > 255) { + $exitCode = 255; + } + + exit($exitCode); + } + + return $exitCode; + } + + /** + * Runs the current application. + * + * @return int 0 if everything went fine, or an error code + */ + public function doRun(InputInterface $input, OutputInterface $output) + { + if (true === $input->hasParameterOption(['--version', '-V'], true)) { + $output->writeln($this->getLongVersion()); + + return 0; + } + + $name = $this->getCommandName($input); + if (true === $input->hasParameterOption(['--help', '-h'], true)) { + if (!$name) { + $name = 'help'; + $input = new ArrayInput(['command_name' => $this->defaultCommand]); + } else { + $this->wantHelps = true; + } + } + + if (!$name) { + $name = $this->defaultCommand; + $definition = $this->getDefinition(); + $definition->setArguments(array_merge( + $definition->getArguments(), + [ + 'command' => new InputArgument('command', InputArgument::OPTIONAL, $definition->getArgument('command')->getDescription(), $name), + ] + )); + } + + try { + $this->runningCommand = null; + // the command name MUST be the first element of the input + $command = $this->find($name); + } catch (\Throwable $e) { + if (!($e instanceof CommandNotFoundException && !$e instanceof NamespaceNotFoundException) || 1 !== \count($alternatives = $e->getAlternatives()) || !$input->isInteractive()) { + if (null !== $this->dispatcher) { + $event = new ConsoleErrorEvent($input, $output, $e); + $this->dispatcher->dispatch(ConsoleEvents::ERROR, $event); + + if (0 === $event->getExitCode()) { + return 0; + } + + $e = $event->getError(); + } + + throw $e; + } + + $alternative = $alternatives[0]; + + $style = new SymfonyStyle($input, $output); + $style->block(sprintf("\nCommand \"%s\" is not defined.\n", $name), null, 'error'); + if (!$style->confirm(sprintf('Do you want to run "%s" instead? ', $alternative), false)) { + if (null !== $this->dispatcher) { + $event = new ConsoleErrorEvent($input, $output, $e); + $this->dispatcher->dispatch(ConsoleEvents::ERROR, $event); + + return $event->getExitCode(); + } + + return 1; + } + + $command = $this->find($alternative); + } + + $this->runningCommand = $command; + $exitCode = $this->doRunCommand($command, $input, $output); + $this->runningCommand = null; + + return $exitCode; + } + + public function setHelperSet(HelperSet $helperSet) + { + $this->helperSet = $helperSet; + } + + /** + * Get the helper set associated with the command. + * + * @return HelperSet The HelperSet instance associated with this command + */ + public function getHelperSet() + { + if (!$this->helperSet) { + $this->helperSet = $this->getDefaultHelperSet(); + } + + return $this->helperSet; + } + + public function setDefinition(InputDefinition $definition) + { + $this->definition = $definition; + } + + /** + * Gets the InputDefinition related to this Application. + * + * @return InputDefinition The InputDefinition instance + */ + public function getDefinition() + { + if (!$this->definition) { + $this->definition = $this->getDefaultInputDefinition(); + } + + if ($this->singleCommand) { + $inputDefinition = $this->definition; + $inputDefinition->setArguments(); + + return $inputDefinition; + } + + return $this->definition; + } + + /** + * Gets the help message. + * + * @return string A help message + */ + public function getHelp() + { + return $this->getLongVersion(); + } + + /** + * Gets whether to catch exceptions or not during commands execution. + * + * @return bool Whether to catch exceptions or not during commands execution + */ + public function areExceptionsCaught() + { + return $this->catchExceptions; + } + + /** + * Sets whether to catch exceptions or not during commands execution. + * + * @param bool $boolean Whether to catch exceptions or not during commands execution + */ + public function setCatchExceptions($boolean) + { + $this->catchExceptions = (bool) $boolean; + } + + /** + * Gets whether to automatically exit after a command execution or not. + * + * @return bool Whether to automatically exit after a command execution or not + */ + public function isAutoExitEnabled() + { + return $this->autoExit; + } + + /** + * Sets whether to automatically exit after a command execution or not. + * + * @param bool $boolean Whether to automatically exit after a command execution or not + */ + public function setAutoExit($boolean) + { + $this->autoExit = (bool) $boolean; + } + + /** + * Gets the name of the application. + * + * @return string The application name + */ + public function getName() + { + return $this->name; + } + + /** + * Sets the application name. + * + * @param string $name The application name + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Gets the application version. + * + * @return string The application version + */ + public function getVersion() + { + return $this->version; + } + + /** + * Sets the application version. + * + * @param string $version The application version + */ + public function setVersion($version) + { + $this->version = $version; + } + + /** + * Returns the long version of the application. + * + * @return string The long application version + */ + public function getLongVersion() + { + if ('UNKNOWN' !== $this->getName()) { + if ('UNKNOWN' !== $this->getVersion()) { + return sprintf('%s %s', $this->getName(), $this->getVersion()); + } + + return $this->getName(); + } + + return 'Console Tool'; + } + + /** + * Registers a new command. + * + * @param string $name The command name + * + * @return Command The newly created command + */ + public function register($name) + { + return $this->add(new Command($name)); + } + + /** + * Adds an array of command objects. + * + * If a Command is not enabled it will not be added. + * + * @param Command[] $commands An array of commands + */ + public function addCommands(array $commands) + { + foreach ($commands as $command) { + $this->add($command); + } + } + + /** + * Adds a command object. + * + * If a command with the same name already exists, it will be overridden. + * If the command is not enabled it will not be added. + * + * @return Command|null The registered command if enabled or null + */ + public function add(Command $command) + { + $this->init(); + + $command->setApplication($this); + + if (!$command->isEnabled()) { + $command->setApplication(null); + + return; + } + + if (null === $command->getDefinition()) { + throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', \get_class($command))); + } + + if (!$command->getName()) { + throw new LogicException(sprintf('The command defined in "%s" cannot have an empty name.', \get_class($command))); + } + + $this->commands[$command->getName()] = $command; + + foreach ($command->getAliases() as $alias) { + $this->commands[$alias] = $command; + } + + return $command; + } + + /** + * Returns a registered command by name or alias. + * + * @param string $name The command name or alias + * + * @return Command A Command object + * + * @throws CommandNotFoundException When given command name does not exist + */ + public function get($name) + { + $this->init(); + + if (!$this->has($name)) { + throw new CommandNotFoundException(sprintf('The command "%s" does not exist.', $name)); + } + + $command = $this->commands[$name]; + + if ($this->wantHelps) { + $this->wantHelps = false; + + $helpCommand = $this->get('help'); + $helpCommand->setCommand($command); + + return $helpCommand; + } + + return $command; + } + + /** + * Returns true if the command exists, false otherwise. + * + * @param string $name The command name or alias + * + * @return bool true if the command exists, false otherwise + */ + public function has($name) + { + $this->init(); + + return isset($this->commands[$name]) || ($this->commandLoader && $this->commandLoader->has($name) && $this->add($this->commandLoader->get($name))); + } + + /** + * Returns an array of all unique namespaces used by currently registered commands. + * + * It does not return the global namespace which always exists. + * + * @return string[] An array of namespaces + */ + public function getNamespaces() + { + $namespaces = []; + foreach ($this->all() as $command) { + $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName())); + + foreach ($command->getAliases() as $alias) { + $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias)); + } + } + + return array_values(array_unique(array_filter($namespaces))); + } + + /** + * Finds a registered namespace by a name or an abbreviation. + * + * @param string $namespace A namespace or abbreviation to search for + * + * @return string A registered namespace + * + * @throws NamespaceNotFoundException When namespace is incorrect or ambiguous + */ + public function findNamespace($namespace) + { + $allNamespaces = $this->getNamespaces(); + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $namespace); + $namespaces = preg_grep('{^'.$expr.'}', $allNamespaces); + + if (empty($namespaces)) { + $message = sprintf('There are no commands defined in the "%s" namespace.', $namespace); + + if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) { + if (1 == \count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; + } + + $message .= implode("\n ", $alternatives); + } + + throw new NamespaceNotFoundException($message, $alternatives); + } + + $exact = \in_array($namespace, $namespaces, true); + if (\count($namespaces) > 1 && !$exact) { + throw new NamespaceNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces)); + } + + return $exact ? $namespace : reset($namespaces); + } + + /** + * Finds a command by name or alias. + * + * Contrary to get, this command tries to find the best + * match if you give it an abbreviation of a name or alias. + * + * @param string $name A command name or a command alias + * + * @return Command A Command instance + * + * @throws CommandNotFoundException When command name is incorrect or ambiguous + */ + public function find($name) + { + $this->init(); + + $aliases = []; + $allCommands = $this->commandLoader ? array_merge($this->commandLoader->getNames(), array_keys($this->commands)) : array_keys($this->commands); + $expr = preg_replace_callback('{([^:]+|)}', function ($matches) { return preg_quote($matches[1]).'[^:]*'; }, $name); + $commands = preg_grep('{^'.$expr.'}', $allCommands); + + if (empty($commands)) { + $commands = preg_grep('{^'.$expr.'}i', $allCommands); + } + + // if no commands matched or we just matched namespaces + if (empty($commands) || \count(preg_grep('{^'.$expr.'$}i', $commands)) < 1) { + if (false !== $pos = strrpos($name, ':')) { + // check if a namespace exists and contains commands + $this->findNamespace(substr($name, 0, $pos)); + } + + $message = sprintf('Command "%s" is not defined.', $name); + + if ($alternatives = $this->findAlternatives($name, $allCommands)) { + if (1 == \count($alternatives)) { + $message .= "\n\nDid you mean this?\n "; + } else { + $message .= "\n\nDid you mean one of these?\n "; + } + $message .= implode("\n ", $alternatives); + } + + throw new CommandNotFoundException($message, $alternatives); + } + + // filter out aliases for commands which are already on the list + if (\count($commands) > 1) { + $commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands; + $commands = array_unique(array_filter($commands, function ($nameOrAlias) use ($commandList, $commands, &$aliases) { + $commandName = $commandList[$nameOrAlias] instanceof Command ? $commandList[$nameOrAlias]->getName() : $nameOrAlias; + $aliases[$nameOrAlias] = $commandName; + + return $commandName === $nameOrAlias || !\in_array($commandName, $commands); + })); + } + + $exact = \in_array($name, $commands, true) || isset($aliases[$name]); + if (\count($commands) > 1 && !$exact) { + $usableWidth = $this->terminal->getWidth() - 10; + $abbrevs = array_values($commands); + $maxLen = 0; + foreach ($abbrevs as $abbrev) { + $maxLen = max(Helper::strlen($abbrev), $maxLen); + } + $abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen) { + if (!$commandList[$cmd] instanceof Command) { + return $cmd; + } + $abbrev = str_pad($cmd, $maxLen, ' ').' '.$commandList[$cmd]->getDescription(); + + return Helper::strlen($abbrev) > $usableWidth ? Helper::substr($abbrev, 0, $usableWidth - 3).'...' : $abbrev; + }, array_values($commands)); + $suggestions = $this->getAbbreviationSuggestions($abbrevs); + + throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands)); + } + + return $this->get($exact ? $name : reset($commands)); + } + + /** + * Gets the commands (registered in the given namespace if provided). + * + * The array keys are the full names and the values the command instances. + * + * @param string $namespace A namespace name + * + * @return Command[] An array of Command instances + */ + public function all($namespace = null) + { + $this->init(); + + if (null === $namespace) { + if (!$this->commandLoader) { + return $this->commands; + } + + $commands = $this->commands; + foreach ($this->commandLoader->getNames() as $name) { + if (!isset($commands[$name]) && $this->has($name)) { + $commands[$name] = $this->get($name); + } + } + + return $commands; + } + + $commands = []; + foreach ($this->commands as $name => $command) { + if ($namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1)) { + $commands[$name] = $command; + } + } + + if ($this->commandLoader) { + foreach ($this->commandLoader->getNames() as $name) { + if (!isset($commands[$name]) && $namespace === $this->extractNamespace($name, substr_count($namespace, ':') + 1) && $this->has($name)) { + $commands[$name] = $this->get($name); + } + } + } + + return $commands; + } + + /** + * Returns an array of possible abbreviations given a set of names. + * + * @param array $names An array of names + * + * @return array An array of abbreviations + */ + public static function getAbbreviations($names) + { + $abbrevs = []; + foreach ($names as $name) { + for ($len = \strlen($name); $len > 0; --$len) { + $abbrev = substr($name, 0, $len); + $abbrevs[$abbrev][] = $name; + } + } + + return $abbrevs; + } + + /** + * Renders a caught exception. + */ + public function renderException(\Exception $e, OutputInterface $output) + { + $output->writeln('', OutputInterface::VERBOSITY_QUIET); + + $this->doRenderException($e, $output); + + if (null !== $this->runningCommand) { + $output->writeln(sprintf('%s', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET); + $output->writeln('', OutputInterface::VERBOSITY_QUIET); + } + } + + protected function doRenderException(\Exception $e, OutputInterface $output) + { + do { + $message = trim($e->getMessage()); + if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $class = \get_class($e); + $class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; + $title = sprintf(' [%s%s] ', $class, 0 !== ($code = $e->getCode()) ? ' ('.$code.')' : ''); + $len = Helper::strlen($title); + } else { + $len = 0; + } + + if (false !== strpos($message, "class@anonymous\0")) { + $message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) { + return \class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0]; + }, $message); + } + + $width = $this->terminal->getWidth() ? $this->terminal->getWidth() - 1 : PHP_INT_MAX; + $lines = []; + foreach ('' !== $message ? preg_split('/\r?\n/', $message) : [] as $line) { + foreach ($this->splitStringByWidth($line, $width - 4) as $line) { + // pre-format lines to get the right string length + $lineLength = Helper::strlen($line) + 4; + $lines[] = [$line, $lineLength]; + + $len = max($lineLength, $len); + } + } + + $messages = []; + if (!$e instanceof ExceptionInterface || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $messages[] = sprintf('%s', OutputFormatter::escape(sprintf('In %s line %s:', basename($e->getFile()) ?: 'n/a', $e->getLine() ?: 'n/a'))); + } + $messages[] = $emptyLine = sprintf('%s', str_repeat(' ', $len)); + if ('' === $message || OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $messages[] = sprintf('%s%s', $title, str_repeat(' ', max(0, $len - Helper::strlen($title)))); + } + foreach ($lines as $line) { + $messages[] = sprintf(' %s %s', OutputFormatter::escape($line[0]), str_repeat(' ', $len - $line[1])); + } + $messages[] = $emptyLine; + $messages[] = ''; + + $output->writeln($messages, OutputInterface::VERBOSITY_QUIET); + + if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { + $output->writeln('Exception trace:', OutputInterface::VERBOSITY_QUIET); + + // exception related properties + $trace = $e->getTrace(); + + array_unshift($trace, [ + 'function' => '', + 'file' => $e->getFile() ?: 'n/a', + 'line' => $e->getLine() ?: 'n/a', + 'args' => [], + ]); + + for ($i = 0, $count = \count($trace); $i < $count; ++$i) { + $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : ''; + $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : ''; + $function = $trace[$i]['function']; + $file = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a'; + $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a'; + + $output->writeln(sprintf(' %s%s%s() at %s:%s', $class, $type, $function, $file, $line), OutputInterface::VERBOSITY_QUIET); + } + + $output->writeln('', OutputInterface::VERBOSITY_QUIET); + } + } while ($e = $e->getPrevious()); + } + + /** + * Configures the input and output instances based on the user arguments and options. + */ + protected function configureIO(InputInterface $input, OutputInterface $output) + { + if (true === $input->hasParameterOption(['--ansi'], true)) { + $output->setDecorated(true); + } elseif (true === $input->hasParameterOption(['--no-ansi'], true)) { + $output->setDecorated(false); + } + + if (true === $input->hasParameterOption(['--no-interaction', '-n'], true)) { + $input->setInteractive(false); + } elseif (\function_exists('posix_isatty')) { + $inputStream = null; + + if ($input instanceof StreamableInputInterface) { + $inputStream = $input->getStream(); + } + + if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) { + $input->setInteractive(false); + } + } + + switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) { + case -1: $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); break; + case 1: $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); break; + case 2: $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); break; + case 3: $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); break; + default: $shellVerbosity = 0; break; + } + + if (true === $input->hasParameterOption(['--quiet', '-q'], true)) { + $output->setVerbosity(OutputInterface::VERBOSITY_QUIET); + $shellVerbosity = -1; + } else { + if ($input->hasParameterOption('-vvv', true) || $input->hasParameterOption('--verbose=3', true) || 3 === $input->getParameterOption('--verbose', false, true)) { + $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); + $shellVerbosity = 3; + } elseif ($input->hasParameterOption('-vv', true) || $input->hasParameterOption('--verbose=2', true) || 2 === $input->getParameterOption('--verbose', false, true)) { + $output->setVerbosity(OutputInterface::VERBOSITY_VERY_VERBOSE); + $shellVerbosity = 2; + } elseif ($input->hasParameterOption('-v', true) || $input->hasParameterOption('--verbose=1', true) || $input->hasParameterOption('--verbose', true) || $input->getParameterOption('--verbose', false, true)) { + $output->setVerbosity(OutputInterface::VERBOSITY_VERBOSE); + $shellVerbosity = 1; + } + } + + if (-1 === $shellVerbosity) { + $input->setInteractive(false); + } + + putenv('SHELL_VERBOSITY='.$shellVerbosity); + $_ENV['SHELL_VERBOSITY'] = $shellVerbosity; + $_SERVER['SHELL_VERBOSITY'] = $shellVerbosity; + } + + /** + * Runs the current command. + * + * If an event dispatcher has been attached to the application, + * events are also dispatched during the life-cycle of the command. + * + * @return int 0 if everything went fine, or an error code + */ + protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output) + { + foreach ($command->getHelperSet() as $helper) { + if ($helper instanceof InputAwareInterface) { + $helper->setInput($input); + } + } + + if (null === $this->dispatcher) { + return $command->run($input, $output); + } + + // bind before the console.command event, so the listeners have access to input options/arguments + try { + $command->mergeApplicationDefinition(); + $input->bind($command->getDefinition()); + } catch (ExceptionInterface $e) { + // ignore invalid options/arguments for now, to allow the event listeners to customize the InputDefinition + } + + $event = new ConsoleCommandEvent($command, $input, $output); + $e = null; + + try { + $this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event); + + if ($event->commandShouldRun()) { + $exitCode = $command->run($input, $output); + } else { + $exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED; + } + } catch (\Throwable $e) { + $event = new ConsoleErrorEvent($input, $output, $e, $command); + $this->dispatcher->dispatch(ConsoleEvents::ERROR, $event); + $e = $event->getError(); + + if (0 === $exitCode = $event->getExitCode()) { + $e = null; + } + } + + $event = new ConsoleTerminateEvent($command, $input, $output, $exitCode); + $this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event); + + if (null !== $e) { + throw $e; + } + + return $event->getExitCode(); + } + + /** + * Gets the name of the command based on input. + * + * @return string The command name + */ + protected function getCommandName(InputInterface $input) + { + return $this->singleCommand ? $this->defaultCommand : $input->getFirstArgument(); + } + + /** + * Gets the default input definition. + * + * @return InputDefinition An InputDefinition instance + */ + protected function getDefaultInputDefinition() + { + return new InputDefinition([ + new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), + + new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'), + new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'), + new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'), + new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'), + new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'), + new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'), + new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'), + ]); + } + + /** + * Gets the default commands that should always be available. + * + * @return Command[] An array of default Command instances + */ + protected function getDefaultCommands() + { + return [new HelpCommand(), new ListCommand()]; + } + + /** + * Gets the default helper set with the helpers that should always be available. + * + * @return HelperSet A HelperSet instance + */ + protected function getDefaultHelperSet() + { + return new HelperSet([ + new FormatterHelper(), + new DebugFormatterHelper(), + new ProcessHelper(), + new QuestionHelper(), + ]); + } + + /** + * Returns abbreviated suggestions in string format. + * + * @param array $abbrevs Abbreviated suggestions to convert + * + * @return string A formatted string of abbreviated suggestions + */ + private function getAbbreviationSuggestions($abbrevs) + { + return ' '.implode("\n ", $abbrevs); + } + + /** + * Returns the namespace part of the command name. + * + * This method is not part of public API and should not be used directly. + * + * @param string $name The full name of the command + * @param string $limit The maximum number of parts of the namespace + * + * @return string The namespace of the command + */ + public function extractNamespace($name, $limit = null) + { + $parts = explode(':', $name); + array_pop($parts); + + return implode(':', null === $limit ? $parts : \array_slice($parts, 0, $limit)); + } + + /** + * Finds alternative of $name among $collection, + * if nothing is found in $collection, try in $abbrevs. + * + * @param string $name The string + * @param iterable $collection The collection + * + * @return string[] A sorted array of similar string + */ + private function findAlternatives($name, $collection) + { + $threshold = 1e3; + $alternatives = []; + + $collectionParts = []; + foreach ($collection as $item) { + $collectionParts[$item] = explode(':', $item); + } + + foreach (explode(':', $name) as $i => $subname) { + foreach ($collectionParts as $collectionName => $parts) { + $exists = isset($alternatives[$collectionName]); + if (!isset($parts[$i]) && $exists) { + $alternatives[$collectionName] += $threshold; + continue; + } elseif (!isset($parts[$i])) { + continue; + } + + $lev = levenshtein($subname, $parts[$i]); + if ($lev <= \strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) { + $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev; + } elseif ($exists) { + $alternatives[$collectionName] += $threshold; + } + } + } + + foreach ($collection as $item) { + $lev = levenshtein($name, $item); + if ($lev <= \strlen($name) / 3 || false !== strpos($item, $name)) { + $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev; + } + } + + $alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; }); + ksort($alternatives, SORT_NATURAL | SORT_FLAG_CASE); + + return array_keys($alternatives); + } + + /** + * Sets the default Command name. + * + * @param string $commandName The Command name + * @param bool $isSingleCommand Set to true if there is only one command in this application + * + * @return self + */ + public function setDefaultCommand($commandName, $isSingleCommand = false) + { + $this->defaultCommand = $commandName; + + if ($isSingleCommand) { + // Ensure the command exist + $this->find($commandName); + + $this->singleCommand = true; + } + + return $this; + } + + /** + * @internal + */ + public function isSingleCommand() + { + return $this->singleCommand; + } + + private function splitStringByWidth($string, $width) + { + // str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly. + // additionally, array_slice() is not enough as some character has doubled width. + // we need a function to split string not by character count but by string width + if (false === $encoding = mb_detect_encoding($string, null, true)) { + return str_split($string, $width); + } + + $utf8String = mb_convert_encoding($string, 'utf8', $encoding); + $lines = []; + $line = ''; + foreach (preg_split('//u', $utf8String) as $char) { + // test if $char could be appended to current line + if (mb_strwidth($line.$char, 'utf8') <= $width) { + $line .= $char; + continue; + } + // if not, push current line to array and make new line + $lines[] = str_pad($line, $width); + $line = $char; + } + + $lines[] = \count($lines) ? str_pad($line, $width) : $line; + + mb_convert_variables($encoding, 'utf8', $lines); + + return $lines; + } + + /** + * Returns all namespaces of the command name. + * + * @param string $name The full name of the command + * + * @return string[] The namespaces of the command + */ + private function extractAllNamespaces($name) + { + // -1 as third argument is needed to skip the command short name when exploding + $parts = explode(':', $name, -1); + $namespaces = []; + + foreach ($parts as $part) { + if (\count($namespaces)) { + $namespaces[] = end($namespaces).':'.$part; + } else { + $namespaces[] = $part; + } + } + + return $namespaces; + } + + private function init() + { + if ($this->initialized) { + return; + } + $this->initialized = true; + + foreach ($this->getDefaultCommands() as $command) { + $this->add($command); + } + } +} diff --git a/vendor/symfony/console/CHANGELOG.md b/vendor/symfony/console/CHANGELOG.md new file mode 100644 index 00000000..399bbc22 --- /dev/null +++ b/vendor/symfony/console/CHANGELOG.md @@ -0,0 +1,140 @@ +CHANGELOG +========= + +4.2.0 +----- + + * allowed passing commands as `[$process, 'ENV_VAR' => 'value']` to + `ProcessHelper::run()` to pass environment variables + * deprecated passing a command as a string to `ProcessHelper::run()`, + pass it the command as an array of its arguments instead + * made the `ProcessHelper` class final + * added `WrappableOutputFormatterInterface::formatAndWrap()` (implemented in `OutputFormatter`) + * added `capture_stderr_separately` option to `CommandTester::execute()` + +4.1.0 +----- + + * added option to run suggested command if command is not found and only 1 alternative is available + * added option to modify console output and print multiple modifiable sections + * added support for iterable messages in output `write` and `writeln` methods + +4.0.0 +----- + + * `OutputFormatter` throws an exception when unknown options are used + * removed `QuestionHelper::setInputStream()/getInputStream()` + * removed `Application::getTerminalWidth()/getTerminalHeight()` and + `Application::setTerminalDimensions()/getTerminalDimensions()` +* removed `ConsoleExceptionEvent` +* removed `ConsoleEvents::EXCEPTION` + +3.4.0 +----- + + * added `SHELL_VERBOSITY` env var to control verbosity + * added `CommandLoaderInterface`, `FactoryCommandLoader` and PSR-11 + `ContainerCommandLoader` for commands lazy-loading + * added a case-insensitive command name matching fallback + * added static `Command::$defaultName/getDefaultName()`, allowing for + commands to be registered at compile time in the application command loader. + Setting the `$defaultName` property avoids the need for filling the `command` + attribute on the `console.command` tag when using `AddConsoleCommandPass`. + +3.3.0 +----- + +* added `ExceptionListener` +* added `AddConsoleCommandPass` (originally in FrameworkBundle) +* [BC BREAK] `Input::getOption()` no longer returns the default value for options + with value optional explicitly passed empty +* added console.error event to catch exceptions thrown by other listeners +* deprecated console.exception event in favor of console.error +* added ability to handle `CommandNotFoundException` through the + `console.error` event +* deprecated default validation in `SymfonyQuestionHelper::ask` + +3.2.0 +------ + +* added `setInputs()` method to CommandTester for ease testing of commands expecting inputs +* added `setStream()` and `getStream()` methods to Input (implement StreamableInputInterface) +* added StreamableInputInterface +* added LockableTrait + +3.1.0 +----- + + * added truncate method to FormatterHelper + * added setColumnWidth(s) method to Table + +2.8.3 +----- + + * remove readline support from the question helper as it caused issues + +2.8.0 +----- + + * use readline for user input in the question helper when available to allow + the use of arrow keys + +2.6.0 +----- + + * added a Process helper + * added a DebugFormatter helper + +2.5.0 +----- + + * deprecated the dialog helper (use the question helper instead) + * deprecated TableHelper in favor of Table + * deprecated ProgressHelper in favor of ProgressBar + * added ConsoleLogger + * added a question helper + * added a way to set the process name of a command + * added a way to set a default command instead of `ListCommand` + +2.4.0 +----- + + * added a way to force terminal dimensions + * added a convenient method to detect verbosity level + * [BC BREAK] made descriptors use output instead of returning a string + +2.3.0 +----- + + * added multiselect support to the select dialog helper + * added Table Helper for tabular data rendering + * added support for events in `Application` + * added a way to normalize EOLs in `ApplicationTester::getDisplay()` and `CommandTester::getDisplay()` + * added a way to set the progress bar progress via the `setCurrent` method + * added support for multiple InputOption shortcuts, written as `'-a|-b|-c'` + * added two additional verbosity levels, VERBOSITY_VERY_VERBOSE and VERBOSITY_DEBUG + +2.2.0 +----- + + * added support for colorization on Windows via ConEmu + * add a method to Dialog Helper to ask for a question and hide the response + * added support for interactive selections in console (DialogHelper::select()) + * added support for autocompletion as you type in Dialog Helper + +2.1.0 +----- + + * added ConsoleOutputInterface + * added the possibility to disable a command (Command::isEnabled()) + * added suggestions when a command does not exist + * added a --raw option to the list command + * added support for STDERR in the console output class (errors are now sent + to STDERR) + * made the defaults (helper set, commands, input definition) in Application + more easily customizable + * added support for the shell even if readline is not available + * added support for process isolation in Symfony shell via + `--process-isolation` switch + * added support for `--`, which disables options parsing after that point + (tokens will be parsed as arguments) diff --git a/vendor/symfony/console/Command/Command.php b/vendor/symfony/console/Command/Command.php new file mode 100644 index 00000000..18d683de --- /dev/null +++ b/vendor/symfony/console/Command/Command.php @@ -0,0 +1,654 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Command; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Exception\ExceptionInterface; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\LogicException; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Base class for all commands. + * + * @author Fabien Potencier + */ +class Command +{ + /** + * @var string|null The default command name + */ + protected static $defaultName; + + private $application; + private $name; + private $processTitle; + private $aliases = []; + private $definition; + private $hidden = false; + private $help; + private $description; + private $ignoreValidationErrors = false; + private $applicationDefinitionMerged = false; + private $applicationDefinitionMergedWithArgs = false; + private $code; + private $synopsis = []; + private $usages = []; + private $helperSet; + + /** + * @return string|null The default command name or null when no default name is set + */ + public static function getDefaultName() + { + $class = \get_called_class(); + $r = new \ReflectionProperty($class, 'defaultName'); + + return $class === $r->class ? static::$defaultName : null; + } + + /** + * @param string|null $name The name of the command; passing null means it must be set in configure() + * + * @throws LogicException When the command name is empty + */ + public function __construct(string $name = null) + { + $this->definition = new InputDefinition(); + + if (null !== $name || null !== $name = static::getDefaultName()) { + $this->setName($name); + } + + $this->configure(); + } + + /** + * Ignores validation errors. + * + * This is mainly useful for the help command. + */ + public function ignoreValidationErrors() + { + $this->ignoreValidationErrors = true; + } + + public function setApplication(Application $application = null) + { + $this->application = $application; + if ($application) { + $this->setHelperSet($application->getHelperSet()); + } else { + $this->helperSet = null; + } + } + + public function setHelperSet(HelperSet $helperSet) + { + $this->helperSet = $helperSet; + } + + /** + * Gets the helper set. + * + * @return HelperSet A HelperSet instance + */ + public function getHelperSet() + { + return $this->helperSet; + } + + /** + * Gets the application instance for this command. + * + * @return Application An Application instance + */ + public function getApplication() + { + return $this->application; + } + + /** + * Checks whether the command is enabled or not in the current environment. + * + * Override this to check for x or y and return false if the command can not + * run properly under the current conditions. + * + * @return bool + */ + public function isEnabled() + { + return true; + } + + /** + * Configures the current command. + */ + protected function configure() + { + } + + /** + * Executes the current command. + * + * This method is not abstract because you can use this class + * as a concrete class. In this case, instead of defining the + * execute() method, you set the code to execute by passing + * a Closure to the setCode() method. + * + * @return int|null null or 0 if everything went fine, or an error code + * + * @throws LogicException When this abstract method is not implemented + * + * @see setCode() + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + throw new LogicException('You must override the execute() method in the concrete command class.'); + } + + /** + * Interacts with the user. + * + * This method is executed before the InputDefinition is validated. + * This means that this is the only place where the command can + * interactively ask for values of missing required arguments. + */ + protected function interact(InputInterface $input, OutputInterface $output) + { + } + + /** + * Initializes the command after the input has been bound and before the input + * is validated. + * + * This is mainly useful when a lot of commands extends one main command + * where some things need to be initialized based on the input arguments and options. + * + * @see InputInterface::bind() + * @see InputInterface::validate() + */ + protected function initialize(InputInterface $input, OutputInterface $output) + { + } + + /** + * Runs the command. + * + * The code to execute is either defined directly with the + * setCode() method or by overriding the execute() method + * in a sub-class. + * + * @return int The command exit code + * + * @throws \Exception When binding input fails. Bypass this by calling {@link ignoreValidationErrors()}. + * + * @see setCode() + * @see execute() + */ + public function run(InputInterface $input, OutputInterface $output) + { + // force the creation of the synopsis before the merge with the app definition + $this->getSynopsis(true); + $this->getSynopsis(false); + + // add the application arguments and options + $this->mergeApplicationDefinition(); + + // bind the input against the command specific arguments/options + try { + $input->bind($this->definition); + } catch (ExceptionInterface $e) { + if (!$this->ignoreValidationErrors) { + throw $e; + } + } + + $this->initialize($input, $output); + + if (null !== $this->processTitle) { + if (\function_exists('cli_set_process_title')) { + if (!@cli_set_process_title($this->processTitle)) { + if ('Darwin' === PHP_OS) { + $output->writeln('Running "cli_set_process_title" as an unprivileged user is not supported on MacOS.', OutputInterface::VERBOSITY_VERY_VERBOSE); + } else { + cli_set_process_title($this->processTitle); + } + } + } elseif (\function_exists('setproctitle')) { + setproctitle($this->processTitle); + } elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) { + $output->writeln('Install the proctitle PECL to be able to change the process title.'); + } + } + + if ($input->isInteractive()) { + $this->interact($input, $output); + } + + // The command name argument is often omitted when a command is executed directly with its run() method. + // It would fail the validation if we didn't make sure the command argument is present, + // since it's required by the application. + if ($input->hasArgument('command') && null === $input->getArgument('command')) { + $input->setArgument('command', $this->getName()); + } + + $input->validate(); + + if ($this->code) { + $statusCode = ($this->code)($input, $output); + } else { + $statusCode = $this->execute($input, $output); + } + + return is_numeric($statusCode) ? (int) $statusCode : 0; + } + + /** + * Sets the code to execute when running this command. + * + * If this method is used, it overrides the code defined + * in the execute() method. + * + * @param callable $code A callable(InputInterface $input, OutputInterface $output) + * + * @return $this + * + * @throws InvalidArgumentException + * + * @see execute() + */ + public function setCode(callable $code) + { + if ($code instanceof \Closure) { + $r = new \ReflectionFunction($code); + if (null === $r->getClosureThis()) { + $code = \Closure::bind($code, $this); + } + } + + $this->code = $code; + + return $this; + } + + /** + * Merges the application definition with the command definition. + * + * This method is not part of public API and should not be used directly. + * + * @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments + */ + public function mergeApplicationDefinition($mergeArgs = true) + { + if (null === $this->application || (true === $this->applicationDefinitionMerged && ($this->applicationDefinitionMergedWithArgs || !$mergeArgs))) { + return; + } + + $this->definition->addOptions($this->application->getDefinition()->getOptions()); + + $this->applicationDefinitionMerged = true; + + if ($mergeArgs) { + $currentArguments = $this->definition->getArguments(); + $this->definition->setArguments($this->application->getDefinition()->getArguments()); + $this->definition->addArguments($currentArguments); + + $this->applicationDefinitionMergedWithArgs = true; + } + } + + /** + * Sets an array of argument and option instances. + * + * @param array|InputDefinition $definition An array of argument and option instances or a definition instance + * + * @return $this + */ + public function setDefinition($definition) + { + if ($definition instanceof InputDefinition) { + $this->definition = $definition; + } else { + $this->definition->setDefinition($definition); + } + + $this->applicationDefinitionMerged = false; + + return $this; + } + + /** + * Gets the InputDefinition attached to this Command. + * + * @return InputDefinition An InputDefinition instance + */ + public function getDefinition() + { + return $this->definition; + } + + /** + * Gets the InputDefinition to be used to create representations of this Command. + * + * Can be overridden to provide the original command representation when it would otherwise + * be changed by merging with the application InputDefinition. + * + * This method is not part of public API and should not be used directly. + * + * @return InputDefinition An InputDefinition instance + */ + public function getNativeDefinition() + { + return $this->getDefinition(); + } + + /** + * Adds an argument. + * + * @param string $name The argument name + * @param int|null $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL + * @param string $description A description text + * @param string|string[]|null $default The default value (for InputArgument::OPTIONAL mode only) + * + * @throws InvalidArgumentException When argument mode is not valid + * + * @return $this + */ + public function addArgument($name, $mode = null, $description = '', $default = null) + { + $this->definition->addArgument(new InputArgument($name, $mode, $description, $default)); + + return $this; + } + + /** + * Adds an option. + * + * @param string $name The option name + * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the InputOption::VALUE_* constants + * @param string $description A description text + * @param string|string[]|int|bool|null $default The default value (must be null for InputOption::VALUE_NONE) + * + * @throws InvalidArgumentException If option mode is invalid or incompatible + * + * @return $this + */ + public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null) + { + $this->definition->addOption(new InputOption($name, $shortcut, $mode, $description, $default)); + + return $this; + } + + /** + * Sets the name of the command. + * + * This method can set both the namespace and the name if + * you separate them by a colon (:) + * + * $command->setName('foo:bar'); + * + * @param string $name The command name + * + * @return $this + * + * @throws InvalidArgumentException When the name is invalid + */ + public function setName($name) + { + $this->validateName($name); + + $this->name = $name; + + return $this; + } + + /** + * Sets the process title of the command. + * + * This feature should be used only when creating a long process command, + * like a daemon. + * + * PHP 5.5+ or the proctitle PECL library is required + * + * @param string $title The process title + * + * @return $this + */ + public function setProcessTitle($title) + { + $this->processTitle = $title; + + return $this; + } + + /** + * Returns the command name. + * + * @return string The command name + */ + public function getName() + { + return $this->name; + } + + /** + * @param bool $hidden Whether or not the command should be hidden from the list of commands + * + * @return Command The current instance + */ + public function setHidden($hidden) + { + $this->hidden = (bool) $hidden; + + return $this; + } + + /** + * @return bool whether the command should be publicly shown or not + */ + public function isHidden() + { + return $this->hidden; + } + + /** + * Sets the description for the command. + * + * @param string $description The description for the command + * + * @return $this + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + + /** + * Returns the description for the command. + * + * @return string The description for the command + */ + public function getDescription() + { + return $this->description; + } + + /** + * Sets the help for the command. + * + * @param string $help The help for the command + * + * @return $this + */ + public function setHelp($help) + { + $this->help = $help; + + return $this; + } + + /** + * Returns the help for the command. + * + * @return string The help for the command + */ + public function getHelp() + { + return $this->help; + } + + /** + * Returns the processed help for the command replacing the %command.name% and + * %command.full_name% patterns with the real values dynamically. + * + * @return string The processed help for the command + */ + public function getProcessedHelp() + { + $name = $this->name; + $isSingleCommand = $this->application && $this->application->isSingleCommand(); + + $placeholders = [ + '%command.name%', + '%command.full_name%', + ]; + $replacements = [ + $name, + $isSingleCommand ? $_SERVER['PHP_SELF'] : $_SERVER['PHP_SELF'].' '.$name, + ]; + + return str_replace($placeholders, $replacements, $this->getHelp() ?: $this->getDescription()); + } + + /** + * Sets the aliases for the command. + * + * @param string[] $aliases An array of aliases for the command + * + * @return $this + * + * @throws InvalidArgumentException When an alias is invalid + */ + public function setAliases($aliases) + { + if (!\is_array($aliases) && !$aliases instanceof \Traversable) { + throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable'); + } + + foreach ($aliases as $alias) { + $this->validateName($alias); + } + + $this->aliases = $aliases; + + return $this; + } + + /** + * Returns the aliases for the command. + * + * @return array An array of aliases for the command + */ + public function getAliases() + { + return $this->aliases; + } + + /** + * Returns the synopsis for the command. + * + * @param bool $short Whether to show the short version of the synopsis (with options folded) or not + * + * @return string The synopsis + */ + public function getSynopsis($short = false) + { + $key = $short ? 'short' : 'long'; + + if (!isset($this->synopsis[$key])) { + $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short))); + } + + return $this->synopsis[$key]; + } + + /** + * Add a command usage example. + * + * @param string $usage The usage, it'll be prefixed with the command name + * + * @return $this + */ + public function addUsage($usage) + { + if (0 !== strpos($usage, $this->name)) { + $usage = sprintf('%s %s', $this->name, $usage); + } + + $this->usages[] = $usage; + + return $this; + } + + /** + * Returns alternative usages of the command. + * + * @return array + */ + public function getUsages() + { + return $this->usages; + } + + /** + * Gets a helper instance by name. + * + * @param string $name The helper name + * + * @return mixed The helper value + * + * @throws LogicException if no HelperSet is defined + * @throws InvalidArgumentException if the helper is not defined + */ + public function getHelper($name) + { + if (null === $this->helperSet) { + throw new LogicException(sprintf('Cannot retrieve helper "%s" because there is no HelperSet defined. Did you forget to add your command to the application or to set the application on the command using the setApplication() method? You can also set the HelperSet directly using the setHelperSet() method.', $name)); + } + + return $this->helperSet->get($name); + } + + /** + * Validates a command name. + * + * It must be non-empty and parts can optionally be separated by ":". + * + * @throws InvalidArgumentException When the name is invalid + */ + private function validateName(string $name) + { + if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) { + throw new InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name)); + } + } +} diff --git a/vendor/symfony/console/Command/HelpCommand.php b/vendor/symfony/console/Command/HelpCommand.php new file mode 100644 index 00000000..23847766 --- /dev/null +++ b/vendor/symfony/console/Command/HelpCommand.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Command; + +use Symfony\Component\Console\Helper\DescriptorHelper; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * HelpCommand displays the help for a given command. + * + * @author Fabien Potencier + */ +class HelpCommand extends Command +{ + private $command; + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this->ignoreValidationErrors(); + + $this + ->setName('help') + ->setDefinition([ + new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), + new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'), + ]) + ->setDescription('Displays help for a command') + ->setHelp(<<<'EOF' +The %command.name% command displays help for a given command: + + php %command.full_name% list + +You can also output the help in other formats by using the --format option: + + php %command.full_name% --format=xml list + +To display the list of available commands, please use the list command. +EOF + ) + ; + } + + public function setCommand(Command $command) + { + $this->command = $command; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + if (null === $this->command) { + $this->command = $this->getApplication()->find($input->getArgument('command_name')); + } + + $helper = new DescriptorHelper(); + $helper->describe($output, $this->command, [ + 'format' => $input->getOption('format'), + 'raw_text' => $input->getOption('raw'), + ]); + + $this->command = null; + } +} diff --git a/vendor/symfony/console/Command/ListCommand.php b/vendor/symfony/console/Command/ListCommand.php new file mode 100644 index 00000000..7259b126 --- /dev/null +++ b/vendor/symfony/console/Command/ListCommand.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Command; + +use Symfony\Component\Console\Helper\DescriptorHelper; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * ListCommand displays the list of all available commands for the application. + * + * @author Fabien Potencier + */ +class ListCommand extends Command +{ + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('list') + ->setDefinition($this->createDefinition()) + ->setDescription('Lists commands') + ->setHelp(<<<'EOF' +The %command.name% command lists all commands: + + php %command.full_name% + +You can also display the commands for a specific namespace: + + php %command.full_name% test + +You can also output the information in other formats by using the --format option: + + php %command.full_name% --format=xml + +It's also possible to get raw list of commands (useful for embedding command runner): + + php %command.full_name% --raw +EOF + ) + ; + } + + /** + * {@inheritdoc} + */ + public function getNativeDefinition() + { + return $this->createDefinition(); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $helper = new DescriptorHelper(); + $helper->describe($output, $this->getApplication(), [ + 'format' => $input->getOption('format'), + 'raw_text' => $input->getOption('raw'), + 'namespace' => $input->getArgument('namespace'), + ]); + } + + /** + * {@inheritdoc} + */ + private function createDefinition() + { + return new InputDefinition([ + new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'), + new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'), + ]); + } +} diff --git a/vendor/symfony/console/Command/LockableTrait.php b/vendor/symfony/console/Command/LockableTrait.php new file mode 100644 index 00000000..f4ebe45b --- /dev/null +++ b/vendor/symfony/console/Command/LockableTrait.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Command; + +use Symfony\Component\Console\Exception\LogicException; +use Symfony\Component\Lock\Factory; +use Symfony\Component\Lock\Lock; +use Symfony\Component\Lock\Store\FlockStore; +use Symfony\Component\Lock\Store\SemaphoreStore; + +/** + * Basic lock feature for commands. + * + * @author Geoffrey Brier + */ +trait LockableTrait +{ + /** @var Lock */ + private $lock; + + /** + * Locks a command. + * + * @return bool + */ + private function lock($name = null, $blocking = false) + { + if (!class_exists(SemaphoreStore::class)) { + throw new LogicException('To enable the locking feature you must install the symfony/lock component.'); + } + + if (null !== $this->lock) { + throw new LogicException('A lock is already in place.'); + } + + if (SemaphoreStore::isSupported()) { + $store = new SemaphoreStore(); + } else { + $store = new FlockStore(); + } + + $this->lock = (new Factory($store))->createLock($name ?: $this->getName()); + if (!$this->lock->acquire($blocking)) { + $this->lock = null; + + return false; + } + + return true; + } + + /** + * Releases the command lock if there is one. + */ + private function release() + { + if ($this->lock) { + $this->lock->release(); + $this->lock = null; + } + } +} diff --git a/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php b/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php new file mode 100644 index 00000000..9462996f --- /dev/null +++ b/vendor/symfony/console/CommandLoader/CommandLoaderInterface.php @@ -0,0 +1,37 @@ + + */ +interface CommandLoaderInterface +{ + /** + * Loads a command. + * + * @param string $name + * + * @return Command + * + * @throws CommandNotFoundException + */ + public function get($name); + + /** + * Checks if a command exists. + * + * @param string $name + * + * @return bool + */ + public function has($name); + + /** + * @return string[] All registered command names + */ + public function getNames(); +} diff --git a/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php new file mode 100644 index 00000000..753ad0fb --- /dev/null +++ b/vendor/symfony/console/CommandLoader/ContainerCommandLoader.php @@ -0,0 +1,55 @@ + + */ +class ContainerCommandLoader implements CommandLoaderInterface +{ + private $container; + private $commandMap; + + /** + * @param ContainerInterface $container A container from which to load command services + * @param array $commandMap An array with command names as keys and service ids as values + */ + public function __construct(ContainerInterface $container, array $commandMap) + { + $this->container = $container; + $this->commandMap = $commandMap; + } + + /** + * {@inheritdoc} + */ + public function get($name) + { + if (!$this->has($name)) { + throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name)); + } + + return $this->container->get($this->commandMap[$name]); + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + return isset($this->commandMap[$name]) && $this->container->has($this->commandMap[$name]); + } + + /** + * {@inheritdoc} + */ + public function getNames() + { + return array_keys($this->commandMap); + } +} diff --git a/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php new file mode 100644 index 00000000..d9c20557 --- /dev/null +++ b/vendor/symfony/console/CommandLoader/FactoryCommandLoader.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\CommandLoader; + +use Symfony\Component\Console\Exception\CommandNotFoundException; + +/** + * A simple command loader using factories to instantiate commands lazily. + * + * @author Maxime Steinhausser + */ +class FactoryCommandLoader implements CommandLoaderInterface +{ + private $factories; + + /** + * @param callable[] $factories Indexed by command names + */ + public function __construct(array $factories) + { + $this->factories = $factories; + } + + /** + * {@inheritdoc} + */ + public function has($name) + { + return isset($this->factories[$name]); + } + + /** + * {@inheritdoc} + */ + public function get($name) + { + if (!isset($this->factories[$name])) { + throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name)); + } + + $factory = $this->factories[$name]; + + return $factory(); + } + + /** + * {@inheritdoc} + */ + public function getNames() + { + return array_keys($this->factories); + } +} diff --git a/vendor/symfony/console/ConsoleEvents.php b/vendor/symfony/console/ConsoleEvents.php new file mode 100644 index 00000000..4975643a --- /dev/null +++ b/vendor/symfony/console/ConsoleEvents.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console; + +/** + * Contains all events dispatched by an Application. + * + * @author Francesco Levorato + */ +final class ConsoleEvents +{ + /** + * The COMMAND event allows you to attach listeners before any command is + * executed by the console. It also allows you to modify the command, input and output + * before they are handled to the command. + * + * @Event("Symfony\Component\Console\Event\ConsoleCommandEvent") + */ + const COMMAND = 'console.command'; + + /** + * The TERMINATE event allows you to attach listeners after a command is + * executed by the console. + * + * @Event("Symfony\Component\Console\Event\ConsoleTerminateEvent") + */ + const TERMINATE = 'console.terminate'; + + /** + * The ERROR event occurs when an uncaught exception or error appears. + * + * This event allows you to deal with the exception/error or + * to modify the thrown exception. + * + * @Event("Symfony\Component\Console\Event\ConsoleErrorEvent") + */ + const ERROR = 'console.error'; +} diff --git a/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php new file mode 100644 index 00000000..666c8fa5 --- /dev/null +++ b/vendor/symfony/console/DependencyInjection/AddConsoleCommandPass.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\DependencyInjection; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\CommandLoader\ContainerCommandLoader; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; +use Symfony\Component\DependencyInjection\TypedReference; + +/** + * Registers console commands. + * + * @author Grégoire Pineau + */ +class AddConsoleCommandPass implements CompilerPassInterface +{ + private $commandLoaderServiceId; + private $commandTag; + + public function __construct(string $commandLoaderServiceId = 'console.command_loader', string $commandTag = 'console.command') + { + $this->commandLoaderServiceId = $commandLoaderServiceId; + $this->commandTag = $commandTag; + } + + public function process(ContainerBuilder $container) + { + $commandServices = $container->findTaggedServiceIds($this->commandTag, true); + $lazyCommandMap = []; + $lazyCommandRefs = []; + $serviceIds = []; + + foreach ($commandServices as $id => $tags) { + $definition = $container->getDefinition($id); + $class = $container->getParameterBag()->resolveValue($definition->getClass()); + + if (isset($tags[0]['command'])) { + $commandName = $tags[0]['command']; + } else { + if (!$r = $container->getReflectionClass($class)) { + throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + } + if (!$r->isSubclassOf(Command::class)) { + throw new InvalidArgumentException(sprintf('The service "%s" tagged "%s" must be a subclass of "%s".', $id, $this->commandTag, Command::class)); + } + $commandName = $class::getDefaultName(); + } + + if (null === $commandName) { + if (!$definition->isPublic() || $definition->isPrivate()) { + $commandId = 'console.command.public_alias.'.$id; + $container->setAlias($commandId, $id)->setPublic(true); + $id = $commandId; + } + $serviceIds[] = $id; + + continue; + } + + unset($tags[0]); + $lazyCommandMap[$commandName] = $id; + $lazyCommandRefs[$id] = new TypedReference($id, $class); + $aliases = []; + + foreach ($tags as $tag) { + if (isset($tag['command'])) { + $aliases[] = $tag['command']; + $lazyCommandMap[$tag['command']] = $id; + } + } + + $definition->addMethodCall('setName', [$commandName]); + + if ($aliases) { + $definition->addMethodCall('setAliases', [$aliases]); + } + } + + $container + ->register($this->commandLoaderServiceId, ContainerCommandLoader::class) + ->setPublic(true) + ->setArguments([ServiceLocatorTagPass::register($container, $lazyCommandRefs), $lazyCommandMap]); + + $container->setParameter('console.command.ids', $serviceIds); + } +} diff --git a/vendor/symfony/console/Descriptor/ApplicationDescription.php b/vendor/symfony/console/Descriptor/ApplicationDescription.php new file mode 100644 index 00000000..03bfcfcd --- /dev/null +++ b/vendor/symfony/console/Descriptor/ApplicationDescription.php @@ -0,0 +1,144 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Descriptor; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\CommandNotFoundException; + +/** + * @author Jean-François Simon + * + * @internal + */ +class ApplicationDescription +{ + const GLOBAL_NAMESPACE = '_global'; + + private $application; + private $namespace; + private $showHidden; + + /** + * @var array + */ + private $namespaces; + + /** + * @var Command[] + */ + private $commands; + + /** + * @var Command[] + */ + private $aliases; + + public function __construct(Application $application, string $namespace = null, bool $showHidden = false) + { + $this->application = $application; + $this->namespace = $namespace; + $this->showHidden = $showHidden; + } + + /** + * @return array + */ + public function getNamespaces() + { + if (null === $this->namespaces) { + $this->inspectApplication(); + } + + return $this->namespaces; + } + + /** + * @return Command[] + */ + public function getCommands() + { + if (null === $this->commands) { + $this->inspectApplication(); + } + + return $this->commands; + } + + /** + * @param string $name + * + * @return Command + * + * @throws CommandNotFoundException + */ + public function getCommand($name) + { + if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) { + throw new CommandNotFoundException(sprintf('Command %s does not exist.', $name)); + } + + return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name]; + } + + private function inspectApplication() + { + $this->commands = []; + $this->namespaces = []; + + $all = $this->application->all($this->namespace ? $this->application->findNamespace($this->namespace) : null); + foreach ($this->sortCommands($all) as $namespace => $commands) { + $names = []; + + /** @var Command $command */ + foreach ($commands as $name => $command) { + if (!$command->getName() || (!$this->showHidden && $command->isHidden())) { + continue; + } + + if ($command->getName() === $name) { + $this->commands[$name] = $command; + } else { + $this->aliases[$name] = $command; + } + + $names[] = $name; + } + + $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names]; + } + } + + private function sortCommands(array $commands): array + { + $namespacedCommands = []; + $globalCommands = []; + foreach ($commands as $name => $command) { + $key = $this->application->extractNamespace($name, 1); + if (!$key) { + $globalCommands['_global'][$name] = $command; + } else { + $namespacedCommands[$key][$name] = $command; + } + } + ksort($namespacedCommands); + $namespacedCommands = array_merge($globalCommands, $namespacedCommands); + + foreach ($namespacedCommands as &$commandsSet) { + ksort($commandsSet); + } + // unset reference to keep scope clear + unset($commandsSet); + + return $namespacedCommands; + } +} diff --git a/vendor/symfony/console/Descriptor/Descriptor.php b/vendor/symfony/console/Descriptor/Descriptor.php new file mode 100644 index 00000000..d25a708e --- /dev/null +++ b/vendor/symfony/console/Descriptor/Descriptor.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Descriptor; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * @author Jean-François Simon + * + * @internal + */ +abstract class Descriptor implements DescriptorInterface +{ + /** + * @var OutputInterface + */ + protected $output; + + /** + * {@inheritdoc} + */ + public function describe(OutputInterface $output, $object, array $options = []) + { + $this->output = $output; + + switch (true) { + case $object instanceof InputArgument: + $this->describeInputArgument($object, $options); + break; + case $object instanceof InputOption: + $this->describeInputOption($object, $options); + break; + case $object instanceof InputDefinition: + $this->describeInputDefinition($object, $options); + break; + case $object instanceof Command: + $this->describeCommand($object, $options); + break; + case $object instanceof Application: + $this->describeApplication($object, $options); + break; + default: + throw new InvalidArgumentException(sprintf('Object of type "%s" is not describable.', \get_class($object))); + } + } + + /** + * Writes content to output. + * + * @param string $content + * @param bool $decorated + */ + protected function write($content, $decorated = false) + { + $this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW); + } + + /** + * Describes an InputArgument instance. + * + * @return string|mixed + */ + abstract protected function describeInputArgument(InputArgument $argument, array $options = []); + + /** + * Describes an InputOption instance. + * + * @return string|mixed + */ + abstract protected function describeInputOption(InputOption $option, array $options = []); + + /** + * Describes an InputDefinition instance. + * + * @return string|mixed + */ + abstract protected function describeInputDefinition(InputDefinition $definition, array $options = []); + + /** + * Describes a Command instance. + * + * @return string|mixed + */ + abstract protected function describeCommand(Command $command, array $options = []); + + /** + * Describes an Application instance. + * + * @return string|mixed + */ + abstract protected function describeApplication(Application $application, array $options = []); +} diff --git a/vendor/symfony/console/Descriptor/DescriptorInterface.php b/vendor/symfony/console/Descriptor/DescriptorInterface.php new file mode 100644 index 00000000..fbc07df8 --- /dev/null +++ b/vendor/symfony/console/Descriptor/DescriptorInterface.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Descriptor; + +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Descriptor interface. + * + * @author Jean-François Simon + */ +interface DescriptorInterface +{ + /** + * Describes an object if supported. + * + * @param OutputInterface $output + * @param object $object + * @param array $options + */ + public function describe(OutputInterface $output, $object, array $options = []); +} diff --git a/vendor/symfony/console/Descriptor/JsonDescriptor.php b/vendor/symfony/console/Descriptor/JsonDescriptor.php new file mode 100644 index 00000000..197b843d --- /dev/null +++ b/vendor/symfony/console/Descriptor/JsonDescriptor.php @@ -0,0 +1,168 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Descriptor; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; + +/** + * JSON descriptor. + * + * @author Jean-François Simon + * + * @internal + */ +class JsonDescriptor extends Descriptor +{ + /** + * {@inheritdoc} + */ + protected function describeInputArgument(InputArgument $argument, array $options = []) + { + $this->writeData($this->getInputArgumentData($argument), $options); + } + + /** + * {@inheritdoc} + */ + protected function describeInputOption(InputOption $option, array $options = []) + { + $this->writeData($this->getInputOptionData($option), $options); + } + + /** + * {@inheritdoc} + */ + protected function describeInputDefinition(InputDefinition $definition, array $options = []) + { + $this->writeData($this->getInputDefinitionData($definition), $options); + } + + /** + * {@inheritdoc} + */ + protected function describeCommand(Command $command, array $options = []) + { + $this->writeData($this->getCommandData($command), $options); + } + + /** + * {@inheritdoc} + */ + protected function describeApplication(Application $application, array $options = []) + { + $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; + $description = new ApplicationDescription($application, $describedNamespace, true); + $commands = []; + + foreach ($description->getCommands() as $command) { + $commands[] = $this->getCommandData($command); + } + + $data = []; + if ('UNKNOWN' !== $application->getName()) { + $data['application']['name'] = $application->getName(); + if ('UNKNOWN' !== $application->getVersion()) { + $data['application']['version'] = $application->getVersion(); + } + } + + $data['commands'] = $commands; + + if ($describedNamespace) { + $data['namespace'] = $describedNamespace; + } else { + $data['namespaces'] = array_values($description->getNamespaces()); + } + + $this->writeData($data, $options); + } + + /** + * Writes data as json. + * + * @return array|string + */ + private function writeData(array $data, array $options) + { + $this->write(json_encode($data, isset($options['json_encoding']) ? $options['json_encoding'] : 0)); + } + + /** + * @return array + */ + private function getInputArgumentData(InputArgument $argument) + { + return [ + 'name' => $argument->getName(), + 'is_required' => $argument->isRequired(), + 'is_array' => $argument->isArray(), + 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $argument->getDescription()), + 'default' => INF === $argument->getDefault() ? 'INF' : $argument->getDefault(), + ]; + } + + /** + * @return array + */ + private function getInputOptionData(InputOption $option) + { + return [ + 'name' => '--'.$option->getName(), + 'shortcut' => $option->getShortcut() ? '-'.str_replace('|', '|-', $option->getShortcut()) : '', + 'accept_value' => $option->acceptValue(), + 'is_value_required' => $option->isValueRequired(), + 'is_multiple' => $option->isArray(), + 'description' => preg_replace('/\s*[\r\n]\s*/', ' ', $option->getDescription()), + 'default' => INF === $option->getDefault() ? 'INF' : $option->getDefault(), + ]; + } + + /** + * @return array + */ + private function getInputDefinitionData(InputDefinition $definition) + { + $inputArguments = []; + foreach ($definition->getArguments() as $name => $argument) { + $inputArguments[$name] = $this->getInputArgumentData($argument); + } + + $inputOptions = []; + foreach ($definition->getOptions() as $name => $option) { + $inputOptions[$name] = $this->getInputOptionData($option); + } + + return ['arguments' => $inputArguments, 'options' => $inputOptions]; + } + + /** + * @return array + */ + private function getCommandData(Command $command) + { + $command->getSynopsis(); + $command->mergeApplicationDefinition(false); + + return [ + 'name' => $command->getName(), + 'usage' => array_merge([$command->getSynopsis()], $command->getUsages(), $command->getAliases()), + 'description' => $command->getDescription(), + 'help' => $command->getProcessedHelp(), + 'definition' => $this->getInputDefinitionData($command->getNativeDefinition()), + 'hidden' => $command->isHidden(), + ]; + } +} diff --git a/vendor/symfony/console/Descriptor/MarkdownDescriptor.php b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php new file mode 100644 index 00000000..e6245778 --- /dev/null +++ b/vendor/symfony/console/Descriptor/MarkdownDescriptor.php @@ -0,0 +1,182 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Descriptor; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\Helper; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Markdown descriptor. + * + * @author Jean-François Simon + * + * @internal + */ +class MarkdownDescriptor extends Descriptor +{ + /** + * {@inheritdoc} + */ + public function describe(OutputInterface $output, $object, array $options = []) + { + $decorated = $output->isDecorated(); + $output->setDecorated(false); + + parent::describe($output, $object, $options); + + $output->setDecorated($decorated); + } + + /** + * {@inheritdoc} + */ + protected function write($content, $decorated = true) + { + parent::write($content, $decorated); + } + + /** + * {@inheritdoc} + */ + protected function describeInputArgument(InputArgument $argument, array $options = []) + { + $this->write( + '#### `'.($argument->getName() ?: '')."`\n\n" + .($argument->getDescription() ? preg_replace('/\s*[\r\n]\s*/', "\n", $argument->getDescription())."\n\n" : '') + .'* Is required: '.($argument->isRequired() ? 'yes' : 'no')."\n" + .'* Is array: '.($argument->isArray() ? 'yes' : 'no')."\n" + .'* Default: `'.str_replace("\n", '', var_export($argument->getDefault(), true)).'`' + ); + } + + /** + * {@inheritdoc} + */ + protected function describeInputOption(InputOption $option, array $options = []) + { + $name = '--'.$option->getName(); + if ($option->getShortcut()) { + $name .= '|-'.str_replace('|', '|-', $option->getShortcut()).''; + } + + $this->write( + '#### `'.$name.'`'."\n\n" + .($option->getDescription() ? preg_replace('/\s*[\r\n]\s*/', "\n", $option->getDescription())."\n\n" : '') + .'* Accept value: '.($option->acceptValue() ? 'yes' : 'no')."\n" + .'* Is value required: '.($option->isValueRequired() ? 'yes' : 'no')."\n" + .'* Is multiple: '.($option->isArray() ? 'yes' : 'no')."\n" + .'* Default: `'.str_replace("\n", '', var_export($option->getDefault(), true)).'`' + ); + } + + /** + * {@inheritdoc} + */ + protected function describeInputDefinition(InputDefinition $definition, array $options = []) + { + if ($showArguments = \count($definition->getArguments()) > 0) { + $this->write('### Arguments'); + foreach ($definition->getArguments() as $argument) { + $this->write("\n\n"); + $this->write($this->describeInputArgument($argument)); + } + } + + if (\count($definition->getOptions()) > 0) { + if ($showArguments) { + $this->write("\n\n"); + } + + $this->write('### Options'); + foreach ($definition->getOptions() as $option) { + $this->write("\n\n"); + $this->write($this->describeInputOption($option)); + } + } + } + + /** + * {@inheritdoc} + */ + protected function describeCommand(Command $command, array $options = []) + { + $command->getSynopsis(); + $command->mergeApplicationDefinition(false); + + $this->write( + '`'.$command->getName()."`\n" + .str_repeat('-', Helper::strlen($command->getName()) + 2)."\n\n" + .($command->getDescription() ? $command->getDescription()."\n\n" : '') + .'### Usage'."\n\n" + .array_reduce(array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()), function ($carry, $usage) { + return $carry.'* `'.$usage.'`'."\n"; + }) + ); + + if ($help = $command->getProcessedHelp()) { + $this->write("\n"); + $this->write($help); + } + + if ($command->getNativeDefinition()) { + $this->write("\n\n"); + $this->describeInputDefinition($command->getNativeDefinition()); + } + } + + /** + * {@inheritdoc} + */ + protected function describeApplication(Application $application, array $options = []) + { + $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; + $description = new ApplicationDescription($application, $describedNamespace); + $title = $this->getApplicationTitle($application); + + $this->write($title."\n".str_repeat('=', Helper::strlen($title))); + + foreach ($description->getNamespaces() as $namespace) { + if (ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { + $this->write("\n\n"); + $this->write('**'.$namespace['id'].':**'); + } + + $this->write("\n\n"); + $this->write(implode("\n", array_map(function ($commandName) use ($description) { + return sprintf('* [`%s`](#%s)', $commandName, str_replace(':', '', $description->getCommand($commandName)->getName())); + }, $namespace['commands']))); + } + + foreach ($description->getCommands() as $command) { + $this->write("\n\n"); + $this->write($this->describeCommand($command)); + } + } + + private function getApplicationTitle(Application $application) + { + if ('UNKNOWN' !== $application->getName()) { + if ('UNKNOWN' !== $application->getVersion()) { + return sprintf('%s %s', $application->getName(), $application->getVersion()); + } + + return $application->getName(); + } + + return 'Console Tool'; + } +} diff --git a/vendor/symfony/console/Descriptor/TextDescriptor.php b/vendor/symfony/console/Descriptor/TextDescriptor.php new file mode 100644 index 00000000..24fcf00a --- /dev/null +++ b/vendor/symfony/console/Descriptor/TextDescriptor.php @@ -0,0 +1,342 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Descriptor; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Helper\Helper; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; + +/** + * Text descriptor. + * + * @author Jean-François Simon + * + * @internal + */ +class TextDescriptor extends Descriptor +{ + /** + * {@inheritdoc} + */ + protected function describeInputArgument(InputArgument $argument, array $options = []) + { + if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) { + $default = sprintf(' [default: %s]', $this->formatDefaultValue($argument->getDefault())); + } else { + $default = ''; + } + + $totalWidth = isset($options['total_width']) ? $options['total_width'] : Helper::strlen($argument->getName()); + $spacingWidth = $totalWidth - \strlen($argument->getName()); + + $this->writeText(sprintf(' %s %s%s%s', + $argument->getName(), + str_repeat(' ', $spacingWidth), + // + 4 = 2 spaces before , 2 spaces after + preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $argument->getDescription()), + $default + ), $options); + } + + /** + * {@inheritdoc} + */ + protected function describeInputOption(InputOption $option, array $options = []) + { + if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) { + $default = sprintf(' [default: %s]', $this->formatDefaultValue($option->getDefault())); + } else { + $default = ''; + } + + $value = ''; + if ($option->acceptValue()) { + $value = '='.strtoupper($option->getName()); + + if ($option->isValueOptional()) { + $value = '['.$value.']'; + } + } + + $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions([$option]); + $synopsis = sprintf('%s%s', + $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : ' ', + sprintf('--%s%s', $option->getName(), $value) + ); + + $spacingWidth = $totalWidth - Helper::strlen($synopsis); + + $this->writeText(sprintf(' %s %s%s%s%s', + $synopsis, + str_repeat(' ', $spacingWidth), + // + 4 = 2 spaces before , 2 spaces after + preg_replace('/\s*[\r\n]\s*/', "\n".str_repeat(' ', $totalWidth + 4), $option->getDescription()), + $default, + $option->isArray() ? ' (multiple values allowed)' : '' + ), $options); + } + + /** + * {@inheritdoc} + */ + protected function describeInputDefinition(InputDefinition $definition, array $options = []) + { + $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions()); + foreach ($definition->getArguments() as $argument) { + $totalWidth = max($totalWidth, Helper::strlen($argument->getName())); + } + + if ($definition->getArguments()) { + $this->writeText('Arguments:', $options); + $this->writeText("\n"); + foreach ($definition->getArguments() as $argument) { + $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth])); + $this->writeText("\n"); + } + } + + if ($definition->getArguments() && $definition->getOptions()) { + $this->writeText("\n"); + } + + if ($definition->getOptions()) { + $laterOptions = []; + + $this->writeText('Options:', $options); + foreach ($definition->getOptions() as $option) { + if (\strlen($option->getShortcut()) > 1) { + $laterOptions[] = $option; + continue; + } + $this->writeText("\n"); + $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); + } + foreach ($laterOptions as $option) { + $this->writeText("\n"); + $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth])); + } + } + } + + /** + * {@inheritdoc} + */ + protected function describeCommand(Command $command, array $options = []) + { + $command->getSynopsis(true); + $command->getSynopsis(false); + $command->mergeApplicationDefinition(false); + + if ($description = $command->getDescription()) { + $this->writeText('Description:', $options); + $this->writeText("\n"); + $this->writeText(' '.$description); + $this->writeText("\n\n"); + } + + $this->writeText('Usage:', $options); + foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) { + $this->writeText("\n"); + $this->writeText(' '.OutputFormatter::escape($usage), $options); + } + $this->writeText("\n"); + + $definition = $command->getNativeDefinition(); + if ($definition->getOptions() || $definition->getArguments()) { + $this->writeText("\n"); + $this->describeInputDefinition($definition, $options); + $this->writeText("\n"); + } + + $help = $command->getProcessedHelp(); + if ($help && $help !== $description) { + $this->writeText("\n"); + $this->writeText('Help:', $options); + $this->writeText("\n"); + $this->writeText(' '.str_replace("\n", "\n ", $help), $options); + $this->writeText("\n"); + } + } + + /** + * {@inheritdoc} + */ + protected function describeApplication(Application $application, array $options = []) + { + $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null; + $description = new ApplicationDescription($application, $describedNamespace); + + if (isset($options['raw_text']) && $options['raw_text']) { + $width = $this->getColumnWidth($description->getCommands()); + + foreach ($description->getCommands() as $command) { + $this->writeText(sprintf("%-{$width}s %s", $command->getName(), $command->getDescription()), $options); + $this->writeText("\n"); + } + } else { + if ('' != $help = $application->getHelp()) { + $this->writeText("$help\n\n", $options); + } + + $this->writeText("Usage:\n", $options); + $this->writeText(" command [options] [arguments]\n\n", $options); + + $this->describeInputDefinition(new InputDefinition($application->getDefinition()->getOptions()), $options); + + $this->writeText("\n"); + $this->writeText("\n"); + + $commands = $description->getCommands(); + $namespaces = $description->getNamespaces(); + if ($describedNamespace && $namespaces) { + // make sure all alias commands are included when describing a specific namespace + $describedNamespaceInfo = reset($namespaces); + foreach ($describedNamespaceInfo['commands'] as $name) { + $commands[$name] = $description->getCommand($name); + } + } + + // calculate max. width based on available commands per namespace + $width = $this->getColumnWidth(array_merge(...array_values(array_map(function ($namespace) use ($commands) { + return array_intersect($namespace['commands'], array_keys($commands)); + }, $namespaces)))); + + if ($describedNamespace) { + $this->writeText(sprintf('Available commands for the "%s" namespace:', $describedNamespace), $options); + } else { + $this->writeText('Available commands:', $options); + } + + foreach ($namespaces as $namespace) { + $namespace['commands'] = array_filter($namespace['commands'], function ($name) use ($commands) { + return isset($commands[$name]); + }); + + if (!$namespace['commands']) { + continue; + } + + if (!$describedNamespace && ApplicationDescription::GLOBAL_NAMESPACE !== $namespace['id']) { + $this->writeText("\n"); + $this->writeText(' '.$namespace['id'].'', $options); + } + + foreach ($namespace['commands'] as $name) { + $this->writeText("\n"); + $spacingWidth = $width - Helper::strlen($name); + $command = $commands[$name]; + $commandAliases = $name === $command->getName() ? $this->getCommandAliasesText($command) : ''; + $this->writeText(sprintf(' %s%s%s', $name, str_repeat(' ', $spacingWidth), $commandAliases.$command->getDescription()), $options); + } + } + + $this->writeText("\n"); + } + } + + /** + * {@inheritdoc} + */ + private function writeText($content, array $options = []) + { + $this->write( + isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content, + isset($options['raw_output']) ? !$options['raw_output'] : true + ); + } + + /** + * Formats command aliases to show them in the command description. + */ + private function getCommandAliasesText(Command $command): string + { + $text = ''; + $aliases = $command->getAliases(); + + if ($aliases) { + $text = '['.implode('|', $aliases).'] '; + } + + return $text; + } + + /** + * Formats input option/argument default value. + * + * @param mixed $default + */ + private function formatDefaultValue($default): string + { + if (INF === $default) { + return 'INF'; + } + + if (\is_string($default)) { + $default = OutputFormatter::escape($default); + } elseif (\is_array($default)) { + foreach ($default as $key => $value) { + if (\is_string($value)) { + $default[$key] = OutputFormatter::escape($value); + } + } + } + + return str_replace('\\\\', '\\', json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); + } + + /** + * @param (Command|string)[] $commands + */ + private function getColumnWidth(array $commands): int + { + $widths = []; + + foreach ($commands as $command) { + if ($command instanceof Command) { + $widths[] = Helper::strlen($command->getName()); + foreach ($command->getAliases() as $alias) { + $widths[] = Helper::strlen($alias); + } + } else { + $widths[] = Helper::strlen($command); + } + } + + return $widths ? max($widths) + 2 : 0; + } + + /** + * @param InputOption[] $options + */ + private function calculateTotalWidthForOptions(array $options): int + { + $totalWidth = 0; + foreach ($options as $option) { + // "-" + shortcut + ", --" + name + $nameLength = 1 + max(Helper::strlen($option->getShortcut()), 1) + 4 + Helper::strlen($option->getName()); + + if ($option->acceptValue()) { + $valueLength = 1 + Helper::strlen($option->getName()); // = + value + $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ] + + $nameLength += $valueLength; + } + $totalWidth = max($totalWidth, $nameLength); + } + + return $totalWidth; + } +} diff --git a/vendor/symfony/console/Descriptor/XmlDescriptor.php b/vendor/symfony/console/Descriptor/XmlDescriptor.php new file mode 100644 index 00000000..f5202a33 --- /dev/null +++ b/vendor/symfony/console/Descriptor/XmlDescriptor.php @@ -0,0 +1,245 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Descriptor; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputOption; + +/** + * XML descriptor. + * + * @author Jean-François Simon + * + * @internal + */ +class XmlDescriptor extends Descriptor +{ + /** + * @return \DOMDocument + */ + public function getInputDefinitionDocument(InputDefinition $definition) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($definitionXML = $dom->createElement('definition')); + + $definitionXML->appendChild($argumentsXML = $dom->createElement('arguments')); + foreach ($definition->getArguments() as $argument) { + $this->appendDocument($argumentsXML, $this->getInputArgumentDocument($argument)); + } + + $definitionXML->appendChild($optionsXML = $dom->createElement('options')); + foreach ($definition->getOptions() as $option) { + $this->appendDocument($optionsXML, $this->getInputOptionDocument($option)); + } + + return $dom; + } + + /** + * @return \DOMDocument + */ + public function getCommandDocument(Command $command) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($commandXML = $dom->createElement('command')); + + $command->getSynopsis(); + $command->mergeApplicationDefinition(false); + + $commandXML->setAttribute('id', $command->getName()); + $commandXML->setAttribute('name', $command->getName()); + $commandXML->setAttribute('hidden', $command->isHidden() ? 1 : 0); + + $commandXML->appendChild($usagesXML = $dom->createElement('usages')); + + foreach (array_merge([$command->getSynopsis()], $command->getAliases(), $command->getUsages()) as $usage) { + $usagesXML->appendChild($dom->createElement('usage', $usage)); + } + + $commandXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getDescription()))); + + $commandXML->appendChild($helpXML = $dom->createElement('help')); + $helpXML->appendChild($dom->createTextNode(str_replace("\n", "\n ", $command->getProcessedHelp()))); + + $definitionXML = $this->getInputDefinitionDocument($command->getNativeDefinition()); + $this->appendDocument($commandXML, $definitionXML->getElementsByTagName('definition')->item(0)); + + return $dom; + } + + /** + * @param Application $application + * @param string|null $namespace + * + * @return \DOMDocument + */ + public function getApplicationDocument(Application $application, $namespace = null) + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + $dom->appendChild($rootXml = $dom->createElement('symfony')); + + if ('UNKNOWN' !== $application->getName()) { + $rootXml->setAttribute('name', $application->getName()); + if ('UNKNOWN' !== $application->getVersion()) { + $rootXml->setAttribute('version', $application->getVersion()); + } + } + + $rootXml->appendChild($commandsXML = $dom->createElement('commands')); + + $description = new ApplicationDescription($application, $namespace, true); + + if ($namespace) { + $commandsXML->setAttribute('namespace', $namespace); + } + + foreach ($description->getCommands() as $command) { + $this->appendDocument($commandsXML, $this->getCommandDocument($command)); + } + + if (!$namespace) { + $rootXml->appendChild($namespacesXML = $dom->createElement('namespaces')); + + foreach ($description->getNamespaces() as $namespaceDescription) { + $namespacesXML->appendChild($namespaceArrayXML = $dom->createElement('namespace')); + $namespaceArrayXML->setAttribute('id', $namespaceDescription['id']); + + foreach ($namespaceDescription['commands'] as $name) { + $namespaceArrayXML->appendChild($commandXML = $dom->createElement('command')); + $commandXML->appendChild($dom->createTextNode($name)); + } + } + } + + return $dom; + } + + /** + * {@inheritdoc} + */ + protected function describeInputArgument(InputArgument $argument, array $options = []) + { + $this->writeDocument($this->getInputArgumentDocument($argument)); + } + + /** + * {@inheritdoc} + */ + protected function describeInputOption(InputOption $option, array $options = []) + { + $this->writeDocument($this->getInputOptionDocument($option)); + } + + /** + * {@inheritdoc} + */ + protected function describeInputDefinition(InputDefinition $definition, array $options = []) + { + $this->writeDocument($this->getInputDefinitionDocument($definition)); + } + + /** + * {@inheritdoc} + */ + protected function describeCommand(Command $command, array $options = []) + { + $this->writeDocument($this->getCommandDocument($command)); + } + + /** + * {@inheritdoc} + */ + protected function describeApplication(Application $application, array $options = []) + { + $this->writeDocument($this->getApplicationDocument($application, isset($options['namespace']) ? $options['namespace'] : null)); + } + + /** + * Appends document children to parent node. + */ + private function appendDocument(\DOMNode $parentNode, \DOMNode $importedParent) + { + foreach ($importedParent->childNodes as $childNode) { + $parentNode->appendChild($parentNode->ownerDocument->importNode($childNode, true)); + } + } + + /** + * Writes DOM document. + * + * @return \DOMDocument|string + */ + private function writeDocument(\DOMDocument $dom) + { + $dom->formatOutput = true; + $this->write($dom->saveXML()); + } + + private function getInputArgumentDocument(InputArgument $argument): \DOMDocument + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + + $dom->appendChild($objectXML = $dom->createElement('argument')); + $objectXML->setAttribute('name', $argument->getName()); + $objectXML->setAttribute('is_required', $argument->isRequired() ? 1 : 0); + $objectXML->setAttribute('is_array', $argument->isArray() ? 1 : 0); + $objectXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode($argument->getDescription())); + + $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); + $defaults = \is_array($argument->getDefault()) ? $argument->getDefault() : (\is_bool($argument->getDefault()) ? [var_export($argument->getDefault(), true)] : ($argument->getDefault() ? [$argument->getDefault()] : [])); + foreach ($defaults as $default) { + $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); + $defaultXML->appendChild($dom->createTextNode($default)); + } + + return $dom; + } + + private function getInputOptionDocument(InputOption $option): \DOMDocument + { + $dom = new \DOMDocument('1.0', 'UTF-8'); + + $dom->appendChild($objectXML = $dom->createElement('option')); + $objectXML->setAttribute('name', '--'.$option->getName()); + $pos = strpos($option->getShortcut(), '|'); + if (false !== $pos) { + $objectXML->setAttribute('shortcut', '-'.substr($option->getShortcut(), 0, $pos)); + $objectXML->setAttribute('shortcuts', '-'.str_replace('|', '|-', $option->getShortcut())); + } else { + $objectXML->setAttribute('shortcut', $option->getShortcut() ? '-'.$option->getShortcut() : ''); + } + $objectXML->setAttribute('accept_value', $option->acceptValue() ? 1 : 0); + $objectXML->setAttribute('is_value_required', $option->isValueRequired() ? 1 : 0); + $objectXML->setAttribute('is_multiple', $option->isArray() ? 1 : 0); + $objectXML->appendChild($descriptionXML = $dom->createElement('description')); + $descriptionXML->appendChild($dom->createTextNode($option->getDescription())); + + if ($option->acceptValue()) { + $defaults = \is_array($option->getDefault()) ? $option->getDefault() : (\is_bool($option->getDefault()) ? [var_export($option->getDefault(), true)] : ($option->getDefault() ? [$option->getDefault()] : [])); + $objectXML->appendChild($defaultsXML = $dom->createElement('defaults')); + + if (!empty($defaults)) { + foreach ($defaults as $default) { + $defaultsXML->appendChild($defaultXML = $dom->createElement('default')); + $defaultXML->appendChild($dom->createTextNode($default)); + } + } + } + + return $dom; + } +} diff --git a/vendor/symfony/console/Event/ConsoleCommandEvent.php b/vendor/symfony/console/Event/ConsoleCommandEvent.php new file mode 100644 index 00000000..2f517c1d --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleCommandEvent.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Event; + +/** + * Allows to do things before the command is executed, like skipping the command or changing the input. + * + * @author Fabien Potencier + */ +class ConsoleCommandEvent extends ConsoleEvent +{ + /** + * The return code for skipped commands, this will also be passed into the terminate event. + */ + const RETURN_CODE_DISABLED = 113; + + /** + * Indicates if the command should be run or skipped. + */ + private $commandShouldRun = true; + + /** + * Disables the command, so it won't be run. + * + * @return bool + */ + public function disableCommand() + { + return $this->commandShouldRun = false; + } + + /** + * Enables the command. + * + * @return bool + */ + public function enableCommand() + { + return $this->commandShouldRun = true; + } + + /** + * Returns true if the command is runnable, false otherwise. + * + * @return bool + */ + public function commandShouldRun() + { + return $this->commandShouldRun; + } +} diff --git a/vendor/symfony/console/Event/ConsoleErrorEvent.php b/vendor/symfony/console/Event/ConsoleErrorEvent.php new file mode 100644 index 00000000..25d9b881 --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleErrorEvent.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Event; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Allows to handle throwables thrown while running a command. + * + * @author Wouter de Jong + */ +final class ConsoleErrorEvent extends ConsoleEvent +{ + private $error; + private $exitCode; + + public function __construct(InputInterface $input, OutputInterface $output, \Throwable $error, Command $command = null) + { + parent::__construct($command, $input, $output); + + $this->error = $error; + } + + public function getError(): \Throwable + { + return $this->error; + } + + public function setError(\Throwable $error): void + { + $this->error = $error; + } + + public function setExitCode(int $exitCode): void + { + $this->exitCode = $exitCode; + + $r = new \ReflectionProperty($this->error, 'code'); + $r->setAccessible(true); + $r->setValue($this->error, $this->exitCode); + } + + public function getExitCode(): int + { + return null !== $this->exitCode ? $this->exitCode : (\is_int($this->error->getCode()) && 0 !== $this->error->getCode() ? $this->error->getCode() : 1); + } +} diff --git a/vendor/symfony/console/Event/ConsoleEvent.php b/vendor/symfony/console/Event/ConsoleEvent.php new file mode 100644 index 00000000..5440da21 --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleEvent.php @@ -0,0 +1,67 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Event; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\EventDispatcher\Event; + +/** + * Allows to inspect input and output of a command. + * + * @author Francesco Levorato + */ +class ConsoleEvent extends Event +{ + protected $command; + + private $input; + private $output; + + public function __construct(Command $command = null, InputInterface $input, OutputInterface $output) + { + $this->command = $command; + $this->input = $input; + $this->output = $output; + } + + /** + * Gets the command that is executed. + * + * @return Command|null A Command instance + */ + public function getCommand() + { + return $this->command; + } + + /** + * Gets the input instance. + * + * @return InputInterface An InputInterface instance + */ + public function getInput() + { + return $this->input; + } + + /** + * Gets the output instance. + * + * @return OutputInterface An OutputInterface instance + */ + public function getOutput() + { + return $this->output; + } +} diff --git a/vendor/symfony/console/Event/ConsoleTerminateEvent.php b/vendor/symfony/console/Event/ConsoleTerminateEvent.php new file mode 100644 index 00000000..ff0c749d --- /dev/null +++ b/vendor/symfony/console/Event/ConsoleTerminateEvent.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Event; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Allows to manipulate the exit code of a command after its execution. + * + * @author Francesco Levorato + */ +class ConsoleTerminateEvent extends ConsoleEvent +{ + private $exitCode; + + public function __construct(Command $command, InputInterface $input, OutputInterface $output, int $exitCode) + { + parent::__construct($command, $input, $output); + + $this->setExitCode($exitCode); + } + + /** + * Sets the exit code. + * + * @param int $exitCode The command exit code + */ + public function setExitCode($exitCode) + { + $this->exitCode = (int) $exitCode; + } + + /** + * Gets the exit code. + * + * @return int The command exit code + */ + public function getExitCode() + { + return $this->exitCode; + } +} diff --git a/vendor/symfony/console/EventListener/ErrorListener.php b/vendor/symfony/console/EventListener/ErrorListener.php new file mode 100644 index 00000000..212ad1d9 --- /dev/null +++ b/vendor/symfony/console/EventListener/ErrorListener.php @@ -0,0 +1,91 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\EventListener; + +use Psr\Log\LoggerInterface; +use Symfony\Component\Console\ConsoleEvents; +use Symfony\Component\Console\Event\ConsoleErrorEvent; +use Symfony\Component\Console\Event\ConsoleEvent; +use Symfony\Component\Console\Event\ConsoleTerminateEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * @author James Halsall + * @author Robin Chalas + */ +class ErrorListener implements EventSubscriberInterface +{ + private $logger; + + public function __construct(LoggerInterface $logger = null) + { + $this->logger = $logger; + } + + public function onConsoleError(ConsoleErrorEvent $event) + { + if (null === $this->logger) { + return; + } + + $error = $event->getError(); + + if (!$inputString = $this->getInputString($event)) { + return $this->logger->error('An error occurred while using the console. Message: "{message}"', ['exception' => $error, 'message' => $error->getMessage()]); + } + + $this->logger->error('Error thrown while running command "{command}". Message: "{message}"', ['exception' => $error, 'command' => $inputString, 'message' => $error->getMessage()]); + } + + public function onConsoleTerminate(ConsoleTerminateEvent $event) + { + if (null === $this->logger) { + return; + } + + $exitCode = $event->getExitCode(); + + if (0 === $exitCode) { + return; + } + + if (!$inputString = $this->getInputString($event)) { + return $this->logger->debug('The console exited with code "{code}"', ['code' => $exitCode]); + } + + $this->logger->debug('Command "{command}" exited with code "{code}"', ['command' => $inputString, 'code' => $exitCode]); + } + + public static function getSubscribedEvents() + { + return [ + ConsoleEvents::ERROR => ['onConsoleError', -128], + ConsoleEvents::TERMINATE => ['onConsoleTerminate', -128], + ]; + } + + private static function getInputString(ConsoleEvent $event) + { + $commandName = $event->getCommand() ? $event->getCommand()->getName() : null; + $input = $event->getInput(); + + if (method_exists($input, '__toString')) { + if ($commandName) { + return str_replace(["'$commandName'", "\"$commandName\""], $commandName, (string) $input); + } + + return (string) $input; + } + + return $commandName; + } +} diff --git a/vendor/symfony/console/Exception/CommandNotFoundException.php b/vendor/symfony/console/Exception/CommandNotFoundException.php new file mode 100644 index 00000000..15ac522c --- /dev/null +++ b/vendor/symfony/console/Exception/CommandNotFoundException.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Exception; + +/** + * Represents an incorrect command name typed in the console. + * + * @author Jérôme Tamarelle + */ +class CommandNotFoundException extends \InvalidArgumentException implements ExceptionInterface +{ + private $alternatives; + + /** + * @param string $message Exception message to throw + * @param array $alternatives List of similar defined names + * @param int $code Exception code + * @param \Exception $previous Previous exception used for the exception chaining + */ + public function __construct(string $message, array $alternatives = [], int $code = 0, \Exception $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->alternatives = $alternatives; + } + + /** + * @return array A list of similar defined names + */ + public function getAlternatives() + { + return $this->alternatives; + } +} diff --git a/vendor/symfony/console/Exception/ExceptionInterface.php b/vendor/symfony/console/Exception/ExceptionInterface.php new file mode 100644 index 00000000..1624e13d --- /dev/null +++ b/vendor/symfony/console/Exception/ExceptionInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Exception; + +/** + * ExceptionInterface. + * + * @author Jérôme Tamarelle + */ +interface ExceptionInterface extends \Throwable +{ +} diff --git a/vendor/symfony/console/Exception/InvalidArgumentException.php b/vendor/symfony/console/Exception/InvalidArgumentException.php new file mode 100644 index 00000000..07cc0b61 --- /dev/null +++ b/vendor/symfony/console/Exception/InvalidArgumentException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Exception; + +/** + * @author Jérôme Tamarelle + */ +class InvalidArgumentException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Exception/InvalidOptionException.php b/vendor/symfony/console/Exception/InvalidOptionException.php new file mode 100644 index 00000000..b2eec616 --- /dev/null +++ b/vendor/symfony/console/Exception/InvalidOptionException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Exception; + +/** + * Represents an incorrect option name typed in the console. + * + * @author Jérôme Tamarelle + */ +class InvalidOptionException extends \InvalidArgumentException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Exception/LogicException.php b/vendor/symfony/console/Exception/LogicException.php new file mode 100644 index 00000000..fc37b8d8 --- /dev/null +++ b/vendor/symfony/console/Exception/LogicException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Exception; + +/** + * @author Jérôme Tamarelle + */ +class LogicException extends \LogicException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Exception/NamespaceNotFoundException.php b/vendor/symfony/console/Exception/NamespaceNotFoundException.php new file mode 100644 index 00000000..dd16e450 --- /dev/null +++ b/vendor/symfony/console/Exception/NamespaceNotFoundException.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Exception; + +/** + * Represents an incorrect namespace typed in the console. + * + * @author Pierre du Plessis + */ +class NamespaceNotFoundException extends CommandNotFoundException +{ +} diff --git a/vendor/symfony/console/Exception/RuntimeException.php b/vendor/symfony/console/Exception/RuntimeException.php new file mode 100644 index 00000000..51d7d80a --- /dev/null +++ b/vendor/symfony/console/Exception/RuntimeException.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Exception; + +/** + * @author Jérôme Tamarelle + */ +class RuntimeException extends \RuntimeException implements ExceptionInterface +{ +} diff --git a/vendor/symfony/console/Formatter/OutputFormatter.php b/vendor/symfony/console/Formatter/OutputFormatter.php new file mode 100644 index 00000000..a333f45b --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatter.php @@ -0,0 +1,278 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Formatter; + +use Symfony\Component\Console\Exception\InvalidArgumentException; + +/** + * Formatter class for console output. + * + * @author Konstantin Kudryashov + * @author Roland Franssen + */ +class OutputFormatter implements WrappableOutputFormatterInterface +{ + private $decorated; + private $styles = []; + private $styleStack; + + /** + * Escapes "<" special char in given text. + * + * @param string $text Text to escape + * + * @return string Escaped text + */ + public static function escape($text) + { + $text = preg_replace('/([^\\\\]?) FormatterStyle" instances + */ + public function __construct(bool $decorated = false, array $styles = []) + { + $this->decorated = $decorated; + + $this->setStyle('error', new OutputFormatterStyle('white', 'red')); + $this->setStyle('info', new OutputFormatterStyle('green')); + $this->setStyle('comment', new OutputFormatterStyle('yellow')); + $this->setStyle('question', new OutputFormatterStyle('black', 'cyan')); + + foreach ($styles as $name => $style) { + $this->setStyle($name, $style); + } + + $this->styleStack = new OutputFormatterStyleStack(); + } + + /** + * {@inheritdoc} + */ + public function setDecorated($decorated) + { + $this->decorated = (bool) $decorated; + } + + /** + * {@inheritdoc} + */ + public function isDecorated() + { + return $this->decorated; + } + + /** + * {@inheritdoc} + */ + public function setStyle($name, OutputFormatterStyleInterface $style) + { + $this->styles[strtolower($name)] = $style; + } + + /** + * {@inheritdoc} + */ + public function hasStyle($name) + { + return isset($this->styles[strtolower($name)]); + } + + /** + * {@inheritdoc} + */ + public function getStyle($name) + { + if (!$this->hasStyle($name)) { + throw new InvalidArgumentException(sprintf('Undefined style: %s', $name)); + } + + return $this->styles[strtolower($name)]; + } + + /** + * {@inheritdoc} + */ + public function format($message) + { + return $this->formatAndWrap((string) $message, 0); + } + + /** + * {@inheritdoc} + */ + public function formatAndWrap(string $message, int $width) + { + $offset = 0; + $output = ''; + $tagRegex = '[a-z][a-z0-9,_=;-]*+'; + $currentLineLength = 0; + preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE); + foreach ($matches[0] as $i => $match) { + $pos = $match[1]; + $text = $match[0]; + + if (0 != $pos && '\\' == $message[$pos - 1]) { + continue; + } + + // add the text up to the next tag + $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset), $output, $width, $currentLineLength); + $offset = $pos + \strlen($text); + + // opening tag? + if ($open = '/' != $text[1]) { + $tag = $matches[1][$i][0]; + } else { + $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : ''; + } + + if (!$open && !$tag) { + // + $this->styleStack->pop(); + } elseif (false === $style = $this->createStyleFromString($tag)) { + $output .= $this->applyCurrentStyle($text, $output, $width, $currentLineLength); + } elseif ($open) { + $this->styleStack->push($style); + } else { + $this->styleStack->pop($style); + } + } + + $output .= $this->applyCurrentStyle(substr($message, $offset), $output, $width, $currentLineLength); + + if (false !== strpos($output, "\0")) { + return strtr($output, ["\0" => '\\', '\\<' => '<']); + } + + return str_replace('\\<', '<', $output); + } + + /** + * @return OutputFormatterStyleStack + */ + public function getStyleStack() + { + return $this->styleStack; + } + + /** + * Tries to create new style instance from string. + * + * @return OutputFormatterStyle|false False if string is not format string + */ + private function createStyleFromString(string $string) + { + if (isset($this->styles[$string])) { + return $this->styles[$string]; + } + + if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', $string, $matches, PREG_SET_ORDER)) { + return false; + } + + $style = new OutputFormatterStyle(); + foreach ($matches as $match) { + array_shift($match); + $match[0] = strtolower($match[0]); + + if ('fg' == $match[0]) { + $style->setForeground(strtolower($match[1])); + } elseif ('bg' == $match[0]) { + $style->setBackground(strtolower($match[1])); + } elseif ('options' === $match[0]) { + preg_match_all('([^,;]+)', strtolower($match[1]), $options); + $options = array_shift($options); + foreach ($options as $option) { + $style->setOption($option); + } + } else { + return false; + } + } + + return $style; + } + + /** + * Applies current style from stack to text, if must be applied. + */ + private function applyCurrentStyle(string $text, string $current, int $width, int &$currentLineLength): string + { + if ('' === $text) { + return ''; + } + + if (!$width) { + return $this->isDecorated() ? $this->styleStack->getCurrent()->apply($text) : $text; + } + + if (!$currentLineLength && '' !== $current) { + $text = ltrim($text); + } + + if ($currentLineLength) { + $prefix = substr($text, 0, $i = $width - $currentLineLength)."\n"; + $text = substr($text, $i); + } else { + $prefix = ''; + } + + preg_match('~(\\n)$~', $text, $matches); + $text = $prefix.preg_replace('~([^\\n]{'.$width.'})\\ *~', "\$1\n", $text); + $text = rtrim($text, "\n").($matches[1] ?? ''); + + if (!$currentLineLength && '' !== $current && "\n" !== substr($current, -1)) { + $text = "\n".$text; + } + + $lines = explode("\n", $text); + if ($width === $currentLineLength = \strlen(end($lines))) { + $currentLineLength = 0; + } + + if ($this->isDecorated()) { + foreach ($lines as $i => $line) { + $lines[$i] = $this->styleStack->getCurrent()->apply($line); + } + } + + return implode("\n", $lines); + } +} diff --git a/vendor/symfony/console/Formatter/OutputFormatterInterface.php b/vendor/symfony/console/Formatter/OutputFormatterInterface.php new file mode 100644 index 00000000..281e240c --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatterInterface.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Formatter; + +/** + * Formatter interface for console output. + * + * @author Konstantin Kudryashov + */ +interface OutputFormatterInterface +{ + /** + * Sets the decorated flag. + * + * @param bool $decorated Whether to decorate the messages or not + */ + public function setDecorated($decorated); + + /** + * Gets the decorated flag. + * + * @return bool true if the output will decorate messages, false otherwise + */ + public function isDecorated(); + + /** + * Sets a new style. + * + * @param string $name The style name + * @param OutputFormatterStyleInterface $style The style instance + */ + public function setStyle($name, OutputFormatterStyleInterface $style); + + /** + * Checks if output formatter has style with specified name. + * + * @param string $name + * + * @return bool + */ + public function hasStyle($name); + + /** + * Gets style options from style with specified name. + * + * @param string $name + * + * @return OutputFormatterStyleInterface + * + * @throws \InvalidArgumentException When style isn't defined + */ + public function getStyle($name); + + /** + * Formats a message according to the given styles. + * + * @param string $message The message to style + * + * @return string The styled message + */ + public function format($message); +} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyle.php b/vendor/symfony/console/Formatter/OutputFormatterStyle.php new file mode 100644 index 00000000..dcc1beb4 --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatterStyle.php @@ -0,0 +1,203 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Formatter; + +use Symfony\Component\Console\Exception\InvalidArgumentException; + +/** + * Formatter style class for defining styles. + * + * @author Konstantin Kudryashov + */ +class OutputFormatterStyle implements OutputFormatterStyleInterface +{ + private static $availableForegroundColors = [ + 'black' => ['set' => 30, 'unset' => 39], + 'red' => ['set' => 31, 'unset' => 39], + 'green' => ['set' => 32, 'unset' => 39], + 'yellow' => ['set' => 33, 'unset' => 39], + 'blue' => ['set' => 34, 'unset' => 39], + 'magenta' => ['set' => 35, 'unset' => 39], + 'cyan' => ['set' => 36, 'unset' => 39], + 'white' => ['set' => 37, 'unset' => 39], + 'default' => ['set' => 39, 'unset' => 39], + ]; + private static $availableBackgroundColors = [ + 'black' => ['set' => 40, 'unset' => 49], + 'red' => ['set' => 41, 'unset' => 49], + 'green' => ['set' => 42, 'unset' => 49], + 'yellow' => ['set' => 43, 'unset' => 49], + 'blue' => ['set' => 44, 'unset' => 49], + 'magenta' => ['set' => 45, 'unset' => 49], + 'cyan' => ['set' => 46, 'unset' => 49], + 'white' => ['set' => 47, 'unset' => 49], + 'default' => ['set' => 49, 'unset' => 49], + ]; + private static $availableOptions = [ + 'bold' => ['set' => 1, 'unset' => 22], + 'underscore' => ['set' => 4, 'unset' => 24], + 'blink' => ['set' => 5, 'unset' => 25], + 'reverse' => ['set' => 7, 'unset' => 27], + 'conceal' => ['set' => 8, 'unset' => 28], + ]; + + private $foreground; + private $background; + private $options = []; + + /** + * Initializes output formatter style. + * + * @param string|null $foreground The style foreground color name + * @param string|null $background The style background color name + * @param array $options The style options + */ + public function __construct(string $foreground = null, string $background = null, array $options = []) + { + if (null !== $foreground) { + $this->setForeground($foreground); + } + if (null !== $background) { + $this->setBackground($background); + } + if (\count($options)) { + $this->setOptions($options); + } + } + + /** + * Sets style foreground color. + * + * @param string|null $color The color name + * + * @throws InvalidArgumentException When the color name isn't defined + */ + public function setForeground($color = null) + { + if (null === $color) { + $this->foreground = null; + + return; + } + + if (!isset(static::$availableForegroundColors[$color])) { + throw new InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors)))); + } + + $this->foreground = static::$availableForegroundColors[$color]; + } + + /** + * Sets style background color. + * + * @param string|null $color The color name + * + * @throws InvalidArgumentException When the color name isn't defined + */ + public function setBackground($color = null) + { + if (null === $color) { + $this->background = null; + + return; + } + + if (!isset(static::$availableBackgroundColors[$color])) { + throw new InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors)))); + } + + $this->background = static::$availableBackgroundColors[$color]; + } + + /** + * Sets some specific style option. + * + * @param string $option The option name + * + * @throws InvalidArgumentException When the option name isn't defined + */ + public function setOption($option) + { + if (!isset(static::$availableOptions[$option])) { + throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions)))); + } + + if (!\in_array(static::$availableOptions[$option], $this->options)) { + $this->options[] = static::$availableOptions[$option]; + } + } + + /** + * Unsets some specific style option. + * + * @param string $option The option name + * + * @throws InvalidArgumentException When the option name isn't defined + */ + public function unsetOption($option) + { + if (!isset(static::$availableOptions[$option])) { + throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions)))); + } + + $pos = array_search(static::$availableOptions[$option], $this->options); + if (false !== $pos) { + unset($this->options[$pos]); + } + } + + /** + * {@inheritdoc} + */ + public function setOptions(array $options) + { + $this->options = []; + + foreach ($options as $option) { + $this->setOption($option); + } + } + + /** + * Applies the style to a given text. + * + * @param string $text The text to style + * + * @return string + */ + public function apply($text) + { + $setCodes = []; + $unsetCodes = []; + + if (null !== $this->foreground) { + $setCodes[] = $this->foreground['set']; + $unsetCodes[] = $this->foreground['unset']; + } + if (null !== $this->background) { + $setCodes[] = $this->background['set']; + $unsetCodes[] = $this->background['unset']; + } + if (\count($this->options)) { + foreach ($this->options as $option) { + $setCodes[] = $option['set']; + $unsetCodes[] = $option['unset']; + } + } + + if (0 === \count($setCodes)) { + return $text; + } + + return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes)); + } +} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php new file mode 100644 index 00000000..4c7dc413 --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Formatter; + +/** + * Formatter style interface for defining styles. + * + * @author Konstantin Kudryashov + */ +interface OutputFormatterStyleInterface +{ + /** + * Sets style foreground color. + * + * @param string $color The color name + */ + public function setForeground($color = null); + + /** + * Sets style background color. + * + * @param string $color The color name + */ + public function setBackground($color = null); + + /** + * Sets some specific style option. + * + * @param string $option The option name + */ + public function setOption($option); + + /** + * Unsets some specific style option. + * + * @param string $option The option name + */ + public function unsetOption($option); + + /** + * Sets multiple style options at once. + */ + public function setOptions(array $options); + + /** + * Applies the style to a given text. + * + * @param string $text The text to style + * + * @return string + */ + public function apply($text); +} diff --git a/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php new file mode 100644 index 00000000..33f7d522 --- /dev/null +++ b/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php @@ -0,0 +1,110 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Formatter; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Contracts\Service\ResetInterface; + +/** + * @author Jean-François Simon + */ +class OutputFormatterStyleStack implements ResetInterface +{ + /** + * @var OutputFormatterStyleInterface[] + */ + private $styles; + + private $emptyStyle; + + public function __construct(OutputFormatterStyleInterface $emptyStyle = null) + { + $this->emptyStyle = $emptyStyle ?: new OutputFormatterStyle(); + $this->reset(); + } + + /** + * Resets stack (ie. empty internal arrays). + */ + public function reset() + { + $this->styles = []; + } + + /** + * Pushes a style in the stack. + */ + public function push(OutputFormatterStyleInterface $style) + { + $this->styles[] = $style; + } + + /** + * Pops a style from the stack. + * + * @return OutputFormatterStyleInterface + * + * @throws InvalidArgumentException When style tags incorrectly nested + */ + public function pop(OutputFormatterStyleInterface $style = null) + { + if (empty($this->styles)) { + return $this->emptyStyle; + } + + if (null === $style) { + return array_pop($this->styles); + } + + foreach (array_reverse($this->styles, true) as $index => $stackedStyle) { + if ($style->apply('') === $stackedStyle->apply('')) { + $this->styles = \array_slice($this->styles, 0, $index); + + return $stackedStyle; + } + } + + throw new InvalidArgumentException('Incorrectly nested style tag found.'); + } + + /** + * Computes current style with stacks top codes. + * + * @return OutputFormatterStyle + */ + public function getCurrent() + { + if (empty($this->styles)) { + return $this->emptyStyle; + } + + return $this->styles[\count($this->styles) - 1]; + } + + /** + * @return $this + */ + public function setEmptyStyle(OutputFormatterStyleInterface $emptyStyle) + { + $this->emptyStyle = $emptyStyle; + + return $this; + } + + /** + * @return OutputFormatterStyleInterface + */ + public function getEmptyStyle() + { + return $this->emptyStyle; + } +} diff --git a/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php new file mode 100644 index 00000000..6694053f --- /dev/null +++ b/vendor/symfony/console/Formatter/WrappableOutputFormatterInterface.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Formatter; + +/** + * Formatter interface for console output that supports word wrapping. + * + * @author Roland Franssen + */ +interface WrappableOutputFormatterInterface extends OutputFormatterInterface +{ + /** + * Formats a message according to the given styles, wrapping at `$width` (0 means no wrapping). + */ + public function formatAndWrap(string $message, int $width); +} diff --git a/vendor/symfony/console/Helper/DebugFormatterHelper.php b/vendor/symfony/console/Helper/DebugFormatterHelper.php new file mode 100644 index 00000000..16d11755 --- /dev/null +++ b/vendor/symfony/console/Helper/DebugFormatterHelper.php @@ -0,0 +1,127 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +/** + * Helps outputting debug information when running an external program from a command. + * + * An external program can be a Process, an HTTP request, or anything else. + * + * @author Fabien Potencier + */ +class DebugFormatterHelper extends Helper +{ + private $colors = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', 'default']; + private $started = []; + private $count = -1; + + /** + * Starts a debug formatting session. + * + * @param string $id The id of the formatting session + * @param string $message The message to display + * @param string $prefix The prefix to use + * + * @return string + */ + public function start($id, $message, $prefix = 'RUN') + { + $this->started[$id] = ['border' => ++$this->count % \count($this->colors)]; + + return sprintf("%s %s %s\n", $this->getBorder($id), $prefix, $message); + } + + /** + * Adds progress to a formatting session. + * + * @param string $id The id of the formatting session + * @param string $buffer The message to display + * @param bool $error Whether to consider the buffer as error + * @param string $prefix The prefix for output + * @param string $errorPrefix The prefix for error output + * + * @return string + */ + public function progress($id, $buffer, $error = false, $prefix = 'OUT', $errorPrefix = 'ERR') + { + $message = ''; + + if ($error) { + if (isset($this->started[$id]['out'])) { + $message .= "\n"; + unset($this->started[$id]['out']); + } + if (!isset($this->started[$id]['err'])) { + $message .= sprintf('%s %s ', $this->getBorder($id), $errorPrefix); + $this->started[$id]['err'] = true; + } + + $message .= str_replace("\n", sprintf("\n%s %s ", $this->getBorder($id), $errorPrefix), $buffer); + } else { + if (isset($this->started[$id]['err'])) { + $message .= "\n"; + unset($this->started[$id]['err']); + } + if (!isset($this->started[$id]['out'])) { + $message .= sprintf('%s %s ', $this->getBorder($id), $prefix); + $this->started[$id]['out'] = true; + } + + $message .= str_replace("\n", sprintf("\n%s %s ", $this->getBorder($id), $prefix), $buffer); + } + + return $message; + } + + /** + * Stops a formatting session. + * + * @param string $id The id of the formatting session + * @param string $message The message to display + * @param bool $successful Whether to consider the result as success + * @param string $prefix The prefix for the end output + * + * @return string + */ + public function stop($id, $message, $successful, $prefix = 'RES') + { + $trailingEOL = isset($this->started[$id]['out']) || isset($this->started[$id]['err']) ? "\n" : ''; + + if ($successful) { + return sprintf("%s%s %s %s\n", $trailingEOL, $this->getBorder($id), $prefix, $message); + } + + $message = sprintf("%s%s %s %s\n", $trailingEOL, $this->getBorder($id), $prefix, $message); + + unset($this->started[$id]['out'], $this->started[$id]['err']); + + return $message; + } + + /** + * @param string $id The id of the formatting session + * + * @return string + */ + private function getBorder($id) + { + return sprintf(' ', $this->colors[$this->started[$id]['border']]); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'debug_formatter'; + } +} diff --git a/vendor/symfony/console/Helper/DescriptorHelper.php b/vendor/symfony/console/Helper/DescriptorHelper.php new file mode 100644 index 00000000..f8a3847b --- /dev/null +++ b/vendor/symfony/console/Helper/DescriptorHelper.php @@ -0,0 +1,94 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Descriptor\DescriptorInterface; +use Symfony\Component\Console\Descriptor\JsonDescriptor; +use Symfony\Component\Console\Descriptor\MarkdownDescriptor; +use Symfony\Component\Console\Descriptor\TextDescriptor; +use Symfony\Component\Console\Descriptor\XmlDescriptor; +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * This class adds helper method to describe objects in various formats. + * + * @author Jean-François Simon + */ +class DescriptorHelper extends Helper +{ + /** + * @var DescriptorInterface[] + */ + private $descriptors = []; + + public function __construct() + { + $this + ->register('txt', new TextDescriptor()) + ->register('xml', new XmlDescriptor()) + ->register('json', new JsonDescriptor()) + ->register('md', new MarkdownDescriptor()) + ; + } + + /** + * Describes an object if supported. + * + * Available options are: + * * format: string, the output format name + * * raw_text: boolean, sets output type as raw + * + * @param OutputInterface $output + * @param object $object + * @param array $options + * + * @throws InvalidArgumentException when the given format is not supported + */ + public function describe(OutputInterface $output, $object, array $options = []) + { + $options = array_merge([ + 'raw_text' => false, + 'format' => 'txt', + ], $options); + + if (!isset($this->descriptors[$options['format']])) { + throw new InvalidArgumentException(sprintf('Unsupported format "%s".', $options['format'])); + } + + $descriptor = $this->descriptors[$options['format']]; + $descriptor->describe($output, $object, $options); + } + + /** + * Registers a descriptor. + * + * @param string $format + * @param DescriptorInterface $descriptor + * + * @return $this + */ + public function register($format, DescriptorInterface $descriptor) + { + $this->descriptors[$format] = $descriptor; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'descriptor'; + } +} diff --git a/vendor/symfony/console/Helper/FormatterHelper.php b/vendor/symfony/console/Helper/FormatterHelper.php new file mode 100644 index 00000000..4ad63856 --- /dev/null +++ b/vendor/symfony/console/Helper/FormatterHelper.php @@ -0,0 +1,106 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Formatter\OutputFormatter; + +/** + * The Formatter class provides helpers to format messages. + * + * @author Fabien Potencier + */ +class FormatterHelper extends Helper +{ + /** + * Formats a message within a section. + * + * @param string $section The section name + * @param string $message The message + * @param string $style The style to apply to the section + * + * @return string The format section + */ + public function formatSection($section, $message, $style = 'info') + { + return sprintf('<%s>[%s] %s', $style, $section, $style, $message); + } + + /** + * Formats a message as a block of text. + * + * @param string|array $messages The message to write in the block + * @param string $style The style to apply to the whole block + * @param bool $large Whether to return a large block + * + * @return string The formatter message + */ + public function formatBlock($messages, $style, $large = false) + { + if (!\is_array($messages)) { + $messages = [$messages]; + } + + $len = 0; + $lines = []; + foreach ($messages as $message) { + $message = OutputFormatter::escape($message); + $lines[] = sprintf($large ? ' %s ' : ' %s ', $message); + $len = max($this->strlen($message) + ($large ? 4 : 2), $len); + } + + $messages = $large ? [str_repeat(' ', $len)] : []; + for ($i = 0; isset($lines[$i]); ++$i) { + $messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i])); + } + if ($large) { + $messages[] = str_repeat(' ', $len); + } + + for ($i = 0; isset($messages[$i]); ++$i) { + $messages[$i] = sprintf('<%s>%s', $style, $messages[$i], $style); + } + + return implode("\n", $messages); + } + + /** + * Truncates a message to the given length. + * + * @param string $message + * @param int $length + * @param string $suffix + * + * @return string + */ + public function truncate($message, $length, $suffix = '...') + { + $computedLength = $length - $this->strlen($suffix); + + if ($computedLength > $this->strlen($message)) { + return $message; + } + + if (false === $encoding = mb_detect_encoding($message, null, true)) { + return substr($message, 0, $length).$suffix; + } + + return mb_substr($message, 0, $length, $encoding).$suffix; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'formatter'; + } +} diff --git a/vendor/symfony/console/Helper/Helper.php b/vendor/symfony/console/Helper/Helper.php new file mode 100644 index 00000000..0ddddf6b --- /dev/null +++ b/vendor/symfony/console/Helper/Helper.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Formatter\OutputFormatterInterface; + +/** + * Helper is the base class for all helper classes. + * + * @author Fabien Potencier + */ +abstract class Helper implements HelperInterface +{ + protected $helperSet = null; + + /** + * {@inheritdoc} + */ + public function setHelperSet(HelperSet $helperSet = null) + { + $this->helperSet = $helperSet; + } + + /** + * {@inheritdoc} + */ + public function getHelperSet() + { + return $this->helperSet; + } + + /** + * Returns the length of a string, using mb_strwidth if it is available. + * + * @param string $string The string to check its length + * + * @return int The length of the string + */ + public static function strlen($string) + { + if (false === $encoding = mb_detect_encoding($string, null, true)) { + return \strlen($string); + } + + return mb_strwidth($string, $encoding); + } + + /** + * Returns the subset of a string, using mb_substr if it is available. + * + * @param string $string String to subset + * @param int $from Start offset + * @param int|null $length Length to read + * + * @return string The string subset + */ + public static function substr($string, $from, $length = null) + { + if (false === $encoding = mb_detect_encoding($string, null, true)) { + return substr($string, $from, $length); + } + + return mb_substr($string, $from, $length, $encoding); + } + + public static function formatTime($secs) + { + static $timeFormats = [ + [0, '< 1 sec'], + [1, '1 sec'], + [2, 'secs', 1], + [60, '1 min'], + [120, 'mins', 60], + [3600, '1 hr'], + [7200, 'hrs', 3600], + [86400, '1 day'], + [172800, 'days', 86400], + ]; + + foreach ($timeFormats as $index => $format) { + if ($secs >= $format[0]) { + if ((isset($timeFormats[$index + 1]) && $secs < $timeFormats[$index + 1][0]) + || $index == \count($timeFormats) - 1 + ) { + if (2 == \count($format)) { + return $format[1]; + } + + return floor($secs / $format[2]).' '.$format[1]; + } + } + } + } + + public static function formatMemory($memory) + { + if ($memory >= 1024 * 1024 * 1024) { + return sprintf('%.1f GiB', $memory / 1024 / 1024 / 1024); + } + + if ($memory >= 1024 * 1024) { + return sprintf('%.1f MiB', $memory / 1024 / 1024); + } + + if ($memory >= 1024) { + return sprintf('%d KiB', $memory / 1024); + } + + return sprintf('%d B', $memory); + } + + public static function strlenWithoutDecoration(OutputFormatterInterface $formatter, $string) + { + return self::strlen(self::removeDecoration($formatter, $string)); + } + + public static function removeDecoration(OutputFormatterInterface $formatter, $string) + { + $isDecorated = $formatter->isDecorated(); + $formatter->setDecorated(false); + // remove <...> formatting + $string = $formatter->format($string); + // remove already formatted characters + $string = preg_replace("/\033\[[^m]*m/", '', $string); + $formatter->setDecorated($isDecorated); + + return $string; + } +} diff --git a/vendor/symfony/console/Helper/HelperInterface.php b/vendor/symfony/console/Helper/HelperInterface.php new file mode 100644 index 00000000..1ce82358 --- /dev/null +++ b/vendor/symfony/console/Helper/HelperInterface.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +/** + * HelperInterface is the interface all helpers must implement. + * + * @author Fabien Potencier + */ +interface HelperInterface +{ + /** + * Sets the helper set associated with this helper. + */ + public function setHelperSet(HelperSet $helperSet = null); + + /** + * Gets the helper set associated with this helper. + * + * @return HelperSet A HelperSet instance + */ + public function getHelperSet(); + + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + public function getName(); +} diff --git a/vendor/symfony/console/Helper/HelperSet.php b/vendor/symfony/console/Helper/HelperSet.php new file mode 100644 index 00000000..c73fecd4 --- /dev/null +++ b/vendor/symfony/console/Helper/HelperSet.php @@ -0,0 +1,108 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Exception\InvalidArgumentException; + +/** + * HelperSet represents a set of helpers to be used with a command. + * + * @author Fabien Potencier + */ +class HelperSet implements \IteratorAggregate +{ + /** + * @var Helper[] + */ + private $helpers = []; + private $command; + + /** + * @param Helper[] $helpers An array of helper + */ + public function __construct(array $helpers = []) + { + foreach ($helpers as $alias => $helper) { + $this->set($helper, \is_int($alias) ? null : $alias); + } + } + + /** + * Sets a helper. + * + * @param HelperInterface $helper The helper instance + * @param string $alias An alias + */ + public function set(HelperInterface $helper, $alias = null) + { + $this->helpers[$helper->getName()] = $helper; + if (null !== $alias) { + $this->helpers[$alias] = $helper; + } + + $helper->setHelperSet($this); + } + + /** + * Returns true if the helper if defined. + * + * @param string $name The helper name + * + * @return bool true if the helper is defined, false otherwise + */ + public function has($name) + { + return isset($this->helpers[$name]); + } + + /** + * Gets a helper value. + * + * @param string $name The helper name + * + * @return HelperInterface The helper instance + * + * @throws InvalidArgumentException if the helper is not defined + */ + public function get($name) + { + if (!$this->has($name)) { + throw new InvalidArgumentException(sprintf('The helper "%s" is not defined.', $name)); + } + + return $this->helpers[$name]; + } + + public function setCommand(Command $command = null) + { + $this->command = $command; + } + + /** + * Gets the command associated with this helper set. + * + * @return Command A Command instance + */ + public function getCommand() + { + return $this->command; + } + + /** + * @return Helper[] + */ + public function getIterator() + { + return new \ArrayIterator($this->helpers); + } +} diff --git a/vendor/symfony/console/Helper/InputAwareHelper.php b/vendor/symfony/console/Helper/InputAwareHelper.php new file mode 100644 index 00000000..0d0dba23 --- /dev/null +++ b/vendor/symfony/console/Helper/InputAwareHelper.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Input\InputAwareInterface; +use Symfony\Component\Console\Input\InputInterface; + +/** + * An implementation of InputAwareInterface for Helpers. + * + * @author Wouter J + */ +abstract class InputAwareHelper extends Helper implements InputAwareInterface +{ + protected $input; + + /** + * {@inheritdoc} + */ + public function setInput(InputInterface $input) + { + $this->input = $input; + } +} diff --git a/vendor/symfony/console/Helper/ProcessHelper.php b/vendor/symfony/console/Helper/ProcessHelper.php new file mode 100644 index 00000000..e3a7c77b --- /dev/null +++ b/vendor/symfony/console/Helper/ProcessHelper.php @@ -0,0 +1,156 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Process\Exception\ProcessFailedException; +use Symfony\Component\Process\Process; + +/** + * The ProcessHelper class provides helpers to run external processes. + * + * @author Fabien Potencier + * + * @final since Symfony 4.2 + */ +class ProcessHelper extends Helper +{ + /** + * Runs an external process. + * + * @param OutputInterface $output An OutputInterface instance + * @param array|Process $cmd An instance of Process or an array of the command and arguments + * @param string|null $error An error message that must be displayed if something went wrong + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * @param int $verbosity The threshold for verbosity + * + * @return Process The process that ran + */ + public function run(OutputInterface $output, $cmd, $error = null, callable $callback = null, $verbosity = OutputInterface::VERBOSITY_VERY_VERBOSE) + { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + + $formatter = $this->getHelperSet()->get('debug_formatter'); + + if ($cmd instanceof Process) { + $cmd = [$cmd]; + } + + if (!\is_array($cmd)) { + @trigger_error(sprintf('Passing a command as a string to "%s()" is deprecated since Symfony 4.2, pass it the command as an array of arguments instead.', __METHOD__), E_USER_DEPRECATED); + $cmd = [\method_exists(Process::class, 'fromShellCommandline') ? Process::fromShellCommandline($cmd) : new Process($cmd)]; + } + + if (\is_string($cmd[0] ?? null)) { + $process = new Process($cmd); + $cmd = []; + } elseif (($cmd[0] ?? null) instanceof Process) { + $process = $cmd[0]; + unset($cmd[0]); + } else { + throw new \InvalidArgumentException(sprintf('Invalid command provided to "%s()": the command should be an array whose first element is either the path to the binary to run or a "Process" object.', __METHOD__)); + } + + if ($verbosity <= $output->getVerbosity()) { + $output->write($formatter->start(spl_object_hash($process), $this->escapeString($process->getCommandLine()))); + } + + if ($output->isDebug()) { + $callback = $this->wrapCallback($output, $process, $callback); + } + + $process->run($callback, $cmd); + + if ($verbosity <= $output->getVerbosity()) { + $message = $process->isSuccessful() ? 'Command ran successfully' : sprintf('%s Command did not run successfully', $process->getExitCode()); + $output->write($formatter->stop(spl_object_hash($process), $message, $process->isSuccessful())); + } + + if (!$process->isSuccessful() && null !== $error) { + $output->writeln(sprintf('%s', $this->escapeString($error))); + } + + return $process; + } + + /** + * Runs the process. + * + * This is identical to run() except that an exception is thrown if the process + * exits with a non-zero exit code. + * + * @param OutputInterface $output An OutputInterface instance + * @param string|Process $cmd An instance of Process or a command to run + * @param string|null $error An error message that must be displayed if something went wrong + * @param callable|null $callback A PHP callback to run whenever there is some + * output available on STDOUT or STDERR + * + * @return Process The process that ran + * + * @throws ProcessFailedException + * + * @see run() + */ + public function mustRun(OutputInterface $output, $cmd, $error = null, callable $callback = null) + { + $process = $this->run($output, $cmd, $error, $callback); + + if (!$process->isSuccessful()) { + throw new ProcessFailedException($process); + } + + return $process; + } + + /** + * Wraps a Process callback to add debugging output. + * + * @param OutputInterface $output An OutputInterface interface + * @param Process $process The Process + * @param callable|null $callback A PHP callable + * + * @return callable + */ + public function wrapCallback(OutputInterface $output, Process $process, callable $callback = null) + { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + + $formatter = $this->getHelperSet()->get('debug_formatter'); + + return function ($type, $buffer) use ($output, $process, $callback, $formatter) { + $output->write($formatter->progress(spl_object_hash($process), $this->escapeString($buffer), Process::ERR === $type)); + + if (null !== $callback) { + $callback($type, $buffer); + } + }; + } + + private function escapeString($str) + { + return str_replace('<', '\\<', $str); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'process'; + } +} diff --git a/vendor/symfony/console/Helper/ProgressBar.php b/vendor/symfony/console/Helper/ProgressBar.php new file mode 100644 index 00000000..b68d9fe3 --- /dev/null +++ b/vendor/symfony/console/Helper/ProgressBar.php @@ -0,0 +1,530 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Exception\LogicException; +use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\ConsoleSectionOutput; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Terminal; + +/** + * The ProgressBar provides helpers to display progress output. + * + * @author Fabien Potencier + * @author Chris Jones + */ +final class ProgressBar +{ + private $barWidth = 28; + private $barChar; + private $emptyBarChar = '-'; + private $progressChar = '>'; + private $format; + private $internalFormat; + private $redrawFreq = 1; + private $output; + private $step = 0; + private $max; + private $startTime; + private $stepWidth; + private $percent = 0.0; + private $formatLineCount; + private $messages = []; + private $overwrite = true; + private $terminal; + private $firstRun = true; + + private static $formatters; + private static $formats; + + /** + * @param OutputInterface $output An OutputInterface instance + * @param int $max Maximum steps (0 if unknown) + */ + public function __construct(OutputInterface $output, int $max = 0) + { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + + $this->output = $output; + $this->setMaxSteps($max); + $this->terminal = new Terminal(); + + if (!$this->output->isDecorated()) { + // disable overwrite when output does not support ANSI codes. + $this->overwrite = false; + + // set a reasonable redraw frequency so output isn't flooded + $this->setRedrawFrequency($max / 10); + } + + $this->startTime = time(); + } + + /** + * Sets a placeholder formatter for a given name. + * + * This method also allow you to override an existing placeholder. + * + * @param string $name The placeholder name (including the delimiter char like %) + * @param callable $callable A PHP callable + */ + public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void + { + if (!self::$formatters) { + self::$formatters = self::initPlaceholderFormatters(); + } + + self::$formatters[$name] = $callable; + } + + /** + * Gets the placeholder formatter for a given name. + * + * @param string $name The placeholder name (including the delimiter char like %) + * + * @return callable|null A PHP callable + */ + public static function getPlaceholderFormatterDefinition(string $name): ?callable + { + if (!self::$formatters) { + self::$formatters = self::initPlaceholderFormatters(); + } + + return isset(self::$formatters[$name]) ? self::$formatters[$name] : null; + } + + /** + * Sets a format for a given name. + * + * This method also allow you to override an existing format. + * + * @param string $name The format name + * @param string $format A format string + */ + public static function setFormatDefinition(string $name, string $format): void + { + if (!self::$formats) { + self::$formats = self::initFormats(); + } + + self::$formats[$name] = $format; + } + + /** + * Gets the format for a given name. + * + * @param string $name The format name + * + * @return string|null A format string + */ + public static function getFormatDefinition(string $name): ?string + { + if (!self::$formats) { + self::$formats = self::initFormats(); + } + + return isset(self::$formats[$name]) ? self::$formats[$name] : null; + } + + /** + * Associates a text with a named placeholder. + * + * The text is displayed when the progress bar is rendered but only + * when the corresponding placeholder is part of the custom format line + * (by wrapping the name with %). + * + * @param string $message The text to associate with the placeholder + * @param string $name The name of the placeholder + */ + public function setMessage(string $message, string $name = 'message') + { + $this->messages[$name] = $message; + } + + public function getMessage(string $name = 'message') + { + return $this->messages[$name]; + } + + public function getStartTime(): int + { + return $this->startTime; + } + + public function getMaxSteps(): int + { + return $this->max; + } + + public function getProgress(): int + { + return $this->step; + } + + private function getStepWidth(): int + { + return $this->stepWidth; + } + + public function getProgressPercent(): float + { + return $this->percent; + } + + public function setBarWidth(int $size) + { + $this->barWidth = max(1, $size); + } + + public function getBarWidth(): int + { + return $this->barWidth; + } + + public function setBarCharacter(string $char) + { + $this->barChar = $char; + } + + public function getBarCharacter(): string + { + if (null === $this->barChar) { + return $this->max ? '=' : $this->emptyBarChar; + } + + return $this->barChar; + } + + public function setEmptyBarCharacter(string $char) + { + $this->emptyBarChar = $char; + } + + public function getEmptyBarCharacter(): string + { + return $this->emptyBarChar; + } + + public function setProgressCharacter(string $char) + { + $this->progressChar = $char; + } + + public function getProgressCharacter(): string + { + return $this->progressChar; + } + + public function setFormat(string $format) + { + $this->format = null; + $this->internalFormat = $format; + } + + /** + * Sets the redraw frequency. + * + * @param int|float $freq The frequency in steps + */ + public function setRedrawFrequency(int $freq) + { + $this->redrawFreq = max($freq, 1); + } + + /** + * Starts the progress output. + * + * @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged + */ + public function start(int $max = null) + { + $this->startTime = time(); + $this->step = 0; + $this->percent = 0.0; + + if (null !== $max) { + $this->setMaxSteps($max); + } + + $this->display(); + } + + /** + * Advances the progress output X steps. + * + * @param int $step Number of steps to advance + */ + public function advance(int $step = 1) + { + $this->setProgress($this->step + $step); + } + + /** + * Sets whether to overwrite the progressbar, false for new line. + */ + public function setOverwrite(bool $overwrite) + { + $this->overwrite = $overwrite; + } + + public function setProgress(int $step) + { + if ($this->max && $step > $this->max) { + $this->max = $step; + } elseif ($step < 0) { + $step = 0; + } + + $prevPeriod = (int) ($this->step / $this->redrawFreq); + $currPeriod = (int) ($step / $this->redrawFreq); + $this->step = $step; + $this->percent = $this->max ? (float) $this->step / $this->max : 0; + if ($prevPeriod !== $currPeriod || $this->max === $step) { + $this->display(); + } + } + + public function setMaxSteps(int $max) + { + $this->format = null; + $this->max = max(0, $max); + $this->stepWidth = $this->max ? Helper::strlen((string) $this->max) : 4; + } + + /** + * Finishes the progress output. + */ + public function finish(): void + { + if (!$this->max) { + $this->max = $this->step; + } + + if ($this->step === $this->max && !$this->overwrite) { + // prevent double 100% output + return; + } + + $this->setProgress($this->max); + } + + /** + * Outputs the current progress string. + */ + public function display(): void + { + if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { + return; + } + + if (null === $this->format) { + $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); + } + + $this->overwrite($this->buildLine()); + } + + /** + * Removes the progress bar from the current line. + * + * This is useful if you wish to write some output + * while a progress bar is running. + * Call display() to show the progress bar again. + */ + public function clear(): void + { + if (!$this->overwrite) { + return; + } + + if (null === $this->format) { + $this->setRealFormat($this->internalFormat ?: $this->determineBestFormat()); + } + + $this->overwrite(''); + } + + private function setRealFormat(string $format) + { + // try to use the _nomax variant if available + if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) { + $this->format = self::getFormatDefinition($format.'_nomax'); + } elseif (null !== self::getFormatDefinition($format)) { + $this->format = self::getFormatDefinition($format); + } else { + $this->format = $format; + } + + $this->formatLineCount = substr_count($this->format, "\n"); + } + + /** + * Overwrites a previous message to the output. + */ + private function overwrite(string $message): void + { + if ($this->overwrite) { + if (!$this->firstRun) { + if ($this->output instanceof ConsoleSectionOutput) { + $lines = floor(Helper::strlen($message) / $this->terminal->getWidth()) + $this->formatLineCount + 1; + $this->output->clear($lines); + } else { + // Move the cursor to the beginning of the line + $this->output->write("\x0D"); + + // Erase the line + $this->output->write("\x1B[2K"); + + // Erase previous lines + if ($this->formatLineCount > 0) { + $this->output->write(str_repeat("\x1B[1A\x1B[2K", $this->formatLineCount)); + } + } + } + } elseif ($this->step > 0) { + $this->output->writeln(''); + } + + $this->firstRun = false; + + $this->output->write($message); + } + + private function determineBestFormat(): string + { + switch ($this->output->getVerbosity()) { + // OutputInterface::VERBOSITY_QUIET: display is disabled anyway + case OutputInterface::VERBOSITY_VERBOSE: + return $this->max ? 'verbose' : 'verbose_nomax'; + case OutputInterface::VERBOSITY_VERY_VERBOSE: + return $this->max ? 'very_verbose' : 'very_verbose_nomax'; + case OutputInterface::VERBOSITY_DEBUG: + return $this->max ? 'debug' : 'debug_nomax'; + default: + return $this->max ? 'normal' : 'normal_nomax'; + } + } + + private static function initPlaceholderFormatters(): array + { + return [ + 'bar' => function (self $bar, OutputInterface $output) { + $completeBars = floor($bar->getMaxSteps() > 0 ? $bar->getProgressPercent() * $bar->getBarWidth() : $bar->getProgress() % $bar->getBarWidth()); + $display = str_repeat($bar->getBarCharacter(), $completeBars); + if ($completeBars < $bar->getBarWidth()) { + $emptyBars = $bar->getBarWidth() - $completeBars - Helper::strlenWithoutDecoration($output->getFormatter(), $bar->getProgressCharacter()); + $display .= $bar->getProgressCharacter().str_repeat($bar->getEmptyBarCharacter(), $emptyBars); + } + + return $display; + }, + 'elapsed' => function (self $bar) { + return Helper::formatTime(time() - $bar->getStartTime()); + }, + 'remaining' => function (self $bar) { + if (!$bar->getMaxSteps()) { + throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.'); + } + + if (!$bar->getProgress()) { + $remaining = 0; + } else { + $remaining = round((time() - $bar->getStartTime()) / $bar->getProgress() * ($bar->getMaxSteps() - $bar->getProgress())); + } + + return Helper::formatTime($remaining); + }, + 'estimated' => function (self $bar) { + if (!$bar->getMaxSteps()) { + throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.'); + } + + if (!$bar->getProgress()) { + $estimated = 0; + } else { + $estimated = round((time() - $bar->getStartTime()) / $bar->getProgress() * $bar->getMaxSteps()); + } + + return Helper::formatTime($estimated); + }, + 'memory' => function (self $bar) { + return Helper::formatMemory(memory_get_usage(true)); + }, + 'current' => function (self $bar) { + return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', STR_PAD_LEFT); + }, + 'max' => function (self $bar) { + return $bar->getMaxSteps(); + }, + 'percent' => function (self $bar) { + return floor($bar->getProgressPercent() * 100); + }, + ]; + } + + private static function initFormats(): array + { + return [ + 'normal' => ' %current%/%max% [%bar%] %percent:3s%%', + 'normal_nomax' => ' %current% [%bar%]', + + 'verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%', + 'verbose_nomax' => ' %current% [%bar%] %elapsed:6s%', + + 'very_verbose' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s%', + 'very_verbose_nomax' => ' %current% [%bar%] %elapsed:6s%', + + 'debug' => ' %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%/%estimated:-6s% %memory:6s%', + 'debug_nomax' => ' %current% [%bar%] %elapsed:6s% %memory:6s%', + ]; + } + + private function buildLine(): string + { + $regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i"; + $callback = function ($matches) { + if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) { + $text = $formatter($this, $this->output); + } elseif (isset($this->messages[$matches[1]])) { + $text = $this->messages[$matches[1]]; + } else { + return $matches[0]; + } + + if (isset($matches[2])) { + $text = sprintf('%'.$matches[2], $text); + } + + return $text; + }; + $line = preg_replace_callback($regex, $callback, $this->format); + + // gets string length for each sub line with multiline format + $linesLength = array_map(function ($subLine) { + return Helper::strlenWithoutDecoration($this->output->getFormatter(), rtrim($subLine, "\r")); + }, explode("\n", $line)); + + $linesWidth = max($linesLength); + + $terminalWidth = $this->terminal->getWidth(); + if ($linesWidth <= $terminalWidth) { + return $line; + } + + $this->setBarWidth($this->barWidth - $linesWidth + $terminalWidth); + + return preg_replace_callback($regex, $callback, $this->format); + } +} diff --git a/vendor/symfony/console/Helper/ProgressIndicator.php b/vendor/symfony/console/Helper/ProgressIndicator.php new file mode 100644 index 00000000..301be27e --- /dev/null +++ b/vendor/symfony/console/Helper/ProgressIndicator.php @@ -0,0 +1,269 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\LogicException; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * @author Kevin Bond + */ +class ProgressIndicator +{ + private $output; + private $startTime; + private $format; + private $message; + private $indicatorValues; + private $indicatorCurrent; + private $indicatorChangeInterval; + private $indicatorUpdateTime; + private $started = false; + + private static $formatters; + private static $formats; + + /** + * @param OutputInterface $output + * @param string|null $format Indicator format + * @param int $indicatorChangeInterval Change interval in milliseconds + * @param array|null $indicatorValues Animated indicator characters + */ + public function __construct(OutputInterface $output, string $format = null, int $indicatorChangeInterval = 100, array $indicatorValues = null) + { + $this->output = $output; + + if (null === $format) { + $format = $this->determineBestFormat(); + } + + if (null === $indicatorValues) { + $indicatorValues = ['-', '\\', '|', '/']; + } + + $indicatorValues = array_values($indicatorValues); + + if (2 > \count($indicatorValues)) { + throw new InvalidArgumentException('Must have at least 2 indicator value characters.'); + } + + $this->format = self::getFormatDefinition($format); + $this->indicatorChangeInterval = $indicatorChangeInterval; + $this->indicatorValues = $indicatorValues; + $this->startTime = time(); + } + + /** + * Sets the current indicator message. + * + * @param string|null $message + */ + public function setMessage($message) + { + $this->message = $message; + + $this->display(); + } + + /** + * Starts the indicator output. + * + * @param $message + */ + public function start($message) + { + if ($this->started) { + throw new LogicException('Progress indicator already started.'); + } + + $this->message = $message; + $this->started = true; + $this->startTime = time(); + $this->indicatorUpdateTime = $this->getCurrentTimeInMilliseconds() + $this->indicatorChangeInterval; + $this->indicatorCurrent = 0; + + $this->display(); + } + + /** + * Advances the indicator. + */ + public function advance() + { + if (!$this->started) { + throw new LogicException('Progress indicator has not yet been started.'); + } + + if (!$this->output->isDecorated()) { + return; + } + + $currentTime = $this->getCurrentTimeInMilliseconds(); + + if ($currentTime < $this->indicatorUpdateTime) { + return; + } + + $this->indicatorUpdateTime = $currentTime + $this->indicatorChangeInterval; + ++$this->indicatorCurrent; + + $this->display(); + } + + /** + * Finish the indicator with message. + * + * @param $message + */ + public function finish($message) + { + if (!$this->started) { + throw new LogicException('Progress indicator has not yet been started.'); + } + + $this->message = $message; + $this->display(); + $this->output->writeln(''); + $this->started = false; + } + + /** + * Gets the format for a given name. + * + * @param string $name The format name + * + * @return string|null A format string + */ + public static function getFormatDefinition($name) + { + if (!self::$formats) { + self::$formats = self::initFormats(); + } + + return isset(self::$formats[$name]) ? self::$formats[$name] : null; + } + + /** + * Sets a placeholder formatter for a given name. + * + * This method also allow you to override an existing placeholder. + * + * @param string $name The placeholder name (including the delimiter char like %) + * @param callable $callable A PHP callable + */ + public static function setPlaceholderFormatterDefinition($name, $callable) + { + if (!self::$formatters) { + self::$formatters = self::initPlaceholderFormatters(); + } + + self::$formatters[$name] = $callable; + } + + /** + * Gets the placeholder formatter for a given name. + * + * @param string $name The placeholder name (including the delimiter char like %) + * + * @return callable|null A PHP callable + */ + public static function getPlaceholderFormatterDefinition($name) + { + if (!self::$formatters) { + self::$formatters = self::initPlaceholderFormatters(); + } + + return isset(self::$formatters[$name]) ? self::$formatters[$name] : null; + } + + private function display() + { + if (OutputInterface::VERBOSITY_QUIET === $this->output->getVerbosity()) { + return; + } + + $self = $this; + + $this->overwrite(preg_replace_callback("{%([a-z\-_]+)(?:\:([^%]+))?%}i", function ($matches) use ($self) { + if ($formatter = $self::getPlaceholderFormatterDefinition($matches[1])) { + return $formatter($self); + } + + return $matches[0]; + }, $this->format)); + } + + private function determineBestFormat() + { + switch ($this->output->getVerbosity()) { + // OutputInterface::VERBOSITY_QUIET: display is disabled anyway + case OutputInterface::VERBOSITY_VERBOSE: + return $this->output->isDecorated() ? 'verbose' : 'verbose_no_ansi'; + case OutputInterface::VERBOSITY_VERY_VERBOSE: + case OutputInterface::VERBOSITY_DEBUG: + return $this->output->isDecorated() ? 'very_verbose' : 'very_verbose_no_ansi'; + default: + return $this->output->isDecorated() ? 'normal' : 'normal_no_ansi'; + } + } + + /** + * Overwrites a previous message to the output. + */ + private function overwrite(string $message) + { + if ($this->output->isDecorated()) { + $this->output->write("\x0D\x1B[2K"); + $this->output->write($message); + } else { + $this->output->writeln($message); + } + } + + private function getCurrentTimeInMilliseconds() + { + return round(microtime(true) * 1000); + } + + private static function initPlaceholderFormatters() + { + return [ + 'indicator' => function (self $indicator) { + return $indicator->indicatorValues[$indicator->indicatorCurrent % \count($indicator->indicatorValues)]; + }, + 'message' => function (self $indicator) { + return $indicator->message; + }, + 'elapsed' => function (self $indicator) { + return Helper::formatTime(time() - $indicator->startTime); + }, + 'memory' => function () { + return Helper::formatMemory(memory_get_usage(true)); + }, + ]; + } + + private static function initFormats() + { + return [ + 'normal' => ' %indicator% %message%', + 'normal_no_ansi' => ' %message%', + + 'verbose' => ' %indicator% %message% (%elapsed:6s%)', + 'verbose_no_ansi' => ' %message% (%elapsed:6s%)', + + 'very_verbose' => ' %indicator% %message% (%elapsed:6s%, %memory:6s%)', + 'very_verbose_no_ansi' => ' %message% (%elapsed:6s%, %memory:6s%)', + ]; + } +} diff --git a/vendor/symfony/console/Helper/QuestionHelper.php b/vendor/symfony/console/Helper/QuestionHelper.php new file mode 100644 index 00000000..575c5345 --- /dev/null +++ b/vendor/symfony/console/Helper/QuestionHelper.php @@ -0,0 +1,434 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Exception\RuntimeException; +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Formatter\OutputFormatterStyle; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\StreamableInputInterface; +use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\ConsoleSectionOutput; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ChoiceQuestion; +use Symfony\Component\Console\Question\Question; + +/** + * The QuestionHelper class provides helpers to interact with the user. + * + * @author Fabien Potencier + */ +class QuestionHelper extends Helper +{ + private $inputStream; + private static $shell; + private static $stty; + + /** + * Asks a question to the user. + * + * @return mixed The user answer + * + * @throws RuntimeException If there is no data to read in the input stream + */ + public function ask(InputInterface $input, OutputInterface $output, Question $question) + { + if ($output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + + if (!$input->isInteractive()) { + $default = $question->getDefault(); + + if (null !== $default && $question instanceof ChoiceQuestion) { + $choices = $question->getChoices(); + + if (!$question->isMultiselect()) { + return isset($choices[$default]) ? $choices[$default] : $default; + } + + $default = explode(',', $default); + foreach ($default as $k => $v) { + $v = trim($v); + $default[$k] = isset($choices[$v]) ? $choices[$v] : $v; + } + } + + return $default; + } + + if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) { + $this->inputStream = $stream; + } + + if (!$question->getValidator()) { + return $this->doAsk($output, $question); + } + + $interviewer = function () use ($output, $question) { + return $this->doAsk($output, $question); + }; + + return $this->validateAttempts($interviewer, $output, $question); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'question'; + } + + /** + * Prevents usage of stty. + */ + public static function disableStty() + { + self::$stty = false; + } + + /** + * Asks the question to the user. + * + * @return bool|mixed|string|null + * + * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden + */ + private function doAsk(OutputInterface $output, Question $question) + { + $this->writePrompt($output, $question); + + $inputStream = $this->inputStream ?: STDIN; + $autocomplete = $question->getAutocompleterValues(); + + if (null === $autocomplete || !$this->hasSttyAvailable()) { + $ret = false; + if ($question->isHidden()) { + try { + $ret = trim($this->getHiddenResponse($output, $inputStream)); + } catch (RuntimeException $e) { + if (!$question->isHiddenFallback()) { + throw $e; + } + } + } + + if (false === $ret) { + $ret = fgets($inputStream, 4096); + if (false === $ret) { + throw new RuntimeException('Aborted'); + } + $ret = trim($ret); + } + } else { + $ret = trim($this->autocomplete($output, $question, $inputStream, \is_array($autocomplete) ? $autocomplete : iterator_to_array($autocomplete, false))); + } + + if ($output instanceof ConsoleSectionOutput) { + $output->addContent($ret); + } + + $ret = \strlen($ret) > 0 ? $ret : $question->getDefault(); + + if ($normalizer = $question->getNormalizer()) { + return $normalizer($ret); + } + + return $ret; + } + + /** + * Outputs the question prompt. + */ + protected function writePrompt(OutputInterface $output, Question $question) + { + $message = $question->getQuestion(); + + if ($question instanceof ChoiceQuestion) { + $maxWidth = max(array_map([$this, 'strlen'], array_keys($question->getChoices()))); + + $messages = (array) $question->getQuestion(); + foreach ($question->getChoices() as $key => $value) { + $width = $maxWidth - $this->strlen($key); + $messages[] = ' ['.$key.str_repeat(' ', $width).'] '.$value; + } + + $output->writeln($messages); + + $message = $question->getPrompt(); + } + + $output->write($message); + } + + /** + * Outputs an error message. + */ + protected function writeError(OutputInterface $output, \Exception $error) + { + if (null !== $this->getHelperSet() && $this->getHelperSet()->has('formatter')) { + $message = $this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error'); + } else { + $message = ''.$error->getMessage().''; + } + + $output->writeln($message); + } + + /** + * Autocompletes a question. + * + * @param OutputInterface $output + * @param Question $question + * @param resource $inputStream + */ + private function autocomplete(OutputInterface $output, Question $question, $inputStream, array $autocomplete): string + { + $ret = ''; + + $i = 0; + $ofs = -1; + $matches = $autocomplete; + $numMatches = \count($matches); + + $sttyMode = shell_exec('stty -g'); + + // Disable icanon (so we can fread each keypress) and echo (we'll do echoing here instead) + shell_exec('stty -icanon -echo'); + + // Add highlighted text style + $output->getFormatter()->setStyle('hl', new OutputFormatterStyle('black', 'white')); + + // Read a keypress + while (!feof($inputStream)) { + $c = fread($inputStream, 1); + + // Backspace Character + if ("\177" === $c) { + if (0 === $numMatches && 0 !== $i) { + --$i; + // Move cursor backwards + $output->write("\033[1D"); + } + + if (0 === $i) { + $ofs = -1; + $matches = $autocomplete; + $numMatches = \count($matches); + } else { + $numMatches = 0; + } + + // Pop the last character off the end of our string + $ret = substr($ret, 0, $i); + } elseif ("\033" === $c) { + // Did we read an escape sequence? + $c .= fread($inputStream, 2); + + // A = Up Arrow. B = Down Arrow + if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) { + if ('A' === $c[2] && -1 === $ofs) { + $ofs = 0; + } + + if (0 === $numMatches) { + continue; + } + + $ofs += ('A' === $c[2]) ? -1 : 1; + $ofs = ($numMatches + $ofs) % $numMatches; + } + } elseif (\ord($c) < 32) { + if ("\t" === $c || "\n" === $c) { + if ($numMatches > 0 && -1 !== $ofs) { + $ret = $matches[$ofs]; + // Echo out remaining chars for current match + $output->write(substr($ret, $i)); + $i = \strlen($ret); + } + + if ("\n" === $c) { + $output->write($c); + break; + } + + $numMatches = 0; + } + + continue; + } else { + $output->write($c); + $ret .= $c; + ++$i; + + $numMatches = 0; + $ofs = 0; + + foreach ($autocomplete as $value) { + // If typed characters match the beginning chunk of value (e.g. [AcmeDe]moBundle) + if (0 === strpos($value, $ret)) { + $matches[$numMatches++] = $value; + } + } + } + + // Erase characters from cursor to end of line + $output->write("\033[K"); + + if ($numMatches > 0 && -1 !== $ofs) { + // Save cursor position + $output->write("\0337"); + // Write highlighted text + $output->write(''.OutputFormatter::escapeTrailingBackslash(substr($matches[$ofs], $i)).''); + // Restore cursor position + $output->write("\0338"); + } + } + + // Reset stty so it behaves normally again + shell_exec(sprintf('stty %s', $sttyMode)); + + return $ret; + } + + /** + * Gets a hidden response from user. + * + * @param OutputInterface $output An Output instance + * @param resource $inputStream The handler resource + * + * @throws RuntimeException In case the fallback is deactivated and the response cannot be hidden + */ + private function getHiddenResponse(OutputInterface $output, $inputStream): string + { + if ('\\' === \DIRECTORY_SEPARATOR) { + $exe = __DIR__.'/../Resources/bin/hiddeninput.exe'; + + // handle code running from a phar + if ('phar:' === substr(__FILE__, 0, 5)) { + $tmpExe = sys_get_temp_dir().'/hiddeninput.exe'; + copy($exe, $tmpExe); + $exe = $tmpExe; + } + + $value = rtrim(shell_exec($exe)); + $output->writeln(''); + + if (isset($tmpExe)) { + unlink($tmpExe); + } + + return $value; + } + + if ($this->hasSttyAvailable()) { + $sttyMode = shell_exec('stty -g'); + + shell_exec('stty -echo'); + $value = fgets($inputStream, 4096); + shell_exec(sprintf('stty %s', $sttyMode)); + + if (false === $value) { + throw new RuntimeException('Aborted'); + } + + $value = trim($value); + $output->writeln(''); + + return $value; + } + + if (false !== $shell = $this->getShell()) { + $readCmd = 'csh' === $shell ? 'set mypassword = $<' : 'read -r mypassword'; + $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd); + $value = rtrim(shell_exec($command)); + $output->writeln(''); + + return $value; + } + + throw new RuntimeException('Unable to hide the response.'); + } + + /** + * Validates an attempt. + * + * @param callable $interviewer A callable that will ask for a question and return the result + * @param OutputInterface $output An Output instance + * @param Question $question A Question instance + * + * @return mixed The validated response + * + * @throws \Exception In case the max number of attempts has been reached and no valid response has been given + */ + private function validateAttempts(callable $interviewer, OutputInterface $output, Question $question) + { + $error = null; + $attempts = $question->getMaxAttempts(); + while (null === $attempts || $attempts--) { + if (null !== $error) { + $this->writeError($output, $error); + } + + try { + return $question->getValidator()($interviewer()); + } catch (RuntimeException $e) { + throw $e; + } catch (\Exception $error) { + } + } + + throw $error; + } + + /** + * Returns a valid unix shell. + * + * @return string|bool The valid shell name, false in case no valid shell is found + */ + private function getShell() + { + if (null !== self::$shell) { + return self::$shell; + } + + self::$shell = false; + + if (file_exists('/usr/bin/env')) { + // handle other OSs with bash/zsh/ksh/csh if available to hide the answer + $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null"; + foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) { + if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) { + self::$shell = $sh; + break; + } + } + } + + return self::$shell; + } + + /** + * Returns whether Stty is available or not. + */ + private function hasSttyAvailable(): bool + { + if (null !== self::$stty) { + return self::$stty; + } + + exec('stty 2>&1', $output, $exitcode); + + return self::$stty = 0 === $exitcode; + } +} diff --git a/vendor/symfony/console/Helper/SymfonyQuestionHelper.php b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php new file mode 100644 index 00000000..260c03e2 --- /dev/null +++ b/vendor/symfony/console/Helper/SymfonyQuestionHelper.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ChoiceQuestion; +use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Style\SymfonyStyle; + +/** + * Symfony Style Guide compliant question helper. + * + * @author Kevin Bond + */ +class SymfonyQuestionHelper extends QuestionHelper +{ + /** + * {@inheritdoc} + */ + protected function writePrompt(OutputInterface $output, Question $question) + { + $text = OutputFormatter::escapeTrailingBackslash($question->getQuestion()); + $default = $question->getDefault(); + + switch (true) { + case null === $default: + $text = sprintf(' %s:', $text); + + break; + + case $question instanceof ConfirmationQuestion: + $text = sprintf(' %s (yes/no) [%s]:', $text, $default ? 'yes' : 'no'); + + break; + + case $question instanceof ChoiceQuestion && $question->isMultiselect(): + $choices = $question->getChoices(); + $default = explode(',', $default); + + foreach ($default as $key => $value) { + $default[$key] = $choices[trim($value)]; + } + + $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape(implode(', ', $default))); + + break; + + case $question instanceof ChoiceQuestion: + $choices = $question->getChoices(); + $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape(isset($choices[$default]) ? $choices[$default] : $default)); + + break; + + default: + $text = sprintf(' %s [%s]:', $text, OutputFormatter::escape($default)); + } + + $output->writeln($text); + + if ($question instanceof ChoiceQuestion) { + $width = max(array_map('strlen', array_keys($question->getChoices()))); + + foreach ($question->getChoices() as $key => $value) { + $output->writeln(sprintf(" [%-${width}s] %s", $key, $value)); + } + } + + $output->write(' > '); + } + + /** + * {@inheritdoc} + */ + protected function writeError(OutputInterface $output, \Exception $error) + { + if ($output instanceof SymfonyStyle) { + $output->newLine(); + $output->error($error->getMessage()); + + return; + } + + parent::writeError($output, $error); + } +} diff --git a/vendor/symfony/console/Helper/Table.php b/vendor/symfony/console/Helper/Table.php new file mode 100644 index 00000000..99aa83d4 --- /dev/null +++ b/vendor/symfony/console/Helper/Table.php @@ -0,0 +1,808 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\RuntimeException; +use Symfony\Component\Console\Formatter\WrappableOutputFormatterInterface; +use Symfony\Component\Console\Output\ConsoleSectionOutput; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Provides helpers to display a table. + * + * @author Fabien Potencier + * @author Саша Стаменковић + * @author Abdellatif Ait boudad + * @author Max Grigorian + * @author Dany Maillard + */ +class Table +{ + private const SEPARATOR_TOP = 0; + private const SEPARATOR_TOP_BOTTOM = 1; + private const SEPARATOR_MID = 2; + private const SEPARATOR_BOTTOM = 3; + private const BORDER_OUTSIDE = 0; + private const BORDER_INSIDE = 1; + + private $headerTitle; + private $footerTitle; + + /** + * Table headers. + */ + private $headers = []; + + /** + * Table rows. + */ + private $rows = []; + + /** + * Column widths cache. + */ + private $effectiveColumnWidths = []; + + /** + * Number of columns cache. + * + * @var int + */ + private $numberOfColumns; + + /** + * @var OutputInterface + */ + private $output; + + /** + * @var TableStyle + */ + private $style; + + /** + * @var array + */ + private $columnStyles = []; + + /** + * User set column widths. + * + * @var array + */ + private $columnWidths = []; + private $columnMaxWidths = []; + + private static $styles; + + private $rendered = false; + + public function __construct(OutputInterface $output) + { + $this->output = $output; + + if (!self::$styles) { + self::$styles = self::initStyles(); + } + + $this->setStyle('default'); + } + + /** + * Sets a style definition. + * + * @param string $name The style name + * @param TableStyle $style A TableStyle instance + */ + public static function setStyleDefinition($name, TableStyle $style) + { + if (!self::$styles) { + self::$styles = self::initStyles(); + } + + self::$styles[$name] = $style; + } + + /** + * Gets a style definition by name. + * + * @param string $name The style name + * + * @return TableStyle + */ + public static function getStyleDefinition($name) + { + if (!self::$styles) { + self::$styles = self::initStyles(); + } + + if (isset(self::$styles[$name])) { + return self::$styles[$name]; + } + + throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name)); + } + + /** + * Sets table style. + * + * @param TableStyle|string $name The style name or a TableStyle instance + * + * @return $this + */ + public function setStyle($name) + { + $this->style = $this->resolveStyle($name); + + return $this; + } + + /** + * Gets the current table style. + * + * @return TableStyle + */ + public function getStyle() + { + return $this->style; + } + + /** + * Sets table column style. + * + * @param int $columnIndex Column index + * @param TableStyle|string $name The style name or a TableStyle instance + * + * @return $this + */ + public function setColumnStyle($columnIndex, $name) + { + $columnIndex = (int) $columnIndex; + + $this->columnStyles[$columnIndex] = $this->resolveStyle($name); + + return $this; + } + + /** + * Gets the current style for a column. + * + * If style was not set, it returns the global table style. + * + * @param int $columnIndex Column index + * + * @return TableStyle + */ + public function getColumnStyle($columnIndex) + { + return $this->columnStyles[$columnIndex] ?? $this->getStyle(); + } + + /** + * Sets the minimum width of a column. + * + * @param int $columnIndex Column index + * @param int $width Minimum column width in characters + * + * @return $this + */ + public function setColumnWidth($columnIndex, $width) + { + $this->columnWidths[(int) $columnIndex] = (int) $width; + + return $this; + } + + /** + * Sets the minimum width of all columns. + * + * @param array $widths + * + * @return $this + */ + public function setColumnWidths(array $widths) + { + $this->columnWidths = []; + foreach ($widths as $index => $width) { + $this->setColumnWidth($index, $width); + } + + return $this; + } + + /** + * Sets the maximum width of a column. + * + * Any cell within this column which contents exceeds the specified width will be wrapped into multiple lines, while + * formatted strings are preserved. + * + * @return $this + */ + public function setColumnMaxWidth(int $columnIndex, int $width): self + { + if (!$this->output->getFormatter() instanceof WrappableOutputFormatterInterface) { + throw new \LogicException(sprintf('Setting a maximum column width is only supported when using a "%s" formatter, got "%s".', WrappableOutputFormatterInterface::class, \get_class($this->output->getFormatter()))); + } + + $this->columnMaxWidths[$columnIndex] = $width; + + return $this; + } + + public function setHeaders(array $headers) + { + $headers = array_values($headers); + if (!empty($headers) && !\is_array($headers[0])) { + $headers = [$headers]; + } + + $this->headers = $headers; + + return $this; + } + + public function setRows(array $rows) + { + $this->rows = []; + + return $this->addRows($rows); + } + + public function addRows(array $rows) + { + foreach ($rows as $row) { + $this->addRow($row); + } + + return $this; + } + + public function addRow($row) + { + if ($row instanceof TableSeparator) { + $this->rows[] = $row; + + return $this; + } + + if (!\is_array($row)) { + throw new InvalidArgumentException('A row must be an array or a TableSeparator instance.'); + } + + $this->rows[] = array_values($row); + + return $this; + } + + /** + * Adds a row to the table, and re-renders the table. + */ + public function appendRow($row): self + { + if (!$this->output instanceof ConsoleSectionOutput) { + throw new RuntimeException(sprintf('Output should be an instance of "%s" when calling "%s".', ConsoleSectionOutput::class, __METHOD__)); + } + + if ($this->rendered) { + $this->output->clear($this->calculateRowCount()); + } + + $this->addRow($row); + $this->render(); + + return $this; + } + + public function setRow($column, array $row) + { + $this->rows[$column] = $row; + + return $this; + } + + public function setHeaderTitle(?string $title): self + { + $this->headerTitle = $title; + + return $this; + } + + public function setFooterTitle(?string $title): self + { + $this->footerTitle = $title; + + return $this; + } + + /** + * Renders table to output. + * + * Example: + * + * +---------------+-----------------------+------------------+ + * | ISBN | Title | Author | + * +---------------+-----------------------+------------------+ + * | 99921-58-10-7 | Divine Comedy | Dante Alighieri | + * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | + * | 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien | + * +---------------+-----------------------+------------------+ + */ + public function render() + { + $rows = array_merge($this->headers, [$divider = new TableSeparator()], $this->rows); + $this->calculateNumberOfColumns($rows); + + $rows = $this->buildTableRows($rows); + $this->calculateColumnsWidth($rows); + + $isHeader = true; + $isFirstRow = false; + foreach ($rows as $row) { + if ($divider === $row) { + $isHeader = false; + $isFirstRow = true; + + continue; + } + if ($row instanceof TableSeparator) { + $this->renderRowSeparator(); + + continue; + } + if (!$row) { + continue; + } + + if ($isHeader || $isFirstRow) { + if ($isFirstRow) { + $this->renderRowSeparator(self::SEPARATOR_TOP_BOTTOM); + $isFirstRow = false; + } else { + $this->renderRowSeparator(self::SEPARATOR_TOP, $this->headerTitle, $this->style->getHeaderTitleFormat()); + } + } + + $this->renderRow($row, $isHeader ? $this->style->getCellHeaderFormat() : $this->style->getCellRowFormat()); + } + $this->renderRowSeparator(self::SEPARATOR_BOTTOM, $this->footerTitle, $this->style->getFooterTitleFormat()); + + $this->cleanup(); + $this->rendered = true; + } + + /** + * Renders horizontal header separator. + * + * Example: + * + * +-----+-----------+-------+ + */ + private function renderRowSeparator(int $type = self::SEPARATOR_MID, string $title = null, string $titleFormat = null) + { + if (0 === $count = $this->numberOfColumns) { + return; + } + + $borders = $this->style->getBorderChars(); + if (!$borders[0] && !$borders[2] && !$this->style->getCrossingChar()) { + return; + } + + $crossings = $this->style->getCrossingChars(); + if (self::SEPARATOR_MID === $type) { + list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[2], $crossings[8], $crossings[0], $crossings[4]]; + } elseif (self::SEPARATOR_TOP === $type) { + list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[1], $crossings[2], $crossings[3]]; + } elseif (self::SEPARATOR_TOP_BOTTOM === $type) { + list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[9], $crossings[10], $crossings[11]]; + } else { + list($horizontal, $leftChar, $midChar, $rightChar) = [$borders[0], $crossings[7], $crossings[6], $crossings[5]]; + } + + $markup = $leftChar; + for ($column = 0; $column < $count; ++$column) { + $markup .= str_repeat($horizontal, $this->effectiveColumnWidths[$column]); + $markup .= $column === $count - 1 ? $rightChar : $midChar; + } + + if (null !== $title) { + $titleLength = Helper::strlenWithoutDecoration($formatter = $this->output->getFormatter(), $formattedTitle = sprintf($titleFormat, $title)); + $markupLength = Helper::strlen($markup); + if ($titleLength > $limit = $markupLength - 4) { + $titleLength = $limit; + $formatLength = Helper::strlenWithoutDecoration($formatter, sprintf($titleFormat, '')); + $formattedTitle = sprintf($titleFormat, Helper::substr($title, 0, $limit - $formatLength - 3).'...'); + } + + $titleStart = ($markupLength - $titleLength) / 2; + if (false === mb_detect_encoding($markup, null, true)) { + $markup = substr_replace($markup, $formattedTitle, $titleStart, $titleLength); + } else { + $markup = mb_substr($markup, 0, $titleStart).$formattedTitle.mb_substr($markup, $titleStart + $titleLength); + } + } + + $this->output->writeln(sprintf($this->style->getBorderFormat(), $markup)); + } + + /** + * Renders vertical column separator. + */ + private function renderColumnSeparator($type = self::BORDER_OUTSIDE) + { + $borders = $this->style->getBorderChars(); + + return sprintf($this->style->getBorderFormat(), self::BORDER_OUTSIDE === $type ? $borders[1] : $borders[3]); + } + + /** + * Renders table row. + * + * Example: + * + * | 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens | + */ + private function renderRow(array $row, string $cellFormat) + { + $rowContent = $this->renderColumnSeparator(self::BORDER_OUTSIDE); + $columns = $this->getRowColumns($row); + $last = \count($columns) - 1; + foreach ($columns as $i => $column) { + $rowContent .= $this->renderCell($row, $column, $cellFormat); + $rowContent .= $this->renderColumnSeparator($last === $i ? self::BORDER_OUTSIDE : self::BORDER_INSIDE); + } + $this->output->writeln($rowContent); + } + + /** + * Renders table cell with padding. + */ + private function renderCell(array $row, int $column, string $cellFormat) + { + $cell = isset($row[$column]) ? $row[$column] : ''; + $width = $this->effectiveColumnWidths[$column]; + if ($cell instanceof TableCell && $cell->getColspan() > 1) { + // add the width of the following columns(numbers of colspan). + foreach (range($column + 1, $column + $cell->getColspan() - 1) as $nextColumn) { + $width += $this->getColumnSeparatorWidth() + $this->effectiveColumnWidths[$nextColumn]; + } + } + + // str_pad won't work properly with multi-byte strings, we need to fix the padding + if (false !== $encoding = mb_detect_encoding($cell, null, true)) { + $width += \strlen($cell) - mb_strwidth($cell, $encoding); + } + + $style = $this->getColumnStyle($column); + + if ($cell instanceof TableSeparator) { + return sprintf($style->getBorderFormat(), str_repeat($style->getBorderChars()[2], $width)); + } + + $width += Helper::strlen($cell) - Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell); + $content = sprintf($style->getCellRowContentFormat(), $cell); + + return sprintf($cellFormat, str_pad($content, $width, $style->getPaddingChar(), $style->getPadType())); + } + + /** + * Calculate number of columns for this table. + */ + private function calculateNumberOfColumns($rows) + { + $columns = [0]; + foreach ($rows as $row) { + if ($row instanceof TableSeparator) { + continue; + } + + $columns[] = $this->getNumberOfColumns($row); + } + + $this->numberOfColumns = max($columns); + } + + private function buildTableRows($rows) + { + /** @var WrappableOutputFormatterInterface $formatter */ + $formatter = $this->output->getFormatter(); + $unmergedRows = []; + for ($rowKey = 0; $rowKey < \count($rows); ++$rowKey) { + $rows = $this->fillNextRows($rows, $rowKey); + + // Remove any new line breaks and replace it with a new line + foreach ($rows[$rowKey] as $column => $cell) { + if (isset($this->columnMaxWidths[$column]) && Helper::strlenWithoutDecoration($formatter, $cell) > $this->columnMaxWidths[$column]) { + $cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column]); + } + if (!strstr($cell, "\n")) { + continue; + } + $lines = explode("\n", str_replace("\n", "\n", $cell)); + foreach ($lines as $lineKey => $line) { + if ($cell instanceof TableCell) { + $line = new TableCell($line, ['colspan' => $cell->getColspan()]); + } + if (0 === $lineKey) { + $rows[$rowKey][$column] = $line; + } else { + $unmergedRows[$rowKey][$lineKey][$column] = $line; + } + } + } + } + + return new TableRows(function () use ($rows, $unmergedRows) { + foreach ($rows as $rowKey => $row) { + yield $this->fillCells($row); + + if (isset($unmergedRows[$rowKey])) { + foreach ($unmergedRows[$rowKey] as $row) { + yield $row; + } + } + } + }); + } + + private function calculateRowCount(): int + { + $numberOfRows = \count(iterator_to_array($this->buildTableRows(array_merge($this->headers, [new TableSeparator()], $this->rows)))); + + if ($this->headers) { + ++$numberOfRows; // Add row for header separator + } + + ++$numberOfRows; // Add row for footer separator + + return $numberOfRows; + } + + /** + * fill rows that contains rowspan > 1. + * + * @throws InvalidArgumentException + */ + private function fillNextRows(array $rows, int $line): array + { + $unmergedRows = []; + foreach ($rows[$line] as $column => $cell) { + if (null !== $cell && !$cell instanceof TableCell && !is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) { + throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing __toString, %s given.', \gettype($cell))); + } + if ($cell instanceof TableCell && $cell->getRowspan() > 1) { + $nbLines = $cell->getRowspan() - 1; + $lines = [$cell]; + if (strstr($cell, "\n")) { + $lines = explode("\n", str_replace("\n", "\n", $cell)); + $nbLines = \count($lines) > $nbLines ? substr_count($cell, "\n") : $nbLines; + + $rows[$line][$column] = new TableCell($lines[0], ['colspan' => $cell->getColspan()]); + unset($lines[0]); + } + + // create a two dimensional array (rowspan x colspan) + $unmergedRows = array_replace_recursive(array_fill($line + 1, $nbLines, []), $unmergedRows); + foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { + $value = isset($lines[$unmergedRowKey - $line]) ? $lines[$unmergedRowKey - $line] : ''; + $unmergedRows[$unmergedRowKey][$column] = new TableCell($value, ['colspan' => $cell->getColspan()]); + if ($nbLines === $unmergedRowKey - $line) { + break; + } + } + } + } + + foreach ($unmergedRows as $unmergedRowKey => $unmergedRow) { + // we need to know if $unmergedRow will be merged or inserted into $rows + if (isset($rows[$unmergedRowKey]) && \is_array($rows[$unmergedRowKey]) && ($this->getNumberOfColumns($rows[$unmergedRowKey]) + $this->getNumberOfColumns($unmergedRows[$unmergedRowKey]) <= $this->numberOfColumns)) { + foreach ($unmergedRow as $cellKey => $cell) { + // insert cell into row at cellKey position + array_splice($rows[$unmergedRowKey], $cellKey, 0, [$cell]); + } + } else { + $row = $this->copyRow($rows, $unmergedRowKey - 1); + foreach ($unmergedRow as $column => $cell) { + if (!empty($cell)) { + $row[$column] = $unmergedRow[$column]; + } + } + array_splice($rows, $unmergedRowKey, 0, [$row]); + } + } + + return $rows; + } + + /** + * fill cells for a row that contains colspan > 1. + */ + private function fillCells($row) + { + $newRow = []; + foreach ($row as $column => $cell) { + $newRow[] = $cell; + if ($cell instanceof TableCell && $cell->getColspan() > 1) { + foreach (range($column + 1, $column + $cell->getColspan() - 1) as $position) { + // insert empty value at column position + $newRow[] = ''; + } + } + } + + return $newRow ?: $row; + } + + private function copyRow(array $rows, int $line): array + { + $row = $rows[$line]; + foreach ($row as $cellKey => $cellValue) { + $row[$cellKey] = ''; + if ($cellValue instanceof TableCell) { + $row[$cellKey] = new TableCell('', ['colspan' => $cellValue->getColspan()]); + } + } + + return $row; + } + + /** + * Gets number of columns by row. + */ + private function getNumberOfColumns(array $row): int + { + $columns = \count($row); + foreach ($row as $column) { + $columns += $column instanceof TableCell ? ($column->getColspan() - 1) : 0; + } + + return $columns; + } + + /** + * Gets list of columns for the given row. + */ + private function getRowColumns(array $row): array + { + $columns = range(0, $this->numberOfColumns - 1); + foreach ($row as $cellKey => $cell) { + if ($cell instanceof TableCell && $cell->getColspan() > 1) { + // exclude grouped columns. + $columns = array_diff($columns, range($cellKey + 1, $cellKey + $cell->getColspan() - 1)); + } + } + + return $columns; + } + + /** + * Calculates columns widths. + */ + private function calculateColumnsWidth(iterable $rows) + { + for ($column = 0; $column < $this->numberOfColumns; ++$column) { + $lengths = []; + foreach ($rows as $row) { + if ($row instanceof TableSeparator) { + continue; + } + + foreach ($row as $i => $cell) { + if ($cell instanceof TableCell) { + $textContent = Helper::removeDecoration($this->output->getFormatter(), $cell); + $textLength = Helper::strlen($textContent); + if ($textLength > 0) { + $contentColumns = str_split($textContent, ceil($textLength / $cell->getColspan())); + foreach ($contentColumns as $position => $content) { + $row[$i + $position] = $content; + } + } + } + } + + $lengths[] = $this->getCellWidth($row, $column); + } + + $this->effectiveColumnWidths[$column] = max($lengths) + Helper::strlen($this->style->getCellRowContentFormat()) - 2; + } + } + + private function getColumnSeparatorWidth(): int + { + return Helper::strlen(sprintf($this->style->getBorderFormat(), $this->style->getBorderChars()[3])); + } + + private function getCellWidth(array $row, int $column): int + { + $cellWidth = 0; + + if (isset($row[$column])) { + $cell = $row[$column]; + $cellWidth = Helper::strlenWithoutDecoration($this->output->getFormatter(), $cell); + } + + $columnWidth = isset($this->columnWidths[$column]) ? $this->columnWidths[$column] : 0; + $cellWidth = max($cellWidth, $columnWidth); + + return isset($this->columnMaxWidths[$column]) ? min($this->columnMaxWidths[$column], $cellWidth) : $cellWidth; + } + + /** + * Called after rendering to cleanup cache data. + */ + private function cleanup() + { + $this->effectiveColumnWidths = []; + $this->numberOfColumns = null; + } + + private static function initStyles() + { + $borderless = new TableStyle(); + $borderless + ->setHorizontalBorderChars('=') + ->setVerticalBorderChars(' ') + ->setDefaultCrossingChar(' ') + ; + + $compact = new TableStyle(); + $compact + ->setHorizontalBorderChars('') + ->setVerticalBorderChars(' ') + ->setDefaultCrossingChar('') + ->setCellRowContentFormat('%s') + ; + + $styleGuide = new TableStyle(); + $styleGuide + ->setHorizontalBorderChars('-') + ->setVerticalBorderChars(' ') + ->setDefaultCrossingChar(' ') + ->setCellHeaderFormat('%s') + ; + + $box = (new TableStyle()) + ->setHorizontalBorderChars('─') + ->setVerticalBorderChars('│') + ->setCrossingChars('┼', '┌', '┬', '┐', '┤', '┘', '┴', '└', '├') + ; + + $boxDouble = (new TableStyle()) + ->setHorizontalBorderChars('═', '─') + ->setVerticalBorderChars('║', '│') + ->setCrossingChars('┼', '╔', '╤', '╗', '╢', '╝', '╧', '╚', '╟', '╠', '╪', '╣') + ; + + return [ + 'default' => new TableStyle(), + 'borderless' => $borderless, + 'compact' => $compact, + 'symfony-style-guide' => $styleGuide, + 'box' => $box, + 'box-double' => $boxDouble, + ]; + } + + private function resolveStyle($name) + { + if ($name instanceof TableStyle) { + return $name; + } + + if (isset(self::$styles[$name])) { + return self::$styles[$name]; + } + + throw new InvalidArgumentException(sprintf('Style "%s" is not defined.', $name)); + } +} diff --git a/vendor/symfony/console/Helper/TableCell.php b/vendor/symfony/console/Helper/TableCell.php new file mode 100644 index 00000000..5b6af4a9 --- /dev/null +++ b/vendor/symfony/console/Helper/TableCell.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Exception\InvalidArgumentException; + +/** + * @author Abdellatif Ait boudad + */ +class TableCell +{ + private $value; + private $options = [ + 'rowspan' => 1, + 'colspan' => 1, + ]; + + public function __construct(string $value = '', array $options = []) + { + $this->value = $value; + + // check option names + if ($diff = array_diff(array_keys($options), array_keys($this->options))) { + throw new InvalidArgumentException(sprintf('The TableCell does not support the following options: \'%s\'.', implode('\', \'', $diff))); + } + + $this->options = array_merge($this->options, $options); + } + + /** + * Returns the cell value. + * + * @return string + */ + public function __toString() + { + return $this->value; + } + + /** + * Gets number of colspan. + * + * @return int + */ + public function getColspan() + { + return (int) $this->options['colspan']; + } + + /** + * Gets number of rowspan. + * + * @return int + */ + public function getRowspan() + { + return (int) $this->options['rowspan']; + } +} diff --git a/vendor/symfony/console/Helper/TableRows.php b/vendor/symfony/console/Helper/TableRows.php new file mode 100644 index 00000000..4809daf1 --- /dev/null +++ b/vendor/symfony/console/Helper/TableRows.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +/** + * @internal + */ +class TableRows implements \IteratorAggregate +{ + private $generator; + + public function __construct(callable $generator) + { + $this->generator = $generator; + } + + public function getIterator() + { + $g = $this->generator; + + return $g(); + } +} diff --git a/vendor/symfony/console/Helper/TableSeparator.php b/vendor/symfony/console/Helper/TableSeparator.php new file mode 100644 index 00000000..e541c531 --- /dev/null +++ b/vendor/symfony/console/Helper/TableSeparator.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +/** + * Marks a row as being a separator. + * + * @author Fabien Potencier + */ +class TableSeparator extends TableCell +{ + public function __construct(array $options = []) + { + parent::__construct('', $options); + } +} diff --git a/vendor/symfony/console/Helper/TableStyle.php b/vendor/symfony/console/Helper/TableStyle.php new file mode 100644 index 00000000..02dd693c --- /dev/null +++ b/vendor/symfony/console/Helper/TableStyle.php @@ -0,0 +1,458 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Helper; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\LogicException; + +/** + * Defines the styles for a Table. + * + * @author Fabien Potencier + * @author Саша Стаменковић + * @author Dany Maillard + */ +class TableStyle +{ + private $paddingChar = ' '; + private $horizontalOutsideBorderChar = '-'; + private $horizontalInsideBorderChar = '-'; + private $verticalOutsideBorderChar = '|'; + private $verticalInsideBorderChar = '|'; + private $crossingChar = '+'; + private $crossingTopRightChar = '+'; + private $crossingTopMidChar = '+'; + private $crossingTopLeftChar = '+'; + private $crossingMidRightChar = '+'; + private $crossingBottomRightChar = '+'; + private $crossingBottomMidChar = '+'; + private $crossingBottomLeftChar = '+'; + private $crossingMidLeftChar = '+'; + private $crossingTopLeftBottomChar = '+'; + private $crossingTopMidBottomChar = '+'; + private $crossingTopRightBottomChar = '+'; + private $headerTitleFormat = ' %s '; + private $footerTitleFormat = ' %s '; + private $cellHeaderFormat = '%s'; + private $cellRowFormat = '%s'; + private $cellRowContentFormat = ' %s '; + private $borderFormat = '%s'; + private $padType = STR_PAD_RIGHT; + + /** + * Sets padding character, used for cell padding. + * + * @param string $paddingChar + * + * @return $this + */ + public function setPaddingChar($paddingChar) + { + if (!$paddingChar) { + throw new LogicException('The padding char must not be empty'); + } + + $this->paddingChar = $paddingChar; + + return $this; + } + + /** + * Gets padding character, used for cell padding. + * + * @return string + */ + public function getPaddingChar() + { + return $this->paddingChar; + } + + /** + * Sets horizontal border characters. + * + * + * ╔═══════════════╤══════════════════════════╤══════════════════╗ + * 1 ISBN 2 Title │ Author ║ + * ╠═══════════════╪══════════════════════════╪══════════════════╣ + * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ + * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ + * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ + * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ + * ╚═══════════════╧══════════════════════════╧══════════════════╝ + * + * + * @param string $outside Outside border char (see #1 of example) + * @param string|null $inside Inside border char (see #2 of example), equals $outside if null + */ + public function setHorizontalBorderChars(string $outside, string $inside = null): self + { + $this->horizontalOutsideBorderChar = $outside; + $this->horizontalInsideBorderChar = $inside ?? $outside; + + return $this; + } + + /** + * Sets horizontal border character. + * + * @param string $horizontalBorderChar + * + * @return $this + * + * @deprecated since Symfony 4.1, use {@link setHorizontalBorderChars()} instead. + */ + public function setHorizontalBorderChar($horizontalBorderChar) + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use setHorizontalBorderChars() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->setHorizontalBorderChars($horizontalBorderChar, $horizontalBorderChar); + } + + /** + * Gets horizontal border character. + * + * @return string + * + * @deprecated since Symfony 4.1, use {@link getBorderChars()} instead. + */ + public function getHorizontalBorderChar() + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use getBorderChars() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->horizontalOutsideBorderChar; + } + + /** + * Sets vertical border characters. + * + * + * ╔═══════════════╤══════════════════════════╤══════════════════╗ + * ║ ISBN │ Title │ Author ║ + * ╠═══════1═══════╪══════════════════════════╪══════════════════╣ + * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ + * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ + * ╟───────2───────┼──────────────────────────┼──────────────────╢ + * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ + * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ + * ╚═══════════════╧══════════════════════════╧══════════════════╝ + * + * + * @param string $outside Outside border char (see #1 of example) + * @param string|null $inside Inside border char (see #2 of example), equals $outside if null + */ + public function setVerticalBorderChars(string $outside, string $inside = null): self + { + $this->verticalOutsideBorderChar = $outside; + $this->verticalInsideBorderChar = $inside ?? $outside; + + return $this; + } + + /** + * Sets vertical border character. + * + * @param string $verticalBorderChar + * + * @return $this + * + * @deprecated since Symfony 4.1, use {@link setVerticalBorderChars()} instead. + */ + public function setVerticalBorderChar($verticalBorderChar) + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use setVerticalBorderChars() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->setVerticalBorderChars($verticalBorderChar, $verticalBorderChar); + } + + /** + * Gets vertical border character. + * + * @return string + * + * @deprecated since Symfony 4.1, use {@link getBorderChars()} instead. + */ + public function getVerticalBorderChar() + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use getBorderChars() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->verticalOutsideBorderChar; + } + + /** + * Gets border characters. + * + * @internal + */ + public function getBorderChars() + { + return [ + $this->horizontalOutsideBorderChar, + $this->verticalOutsideBorderChar, + $this->horizontalInsideBorderChar, + $this->verticalInsideBorderChar, + ]; + } + + /** + * Sets crossing characters. + * + * Example: + * + * 1═══════════════2══════════════════════════2══════════════════3 + * ║ ISBN │ Title │ Author ║ + * 8'══════════════0'═════════════════════════0'═════════════════4' + * ║ 99921-58-10-7 │ Divine Comedy │ Dante Alighieri ║ + * ║ 9971-5-0210-0 │ A Tale of Two Cities │ Charles Dickens ║ + * 8───────────────0──────────────────────────0──────────────────4 + * ║ 960-425-059-0 │ The Lord of the Rings │ J. R. R. Tolkien ║ + * ║ 80-902734-1-6 │ And Then There Were None │ Agatha Christie ║ + * 7═══════════════6══════════════════════════6══════════════════5 + * + * + * @param string $cross Crossing char (see #0 of example) + * @param string $topLeft Top left char (see #1 of example) + * @param string $topMid Top mid char (see #2 of example) + * @param string $topRight Top right char (see #3 of example) + * @param string $midRight Mid right char (see #4 of example) + * @param string $bottomRight Bottom right char (see #5 of example) + * @param string $bottomMid Bottom mid char (see #6 of example) + * @param string $bottomLeft Bottom left char (see #7 of example) + * @param string $midLeft Mid left char (see #8 of example) + * @param string|null $topLeftBottom Top left bottom char (see #8' of example), equals to $midLeft if null + * @param string|null $topMidBottom Top mid bottom char (see #0' of example), equals to $cross if null + * @param string|null $topRightBottom Top right bottom char (see #4' of example), equals to $midRight if null + */ + public function setCrossingChars(string $cross, string $topLeft, string $topMid, string $topRight, string $midRight, string $bottomRight, string $bottomMid, string $bottomLeft, string $midLeft, string $topLeftBottom = null, string $topMidBottom = null, string $topRightBottom = null): self + { + $this->crossingChar = $cross; + $this->crossingTopLeftChar = $topLeft; + $this->crossingTopMidChar = $topMid; + $this->crossingTopRightChar = $topRight; + $this->crossingMidRightChar = $midRight; + $this->crossingBottomRightChar = $bottomRight; + $this->crossingBottomMidChar = $bottomMid; + $this->crossingBottomLeftChar = $bottomLeft; + $this->crossingMidLeftChar = $midLeft; + $this->crossingTopLeftBottomChar = $topLeftBottom ?? $midLeft; + $this->crossingTopMidBottomChar = $topMidBottom ?? $cross; + $this->crossingTopRightBottomChar = $topRightBottom ?? $midRight; + + return $this; + } + + /** + * Sets default crossing character used for each cross. + * + * @see {@link setCrossingChars()} for setting each crossing individually. + */ + public function setDefaultCrossingChar(string $char): self + { + return $this->setCrossingChars($char, $char, $char, $char, $char, $char, $char, $char, $char); + } + + /** + * Sets crossing character. + * + * @param string $crossingChar + * + * @return $this + * + * @deprecated since Symfony 4.1. Use {@link setDefaultCrossingChar()} instead. + */ + public function setCrossingChar($crossingChar) + { + @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1. Use setDefaultCrossingChar() instead.', __METHOD__), E_USER_DEPRECATED); + + return $this->setDefaultCrossingChar($crossingChar); + } + + /** + * Gets crossing character. + * + * @return string + */ + public function getCrossingChar() + { + return $this->crossingChar; + } + + /** + * Gets crossing characters. + * + * @internal + */ + public function getCrossingChars(): array + { + return [ + $this->crossingChar, + $this->crossingTopLeftChar, + $this->crossingTopMidChar, + $this->crossingTopRightChar, + $this->crossingMidRightChar, + $this->crossingBottomRightChar, + $this->crossingBottomMidChar, + $this->crossingBottomLeftChar, + $this->crossingMidLeftChar, + $this->crossingTopLeftBottomChar, + $this->crossingTopMidBottomChar, + $this->crossingTopRightBottomChar, + ]; + } + + /** + * Sets header cell format. + * + * @param string $cellHeaderFormat + * + * @return $this + */ + public function setCellHeaderFormat($cellHeaderFormat) + { + $this->cellHeaderFormat = $cellHeaderFormat; + + return $this; + } + + /** + * Gets header cell format. + * + * @return string + */ + public function getCellHeaderFormat() + { + return $this->cellHeaderFormat; + } + + /** + * Sets row cell format. + * + * @param string $cellRowFormat + * + * @return $this + */ + public function setCellRowFormat($cellRowFormat) + { + $this->cellRowFormat = $cellRowFormat; + + return $this; + } + + /** + * Gets row cell format. + * + * @return string + */ + public function getCellRowFormat() + { + return $this->cellRowFormat; + } + + /** + * Sets row cell content format. + * + * @param string $cellRowContentFormat + * + * @return $this + */ + public function setCellRowContentFormat($cellRowContentFormat) + { + $this->cellRowContentFormat = $cellRowContentFormat; + + return $this; + } + + /** + * Gets row cell content format. + * + * @return string + */ + public function getCellRowContentFormat() + { + return $this->cellRowContentFormat; + } + + /** + * Sets table border format. + * + * @param string $borderFormat + * + * @return $this + */ + public function setBorderFormat($borderFormat) + { + $this->borderFormat = $borderFormat; + + return $this; + } + + /** + * Gets table border format. + * + * @return string + */ + public function getBorderFormat() + { + return $this->borderFormat; + } + + /** + * Sets cell padding type. + * + * @param int $padType STR_PAD_* + * + * @return $this + */ + public function setPadType($padType) + { + if (!\in_array($padType, [STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH], true)) { + throw new InvalidArgumentException('Invalid padding type. Expected one of (STR_PAD_LEFT, STR_PAD_RIGHT, STR_PAD_BOTH).'); + } + + $this->padType = $padType; + + return $this; + } + + /** + * Gets cell padding type. + * + * @return int + */ + public function getPadType() + { + return $this->padType; + } + + public function getHeaderTitleFormat(): string + { + return $this->headerTitleFormat; + } + + public function setHeaderTitleFormat(string $format): self + { + $this->headerTitleFormat = $format; + + return $this; + } + + public function getFooterTitleFormat(): string + { + return $this->footerTitleFormat; + } + + public function setFooterTitleFormat(string $format): self + { + $this->footerTitleFormat = $format; + + return $this; + } +} diff --git a/vendor/symfony/console/Input/ArgvInput.php b/vendor/symfony/console/Input/ArgvInput.php new file mode 100644 index 00000000..85ff6f91 --- /dev/null +++ b/vendor/symfony/console/Input/ArgvInput.php @@ -0,0 +1,346 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +use Symfony\Component\Console\Exception\RuntimeException; + +/** + * ArgvInput represents an input coming from the CLI arguments. + * + * Usage: + * + * $input = new ArgvInput(); + * + * By default, the `$_SERVER['argv']` array is used for the input values. + * + * This can be overridden by explicitly passing the input values in the constructor: + * + * $input = new ArgvInput($_SERVER['argv']); + * + * If you pass it yourself, don't forget that the first element of the array + * is the name of the running application. + * + * When passing an argument to the constructor, be sure that it respects + * the same rules as the argv one. It's almost always better to use the + * `StringInput` when you want to provide your own input. + * + * @author Fabien Potencier + * + * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html + * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02 + */ +class ArgvInput extends Input +{ + private $tokens; + private $parsed; + + /** + * @param array|null $argv An array of parameters from the CLI (in the argv format) + * @param InputDefinition|null $definition A InputDefinition instance + */ + public function __construct(array $argv = null, InputDefinition $definition = null) + { + if (null === $argv) { + $argv = $_SERVER['argv']; + } + + // strip the application name + array_shift($argv); + + $this->tokens = $argv; + + parent::__construct($definition); + } + + protected function setTokens(array $tokens) + { + $this->tokens = $tokens; + } + + /** + * {@inheritdoc} + */ + protected function parse() + { + $parseOptions = true; + $this->parsed = $this->tokens; + while (null !== $token = array_shift($this->parsed)) { + if ($parseOptions && '' == $token) { + $this->parseArgument($token); + } elseif ($parseOptions && '--' == $token) { + $parseOptions = false; + } elseif ($parseOptions && 0 === strpos($token, '--')) { + $this->parseLongOption($token); + } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { + $this->parseShortOption($token); + } else { + $this->parseArgument($token); + } + } + } + + /** + * Parses a short option. + * + * @param string $token The current token + */ + private function parseShortOption($token) + { + $name = substr($token, 1); + + if (\strlen($name) > 1) { + if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) { + // an option with a value (with no space) + $this->addShortOption($name[0], substr($name, 1)); + } else { + $this->parseShortOptionSet($name); + } + } else { + $this->addShortOption($name, null); + } + } + + /** + * Parses a short option set. + * + * @param string $name The current token + * + * @throws RuntimeException When option given doesn't exist + */ + private function parseShortOptionSet($name) + { + $len = \strlen($name); + for ($i = 0; $i < $len; ++$i) { + if (!$this->definition->hasShortcut($name[$i])) { + $encoding = mb_detect_encoding($name, null, true); + throw new RuntimeException(sprintf('The "-%s" option does not exist.', false === $encoding ? $name[$i] : mb_substr($name, $i, 1, $encoding))); + } + + $option = $this->definition->getOptionForShortcut($name[$i]); + if ($option->acceptValue()) { + $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1)); + + break; + } else { + $this->addLongOption($option->getName(), null); + } + } + } + + /** + * Parses a long option. + * + * @param string $token The current token + */ + private function parseLongOption($token) + { + $name = substr($token, 2); + + if (false !== $pos = strpos($name, '=')) { + if (0 === \strlen($value = substr($name, $pos + 1))) { + array_unshift($this->parsed, $value); + } + $this->addLongOption(substr($name, 0, $pos), $value); + } else { + $this->addLongOption($name, null); + } + } + + /** + * Parses an argument. + * + * @param string $token The current token + * + * @throws RuntimeException When too many arguments are given + */ + private function parseArgument($token) + { + $c = \count($this->arguments); + + // if input is expecting another argument, add it + if ($this->definition->hasArgument($c)) { + $arg = $this->definition->getArgument($c); + $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token; + + // if last argument isArray(), append token to last argument + } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) { + $arg = $this->definition->getArgument($c - 1); + $this->arguments[$arg->getName()][] = $token; + + // unexpected argument + } else { + $all = $this->definition->getArguments(); + if (\count($all)) { + throw new RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all)))); + } + + throw new RuntimeException(sprintf('No arguments expected, got "%s".', $token)); + } + } + + /** + * Adds a short option value. + * + * @param string $shortcut The short option key + * @param mixed $value The value for the option + * + * @throws RuntimeException When option given doesn't exist + */ + private function addShortOption($shortcut, $value) + { + if (!$this->definition->hasShortcut($shortcut)) { + throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut)); + } + + $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); + } + + /** + * Adds a long option value. + * + * @param string $name The long option key + * @param mixed $value The value for the option + * + * @throws RuntimeException When option given doesn't exist + */ + private function addLongOption($name, $value) + { + if (!$this->definition->hasOption($name)) { + throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name)); + } + + $option = $this->definition->getOption($name); + + if (null !== $value && !$option->acceptValue()) { + throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name)); + } + + if (\in_array($value, ['', null], true) && $option->acceptValue() && \count($this->parsed)) { + // if option accepts an optional or mandatory argument + // let's see if there is one provided + $next = array_shift($this->parsed); + if ((isset($next[0]) && '-' !== $next[0]) || \in_array($next, ['', null], true)) { + $value = $next; + } else { + array_unshift($this->parsed, $next); + } + } + + if (null === $value) { + if ($option->isValueRequired()) { + throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name)); + } + + if (!$option->isArray() && !$option->isValueOptional()) { + $value = true; + } + } + + if ($option->isArray()) { + $this->options[$name][] = $value; + } else { + $this->options[$name] = $value; + } + } + + /** + * {@inheritdoc} + */ + public function getFirstArgument() + { + foreach ($this->tokens as $token) { + if ($token && '-' === $token[0]) { + continue; + } + + return $token; + } + } + + /** + * {@inheritdoc} + */ + public function hasParameterOption($values, $onlyParams = false) + { + $values = (array) $values; + + foreach ($this->tokens as $token) { + if ($onlyParams && '--' === $token) { + return false; + } + foreach ($values as $value) { + // Options with values: + // For long options, test for '--option=' at beginning + // For short options, test for '-o' at beginning + $leading = 0 === strpos($value, '--') ? $value.'=' : $value; + if ($token === $value || '' !== $leading && 0 === strpos($token, $leading)) { + return true; + } + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getParameterOption($values, $default = false, $onlyParams = false) + { + $values = (array) $values; + $tokens = $this->tokens; + + while (0 < \count($tokens)) { + $token = array_shift($tokens); + if ($onlyParams && '--' === $token) { + return $default; + } + + foreach ($values as $value) { + if ($token === $value) { + return array_shift($tokens); + } + // Options with values: + // For long options, test for '--option=' at beginning + // For short options, test for '-o' at beginning + $leading = 0 === strpos($value, '--') ? $value.'=' : $value; + if ('' !== $leading && 0 === strpos($token, $leading)) { + return substr($token, \strlen($leading)); + } + } + } + + return $default; + } + + /** + * Returns a stringified representation of the args passed to the command. + * + * @return string + */ + public function __toString() + { + $tokens = array_map(function ($token) { + if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) { + return $match[1].$this->escapeToken($match[2]); + } + + if ($token && '-' !== $token[0]) { + return $this->escapeToken($token); + } + + return $token; + }, $this->tokens); + + return implode(' ', $tokens); + } +} diff --git a/vendor/symfony/console/Input/ArrayInput.php b/vendor/symfony/console/Input/ArrayInput.php new file mode 100644 index 00000000..cf09ff45 --- /dev/null +++ b/vendor/symfony/console/Input/ArrayInput.php @@ -0,0 +1,206 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\InvalidOptionException; + +/** + * ArrayInput represents an input provided as an array. + * + * Usage: + * + * $input = new ArrayInput(['name' => 'foo', '--bar' => 'foobar']); + * + * @author Fabien Potencier + */ +class ArrayInput extends Input +{ + private $parameters; + + public function __construct(array $parameters, InputDefinition $definition = null) + { + $this->parameters = $parameters; + + parent::__construct($definition); + } + + /** + * {@inheritdoc} + */ + public function getFirstArgument() + { + foreach ($this->parameters as $key => $value) { + if ($key && '-' === $key[0]) { + continue; + } + + return $value; + } + } + + /** + * {@inheritdoc} + */ + public function hasParameterOption($values, $onlyParams = false) + { + $values = (array) $values; + + foreach ($this->parameters as $k => $v) { + if (!\is_int($k)) { + $v = $k; + } + + if ($onlyParams && '--' === $v) { + return false; + } + + if (\in_array($v, $values)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getParameterOption($values, $default = false, $onlyParams = false) + { + $values = (array) $values; + + foreach ($this->parameters as $k => $v) { + if ($onlyParams && ('--' === $k || (\is_int($k) && '--' === $v))) { + return $default; + } + + if (\is_int($k)) { + if (\in_array($v, $values)) { + return true; + } + } elseif (\in_array($k, $values)) { + return $v; + } + } + + return $default; + } + + /** + * Returns a stringified representation of the args passed to the command. + * + * @return string + */ + public function __toString() + { + $params = []; + foreach ($this->parameters as $param => $val) { + if ($param && '-' === $param[0]) { + if (\is_array($val)) { + foreach ($val as $v) { + $params[] = $param.('' != $v ? '='.$this->escapeToken($v) : ''); + } + } else { + $params[] = $param.('' != $val ? '='.$this->escapeToken($val) : ''); + } + } else { + $params[] = \is_array($val) ? implode(' ', array_map([$this, 'escapeToken'], $val)) : $this->escapeToken($val); + } + } + + return implode(' ', $params); + } + + /** + * {@inheritdoc} + */ + protected function parse() + { + foreach ($this->parameters as $key => $value) { + if ('--' === $key) { + return; + } + if (0 === strpos($key, '--')) { + $this->addLongOption(substr($key, 2), $value); + } elseif ('-' === $key[0]) { + $this->addShortOption(substr($key, 1), $value); + } else { + $this->addArgument($key, $value); + } + } + } + + /** + * Adds a short option value. + * + * @param string $shortcut The short option key + * @param mixed $value The value for the option + * + * @throws InvalidOptionException When option given doesn't exist + */ + private function addShortOption($shortcut, $value) + { + if (!$this->definition->hasShortcut($shortcut)) { + throw new InvalidOptionException(sprintf('The "-%s" option does not exist.', $shortcut)); + } + + $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); + } + + /** + * Adds a long option value. + * + * @param string $name The long option key + * @param mixed $value The value for the option + * + * @throws InvalidOptionException When option given doesn't exist + * @throws InvalidOptionException When a required value is missing + */ + private function addLongOption($name, $value) + { + if (!$this->definition->hasOption($name)) { + throw new InvalidOptionException(sprintf('The "--%s" option does not exist.', $name)); + } + + $option = $this->definition->getOption($name); + + if (null === $value) { + if ($option->isValueRequired()) { + throw new InvalidOptionException(sprintf('The "--%s" option requires a value.', $name)); + } + + if (!$option->isValueOptional()) { + $value = true; + } + } + + $this->options[$name] = $value; + } + + /** + * Adds an argument value. + * + * @param string $name The argument name + * @param mixed $value The value for the argument + * + * @throws InvalidArgumentException When argument given doesn't exist + */ + private function addArgument($name, $value) + { + if (!$this->definition->hasArgument($name)) { + throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); + } + + $this->arguments[$name] = $value; + } +} diff --git a/vendor/symfony/console/Input/Input.php b/vendor/symfony/console/Input/Input.php new file mode 100644 index 00000000..7a16e0ee --- /dev/null +++ b/vendor/symfony/console/Input/Input.php @@ -0,0 +1,203 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\RuntimeException; + +/** + * Input is the base class for all concrete Input classes. + * + * Three concrete classes are provided by default: + * + * * `ArgvInput`: The input comes from the CLI arguments (argv) + * * `StringInput`: The input is provided as a string + * * `ArrayInput`: The input is provided as an array + * + * @author Fabien Potencier + */ +abstract class Input implements InputInterface, StreamableInputInterface +{ + protected $definition; + protected $stream; + protected $options = []; + protected $arguments = []; + protected $interactive = true; + + public function __construct(InputDefinition $definition = null) + { + if (null === $definition) { + $this->definition = new InputDefinition(); + } else { + $this->bind($definition); + $this->validate(); + } + } + + /** + * {@inheritdoc} + */ + public function bind(InputDefinition $definition) + { + $this->arguments = []; + $this->options = []; + $this->definition = $definition; + + $this->parse(); + } + + /** + * Processes command line arguments. + */ + abstract protected function parse(); + + /** + * {@inheritdoc} + */ + public function validate() + { + $definition = $this->definition; + $givenArguments = $this->arguments; + + $missingArguments = array_filter(array_keys($definition->getArguments()), function ($argument) use ($definition, $givenArguments) { + return !array_key_exists($argument, $givenArguments) && $definition->getArgument($argument)->isRequired(); + }); + + if (\count($missingArguments) > 0) { + throw new RuntimeException(sprintf('Not enough arguments (missing: "%s").', implode(', ', $missingArguments))); + } + } + + /** + * {@inheritdoc} + */ + public function isInteractive() + { + return $this->interactive; + } + + /** + * {@inheritdoc} + */ + public function setInteractive($interactive) + { + $this->interactive = (bool) $interactive; + } + + /** + * {@inheritdoc} + */ + public function getArguments() + { + return array_merge($this->definition->getArgumentDefaults(), $this->arguments); + } + + /** + * {@inheritdoc} + */ + public function getArgument($name) + { + if (!$this->definition->hasArgument($name)) { + throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); + } + + return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)->getDefault(); + } + + /** + * {@inheritdoc} + */ + public function setArgument($name, $value) + { + if (!$this->definition->hasArgument($name)) { + throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); + } + + $this->arguments[$name] = $value; + } + + /** + * {@inheritdoc} + */ + public function hasArgument($name) + { + return $this->definition->hasArgument($name); + } + + /** + * {@inheritdoc} + */ + public function getOptions() + { + return array_merge($this->definition->getOptionDefaults(), $this->options); + } + + /** + * {@inheritdoc} + */ + public function getOption($name) + { + if (!$this->definition->hasOption($name)) { + throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); + } + + return array_key_exists($name, $this->options) ? $this->options[$name] : $this->definition->getOption($name)->getDefault(); + } + + /** + * {@inheritdoc} + */ + public function setOption($name, $value) + { + if (!$this->definition->hasOption($name)) { + throw new InvalidArgumentException(sprintf('The "%s" option does not exist.', $name)); + } + + $this->options[$name] = $value; + } + + /** + * {@inheritdoc} + */ + public function hasOption($name) + { + return $this->definition->hasOption($name); + } + + /** + * Escapes a token through escapeshellarg if it contains unsafe chars. + * + * @param string $token + * + * @return string + */ + public function escapeToken($token) + { + return preg_match('{^[\w-]+$}', $token) ? $token : escapeshellarg($token); + } + + /** + * {@inheritdoc} + */ + public function setStream($stream) + { + $this->stream = $stream; + } + + /** + * {@inheritdoc} + */ + public function getStream() + { + return $this->stream; + } +} diff --git a/vendor/symfony/console/Input/InputArgument.php b/vendor/symfony/console/Input/InputArgument.php new file mode 100644 index 00000000..b6aa6452 --- /dev/null +++ b/vendor/symfony/console/Input/InputArgument.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\LogicException; + +/** + * Represents a command line argument. + * + * @author Fabien Potencier + */ +class InputArgument +{ + const REQUIRED = 1; + const OPTIONAL = 2; + const IS_ARRAY = 4; + + private $name; + private $mode; + private $default; + private $description; + + /** + * @param string $name The argument name + * @param int|null $mode The argument mode: self::REQUIRED or self::OPTIONAL + * @param string $description A description text + * @param string|string[]|null $default The default value (for self::OPTIONAL mode only) + * + * @throws InvalidArgumentException When argument mode is not valid + */ + public function __construct(string $name, int $mode = null, string $description = '', $default = null) + { + if (null === $mode) { + $mode = self::OPTIONAL; + } elseif ($mode > 7 || $mode < 1) { + throw new InvalidArgumentException(sprintf('Argument mode "%s" is not valid.', $mode)); + } + + $this->name = $name; + $this->mode = $mode; + $this->description = $description; + + $this->setDefault($default); + } + + /** + * Returns the argument name. + * + * @return string The argument name + */ + public function getName() + { + return $this->name; + } + + /** + * Returns true if the argument is required. + * + * @return bool true if parameter mode is self::REQUIRED, false otherwise + */ + public function isRequired() + { + return self::REQUIRED === (self::REQUIRED & $this->mode); + } + + /** + * Returns true if the argument can take multiple values. + * + * @return bool true if mode is self::IS_ARRAY, false otherwise + */ + public function isArray() + { + return self::IS_ARRAY === (self::IS_ARRAY & $this->mode); + } + + /** + * Sets the default value. + * + * @param string|string[]|null $default The default value + * + * @throws LogicException When incorrect default value is given + */ + public function setDefault($default = null) + { + if (self::REQUIRED === $this->mode && null !== $default) { + throw new LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.'); + } + + if ($this->isArray()) { + if (null === $default) { + $default = []; + } elseif (!\is_array($default)) { + throw new LogicException('A default value for an array argument must be an array.'); + } + } + + $this->default = $default; + } + + /** + * Returns the default value. + * + * @return string|string[]|null The default value + */ + public function getDefault() + { + return $this->default; + } + + /** + * Returns the description text. + * + * @return string The description text + */ + public function getDescription() + { + return $this->description; + } +} diff --git a/vendor/symfony/console/Input/InputAwareInterface.php b/vendor/symfony/console/Input/InputAwareInterface.php new file mode 100644 index 00000000..5a288de5 --- /dev/null +++ b/vendor/symfony/console/Input/InputAwareInterface.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +/** + * InputAwareInterface should be implemented by classes that depends on the + * Console Input. + * + * @author Wouter J + */ +interface InputAwareInterface +{ + /** + * Sets the Console Input. + */ + public function setInput(InputInterface $input); +} diff --git a/vendor/symfony/console/Input/InputDefinition.php b/vendor/symfony/console/Input/InputDefinition.php new file mode 100644 index 00000000..c7e5c987 --- /dev/null +++ b/vendor/symfony/console/Input/InputDefinition.php @@ -0,0 +1,402 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\LogicException; + +/** + * A InputDefinition represents a set of valid command line arguments and options. + * + * Usage: + * + * $definition = new InputDefinition([ + * new InputArgument('name', InputArgument::REQUIRED), + * new InputOption('foo', 'f', InputOption::VALUE_REQUIRED), + * ]); + * + * @author Fabien Potencier + */ +class InputDefinition +{ + private $arguments; + private $requiredCount; + private $hasAnArrayArgument = false; + private $hasOptional; + private $options; + private $shortcuts; + + /** + * @param array $definition An array of InputArgument and InputOption instance + */ + public function __construct(array $definition = []) + { + $this->setDefinition($definition); + } + + /** + * Sets the definition of the input. + */ + public function setDefinition(array $definition) + { + $arguments = []; + $options = []; + foreach ($definition as $item) { + if ($item instanceof InputOption) { + $options[] = $item; + } else { + $arguments[] = $item; + } + } + + $this->setArguments($arguments); + $this->setOptions($options); + } + + /** + * Sets the InputArgument objects. + * + * @param InputArgument[] $arguments An array of InputArgument objects + */ + public function setArguments($arguments = []) + { + $this->arguments = []; + $this->requiredCount = 0; + $this->hasOptional = false; + $this->hasAnArrayArgument = false; + $this->addArguments($arguments); + } + + /** + * Adds an array of InputArgument objects. + * + * @param InputArgument[] $arguments An array of InputArgument objects + */ + public function addArguments($arguments = []) + { + if (null !== $arguments) { + foreach ($arguments as $argument) { + $this->addArgument($argument); + } + } + } + + /** + * @throws LogicException When incorrect argument is given + */ + public function addArgument(InputArgument $argument) + { + if (isset($this->arguments[$argument->getName()])) { + throw new LogicException(sprintf('An argument with name "%s" already exists.', $argument->getName())); + } + + if ($this->hasAnArrayArgument) { + throw new LogicException('Cannot add an argument after an array argument.'); + } + + if ($argument->isRequired() && $this->hasOptional) { + throw new LogicException('Cannot add a required argument after an optional one.'); + } + + if ($argument->isArray()) { + $this->hasAnArrayArgument = true; + } + + if ($argument->isRequired()) { + ++$this->requiredCount; + } else { + $this->hasOptional = true; + } + + $this->arguments[$argument->getName()] = $argument; + } + + /** + * Returns an InputArgument by name or by position. + * + * @param string|int $name The InputArgument name or position + * + * @return InputArgument An InputArgument object + * + * @throws InvalidArgumentException When argument given doesn't exist + */ + public function getArgument($name) + { + if (!$this->hasArgument($name)) { + throw new InvalidArgumentException(sprintf('The "%s" argument does not exist.', $name)); + } + + $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments; + + return $arguments[$name]; + } + + /** + * Returns true if an InputArgument object exists by name or position. + * + * @param string|int $name The InputArgument name or position + * + * @return bool true if the InputArgument object exists, false otherwise + */ + public function hasArgument($name) + { + $arguments = \is_int($name) ? array_values($this->arguments) : $this->arguments; + + return isset($arguments[$name]); + } + + /** + * Gets the array of InputArgument objects. + * + * @return InputArgument[] An array of InputArgument objects + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Returns the number of InputArguments. + * + * @return int The number of InputArguments + */ + public function getArgumentCount() + { + return $this->hasAnArrayArgument ? PHP_INT_MAX : \count($this->arguments); + } + + /** + * Returns the number of required InputArguments. + * + * @return int The number of required InputArguments + */ + public function getArgumentRequiredCount() + { + return $this->requiredCount; + } + + /** + * Gets the default values. + * + * @return array An array of default values + */ + public function getArgumentDefaults() + { + $values = []; + foreach ($this->arguments as $argument) { + $values[$argument->getName()] = $argument->getDefault(); + } + + return $values; + } + + /** + * Sets the InputOption objects. + * + * @param InputOption[] $options An array of InputOption objects + */ + public function setOptions($options = []) + { + $this->options = []; + $this->shortcuts = []; + $this->addOptions($options); + } + + /** + * Adds an array of InputOption objects. + * + * @param InputOption[] $options An array of InputOption objects + */ + public function addOptions($options = []) + { + foreach ($options as $option) { + $this->addOption($option); + } + } + + /** + * @throws LogicException When option given already exist + */ + public function addOption(InputOption $option) + { + if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) { + throw new LogicException(sprintf('An option named "%s" already exists.', $option->getName())); + } + + if ($option->getShortcut()) { + foreach (explode('|', $option->getShortcut()) as $shortcut) { + if (isset($this->shortcuts[$shortcut]) && !$option->equals($this->options[$this->shortcuts[$shortcut]])) { + throw new LogicException(sprintf('An option with shortcut "%s" already exists.', $shortcut)); + } + } + } + + $this->options[$option->getName()] = $option; + if ($option->getShortcut()) { + foreach (explode('|', $option->getShortcut()) as $shortcut) { + $this->shortcuts[$shortcut] = $option->getName(); + } + } + } + + /** + * Returns an InputOption by name. + * + * @param string $name The InputOption name + * + * @return InputOption A InputOption object + * + * @throws InvalidArgumentException When option given doesn't exist + */ + public function getOption($name) + { + if (!$this->hasOption($name)) { + throw new InvalidArgumentException(sprintf('The "--%s" option does not exist.', $name)); + } + + return $this->options[$name]; + } + + /** + * Returns true if an InputOption object exists by name. + * + * This method can't be used to check if the user included the option when + * executing the command (use getOption() instead). + * + * @param string $name The InputOption name + * + * @return bool true if the InputOption object exists, false otherwise + */ + public function hasOption($name) + { + return isset($this->options[$name]); + } + + /** + * Gets the array of InputOption objects. + * + * @return InputOption[] An array of InputOption objects + */ + public function getOptions() + { + return $this->options; + } + + /** + * Returns true if an InputOption object exists by shortcut. + * + * @param string $name The InputOption shortcut + * + * @return bool true if the InputOption object exists, false otherwise + */ + public function hasShortcut($name) + { + return isset($this->shortcuts[$name]); + } + + /** + * Gets an InputOption by shortcut. + * + * @param string $shortcut The Shortcut name + * + * @return InputOption An InputOption object + */ + public function getOptionForShortcut($shortcut) + { + return $this->getOption($this->shortcutToName($shortcut)); + } + + /** + * Gets an array of default values. + * + * @return array An array of all default values + */ + public function getOptionDefaults() + { + $values = []; + foreach ($this->options as $option) { + $values[$option->getName()] = $option->getDefault(); + } + + return $values; + } + + /** + * Returns the InputOption name given a shortcut. + * + * @param string $shortcut The shortcut + * + * @return string The InputOption name + * + * @throws InvalidArgumentException When option given does not exist + */ + private function shortcutToName($shortcut) + { + if (!isset($this->shortcuts[$shortcut])) { + throw new InvalidArgumentException(sprintf('The "-%s" option does not exist.', $shortcut)); + } + + return $this->shortcuts[$shortcut]; + } + + /** + * Gets the synopsis. + * + * @param bool $short Whether to return the short version (with options folded) or not + * + * @return string The synopsis + */ + public function getSynopsis($short = false) + { + $elements = []; + + if ($short && $this->getOptions()) { + $elements[] = '[options]'; + } elseif (!$short) { + foreach ($this->getOptions() as $option) { + $value = ''; + if ($option->acceptValue()) { + $value = sprintf( + ' %s%s%s', + $option->isValueOptional() ? '[' : '', + strtoupper($option->getName()), + $option->isValueOptional() ? ']' : '' + ); + } + + $shortcut = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : ''; + $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value); + } + } + + if (\count($elements) && $this->getArguments()) { + $elements[] = '[--]'; + } + + $tail = ''; + foreach ($this->getArguments() as $argument) { + $element = '<'.$argument->getName().'>'; + if ($argument->isArray()) { + $element .= '...'; + } + + if (!$argument->isRequired()) { + $element = '['.$element; + $tail .= ']'; + } + + $elements[] = $element; + } + + return implode(' ', $elements).$tail; + } +} diff --git a/vendor/symfony/console/Input/InputInterface.php b/vendor/symfony/console/Input/InputInterface.php new file mode 100644 index 00000000..b9bcf3bb --- /dev/null +++ b/vendor/symfony/console/Input/InputInterface.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\RuntimeException; + +/** + * InputInterface is the interface implemented by all input classes. + * + * @author Fabien Potencier + */ +interface InputInterface +{ + /** + * Returns the first argument from the raw parameters (not parsed). + * + * @return string|null The value of the first argument or null otherwise + */ + public function getFirstArgument(); + + /** + * Returns true if the raw parameters (not parsed) contain a value. + * + * This method is to be used to introspect the input parameters + * before they have been validated. It must be used carefully. + * Does not necessarily return the correct result for short options + * when multiple flags are combined in the same option. + * + * @param string|array $values The values to look for in the raw parameters (can be an array) + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal + * + * @return bool true if the value is contained in the raw parameters + */ + public function hasParameterOption($values, $onlyParams = false); + + /** + * Returns the value of a raw option (not parsed). + * + * This method is to be used to introspect the input parameters + * before they have been validated. It must be used carefully. + * Does not necessarily return the correct result for short options + * when multiple flags are combined in the same option. + * + * @param string|array $values The value(s) to look for in the raw parameters (can be an array) + * @param mixed $default The default value to return if no result is found + * @param bool $onlyParams Only check real parameters, skip those following an end of options (--) signal + * + * @return mixed The option value + */ + public function getParameterOption($values, $default = false, $onlyParams = false); + + /** + * Binds the current Input instance with the given arguments and options. + * + * @throws RuntimeException + */ + public function bind(InputDefinition $definition); + + /** + * Validates the input. + * + * @throws RuntimeException When not enough arguments are given + */ + public function validate(); + + /** + * Returns all the given arguments merged with the default values. + * + * @return array + */ + public function getArguments(); + + /** + * Returns the argument value for a given argument name. + * + * @param string $name The argument name + * + * @return string|string[]|null The argument value + * + * @throws InvalidArgumentException When argument given doesn't exist + */ + public function getArgument($name); + + /** + * Sets an argument value by name. + * + * @param string $name The argument name + * @param string|string[]|null $value The argument value + * + * @throws InvalidArgumentException When argument given doesn't exist + */ + public function setArgument($name, $value); + + /** + * Returns true if an InputArgument object exists by name or position. + * + * @param string|int $name The InputArgument name or position + * + * @return bool true if the InputArgument object exists, false otherwise + */ + public function hasArgument($name); + + /** + * Returns all the given options merged with the default values. + * + * @return array + */ + public function getOptions(); + + /** + * Returns the option value for a given option name. + * + * @param string $name The option name + * + * @return string|string[]|bool|null The option value + * + * @throws InvalidArgumentException When option given doesn't exist + */ + public function getOption($name); + + /** + * Sets an option value by name. + * + * @param string $name The option name + * @param string|string[]|bool|null $value The option value + * + * @throws InvalidArgumentException When option given doesn't exist + */ + public function setOption($name, $value); + + /** + * Returns true if an InputOption object exists by name. + * + * @param string $name The InputOption name + * + * @return bool true if the InputOption object exists, false otherwise + */ + public function hasOption($name); + + /** + * Is this input means interactive? + * + * @return bool + */ + public function isInteractive(); + + /** + * Sets the input interactivity. + * + * @param bool $interactive If the input should be interactive + */ + public function setInteractive($interactive); +} diff --git a/vendor/symfony/console/Input/InputOption.php b/vendor/symfony/console/Input/InputOption.php new file mode 100644 index 00000000..d62e0aea --- /dev/null +++ b/vendor/symfony/console/Input/InputOption.php @@ -0,0 +1,208 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\LogicException; + +/** + * Represents a command line option. + * + * @author Fabien Potencier + */ +class InputOption +{ + const VALUE_NONE = 1; + const VALUE_REQUIRED = 2; + const VALUE_OPTIONAL = 4; + const VALUE_IS_ARRAY = 8; + + private $name; + private $shortcut; + private $mode; + private $default; + private $description; + + /** + * @param string $name The option name + * @param string|array|null $shortcut The shortcuts, can be null, a string of shortcuts delimited by | or an array of shortcuts + * @param int|null $mode The option mode: One of the VALUE_* constants + * @param string $description A description text + * @param string|string[]|int|bool|null $default The default value (must be null for self::VALUE_NONE) + * + * @throws InvalidArgumentException If option mode is invalid or incompatible + */ + public function __construct(string $name, $shortcut = null, int $mode = null, string $description = '', $default = null) + { + if (0 === strpos($name, '--')) { + $name = substr($name, 2); + } + + if (empty($name)) { + throw new InvalidArgumentException('An option name cannot be empty.'); + } + + if (empty($shortcut)) { + $shortcut = null; + } + + if (null !== $shortcut) { + if (\is_array($shortcut)) { + $shortcut = implode('|', $shortcut); + } + $shortcuts = preg_split('{(\|)-?}', ltrim($shortcut, '-')); + $shortcuts = array_filter($shortcuts); + $shortcut = implode('|', $shortcuts); + + if (empty($shortcut)) { + throw new InvalidArgumentException('An option shortcut cannot be empty.'); + } + } + + if (null === $mode) { + $mode = self::VALUE_NONE; + } elseif ($mode > 15 || $mode < 1) { + throw new InvalidArgumentException(sprintf('Option mode "%s" is not valid.', $mode)); + } + + $this->name = $name; + $this->shortcut = $shortcut; + $this->mode = $mode; + $this->description = $description; + + if ($this->isArray() && !$this->acceptValue()) { + throw new InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.'); + } + + $this->setDefault($default); + } + + /** + * Returns the option shortcut. + * + * @return string|null The shortcut + */ + public function getShortcut() + { + return $this->shortcut; + } + + /** + * Returns the option name. + * + * @return string The name + */ + public function getName() + { + return $this->name; + } + + /** + * Returns true if the option accepts a value. + * + * @return bool true if value mode is not self::VALUE_NONE, false otherwise + */ + public function acceptValue() + { + return $this->isValueRequired() || $this->isValueOptional(); + } + + /** + * Returns true if the option requires a value. + * + * @return bool true if value mode is self::VALUE_REQUIRED, false otherwise + */ + public function isValueRequired() + { + return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode); + } + + /** + * Returns true if the option takes an optional value. + * + * @return bool true if value mode is self::VALUE_OPTIONAL, false otherwise + */ + public function isValueOptional() + { + return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode); + } + + /** + * Returns true if the option can take multiple values. + * + * @return bool true if mode is self::VALUE_IS_ARRAY, false otherwise + */ + public function isArray() + { + return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode); + } + + /** + * Sets the default value. + * + * @param string|string[]|int|bool|null $default The default value + * + * @throws LogicException When incorrect default value is given + */ + public function setDefault($default = null) + { + if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) { + throw new LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.'); + } + + if ($this->isArray()) { + if (null === $default) { + $default = []; + } elseif (!\is_array($default)) { + throw new LogicException('A default value for an array option must be an array.'); + } + } + + $this->default = $this->acceptValue() ? $default : false; + } + + /** + * Returns the default value. + * + * @return string|string[]|int|bool|null The default value + */ + public function getDefault() + { + return $this->default; + } + + /** + * Returns the description text. + * + * @return string The description text + */ + public function getDescription() + { + return $this->description; + } + + /** + * Checks whether the given option equals this one. + * + * @return bool + */ + public function equals(self $option) + { + return $option->getName() === $this->getName() + && $option->getShortcut() === $this->getShortcut() + && $option->getDefault() === $this->getDefault() + && $option->isArray() === $this->isArray() + && $option->isValueRequired() === $this->isValueRequired() + && $option->isValueOptional() === $this->isValueOptional() + ; + } +} diff --git a/vendor/symfony/console/Input/StreamableInputInterface.php b/vendor/symfony/console/Input/StreamableInputInterface.php new file mode 100644 index 00000000..d7e462f2 --- /dev/null +++ b/vendor/symfony/console/Input/StreamableInputInterface.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +/** + * StreamableInputInterface is the interface implemented by all input classes + * that have an input stream. + * + * @author Robin Chalas + */ +interface StreamableInputInterface extends InputInterface +{ + /** + * Sets the input stream to read from when interacting with the user. + * + * This is mainly useful for testing purpose. + * + * @param resource $stream The input stream + */ + public function setStream($stream); + + /** + * Returns the input stream. + * + * @return resource|null + */ + public function getStream(); +} diff --git a/vendor/symfony/console/Input/StringInput.php b/vendor/symfony/console/Input/StringInput.php new file mode 100644 index 00000000..0c63ed0e --- /dev/null +++ b/vendor/symfony/console/Input/StringInput.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Input; + +use Symfony\Component\Console\Exception\InvalidArgumentException; + +/** + * StringInput represents an input provided as a string. + * + * Usage: + * + * $input = new StringInput('foo --bar="foobar"'); + * + * @author Fabien Potencier + */ +class StringInput extends ArgvInput +{ + const REGEX_STRING = '([^\s]+?)(?:\s|(?setTokens($this->tokenize($input)); + } + + /** + * Tokenizes a string. + * + * @param string $input The input to tokenize + * + * @return array An array of tokens + * + * @throws InvalidArgumentException When unable to parse input (should never happen) + */ + private function tokenize($input) + { + $tokens = []; + $length = \strlen($input); + $cursor = 0; + while ($cursor < $length) { + if (preg_match('/\s+/A', $input, $match, null, $cursor)) { + } elseif (preg_match('/([^="\'\s]+?)(=?)('.self::REGEX_QUOTED_STRING.'+)/A', $input, $match, null, $cursor)) { + $tokens[] = $match[1].$match[2].stripcslashes(str_replace(['"\'', '\'"', '\'\'', '""'], '', substr($match[3], 1, \strlen($match[3]) - 2))); + } elseif (preg_match('/'.self::REGEX_QUOTED_STRING.'/A', $input, $match, null, $cursor)) { + $tokens[] = stripcslashes(substr($match[0], 1, \strlen($match[0]) - 2)); + } elseif (preg_match('/'.self::REGEX_STRING.'/A', $input, $match, null, $cursor)) { + $tokens[] = stripcslashes($match[1]); + } else { + // should never happen + throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10))); + } + + $cursor += \strlen($match[0]); + } + + return $tokens; + } +} diff --git a/vendor/symfony/console/LICENSE b/vendor/symfony/console/LICENSE new file mode 100644 index 00000000..a677f437 --- /dev/null +++ b/vendor/symfony/console/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2004-2019 Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/vendor/symfony/console/Logger/ConsoleLogger.php b/vendor/symfony/console/Logger/ConsoleLogger.php new file mode 100644 index 00000000..36f3b99f --- /dev/null +++ b/vendor/symfony/console/Logger/ConsoleLogger.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Logger; + +use Psr\Log\AbstractLogger; +use Psr\Log\InvalidArgumentException; +use Psr\Log\LogLevel; +use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * PSR-3 compliant console logger. + * + * @author Kévin Dunglas + * + * @see http://www.php-fig.org/psr/psr-3/ + */ +class ConsoleLogger extends AbstractLogger +{ + const INFO = 'info'; + const ERROR = 'error'; + + private $output; + private $verbosityLevelMap = [ + LogLevel::EMERGENCY => OutputInterface::VERBOSITY_NORMAL, + LogLevel::ALERT => OutputInterface::VERBOSITY_NORMAL, + LogLevel::CRITICAL => OutputInterface::VERBOSITY_NORMAL, + LogLevel::ERROR => OutputInterface::VERBOSITY_NORMAL, + LogLevel::WARNING => OutputInterface::VERBOSITY_NORMAL, + LogLevel::NOTICE => OutputInterface::VERBOSITY_VERBOSE, + LogLevel::INFO => OutputInterface::VERBOSITY_VERY_VERBOSE, + LogLevel::DEBUG => OutputInterface::VERBOSITY_DEBUG, + ]; + private $formatLevelMap = [ + LogLevel::EMERGENCY => self::ERROR, + LogLevel::ALERT => self::ERROR, + LogLevel::CRITICAL => self::ERROR, + LogLevel::ERROR => self::ERROR, + LogLevel::WARNING => self::INFO, + LogLevel::NOTICE => self::INFO, + LogLevel::INFO => self::INFO, + LogLevel::DEBUG => self::INFO, + ]; + private $errored = false; + + public function __construct(OutputInterface $output, array $verbosityLevelMap = [], array $formatLevelMap = []) + { + $this->output = $output; + $this->verbosityLevelMap = $verbosityLevelMap + $this->verbosityLevelMap; + $this->formatLevelMap = $formatLevelMap + $this->formatLevelMap; + } + + /** + * {@inheritdoc} + */ + public function log($level, $message, array $context = []) + { + if (!isset($this->verbosityLevelMap[$level])) { + throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level)); + } + + $output = $this->output; + + // Write to the error output if necessary and available + if (self::ERROR === $this->formatLevelMap[$level]) { + if ($this->output instanceof ConsoleOutputInterface) { + $output = $output->getErrorOutput(); + } + $this->errored = true; + } + + // the if condition check isn't necessary -- it's the same one that $output will do internally anyway. + // We only do it for efficiency here as the message formatting is relatively expensive. + if ($output->getVerbosity() >= $this->verbosityLevelMap[$level]) { + $output->writeln(sprintf('<%1$s>[%2$s] %3$s', $this->formatLevelMap[$level], $level, $this->interpolate($message, $context)), $this->verbosityLevelMap[$level]); + } + } + + /** + * Returns true when any messages have been logged at error levels. + * + * @return bool + */ + public function hasErrored() + { + return $this->errored; + } + + /** + * Interpolates context values into the message placeholders. + * + * @author PHP Framework Interoperability Group + */ + private function interpolate(string $message, array $context): string + { + if (false === strpos($message, '{')) { + return $message; + } + + $replacements = []; + foreach ($context as $key => $val) { + if (null === $val || is_scalar($val) || (\is_object($val) && method_exists($val, '__toString'))) { + $replacements["{{$key}}"] = $val; + } elseif ($val instanceof \DateTimeInterface) { + $replacements["{{$key}}"] = $val->format(\DateTime::RFC3339); + } elseif (\is_object($val)) { + $replacements["{{$key}}"] = '[object '.\get_class($val).']'; + } else { + $replacements["{{$key}}"] = '['.\gettype($val).']'; + } + } + + return strtr($message, $replacements); + } +} diff --git a/vendor/symfony/console/Output/BufferedOutput.php b/vendor/symfony/console/Output/BufferedOutput.php new file mode 100644 index 00000000..8afc8931 --- /dev/null +++ b/vendor/symfony/console/Output/BufferedOutput.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +/** + * @author Jean-François Simon + */ +class BufferedOutput extends Output +{ + private $buffer = ''; + + /** + * Empties buffer and returns its content. + * + * @return string + */ + public function fetch() + { + $content = $this->buffer; + $this->buffer = ''; + + return $content; + } + + /** + * {@inheritdoc} + */ + protected function doWrite($message, $newline) + { + $this->buffer .= $message; + + if ($newline) { + $this->buffer .= PHP_EOL; + } + } +} diff --git a/vendor/symfony/console/Output/ConsoleOutput.php b/vendor/symfony/console/Output/ConsoleOutput.php new file mode 100644 index 00000000..8430c9c8 --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleOutput.php @@ -0,0 +1,161 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +use Symfony\Component\Console\Formatter\OutputFormatterInterface; + +/** + * ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR. + * + * This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR. + * + * $output = new ConsoleOutput(); + * + * This is equivalent to: + * + * $output = new StreamOutput(fopen('php://stdout', 'w')); + * $stdErr = new StreamOutput(fopen('php://stderr', 'w')); + * + * @author Fabien Potencier + */ +class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface +{ + private $stderr; + private $consoleSectionOutputs = []; + + /** + * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) + * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) + * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) + */ + public function __construct(int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null) + { + parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter); + + $actualDecorated = $this->isDecorated(); + $this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter()); + + if (null === $decorated) { + $this->setDecorated($actualDecorated && $this->stderr->isDecorated()); + } + } + + /** + * Creates a new output section. + */ + public function section(): ConsoleSectionOutput + { + return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter()); + } + + /** + * {@inheritdoc} + */ + public function setDecorated($decorated) + { + parent::setDecorated($decorated); + $this->stderr->setDecorated($decorated); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + parent::setFormatter($formatter); + $this->stderr->setFormatter($formatter); + } + + /** + * {@inheritdoc} + */ + public function setVerbosity($level) + { + parent::setVerbosity($level); + $this->stderr->setVerbosity($level); + } + + /** + * {@inheritdoc} + */ + public function getErrorOutput() + { + return $this->stderr; + } + + /** + * {@inheritdoc} + */ + public function setErrorOutput(OutputInterface $error) + { + $this->stderr = $error; + } + + /** + * Returns true if current environment supports writing console output to + * STDOUT. + * + * @return bool + */ + protected function hasStdoutSupport() + { + return false === $this->isRunningOS400(); + } + + /** + * Returns true if current environment supports writing console output to + * STDERR. + * + * @return bool + */ + protected function hasStderrSupport() + { + return false === $this->isRunningOS400(); + } + + /** + * Checks if current executing environment is IBM iSeries (OS400), which + * doesn't properly convert character-encodings between ASCII to EBCDIC. + * + * @return bool + */ + private function isRunningOS400() + { + $checks = [ + \function_exists('php_uname') ? php_uname('s') : '', + getenv('OSTYPE'), + PHP_OS, + ]; + + return false !== stripos(implode(';', $checks), 'OS400'); + } + + /** + * @return resource + */ + private function openOutputStream() + { + if (!$this->hasStdoutSupport()) { + return fopen('php://output', 'w'); + } + + return @fopen('php://stdout', 'w') ?: fopen('php://output', 'w'); + } + + /** + * @return resource + */ + private function openErrorStream() + { + return fopen($this->hasStderrSupport() ? 'php://stderr' : 'php://output', 'w'); + } +} diff --git a/vendor/symfony/console/Output/ConsoleOutputInterface.php b/vendor/symfony/console/Output/ConsoleOutputInterface.php new file mode 100644 index 00000000..f4c2fa62 --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleOutputInterface.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +/** + * ConsoleOutputInterface is the interface implemented by ConsoleOutput class. + * This adds information about stderr and section output stream. + * + * @author Dariusz Górecki + * + * @method ConsoleSectionOutput section() Creates a new output section + */ +interface ConsoleOutputInterface extends OutputInterface +{ + /** + * Gets the OutputInterface for errors. + * + * @return OutputInterface + */ + public function getErrorOutput(); + + public function setErrorOutput(OutputInterface $error); +} diff --git a/vendor/symfony/console/Output/ConsoleSectionOutput.php b/vendor/symfony/console/Output/ConsoleSectionOutput.php new file mode 100644 index 00000000..4ada2e86 --- /dev/null +++ b/vendor/symfony/console/Output/ConsoleSectionOutput.php @@ -0,0 +1,141 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +use Symfony\Component\Console\Formatter\OutputFormatterInterface; +use Symfony\Component\Console\Helper\Helper; +use Symfony\Component\Console\Terminal; + +/** + * @author Pierre du Plessis + * @author Gabriel Ostrolucký + */ +class ConsoleSectionOutput extends StreamOutput +{ + private $content = []; + private $lines = 0; + private $sections; + private $terminal; + + /** + * @param resource $stream + * @param ConsoleSectionOutput[] $sections + */ + public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter) + { + parent::__construct($stream, $verbosity, $decorated, $formatter); + array_unshift($sections, $this); + $this->sections = &$sections; + $this->terminal = new Terminal(); + } + + /** + * Clears previous output for this section. + * + * @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared + */ + public function clear(int $lines = null) + { + if (empty($this->content) || !$this->isDecorated()) { + return; + } + + if ($lines) { + \array_splice($this->content, -($lines * 2)); // Multiply lines by 2 to cater for each new line added between content + } else { + $lines = $this->lines; + $this->content = []; + } + + $this->lines -= $lines; + + parent::doWrite($this->popStreamContentUntilCurrentSection($lines), false); + } + + /** + * Overwrites the previous output with a new message. + * + * @param array|string $message + */ + public function overwrite($message) + { + $this->clear(); + $this->writeln($message); + } + + public function getContent(): string + { + return implode('', $this->content); + } + + /** + * @internal + */ + public function addContent(string $input) + { + foreach (explode(PHP_EOL, $input) as $lineContent) { + $this->lines += ceil($this->getDisplayLength($lineContent) / $this->terminal->getWidth()) ?: 1; + $this->content[] = $lineContent; + $this->content[] = PHP_EOL; + } + } + + /** + * {@inheritdoc} + */ + protected function doWrite($message, $newline) + { + if (!$this->isDecorated()) { + return parent::doWrite($message, $newline); + } + + $erasedContent = $this->popStreamContentUntilCurrentSection(); + + $this->addContent($message); + + parent::doWrite($message, true); + parent::doWrite($erasedContent, false); + } + + /** + * At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits + * current section. Then it erases content it crawled through. Optionally, it erases part of current section too. + */ + private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0): string + { + $numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection; + $erasedContent = []; + + foreach ($this->sections as $section) { + if ($section === $this) { + break; + } + + $numberOfLinesToClear += $section->lines; + $erasedContent[] = $section->getContent(); + } + + if ($numberOfLinesToClear > 0) { + // move cursor up n lines + parent::doWrite(sprintf("\x1b[%dA", $numberOfLinesToClear), false); + // erase to end of screen + parent::doWrite("\x1b[0J", false); + } + + return implode('', array_reverse($erasedContent)); + } + + private function getDisplayLength(string $text): string + { + return Helper::strlenWithoutDecoration($this->getFormatter(), str_replace("\t", ' ', $text)); + } +} diff --git a/vendor/symfony/console/Output/NullOutput.php b/vendor/symfony/console/Output/NullOutput.php new file mode 100644 index 00000000..218f285b --- /dev/null +++ b/vendor/symfony/console/Output/NullOutput.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Formatter\OutputFormatterInterface; + +/** + * NullOutput suppresses all output. + * + * $output = new NullOutput(); + * + * @author Fabien Potencier + * @author Tobias Schultze + */ +class NullOutput implements OutputInterface +{ + /** + * {@inheritdoc} + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + // do nothing + } + + /** + * {@inheritdoc} + */ + public function getFormatter() + { + // to comply with the interface we must return a OutputFormatterInterface + return new OutputFormatter(); + } + + /** + * {@inheritdoc} + */ + public function setDecorated($decorated) + { + // do nothing + } + + /** + * {@inheritdoc} + */ + public function isDecorated() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function setVerbosity($level) + { + // do nothing + } + + /** + * {@inheritdoc} + */ + public function getVerbosity() + { + return self::VERBOSITY_QUIET; + } + + /** + * {@inheritdoc} + */ + public function isQuiet() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function isVerbose() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function isVeryVerbose() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function isDebug() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function writeln($messages, $options = self::OUTPUT_NORMAL) + { + // do nothing + } + + /** + * {@inheritdoc} + */ + public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL) + { + // do nothing + } +} diff --git a/vendor/symfony/console/Output/Output.php b/vendor/symfony/console/Output/Output.php new file mode 100644 index 00000000..9dd76511 --- /dev/null +++ b/vendor/symfony/console/Output/Output.php @@ -0,0 +1,177 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Formatter\OutputFormatterInterface; + +/** + * Base class for output classes. + * + * There are five levels of verbosity: + * + * * normal: no option passed (normal output) + * * verbose: -v (more output) + * * very verbose: -vv (highly extended output) + * * debug: -vvv (all debug output) + * * quiet: -q (no output) + * + * @author Fabien Potencier + */ +abstract class Output implements OutputInterface +{ + private $verbosity; + private $formatter; + + /** + * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) + * @param bool $decorated Whether to decorate messages + * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) + */ + public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, OutputFormatterInterface $formatter = null) + { + $this->verbosity = null === $verbosity ? self::VERBOSITY_NORMAL : $verbosity; + $this->formatter = $formatter ?: new OutputFormatter(); + $this->formatter->setDecorated($decorated); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + $this->formatter = $formatter; + } + + /** + * {@inheritdoc} + */ + public function getFormatter() + { + return $this->formatter; + } + + /** + * {@inheritdoc} + */ + public function setDecorated($decorated) + { + $this->formatter->setDecorated($decorated); + } + + /** + * {@inheritdoc} + */ + public function isDecorated() + { + return $this->formatter->isDecorated(); + } + + /** + * {@inheritdoc} + */ + public function setVerbosity($level) + { + $this->verbosity = (int) $level; + } + + /** + * {@inheritdoc} + */ + public function getVerbosity() + { + return $this->verbosity; + } + + /** + * {@inheritdoc} + */ + public function isQuiet() + { + return self::VERBOSITY_QUIET === $this->verbosity; + } + + /** + * {@inheritdoc} + */ + public function isVerbose() + { + return self::VERBOSITY_VERBOSE <= $this->verbosity; + } + + /** + * {@inheritdoc} + */ + public function isVeryVerbose() + { + return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; + } + + /** + * {@inheritdoc} + */ + public function isDebug() + { + return self::VERBOSITY_DEBUG <= $this->verbosity; + } + + /** + * {@inheritdoc} + */ + public function writeln($messages, $options = self::OUTPUT_NORMAL) + { + $this->write($messages, true, $options); + } + + /** + * {@inheritdoc} + */ + public function write($messages, $newline = false, $options = self::OUTPUT_NORMAL) + { + if (!is_iterable($messages)) { + $messages = [$messages]; + } + + $types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN; + $type = $types & $options ?: self::OUTPUT_NORMAL; + + $verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG; + $verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL; + + if ($verbosity > $this->getVerbosity()) { + return; + } + + foreach ($messages as $message) { + switch ($type) { + case OutputInterface::OUTPUT_NORMAL: + $message = $this->formatter->format($message); + break; + case OutputInterface::OUTPUT_RAW: + break; + case OutputInterface::OUTPUT_PLAIN: + $message = strip_tags($this->formatter->format($message)); + break; + } + + $this->doWrite($message, $newline); + } + } + + /** + * Writes a message to the output. + * + * @param string $message A message to write to the output + * @param bool $newline Whether to add a newline or not + */ + abstract protected function doWrite($message, $newline); +} diff --git a/vendor/symfony/console/Output/OutputInterface.php b/vendor/symfony/console/Output/OutputInterface.php new file mode 100644 index 00000000..0dfd12b9 --- /dev/null +++ b/vendor/symfony/console/Output/OutputInterface.php @@ -0,0 +1,114 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +use Symfony\Component\Console\Formatter\OutputFormatterInterface; + +/** + * OutputInterface is the interface implemented by all Output classes. + * + * @author Fabien Potencier + */ +interface OutputInterface +{ + const VERBOSITY_QUIET = 16; + const VERBOSITY_NORMAL = 32; + const VERBOSITY_VERBOSE = 64; + const VERBOSITY_VERY_VERBOSE = 128; + const VERBOSITY_DEBUG = 256; + + const OUTPUT_NORMAL = 1; + const OUTPUT_RAW = 2; + const OUTPUT_PLAIN = 4; + + /** + * Writes a message to the output. + * + * @param string|iterable $messages The message as an iterable of strings or a single string + * @param bool $newline Whether to add a newline + * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL + */ + public function write($messages, $newline = false, $options = 0); + + /** + * Writes a message to the output and adds a newline at the end. + * + * @param string|iterable $messages The message as an iterable of strings or a single string + * @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL + */ + public function writeln($messages, $options = 0); + + /** + * Sets the verbosity of the output. + * + * @param int $level The level of verbosity (one of the VERBOSITY constants) + */ + public function setVerbosity($level); + + /** + * Gets the current verbosity of the output. + * + * @return int The current level of verbosity (one of the VERBOSITY constants) + */ + public function getVerbosity(); + + /** + * Returns whether verbosity is quiet (-q). + * + * @return bool true if verbosity is set to VERBOSITY_QUIET, false otherwise + */ + public function isQuiet(); + + /** + * Returns whether verbosity is verbose (-v). + * + * @return bool true if verbosity is set to VERBOSITY_VERBOSE, false otherwise + */ + public function isVerbose(); + + /** + * Returns whether verbosity is very verbose (-vv). + * + * @return bool true if verbosity is set to VERBOSITY_VERY_VERBOSE, false otherwise + */ + public function isVeryVerbose(); + + /** + * Returns whether verbosity is debug (-vvv). + * + * @return bool true if verbosity is set to VERBOSITY_DEBUG, false otherwise + */ + public function isDebug(); + + /** + * Sets the decorated flag. + * + * @param bool $decorated Whether to decorate the messages + */ + public function setDecorated($decorated); + + /** + * Gets the decorated flag. + * + * @return bool true if the output will decorate messages, false otherwise + */ + public function isDecorated(); + + public function setFormatter(OutputFormatterInterface $formatter); + + /** + * Returns current output formatter instance. + * + * @return OutputFormatterInterface + */ + public function getFormatter(); +} diff --git a/vendor/symfony/console/Output/StreamOutput.php b/vendor/symfony/console/Output/StreamOutput.php new file mode 100644 index 00000000..43f7a2f2 --- /dev/null +++ b/vendor/symfony/console/Output/StreamOutput.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Output; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\RuntimeException; +use Symfony\Component\Console\Formatter\OutputFormatterInterface; + +/** + * StreamOutput writes the output to a given stream. + * + * Usage: + * + * $output = new StreamOutput(fopen('php://stdout', 'w')); + * + * As `StreamOutput` can use any stream, you can also use a file: + * + * $output = new StreamOutput(fopen('/path/to/output.log', 'a', false)); + * + * @author Fabien Potencier + */ +class StreamOutput extends Output +{ + private $stream; + + /** + * @param resource $stream A stream resource + * @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface) + * @param bool|null $decorated Whether to decorate messages (null for auto-guessing) + * @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter) + * + * @throws InvalidArgumentException When first argument is not a real stream + */ + public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = null, OutputFormatterInterface $formatter = null) + { + if (!\is_resource($stream) || 'stream' !== get_resource_type($stream)) { + throw new InvalidArgumentException('The StreamOutput class needs a stream as its first argument.'); + } + + $this->stream = $stream; + + if (null === $decorated) { + $decorated = $this->hasColorSupport(); + } + + parent::__construct($verbosity, $decorated, $formatter); + } + + /** + * Gets the stream attached to this StreamOutput instance. + * + * @return resource A stream resource + */ + public function getStream() + { + return $this->stream; + } + + /** + * {@inheritdoc} + */ + protected function doWrite($message, $newline) + { + if ($newline) { + $message .= PHP_EOL; + } + + if (false === @fwrite($this->stream, $message)) { + // should never happen + throw new RuntimeException('Unable to write output.'); + } + + fflush($this->stream); + } + + /** + * Returns true if the stream supports colorization. + * + * Colorization is disabled if not supported by the stream: + * + * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo + * terminals via named pipes, so we can only check the environment. + * + * Reference: Composer\XdebugHandler\Process::supportsColor + * https://github.com/composer/xdebug-handler + * + * @return bool true if the stream supports colorization, false otherwise + */ + protected function hasColorSupport() + { + if ('Hyper' === getenv('TERM_PROGRAM')) { + return true; + } + + if (\DIRECTORY_SEPARATOR === '\\') { + return (\function_exists('sapi_windows_vt100_support') + && @sapi_windows_vt100_support($this->stream)) + || false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM'); + } + + if (\function_exists('stream_isatty')) { + return @stream_isatty($this->stream); + } + + if (\function_exists('posix_isatty')) { + return @posix_isatty($this->stream); + } + + $stat = @fstat($this->stream); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + } +} diff --git a/vendor/symfony/console/Question/ChoiceQuestion.php b/vendor/symfony/console/Question/ChoiceQuestion.php new file mode 100644 index 00000000..612e406a --- /dev/null +++ b/vendor/symfony/console/Question/ChoiceQuestion.php @@ -0,0 +1,184 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Question; + +use Symfony\Component\Console\Exception\InvalidArgumentException; + +/** + * Represents a choice question. + * + * @author Fabien Potencier + */ +class ChoiceQuestion extends Question +{ + private $choices; + private $multiselect = false; + private $prompt = ' > '; + private $errorMessage = 'Value "%s" is invalid'; + + /** + * @param string $question The question to ask to the user + * @param array $choices The list of available choices + * @param mixed $default The default answer to return + */ + public function __construct(string $question, array $choices, $default = null) + { + if (!$choices) { + throw new \LogicException('Choice question must have at least 1 choice available.'); + } + + parent::__construct($question, $default); + + $this->choices = $choices; + $this->setValidator($this->getDefaultValidator()); + $this->setAutocompleterValues($choices); + } + + /** + * Returns available choices. + * + * @return array + */ + public function getChoices() + { + return $this->choices; + } + + /** + * Sets multiselect option. + * + * When multiselect is set to true, multiple choices can be answered. + * + * @param bool $multiselect + * + * @return $this + */ + public function setMultiselect($multiselect) + { + $this->multiselect = $multiselect; + $this->setValidator($this->getDefaultValidator()); + + return $this; + } + + /** + * Returns whether the choices are multiselect. + * + * @return bool + */ + public function isMultiselect() + { + return $this->multiselect; + } + + /** + * Gets the prompt for choices. + * + * @return string + */ + public function getPrompt() + { + return $this->prompt; + } + + /** + * Sets the prompt for choices. + * + * @param string $prompt + * + * @return $this + */ + public function setPrompt($prompt) + { + $this->prompt = $prompt; + + return $this; + } + + /** + * Sets the error message for invalid values. + * + * The error message has a string placeholder (%s) for the invalid value. + * + * @param string $errorMessage + * + * @return $this + */ + public function setErrorMessage($errorMessage) + { + $this->errorMessage = $errorMessage; + $this->setValidator($this->getDefaultValidator()); + + return $this; + } + + private function getDefaultValidator(): callable + { + $choices = $this->choices; + $errorMessage = $this->errorMessage; + $multiselect = $this->multiselect; + $isAssoc = $this->isAssoc($choices); + + return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) { + // Collapse all spaces. + $selectedChoices = str_replace(' ', '', $selected); + + if ($multiselect) { + // Check for a separated comma values + if (!preg_match('/^[^,]+(?:,[^,]+)*$/', $selectedChoices, $matches)) { + throw new InvalidArgumentException(sprintf($errorMessage, $selected)); + } + $selectedChoices = explode(',', $selectedChoices); + } else { + $selectedChoices = [$selected]; + } + + $multiselectChoices = []; + foreach ($selectedChoices as $value) { + $results = []; + foreach ($choices as $key => $choice) { + if ($choice === $value) { + $results[] = $key; + } + } + + if (\count($results) > 1) { + throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results))); + } + + $result = array_search($value, $choices); + + if (!$isAssoc) { + if (false !== $result) { + $result = $choices[$result]; + } elseif (isset($choices[$value])) { + $result = $choices[$value]; + } + } elseif (false === $result && isset($choices[$value])) { + $result = $value; + } + + if (false === $result) { + throw new InvalidArgumentException(sprintf($errorMessage, $value)); + } + + $multiselectChoices[] = (string) $result; + } + + if ($multiselect) { + return $multiselectChoices; + } + + return current($multiselectChoices); + }; + } +} diff --git a/vendor/symfony/console/Question/ConfirmationQuestion.php b/vendor/symfony/console/Question/ConfirmationQuestion.php new file mode 100644 index 00000000..88227dfa --- /dev/null +++ b/vendor/symfony/console/Question/ConfirmationQuestion.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Question; + +/** + * Represents a yes/no question. + * + * @author Fabien Potencier + */ +class ConfirmationQuestion extends Question +{ + private $trueAnswerRegex; + + /** + * @param string $question The question to ask to the user + * @param bool $default The default answer to return, true or false + * @param string $trueAnswerRegex A regex to match the "yes" answer + */ + public function __construct(string $question, bool $default = true, string $trueAnswerRegex = '/^y/i') + { + parent::__construct($question, $default); + + $this->trueAnswerRegex = $trueAnswerRegex; + $this->setNormalizer($this->getDefaultNormalizer()); + } + + /** + * Returns the default answer normalizer. + * + * @return callable + */ + private function getDefaultNormalizer() + { + $default = $this->getDefault(); + $regex = $this->trueAnswerRegex; + + return function ($answer) use ($default, $regex) { + if (\is_bool($answer)) { + return $answer; + } + + $answerIsTrue = (bool) preg_match($regex, $answer); + if (false === $default) { + return $answer && $answerIsTrue; + } + + return '' === $answer || $answerIsTrue; + }; + } +} diff --git a/vendor/symfony/console/Question/Question.php b/vendor/symfony/console/Question/Question.php new file mode 100644 index 00000000..eac82cfa --- /dev/null +++ b/vendor/symfony/console/Question/Question.php @@ -0,0 +1,246 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Question; + +use Symfony\Component\Console\Exception\InvalidArgumentException; +use Symfony\Component\Console\Exception\LogicException; + +/** + * Represents a Question. + * + * @author Fabien Potencier + */ +class Question +{ + private $question; + private $attempts; + private $hidden = false; + private $hiddenFallback = true; + private $autocompleterValues; + private $validator; + private $default; + private $normalizer; + + /** + * @param string $question The question to ask to the user + * @param mixed $default The default answer to return if the user enters nothing + */ + public function __construct(string $question, $default = null) + { + $this->question = $question; + $this->default = $default; + } + + /** + * Returns the question. + * + * @return string + */ + public function getQuestion() + { + return $this->question; + } + + /** + * Returns the default answer. + * + * @return mixed + */ + public function getDefault() + { + return $this->default; + } + + /** + * Returns whether the user response must be hidden. + * + * @return bool + */ + public function isHidden() + { + return $this->hidden; + } + + /** + * Sets whether the user response must be hidden or not. + * + * @param bool $hidden + * + * @return $this + * + * @throws LogicException In case the autocompleter is also used + */ + public function setHidden($hidden) + { + if ($this->autocompleterValues) { + throw new LogicException('A hidden question cannot use the autocompleter.'); + } + + $this->hidden = (bool) $hidden; + + return $this; + } + + /** + * In case the response can not be hidden, whether to fallback on non-hidden question or not. + * + * @return bool + */ + public function isHiddenFallback() + { + return $this->hiddenFallback; + } + + /** + * Sets whether to fallback on non-hidden question if the response can not be hidden. + * + * @param bool $fallback + * + * @return $this + */ + public function setHiddenFallback($fallback) + { + $this->hiddenFallback = (bool) $fallback; + + return $this; + } + + /** + * Gets values for the autocompleter. + * + * @return iterable|null + */ + public function getAutocompleterValues() + { + return $this->autocompleterValues; + } + + /** + * Sets values for the autocompleter. + * + * @param iterable|null $values + * + * @return $this + * + * @throws InvalidArgumentException + * @throws LogicException + */ + public function setAutocompleterValues($values) + { + if (\is_array($values)) { + $values = $this->isAssoc($values) ? array_merge(array_keys($values), array_values($values)) : array_values($values); + } + + if (null !== $values && !\is_array($values) && !$values instanceof \Traversable) { + throw new InvalidArgumentException('Autocompleter values can be either an array, "null" or a "Traversable" object.'); + } + + if ($this->hidden) { + throw new LogicException('A hidden question cannot use the autocompleter.'); + } + + $this->autocompleterValues = $values; + + return $this; + } + + /** + * Sets a validator for the question. + * + * @param callable|null $validator + * + * @return $this + */ + public function setValidator(callable $validator = null) + { + $this->validator = $validator; + + return $this; + } + + /** + * Gets the validator for the question. + * + * @return callable|null + */ + public function getValidator() + { + return $this->validator; + } + + /** + * Sets the maximum number of attempts. + * + * Null means an unlimited number of attempts. + * + * @param int|null $attempts + * + * @return $this + * + * @throws InvalidArgumentException in case the number of attempts is invalid + */ + public function setMaxAttempts($attempts) + { + if (null !== $attempts && $attempts < 1) { + throw new InvalidArgumentException('Maximum number of attempts must be a positive value.'); + } + + $this->attempts = $attempts; + + return $this; + } + + /** + * Gets the maximum number of attempts. + * + * Null means an unlimited number of attempts. + * + * @return int|null + */ + public function getMaxAttempts() + { + return $this->attempts; + } + + /** + * Sets a normalizer for the response. + * + * The normalizer can be a callable (a string), a closure or a class implementing __invoke. + * + * @param callable $normalizer + * + * @return $this + */ + public function setNormalizer(callable $normalizer) + { + $this->normalizer = $normalizer; + + return $this; + } + + /** + * Gets the normalizer for the response. + * + * The normalizer can ba a callable (a string), a closure or a class implementing __invoke. + * + * @return callable + */ + public function getNormalizer() + { + return $this->normalizer; + } + + protected function isAssoc($array) + { + return (bool) \count(array_filter(array_keys($array), 'is_string')); + } +} diff --git a/vendor/symfony/console/README.md b/vendor/symfony/console/README.md new file mode 100644 index 00000000..664a37c0 --- /dev/null +++ b/vendor/symfony/console/README.md @@ -0,0 +1,20 @@ +Console Component +================= + +The Console component eases the creation of beautiful and testable command line +interfaces. + +Resources +--------- + + * [Documentation](https://symfony.com/doc/current/components/console/index.html) + * [Contributing](https://symfony.com/doc/current/contributing/index.html) + * [Report issues](https://github.com/symfony/symfony/issues) and + [send Pull Requests](https://github.com/symfony/symfony/pulls) + in the [main Symfony repository](https://github.com/symfony/symfony) + +Credits +------- + +`Resources/bin/hiddeninput.exe` is a third party binary provided within this +component. Find sources and license at https://github.com/Seldaek/hidden-input. diff --git a/vendor/symfony/console/Resources/bin/hiddeninput.exe b/vendor/symfony/console/Resources/bin/hiddeninput.exe new file mode 100644 index 00000000..c8cf65e8 Binary files /dev/null and b/vendor/symfony/console/Resources/bin/hiddeninput.exe differ diff --git a/vendor/symfony/console/Style/OutputStyle.php b/vendor/symfony/console/Style/OutputStyle.php new file mode 100644 index 00000000..b1262b55 --- /dev/null +++ b/vendor/symfony/console/Style/OutputStyle.php @@ -0,0 +1,155 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Style; + +use Symfony\Component\Console\Formatter\OutputFormatterInterface; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Output\ConsoleOutputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Decorates output to add console style guide helpers. + * + * @author Kevin Bond + */ +abstract class OutputStyle implements OutputInterface, StyleInterface +{ + private $output; + + public function __construct(OutputInterface $output) + { + $this->output = $output; + } + + /** + * {@inheritdoc} + */ + public function newLine($count = 1) + { + $this->output->write(str_repeat(PHP_EOL, $count)); + } + + /** + * @param int $max + * + * @return ProgressBar + */ + public function createProgressBar($max = 0) + { + return new ProgressBar($this->output, $max); + } + + /** + * {@inheritdoc} + */ + public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) + { + $this->output->write($messages, $newline, $type); + } + + /** + * {@inheritdoc} + */ + public function writeln($messages, $type = self::OUTPUT_NORMAL) + { + $this->output->writeln($messages, $type); + } + + /** + * {@inheritdoc} + */ + public function setVerbosity($level) + { + $this->output->setVerbosity($level); + } + + /** + * {@inheritdoc} + */ + public function getVerbosity() + { + return $this->output->getVerbosity(); + } + + /** + * {@inheritdoc} + */ + public function setDecorated($decorated) + { + $this->output->setDecorated($decorated); + } + + /** + * {@inheritdoc} + */ + public function isDecorated() + { + return $this->output->isDecorated(); + } + + /** + * {@inheritdoc} + */ + public function setFormatter(OutputFormatterInterface $formatter) + { + $this->output->setFormatter($formatter); + } + + /** + * {@inheritdoc} + */ + public function getFormatter() + { + return $this->output->getFormatter(); + } + + /** + * {@inheritdoc} + */ + public function isQuiet() + { + return $this->output->isQuiet(); + } + + /** + * {@inheritdoc} + */ + public function isVerbose() + { + return $this->output->isVerbose(); + } + + /** + * {@inheritdoc} + */ + public function isVeryVerbose() + { + return $this->output->isVeryVerbose(); + } + + /** + * {@inheritdoc} + */ + public function isDebug() + { + return $this->output->isDebug(); + } + + protected function getErrorOutput() + { + if (!$this->output instanceof ConsoleOutputInterface) { + return $this->output; + } + + return $this->output->getErrorOutput(); + } +} diff --git a/vendor/symfony/console/Style/StyleInterface.php b/vendor/symfony/console/Style/StyleInterface.php new file mode 100644 index 00000000..475c268f --- /dev/null +++ b/vendor/symfony/console/Style/StyleInterface.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Style; + +/** + * Output style helpers. + * + * @author Kevin Bond + */ +interface StyleInterface +{ + /** + * Formats a command title. + * + * @param string $message + */ + public function title($message); + + /** + * Formats a section title. + * + * @param string $message + */ + public function section($message); + + /** + * Formats a list. + */ + public function listing(array $elements); + + /** + * Formats informational text. + * + * @param string|array $message + */ + public function text($message); + + /** + * Formats a success result bar. + * + * @param string|array $message + */ + public function success($message); + + /** + * Formats an error result bar. + * + * @param string|array $message + */ + public function error($message); + + /** + * Formats an warning result bar. + * + * @param string|array $message + */ + public function warning($message); + + /** + * Formats a note admonition. + * + * @param string|array $message + */ + public function note($message); + + /** + * Formats a caution admonition. + * + * @param string|array $message + */ + public function caution($message); + + /** + * Formats a table. + */ + public function table(array $headers, array $rows); + + /** + * Asks a question. + * + * @param string $question + * @param string|null $default + * @param callable|null $validator + * + * @return mixed + */ + public function ask($question, $default = null, $validator = null); + + /** + * Asks a question with the user input hidden. + * + * @param string $question + * @param callable|null $validator + * + * @return mixed + */ + public function askHidden($question, $validator = null); + + /** + * Asks for confirmation. + * + * @param string $question + * @param bool $default + * + * @return bool + */ + public function confirm($question, $default = true); + + /** + * Asks a choice question. + * + * @param string $question + * @param array $choices + * @param string|int|null $default + * + * @return mixed + */ + public function choice($question, array $choices, $default = null); + + /** + * Add newline(s). + * + * @param int $count The number of newlines + */ + public function newLine($count = 1); + + /** + * Starts the progress output. + * + * @param int $max Maximum steps (0 if unknown) + */ + public function progressStart($max = 0); + + /** + * Advances the progress output X steps. + * + * @param int $step Number of steps to advance + */ + public function progressAdvance($step = 1); + + /** + * Finishes the progress output. + */ + public function progressFinish(); +} diff --git a/vendor/symfony/console/Style/SymfonyStyle.php b/vendor/symfony/console/Style/SymfonyStyle.php new file mode 100644 index 00000000..b46162de --- /dev/null +++ b/vendor/symfony/console/Style/SymfonyStyle.php @@ -0,0 +1,438 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Style; + +use Symfony\Component\Console\Exception\RuntimeException; +use Symfony\Component\Console\Formatter\OutputFormatter; +use Symfony\Component\Console\Helper\Helper; +use Symfony\Component\Console\Helper\ProgressBar; +use Symfony\Component\Console\Helper\SymfonyQuestionHelper; +use Symfony\Component\Console\Helper\Table; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\BufferedOutput; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ChoiceQuestion; +use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Question\Question; +use Symfony\Component\Console\Terminal; + +/** + * Output decorator helpers for the Symfony Style Guide. + * + * @author Kevin Bond + */ +class SymfonyStyle extends OutputStyle +{ + const MAX_LINE_LENGTH = 120; + + private $input; + private $questionHelper; + private $progressBar; + private $lineLength; + private $bufferedOutput; + + public function __construct(InputInterface $input, OutputInterface $output) + { + $this->input = $input; + $this->bufferedOutput = new BufferedOutput($output->getVerbosity(), false, clone $output->getFormatter()); + // Windows cmd wraps lines as soon as the terminal width is reached, whether there are following chars or not. + $width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH; + $this->lineLength = min($width - (int) (\DIRECTORY_SEPARATOR === '\\'), self::MAX_LINE_LENGTH); + + parent::__construct($output); + } + + /** + * Formats a message as a block of text. + * + * @param string|array $messages The message to write in the block + * @param string|null $type The block type (added in [] on first line) + * @param string|null $style The style to apply to the whole block + * @param string $prefix The prefix for the block + * @param bool $padding Whether to add vertical padding + * @param bool $escape Whether to escape the message + */ + public function block($messages, $type = null, $style = null, $prefix = ' ', $padding = false, $escape = true) + { + $messages = \is_array($messages) ? array_values($messages) : [$messages]; + + $this->autoPrependBlock(); + $this->writeln($this->createBlock($messages, $type, $style, $prefix, $padding, $escape)); + $this->newLine(); + } + + /** + * {@inheritdoc} + */ + public function title($message) + { + $this->autoPrependBlock(); + $this->writeln([ + sprintf('%s', OutputFormatter::escapeTrailingBackslash($message)), + sprintf('%s', str_repeat('=', Helper::strlenWithoutDecoration($this->getFormatter(), $message))), + ]); + $this->newLine(); + } + + /** + * {@inheritdoc} + */ + public function section($message) + { + $this->autoPrependBlock(); + $this->writeln([ + sprintf('%s', OutputFormatter::escapeTrailingBackslash($message)), + sprintf('%s', str_repeat('-', Helper::strlenWithoutDecoration($this->getFormatter(), $message))), + ]); + $this->newLine(); + } + + /** + * {@inheritdoc} + */ + public function listing(array $elements) + { + $this->autoPrependText(); + $elements = array_map(function ($element) { + return sprintf(' * %s', $element); + }, $elements); + + $this->writeln($elements); + $this->newLine(); + } + + /** + * {@inheritdoc} + */ + public function text($message) + { + $this->autoPrependText(); + + $messages = \is_array($message) ? array_values($message) : [$message]; + foreach ($messages as $message) { + $this->writeln(sprintf(' %s', $message)); + } + } + + /** + * Formats a command comment. + * + * @param string|array $message + */ + public function comment($message) + { + $this->block($message, null, null, ' // ', false, false); + } + + /** + * {@inheritdoc} + */ + public function success($message) + { + $this->block($message, 'OK', 'fg=black;bg=green', ' ', true); + } + + /** + * {@inheritdoc} + */ + public function error($message) + { + $this->block($message, 'ERROR', 'fg=white;bg=red', ' ', true); + } + + /** + * {@inheritdoc} + */ + public function warning($message) + { + $this->block($message, 'WARNING', 'fg=white;bg=red', ' ', true); + } + + /** + * {@inheritdoc} + */ + public function note($message) + { + $this->block($message, 'NOTE', 'fg=yellow', ' ! '); + } + + /** + * {@inheritdoc} + */ + public function caution($message) + { + $this->block($message, 'CAUTION', 'fg=white;bg=red', ' ! ', true); + } + + /** + * {@inheritdoc} + */ + public function table(array $headers, array $rows) + { + $style = clone Table::getStyleDefinition('symfony-style-guide'); + $style->setCellHeaderFormat('%s'); + + $table = new Table($this); + $table->setHeaders($headers); + $table->setRows($rows); + $table->setStyle($style); + + $table->render(); + $this->newLine(); + } + + /** + * {@inheritdoc} + */ + public function ask($question, $default = null, $validator = null) + { + $question = new Question($question, $default); + $question->setValidator($validator); + + return $this->askQuestion($question); + } + + /** + * {@inheritdoc} + */ + public function askHidden($question, $validator = null) + { + $question = new Question($question); + + $question->setHidden(true); + $question->setValidator($validator); + + return $this->askQuestion($question); + } + + /** + * {@inheritdoc} + */ + public function confirm($question, $default = true) + { + return $this->askQuestion(new ConfirmationQuestion($question, $default)); + } + + /** + * {@inheritdoc} + */ + public function choice($question, array $choices, $default = null) + { + if (null !== $default) { + $values = array_flip($choices); + $default = $values[$default]; + } + + return $this->askQuestion(new ChoiceQuestion($question, $choices, $default)); + } + + /** + * {@inheritdoc} + */ + public function progressStart($max = 0) + { + $this->progressBar = $this->createProgressBar($max); + $this->progressBar->start(); + } + + /** + * {@inheritdoc} + */ + public function progressAdvance($step = 1) + { + $this->getProgressBar()->advance($step); + } + + /** + * {@inheritdoc} + */ + public function progressFinish() + { + $this->getProgressBar()->finish(); + $this->newLine(2); + $this->progressBar = null; + } + + /** + * {@inheritdoc} + */ + public function createProgressBar($max = 0) + { + $progressBar = parent::createProgressBar($max); + + if ('\\' !== \DIRECTORY_SEPARATOR || 'Hyper' === getenv('TERM_PROGRAM')) { + $progressBar->setEmptyBarCharacter('░'); // light shade character \u2591 + $progressBar->setProgressCharacter(''); + $progressBar->setBarCharacter('▓'); // dark shade character \u2593 + } + + return $progressBar; + } + + /** + * @return mixed + */ + public function askQuestion(Question $question) + { + if ($this->input->isInteractive()) { + $this->autoPrependBlock(); + } + + if (!$this->questionHelper) { + $this->questionHelper = new SymfonyQuestionHelper(); + } + + $answer = $this->questionHelper->ask($this->input, $this, $question); + + if ($this->input->isInteractive()) { + $this->newLine(); + $this->bufferedOutput->write("\n"); + } + + return $answer; + } + + /** + * {@inheritdoc} + */ + public function writeln($messages, $type = self::OUTPUT_NORMAL) + { + if (!is_iterable($messages)) { + $messages = [$messages]; + } + + foreach ($messages as $message) { + parent::writeln($message, $type); + $this->writeBuffer($message, true, $type); + } + } + + /** + * {@inheritdoc} + */ + public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) + { + if (!is_iterable($messages)) { + $messages = [$messages]; + } + + foreach ($messages as $message) { + parent::write($message, $newline, $type); + $this->writeBuffer($message, $newline, $type); + } + } + + /** + * {@inheritdoc} + */ + public function newLine($count = 1) + { + parent::newLine($count); + $this->bufferedOutput->write(str_repeat("\n", $count)); + } + + /** + * Returns a new instance which makes use of stderr if available. + * + * @return self + */ + public function getErrorStyle() + { + return new self($this->input, $this->getErrorOutput()); + } + + private function getProgressBar(): ProgressBar + { + if (!$this->progressBar) { + throw new RuntimeException('The ProgressBar is not started.'); + } + + return $this->progressBar; + } + + private function autoPrependBlock(): void + { + $chars = substr(str_replace(PHP_EOL, "\n", $this->bufferedOutput->fetch()), -2); + + if (!isset($chars[0])) { + $this->newLine(); //empty history, so we should start with a new line. + + return; + } + //Prepend new line for each non LF chars (This means no blank line was output before) + $this->newLine(2 - substr_count($chars, "\n")); + } + + private function autoPrependText(): void + { + $fetched = $this->bufferedOutput->fetch(); + //Prepend new line if last char isn't EOL: + if ("\n" !== substr($fetched, -1)) { + $this->newLine(); + } + } + + private function writeBuffer(string $message, bool $newLine, int $type): void + { + // We need to know if the two last chars are PHP_EOL + // Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer + $this->bufferedOutput->write(substr($message, -4), $newLine, $type); + } + + private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false) + { + $indentLength = 0; + $prefixLength = Helper::strlenWithoutDecoration($this->getFormatter(), $prefix); + $lines = []; + + if (null !== $type) { + $type = sprintf('[%s] ', $type); + $indentLength = \strlen($type); + $lineIndentation = str_repeat(' ', $indentLength); + } + + // wrap and add newlines for each element + foreach ($messages as $key => $message) { + if ($escape) { + $message = OutputFormatter::escape($message); + } + + $lines = array_merge($lines, explode(PHP_EOL, wordwrap($message, $this->lineLength - $prefixLength - $indentLength, PHP_EOL, true))); + + if (\count($messages) > 1 && $key < \count($messages) - 1) { + $lines[] = ''; + } + } + + $firstLineIndex = 0; + if ($padding && $this->isDecorated()) { + $firstLineIndex = 1; + array_unshift($lines, ''); + $lines[] = ''; + } + + foreach ($lines as $i => &$line) { + if (null !== $type) { + $line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line; + } + + $line = $prefix.$line; + $line .= str_repeat(' ', $this->lineLength - Helper::strlenWithoutDecoration($this->getFormatter(), $line)); + + if ($style) { + $line = sprintf('<%s>%s', $style, $line); + } + } + + return $lines; + } +} diff --git a/vendor/symfony/console/Terminal.php b/vendor/symfony/console/Terminal.php new file mode 100644 index 00000000..456cca11 --- /dev/null +++ b/vendor/symfony/console/Terminal.php @@ -0,0 +1,137 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console; + +class Terminal +{ + private static $width; + private static $height; + + /** + * Gets the terminal width. + * + * @return int + */ + public function getWidth() + { + $width = getenv('COLUMNS'); + if (false !== $width) { + return (int) trim($width); + } + + if (null === self::$width) { + self::initDimensions(); + } + + return self::$width ?: 80; + } + + /** + * Gets the terminal height. + * + * @return int + */ + public function getHeight() + { + $height = getenv('LINES'); + if (false !== $height) { + return (int) trim($height); + } + + if (null === self::$height) { + self::initDimensions(); + } + + return self::$height ?: 50; + } + + private static function initDimensions() + { + if ('\\' === \DIRECTORY_SEPARATOR) { + if (preg_match('/^(\d+)x(\d+)(?: \((\d+)x(\d+)\))?$/', trim(getenv('ANSICON')), $matches)) { + // extract [w, H] from "wxh (WxH)" + // or [w, h] from "wxh" + self::$width = (int) $matches[1]; + self::$height = isset($matches[4]) ? (int) $matches[4] : (int) $matches[2]; + } elseif (null !== $dimensions = self::getConsoleMode()) { + // extract [w, h] from "wxh" + self::$width = (int) $dimensions[0]; + self::$height = (int) $dimensions[1]; + } + } elseif ($sttyString = self::getSttyColumns()) { + if (preg_match('/rows.(\d+);.columns.(\d+);/i', $sttyString, $matches)) { + // extract [w, h] from "rows h; columns w;" + self::$width = (int) $matches[2]; + self::$height = (int) $matches[1]; + } elseif (preg_match('/;.(\d+).rows;.(\d+).columns/i', $sttyString, $matches)) { + // extract [w, h] from "; h rows; w columns" + self::$width = (int) $matches[2]; + self::$height = (int) $matches[1]; + } + } + } + + /** + * Runs and parses mode CON if it's available, suppressing any error output. + * + * @return int[]|null An array composed of the width and the height or null if it could not be parsed + */ + private static function getConsoleMode() + { + if (!\function_exists('proc_open')) { + return; + } + + $descriptorspec = [ + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], + ]; + $process = proc_open('mode CON', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]); + if (\is_resource($process)) { + $info = stream_get_contents($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + + if (preg_match('/--------+\r?\n.+?(\d+)\r?\n.+?(\d+)\r?\n/', $info, $matches)) { + return [(int) $matches[2], (int) $matches[1]]; + } + } + } + + /** + * Runs and parses stty -a if it's available, suppressing any error output. + * + * @return string|null + */ + private static function getSttyColumns() + { + if (!\function_exists('proc_open')) { + return; + } + + $descriptorspec = [ + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], + ]; + + $process = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]); + if (\is_resource($process)) { + $info = stream_get_contents($pipes[1]); + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($process); + + return $info; + } + } +} diff --git a/vendor/symfony/console/Tester/ApplicationTester.php b/vendor/symfony/console/Tester/ApplicationTester.php new file mode 100644 index 00000000..ced56cff --- /dev/null +++ b/vendor/symfony/console/Tester/ApplicationTester.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tester; + +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Input\ArrayInput; + +/** + * Eases the testing of console applications. + * + * When testing an application, don't forget to disable the auto exit flag: + * + * $application = new Application(); + * $application->setAutoExit(false); + * + * @author Fabien Potencier + */ +class ApplicationTester +{ + use TesterTrait; + + private $application; + private $input; + private $statusCode; + + public function __construct(Application $application) + { + $this->application = $application; + } + + /** + * Executes the application. + * + * Available options: + * + * * interactive: Sets the input interactive flag + * * decorated: Sets the output decorated flag + * * verbosity: Sets the output verbosity flag + * * capture_stderr_separately: Make output of stdOut and stdErr separately available + * + * @param array $input An array of arguments and options + * @param array $options An array of options + * + * @return int The command exit code + */ + public function run(array $input, $options = []) + { + $this->input = new ArrayInput($input); + if (isset($options['interactive'])) { + $this->input->setInteractive($options['interactive']); + } + + $shellInteractive = getenv('SHELL_INTERACTIVE'); + + if ($this->inputs) { + $this->input->setStream(self::createStream($this->inputs)); + putenv('SHELL_INTERACTIVE=1'); + } + + $this->initOutput($options); + + $this->statusCode = $this->application->run($this->input, $this->output); + + putenv($shellInteractive ? "SHELL_INTERACTIVE=$shellInteractive" : 'SHELL_INTERACTIVE'); + + return $this->statusCode; + } +} diff --git a/vendor/symfony/console/Tester/CommandTester.php b/vendor/symfony/console/Tester/CommandTester.php new file mode 100644 index 00000000..da51559f --- /dev/null +++ b/vendor/symfony/console/Tester/CommandTester.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tester; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\ArrayInput; + +/** + * Eases the testing of console commands. + * + * @author Fabien Potencier + * @author Robin Chalas + */ +class CommandTester +{ + use TesterTrait; + + private $command; + private $input; + private $statusCode; + + public function __construct(Command $command) + { + $this->command = $command; + } + + /** + * Executes the command. + * + * Available execution options: + * + * * interactive: Sets the input interactive flag + * * decorated: Sets the output decorated flag + * * verbosity: Sets the output verbosity flag + * * capture_stderr_separately: Make output of stdOut and stdErr separately available + * + * @param array $input An array of command arguments and options + * @param array $options An array of execution options + * + * @return int The command exit code + */ + public function execute(array $input, array $options = []) + { + // set the command name automatically if the application requires + // this argument and no command name was passed + if (!isset($input['command']) + && (null !== $application = $this->command->getApplication()) + && $application->getDefinition()->hasArgument('command') + ) { + $input = array_merge(['command' => $this->command->getName()], $input); + } + + $this->input = new ArrayInput($input); + if ($this->inputs) { + $this->input->setStream(self::createStream($this->inputs)); + } + + if (isset($options['interactive'])) { + $this->input->setInteractive($options['interactive']); + } + + if (!isset($options['decorated'])) { + $options['decorated'] = false; + } + + $this->initOutput($options); + + return $this->statusCode = $this->command->run($this->input, $this->output); + } +} diff --git a/vendor/symfony/console/Tester/TesterTrait.php b/vendor/symfony/console/Tester/TesterTrait.php new file mode 100644 index 00000000..e5df56d8 --- /dev/null +++ b/vendor/symfony/console/Tester/TesterTrait.php @@ -0,0 +1,173 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tester; + +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\ConsoleOutput; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\StreamOutput; + +/** + * @author Amrouche Hamza + */ +trait TesterTrait +{ + /** @var StreamOutput */ + private $output; + private $inputs = []; + private $captureStreamsIndependently = false; + + /** + * Gets the display returned by the last execution of the command or application. + * + * @param bool $normalize Whether to normalize end of lines to \n or not + * + * @return string The display + */ + public function getDisplay($normalize = false) + { + rewind($this->output->getStream()); + + $display = stream_get_contents($this->output->getStream()); + + if ($normalize) { + $display = str_replace(PHP_EOL, "\n", $display); + } + + return $display; + } + + /** + * Gets the output written to STDERR by the application. + * + * @param bool $normalize Whether to normalize end of lines to \n or not + * + * @return string + */ + public function getErrorOutput($normalize = false) + { + if (!$this->captureStreamsIndependently) { + throw new \LogicException('The error output is not available when the tester is run without "capture_stderr_separately" option set.'); + } + + rewind($this->output->getErrorOutput()->getStream()); + + $display = stream_get_contents($this->output->getErrorOutput()->getStream()); + + if ($normalize) { + $display = str_replace(PHP_EOL, "\n", $display); + } + + return $display; + } + + /** + * Gets the input instance used by the last execution of the command or application. + * + * @return InputInterface The current input instance + */ + public function getInput() + { + return $this->input; + } + + /** + * Gets the output instance used by the last execution of the command or application. + * + * @return OutputInterface The current output instance + */ + public function getOutput() + { + return $this->output; + } + + /** + * Gets the status code returned by the last execution of the command or application. + * + * @return int The status code + */ + public function getStatusCode() + { + return $this->statusCode; + } + + /** + * Sets the user inputs. + * + * @param array $inputs An array of strings representing each input + * passed to the command input stream + * + * @return self + */ + public function setInputs(array $inputs) + { + $this->inputs = $inputs; + + return $this; + } + + /** + * Initializes the output property. + * + * Available options: + * + * * decorated: Sets the output decorated flag + * * verbosity: Sets the output verbosity flag + * * capture_stderr_separately: Make output of stdOut and stdErr separately available + */ + private function initOutput(array $options) + { + $this->captureStreamsIndependently = array_key_exists('capture_stderr_separately', $options) && $options['capture_stderr_separately']; + if (!$this->captureStreamsIndependently) { + $this->output = new StreamOutput(fopen('php://memory', 'w', false)); + if (isset($options['decorated'])) { + $this->output->setDecorated($options['decorated']); + } + if (isset($options['verbosity'])) { + $this->output->setVerbosity($options['verbosity']); + } + } else { + $this->output = new ConsoleOutput( + isset($options['verbosity']) ? $options['verbosity'] : ConsoleOutput::VERBOSITY_NORMAL, + isset($options['decorated']) ? $options['decorated'] : null + ); + + $errorOutput = new StreamOutput(fopen('php://memory', 'w', false)); + $errorOutput->setFormatter($this->output->getFormatter()); + $errorOutput->setVerbosity($this->output->getVerbosity()); + $errorOutput->setDecorated($this->output->isDecorated()); + + $reflectedOutput = new \ReflectionObject($this->output); + $strErrProperty = $reflectedOutput->getProperty('stderr'); + $strErrProperty->setAccessible(true); + $strErrProperty->setValue($this->output, $errorOutput); + + $reflectedParent = $reflectedOutput->getParentClass(); + $streamProperty = $reflectedParent->getProperty('stream'); + $streamProperty->setAccessible(true); + $streamProperty->setValue($this->output, fopen('php://memory', 'w', false)); + } + } + + private static function createStream(array $inputs) + { + $stream = fopen('php://memory', 'r+', false); + + foreach ($inputs as $input) { + fwrite($stream, $input.PHP_EOL); + } + + rewind($stream); + + return $stream; + } +} diff --git a/vendor/symfony/console/Tests/ApplicationTest.php b/vendor/symfony/console/Tests/ApplicationTest.php new file mode 100644 index 00000000..2aaf9d7d --- /dev/null +++ b/vendor/symfony/console/Tests/ApplicationTest.php @@ -0,0 +1,1791 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\CommandLoader\FactoryCommandLoader; +use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass; +use Symfony\Component\Console\Event\ConsoleCommandEvent; +use Symfony\Component\Console\Event\ConsoleErrorEvent; +use Symfony\Component\Console\Event\ConsoleTerminateEvent; +use Symfony\Component\Console\Exception\CommandNotFoundException; +use Symfony\Component\Console\Exception\NamespaceNotFoundException; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Helper\HelperSet; +use Symfony\Component\Console\Input\ArgvInput; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\Console\Output\Output; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Output\StreamOutput; +use Symfony\Component\Console\Tester\ApplicationTester; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\EventDispatcher\EventDispatcher; + +class ApplicationTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = realpath(__DIR__.'/Fixtures/'); + require_once self::$fixturesPath.'/FooCommand.php'; + require_once self::$fixturesPath.'/FooOptCommand.php'; + require_once self::$fixturesPath.'/Foo1Command.php'; + require_once self::$fixturesPath.'/Foo2Command.php'; + require_once self::$fixturesPath.'/Foo3Command.php'; + require_once self::$fixturesPath.'/Foo4Command.php'; + require_once self::$fixturesPath.'/Foo5Command.php'; + require_once self::$fixturesPath.'/FooSameCaseUppercaseCommand.php'; + require_once self::$fixturesPath.'/FooSameCaseLowercaseCommand.php'; + require_once self::$fixturesPath.'/FoobarCommand.php'; + require_once self::$fixturesPath.'/BarBucCommand.php'; + require_once self::$fixturesPath.'/FooSubnamespaced1Command.php'; + require_once self::$fixturesPath.'/FooSubnamespaced2Command.php'; + require_once self::$fixturesPath.'/FooWithoutAliasCommand.php'; + require_once self::$fixturesPath.'/TestTiti.php'; + require_once self::$fixturesPath.'/TestToto.php'; + } + + protected function normalizeLineBreaks($text) + { + return str_replace(PHP_EOL, "\n", $text); + } + + /** + * Replaces the dynamic placeholders of the command help text with a static version. + * The placeholder %command.full_name% includes the script path that is not predictable + * and can not be tested against. + */ + protected function ensureStaticCommandHelp(Application $application) + { + foreach ($application->all() as $command) { + $command->setHelp(str_replace('%command.full_name%', 'app/console %command.name%', $command->getHelp())); + } + } + + public function testConstructor() + { + $application = new Application('foo', 'bar'); + $this->assertEquals('foo', $application->getName(), '__construct() takes the application name as its first argument'); + $this->assertEquals('bar', $application->getVersion(), '__construct() takes the application version as its second argument'); + $this->assertEquals(['help', 'list'], array_keys($application->all()), '__construct() registered the help and list commands by default'); + } + + public function testSetGetName() + { + $application = new Application(); + $application->setName('foo'); + $this->assertEquals('foo', $application->getName(), '->setName() sets the name of the application'); + } + + public function testSetGetVersion() + { + $application = new Application(); + $application->setVersion('bar'); + $this->assertEquals('bar', $application->getVersion(), '->setVersion() sets the version of the application'); + } + + public function testGetLongVersion() + { + $application = new Application('foo', 'bar'); + $this->assertEquals('foo bar', $application->getLongVersion(), '->getLongVersion() returns the long version of the application'); + } + + public function testHelp() + { + $application = new Application(); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_gethelp.txt', $this->normalizeLineBreaks($application->getHelp()), '->getHelp() returns a help message'); + } + + public function testAll() + { + $application = new Application(); + $commands = $application->all(); + $this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands'); + + $application->add(new \FooCommand()); + $commands = $application->all('foo'); + $this->assertCount(1, $commands, '->all() takes a namespace as its first argument'); + } + + public function testAllWithCommandLoader() + { + $application = new Application(); + $commands = $application->all(); + $this->assertInstanceOf('Symfony\\Component\\Console\\Command\\HelpCommand', $commands['help'], '->all() returns the registered commands'); + + $application->add(new \FooCommand()); + $commands = $application->all('foo'); + $this->assertCount(1, $commands, '->all() takes a namespace as its first argument'); + + $application->setCommandLoader(new FactoryCommandLoader([ + 'foo:bar1' => function () { return new \Foo1Command(); }, + ])); + $commands = $application->all('foo'); + $this->assertCount(2, $commands, '->all() takes a namespace as its first argument'); + $this->assertInstanceOf(\FooCommand::class, $commands['foo:bar'], '->all() returns the registered commands'); + $this->assertInstanceOf(\Foo1Command::class, $commands['foo:bar1'], '->all() returns the registered commands'); + } + + public function testRegister() + { + $application = new Application(); + $command = $application->register('foo'); + $this->assertEquals('foo', $command->getName(), '->register() registers a new command'); + } + + public function testAdd() + { + $application = new Application(); + $application->add($foo = new \FooCommand()); + $commands = $application->all(); + $this->assertEquals($foo, $commands['foo:bar'], '->add() registers a command'); + + $application = new Application(); + $application->addCommands([$foo = new \FooCommand(), $foo1 = new \Foo1Command()]); + $commands = $application->all(); + $this->assertEquals([$foo, $foo1], [$commands['foo:bar'], $commands['foo:bar1']], '->addCommands() registers an array of commands'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Command class "Foo5Command" is not correctly initialized. You probably forgot to call the parent constructor. + */ + public function testAddCommandWithEmptyConstructor() + { + $application = new Application(); + $application->add(new \Foo5Command()); + } + + public function testHasGet() + { + $application = new Application(); + $this->assertTrue($application->has('list'), '->has() returns true if a named command is registered'); + $this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered'); + + $application->add($foo = new \FooCommand()); + $this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered'); + $this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name'); + $this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias'); + + $application = new Application(); + $application->add($foo = new \FooCommand()); + // simulate --help + $r = new \ReflectionObject($application); + $p = $r->getProperty('wantHelps'); + $p->setAccessible(true); + $p->setValue($application, true); + $command = $application->get('foo:bar'); + $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $command, '->get() returns the help command if --help is provided as the input'); + } + + public function testHasGetWithCommandLoader() + { + $application = new Application(); + $this->assertTrue($application->has('list'), '->has() returns true if a named command is registered'); + $this->assertFalse($application->has('afoobar'), '->has() returns false if a named command is not registered'); + + $application->add($foo = new \FooCommand()); + $this->assertTrue($application->has('afoobar'), '->has() returns true if an alias is registered'); + $this->assertEquals($foo, $application->get('foo:bar'), '->get() returns a command by name'); + $this->assertEquals($foo, $application->get('afoobar'), '->get() returns a command by alias'); + + $application->setCommandLoader(new FactoryCommandLoader([ + 'foo:bar1' => function () { return new \Foo1Command(); }, + ])); + + $this->assertTrue($application->has('afoobar'), '->has() returns true if an instance is registered for an alias even with command loader'); + $this->assertEquals($foo, $application->get('foo:bar'), '->get() returns an instance by name even with command loader'); + $this->assertEquals($foo, $application->get('afoobar'), '->get() returns an instance by alias even with command loader'); + $this->assertTrue($application->has('foo:bar1'), '->has() returns true for commands registered in the loader'); + $this->assertInstanceOf(\Foo1Command::class, $foo1 = $application->get('foo:bar1'), '->get() returns a command by name from the command loader'); + $this->assertTrue($application->has('afoobar1'), '->has() returns true for commands registered in the loader'); + $this->assertEquals($foo1, $application->get('afoobar1'), '->get() returns a command by name from the command loader'); + } + + public function testSilentHelp() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $tester = new ApplicationTester($application); + $tester->run(['-h' => true, '-q' => true], ['decorated' => false]); + + $this->assertEmpty($tester->getDisplay(true)); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage The command "foofoo" does not exist. + */ + public function testGetInvalidCommand() + { + $application = new Application(); + $application->get('foofoo'); + } + + public function testGetNamespaces() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $this->assertEquals(['foo'], $application->getNamespaces(), '->getNamespaces() returns an array of unique used namespaces'); + } + + public function testFindNamespace() + { + $application = new Application(); + $application->add(new \FooCommand()); + $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists'); + $this->assertEquals('foo', $application->findNamespace('f'), '->findNamespace() finds a namespace given an abbreviation'); + $application->add(new \Foo2Command()); + $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns the given namespace if it exists'); + } + + public function testFindNamespaceWithSubnamespaces() + { + $application = new Application(); + $application->add(new \FooSubnamespaced1Command()); + $application->add(new \FooSubnamespaced2Command()); + $this->assertEquals('foo', $application->findNamespace('foo'), '->findNamespace() returns commands even if the commands are only contained in subnamespaces'); + } + + public function testFindAmbiguousNamespace() + { + $application = new Application(); + $application->add(new \BarBucCommand()); + $application->add(new \FooCommand()); + $application->add(new \Foo2Command()); + + $expectedMsg = "The namespace \"f\" is ambiguous.\nDid you mean one of these?\n foo\n foo1"; + + if (method_exists($this, 'expectException')) { + $this->expectException(NamespaceNotFoundException::class); + $this->expectExceptionMessage($expectedMsg); + } else { + $this->setExpectedException(NamespaceNotFoundException::class, $expectedMsg); + } + + $application->findNamespace('f'); + } + + public function testFindNonAmbiguous() + { + $application = new Application(); + $application->add(new \TestTiti()); + $application->add(new \TestToto()); + $this->assertEquals('test-toto', $application->find('test')->getName()); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\NamespaceNotFoundException + * @expectedExceptionMessage There are no commands defined in the "bar" namespace. + */ + public function testFindInvalidNamespace() + { + $application = new Application(); + $application->findNamespace('bar'); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage Command "foo1" is not defined + */ + public function testFindUniqueNameButNamespaceName() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + $application->find($commandName = 'foo1'); + } + + public function testFind() + { + $application = new Application(); + $application->add(new \FooCommand()); + + $this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists'); + $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists'); + $this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists'); + $this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist'); + $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias'); + } + + public function testFindCaseSensitiveFirst() + { + $application = new Application(); + $application->add(new \FooSameCaseUppercaseCommand()); + $application->add(new \FooSameCaseLowercaseCommand()); + + $this->assertInstanceOf('FooSameCaseUppercaseCommand', $application->find('f:B'), '->find() returns a command if the abbreviation is the correct case'); + $this->assertInstanceOf('FooSameCaseUppercaseCommand', $application->find('f:BAR'), '->find() returns a command if the abbreviation is the correct case'); + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:b'), '->find() returns a command if the abbreviation is the correct case'); + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation is the correct case'); + } + + public function testFindCaseInsensitiveAsFallback() + { + $application = new Application(); + $application->add(new \FooSameCaseLowercaseCommand()); + + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:b'), '->find() returns a command if the abbreviation is the correct case'); + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('f:B'), '->find() will fallback to case insensitivity'); + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('FoO:BaR'), '->find() will fallback to case insensitivity'); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage Command "FoO:BaR" is ambiguous + */ + public function testFindCaseInsensitiveSuggestions() + { + $application = new Application(); + $application->add(new \FooSameCaseLowercaseCommand()); + $application->add(new \FooSameCaseUppercaseCommand()); + + $this->assertInstanceOf('FooSameCaseLowercaseCommand', $application->find('FoO:BaR'), '->find() will find two suggestions with case insensitivity'); + } + + public function testFindWithCommandLoader() + { + $application = new Application(); + $application->setCommandLoader(new FactoryCommandLoader([ + 'foo:bar' => $f = function () { return new \FooCommand(); }, + ])); + + $this->assertInstanceOf('FooCommand', $application->find('foo:bar'), '->find() returns a command if its name exists'); + $this->assertInstanceOf('Symfony\Component\Console\Command\HelpCommand', $application->find('h'), '->find() returns a command if its name exists'); + $this->assertInstanceOf('FooCommand', $application->find('f:bar'), '->find() returns a command if the abbreviation for the namespace exists'); + $this->assertInstanceOf('FooCommand', $application->find('f:b'), '->find() returns a command if the abbreviation for the namespace and the command name exist'); + $this->assertInstanceOf('FooCommand', $application->find('a'), '->find() returns a command if the abbreviation exists for an alias'); + } + + /** + * @dataProvider provideAmbiguousAbbreviations + */ + public function testFindWithAmbiguousAbbreviations($abbreviation, $expectedExceptionMessage) + { + if (method_exists($this, 'expectException')) { + $this->expectException('Symfony\Component\Console\Exception\CommandNotFoundException'); + $this->expectExceptionMessage($expectedExceptionMessage); + } else { + $this->setExpectedException('Symfony\Component\Console\Exception\CommandNotFoundException', $expectedExceptionMessage); + } + + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + $application->find($abbreviation); + } + + public function provideAmbiguousAbbreviations() + { + return [ + ['f', 'Command "f" is not defined.'], + [ + 'a', + "Command \"a\" is ambiguous.\nDid you mean one of these?\n". + " afoobar The foo:bar command\n". + " afoobar1 The foo:bar1 command\n". + ' afoobar2 The foo1:bar command', + ], + [ + 'foo:b', + "Command \"foo:b\" is ambiguous.\nDid you mean one of these?\n". + " foo:bar The foo:bar command\n". + " foo:bar1 The foo:bar1 command\n". + ' foo1:bar The foo1:bar command', + ], + ]; + } + + public function testFindCommandEqualNamespace() + { + $application = new Application(); + $application->add(new \Foo3Command()); + $application->add(new \Foo4Command()); + + $this->assertInstanceOf('Foo3Command', $application->find('foo3:bar'), '->find() returns the good command even if a namespace has same name'); + $this->assertInstanceOf('Foo4Command', $application->find('foo3:bar:toh'), '->find() returns a command even if its namespace equals another command name'); + } + + public function testFindCommandWithAmbiguousNamespacesButUniqueName() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \FoobarCommand()); + + $this->assertInstanceOf('FoobarCommand', $application->find('f:f')); + } + + public function testFindCommandWithMissingNamespace() + { + $application = new Application(); + $application->add(new \Foo4Command()); + + $this->assertInstanceOf('Foo4Command', $application->find('f::t')); + } + + /** + * @dataProvider provideInvalidCommandNamesSingle + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage Did you mean this + */ + public function testFindAlternativeExceptionMessageSingle($name) + { + $application = new Application(); + $application->add(new \Foo3Command()); + $application->find($name); + } + + public function testDontRunAlternativeNamespaceName() + { + $application = new Application(); + $application->add(new \Foo1Command()); + $application->setAutoExit(false); + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foos:bar1'], ['decorated' => false]); + $this->assertSame(' + + There are no commands defined in the "foos" namespace. + + Did you mean this? + foo + + +', $tester->getDisplay(true)); + } + + public function testCanRunAlternativeCommandName() + { + $application = new Application(); + $application->add(new \FooWithoutAliasCommand()); + $application->setAutoExit(false); + $tester = new ApplicationTester($application); + $tester->setInputs(['y']); + $tester->run(['command' => 'foos'], ['decorated' => false]); + $display = trim($tester->getDisplay(true)); + $this->assertContains('Command "foos" is not defined', $display); + $this->assertContains('Do you want to run "foo" instead? (yes/no) [no]:', $display); + $this->assertContains('called', $display); + } + + public function testDontRunAlternativeCommandName() + { + $application = new Application(); + $application->add(new \FooWithoutAliasCommand()); + $application->setAutoExit(false); + $tester = new ApplicationTester($application); + $tester->setInputs(['n']); + $exitCode = $tester->run(['command' => 'foos'], ['decorated' => false]); + $this->assertSame(1, $exitCode); + $display = trim($tester->getDisplay(true)); + $this->assertContains('Command "foos" is not defined', $display); + $this->assertContains('Do you want to run "foo" instead? (yes/no) [no]:', $display); + } + + public function provideInvalidCommandNamesSingle() + { + return [ + ['foo3:barr'], + ['fooo3:bar'], + ]; + } + + public function testFindAlternativeExceptionMessageMultiple() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + // Command + plural + try { + $application->find('foo:baR'); + $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/foo1:bar/', $e->getMessage()); + $this->assertRegExp('/foo:bar/', $e->getMessage()); + } + + // Namespace + plural + try { + $application->find('foo2:bar'); + $this->fail('->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/Did you mean one of these/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/foo1/', $e->getMessage()); + } + + $application->add(new \Foo3Command()); + $application->add(new \Foo4Command()); + + // Subnamespace + plural + try { + $a = $application->find('foo3:'); + $this->fail('->find() should throw an Symfony\Component\Console\Exception\CommandNotFoundException if a command is ambiguous because of a subnamespace, with alternatives'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e); + $this->assertRegExp('/foo3:bar/', $e->getMessage()); + $this->assertRegExp('/foo3:bar:toh/', $e->getMessage()); + } + } + + public function testFindAlternativeCommands() + { + $application = new Application(); + + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + + try { + $application->find($commandName = 'Unknown command'); + $this->fail('->find() throws a CommandNotFoundException if command does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist'); + $this->assertSame([], $e->getAlternatives()); + $this->assertEquals(sprintf('Command "%s" is not defined.', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without alternatives'); + } + + // Test if "bar1" command throw a "CommandNotFoundException" and does not contain + // "foo:bar" as alternative because "bar1" is too far from "foo:bar" + try { + $application->find($commandName = 'bar1'); + $this->fail('->find() throws a CommandNotFoundException if command does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command does not exist'); + $this->assertSame(['afoobar1', 'foo:bar1'], $e->getAlternatives()); + $this->assertRegExp(sprintf('/Command "%s" is not defined./', $commandName), $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternatives'); + $this->assertRegExp('/afoobar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "afoobar1"'); + $this->assertRegExp('/foo:bar1/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, with alternative : "foo:bar1"'); + $this->assertNotRegExp('/foo:bar(?>!1)/', $e->getMessage(), '->find() throws a CommandNotFoundException if command does not exist, without "foo:bar" alternative'); + } + } + + public function testFindAlternativeCommandsWithAnAlias() + { + $fooCommand = new \FooCommand(); + $fooCommand->setAliases(['foo2']); + + $application = new Application(); + $application->add($fooCommand); + + $result = $application->find('foo'); + + $this->assertSame($fooCommand, $result); + } + + public function testFindAlternativeNamespace() + { + $application = new Application(); + + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + $application->add(new \Foo3Command()); + + try { + $application->find('Unknown-namespace:Unknown-command'); + $this->fail('->find() throws a CommandNotFoundException if namespace does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if namespace does not exist'); + $this->assertSame([], $e->getAlternatives()); + $this->assertEquals('There are no commands defined in the "Unknown-namespace" namespace.', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, without alternatives'); + } + + try { + $application->find('foo2:command'); + $this->fail('->find() throws a CommandNotFoundException if namespace does not exist'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\NamespaceNotFoundException', $e, '->find() throws a NamespaceNotFoundException if namespace does not exist'); + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, 'NamespaceNotFoundException extends from CommandNotFoundException'); + $this->assertCount(3, $e->getAlternatives()); + $this->assertContains('foo', $e->getAlternatives()); + $this->assertContains('foo1', $e->getAlternatives()); + $this->assertContains('foo3', $e->getAlternatives()); + $this->assertRegExp('/There are no commands defined in the "foo2" namespace./', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative'); + $this->assertRegExp('/foo/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo"'); + $this->assertRegExp('/foo1/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo1"'); + $this->assertRegExp('/foo3/', $e->getMessage(), '->find() throws a CommandNotFoundException if namespace does not exist, with alternative : "foo3"'); + } + } + + public function testFindAlternativesOutput() + { + $application = new Application(); + + $application->add(new \FooCommand()); + $application->add(new \Foo1Command()); + $application->add(new \Foo2Command()); + $application->add(new \Foo3Command()); + + $expectedAlternatives = [ + 'afoobar', + 'afoobar1', + 'afoobar2', + 'foo1:bar', + 'foo3:bar', + 'foo:bar', + 'foo:bar1', + ]; + + try { + $application->find('foo'); + $this->fail('->find() throws a CommandNotFoundException if command is not defined'); + } catch (\Exception $e) { + $this->assertInstanceOf('Symfony\Component\Console\Exception\CommandNotFoundException', $e, '->find() throws a CommandNotFoundException if command is not defined'); + $this->assertSame($expectedAlternatives, $e->getAlternatives()); + + $this->assertRegExp('/Command "foo" is not defined\..*Did you mean one of these\?.*/Ums', $e->getMessage()); + } + } + + public function testFindNamespaceDoesNotFailOnDeepSimilarNamespaces() + { + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(['getNamespaces'])->getMock(); + $application->expects($this->once()) + ->method('getNamespaces') + ->will($this->returnValue(['foo:sublong', 'bar:sub'])); + + $this->assertEquals('foo:sublong', $application->findNamespace('f:sub')); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + * @expectedExceptionMessage Command "foo::bar" is not defined. + */ + public function testFindWithDoubleColonInNameThrowsException() + { + $application = new Application(); + $application->add(new \FooCommand()); + $application->add(new \Foo4Command()); + $application->find('foo::bar'); + } + + public function testSetCatchExceptions() + { + $application = new Application(); + $application->setAutoExit(false); + putenv('COLUMNS=120'); + $tester = new ApplicationTester($application); + + $application->setCatchExceptions(true); + $this->assertTrue($application->areExceptionsCaught()); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getDisplay(true), '->setCatchExceptions() sets the catch exception flag'); + + $tester->run(['command' => 'foo'], ['decorated' => false, 'capture_stderr_separately' => true]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getErrorOutput(true), '->setCatchExceptions() sets the catch exception flag'); + $this->assertSame('', $tester->getDisplay(true)); + + $application->setCatchExceptions(false); + try { + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->fail('->setCatchExceptions() sets the catch exception flag'); + } catch (\Exception $e) { + $this->assertInstanceOf('\Exception', $e, '->setCatchExceptions() sets the catch exception flag'); + $this->assertEquals('Command "foo" is not defined.', $e->getMessage(), '->setCatchExceptions() sets the catch exception flag'); + } + } + + public function testAutoExitSetting() + { + $application = new Application(); + $this->assertTrue($application->isAutoExitEnabled()); + + $application->setAutoExit(false); + $this->assertFalse($application->isAutoExitEnabled()); + } + + public function testRenderException() + { + $application = new Application(); + $application->setAutoExit(false); + putenv('COLUMNS=120'); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false, 'capture_stderr_separately' => true]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception1.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exception'); + + $tester->run(['command' => 'foo'], ['decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE, 'capture_stderr_separately' => true]); + $this->assertContains('Exception trace', $tester->getErrorOutput(), '->renderException() renders a pretty exception with a stack trace when verbosity is verbose'); + + $tester->run(['command' => 'list', '--foo' => true], ['decorated' => false, 'capture_stderr_separately' => true]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception2.txt', $tester->getErrorOutput(true), '->renderException() renders the command synopsis when an exception occurs in the context of a command'); + + $application->add(new \Foo3Command()); + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo3:bar'], ['decorated' => false, 'capture_stderr_separately' => true]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $tester->run(['command' => 'foo3:bar'], ['decorated' => false, 'verbosity' => Output::VERBOSITY_VERBOSE]); + $this->assertRegExp('/\[Exception\]\s*First exception/', $tester->getDisplay(), '->renderException() renders a pretty exception without code exception when code exception is default and verbosity is verbose'); + $this->assertRegExp('/\[Exception\]\s*Second exception/', $tester->getDisplay(), '->renderException() renders a pretty exception without code exception when code exception is 0 and verbosity is verbose'); + $this->assertRegExp('/\[Exception \(404\)\]\s*Third exception/', $tester->getDisplay(), '->renderException() renders a pretty exception with code exception when code exception is 404 and verbosity is verbose'); + + $tester->run(['command' => 'foo3:bar'], ['decorated' => true]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getDisplay(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $tester->run(['command' => 'foo3:bar'], ['decorated' => true, 'capture_stderr_separately' => true]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception3decorated.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $application = new Application(); + $application->setAutoExit(false); + putenv('COLUMNS=32'); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false, 'capture_stderr_separately' => true]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_renderexception4.txt', $tester->getErrorOutput(true), '->renderException() wraps messages when they are bigger than the terminal'); + putenv('COLUMNS=120'); + } + + public function testRenderExceptionWithDoubleWidthCharacters() + { + $application = new Application(); + $application->setAutoExit(false); + putenv('COLUMNS=120'); + $application->register('foo')->setCode(function () { + throw new \Exception('エラーメッセージ'); + }); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false, 'capture_stderr_separately' => true]); + $this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_renderexception_doublewidth1.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $tester->run(['command' => 'foo'], ['decorated' => true, 'capture_stderr_separately' => true]); + $this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_renderexception_doublewidth1decorated.txt', $tester->getErrorOutput(true), '->renderException() renders a pretty exceptions with previous exceptions'); + + $application = new Application(); + $application->setAutoExit(false); + putenv('COLUMNS=32'); + $application->register('foo')->setCode(function () { + throw new \Exception('コマンドの実行中にエラーが発生しました。'); + }); + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo'], ['decorated' => false, 'capture_stderr_separately' => true]); + $this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_renderexception_doublewidth2.txt', $tester->getErrorOutput(true), '->renderException() wraps messages when they are bigger than the terminal'); + putenv('COLUMNS=120'); + } + + public function testRenderExceptionEscapesLines() + { + $application = new Application(); + $application->setAutoExit(false); + putenv('COLUMNS=22'); + $application->register('foo')->setCode(function () { + throw new \Exception('dont break here !'); + }); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_renderexception_escapeslines.txt', $tester->getDisplay(true), '->renderException() escapes lines containing formatting'); + putenv('COLUMNS=120'); + } + + public function testRenderExceptionLineBreaks() + { + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(['getTerminalWidth'])->getMock(); + $application->setAutoExit(false); + $application->expects($this->any()) + ->method('getTerminalWidth') + ->will($this->returnValue(120)); + $application->register('foo')->setCode(function () { + throw new \InvalidArgumentException("\n\nline 1 with extra spaces \nline 2\n\nline 4\n"); + }); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertStringMatchesFormatFile(self::$fixturesPath.'/application_renderexception_linebreaks.txt', $tester->getDisplay(true), '->renderException() keep multiple line breaks'); + } + + public function testRenderAnonymousException() + { + $application = new Application(); + $application->setAutoExit(false); + $application->register('foo')->setCode(function () { + throw new class('') extends \InvalidArgumentException { + }; + }); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertContains('[InvalidArgumentException@anonymous]', $tester->getDisplay(true)); + + $application = new Application(); + $application->setAutoExit(false); + $application->register('foo')->setCode(function () { + throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { + }))); + }); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertContains('Dummy type "@anonymous" is invalid.', $tester->getDisplay(true)); + } + + public function testRenderExceptionStackTraceContainsRootException() + { + $application = new Application(); + $application->setAutoExit(false); + $application->register('foo')->setCode(function () { + throw new class('') extends \InvalidArgumentException { + }; + }); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertContains('[InvalidArgumentException@anonymous]', $tester->getDisplay(true)); + + $application = new Application(); + $application->setAutoExit(false); + $application->register('foo')->setCode(function () { + throw new \InvalidArgumentException(sprintf('Dummy type "%s" is invalid.', \get_class(new class() { + }))); + }); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo'], ['decorated' => false]); + $this->assertContains('Dummy type "@anonymous" is invalid.', $tester->getDisplay(true)); + } + + public function testRun() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->add($command = new \Foo1Command()); + $_SERVER['argv'] = ['cli.php', 'foo:bar1']; + + ob_start(); + $application->run(); + ob_end_clean(); + + $this->assertInstanceOf('Symfony\Component\Console\Input\ArgvInput', $command->input, '->run() creates an ArgvInput by default if none is given'); + $this->assertInstanceOf('Symfony\Component\Console\Output\ConsoleOutput', $command->output, '->run() creates a ConsoleOutput by default if none is given'); + + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $this->ensureStaticCommandHelp($application); + $tester = new ApplicationTester($application); + + $tester->run([], ['decorated' => false]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run1.txt', $tester->getDisplay(true), '->run() runs the list command if no argument is passed'); + + $tester->run(['--help' => true], ['decorated' => false]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if --help is passed'); + + $tester->run(['-h' => true], ['decorated' => false]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run2.txt', $tester->getDisplay(true), '->run() runs the help command if -h is passed'); + + $tester->run(['command' => 'list', '--help' => true], ['decorated' => false]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if --help is passed'); + + $tester->run(['command' => 'list', '-h' => true], ['decorated' => false]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run3.txt', $tester->getDisplay(true), '->run() displays the help if -h is passed'); + + $tester->run(['--ansi' => true]); + $this->assertTrue($tester->getOutput()->isDecorated(), '->run() forces color output if --ansi is passed'); + + $tester->run(['--no-ansi' => true]); + $this->assertFalse($tester->getOutput()->isDecorated(), '->run() forces color output to be disabled if --no-ansi is passed'); + + $tester->run(['--version' => true], ['decorated' => false]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if --version is passed'); + + $tester->run(['-V' => true], ['decorated' => false]); + $this->assertStringEqualsFile(self::$fixturesPath.'/application_run4.txt', $tester->getDisplay(true), '->run() displays the program version if -v is passed'); + + $tester->run(['command' => 'list', '--quiet' => true]); + $this->assertSame('', $tester->getDisplay(), '->run() removes all output if --quiet is passed'); + $this->assertFalse($tester->getInput()->isInteractive(), '->run() sets off the interactive mode if --quiet is passed'); + + $tester->run(['command' => 'list', '-q' => true]); + $this->assertSame('', $tester->getDisplay(), '->run() removes all output if -q is passed'); + $this->assertFalse($tester->getInput()->isInteractive(), '->run() sets off the interactive mode if -q is passed'); + + $tester->run(['command' => 'list', '--verbose' => true]); + $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose is passed'); + + $tester->run(['command' => 'list', '--verbose' => 1]); + $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if --verbose=1 is passed'); + + $tester->run(['command' => 'list', '--verbose' => 2]); + $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to very verbose if --verbose=2 is passed'); + + $tester->run(['command' => 'list', '--verbose' => 3]); + $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to debug if --verbose=3 is passed'); + + $tester->run(['command' => 'list', '--verbose' => 4]); + $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if unknown --verbose level is passed'); + + $tester->run(['command' => 'list', '-v' => true]); + $this->assertSame(Output::VERBOSITY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed'); + + $tester->run(['command' => 'list', '-vv' => true]); + $this->assertSame(Output::VERBOSITY_VERY_VERBOSE, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed'); + + $tester->run(['command' => 'list', '-vvv' => true]); + $this->assertSame(Output::VERBOSITY_DEBUG, $tester->getOutput()->getVerbosity(), '->run() sets the output to verbose if -v is passed'); + + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->add(new \FooCommand()); + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'foo:bar', '--no-interaction' => true], ['decorated' => false]); + $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if --no-interaction is passed'); + + $tester->run(['command' => 'foo:bar', '-n' => true], ['decorated' => false]); + $this->assertSame('called'.PHP_EOL, $tester->getDisplay(), '->run() does not call interact() if -n is passed'); + } + + /** + * Issue #9285. + * + * If the "verbose" option is just before an argument in ArgvInput, + * an argument value should not be treated as verbosity value. + * This test will fail with "Not enough arguments." if broken + */ + public function testVerboseValueNotBreakArguments() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->add(new \FooCommand()); + + $output = new StreamOutput(fopen('php://memory', 'w', false)); + + $input = new ArgvInput(['cli.php', '-v', 'foo:bar']); + $application->run($input, $output); + + $this->addToAssertionCount(1); + + $input = new ArgvInput(['cli.php', '--verbose', 'foo:bar']); + $application->run($input, $output); + + $this->addToAssertionCount(1); + } + + public function testRunReturnsIntegerExitCode() + { + $exception = new \Exception('', 4); + + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(['doRun'])->getMock(); + $application->setAutoExit(false); + $application->expects($this->once()) + ->method('doRun') + ->willThrowException($exception); + + $exitCode = $application->run(new ArrayInput([]), new NullOutput()); + + $this->assertSame(4, $exitCode, '->run() returns integer exit code extracted from raised exception'); + } + + public function testRunDispatchesIntegerExitCode() + { + $passedRightValue = false; + + // We can assume here that some other test asserts that the event is dispatched at all + $dispatcher = new EventDispatcher(); + $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use (&$passedRightValue) { + $passedRightValue = (4 === $event->getExitCode()); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('test')->setCode(function (InputInterface $input, OutputInterface $output) { + throw new \Exception('', 4); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'test']); + + $this->assertTrue($passedRightValue, '-> exit code 4 was passed in the console.terminate event'); + } + + public function testRunReturnsExitCodeOneForExceptionCodeZero() + { + $exception = new \Exception('', 0); + + $application = $this->getMockBuilder('Symfony\Component\Console\Application')->setMethods(['doRun'])->getMock(); + $application->setAutoExit(false); + $application->expects($this->once()) + ->method('doRun') + ->willThrowException($exception); + + $exitCode = $application->run(new ArrayInput([]), new NullOutput()); + + $this->assertSame(1, $exitCode, '->run() returns exit code 1 when exception code is 0'); + } + + public function testRunDispatchesExitCodeOneForExceptionCodeZero() + { + $passedRightValue = false; + + // We can assume here that some other test asserts that the event is dispatched at all + $dispatcher = new EventDispatcher(); + $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use (&$passedRightValue) { + $passedRightValue = (1 === $event->getExitCode()); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('test')->setCode(function (InputInterface $input, OutputInterface $output) { + throw new \Exception(); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'test']); + + $this->assertTrue($passedRightValue, '-> exit code 1 was passed in the console.terminate event'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage An option with shortcut "e" already exists. + */ + public function testAddingOptionWithDuplicateShortcut() + { + $dispatcher = new EventDispatcher(); + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->setDispatcher($dispatcher); + + $application->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'Environment')); + + $application + ->register('foo') + ->setAliases(['f']) + ->setDefinition([new InputOption('survey', 'e', InputOption::VALUE_REQUIRED, 'My option with a shortcut.')]) + ->setCode(function (InputInterface $input, OutputInterface $output) {}) + ; + + $input = new ArrayInput(['command' => 'foo']); + $output = new NullOutput(); + + $application->run($input, $output); + } + + /** + * @expectedException \LogicException + * @dataProvider getAddingAlreadySetDefinitionElementData + */ + public function testAddingAlreadySetDefinitionElementData($def) + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application + ->register('foo') + ->setDefinition([$def]) + ->setCode(function (InputInterface $input, OutputInterface $output) {}) + ; + + $input = new ArrayInput(['command' => 'foo']); + $output = new NullOutput(); + $application->run($input, $output); + } + + public function getAddingAlreadySetDefinitionElementData() + { + return [ + [new InputArgument('command', InputArgument::REQUIRED)], + [new InputOption('quiet', '', InputOption::VALUE_NONE)], + [new InputOption('query', 'q', InputOption::VALUE_NONE)], + ]; + } + + public function testGetDefaultHelperSetReturnsDefaultValues() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $helperSet = $application->getHelperSet(); + + $this->assertTrue($helperSet->has('formatter')); + } + + public function testAddingSingleHelperSetOverwritesDefaultValues() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->setHelperSet(new HelperSet([new FormatterHelper()])); + + $helperSet = $application->getHelperSet(); + + $this->assertTrue($helperSet->has('formatter')); + + // no other default helper set should be returned + $this->assertFalse($helperSet->has('dialog')); + $this->assertFalse($helperSet->has('progress')); + } + + public function testOverwritingDefaultHelperSetOverwritesDefaultValues() + { + $application = new CustomApplication(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->setHelperSet(new HelperSet([new FormatterHelper()])); + + $helperSet = $application->getHelperSet(); + + $this->assertTrue($helperSet->has('formatter')); + + // no other default helper set should be returned + $this->assertFalse($helperSet->has('dialog')); + $this->assertFalse($helperSet->has('progress')); + } + + public function testGetDefaultInputDefinitionReturnsDefaultValues() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $inputDefinition = $application->getDefinition(); + + $this->assertTrue($inputDefinition->hasArgument('command')); + + $this->assertTrue($inputDefinition->hasOption('help')); + $this->assertTrue($inputDefinition->hasOption('quiet')); + $this->assertTrue($inputDefinition->hasOption('verbose')); + $this->assertTrue($inputDefinition->hasOption('version')); + $this->assertTrue($inputDefinition->hasOption('ansi')); + $this->assertTrue($inputDefinition->hasOption('no-ansi')); + $this->assertTrue($inputDefinition->hasOption('no-interaction')); + } + + public function testOverwritingDefaultInputDefinitionOverwritesDefaultValues() + { + $application = new CustomApplication(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $inputDefinition = $application->getDefinition(); + + // check whether the default arguments and options are not returned any more + $this->assertFalse($inputDefinition->hasArgument('command')); + + $this->assertFalse($inputDefinition->hasOption('help')); + $this->assertFalse($inputDefinition->hasOption('quiet')); + $this->assertFalse($inputDefinition->hasOption('verbose')); + $this->assertFalse($inputDefinition->hasOption('version')); + $this->assertFalse($inputDefinition->hasOption('ansi')); + $this->assertFalse($inputDefinition->hasOption('no-ansi')); + $this->assertFalse($inputDefinition->hasOption('no-interaction')); + + $this->assertTrue($inputDefinition->hasOption('custom')); + } + + public function testSettingCustomInputDefinitionOverwritesDefaultValues() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->setDefinition(new InputDefinition([new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.')])); + + $inputDefinition = $application->getDefinition(); + + // check whether the default arguments and options are not returned any more + $this->assertFalse($inputDefinition->hasArgument('command')); + + $this->assertFalse($inputDefinition->hasOption('help')); + $this->assertFalse($inputDefinition->hasOption('quiet')); + $this->assertFalse($inputDefinition->hasOption('verbose')); + $this->assertFalse($inputDefinition->hasOption('version')); + $this->assertFalse($inputDefinition->hasOption('ansi')); + $this->assertFalse($inputDefinition->hasOption('no-ansi')); + $this->assertFalse($inputDefinition->hasOption('no-interaction')); + + $this->assertTrue($inputDefinition->hasOption('custom')); + } + + public function testRunWithDispatcher() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setDispatcher($this->getDispatcher()); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo']); + $this->assertEquals('before.foo.after.'.PHP_EOL, $tester->getDisplay()); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage error + */ + public function testRunWithExceptionAndDispatcher() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + throw new \RuntimeException('foo'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo']); + } + + public function testRunDispatchesAllEventsWithException() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + + throw new \RuntimeException('foo'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo']); + $this->assertContains('before.foo.error.after.', $tester->getDisplay()); + } + + public function testRunDispatchesAllEventsWithExceptionInListener() + { + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.command', function () { + throw new \RuntimeException('foo'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo']); + $this->assertContains('before.error.after.', $tester->getDisplay()); + } + + public function testRunWithError() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dym.'); + + throw new \Error('dymerr'); + }); + + $tester = new ApplicationTester($application); + + try { + $tester->run(['command' => 'dym']); + $this->fail('Error expected.'); + } catch (\Error $e) { + $this->assertSame('dymerr', $e->getMessage()); + } + } + + public function testRunAllowsErrorListenersToSilenceTheException() + { + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) { + $event->getOutput()->write('silenced.'); + + $event->setExitCode(0); + }); + + $dispatcher->addListener('console.command', function () { + throw new \RuntimeException('foo'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo']); + $this->assertContains('before.error.silenced.after.', $tester->getDisplay()); + $this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $tester->getStatusCode()); + } + + public function testConsoleErrorEventIsTriggeredOnCommandNotFound() + { + $dispatcher = new EventDispatcher(); + $dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) { + $this->assertNull($event->getCommand()); + $this->assertInstanceOf(CommandNotFoundException::class, $event->getError()); + $event->getOutput()->write('silenced command not found'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'unknown']); + $this->assertContains('silenced command not found', $tester->getDisplay()); + $this->assertEquals(1, $tester->getStatusCode()); + } + + public function testErrorIsRethrownIfNotHandledByConsoleErrorEvent() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + $application->setDispatcher(new EventDispatcher()); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + new \UnknownClass(); + }); + + $tester = new ApplicationTester($application); + + try { + $tester->run(['command' => 'dym']); + $this->fail('->run() should rethrow PHP errors if not handled via ConsoleErrorEvent.'); + } catch (\Error $e) { + $this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found'); + } + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage error + */ + public function testRunWithErrorAndDispatcher() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dym.'); + + throw new \Error('dymerr'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'dym']); + $this->assertContains('before.dym.error.after.', $tester->getDisplay(), 'The PHP Error did not dispached events'); + } + + public function testRunDispatchesAllEventsWithError() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dym.'); + + throw new \Error('dymerr'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'dym']); + $this->assertContains('before.dym.error.after.', $tester->getDisplay(), 'The PHP Error did not dispached events'); + } + + public function testRunWithErrorFailingStatusCode() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher()); + $application->setAutoExit(false); + + $application->register('dus')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('dus.'); + + throw new \Error('duserr'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'dus']); + $this->assertSame(1, $tester->getStatusCode(), 'Status code should be 1'); + } + + public function testRunWithDispatcherSkippingCommand() + { + $application = new Application(); + $application->setDispatcher($this->getDispatcher(true)); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $exitCode = $tester->run(['command' => 'foo']); + $this->assertContains('before.after.', $tester->getDisplay()); + $this->assertEquals(ConsoleCommandEvent::RETURN_CODE_DISABLED, $exitCode); + } + + public function testRunWithDispatcherAccessingInputOptions() + { + $noInteractionValue = null; + $quietValue = null; + + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$noInteractionValue, &$quietValue) { + $input = $event->getInput(); + + $noInteractionValue = $input->getOption('no-interaction'); + $quietValue = $input->getOption('quiet'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo', '--no-interaction' => true]); + + $this->assertTrue($noInteractionValue); + $this->assertFalse($quietValue); + } + + public function testRunWithDispatcherAddingInputOptions() + { + $extraValue = null; + + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use (&$extraValue) { + $definition = $event->getCommand()->getDefinition(); + $input = $event->getInput(); + + $definition->addOption(new InputOption('extra', null, InputOption::VALUE_REQUIRED)); + $input->bind($definition); + + $extraValue = $input->getOption('extra'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo', '--extra' => 'some test value']); + + $this->assertEquals('some test value', $extraValue); + } + + public function testSetRunCustomDefaultCommand() + { + $command = new \FooCommand(); + + $application = new Application(); + $application->setAutoExit(false); + $application->add($command); + $application->setDefaultCommand($command->getName()); + + $tester = new ApplicationTester($application); + $tester->run([], ['interactive' => false]); + $this->assertEquals('called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command'); + + $application = new CustomDefaultCommandApplication(); + $application->setAutoExit(false); + + $tester = new ApplicationTester($application); + $tester->run([], ['interactive' => false]); + + $this->assertEquals('called'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command'); + } + + public function testSetRunCustomDefaultCommandWithOption() + { + $command = new \FooOptCommand(); + + $application = new Application(); + $application->setAutoExit(false); + $application->add($command); + $application->setDefaultCommand($command->getName()); + + $tester = new ApplicationTester($application); + $tester->run(['--fooopt' => 'opt'], ['interactive' => false]); + + $this->assertEquals('called'.PHP_EOL.'opt'.PHP_EOL, $tester->getDisplay(), 'Application runs the default set command if different from \'list\' command'); + } + + public function testSetRunCustomSingleCommand() + { + $command = new \FooCommand(); + + $application = new Application(); + $application->setAutoExit(false); + $application->add($command); + $application->setDefaultCommand($command->getName(), true); + + $tester = new ApplicationTester($application); + + $tester->run([]); + $this->assertContains('called', $tester->getDisplay()); + + $tester->run(['--help' => true]); + $this->assertContains('The foo:bar command', $tester->getDisplay()); + } + + /** + * @requires function posix_isatty + */ + public function testCanCheckIfTerminalIsInteractive() + { + $application = new CustomDefaultCommandApplication(); + $application->setAutoExit(false); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'help']); + + $this->assertFalse($tester->getInput()->hasParameterOption(['--no-interaction', '-n'])); + + $inputStream = $tester->getInput()->getStream(); + $this->assertEquals($tester->getInput()->isInteractive(), @posix_isatty($inputStream)); + } + + public function testRunLazyCommandService() + { + $container = new ContainerBuilder(); + $container->addCompilerPass(new AddConsoleCommandPass()); + $container + ->register('lazy-command', LazyCommand::class) + ->addTag('console.command', ['command' => 'lazy:command']) + ->addTag('console.command', ['command' => 'lazy:alias']) + ->addTag('console.command', ['command' => 'lazy:alias2']); + $container->compile(); + + $application = new Application(); + $application->setCommandLoader($container->get('console.command_loader')); + $application->setAutoExit(false); + + $tester = new ApplicationTester($application); + + $tester->run(['command' => 'lazy:command']); + $this->assertSame("lazy-command called\n", $tester->getDisplay(true)); + + $tester->run(['command' => 'lazy:alias']); + $this->assertSame("lazy-command called\n", $tester->getDisplay(true)); + + $tester->run(['command' => 'lazy:alias2']); + $this->assertSame("lazy-command called\n", $tester->getDisplay(true)); + + $command = $application->get('lazy:command'); + $this->assertSame(['lazy:alias', 'lazy:alias2'], $command->getAliases()); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\CommandNotFoundException + */ + public function testGetDisabledLazyCommand() + { + $application = new Application(); + $application->setCommandLoader(new FactoryCommandLoader(['disabled' => function () { return new DisabledCommand(); }])); + $application->get('disabled'); + } + + public function testHasReturnsFalseForDisabledLazyCommand() + { + $application = new Application(); + $application->setCommandLoader(new FactoryCommandLoader(['disabled' => function () { return new DisabledCommand(); }])); + $this->assertFalse($application->has('disabled')); + } + + public function testAllExcludesDisabledLazyCommand() + { + $application = new Application(); + $application->setCommandLoader(new FactoryCommandLoader(['disabled' => function () { return new DisabledCommand(); }])); + $this->assertArrayNotHasKey('disabled', $application->all()); + } + + protected function getDispatcher($skipCommand = false) + { + $dispatcher = new EventDispatcher(); + $dispatcher->addListener('console.command', function (ConsoleCommandEvent $event) use ($skipCommand) { + $event->getOutput()->write('before.'); + + if ($skipCommand) { + $event->disableCommand(); + } + }); + $dispatcher->addListener('console.terminate', function (ConsoleTerminateEvent $event) use ($skipCommand) { + $event->getOutput()->writeln('after.'); + + if (!$skipCommand) { + $event->setExitCode(ConsoleCommandEvent::RETURN_CODE_DISABLED); + } + }); + $dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) { + $event->getOutput()->write('error.'); + + $event->setError(new \LogicException('error.', $event->getExitCode(), $event->getError())); + }); + + return $dispatcher; + } + + public function testErrorIsRethrownIfNotHandledByConsoleErrorEventWithCatchingEnabled() + { + $application = new Application(); + $application->setAutoExit(false); + $application->setDispatcher(new EventDispatcher()); + + $application->register('dym')->setCode(function (InputInterface $input, OutputInterface $output) { + new \UnknownClass(); + }); + + $tester = new ApplicationTester($application); + + try { + $tester->run(['command' => 'dym']); + $this->fail('->run() should rethrow PHP errors if not handled via ConsoleErrorEvent.'); + } catch (\Error $e) { + $this->assertSame($e->getMessage(), 'Class \'UnknownClass\' not found'); + } + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage foo + */ + public function testThrowingErrorListener() + { + $dispatcher = $this->getDispatcher(); + $dispatcher->addListener('console.error', function (ConsoleErrorEvent $event) { + throw new \RuntimeException('foo'); + }); + + $dispatcher->addListener('console.command', function () { + throw new \RuntimeException('bar'); + }); + + $application = new Application(); + $application->setDispatcher($dispatcher); + $application->setAutoExit(false); + $application->setCatchExceptions(false); + + $application->register('foo')->setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('foo.'); + }); + + $tester = new ApplicationTester($application); + $tester->run(['command' => 'foo']); + } + + protected function tearDown() + { + putenv('SHELL_VERBOSITY'); + unset($_ENV['SHELL_VERBOSITY']); + unset($_SERVER['SHELL_VERBOSITY']); + } +} + +class CustomApplication extends Application +{ + /** + * Overwrites the default input definition. + * + * @return InputDefinition An InputDefinition instance + */ + protected function getDefaultInputDefinition() + { + return new InputDefinition([new InputOption('--custom', '-c', InputOption::VALUE_NONE, 'Set the custom input definition.')]); + } + + /** + * Gets the default helper set with the helpers that should always be available. + * + * @return HelperSet A HelperSet instance + */ + protected function getDefaultHelperSet() + { + return new HelperSet([new FormatterHelper()]); + } +} + +class CustomDefaultCommandApplication extends Application +{ + /** + * Overwrites the constructor in order to set a different default command. + */ + public function __construct() + { + parent::__construct(); + + $command = new \FooCommand(); + $this->add($command); + $this->setDefaultCommand($command->getName()); + } +} + +class LazyCommand extends Command +{ + public function execute(InputInterface $input, OutputInterface $output) + { + $output->writeln('lazy-command called'); + } +} + +class DisabledCommand extends Command +{ + public function isEnabled() + { + return false; + } +} diff --git a/vendor/symfony/console/Tests/Command/CommandTest.php b/vendor/symfony/console/Tests/Command/CommandTest.php new file mode 100644 index 00000000..512feca7 --- /dev/null +++ b/vendor/symfony/console/Tests/Command/CommandTest.php @@ -0,0 +1,436 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\FormatterHelper; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputDefinition; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\StringInput; +use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Tester\CommandTester; + +class CommandTest extends TestCase +{ + protected static $fixturesPath; + + public static function setUpBeforeClass() + { + self::$fixturesPath = __DIR__.'/../Fixtures/'; + require_once self::$fixturesPath.'/TestCommand.php'; + } + + public function testConstructor() + { + $command = new Command('foo:bar'); + $this->assertEquals('foo:bar', $command->getName(), '__construct() takes the command name as its first argument'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage The command defined in "Symfony\Component\Console\Command\Command" cannot have an empty name. + */ + public function testCommandNameCannotBeEmpty() + { + (new Application())->add(new Command()); + } + + public function testSetApplication() + { + $application = new Application(); + $command = new \TestCommand(); + $command->setApplication($application); + $this->assertEquals($application, $command->getApplication(), '->setApplication() sets the current application'); + $this->assertEquals($application->getHelperSet(), $command->getHelperSet()); + } + + public function testSetApplicationNull() + { + $command = new \TestCommand(); + $command->setApplication(null); + $this->assertNull($command->getHelperSet()); + } + + public function testSetGetDefinition() + { + $command = new \TestCommand(); + $ret = $command->setDefinition($definition = new InputDefinition()); + $this->assertEquals($command, $ret, '->setDefinition() implements a fluent interface'); + $this->assertEquals($definition, $command->getDefinition(), '->setDefinition() sets the current InputDefinition instance'); + $command->setDefinition([new InputArgument('foo'), new InputOption('bar')]); + $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument'); + $this->assertTrue($command->getDefinition()->hasOption('bar'), '->setDefinition() also takes an array of InputArguments and InputOptions as an argument'); + $command->setDefinition(new InputDefinition()); + } + + public function testAddArgument() + { + $command = new \TestCommand(); + $ret = $command->addArgument('foo'); + $this->assertEquals($command, $ret, '->addArgument() implements a fluent interface'); + $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->addArgument() adds an argument to the command'); + } + + public function testAddOption() + { + $command = new \TestCommand(); + $ret = $command->addOption('foo'); + $this->assertEquals($command, $ret, '->addOption() implements a fluent interface'); + $this->assertTrue($command->getDefinition()->hasOption('foo'), '->addOption() adds an option to the command'); + } + + public function testSetHidden() + { + $command = new \TestCommand(); + $command->setHidden(true); + $this->assertTrue($command->isHidden()); + } + + public function testGetNamespaceGetNameSetName() + { + $command = new \TestCommand(); + $this->assertEquals('namespace:name', $command->getName(), '->getName() returns the command name'); + $command->setName('foo'); + $this->assertEquals('foo', $command->getName(), '->setName() sets the command name'); + + $ret = $command->setName('foobar:bar'); + $this->assertEquals($command, $ret, '->setName() implements a fluent interface'); + $this->assertEquals('foobar:bar', $command->getName(), '->setName() sets the command name'); + } + + /** + * @dataProvider provideInvalidCommandNames + */ + public function testInvalidCommandNames($name) + { + if (method_exists($this, 'expectException')) { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage(sprintf('Command name "%s" is invalid.', $name)); + } else { + $this->setExpectedException('InvalidArgumentException', sprintf('Command name "%s" is invalid.', $name)); + } + + $command = new \TestCommand(); + $command->setName($name); + } + + public function provideInvalidCommandNames() + { + return [ + [''], + ['foo:'], + ]; + } + + public function testGetSetDescription() + { + $command = new \TestCommand(); + $this->assertEquals('description', $command->getDescription(), '->getDescription() returns the description'); + $ret = $command->setDescription('description1'); + $this->assertEquals($command, $ret, '->setDescription() implements a fluent interface'); + $this->assertEquals('description1', $command->getDescription(), '->setDescription() sets the description'); + } + + public function testGetSetHelp() + { + $command = new \TestCommand(); + $this->assertEquals('help', $command->getHelp(), '->getHelp() returns the help'); + $ret = $command->setHelp('help1'); + $this->assertEquals($command, $ret, '->setHelp() implements a fluent interface'); + $this->assertEquals('help1', $command->getHelp(), '->setHelp() sets the help'); + $command->setHelp(''); + $this->assertEquals('', $command->getHelp(), '->getHelp() does not fall back to the description'); + } + + public function testGetProcessedHelp() + { + $command = new \TestCommand(); + $command->setHelp('The %command.name% command does... Example: php %command.full_name%.'); + $this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly'); + $this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name%'); + + $command = new \TestCommand(); + $command->setHelp(''); + $this->assertContains('description', $command->getProcessedHelp(), '->getProcessedHelp() falls back to the description'); + + $command = new \TestCommand(); + $command->setHelp('The %command.name% command does... Example: php %command.full_name%.'); + $application = new Application(); + $application->add($command); + $application->setDefaultCommand('namespace:name', true); + $this->assertContains('The namespace:name command does...', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.name% correctly in single command applications'); + $this->assertNotContains('%command.full_name%', $command->getProcessedHelp(), '->getProcessedHelp() replaces %command.full_name% in single command applications'); + } + + public function testGetSetAliases() + { + $command = new \TestCommand(); + $this->assertEquals(['name'], $command->getAliases(), '->getAliases() returns the aliases'); + $ret = $command->setAliases(['name1']); + $this->assertEquals($command, $ret, '->setAliases() implements a fluent interface'); + $this->assertEquals(['name1'], $command->getAliases(), '->setAliases() sets the aliases'); + } + + public function testSetAliasesNull() + { + $command = new \TestCommand(); + $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('InvalidArgumentException'); + $command->setAliases(null); + } + + public function testGetSynopsis() + { + $command = new \TestCommand(); + $command->addOption('foo'); + $command->addArgument('bar'); + $this->assertEquals('namespace:name [--foo] [--] []', $command->getSynopsis(), '->getSynopsis() returns the synopsis'); + } + + public function testAddGetUsages() + { + $command = new \TestCommand(); + $command->addUsage('foo1'); + $command->addUsage('foo2'); + $this->assertContains('namespace:name foo1', $command->getUsages()); + $this->assertContains('namespace:name foo2', $command->getUsages()); + } + + public function testGetHelper() + { + $application = new Application(); + $command = new \TestCommand(); + $command->setApplication($application); + $formatterHelper = new FormatterHelper(); + $this->assertEquals($formatterHelper->getName(), $command->getHelper('formatter')->getName(), '->getHelper() returns the correct helper'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot retrieve helper "formatter" because there is no HelperSet defined. + */ + public function testGetHelperWithoutHelperSet() + { + $command = new \TestCommand(); + $command->getHelper('formatter'); + } + + public function testMergeApplicationDefinition() + { + $application1 = new Application(); + $application1->getDefinition()->addArguments([new InputArgument('foo')]); + $application1->getDefinition()->addOptions([new InputOption('bar')]); + $command = new \TestCommand(); + $command->setApplication($application1); + $command->setDefinition($definition = new InputDefinition([new InputArgument('bar'), new InputOption('foo')])); + + $r = new \ReflectionObject($command); + $m = $r->getMethod('mergeApplicationDefinition'); + $m->setAccessible(true); + $m->invoke($command); + $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition() merges the application arguments and the command arguments'); + $this->assertTrue($command->getDefinition()->hasArgument('bar'), '->mergeApplicationDefinition() merges the application arguments and the command arguments'); + $this->assertTrue($command->getDefinition()->hasOption('foo'), '->mergeApplicationDefinition() merges the application options and the command options'); + $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition() merges the application options and the command options'); + + $m->invoke($command); + $this->assertEquals(3, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments and options'); + } + + public function testMergeApplicationDefinitionWithoutArgsThenWithArgsAddsArgs() + { + $application1 = new Application(); + $application1->getDefinition()->addArguments([new InputArgument('foo')]); + $application1->getDefinition()->addOptions([new InputOption('bar')]); + $command = new \TestCommand(); + $command->setApplication($application1); + $command->setDefinition($definition = new InputDefinition([])); + + $r = new \ReflectionObject($command); + $m = $r->getMethod('mergeApplicationDefinition'); + $m->setAccessible(true); + $m->invoke($command, false); + $this->assertTrue($command->getDefinition()->hasOption('bar'), '->mergeApplicationDefinition(false) merges the application and the command options'); + $this->assertFalse($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(false) does not merge the application arguments'); + + $m->invoke($command, true); + $this->assertTrue($command->getDefinition()->hasArgument('foo'), '->mergeApplicationDefinition(true) merges the application arguments and the command arguments'); + + $m->invoke($command); + $this->assertEquals(2, $command->getDefinition()->getArgumentCount(), '->mergeApplicationDefinition() does not try to merge twice the application arguments'); + } + + public function testRunInteractive() + { + $tester = new CommandTester(new \TestCommand()); + + $tester->execute([], ['interactive' => true]); + + $this->assertEquals('interact called'.PHP_EOL.'execute called'.PHP_EOL, $tester->getDisplay(), '->run() calls the interact() method if the input is interactive'); + } + + public function testRunNonInteractive() + { + $tester = new CommandTester(new \TestCommand()); + + $tester->execute([], ['interactive' => false]); + + $this->assertEquals('execute called'.PHP_EOL, $tester->getDisplay(), '->run() does not call the interact() method if the input is not interactive'); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage You must override the execute() method in the concrete command class. + */ + public function testExecuteMethodNeedsToBeOverridden() + { + $command = new Command('foo'); + $command->run(new StringInput(''), new NullOutput()); + } + + /** + * @expectedException \Symfony\Component\Console\Exception\InvalidOptionException + * @expectedExceptionMessage The "--bar" option does not exist. + */ + public function testRunWithInvalidOption() + { + $command = new \TestCommand(); + $tester = new CommandTester($command); + $tester->execute(['--bar' => true]); + } + + public function testRunReturnsIntegerExitCode() + { + $command = new \TestCommand(); + $exitCode = $command->run(new StringInput(''), new NullOutput()); + $this->assertSame(0, $exitCode, '->run() returns integer exit code (treats null as 0)'); + + $command = $this->getMockBuilder('TestCommand')->setMethods(['execute'])->getMock(); + $command->expects($this->once()) + ->method('execute') + ->will($this->returnValue('2.3')); + $exitCode = $command->run(new StringInput(''), new NullOutput()); + $this->assertSame(2, $exitCode, '->run() returns integer exit code (casts numeric to int)'); + } + + public function testRunWithApplication() + { + $command = new \TestCommand(); + $command->setApplication(new Application()); + $exitCode = $command->run(new StringInput(''), new NullOutput()); + + $this->assertSame(0, $exitCode, '->run() returns an integer exit code'); + } + + public function testRunReturnsAlwaysInteger() + { + $command = new \TestCommand(); + + $this->assertSame(0, $command->run(new StringInput(''), new NullOutput())); + } + + public function testRunWithProcessTitle() + { + $command = new \TestCommand(); + $command->setApplication(new Application()); + $command->setProcessTitle('foo'); + $this->assertSame(0, $command->run(new StringInput(''), new NullOutput())); + if (\function_exists('cli_set_process_title')) { + if (null === @cli_get_process_title() && 'Darwin' === PHP_OS) { + $this->markTestSkipped('Running "cli_get_process_title" as an unprivileged user is not supported on MacOS.'); + } + $this->assertEquals('foo', cli_get_process_title()); + } + } + + public function testSetCode() + { + $command = new \TestCommand(); + $ret = $command->setCode(function (InputInterface $input, OutputInterface $output) { + $output->writeln('from the code...'); + }); + $this->assertEquals($command, $ret, '->setCode() implements a fluent interface'); + $tester = new CommandTester($command); + $tester->execute([]); + $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay()); + } + + public function getSetCodeBindToClosureTests() + { + return [ + [true, 'not bound to the command'], + [false, 'bound to the command'], + ]; + } + + /** + * @dataProvider getSetCodeBindToClosureTests + */ + public function testSetCodeBindToClosure($previouslyBound, $expected) + { + $code = createClosure(); + if ($previouslyBound) { + $code = $code->bindTo($this); + } + + $command = new \TestCommand(); + $command->setCode($code); + $tester = new CommandTester($command); + $tester->execute([]); + $this->assertEquals('interact called'.PHP_EOL.$expected.PHP_EOL, $tester->getDisplay()); + } + + public function testSetCodeWithStaticClosure() + { + $command = new \TestCommand(); + $command->setCode(self::createClosure()); + $tester = new CommandTester($command); + $tester->execute([]); + + $this->assertEquals('interact called'.PHP_EOL.'bound'.PHP_EOL, $tester->getDisplay()); + } + + private static function createClosure() + { + return function (InputInterface $input, OutputInterface $output) { + $output->writeln(isset($this) ? 'bound' : 'not bound'); + }; + } + + public function testSetCodeWithNonClosureCallable() + { + $command = new \TestCommand(); + $ret = $command->setCode([$this, 'callableMethodCommand']); + $this->assertEquals($command, $ret, '->setCode() implements a fluent interface'); + $tester = new CommandTester($command); + $tester->execute([]); + $this->assertEquals('interact called'.PHP_EOL.'from the code...'.PHP_EOL, $tester->getDisplay()); + } + + public function callableMethodCommand(InputInterface $input, OutputInterface $output) + { + $output->writeln('from the code...'); + } +} + +// In order to get an unbound closure, we should create it outside a class +// scope. +function createClosure() +{ + return function (InputInterface $input, OutputInterface $output) { + $output->writeln($this instanceof Command ? 'bound to the command' : 'not bound to the command'); + }; +} diff --git a/vendor/symfony/console/Tests/Command/HelpCommandTest.php b/vendor/symfony/console/Tests/Command/HelpCommandTest.php new file mode 100644 index 00000000..ce9d8d4f --- /dev/null +++ b/vendor/symfony/console/Tests/Command/HelpCommandTest.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Command\HelpCommand; +use Symfony\Component\Console\Command\ListCommand; +use Symfony\Component\Console\Tester\CommandTester; + +class HelpCommandTest extends TestCase +{ + public function testExecuteForCommandAlias() + { + $command = new HelpCommand(); + $command->setApplication(new Application()); + $commandTester = new CommandTester($command); + $commandTester->execute(['command_name' => 'li'], ['decorated' => false]); + $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias'); + $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias'); + $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command alias'); + } + + public function testExecuteForCommand() + { + $command = new HelpCommand(); + $commandTester = new CommandTester($command); + $command->setCommand(new ListCommand()); + $commandTester->execute([], ['decorated' => false]); + $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + } + + public function testExecuteForCommandWithXmlOption() + { + $command = new HelpCommand(); + $commandTester = new CommandTester($command); + $command->setCommand(new ListCommand()); + $commandTester->execute(['--format' => 'xml']); + $this->assertContains('getDisplay(), '->execute() returns an XML help text if --xml is passed'); + } + + public function testExecuteForApplicationCommand() + { + $application = new Application(); + $commandTester = new CommandTester($application->get('help')); + $commandTester->execute(['command_name' => 'list']); + $this->assertContains('list [options] [--] []', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('format=FORMAT', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('raw', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + } + + public function testExecuteForApplicationCommandWithXmlOption() + { + $application = new Application(); + $commandTester = new CommandTester($application->get('help')); + $commandTester->execute(['command_name' => 'list', '--format' => 'xml']); + $this->assertContains('list [--raw] [--format FORMAT] [--] [<namespace>]', $commandTester->getDisplay(), '->execute() returns a text help for the given command'); + $this->assertContains('getDisplay(), '->execute() returns an XML help text if --format=xml is passed'); + } +} diff --git a/vendor/symfony/console/Tests/Command/ListCommandTest.php b/vendor/symfony/console/Tests/Command/ListCommandTest.php new file mode 100644 index 00000000..57687d4c --- /dev/null +++ b/vendor/symfony/console/Tests/Command/ListCommandTest.php @@ -0,0 +1,113 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Console\Tests\Command; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\Console\Application; +use Symfony\Component\Console\Tester\CommandTester; + +class ListCommandTest extends TestCase +{ + public function testExecuteListsCommands() + { + $application = new Application(); + $commandTester = new CommandTester($command = $application->get('list')); + $commandTester->execute(['command' => $command->getName()], ['decorated' => false]); + + $this->assertRegExp('/help\s{2,}Displays help for a command/', $commandTester->getDisplay(), '->execute() returns a list of available commands'); + } + + public function testExecuteListsCommandsWithXmlOption() + { + $application = new Application(); + $commandTester = new CommandTester($command = $application->get('list')); + $commandTester->execute(['command' => $command->getName(), '--format' => 'xml']); + $this->assertRegExp('/