From 39e43b6ccadd46846f50d161ffaeae7eeae107e4 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 11 Dec 2023 13:06:54 +0000 Subject: [PATCH] Updated Rector to commit dc9573d9bd60ec966db626be91c13cc6a5c4bbef https://github.com/rectorphp/rector-src/commit/dc9573d9bd60ec966db626be91c13cc6a5c4bbef [Php55] Make StringClassNameToClassConstantRector configurable to keep first pre-backslash string configurable (#5354) --- .../StringClassNameToClassConstantRector.php | 23 +- src/Application/VersionResolver.php | 4 +- vendor/composer/autoload_classmap.php | 1 + vendor/composer/autoload_static.php | 1 + vendor/composer/installed.json | 22 +- vendor/composer/installed.php | 2 +- vendor/nikic/php-parser/grammar/README.md | 30 - .../nikic/php-parser/grammar/parser.template | 106 -- vendor/nikic/php-parser/grammar/php5.y | 1046 -------------- vendor/nikic/php-parser/grammar/php7.y | 1245 ----------------- vendor/nikic/php-parser/grammar/phpyLang.php | 128 -- .../php-parser/grammar/rebuildParsers.php | 64 - .../nikic/php-parser/grammar/tokens.template | 17 - vendor/nikic/php-parser/grammar/tokens.y | 115 -- .../PhpParser/NodeVisitor/NameResolver.php | 3 + .../php-parser/lib/PhpParser/Parser/Php5.php | 2 + .../php-parser/lib/PhpParser/Parser/Php7.php | 2 + .../lib/PhpParser/ParserFactory.php | 29 + .../src/GeneratedConfig.php | 2 +- .../config/set/downgrade-php82.php | 3 +- ...tandaloneNullTrueFalseReturnTypeRector.php | 159 +++ 21 files changed, 235 insertions(+), 2769 deletions(-) delete mode 100644 vendor/nikic/php-parser/grammar/README.md delete mode 100644 vendor/nikic/php-parser/grammar/parser.template delete mode 100644 vendor/nikic/php-parser/grammar/php5.y delete mode 100644 vendor/nikic/php-parser/grammar/php7.y delete mode 100644 vendor/nikic/php-parser/grammar/phpyLang.php delete mode 100644 vendor/nikic/php-parser/grammar/rebuildParsers.php delete mode 100644 vendor/nikic/php-parser/grammar/tokens.template delete mode 100644 vendor/nikic/php-parser/grammar/tokens.y create mode 100644 vendor/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/FunctionLike/DowngradeStandaloneNullTrueFalseReturnTypeRector.php diff --git a/rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php b/rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php index dcd7e1cefca..73568a547a2 100644 --- a/rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php +++ b/rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php @@ -4,6 +4,7 @@ declare (strict_types=1); namespace Rector\Php55\Rector\String_; use PhpParser\Node; +use PhpParser\Node\Expr\BinaryOp\Concat; use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name\FullyQualified; @@ -38,6 +39,14 @@ final class StringClassNameToClassConstantRector extends AbstractRector implemen * @var string[] */ private $classesToSkip = []; + /** + * @var bool + */ + private $shouldKeepPreslash = \false; + /** + * @var string + */ + public const SHOULD_KEEP_PRE_SLASH = 'should_keep_pre_slash'; public function __construct(ReflectionProvider $reflectionProvider) { $this->reflectionProvider = $reflectionProvider; @@ -70,7 +79,7 @@ class SomeClass } } CODE_SAMPLE -, ['ClassName', 'AnotherClassName'])]); +, ['ClassName', 'AnotherClassName', \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::SHOULD_KEEP_PRE_SLASH => \false])]); } /** * @return array> @@ -81,7 +90,7 @@ CODE_SAMPLE } /** * @param String_|FuncCall|ClassConst $node - * @return \PhpParser\Node\Expr\ClassConstFetch|null|int + * @return \PhpParser\Node\Expr\BinaryOp\Concat|\PhpParser\Node\Expr\ClassConstFetch|null|int */ public function refactor(Node $node) { @@ -115,6 +124,12 @@ CODE_SAMPLE return null; } $fullyQualified = new FullyQualified($classLikeName); + if ($this->shouldKeepPreslash && $classLikeName !== $node->value) { + $preSlashCount = \strlen($node->value) - \strlen($classLikeName); + $preSlash = \str_repeat('\\', $preSlashCount); + $string = new String_($preSlash); + return new Concat($string, new ClassConstFetch($fullyQualified, 'class')); + } return new ClassConstFetch($fullyQualified, 'class'); } /** @@ -122,6 +137,10 @@ CODE_SAMPLE */ public function configure(array $configuration) : void { + if (isset($configuration[self::SHOULD_KEEP_PRE_SLASH]) && \is_bool($configuration[self::SHOULD_KEEP_PRE_SLASH])) { + $this->shouldKeepPreslash = $configuration[self::SHOULD_KEEP_PRE_SLASH]; + unset($configuration[self::SHOULD_KEEP_PRE_SLASH]); + } Assert::allString($configuration); $this->classesToSkip = $configuration; } diff --git a/src/Application/VersionResolver.php b/src/Application/VersionResolver.php index 40dfee09c61..e246252819e 100644 --- a/src/Application/VersionResolver.php +++ b/src/Application/VersionResolver.php @@ -19,12 +19,12 @@ final class VersionResolver * @api * @var string */ - public const PACKAGE_VERSION = '68c42e7e843bfb9fde2b6516bb1bb76648d67045'; + public const PACKAGE_VERSION = 'dc9573d9bd60ec966db626be91c13cc6a5c4bbef'; /** * @api * @var string */ - public const RELEASE_DATE = '2023-12-10 17:31:56'; + public const RELEASE_DATE = '2023-12-11 14:04:32'; /** * @var int */ diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index ec726d74f34..abf710394ba 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -1500,6 +1500,7 @@ return array( 'Rector\\DowngradePhp81\\Rector\\Property\\DowngradeReadonlyPropertyRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp81/Rector/Property/DowngradeReadonlyPropertyRector.php', 'Rector\\DowngradePhp81\\Rector\\StmtsAwareInterface\\DowngradeSetAccessibleReflectionPropertyRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp81/Rector/StmtsAwareInterface/DowngradeSetAccessibleReflectionPropertyRector.php', 'Rector\\DowngradePhp82\\Rector\\Class_\\DowngradeReadonlyClassRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/Class_/DowngradeReadonlyClassRector.php', + 'Rector\\DowngradePhp82\\Rector\\FunctionLike\\DowngradeStandaloneNullTrueFalseReturnTypeRector' => $vendorDir . '/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/FunctionLike/DowngradeStandaloneNullTrueFalseReturnTypeRector.php', 'Rector\\EarlyReturn\\NodeAnalyzer\\IfAndAnalyzer' => $baseDir . '/rules/EarlyReturn/NodeAnalyzer/IfAndAnalyzer.php', 'Rector\\EarlyReturn\\NodeAnalyzer\\SimpleScalarAnalyzer' => $baseDir . '/rules/EarlyReturn/NodeAnalyzer/SimpleScalarAnalyzer.php', 'Rector\\EarlyReturn\\NodeFactory\\InvertedIfFactory' => $baseDir . '/rules/EarlyReturn/NodeFactory/InvertedIfFactory.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index a00f5ff84d9..f3c3dd5cb7e 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -1718,6 +1718,7 @@ class ComposerStaticInita55c41c7fa52abd86138c6f32df1d185 'Rector\\DowngradePhp81\\Rector\\Property\\DowngradeReadonlyPropertyRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp81/Rector/Property/DowngradeReadonlyPropertyRector.php', 'Rector\\DowngradePhp81\\Rector\\StmtsAwareInterface\\DowngradeSetAccessibleReflectionPropertyRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp81/Rector/StmtsAwareInterface/DowngradeSetAccessibleReflectionPropertyRector.php', 'Rector\\DowngradePhp82\\Rector\\Class_\\DowngradeReadonlyClassRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/Class_/DowngradeReadonlyClassRector.php', + 'Rector\\DowngradePhp82\\Rector\\FunctionLike\\DowngradeStandaloneNullTrueFalseReturnTypeRector' => __DIR__ . '/..' . '/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/FunctionLike/DowngradeStandaloneNullTrueFalseReturnTypeRector.php', 'Rector\\EarlyReturn\\NodeAnalyzer\\IfAndAnalyzer' => __DIR__ . '/../..' . '/rules/EarlyReturn/NodeAnalyzer/IfAndAnalyzer.php', 'Rector\\EarlyReturn\\NodeAnalyzer\\SimpleScalarAnalyzer' => __DIR__ . '/../..' . '/rules/EarlyReturn/NodeAnalyzer/SimpleScalarAnalyzer.php', 'Rector\\EarlyReturn\\NodeFactory\\InvertedIfFactory' => __DIR__ . '/../..' . '/rules/EarlyReturn/NodeFactory/InvertedIfFactory.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index e29fbaa4edf..18d239a8972 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -701,17 +701,17 @@ }, { "name": "nikic\/php-parser", - "version": "v4.17.1", - "version_normalized": "4.17.1.0", + "version": "v4.18.0", + "version_normalized": "4.18.0.0", "source": { "type": "git", "url": "https:\/\/github.com\/nikic\/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" }, "dist": { "type": "zip", - "url": "https:\/\/api.github.com\/repos\/nikic\/PHP-Parser\/zipball\/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https:\/\/api.github.com\/repos\/nikic\/PHP-Parser\/zipball\/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", "shasum": "" }, "require": { @@ -722,7 +722,7 @@ "ircmaxell\/php-yacc": "^0.0.7", "phpunit\/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" }, - "time": "2023-08-13T19:53:39+00:00", + "time": "2023-12-10T21:03:43+00:00", "bin": [ "bin\/php-parse" ], @@ -771,7 +771,7 @@ ], "support": { "issues": "https:\/\/github.com\/nikic\/PHP-Parser\/issues", - "source": "https:\/\/github.com\/nikic\/PHP-Parser\/tree\/v4.17.1" + "source": "https:\/\/github.com\/nikic\/PHP-Parser\/tree\/v4.18.0" }, "install-path": "..\/nikic\/php-parser" }, @@ -1743,12 +1743,12 @@ "source": { "type": "git", "url": "https:\/\/github.com\/rectorphp\/rector-downgrade-php.git", - "reference": "a08ccadb84cad9df0cbf6a03007710975e8f7232" + "reference": "917085c6a2a99412440cd3143288d1a17abb5c44" }, "dist": { "type": "zip", - "url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-downgrade-php\/zipball\/a08ccadb84cad9df0cbf6a03007710975e8f7232", - "reference": "a08ccadb84cad9df0cbf6a03007710975e8f7232", + "url": "https:\/\/api.github.com\/repos\/rectorphp\/rector-downgrade-php\/zipball\/917085c6a2a99412440cd3143288d1a17abb5c44", + "reference": "917085c6a2a99412440cd3143288d1a17abb5c44", "shasum": "" }, "require": { @@ -1775,7 +1775,7 @@ "tomasvotruba\/unused-public": "^0.2", "tracy\/tracy": "^2.10" }, - "time": "2023-11-26T07:49:39+00:00", + "time": "2023-12-11T13:03:13+00:00", "default-branch": true, "type": "rector-extension", "extra": { diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 8f249aaa36a..06f9632bf8f 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -2,4 +2,4 @@ namespace RectorPrefix202312; -return array('root' => array('name' => 'rector/rector-src', 'pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => NULL, 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('clue/ndjson-react' => array('pretty_version' => 'v1.3.0', 'version' => '1.3.0.0', 'reference' => '392dc165fce93b5bb5c637b67e59619223c931b0', 'type' => 'library', 'install_path' => __DIR__ . '/../clue/ndjson-react', 'aliases' => array(), 'dev_requirement' => \false), 'composer/pcre' => array('pretty_version' => '3.1.1', 'version' => '3.1.1.0', 'reference' => '00104306927c7a0919b4ced2aaa6782c1e61a3c9', 'type' => 'library', 'install_path' => __DIR__ . '/./pcre', 'aliases' => array(), 'dev_requirement' => \false), 'composer/semver' => array('pretty_version' => '3.4.0', 'version' => '3.4.0.0', 'reference' => '35e8d0af4486141bc745f23a29cc2091eb624a32', 'type' => 'library', 'install_path' => __DIR__ . '/./semver', 'aliases' => array(), 'dev_requirement' => \false), 'composer/xdebug-handler' => array('pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'reference' => 'ced299686f41dce890debac69273b47ffe98a40c', 'type' => 'library', 'install_path' => __DIR__ . '/./xdebug-handler', 'aliases' => array(), 'dev_requirement' => \false), 'doctrine/inflector' => array('pretty_version' => '2.0.8', 'version' => '2.0.8.0', 'reference' => 'f9301a5b2fb1216b2b08f02ba04dc45423db6bff', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/inflector', 'aliases' => array(), 'dev_requirement' => \false), 'evenement/evenement' => array('pretty_version' => 'v3.0.2', 'version' => '3.0.2.0', 'reference' => '0a16b0d71ab13284339abb99d9d2bd813640efbc', 'type' => 'library', 'install_path' => __DIR__ . '/../evenement/evenement', 'aliases' => array(), 'dev_requirement' => \false), 'fidry/cpu-core-counter' => array('pretty_version' => '0.5.1', 'version' => '0.5.1.0', 'reference' => 'b58e5a3933e541dc286cc91fc4f3898bbc6f1623', 'type' => 'library', 'install_path' => __DIR__ . '/../fidry/cpu-core-counter', 'aliases' => array(), 'dev_requirement' => \false), 'illuminate/container' => array('pretty_version' => 'v10.35.0', 'version' => '10.35.0.0', 'reference' => 'ddc26273085fad3c471b2602ad820e0097ff7939', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/container', 'aliases' => array(), 'dev_requirement' => \false), 'illuminate/contracts' => array('pretty_version' => 'v10.35.0', 'version' => '10.35.0.0', 'reference' => 'f6bf37a272fda164f6c451407c99f820eb1eb95b', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/contracts', 'aliases' => array(), 'dev_requirement' => \false), 'nette/utils' => array('pretty_version' => 'v3.2.10', 'version' => '3.2.10.0', 'reference' => 'a4175c62652f2300c8017fb7e640f9ccb11648d2', 'type' => 'library', 'install_path' => __DIR__ . '/../nette/utils', 'aliases' => array(), 'dev_requirement' => \false), 'nikic/php-parser' => array('pretty_version' => 'v4.17.1', 'version' => '4.17.1.0', 'reference' => 'a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d', 'type' => 'library', 'install_path' => __DIR__ . '/../nikic/php-parser', 'aliases' => array(), 'dev_requirement' => \false), 'ondram/ci-detector' => array('pretty_version' => '4.1.0', 'version' => '4.1.0.0', 'reference' => '8a4b664e916df82ff26a44709942dfd593fa6f30', 'type' => 'library', 'install_path' => __DIR__ . '/../ondram/ci-detector', 'aliases' => array(), 'dev_requirement' => \false), 'phpstan/phpdoc-parser' => array('pretty_version' => '1.24.4', 'version' => '1.24.4.0', 'reference' => '6bd0c26f3786cd9b7c359675cb789e35a8e07496', 'type' => 'library', 'install_path' => __DIR__ . '/../phpstan/phpdoc-parser', 'aliases' => array(), 'dev_requirement' => \false), 'phpstan/phpstan' => array('dev_requirement' => \false, 'replaced' => array(0 => '^1.10.35')), 'psr/container' => array('pretty_version' => '2.0.2', 'version' => '2.0.2.0', 'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'dev_requirement' => \false), 'psr/container-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.1|2.0')), 'psr/log' => array('pretty_version' => '3.0.0', 'version' => '3.0.0.0', 'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => \false), 'psr/log-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0|2.0|3.0')), 'psr/simple-cache' => array('pretty_version' => '3.0.0', 'version' => '3.0.0.0', 'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/simple-cache', 'aliases' => array(), 'dev_requirement' => \false), 'react/cache' => array('pretty_version' => 'v1.2.0', 'version' => '1.2.0.0', 'reference' => 'd47c472b64aa5608225f47965a484b75c7817d5b', 'type' => 'library', 'install_path' => __DIR__ . '/../react/cache', 'aliases' => array(), 'dev_requirement' => \false), 'react/child-process' => array('pretty_version' => 'v0.6.5', 'version' => '0.6.5.0', 'reference' => 'e71eb1aa55f057c7a4a0d08d06b0b0a484bead43', 'type' => 'library', 'install_path' => __DIR__ . '/../react/child-process', 'aliases' => array(), 'dev_requirement' => \false), 'react/dns' => array('pretty_version' => 'v1.12.0', 'version' => '1.12.0.0', 'reference' => 'c134600642fa615b46b41237ef243daa65bb64ec', 'type' => 'library', 'install_path' => __DIR__ . '/../react/dns', 'aliases' => array(), 'dev_requirement' => \false), 'react/event-loop' => array('pretty_version' => 'v1.5.0', 'version' => '1.5.0.0', 'reference' => 'bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354', 'type' => 'library', 'install_path' => __DIR__ . '/../react/event-loop', 'aliases' => array(), 'dev_requirement' => \false), 'react/promise' => array('pretty_version' => 'v2.11.0', 'version' => '2.11.0.0', 'reference' => '1a8460931ea36dc5c76838fec5734d55c88c6831', 'type' => 'library', 'install_path' => __DIR__ . '/../react/promise', 'aliases' => array(), 'dev_requirement' => \false), 'react/socket' => array('pretty_version' => 'v1.14.0', 'version' => '1.14.0.0', 'reference' => '21591111d3ea62e31f2254280ca0656bc2b1bda6', 'type' => 'library', 'install_path' => __DIR__ . '/../react/socket', 'aliases' => array(), 'dev_requirement' => \false), 'react/stream' => array('pretty_version' => 'v1.3.0', 'version' => '1.3.0.0', 'reference' => '6fbc9672905c7d5a885f2da2fc696f65840f4a66', 'type' => 'library', 'install_path' => __DIR__ . '/../react/stream', 'aliases' => array(), 'dev_requirement' => \false), 'rector/extension-installer' => array('pretty_version' => '0.11.2', 'version' => '0.11.2.0', 'reference' => '05544e9b195863b8571ae2a3b903cbec7fa062e0', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../rector/extension-installer', 'aliases' => array(), 'dev_requirement' => \false), 'rector/rector' => array('dev_requirement' => \false, 'replaced' => array(0 => 'dev-main')), 'rector/rector-doctrine' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '9de7d58cb2b3438a469a609457a92dd37a310acc', 'type' => 'rector-extension', 'install_path' => __DIR__ . '/../rector/rector-doctrine', 'aliases' => array(0 => '9999999-dev'), 'dev_requirement' => \false), 'rector/rector-downgrade-php' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => 'a08ccadb84cad9df0cbf6a03007710975e8f7232', 'type' => 'rector-extension', 'install_path' => __DIR__ . '/../rector/rector-downgrade-php', 'aliases' => array(0 => '9999999-dev'), 'dev_requirement' => \false), 'rector/rector-phpunit' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '90e87f1032026d2c9c0195a826dc1126d2c40ecd', 'type' => 'rector-extension', 'install_path' => __DIR__ . '/../rector/rector-phpunit', 'aliases' => array(0 => '0.11.x-dev'), 'dev_requirement' => \false), 'rector/rector-src' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => NULL, 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'rector/rector-symfony' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '38014d41e7ccddfdc4c9c839931c68a57d931f63', 'type' => 'rector-extension', 'install_path' => __DIR__ . '/../rector/rector-symfony', 'aliases' => array(0 => '9999999-dev'), 'dev_requirement' => \false), 'sebastian/diff' => array('pretty_version' => '5.0.3', 'version' => '5.0.3.0', 'reference' => '912dc2fbe3e3c1e7873313cc801b100b6c68c87b', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/diff', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/console' => array('pretty_version' => 'v6.4.1', 'version' => '6.4.1.0', 'reference' => 'a550a7c99daeedef3f9d23fb82e3531525ff11fd', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/deprecation-contracts' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'symfony/filesystem' => array('pretty_version' => 'v6.4.0', 'version' => '6.4.0.0', 'reference' => '952a8cb588c3bc6ce76f6023000fb932f16a6e59', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/finder' => array('pretty_version' => 'v6.4.0', 'version' => '6.4.0.0', 'reference' => '11d736e97f116ac375a81f96e662911a34cd50ce', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/finder', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-ctype' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'symfony/polyfill-intl-grapheme' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'symfony/polyfill-mbstring' => array('pretty_version' => 'v1.28.0', 'version' => '1.28.0.0', 'reference' => '42292d99c55abe617799667f454222c54c60e229', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/process' => array('pretty_version' => 'v6.4.0', 'version' => '6.4.0.0', 'reference' => '191703b1566d97a5425dc969e4350d32b8ef17aa', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/service-contracts' => array('pretty_version' => 'v3.4.0', 'version' => '3.4.0.0', 'reference' => 'b3313c2dbffaf71c8de2934e2ea56ed2291a3838', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/service-contracts', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/string' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'symplify/easy-parallel' => array('pretty_version' => '11.1.27', 'version' => '11.1.27.0', 'reference' => '28911142f6a0f4127271f745e2403bb84fcd2b87', 'type' => 'library', 'install_path' => __DIR__ . '/../symplify/easy-parallel', 'aliases' => array(), 'dev_requirement' => \false), 'symplify/rule-doc-generator-contracts' => array('pretty_version' => '11.1.26', 'version' => '11.1.26.0', 'reference' => '3e66b3fec678b74a076395ec629d535fb95293b5', 'type' => 'library', 'install_path' => __DIR__ . '/../symplify/rule-doc-generator-contracts', 'aliases' => array(), 'dev_requirement' => \false), 'webmozart/assert' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991', 'type' => 'library', 'install_path' => __DIR__ . '/../webmozart/assert', 'aliases' => array(), 'dev_requirement' => \false))); +return array('root' => array('name' => 'rector/rector-src', 'pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => NULL, 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev' => \false), 'versions' => array('clue/ndjson-react' => array('pretty_version' => 'v1.3.0', 'version' => '1.3.0.0', 'reference' => '392dc165fce93b5bb5c637b67e59619223c931b0', 'type' => 'library', 'install_path' => __DIR__ . '/../clue/ndjson-react', 'aliases' => array(), 'dev_requirement' => \false), 'composer/pcre' => array('pretty_version' => '3.1.1', 'version' => '3.1.1.0', 'reference' => '00104306927c7a0919b4ced2aaa6782c1e61a3c9', 'type' => 'library', 'install_path' => __DIR__ . '/./pcre', 'aliases' => array(), 'dev_requirement' => \false), 'composer/semver' => array('pretty_version' => '3.4.0', 'version' => '3.4.0.0', 'reference' => '35e8d0af4486141bc745f23a29cc2091eb624a32', 'type' => 'library', 'install_path' => __DIR__ . '/./semver', 'aliases' => array(), 'dev_requirement' => \false), 'composer/xdebug-handler' => array('pretty_version' => '3.0.3', 'version' => '3.0.3.0', 'reference' => 'ced299686f41dce890debac69273b47ffe98a40c', 'type' => 'library', 'install_path' => __DIR__ . '/./xdebug-handler', 'aliases' => array(), 'dev_requirement' => \false), 'doctrine/inflector' => array('pretty_version' => '2.0.8', 'version' => '2.0.8.0', 'reference' => 'f9301a5b2fb1216b2b08f02ba04dc45423db6bff', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/inflector', 'aliases' => array(), 'dev_requirement' => \false), 'evenement/evenement' => array('pretty_version' => 'v3.0.2', 'version' => '3.0.2.0', 'reference' => '0a16b0d71ab13284339abb99d9d2bd813640efbc', 'type' => 'library', 'install_path' => __DIR__ . '/../evenement/evenement', 'aliases' => array(), 'dev_requirement' => \false), 'fidry/cpu-core-counter' => array('pretty_version' => '0.5.1', 'version' => '0.5.1.0', 'reference' => 'b58e5a3933e541dc286cc91fc4f3898bbc6f1623', 'type' => 'library', 'install_path' => __DIR__ . '/../fidry/cpu-core-counter', 'aliases' => array(), 'dev_requirement' => \false), 'illuminate/container' => array('pretty_version' => 'v10.35.0', 'version' => '10.35.0.0', 'reference' => 'ddc26273085fad3c471b2602ad820e0097ff7939', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/container', 'aliases' => array(), 'dev_requirement' => \false), 'illuminate/contracts' => array('pretty_version' => 'v10.35.0', 'version' => '10.35.0.0', 'reference' => 'f6bf37a272fda164f6c451407c99f820eb1eb95b', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/contracts', 'aliases' => array(), 'dev_requirement' => \false), 'nette/utils' => array('pretty_version' => 'v3.2.10', 'version' => '3.2.10.0', 'reference' => 'a4175c62652f2300c8017fb7e640f9ccb11648d2', 'type' => 'library', 'install_path' => __DIR__ . '/../nette/utils', 'aliases' => array(), 'dev_requirement' => \false), 'nikic/php-parser' => array('pretty_version' => 'v4.18.0', 'version' => '4.18.0.0', 'reference' => '1bcbb2179f97633e98bbbc87044ee2611c7d7999', 'type' => 'library', 'install_path' => __DIR__ . '/../nikic/php-parser', 'aliases' => array(), 'dev_requirement' => \false), 'ondram/ci-detector' => array('pretty_version' => '4.1.0', 'version' => '4.1.0.0', 'reference' => '8a4b664e916df82ff26a44709942dfd593fa6f30', 'type' => 'library', 'install_path' => __DIR__ . '/../ondram/ci-detector', 'aliases' => array(), 'dev_requirement' => \false), 'phpstan/phpdoc-parser' => array('pretty_version' => '1.24.4', 'version' => '1.24.4.0', 'reference' => '6bd0c26f3786cd9b7c359675cb789e35a8e07496', 'type' => 'library', 'install_path' => __DIR__ . '/../phpstan/phpdoc-parser', 'aliases' => array(), 'dev_requirement' => \false), 'phpstan/phpstan' => array('dev_requirement' => \false, 'replaced' => array(0 => '^1.10.35')), 'psr/container' => array('pretty_version' => '2.0.2', 'version' => '2.0.2.0', 'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), 'dev_requirement' => \false), 'psr/container-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.1|2.0')), 'psr/log' => array('pretty_version' => '3.0.0', 'version' => '3.0.0.0', 'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), 'dev_requirement' => \false), 'psr/log-implementation' => array('dev_requirement' => \false, 'provided' => array(0 => '1.0|2.0|3.0')), 'psr/simple-cache' => array('pretty_version' => '3.0.0', 'version' => '3.0.0.0', 'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/simple-cache', 'aliases' => array(), 'dev_requirement' => \false), 'react/cache' => array('pretty_version' => 'v1.2.0', 'version' => '1.2.0.0', 'reference' => 'd47c472b64aa5608225f47965a484b75c7817d5b', 'type' => 'library', 'install_path' => __DIR__ . '/../react/cache', 'aliases' => array(), 'dev_requirement' => \false), 'react/child-process' => array('pretty_version' => 'v0.6.5', 'version' => '0.6.5.0', 'reference' => 'e71eb1aa55f057c7a4a0d08d06b0b0a484bead43', 'type' => 'library', 'install_path' => __DIR__ . '/../react/child-process', 'aliases' => array(), 'dev_requirement' => \false), 'react/dns' => array('pretty_version' => 'v1.12.0', 'version' => '1.12.0.0', 'reference' => 'c134600642fa615b46b41237ef243daa65bb64ec', 'type' => 'library', 'install_path' => __DIR__ . '/../react/dns', 'aliases' => array(), 'dev_requirement' => \false), 'react/event-loop' => array('pretty_version' => 'v1.5.0', 'version' => '1.5.0.0', 'reference' => 'bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354', 'type' => 'library', 'install_path' => __DIR__ . '/../react/event-loop', 'aliases' => array(), 'dev_requirement' => \false), 'react/promise' => array('pretty_version' => 'v2.11.0', 'version' => '2.11.0.0', 'reference' => '1a8460931ea36dc5c76838fec5734d55c88c6831', 'type' => 'library', 'install_path' => __DIR__ . '/../react/promise', 'aliases' => array(), 'dev_requirement' => \false), 'react/socket' => array('pretty_version' => 'v1.14.0', 'version' => '1.14.0.0', 'reference' => '21591111d3ea62e31f2254280ca0656bc2b1bda6', 'type' => 'library', 'install_path' => __DIR__ . '/../react/socket', 'aliases' => array(), 'dev_requirement' => \false), 'react/stream' => array('pretty_version' => 'v1.3.0', 'version' => '1.3.0.0', 'reference' => '6fbc9672905c7d5a885f2da2fc696f65840f4a66', 'type' => 'library', 'install_path' => __DIR__ . '/../react/stream', 'aliases' => array(), 'dev_requirement' => \false), 'rector/extension-installer' => array('pretty_version' => '0.11.2', 'version' => '0.11.2.0', 'reference' => '05544e9b195863b8571ae2a3b903cbec7fa062e0', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../rector/extension-installer', 'aliases' => array(), 'dev_requirement' => \false), 'rector/rector' => array('dev_requirement' => \false, 'replaced' => array(0 => 'dev-main')), 'rector/rector-doctrine' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '9de7d58cb2b3438a469a609457a92dd37a310acc', 'type' => 'rector-extension', 'install_path' => __DIR__ . '/../rector/rector-doctrine', 'aliases' => array(0 => '9999999-dev'), 'dev_requirement' => \false), 'rector/rector-downgrade-php' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '917085c6a2a99412440cd3143288d1a17abb5c44', 'type' => 'rector-extension', 'install_path' => __DIR__ . '/../rector/rector-downgrade-php', 'aliases' => array(0 => '9999999-dev'), 'dev_requirement' => \false), 'rector/rector-phpunit' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '90e87f1032026d2c9c0195a826dc1126d2c40ecd', 'type' => 'rector-extension', 'install_path' => __DIR__ . '/../rector/rector-phpunit', 'aliases' => array(0 => '0.11.x-dev'), 'dev_requirement' => \false), 'rector/rector-src' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => NULL, 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => \false), 'rector/rector-symfony' => array('pretty_version' => 'dev-main', 'version' => 'dev-main', 'reference' => '38014d41e7ccddfdc4c9c839931c68a57d931f63', 'type' => 'rector-extension', 'install_path' => __DIR__ . '/../rector/rector-symfony', 'aliases' => array(0 => '9999999-dev'), 'dev_requirement' => \false), 'sebastian/diff' => array('pretty_version' => '5.0.3', 'version' => '5.0.3.0', 'reference' => '912dc2fbe3e3c1e7873313cc801b100b6c68c87b', 'type' => 'library', 'install_path' => __DIR__ . '/../sebastian/diff', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/console' => array('pretty_version' => 'v6.4.1', 'version' => '6.4.1.0', 'reference' => 'a550a7c99daeedef3f9d23fb82e3531525ff11fd', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/deprecation-contracts' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'symfony/filesystem' => array('pretty_version' => 'v6.4.0', 'version' => '6.4.0.0', 'reference' => '952a8cb588c3bc6ce76f6023000fb932f16a6e59', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/finder' => array('pretty_version' => 'v6.4.0', 'version' => '6.4.0.0', 'reference' => '11d736e97f116ac375a81f96e662911a34cd50ce', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/finder', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/polyfill-ctype' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'symfony/polyfill-intl-grapheme' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'symfony/polyfill-mbstring' => array('pretty_version' => 'v1.28.0', 'version' => '1.28.0.0', 'reference' => '42292d99c55abe617799667f454222c54c60e229', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/process' => array('pretty_version' => 'v6.4.0', 'version' => '6.4.0.0', 'reference' => '191703b1566d97a5425dc969e4350d32b8ef17aa', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/service-contracts' => array('pretty_version' => 'v3.4.0', 'version' => '3.4.0.0', 'reference' => 'b3313c2dbffaf71c8de2934e2ea56ed2291a3838', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/service-contracts', 'aliases' => array(), 'dev_requirement' => \false), 'symfony/string' => array('dev_requirement' => \false, 'replaced' => array(0 => '*')), 'symplify/easy-parallel' => array('pretty_version' => '11.1.27', 'version' => '11.1.27.0', 'reference' => '28911142f6a0f4127271f745e2403bb84fcd2b87', 'type' => 'library', 'install_path' => __DIR__ . '/../symplify/easy-parallel', 'aliases' => array(), 'dev_requirement' => \false), 'symplify/rule-doc-generator-contracts' => array('pretty_version' => '11.1.26', 'version' => '11.1.26.0', 'reference' => '3e66b3fec678b74a076395ec629d535fb95293b5', 'type' => 'library', 'install_path' => __DIR__ . '/../symplify/rule-doc-generator-contracts', 'aliases' => array(), 'dev_requirement' => \false), 'webmozart/assert' => array('pretty_version' => '1.11.0', 'version' => '1.11.0.0', 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991', 'type' => 'library', 'install_path' => __DIR__ . '/../webmozart/assert', 'aliases' => array(), 'dev_requirement' => \false))); diff --git a/vendor/nikic/php-parser/grammar/README.md b/vendor/nikic/php-parser/grammar/README.md deleted file mode 100644 index 4bae11d8261..00000000000 --- a/vendor/nikic/php-parser/grammar/README.md +++ /dev/null @@ -1,30 +0,0 @@ -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 -=================== - -Run `php grammar/rebuildParsers.php` to rebuild the parsers. Additional options: - - * The `KMYACC` environment variable can be used to specify an alternative `kmyacc` binary. - By default the `phpyacc` dev dependency will be used. To use the original `kmyacc`, you - need to compile [moriyoshi's fork](https://github.com/moriyoshi/kmyacc-forked). - * The `--debug` option enables emission of debug symbols and creates the `y.output` file. - * The `--keep-tmp-grammar` option preserves the preprocessed grammar file. diff --git a/vendor/nikic/php-parser/grammar/parser.template b/vendor/nikic/php-parser/grammar/parser.template deleted file mode 100644 index 6166607c9e4..00000000000 --- a/vendor/nikic/php-parser/grammar/parser.template +++ /dev/null @@ -1,106 +0,0 @@ -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 deleted file mode 100644 index 77e4fb7ede2..00000000000 --- a/vendor/nikic/php-parser/grammar/php5.y +++ /dev/null @@ -1,1046 +0,0 @@ -%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 - { makeZeroLengthNop($nop, $this->lookaheadStartAttributes); - if ($nop !== null) { $1[] = $nop; } $$ = $1; } -; - -ampersand: - T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG - | T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG -; - -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 | T_FN - | T_MATCH -; - -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: - T_STRING { $$ = Name[$1]; } - | T_NAME_QUALIFIED { $$ = Name[$1]; } -; - -legacy_namespace_name: - namespace_name { $$ = $1; } - | T_NAME_FULLY_QUALIFIED { $$ = Name[substr($1, 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; } -; - -group_use_declaration: - T_USE use_type legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations '}' - { $$ = Stmt\GroupUse[$3, $6, $2]; } - | T_USE legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations '}' - { $$ = Stmt\GroupUse[$2, $5, 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: - legacy_namespace_name - { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } - | legacy_namespace_name T_AS identifier - { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } -; - -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 - { makeZeroLengthNop($nop, $this->lookaheadStartAttributes); - 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; } - | ampersand { $$ = true; } -; - -optional_arg_ref: - /* empty */ { $$ = false; } - | T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG { $$ = true; } -; - -optional_ellipsis: - /* empty */ { $$ = false; } - | T_ELLIPSIS { $$ = true; } -; - -identifier_maybe_readonly: - identifier { $$ = $1; } - | T_READONLY { $$ = Node\Identifier[$1]; } -; - -function_declaration_statement: - T_FUNCTION optional_ref identifier_maybe_readonly '(' 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); } - | ampersand 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_arg_ref optional_ellipsis plain_variable - { $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); } - | optional_param_type optional_arg_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]; } - | ampersand 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 - { makeZeroLengthNop($nop, $this->lookaheadStartAttributes); - 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 '=' ampersand variable { $$ = Expr\AssignRef[$1, $4]; } - | variable '=' ampersand 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 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } - | expr T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG 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 ']' { $$ = Expr\ArrayDimFetch[Scalar\String_::fromString($1, attributes()), $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]; } -; - -name_readonly: - T_READONLY { $$ = Name[$1]; } -; - -function_call: - name argument_list { $$ = Expr\FuncCall[$1, $2]; } - | name_readonly 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: - T_STRING { $$ = Name[$1]; } - | T_NAME_QUALIFIED { $$ = Name[$1]; } - | T_NAME_FULLY_QUALIFIED { $$ = Name\FullyQualified[substr($1, 1)]; } - | T_NAME_RELATIVE { $$ = Name\Relative[substr($1, 10)]; } -; - -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::fromString($1, attributes()); } - | T_CONSTANT_ENCAPSED_STRING { $$ = Scalar\String_::fromString($1, attributes(), false); } - | 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 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG static_scalar - { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } - | static_scalar T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG 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 ampersand variable { $$ = Expr\ArrayItem[$4, $1, true]; } - | ampersand variable { $$ = Expr\ArrayItem[$2, null, true]; } - | T_ELLIPSIS expr { $$ = new Expr\ArrayItem($2, null, false, attributes(), 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 deleted file mode 100644 index 1ef60bfe03e..00000000000 --- a/vendor/nikic/php-parser/grammar/php7.y +++ /dev/null @@ -1,1245 +0,0 @@ -%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 - { makeZeroLengthNop($nop, $this->lookaheadStartAttributes); - if ($nop !== null) { $1[] = $nop; } $$ = $1; } -; - -ampersand: - T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG - | T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG -; - -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 | T_FN - | T_MATCH | T_ENUM -; - -semi_reserved: - reserved_non_modifiers - | T_STATIC | T_ABSTRACT | T_FINAL | T_PRIVATE | T_PROTECTED | T_PUBLIC | T_READONLY -; - -identifier_maybe_reserved: - T_STRING { $$ = Node\Identifier[$1]; } - | semi_reserved { $$ = Node\Identifier[$1]; } -; - -identifier_not_reserved: - T_STRING { $$ = Node\Identifier[$1]; } -; - -reserved_non_modifiers_identifier: - reserved_non_modifiers { $$ = Node\Identifier[$1]; } -; - -namespace_declaration_name: - T_STRING { $$ = Name[$1]; } - | semi_reserved { $$ = Name[$1]; } - | T_NAME_QUALIFIED { $$ = Name[$1]; } -; - -namespace_name: - T_STRING { $$ = Name[$1]; } - | T_NAME_QUALIFIED { $$ = Name[$1]; } -; - -legacy_namespace_name: - namespace_name { $$ = $1; } - | T_NAME_FULLY_QUALIFIED { $$ = Name[substr($1, 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 */ - | ',' -; - -attribute_decl: - class_name { $$ = Node\Attribute[$1, []]; } - | class_name argument_list { $$ = Node\Attribute[$1, $2]; } -; - -attribute_group: - attribute_decl { init($1); } - | attribute_group ',' attribute_decl { push($1, $3); } -; - -attribute: - T_ATTRIBUTE attribute_group optional_comma ']' { $$ = Node\AttributeGroup[$2]; } -; - -attributes: - attribute { init($1); } - | attributes attribute { push($1, $2); } -; - -optional_attributes: - /* empty */ { $$ = []; } - | attributes { $$ = $1; } -; - -top_statement: - statement { $$ = $1; } - | function_declaration_statement { $$ = $1; } - | class_declaration_statement { $$ = $1; } - | T_HALT_COMPILER - { $$ = Stmt\HaltCompiler[$this->lexer->handleHaltCompiler()]; } - | T_NAMESPACE namespace_declaration_name semi - { $$ = Stmt\Namespace_[$2, null]; - $$->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); - $this->checkNamespace($$); } - | T_NAMESPACE namespace_declaration_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; } -; - -group_use_declaration: - T_USE use_type legacy_namespace_name T_NS_SEPARATOR '{' unprefixed_use_declarations '}' - { $$ = Stmt\GroupUse[$3, $6, $2]; } - | T_USE legacy_namespace_name T_NS_SEPARATOR '{' inline_use_declarations '}' - { $$ = Stmt\GroupUse[$2, $5, 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_not_reserved - { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } -; - -use_declaration: - legacy_namespace_name - { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } - | legacy_namespace_name T_AS identifier_not_reserved - { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } -; - -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_not_reserved '=' 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: - T_STRING '=' expr - { $$ = Node\Const_[new Node\Identifier($1, stackAttributes(#1)), $3]; } - | semi_reserved '=' expr - { $$ = Node\Const_[new Node\Identifier($1, stackAttributes(#1)), $3]; } -; - -inner_statement_list_ex: - inner_statement_list_ex inner_statement { pushNormalizing($1, $2); } - | /* empty */ { init(); } -; - -inner_statement_list: - inner_statement_list_ex - { makeZeroLengthNop($nop, $this->lookaheadStartAttributes); - 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_forbid_comma semi { $$ = Stmt\Echo_[$2]; } - | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } - | expr semi { - $e = $1; - if ($e instanceof Expr\Throw_) { - // For backwards-compatibility reasons, convert throw in statement position into - // Stmt\Throw_ rather than Stmt\Expression(Expr\Throw_). - $$ = Stmt\Throw_[$e->expr]; - } else { - $$ = Stmt\Expression[$e]; - } - } - | 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_GOTO identifier_not_reserved semi { $$ = Stmt\Goto_[$2]; } - | identifier_not_reserved ':' { $$ = 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 optional_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; } - | ampersand { $$ = true; } -; - -optional_arg_ref: - /* empty */ { $$ = false; } - | T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG { $$ = true; } -; - -optional_ellipsis: - /* empty */ { $$ = false; } - | T_ELLIPSIS { $$ = true; } -; - -block_or_error: - '{' inner_statement_list '}' { $$ = $2; } - | error { $$ = []; } -; - -identifier_maybe_readonly: - identifier_not_reserved { $$ = $1; } - | T_READONLY { $$ = Node\Identifier[$1]; } -; - -function_declaration_statement: - T_FUNCTION optional_ref identifier_maybe_readonly '(' parameter_list ')' optional_return_type block_or_error - { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $8, 'attrGroups' => []]]; } - | attributes T_FUNCTION optional_ref identifier_maybe_readonly '(' parameter_list ')' optional_return_type block_or_error - { $$ = Stmt\Function_[$4, ['byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => $1]]; } -; - -class_declaration_statement: - class_entry_type identifier_not_reserved extends_from implements_list '{' class_statement_list '}' - { $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6, 'attrGroups' => []]]; - $this->checkClass($$, #2); } - | attributes class_entry_type identifier_not_reserved extends_from implements_list '{' class_statement_list '}' - { $$ = Stmt\Class_[$3, ['type' => $2, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]]; - $this->checkClass($$, #3); } - | optional_attributes T_INTERFACE identifier_not_reserved interface_extends_list '{' class_statement_list '}' - { $$ = Stmt\Interface_[$3, ['extends' => $4, 'stmts' => $6, 'attrGroups' => $1]]; - $this->checkInterface($$, #3); } - | optional_attributes T_TRAIT identifier_not_reserved '{' class_statement_list '}' - { $$ = Stmt\Trait_[$3, ['stmts' => $5, 'attrGroups' => $1]]; } - | optional_attributes T_ENUM identifier_not_reserved enum_scalar_type implements_list '{' class_statement_list '}' - { $$ = Stmt\Enum_[$3, ['scalarType' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]]; - $this->checkEnum($$, #3); } -; - -enum_scalar_type: - /* empty */ { $$ = null; } - | ':' type { $$ = $2; } - -enum_case_expr: - /* empty */ { $$ = null; } - | '=' expr { $$ = $2; } -; - -class_entry_type: - T_CLASS { $$ = 0; } - | class_modifiers T_CLASS { $$ = $1; } -; - -class_modifiers: - class_modifier { $$ = $1; } - | class_modifiers class_modifier { $this->checkClassModifier($1, $2, #2); $$ = $1 | $2; } -; - -class_modifier: - T_ABSTRACT { $$ = Stmt\Class_::MODIFIER_ABSTRACT; } - | T_FINAL { $$ = Stmt\Class_::MODIFIER_FINAL; } - | T_READONLY { $$ = Stmt\Class_::MODIFIER_READONLY; } -; - -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_not_reserved '=' 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: - ':' - | ';' -; - -match: - T_MATCH '(' expr ')' '{' match_arm_list '}' { $$ = Expr\Match_[$3, $6]; } -; - -match_arm_list: - /* empty */ { $$ = []; } - | non_empty_match_arm_list optional_comma { $$ = $1; } -; - -non_empty_match_arm_list: - match_arm { init($1); } - | non_empty_match_arm_list ',' match_arm { push($1, $3); } -; - -match_arm: - expr_list_allow_comma T_DOUBLE_ARROW expr { $$ = Node\MatchArm[$1, $3]; } - | T_DEFAULT optional_comma T_DOUBLE_ARROW expr { $$ = Node\MatchArm[null, $4]; } -; - -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]; $this->fixupAlternativeElse($$); } -; - -else_single: - /* empty */ { $$ = null; } - | T_ELSE statement { $$ = Stmt\Else_[toArray($2)]; } -; - -new_else_single: - /* empty */ { $$ = null; } - | T_ELSE ':' inner_statement_list - { $$ = Stmt\Else_[$3]; $this->fixupAlternativeElse($$); } -; - -foreach_variable: - variable { $$ = array($1, false); } - | ampersand variable { $$ = array($2, true); } - | list_expr { $$ = array($1, false); } - | array_short_syntax { $$ = array($1, false); } -; - -parameter_list: - non_empty_parameter_list optional_comma { $$ = $1; } - | /* empty */ { $$ = array(); } -; - -non_empty_parameter_list: - parameter { init($1); } - | non_empty_parameter_list ',' parameter { push($1, $3); } -; - -optional_property_modifiers: - /* empty */ { $$ = 0; } - | optional_property_modifiers property_modifier - { $this->checkModifier($1, $2, #2); $$ = $1 | $2; } -; - -property_modifier: - T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; } - | T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; } - | T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; } - | T_READONLY { $$ = Stmt\Class_::MODIFIER_READONLY; } -; - -parameter: - optional_attributes optional_property_modifiers optional_type_without_static - optional_arg_ref optional_ellipsis plain_variable - { $$ = new Node\Param($6, null, $3, $4, $5, attributes(), $2, $1); - $this->checkParam($$); } - | optional_attributes optional_property_modifiers optional_type_without_static - optional_arg_ref optional_ellipsis plain_variable '=' expr - { $$ = new Node\Param($6, $8, $3, $4, $5, attributes(), $2, $1); - $this->checkParam($$); } - | optional_attributes optional_property_modifiers optional_type_without_static - optional_arg_ref optional_ellipsis error - { $$ = new Node\Param(Expr\Error[], null, $3, $4, $5, attributes(), $2, $1); } -; - -type_expr: - type { $$ = $1; } - | '?' type { $$ = Node\NullableType[$2]; } - | union_type { $$ = Node\UnionType[$1]; } - | intersection_type { $$ = $1; } -; - -type: - type_without_static { $$ = $1; } - | T_STATIC { $$ = Node\Name['static']; } -; - -type_without_static: - name { $$ = $this->handleBuiltinTypes($1); } - | T_ARRAY { $$ = Node\Identifier['array']; } - | T_CALLABLE { $$ = Node\Identifier['callable']; } -; - -union_type_element: - type { $$ = $1; } - | '(' intersection_type ')' { $$ = $2; } -; - -union_type: - union_type_element '|' union_type_element { init($1, $3); } - | union_type '|' union_type_element { push($1, $3); } -; - -union_type_without_static_element: - type_without_static { $$ = $1; } - | '(' intersection_type_without_static ')' { $$ = $2; } -; - -union_type_without_static: - union_type_without_static_element '|' union_type_without_static_element { init($1, $3); } - | union_type_without_static '|' union_type_without_static_element { push($1, $3); } -; - -intersection_type_list: - type T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type { init($1, $3); } - | intersection_type_list T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type - { push($1, $3); } -; - -intersection_type: - intersection_type_list { $$ = Node\IntersectionType[$1]; } -; - -intersection_type_without_static_list: - type_without_static T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type_without_static - { init($1, $3); } - | intersection_type_without_static_list T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG type_without_static - { push($1, $3); } -; - -intersection_type_without_static: - intersection_type_without_static_list { $$ = Node\IntersectionType[$1]; } -; - -type_expr_without_static: - type_without_static { $$ = $1; } - | '?' type_without_static { $$ = Node\NullableType[$2]; } - | union_type_without_static { $$ = Node\UnionType[$1]; } - | intersection_type_without_static { $$ = $1; } -; - -optional_type_without_static: - /* empty */ { $$ = null; } - | type_expr_without_static { $$ = $1; } -; - -optional_return_type: - /* empty */ { $$ = null; } - | ':' type_expr { $$ = $2; } - | ':' error { $$ = null; } -; - -argument_list: - '(' ')' { $$ = array(); } - | '(' non_empty_argument_list optional_comma ')' { $$ = $2; } - | '(' variadic_placeholder ')' { init($2); } -; - -variadic_placeholder: - T_ELLIPSIS { $$ = Node\VariadicPlaceholder[]; } -; - -non_empty_argument_list: - argument { init($1); } - | non_empty_argument_list ',' argument { push($1, $3); } -; - -argument: - expr { $$ = Node\Arg[$1, false, false]; } - | ampersand variable { $$ = Node\Arg[$2, true, false]; } - | T_ELLIPSIS expr { $$ = Node\Arg[$2, false, true]; } - | identifier_maybe_reserved ':' expr - { $$ = new Node\Arg($3, false, false, attributes(), $1); } -; - -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 { $$ = $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 - { makeZeroLengthNop($nop, $this->lookaheadStartAttributes); - if ($nop !== null) { $1[] = $nop; } $$ = $1; } -; - -class_statement: - optional_attributes variable_modifiers optional_type_without_static property_declaration_list semi - { $$ = new Stmt\Property($2, $4, attributes(), $3, $1); - $this->checkProperty($$, #2); } - | optional_attributes method_modifiers T_CONST class_const_list semi - { $$ = new Stmt\ClassConst($4, $2, attributes(), $1); - $this->checkClassConst($$, #2); } - | optional_attributes method_modifiers T_CONST type_expr class_const_list semi - { $$ = new Stmt\ClassConst($5, $2, attributes(), $1, $4); - $this->checkClassConst($$, #2); } - | optional_attributes method_modifiers T_FUNCTION optional_ref identifier_maybe_reserved '(' parameter_list ')' - optional_return_type method_body - { $$ = Stmt\ClassMethod[$5, ['type' => $2, 'byRef' => $4, 'params' => $7, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]]; - $this->checkClassMethod($$, #2); } - | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } - | optional_attributes T_CASE identifier_maybe_reserved enum_case_expr semi - { $$ = Stmt\EnumCase[$3, $4, $1]; } - | 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_maybe_reserved ';' - { $$ = 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_not_reserved ';' - { $$ = 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_maybe_reserved { $$ = array($1, $3); } -; -trait_method_reference: - trait_method_reference_fully_qualified { $$ = $1; } - | identifier_maybe_reserved { $$ = 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; } - | T_READONLY { $$ = Stmt\Class_::MODIFIER_READONLY; } -; - -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_forbid_comma: - non_empty_expr_list no_comma { $$ = $1; } -; - -expr_list_allow_comma: - non_empty_expr_list optional_comma { $$ = $1; } -; - -non_empty_expr_list: - non_empty_expr_list ',' expr { push($1, $3); } - | expr { init($1); } -; - -for_expr: - /* empty */ { $$ = array(); } - | expr_list_forbid_comma { $$ = $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 '=' ampersand variable { $$ = Expr\AssignRef[$1, $4]; } - | new_expr { $$ = $1; } - | match { $$ = $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 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG expr { $$ = Expr\BinaryOp\BitwiseAnd[$1, $3]; } - | expr T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG 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 '(' expr_list_allow_comma ')' { $$ = 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_THROW expr { $$ = Expr\Throw_[$2]; } - - | T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr %prec T_THROW - { $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $2, 'params' => $4, 'returnType' => $6, 'expr' => $8, 'attrGroups' => []]]; } - | T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr %prec T_THROW - { $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9, 'attrGroups' => []]]; } - | 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, 'attrGroups' => []]]; } - | 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, 'attrGroups' => []]]; } - - | attributes T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr %prec T_THROW - { $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9, 'attrGroups' => $1]]; } - | attributes T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr %prec T_THROW - { $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $4, 'params' => $6, 'returnType' => $8, 'expr' => $10, 'attrGroups' => $1]]; } - | attributes T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error - { $$ = Expr\Closure[['static' => false, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => $1]]; } - | attributes T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error - { $$ = Expr\Closure[['static' => true, 'byRef' => $4, 'params' => $6, 'uses' => $8, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]]; } -; - -anonymous_class: - optional_attributes class_entry_type ctor_arguments extends_from implements_list '{' class_statement_list '}' - { $$ = array(Stmt\Class_[null, ['type' => $2, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]], $3); - $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 optional_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]; } -; - -name_readonly: - T_READONLY { $$ = Name[$1]; } -; - -function_call: - name argument_list { $$ = Expr\FuncCall[$1, $2]; } - | name_readonly 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: - T_STRING { $$ = Name[$1]; } - | T_NAME_QUALIFIED { $$ = Name[$1]; } - | T_NAME_FULLY_QUALIFIED { $$ = Name\FullyQualified[substr($1, 1)]; } - | T_NAME_RELATIVE { $$ = Name\Relative[substr($1, 10)]; } -; - -class_name_reference: - class_name { $$ = $1; } - | new_variable { $$ = $1; } - | '(' expr ')' { $$ = $2; } - | error { $$ = Expr\Error[]; $this->errorState = 2; } -; - -class_name_or_var: - class_name { $$ = $1; } - | fully_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]; } - | 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_[]; } -; - -class_constant: - class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_maybe_reserved - { $$ = Expr\ClassConstFetch[$1, $3]; } - | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM '{' expr '}' - { $$ = Expr\ClassConstFetch[$1, $4]; } - /* We interpret an 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 { $$ = Scalar\String_::fromString($1, attributes()); } - | '"' encaps_list '"' - { $attrs = attributes(); $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; - parseEncapsed($2, '"', true); $$ = new Scalar\Encapsed($2, $attrs); } -; - -scalar: - T_LNUMBER { $$ = $this->parseLNumber($1, attributes()); } - | T_DNUMBER { $$ = Scalar\DNumber::fromString($1, attributes()); } - | dereferencable_scalar { $$ = $1; } - | constant { $$ = $1; } - | class_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); } - | T_START_HEREDOC encaps_list T_END_HEREDOC - { $$ = $this->parseDocString($1, $2, $3, attributes(), stackAttributes(#3), true); } -; - -optional_expr: - /* empty */ { $$ = null; } - | expr { $$ = $1; } -; - -fully_dereferencable: - variable { $$ = $1; } - | '(' expr ')' { $$ = $2; } - | dereferencable_scalar { $$ = $1; } - | class_constant { $$ = $1; } -; - -array_object_dereferencable: - fully_dereferencable { $$ = $1; } - | constant { $$ = $1; } -; - -callable_expr: - callable_variable { $$ = $1; } - | '(' expr ')' { $$ = $2; } - | dereferencable_scalar { $$ = $1; } -; - -callable_variable: - simple_variable { $$ = $1; } - | array_object_dereferencable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } - | array_object_dereferencable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } - | function_call { $$ = $1; } - | array_object_dereferencable T_OBJECT_OPERATOR property_name argument_list - { $$ = Expr\MethodCall[$1, $3, $4]; } - | array_object_dereferencable T_NULLSAFE_OBJECT_OPERATOR property_name argument_list - { $$ = Expr\NullsafeMethodCall[$1, $3, $4]; } -; - -optional_plain_variable: - /* empty */ { $$ = null; } - | plain_variable { $$ = $1; } -; - -variable: - callable_variable { $$ = $1; } - | static_member { $$ = $1; } - | array_object_dereferencable T_OBJECT_OPERATOR property_name - { $$ = Expr\PropertyFetch[$1, $3]; } - | array_object_dereferencable T_NULLSAFE_OBJECT_OPERATOR property_name - { $$ = Expr\NullsafePropertyFetch[$1, $3]; } -; - -simple_variable: - plain_variable { $$ = $1; } - | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } - | '$' simple_variable { $$ = Expr\Variable[$2]; } - | '$' error { $$ = Expr\Variable[Expr\Error[]]; $this->errorState = 2; } -; - -static_member_prop_name: - simple_variable - { $var = $1->name; $$ = \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 { $$ = $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]; } - | new_variable T_NULLSAFE_OBJECT_OPERATOR property_name { $$ = Expr\NullsafePropertyFetch[$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_maybe_reserved { $$ = $1; } - | '{' expr '}' { $$ = $2; } - | simple_variable { $$ = $1; } -; - -property_name: - identifier_not_reserved { $$ = $1; } - | '{' expr '}' { $$ = $2; } - | simple_variable { $$ = $1; } - | error { $$ = Expr\Error[]; $this->errorState = 2; } -; - -list_expr: - T_LIST '(' inner_array_pair_list ')' { $$ = Expr\List_[$3]; } -; - -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 { $$ = Expr\ArrayItem[$1, null, false]; } - | ampersand variable { $$ = Expr\ArrayItem[$2, null, true]; } - | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } - | expr T_DOUBLE_ARROW expr { $$ = Expr\ArrayItem[$3, $1, false]; } - | expr T_DOUBLE_ARROW ampersand variable { $$ = Expr\ArrayItem[$4, $1, true]; } - | expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; } - | T_ELLIPSIS expr { $$ = new Expr\ArrayItem($2, null, false, attributes(), 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_not_reserved - { $$ = Expr\PropertyFetch[$1, $3]; } - | plain_variable T_NULLSAFE_OBJECT_OPERATOR identifier_not_reserved - { $$ = Expr\NullsafePropertyFetch[$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/phpyLang.php b/vendor/nikic/php-parser/grammar/phpyLang.php deleted file mode 100644 index 1eebe148c6a..00000000000 --- a/vendor/nikic/php-parser/grammar/phpyLang.php +++ /dev/null @@ -1,128 +0,0 @@ -\'[^\\\\\']*+(?:\\\\.[^\\\\\']*+)*+\') - (?"[^\\\\"]*+(?:\\\\.[^\\\\"]*+)*+") - (?(?&singleQuotedString)|(?&doubleQuotedString)) - (?/\\*[^*]*+(?:\\*(?!/)[^*]*+)*+\\*/) - (?\\{[^\'"/{}]*+(?:(?:(?&string)|(?&comment)|(?&code)|/)[^\'"/{}]*+)*+}) -)'; -const PARAMS = '\\[(?[^[\\]]*+(?:\\[(?¶ms)\\][^[\\]]*+)*+)\\]'; -const ARGS = '\\((?[^()]*+(?:\\((?&args)\\)[^()]*+)*+)\\)'; -/////////////////////////////// -/// Preprocessing functions /// -/////////////////////////////// -function preprocessGrammar($code) -{ - $code = resolveNodes($code); - $code = resolveMacros($code); - $code = resolveStackAccess($code); - return $code; -} -function resolveNodes($code) -{ - return \preg_replace_callback('~\\b(?[A-Z][a-zA-Z_\\\\]++)\\s*' . \RectorPrefix202312\PARAMS . '~', function ($matches) { - // recurse - $matches['params'] = resolveNodes($matches['params']); - $params = magicSplit('(?:' . \RectorPrefix202312\PARAMS . '|' . \RectorPrefix202312\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]++)' . \RectorPrefix202312\ARGS . '~', function ($matches) { - // recurse - $matches['args'] = resolveMacros($matches['args']); - $name = $matches['name']; - $args = magicSplit('(?:' . \RectorPrefix202312\PARAMS . '|' . \RectorPrefix202312\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 ('makeZeroLengthNop' == $name) { - assertArgs(2, $args, $name); - return '$startAttributes = ' . $args[1] . ';' . ' if (isset($startAttributes[\'comments\']))' . ' { ' . $args[0] . ' = new Stmt\\Nop($this->createCommentNopAttributes($startAttributes[\'comments\'])); }' . ' else { ' . $args[0] . ' = null; }'; - } - 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); -} -////////////////////////////// -/// Regex helper functions /// -////////////////////////////// -function regex($regex) -{ - return '~' . \RectorPrefix202312\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/rebuildParsers.php b/vendor/nikic/php-parser/grammar/rebuildParsers.php deleted file mode 100644 index 0f092633652..00000000000 --- a/vendor/nikic/php-parser/grammar/rebuildParsers.php +++ /dev/null @@ -1,64 +0,0 @@ - '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'; -$kmyacc = \getenv('KMYACC'); -if (!$kmyacc) { - // Use phpyacc from dev dependencies by default. - $kmyacc = __DIR__ . '/../vendor/bin/phpyacc'; -} -$options = \array_flip($argv); -$optionDebug = isset($options['--debug']); -$optionKeepTmpGrammar = isset($options['--keep-tmp-grammar']); -/////////////////// -/// 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 = preprocessGrammar($grammarCode); - \file_put_contents($tmpGrammarFile, $grammarCode); - $additionalArgs = $optionDebug ? '-t -v' : ''; - echo "Building {$name} parser.\n"; - $output = execCmd("{$kmyacc} {$additionalArgs} -m {$skeletonFile} -p {$name} {$tmpGrammarFile}"); - $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 = execCmd("{$kmyacc} -m {$tokensTemplate} {$tmpGrammarFile}"); - \rename($tmpResultFile, $tokensResultsFile); - if (!$optionKeepTmpGrammar) { - \unlink($tmpGrammarFile); - } -} -//////////////////////////////// -/// Utility helper functions /// -//////////////////////////////// -function ensureDirExists($dir) -{ - if (!\is_dir($dir)) { - \mkdir($dir, 0777, \true); - } -} -function execCmd($cmd) -{ - $output = \trim(\shell_exec("{$cmd} 2>&1")); - if ($output !== "") { - echo "> " . $cmd . "\n"; - echo $output; - } - return $output; -} diff --git a/vendor/nikic/php-parser/grammar/tokens.template b/vendor/nikic/php-parser/grammar/tokens.template deleted file mode 100644 index ba4e4901c0b..00000000000 --- a/vendor/nikic/php-parser/grammar/tokens.template +++ /dev/null @@ -1,17 +0,0 @@ -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 deleted file mode 100644 index 8f0b2172549..00000000000 --- a/vendor/nikic/php-parser/grammar/tokens.y +++ /dev/null @@ -1,115 +0,0 @@ -/* 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. */ - -%right T_THROW -%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 T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG -%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_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_MATCH -%token T_ENDSWITCH -%token T_CASE -%token T_DEFAULT -%token T_BREAK -%token T_CONTINUE -%token T_GOTO -%token T_FUNCTION -%token T_FN -%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 T_READONLY -%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_ENUM -%token T_EXTENDS -%token T_IMPLEMENTS -%token T_OBJECT_OPERATOR -%token T_NULLSAFE_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_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 -%token T_NAME_FULLY_QUALIFIED -%token T_NAME_QUALIFIED -%token T_NAME_RELATIVE -%token T_ATTRIBUTE -%token T_ENUM diff --git a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php index 901884cfcf1..200d8a63a9e 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php +++ b/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php @@ -110,6 +110,9 @@ class NameResolver extends NodeVisitorAbstract } } else { if ($node instanceof Stmt\ClassConst) { + if (null !== $node->type) { + $node->type = $this->resolveType($node->type); + } $this->resolveAttrGroups($node); } else { if ($node instanceof Stmt\EnumCase) { diff --git a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php index 369c2b71462..d2b38cdbcce 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php +++ b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php @@ -649,6 +649,8 @@ class Php5 extends \PhpParser\ParserAbstract if ($this->semStack[$stackPos - (2 - 2)] !== null) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + } else { + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; } }, 260 => function ($stackPos) { $this->semValue = array(); diff --git a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php index fc13db96ccc..e042bd333d3 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php +++ b/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php @@ -832,6 +832,8 @@ class Php7 extends \PhpParser\ParserAbstract if ($this->semStack[$stackPos - (2 - 2)] !== null) { $this->semStack[$stackPos - (2 - 1)][] = $this->semStack[$stackPos - (2 - 2)]; $this->semValue = $this->semStack[$stackPos - (2 - 1)]; + } else { + $this->semValue = $this->semStack[$stackPos - (2 - 1)]; } }, 341 => function ($stackPos) { $this->semValue = array(); diff --git a/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php b/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php index c8d6ef6f679..81dd199e87a 100644 --- a/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php +++ b/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php @@ -3,6 +3,8 @@ declare (strict_types=1); namespace PhpParser; +use PhpParser\Lexer\Emulative; +use PhpParser\Parser\Php7; class ParserFactory { const PREFER_PHP7 = 1; @@ -36,4 +38,31 @@ class ParserFactory throw new \LogicException('Kind must be one of ::PREFER_PHP7, ::PREFER_PHP5, ::ONLY_PHP7 or ::ONLY_PHP5'); } } + /** + * Create a parser targeting the newest version supported by this library. Code for older + * versions will be accepted if there have been no relevant backwards-compatibility breaks in + * PHP. + * + * All supported lexer attributes (comments, startLine, endLine, startTokenPos, endTokenPos, + * startFilePos, endFilePos) will be enabled. + */ + public function createForNewestSupportedVersion() : \PhpParser\Parser + { + return new Php7(new Emulative($this->getLexerOptions())); + } + /** + * Create a parser targeting the host PHP version, that is the PHP version we're currently + * running on. This parser will not use any token emulation. + * + * All supported lexer attributes (comments, startLine, endLine, startTokenPos, endTokenPos, + * startFilePos, endFilePos) will be enabled. + */ + public function createForHostVersion() : \PhpParser\Parser + { + return new Php7(new \PhpParser\Lexer($this->getLexerOptions())); + } + private function getLexerOptions() : array + { + return ['usedAttributes' => ['comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', 'startFilePos', 'endFilePos']]; + } } diff --git a/vendor/rector/extension-installer/src/GeneratedConfig.php b/vendor/rector/extension-installer/src/GeneratedConfig.php index d1ecb578fbf..f0410787abf 100644 --- a/vendor/rector/extension-installer/src/GeneratedConfig.php +++ b/vendor/rector/extension-installer/src/GeneratedConfig.php @@ -9,7 +9,7 @@ namespace Rector\RectorInstaller; */ final class GeneratedConfig { - public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 9de7d58'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main a08ccad'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main 90e87f1'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 38014d4')); + public const EXTENSIONS = array('rector/rector-doctrine' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-doctrine', 'relative_install_path' => '../../rector-doctrine', 'extra' => NULL, 'version' => 'dev-main 9de7d58'), 'rector/rector-downgrade-php' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-downgrade-php', 'relative_install_path' => '../../rector-downgrade-php', 'extra' => NULL, 'version' => 'dev-main 917085c'), 'rector/rector-phpunit' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-phpunit', 'relative_install_path' => '../../rector-phpunit', 'extra' => NULL, 'version' => 'dev-main 90e87f1'), 'rector/rector-symfony' => array('install_path' => '/home/runner/work/rector-src/rector-src/rector-build/vendor/rector/rector-symfony', 'relative_install_path' => '../../rector-symfony', 'extra' => NULL, 'version' => 'dev-main 38014d4')); private function __construct() { } diff --git a/vendor/rector/rector-downgrade-php/config/set/downgrade-php82.php b/vendor/rector/rector-downgrade-php/config/set/downgrade-php82.php index 3b27765bcfb..c8e4ed3c246 100644 --- a/vendor/rector/rector-downgrade-php/config/set/downgrade-php82.php +++ b/vendor/rector/rector-downgrade-php/config/set/downgrade-php82.php @@ -6,7 +6,8 @@ namespace RectorPrefix202312; use Rector\Config\RectorConfig; use Rector\Core\ValueObject\PhpVersion; use Rector\DowngradePhp82\Rector\Class_\DowngradeReadonlyClassRector; +use Rector\DowngradePhp82\Rector\FunctionLike\DowngradeStandaloneNullTrueFalseReturnTypeRector; return static function (RectorConfig $rectorConfig) : void { $rectorConfig->phpVersion(PhpVersion::PHP_81); - $rectorConfig->rule(DowngradeReadonlyClassRector::class); + $rectorConfig->rules([DowngradeReadonlyClassRector::class, DowngradeStandaloneNullTrueFalseReturnTypeRector::class]); }; diff --git a/vendor/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/FunctionLike/DowngradeStandaloneNullTrueFalseReturnTypeRector.php b/vendor/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/FunctionLike/DowngradeStandaloneNullTrueFalseReturnTypeRector.php new file mode 100644 index 00000000000..b044ee1483b --- /dev/null +++ b/vendor/rector/rector-downgrade-php/rules/DowngradePhp82/Rector/FunctionLike/DowngradeStandaloneNullTrueFalseReturnTypeRector.php @@ -0,0 +1,159 @@ +phpDocInfoFactory = $phpDocInfoFactory; + $this->phpDocTypeChanger = $phpDocTypeChanger; + $this->astResolver = $astResolver; + } + /** + * @return array> + */ + public function getNodeTypes() : array + { + return [FunctionLike::class]; + } + public function getRuleDefinition() : RuleDefinition + { + return new RuleDefinition('Downgrade standalone return null, true, or false', [new CodeSample(<<<'CODE_SAMPLE' +final class SomeClass +{ + public function run(): null + { + return null; + } +} +CODE_SAMPLE +, <<<'CODE_SAMPLE' +final class SomeClass +{ + public function run(): mixed + { + return null; + } +} +CODE_SAMPLE +)]); + } + /** + * @param ClassMethod|Function_|Closure|ArrowFunction $node + */ + public function refactor(Node $node) : ?Node + { + $returnType = $node->returnType; + if (!$returnType instanceof Identifier) { + return null; + } + $returnTypeName = $this->getName($returnType); + if (!\in_array($returnTypeName, ['null', 'false', 'true'], \true)) { + return null; + } + // in closure and arrow function can't add `@return null` docblock as they are Expr + // that rely on Stmt + $phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); + $this->phpDocTypeChanger->changeReturnType($node, $phpDocInfo, $this->resolveType($returnType)); + $node->returnType = $this->resolveNativeType($node, $returnType); + return $node; + } + private function resolveType(Identifier $identifier) : Type + { + $nodeName = $this->getName($identifier); + if ($nodeName === 'null') { + return new NullType(); + } + if ($nodeName === 'false') { + return new ConstantBooleanType(\false); + } + return new ConstantBooleanType(\true); + } + /** + * @return \PhpParser\Node\ComplexType|\PhpParser\Node\Identifier + */ + private function resolveNativeType(Node $node, Identifier $identifier) + { + if ($node instanceof ClassMethod) { + $returnTypeFromParent = $this->resolveParentNativeReturnType($node); + if ($returnTypeFromParent instanceof UnionType || $returnTypeFromParent instanceof NullableType) { + $this->traverseNodesWithCallable($returnTypeFromParent, static function (Node $subNode) : Node { + $subNode->setAttribute(AttributeKey::ORIGINAL_NODE, null); + return $subNode; + }); + return $returnTypeFromParent; + } + } + $nodeName = $this->getName($identifier); + if ($nodeName === 'null') { + return new Identifier('mixed'); + } + return new Identifier('bool'); + } + private function resolveParentNativeReturnType(ClassMethod $classMethod) : ?Node + { + $scope = $classMethod->getAttribute(AttributeKey::SCOPE); + if ($scope === null) { + return null; + } + $classReflection = $scope->getClassReflection(); + if ($classReflection === null) { + return null; + } + $methodName = $classMethod->name->toString(); + $parents = \array_merge(\is_array($classReflection->getParents()) ? $classReflection->getParents() : \iterator_to_array($classReflection->getParents()), \is_array($classReflection->getInterfaces()) ? $classReflection->getInterfaces() : \iterator_to_array($classReflection->getInterfaces())); + foreach ($parents as $parent) { + if (!$parent->hasMethod($methodName)) { + continue; + } + $parentClassMethod = $this->astResolver->resolveClassMethod($parent->getName(), $methodName); + if (!$parentClassMethod instanceof ClassMethod) { + continue; + } + return $parentClassMethod->returnType; + } + return null; + } +}