diff --git a/app/README.md b/app/README.md new file mode 100644 index 000000000..64cc750af --- /dev/null +++ b/app/README.md @@ -0,0 +1,51 @@ +# CakePHP Application Skeleton + +[![Build Status](https://img.shields.io/travis/cakephp/app/master.svg?style=flat-square)](https://travis-ci.org/cakephp/app) +[![License](https://img.shields.io/packagist/l/cakephp/app.svg?style=flat-square)](https://packagist.org/packages/cakephp/app) + +A skeleton for creating applications with [CakePHP](https://cakephp.org) 3.x. + +The framework source code can be found here: [cakephp/cakephp](https://github.com/cakephp/cakephp). + +## Installation + +1. Download [Composer](https://getcomposer.org/doc/00-intro.md) or update `composer self-update`. +2. Run `php composer.phar create-project --prefer-dist cakephp/app [app_name]`. + +If Composer is installed globally, run + +```bash +composer create-project --prefer-dist cakephp/app +``` + +In case you want to use a custom app dir name (e.g. `/myapp/`): + +```bash +composer create-project --prefer-dist cakephp/app myapp +``` + +You can now either use your machine's webserver to view the default home page, or start +up the built-in webserver with: + +```bash +bin/cake server -p 8765 +``` + +Then visit `http://localhost:8765` to see the welcome page. + +## Update + +Since this skeleton is a starting point for your application and various files +would have been modified as per your needs, there isn't a way to provide +automated upgrades, so you have to do any updates manually. + +## Configuration + +Read and edit `config/app.php` and setup the `'Datasources'` and any other +configuration relevant for your application. + +## Layout + +The app skeleton uses a subset of [Foundation](http://foundation.zurb.com/) (v5) CSS +framework by default. You can, however, replace it with any other library or +custom styles. diff --git a/app/composer.json b/app/composer.json index 6b3354ae8..ac9997dc8 100644 --- a/app/composer.json +++ b/app/composer.json @@ -10,6 +10,7 @@ "cakephp/cakephp": "3.6.*", "cakephp/migrations": "^1.0", "cakephp/plugin-installer": "^1.0", + "doctrine/dbal": "^2.9", "josegonzalez/dotenv": "2.*", "mobiledetect/mobiledetectlib": "2.*" }, diff --git a/app/composer.lock b/app/composer.lock index ad3a97de8..1046ed046 100644 --- a/app/composer.lock +++ b/app/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "486ee95971d8d7984bd7085037dc3921", + "content-hash": "b9b672e596c49bbd0ec228cbdf26f427", "packages": [ { "name": "adodb/adodb-php", @@ -343,6 +343,237 @@ "description": "A composer installer for CakePHP 3.0+ plugins.", "time": "2017-12-24T21:09:29+00:00" }, + { + "name": "doctrine/cache", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", + "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/coding-standard": "^4.0", + "mongodb/mongodb": "^1.1", + "phpunit/phpunit": "^7.0", + "predis/predis": "~1.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ], + "time": "2018-08-21T18:01:43+00:00" + }, + { + "name": "doctrine/dbal", + "version": "v2.9.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", + "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", + "shasum": "" + }, + "require": { + "doctrine/cache": "^1.0", + "doctrine/event-manager": "^1.0", + "ext-pdo": "*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^5.0", + "jetbrains/phpstorm-stubs": "^2018.1.2", + "phpstan/phpstan": "^0.10.1", + "phpunit/phpunit": "^7.4", + "symfony/console": "^2.0.5|^3.0|^4.0", + "symfony/phpunit-bridge": "^3.4.5|^4.0.5" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.9.x-dev", + "dev-develop": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "dbal", + "mysql", + "persistence", + "pgsql", + "php", + "queryobject" + ], + "time": "2018-12-31T03:27:51+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^4.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Doctrine Event Manager component", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "eventdispatcher", + "eventmanager" + ], + "time": "2018-06-11T11:59:03+00:00" + }, { "name": "josegonzalez/dotenv", "version": "2.1.0", diff --git a/app/config/routes.php b/app/config/routes.php index bf1402667..173a3aa6d 100644 --- a/app/config/routes.php +++ b/app/config/routes.php @@ -98,47 +98,3 @@ * As of Cake v3.6 it is no longer necessary to call this * Plugin::routes(); */ - - -/* XXX clean up this before commit -// check getParams - -// Create a route that only responds to GET requests. -$routes->get( - '/cooks/:id', - ['controller' => 'Users', 'action' => 'view'], - 'users:view' -); - -// Create a route that only responds to PUT requests -$routes->put( - '/cooks/:id', - ['controller' => 'Users', 'action' => 'update'], - 'users:update' -); - -$routes->connect( - '/:controller/:id', - ['action' => 'view'] -)->setPatterns(['id' => '[0-9]+']); - - -$routes->connect( - '/cooks/:action/*', ['controller' => 'Users'] -); - -Router::connect( - '/voot/groups/:memberid/:groupid', - array('controller' => 'voot', 'action' => 'groups') -); - -Router::connect( - '/voot/groups/:memberid', - array('controller' => 'voot', 'action' => 'groups') -); - -Router::connect( - '/voot/people/:memberid/:groupid', - array('controller' => 'voot', 'action' => 'people') -); -*/ \ No newline at end of file diff --git a/app/config/schema/schema.json b/app/config/schema/schema.json new file mode 100644 index 000000000..633e99509 --- /dev/null +++ b/app/config/schema/schema.json @@ -0,0 +1,195 @@ +{ + "description": "COmanage Match Database Schema File", + "format": "1", + "license": "Apache 2, See NOTICE and LICENSE files", + + "XXX": [ + "remove schema.xml; adodb can't be removed until inline adodb calls are rewritten", + "review https://www.doctrine-project.org/projects/doctrine-dbal/en/2.9/reference/known-vendor-issues.html#known-vendor-issues" + ], + + "columnLibrary": { + "comment": "columns with names matching those defined here will by default inherit these properties", + + "columns": { + "description": { "type": "string", "size": 128 }, + "id": { "type": "integer", "autoincrement": true, "primarykey": true }, + "matchgrid_id": { "type": "integer", "foreignkey": { "table": "matchgrids", "column": "id" }, "notnull": true }, + "name": { "type": "string", "size": 64, "notnull": true }, + "status": { "type": "string", "size": 2 } + } + }, + + "tables": { + "meta": { + "columns": { + "id": {}, + "upgrade_version": { "type": "string", "size": 16 } + }, + "timestamps": false, + "changelog": false + }, + + "matchgrids": { + "columns": { + "id": {}, + "description": {}, + "table_name": { "type": "string", "size": 128, "notnull": true }, + "status": {}, + "referenceid_method": { "type": "string", "size": 2 }, + "referenceid_start": { "type": "integer" }, + "referenceid_prefix": { "type": "string", "size": 32 } + }, + "indexes": { + "matchgrids_i1": { + "columns": [ "table_name" ], +"XXX": "changelog obviates unique keys?", + "unique": true + } + }, + "changelog": false + }, + + "permissions": { + "columns": { + "id": {}, + "matchgrid_id": { "notnull": false }, + "username": { + "XXX": "we don't currently define username anywhere, ie there is no users table", + "type": "string", "size": 128 + }, + "permission": { "type": "string", "size": 2 } + }, + "indexes": { + "permissions_i1": { + "columns": [ "matchgrid_id" ] + } + }, + "changelog": false + }, + + "attribute_groups": { + "columns": { + "id": {}, + "matchgrid_id": {}, + "name": {} + }, + "indexes": { + "attribute_groups_i1": { + "columns": [ "matchgrid_id" ] + } + }, + "changelog": false + }, + + "attributes": { + "columns": { + "id": {}, + "matchgrid_id": {}, + "attribute_group_id": { "type": "integer", "foreignkey": { "table": "attribute_groups", "column": "id" } }, + "name": {}, + "description": {}, + "api_name": { "type": "string", "size": 128 }, + "alphanumeric": { "type": "boolean" }, + "case_sensitive": { "type": "boolean" }, + "invalidates": { "type": "boolean" }, + "null_equivalents": { "type": "boolean" }, + "required": { "type": "boolean" }, + "search_distance": { "type": "integer" }, + "search_exact": { "type": "boolean" }, + "search_substr_from": { "type": "integer" }, + "search_substr_for": { "type": "integer" } + }, + "indexes": { + "attributes_i1": { + "columns": [ "matchgrid_id" ] + }, + "attributes_i2": { + "comment": "We don't really need this index but DBAL will create it anyway, with a random name", + "columns": [ "attribute_group_id" ] + } + }, + "changelog": false + }, + + "rules": { + "columns": { + "id": {}, + "matchgrid_id": {}, + "name": {}, + "description": {}, + "confidence_mode": { "type": "string", "size": 2 }, + "ordr": { "type": "integer" } + }, + "indexes": { + "rules_i1": { + "columns": [ "matchgrid_id" ] + } + }, + "changelog": false + }, + + "rule_attributes": { + "columns": { + "id": {}, + "rule_id": { "type": "integer", "foreignkey": { "table": "rules", "column": "id" } }, + "attribute_id": { "type": "integer", "foreignkey": { "table": "attributes", "column": "id" } }, + "search_type": { "type": "string", "size": 2 } + }, + "indexes": { + "rule_attributes_i1": { + "columns": [ "rule_id" ] + }, + "rule_attributes_i2": { + "comment": "We don't really need this index but DBAL will create it anyway, with a random name", + "columns": [ "attribute_id" ] + } + }, + "changelog": false + }, + + "systems_of_record": { + "columns": { + "id": {}, + "matchgrid_id": {}, + "label": { "type": "string", "size": 80 }, + "resolution_mode": { "type": "string", "size": 2 } + }, + "indexes": { + "systems_of_record_i1": { + "columns": [ "matchgrid_id" ] + } + }, + "changelog": false + }, + + "api_users": { + "columns": { + "id": {}, + "matchgrid_id": { "notnull": false }, + "system_of_record_id": { "type": "integer", "foreignkey": { "table": "systems_of_record", "column": "id" } }, + "username": { "type": "string", "size": 128 }, + "password": { "type": "string", "size": 255 } + }, + "indexes": { + "api_users_i1": { + "columns": [ "matchgrid_id" ] + }, + "api_users_i2": { + "columns": [ "username" ] + }, + "api_users_i3": { + "comment": "We don't really need this index but DBAL will create it anyway, with a random name", + "columns": [ "system_of_record_id" ] + } + }, + "changelog": false + } + }, + + "drop-tables":[ + { +"XXX": "a list of tables to manually drop, not yet implemented" + } + ] +} \ No newline at end of file diff --git a/app/config/schema/schema.xml b/app/config/schema/schema.xml deleted file mode 100644 index 4e083a590..000000000 --- a/app/config/schema/schema.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - - - - -
- - - - - - - - - - - - - - - - - table_name - - -
- - - - - - - - - - - REFERENCES matchgrids(id) - - - - - - - username - -
- - - - - - - - REFERENCES matchgrids(id) - - - - - - - matchgrid_id - -
- - - - - - - - REFERENCES matchgrids(id) - - - - - - - - REFERENCES attribute_groups(id) - - - - - - - - - - - - - - - matchgrid_id - -
- - - - - - - - REFERENCES matchgrids(id) - - - - - - - - - - - - - matchgrid_id - -
- - - - - - - - - REFERENCES rules(id) - - - REFERENCES attributes(id) - - - - - - - - rule_id - -
- - - - - - - - REFERENCES matchgrids(id) - - - - - - - - - matchgrid_id - -
- - - - - - - - REFERENCES matchgrids(id) - - - REFERENCES systems_of_record(id) - - - - - - - - matchgrid_id - - - - username - -
-
\ No newline at end of file diff --git a/app/src/Command/DatabaseCommand.php b/app/src/Command/DatabaseCommand.php index 8837ec54a..d12024832 100644 --- a/app/src/Command/DatabaseCommand.php +++ b/app/src/Command/DatabaseCommand.php @@ -1,6 +1,6 @@ addOption('not', [ + 'short' => 'n', + 'boolean' => true, + 'help' => __(__('product.code').'.cmd.opt.not') + ]); + + return $parser; + } + /** * Execute the Database Command. * - * @since COmanage Match v1.0.0 + * @since COmanage Match v1.0.0, COmanage Registry v5.0.0 * @param Arguments $args Command Arguments * @param ConsoleIo $io Console IO + * @throws RuntimeException */ public function execute(Arguments $args, ConsoleIo $io) { - // Database schema management. We use adodb rather than Cake's migrations + // Database schema management. We use Doctrine DBAL rather than Cake's migrations // (phinx) because migrations make development annoying (want to add a field // to a table after you've created it? that's a new migration!), and can't // provide a single representation of a given table (since you're recording - // diffs, not desired end state). + // diffs, not desired end state). ADOdb (used in earlier versions) was hard to + // debug and poorly maintained. DBAL doesn't have a schema format (like axmls) + // but it does everything else, and specifying a schema format is easy. + + // What component are we? + $COmponent = __('product.code'); + + // First try to parse our schema file + + $schemaFile = ROOT . DS . 'config' . DS . 'schema' . DS . 'schema.json'; + + if(!is_readable($schemaFile)) { + throw new \RuntimeException(__($COmponent.'.er.file', [$schemaFile])); + } + + $json = file_get_contents($schemaFile); + + $schemaConfig = json_decode($json); + + if(!$schemaConfig) { + // json_last_error[_msg]() are pretty useless. If you are debugging here, + // it's most likely because of one of the following: + // - An unmatched brace { } + // - A trailing comma (permitted in PHP but not JSON) + // - Single quotes instead of double quotes + throw new \RuntimeException(__($COmponent.'.er.schema.parse', [$schemaFile])); + } // Use the ConnectionManager to get the database config to pass to adodb. $db = ConnectionManager::get('default'); @@ -59,53 +112,162 @@ public function execute(Arguments $args, ConsoleIo $io) { // $db is a ConnectionInterface object $cfg = $db->config(); - // We only support Postgres (at least for now) - if($cfg['driver'] != "Cake\Database\Driver\Postgres") { - // We could also use $this->abort(), but then we'd have to $io->out the error - throw new \RuntimeException(__('match.er.db.driver' , [ $cfg['driver'] ])); - } + $config = new \Doctrine\DBAL\Configuration(); - // This ADOdb label actually supports postgres 8+, but Match requires 9.1 or latergamma681 + $cfargs = [ + 'dbname' => $cfg['database'], + 'user' => $cfg['username'], + 'password' => $cfg['password'], + 'host' => $cfg['host'], + 'driver' => ($cfg['driver'] == 'Cake\Database\Driver\Postgres' ? "pdo_pgsql" : "pdo_mysql") + ]; - $dbc = ADONewConnection('postgres9'); + $conn = DriverManager::getConnection($cfargs, $config); - if(!$dbc->Connect($cfg['host'], - $cfg['username'], - $cfg['password'], - $cfg['database'])) { - throw new \RuntimeException(__('match.er.db.connect', [$dbc->ErrorMsg()])); - } + $schema = new Schema(); - $schemaFile = ROOT . DS . 'config' . DS . 'schema' . DS . 'schema.xml'; + // Walk through $schemaConfig and build our schema in DBAL format. - if(!is_readable($schemaFile)) { - throw new \RuntimeException(__('match.er.file', [$schemaFile])); + foreach($schemaConfig->tables as $tName => $tCfg) { + $table = $schema->createTable($tName); + + foreach($tCfg->columns as $cName => $cCfg) { + // We allow "inherited" definitions from the fieldLibrary, so merge together + // the configurations (if appropriate) + + $colCfg = (object)array_merge((isset($schemaConfig->columnLibrary->columns->$cName) + ? (array)$schemaConfig->columnLibrary->columns->$cName + : []), + (array)$cCfg); + + if(!isset($colCfg->type)) { + throw new \RuntimeException(__('match.er.schema.column', [$tName, $cName])); + } + + // For type definitions see https://www.doctrine-project.org/api/dbal/2.9/Doctrine/DBAL/Types/Type.html + $options = []; + + if(isset($colCfg->autoincrement)) { + $options['autoincrement'] = $colCfg->autoincrement; + } + + if($colCfg->type == "string") { + $options['length'] = $colCfg->size; + } + + if(isset($colCfg->notnull)) { + $options['notnull'] = $colCfg->notnull; + } else { + $options['notnull'] = false; + } + + $table->addColumn($cName, $colCfg->type, $options); + + if(isset($colCfg->primarykey) && $colCfg->primarykey) { + $table->setPrimaryKey(["id"]); + } + + if(isset($colCfg->foreignkey)) { + $table->addForeignKeyConstraint($colCfg->foreignkey->table, + [$cName], + [$colCfg->foreignkey->column], + [], + // We name our foreign keys the same way they + // were previously named by adodb + $tName . "_" . $cName . "_fkey"); + } + } + + if(isset($tCfg->indexes)) { + // We don't autogenerate names for indexes so if the definition of an index + // changes DBAL can just rebuild that index instead of recreating every index + // on the table. (This should speed up schema updates vs ADOdb.) This does + // require each index to be named in the schema file, but we had to do that + // in axmls too, even though it rebuilt every index every time through. + + foreach($tCfg->indexes as $iName => $iCfg) { + // $flags and $options as passed to Index(), but otherwise undocumented + $flags = []; + $options = []; + + $table->addIndex($iCfg->columns, $iName, $flags, $options); + } + } + + // Default is to insert timestamp and changelog fields, unless disabled + + if(!isset($tCfg->timestamps) || $tCfg->timestamps) { + // Insert Cake metadata fields + $table->addColumn("created", "datetime"); + $table->addColumn("modified", "datetime", ['notnull' => false]); + } + + if(!isset($tCfg->changelog) || $tCfg->changelog) { + // Insert ChangelogBehavior metadata fields + $clColumn = \Cake\Utility\Inflector::singularize($tName) . "_id"; + $table->addColumn($clColumn, 'integer', ['notnull' => false]); + $table->addColumn("revision", 'integer', ['notnull' => false]); + $table->addColumn("deleted", 'boolean', ['notnull' => false]); + $table->addColumn("actor_identifier", 'string', ['length' => 256, 'notnull' => false]); + + $table->addForeignKeyConstraint($table, [$clColumn], ['id'], [], $tName . "_" . $clColumn . "_fkey"); + $table->addIndex([$clColumn], $tName . "_icl", [], []); + } } - $io->out(__('match.cmd.db.schema', [$schemaFile])); - - $schema = new \adoSchema($dbc); - // ParseSchema is generating bad SQL for Postgres. eg: - // ALTER TABLE cm_cos ALTER COLUMN id SERIAL - // which (1) should be ALTER TABLE cm_cos ALTER COLUMN id TYPE SERIAL - // and (2) SERIAL isn't usable in an ALTER TABLE statement - // So we continue on error (CO-1570) - $schema->ContinueOnError(true); - - // If we add support for MySQL, check to see if the translation from - // boolean to TINYINT performed by Registry is still required. - $sql = $schema->ParseSchema($schemaFile); - - switch($schema->ExecuteSchema($sql)) { - case 2: // !!! - $io->out(__('match.cmd.db.ok')); - break; - default: - $io->out(__('match.er.db.schema')); - break; - } + // This is the SQL that represents the desired state of the database + $toSql = $schema->toSql($conn->getDatabasePlatform()); + + // SchemaManager provides info about the database + $sm = $conn->getSchemaManager(); + + // The is the current database representation + $curSchema = $sm->createSchema(); - $dbc->Disconnect(); + $fromSql = $curSchema->toSql($conn->getDatabasePlatform()); + + // Really run the SQL? + $doSQL = !$args->getOption('not'); + + try { + // We manually call compare so we can get the SchemaDiff object. We need + // this for toSaveSql(), which won't drop undocumented tables (like the + // matchgrids, which are dynamically created and so won't be in the + // schema file). +// $diffSql = $curSchema->getMigrateToSql($schema, $conn->getDatabasePlatform()); + $comparator = new Comparator(); + $schemaDiff = $comparator->compare($curSchema, $schema); + + $diffSql = $schemaDiff->toSaveSql($conn->getDatabasePlatform()); + + // We don't start a transaction since in general we always want to move to + // the desired state, and if we fail in flight it's probably a bug that + // needs to be fixed. + + foreach($diffSql as $sql) { + $io->out($sql); + + if($cfg['driver'] == 'Cake\Database\Driver\Postgres' + && preg_match("/^DROP SEQUENCE [a-z]*_id_seq/", $sql)) { + // Remove the DROP SEQUENCE statements in $fromSql because they're Postgres automagic + // being misinterpretted. (Note toSaveSql might mask this now.) + // XXX Maybe debug and file a PR to not emit DROP SEQUENCE on PG for autoincrementesque fields? + $io->out("Skipping sequence drop"); + } else { + if($doSQL) { + $stmt = $conn->query($sql); + // $stmt just returns the query string so we don't bother examining it + } + } + } + + if(!$doSQL) { + $io->out('** SQL NOT EXECUTED **'); + } + } + catch(\Exception $e) { + $io->out($e->getMessage()); + } // We might run bin/cake schema_cache clear or // bin/cake schema_cache build --connection default diff --git a/app/src/Controller/MatchgridsController.php b/app/src/Controller/MatchgridsController.php index c686734cb..bce41eff1 100644 --- a/app/src/Controller/MatchgridsController.php +++ b/app/src/Controller/MatchgridsController.php @@ -147,7 +147,7 @@ public function pending(string $id) { } /** - * Display the set of pending requests. + * Reconcile a pending request. * * @since COmanage Match v1.0.0 * @param String $id Matchgrid ID diff --git a/app/src/Locale/en_US/default.po b/app/src/Locale/en_US/default.po index b2d5a80d7..65ae30ff3 100644 --- a/app/src/Locale/en_US/default.po +++ b/app/src/Locale/en_US/default.po @@ -22,6 +22,10 @@ # @since COmanage Match v1.0.0 # @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) +# For common code to know which component it is +msgid "product.code" +msgstr "match" + # This should match the ISO 639-1 two letter language code for the translation msgid "match.meta.lang" msgstr "en" @@ -61,6 +65,9 @@ msgstr "Username of initial platform administrator" msgid "match.cmd.opt.force" msgstr "Force a rerun of setup (only if you know what you are doing)"" +msgid "match.cmd.opt.not" +msgstr "Calculate changes but do not apply" + msgid "match.cmd.se.admin" msgstr "- Creating initial administrator permission" @@ -193,6 +200,12 @@ msgstr "Request ID {0} not found" msgid "match.er.save" msgstr "Save Failed ({0})" +msgid "match.er.schema.column" +msgstr "No type defined for table {0} column {1}" + +msgid "match.er.schema.parse" +msgstr "Failed to parse file {0}" + msgid "match.er.unauthorized" msgstr "{0} does not have any valid permissions" diff --git a/app/vendor/bin/doctrine-dbal b/app/vendor/bin/doctrine-dbal new file mode 120000 index 000000000..58a8a89c2 --- /dev/null +++ b/app/vendor/bin/doctrine-dbal @@ -0,0 +1 @@ +../doctrine/dbal/bin/doctrine-dbal \ No newline at end of file diff --git a/app/vendor/cakephp/bake/composer.json b/app/vendor/cakephp/bake/composer.json index f6143c6e7..05ef8a9f5 100644 --- a/app/vendor/cakephp/bake/composer.json +++ b/app/vendor/cakephp/bake/composer.json @@ -19,13 +19,13 @@ }, "require": { "php": ">=5.6.0", - "cakephp/cakephp": "^3.5.10", + "cakephp/cakephp": "^3.6.0", "cakephp/plugin-installer": "^1.0", - "wyrihaximus/twig-view": "^4.2.1" + "wyrihaximus/twig-view": "^4.3.4" }, "require-dev": { "cakephp/cakephp-codesniffer": "^3.0", - "phpunit/phpunit": "^5.7 | ^6.0" + "phpunit/phpunit": "^5.7.14|^6.0" }, "autoload": { "psr-4": { diff --git a/app/vendor/cakephp/bake/phpstan.neon b/app/vendor/cakephp/bake/phpstan.neon index d08453c72..e4f5c4fbf 100644 --- a/app/vendor/cakephp/bake/phpstan.neon +++ b/app/vendor/cakephp/bake/phpstan.neon @@ -2,7 +2,5 @@ parameters: autoload_files: - tests/bootstrap.php ignoreErrors: - - '#Call to an undefined method Cake\\Datasource\\SchemaInterface::columnType\(\)#' - '#Call to an undefined method Cake\\Database\\Type::getDateTimeClassName\(\)#' - '#Constant TESTS not found#' - - '#Call to an undefined method Cake\\ORM\\Association::junction\(\)#' diff --git a/app/vendor/cakephp/bake/src/Plugin.php b/app/vendor/cakephp/bake/src/Plugin.php new file mode 100644 index 000000000..2a25b6c38 --- /dev/null +++ b/app/vendor/cakephp/bake/src/Plugin.php @@ -0,0 +1,52 @@ +addPlugin('WyriHaximus/TwigView'); + } +} diff --git a/app/vendor/cakephp/bake/src/Shell/BakeShell.php b/app/vendor/cakephp/bake/src/Shell/BakeShell.php index d5c1e2439..3e42472ae 100644 --- a/app/vendor/cakephp/bake/src/Shell/BakeShell.php +++ b/app/vendor/cakephp/bake/src/Shell/BakeShell.php @@ -56,6 +56,7 @@ public function startup() parent::startup(); Configure::write('debug', true); Cache::disable(); + // Loading WyriHaximus/TwigView Plugin through the Plugin::load() for backward compatibility. if (!Plugin::loaded('WyriHaximus/TwigView')) { Plugin::load('WyriHaximus/TwigView', ['bootstrap' => true]); } diff --git a/app/vendor/cakephp/bake/src/Shell/Task/BakeTemplateTask.php b/app/vendor/cakephp/bake/src/Shell/Task/BakeTemplateTask.php index 414064278..b2e319e3c 100644 --- a/app/vendor/cakephp/bake/src/Shell/Task/BakeTemplateTask.php +++ b/app/vendor/cakephp/bake/src/Shell/Task/BakeTemplateTask.php @@ -65,7 +65,9 @@ public function getView() $view = new BakeView(new Request(), new Response(), null, $viewOptions); $event = new Event('Bake.initialize', $view); EventManager::instance()->dispatch($event); - $this->View = $event->subject; + /** @var \Bake\View\BakeView $view */ + $view = $event->getSubject(); + $this->View = $view; return $this->View; } diff --git a/app/vendor/cakephp/bake/src/Shell/Task/CommandTask.php b/app/vendor/cakephp/bake/src/Shell/Task/CommandTask.php new file mode 100644 index 000000000..ffc9c36fc --- /dev/null +++ b/app/vendor/cakephp/bake/src/Shell/Task/CommandTask.php @@ -0,0 +1,55 @@ +listAll(); foreach ($tables as $table) { - TableRegistry::clear(); + TableRegistry::getTableLocator()->clear(); $this->main($table); } } @@ -121,10 +121,10 @@ public function bake($controllerName) $plugin .= '.'; } - if (TableRegistry::exists($plugin . $currentModelName)) { - $modelObj = TableRegistry::get($plugin . $currentModelName); + if (TableRegistry::getTableLocator()->exists($plugin . $currentModelName)) { + $modelObj = TableRegistry::getTableLocator()->get($plugin . $currentModelName); } else { - $modelObj = TableRegistry::get($plugin . $currentModelName, [ + $modelObj = TableRegistry::getTableLocator()->get($plugin . $currentModelName, [ 'connectionName' => $this->connection ]); } @@ -200,7 +200,7 @@ public function bakeController($controllerName, array $data) * Assembles and writes a unit test file * * @param string $className Controller class name - * @return string|null Baked test + * @return string|bool Baked test */ public function bakeTest($className) { diff --git a/app/vendor/cakephp/bake/src/Shell/Task/FixtureTask.php b/app/vendor/cakephp/bake/src/Shell/Task/FixtureTask.php index 421a49bfe..492e44bc4 100644 --- a/app/vendor/cakephp/bake/src/Shell/Task/FixtureTask.php +++ b/app/vendor/cakephp/bake/src/Shell/Task/FixtureTask.php @@ -17,7 +17,7 @@ use Cake\Console\Shell; use Cake\Core\Configure; use Cake\Database\Exception; -use Cake\Database\Schema\Table; +use Cake\Database\Schema\TableSchema; use Cake\Datasource\ConnectionManager; use Cake\ORM\TableRegistry; use Cake\Utility\Inflector; @@ -170,19 +170,13 @@ public function bake($model, $useTable = null) $import = sprintf("[%s]", implode(', ', $importBits)); } - $connection = ConnectionManager::get($this->connection); - if (!method_exists($connection, 'schemaCollection')) { - throw new \RuntimeException( - 'Cannot generate fixtures for connections that do not implement schemaCollection()' - ); - } - $schemaCollection = $connection->schemaCollection(); try { - $data = $schemaCollection->describe($useTable); + $data = $this->readSchema($model, $useTable); } catch (Exception $e) { + TableRegistry::getTableLocator()->remove($model); $useTable = Inflector::underscore($model); $table = $useTable; - $data = $schemaCollection->describe($useTable); + $data = $this->readSchema($model, $useTable); } if ($modelImport === null) { @@ -203,6 +197,29 @@ public function bake($model, $useTable = null) return $this->generateFixtureFile($model, compact('records', 'table', 'schema', 'import')); } + /** + * Get schema metadata for the current table mapping. + * + * @param string $name The model alias to use + * @param string $table The table name to get schema metadata for. + * @return \Cake\Database\Schema\TableSchema + */ + public function readSchema($name, $table) + { + $connection = ConnectionManager::get($this->connection); + + if (TableRegistry::getTableLocator()->exists($name)) { + $model = TableRegistry::getTableLocator()->get($name); + } else { + $model = TableRegistry::getTableLocator()->get($name, [ + 'table' => $table, + 'connection' => $connection + ]); + } + + return $model->getSchema(); + } + /** * Generate the fixture file, and write to disk * @@ -244,28 +261,28 @@ public function generateFixtureFile($model, array $otherVars) /** * Generates a string representation of a schema. * - * @param \Cake\Database\Schema\Table $table Table schema + * @param \Cake\Database\Schema\TableSchema $table Table schema * @return string fields definitions */ - protected function _generateSchema(Table $table) + protected function _generateSchema(TableSchema $table) { $cols = $indexes = $constraints = []; foreach ($table->columns() as $field) { - $fieldData = $table->column($field); + $fieldData = $table->getColumn($field); $properties = implode(', ', $this->_values($fieldData)); $cols[] = " '$field' => [$properties],"; } foreach ($table->indexes() as $index) { - $fieldData = $table->index($index); + $fieldData = $table->getIndex($index); $properties = implode(', ', $this->_values($fieldData)); $indexes[] = " '$index' => [$properties],"; } foreach ($table->constraints() as $index) { - $fieldData = $table->constraint($index); + $fieldData = $table->getConstraint($index); $properties = implode(', ', $this->_values($fieldData)); $constraints[] = " '$index' => [$properties],"; } - $options = $this->_values($table->options()); + $options = $this->_values($table->getOptions()); $content = implode("\n", $cols) . "\n"; if (!empty($indexes)) { @@ -318,17 +335,17 @@ protected function _values($values) /** * Generate String representation of Records * - * @param \Cake\Database\Schema\Table $table Table schema array + * @param \Cake\Database\Schema\TableSchema $table Table schema array * @param int $recordCount The number of records to generate. * @return array Array of records to use in the fixture. */ - protected function _generateRecords(Table $table, $recordCount = 1) + protected function _generateRecords(TableSchema $table, $recordCount = 1) { $records = []; for ($i = 0; $i < $recordCount; $i++) { $record = []; foreach ($table->columns() as $field) { - $fieldInfo = $table->column($field); + $fieldInfo = $table->getColumn($field); $insert = ''; switch ($fieldInfo['type']) { case 'decimal': @@ -408,13 +425,13 @@ protected function _makeRecordString($records) if ($val === 'NULL') { $val = 'null'; } - $values[] = " '$field' => $val"; + $values[] = " '$field' => $val"; } - $out .= " [\n"; + $out .= " [\n"; $out .= implode(",\n", $values); - $out .= "\n ],\n"; + $out .= "\n ],\n"; } - $out .= " ]"; + $out .= " ]"; return $out; } @@ -431,10 +448,10 @@ protected function _getRecordsFromTable($modelName, $useTable = null) { $recordCount = (isset($this->params['count']) ? $this->params['count'] : 10); $conditions = (isset($this->params['conditions']) ? $this->params['conditions'] : '1=1'); - if (TableRegistry::exists($modelName)) { - $model = TableRegistry::get($modelName); + if (TableRegistry::getTableLocator()->exists($modelName)) { + $model = TableRegistry::getTableLocator()->get($modelName); } else { - $model = TableRegistry::get($modelName, [ + $model = TableRegistry::getTableLocator()->get($modelName, [ 'table' => $useTable, 'connection' => ConnectionManager::get($this->connection) ]); @@ -444,6 +461,6 @@ protected function _getRecordsFromTable($modelName, $useTable = null) ->limit($recordCount) ->enableHydration(false); - return $records; + return $records->toArray(); } } diff --git a/app/vendor/cakephp/bake/src/Shell/Task/ModelTask.php b/app/vendor/cakephp/bake/src/Shell/Task/ModelTask.php index 62c2b6b1c..3a6cad4a1 100644 --- a/app/vendor/cakephp/bake/src/Shell/Task/ModelTask.php +++ b/app/vendor/cakephp/bake/src/Shell/Task/ModelTask.php @@ -21,6 +21,7 @@ use Cake\ORM\Table; use Cake\ORM\TableRegistry; use Cake\Utility\Inflector; +use Cake\Validation\Validation; /** * Task class for generating model files. @@ -166,7 +167,7 @@ public function all() { $tables = $this->listUnskipped(); foreach ($tables as $table) { - TableRegistry::clear(); + TableRegistry::getTableLocator()->clear(); $this->main($table); } } @@ -185,11 +186,11 @@ public function getTableObject($className, $table) $className = $plugin . '.' . $className; } - if (TableRegistry::exists($className)) { - return TableRegistry::get($className); + if (TableRegistry::getTableLocator()->exists($className)) { + return TableRegistry::getTableLocator()->get($className); } - return TableRegistry::get($className, [ + return TableRegistry::getTableLocator()->get($className, [ 'name' => $className, 'table' => $this->tablePrefix . $table, 'connection' => ConnectionManager::get($this->connection) @@ -291,7 +292,7 @@ public function getAssociationInfo(Table $table) $namespace = $appNamespace; $className = $association->className(); - if ($className !== null) { + if (strlen($className)) { list($plugin, $className) = pluginSplit($className); if ($plugin !== null) { $namespace = $plugin; @@ -405,7 +406,7 @@ public function findTableReferencedBy($schema, $keyField) public function findHasMany($model, array $associations) { $schema = $model->getSchema(); - $primaryKey = (array)$schema->primaryKey(); + $primaryKey = $schema->primaryKey(); $tableName = $schema->name(); $foreignKey = $this->_modelKey($tableName); @@ -650,7 +651,7 @@ public function getHiddenFields($model) * * @param \Cake\ORM\Table $model The model to introspect. * @param array $associations The associations list. - * @return array The validation rules. + * @return array|false The validation rules. */ public function getValidation($model, $associations = []) { @@ -664,7 +665,7 @@ public function getValidation($model, $associations = []) } $validate = []; - $primaryKey = (array)$schema->primaryKey(); + $primaryKey = $schema->primaryKey(); $foreignKeys = []; if (isset($associations['belongsTo'])) { foreach ($associations['belongsTo'] as $assoc) { @@ -707,11 +708,25 @@ public function fieldValidation($schema, $fieldName, array $metaData, $primaryKe } elseif ($metaData['type'] === 'uuid') { $rules['uuid'] = []; } elseif ($metaData['type'] === 'integer') { - $rules['integer'] = []; + if ($metaData['unsigned']) { + $rules['nonNegativeInteger'] = []; + } else { + $rules['integer'] = []; + } } elseif ($metaData['type'] === 'float') { $rules['numeric'] = []; + if ($metaData['unsigned']) { + $rules['greaterThanOrEqual'] = [ + 0 + ]; + } } elseif ($metaData['type'] === 'decimal') { $rules['decimal'] = []; + if ($metaData['unsigned']) { + $rules['greaterThanOrEqual'] = [ + 0 + ]; + } } elseif ($metaData['type'] === 'boolean') { $rules['boolean'] = []; } elseif ($metaData['type'] === 'date') { @@ -731,7 +746,7 @@ public function fieldValidation($schema, $fieldName, array $metaData, $primaryKe } } - if (in_array($fieldName, (array)$primaryKey)) { + if (in_array($fieldName, $primaryKey)) { $rules['allowEmpty'] = ["'create'"]; } elseif ($metaData['null'] === true) { $rules['allowEmpty'] = []; @@ -965,7 +980,7 @@ public function bakeTable($model, array $data = []) if (file_exists($filename)) { require_once $filename; } - TableRegistry::clear(); + TableRegistry::getTableLocator()->clear(); $emptyFile = $path . 'Table' . DS . 'empty'; $this->_deleteEmptyFile($emptyFile); @@ -1031,7 +1046,7 @@ protected function _getAllTables() 'Connections need to implement schemaCollection() to be used with bake.' ); } - $schema = $db->schemaCollection(); + $schema = $db->getSchemaCollection(); $tables = $schema->listTables(); if (empty($tables)) { $this->abort('Your database does not have any tables.'); @@ -1142,7 +1157,7 @@ public function bakeFixture($className, $useTable = null) * Assembles and writes a unit test file * * @param string $className Model class name - * @return string|null + * @return string|bool */ public function bakeTest($className) { diff --git a/app/vendor/cakephp/bake/src/Shell/Task/PluginTask.php b/app/vendor/cakephp/bake/src/Shell/Task/PluginTask.php index 5e00e47b8..8cde50354 100644 --- a/app/vendor/cakephp/bake/src/Shell/Task/PluginTask.php +++ b/app/vendor/cakephp/bake/src/Shell/Task/PluginTask.php @@ -87,7 +87,7 @@ public function main($name = null) return false; } if (!$this->bake($plugin)) { - $this->error(sprintf("An error occurred trying to bake: %s in %s", $plugin, $this->path . $plugin)); + $this->abort(sprintf("An error occurred trying to bake: %s in %s", $plugin, $this->path . $plugin)); } } @@ -210,7 +210,7 @@ protected function _generateFiles($pluginName, $path) sort($templates); foreach ($templates as $template) { - $template = substr($template, strrpos($template, 'Plugin') + 7, -4); + $template = substr($template, strrpos($template, 'Plugin' . DIRECTORY_SEPARATOR) + 7, -4); $template = rtrim($template, '.'); $this->_generateFile($template, $root); } @@ -253,8 +253,8 @@ protected function _modifyAutoloader($plugin, $path) $namespace = str_replace('/', '\\', $plugin); $config = json_decode(file_get_contents($file), true); - $config['autoload']['psr-4'][$namespace . '\\'] = $autoloadPath . $plugin . "/src"; - $config['autoload-dev']['psr-4'][$namespace . '\\Test\\'] = $autoloadPath . $plugin . "/tests"; + $config['autoload']['psr-4'][$namespace . '\\'] = $autoloadPath . $plugin . "/src/"; + $config['autoload-dev']['psr-4'][$namespace . '\\Test\\'] = $autoloadPath . $plugin . "/tests/"; $this->out('Modifying composer autoloader'); @@ -264,7 +264,7 @@ protected function _modifyAutoloader($plugin, $path) $composer = $this->findComposer(); if (!$composer) { - $this->error('Could not locate composer. Add composer to your PATH, or use the --composer option.'); + $this->abort('Could not locate composer. Add composer to your PATH, or use the --composer option.'); return false; } @@ -280,7 +280,7 @@ protected function _modifyAutoloader($plugin, $path) chdir($cwd); } catch (\RuntimeException $e) { $error = $e->getMessage(); - $this->error(sprintf('Could not run `composer dump-autoload`: %s', $error)); + $this->abort(sprintf('Could not run `composer dump-autoload`: %s', $error)); return false; } @@ -366,7 +366,7 @@ public function getOptionParser() /** * Uses either the CLI option or looks in $PATH and cwd for composer. * - * @return string|false Either the path to composer or false if it cannot be found. + * @return string|bool Either the path to composer or false if it cannot be found. */ public function findComposer() { diff --git a/app/vendor/cakephp/bake/src/Shell/Task/SimpleBakeTask.php b/app/vendor/cakephp/bake/src/Shell/Task/SimpleBakeTask.php index 028d6a479..edd6009d6 100644 --- a/app/vendor/cakephp/bake/src/Shell/Task/SimpleBakeTask.php +++ b/app/vendor/cakephp/bake/src/Shell/Task/SimpleBakeTask.php @@ -82,7 +82,9 @@ public function main($name = null) { parent::main(); if (empty($name)) { - return $this->error('You must provide a name to bake a ' . $this->name()); + $this->abort('You must provide a name to bake a ' . $this->name()); + + return null; } $name = $this->_getName($name); $name = Inflector::camelize($name); diff --git a/app/vendor/cakephp/bake/src/Shell/Task/TemplateTask.php b/app/vendor/cakephp/bake/src/Shell/Task/TemplateTask.php index d172fc5e3..f89d042e9 100644 --- a/app/vendor/cakephp/bake/src/Shell/Task/TemplateTask.php +++ b/app/vendor/cakephp/bake/src/Shell/Task/TemplateTask.php @@ -44,7 +44,7 @@ class TemplateTask extends BakeTask /** * path to Template directory * - * @var array + * @var string */ public $pathFragment = 'Template/'; @@ -79,7 +79,7 @@ class TemplateTask extends BakeTask /** * AssociationFilter utility * - * @var AssociationFilter + * @var \Bake\Utility\Model\AssociationFilter|null */ protected $_associationFilter = null; @@ -189,7 +189,7 @@ public function controller($table, $controller = null) if ($prefix) { $prefix .= '/'; } - $this->controllerClass = App::className($plugin . $prefix . $controller, 'Controller', 'Controller'); + $this->controllerClass = (string)App::className($plugin . $prefix . $controller, 'Controller', 'Controller'); } /** @@ -275,10 +275,10 @@ public function all() */ protected function _loadController() { - if (TableRegistry::exists($this->modelName)) { - $modelObject = TableRegistry::get($this->modelName); + if (TableRegistry::getTableLocator()->exists($this->modelName)) { + $modelObject = TableRegistry::getTableLocator()->get($this->modelName); } else { - $modelObject = TableRegistry::get($this->modelName, [ + $modelObject = TableRegistry::getTableLocator()->get($this->modelName, [ 'connectionName' => $this->connection ]); } @@ -331,7 +331,7 @@ protected function _loadController() * Assembles and writes bakes the view file. * * @param string $template Template file to use. - * @param string $content Content to write. + * @param string|true $content Content to write. * @param string $outputFile The output file to create. If null will use `$template` * @return string|false Generated file content. */ @@ -370,7 +370,7 @@ public function getContent($action, $vars = null) } if (empty($vars['primaryKey'])) { - $this->error('Cannot generate views for models with no primary key'); + $this->abort('Cannot generate views for models with no primary key'); return false; } diff --git a/app/vendor/cakephp/bake/src/Shell/Task/TestTask.php b/app/vendor/cakephp/bake/src/Shell/Task/TestTask.php index 939097cc5..a84c75f18 100644 --- a/app/vendor/cakephp/bake/src/Shell/Task/TestTask.php +++ b/app/vendor/cakephp/bake/src/Shell/Task/TestTask.php @@ -12,6 +12,7 @@ * @since 0.1.0 * @license http://www.opensource.org/licenses/mit-license.php MIT License */ + namespace Bake\Shell\Task; use Cake\Console\Shell; @@ -56,10 +57,11 @@ class TestTask extends BakeTask 'Helper' => 'View\Helper', 'Shell' => 'Shell', 'Task' => 'Shell\Task', - 'Shell_helper' => 'Shell\Helper', + 'ShellHelper' => 'Shell\Helper', 'Cell' => 'View\Cell', 'Form' => 'Form', 'Mailer' => 'Mailer', + 'Command' => 'Command', ]; /** @@ -68,18 +70,19 @@ class TestTask extends BakeTask * @var array */ public $classSuffixes = [ - 'entity' => '', - 'table' => 'Table', - 'controller' => 'Controller', - 'component' => 'Component', - 'behavior' => 'Behavior', - 'helper' => 'Helper', - 'shell' => 'Shell', - 'task' => 'Task', - 'shell_helper' => 'Helper', - 'cell' => 'Cell', - 'form' => 'Form', - 'mailer' => 'Mailer', + 'Entity' => '', + 'Table' => 'Table', + 'Controller' => 'Controller', + 'Component' => 'Component', + 'Behavior' => 'Behavior', + 'Helper' => 'Helper', + 'Shell' => 'Shell', + 'Task' => 'Task', + 'ShellHelper' => 'Helper', + 'Cell' => 'Cell', + 'Form' => 'Form', + 'Mailer' => 'Mailer', + 'Command' => 'Command', ]; /** @@ -99,6 +102,9 @@ class TestTask extends BakeTask public function main($type = null, $name = null) { parent::main(); + $type = $this->normalize($type); + $name = $this->_getName($name); + if (empty($type) && empty($name)) { $this->outputTypeChoices(); @@ -215,7 +221,8 @@ protected function _getClassOptions($namespace) */ public function bake($type, $className) { - if (!isset($this->classSuffixes[strtolower($type)]) || !isset($this->classTypes[ucfirst($type)])) { + $type = $this->normalize($type); + if (!isset($this->classSuffixes[$type]) || !isset($this->classTypes[$type])) { return false; } @@ -293,9 +300,7 @@ public function bake($type, $className) */ public function typeCanDetectFixtures($type) { - $type = strtolower($type); - - return in_array($type, ['controller', 'table']); + return in_array($type, ['Controller', 'Table'], true); } /** @@ -308,20 +313,20 @@ public function typeCanDetectFixtures($type) */ public function buildTestSubject($type, $class) { - if (strtolower($type) === 'table') { + if ($type === 'Table') { list(, $name) = namespaceSplit($class); $name = str_replace('Table', '', $name); if ($this->plugin) { $name = $this->plugin . '.' . $name; } - if (TableRegistry::exists($name)) { - $instance = TableRegistry::get($name); + if (TableRegistry::getTableLocator()->exists($name)) { + $instance = TableRegistry::getTableLocator()->get($name); } else { - $instance = TableRegistry::get($name, [ + $instance = TableRegistry::getTableLocator()->get($name, [ 'connectionName' => $this->connection ]); } - } elseif (strtolower($type) === 'controller') { + } elseif ($type === 'Controller') { $instance = new $class(new Request(), new Response()); } else { $instance = new $class(); @@ -344,13 +349,13 @@ public function getRealClassName($type, $class) if ($this->plugin) { $namespace = str_replace('/', '\\', $this->plugin); } - $suffix = $this->classSuffixes[strtolower($type)]; + $suffix = $this->classSuffixes[$type]; $subSpace = $this->mapType($type); if ($suffix && strpos($class, $suffix) === false) { $class .= $suffix; } $prefix = $this->_getPrefix(); - if (in_array(strtolower($type), ['controller', 'cell']) && $prefix) { + if (in_array($type, ['Controller', 'Cell'], true) && $prefix) { $subSpace .= '\\' . str_replace('/', '\\', $prefix); } @@ -379,7 +384,6 @@ public function getSubspacePath($type) */ public function mapType($type) { - $type = ucfirst($type); if (empty($this->classTypes[$type])) { throw new Exception('Invalid object type.'); } @@ -431,8 +435,7 @@ public function generateFixtureList($subject) } /** - * Process a model recursively and pull out all the - * model names converting them to fixture names. + * Process a model, pull out model name + associations converted to fixture names. * * @param \Cake\ORM\Table $subject A Model class to scan for associations and pull fixtures off of. * @return void @@ -444,7 +447,7 @@ protected function _processModel($subject) } $this->_addFixture($subject->getAlias()); foreach ($subject->associations()->keys() as $alias) { - $assoc = $subject->association($alias); + $assoc = $subject->getAssociation($alias); $target = $assoc->getTarget(); $name = $target->getAlias(); $subjectClass = get_class($subject); @@ -452,15 +455,8 @@ protected function _processModel($subject) if ($subjectClass !== 'Cake\ORM\Table' && $subjectClass === get_class($target)) { continue; } - if (!isset($this->_fixtures[$name])) { - $this->_processModel($target); - } - if ($assoc->type() === Association::MANY_TO_MANY) { - $junction = $assoc->junction(); - if (!isset($this->_fixtures[$junction->getAlias()])) { - $this->_processModel($junction); - } + $this->_addFixture($target->getAlias()); } } } @@ -508,9 +504,7 @@ protected function _addFixture($name) */ public function hasMockClass($type) { - $type = strtolower($type); - - return $type === 'controller'; + return $type === 'Controller'; } /** @@ -523,40 +517,40 @@ public function hasMockClass($type) public function generateConstructor($type, $fullClassName) { list(, $className) = namespaceSplit($fullClassName); - $type = strtolower($type); $pre = $construct = $post = ''; - if ($type === 'table') { + if ($type === 'Table') { $tableName = str_replace('Table', '', $className); - $pre = "\$config = TableRegistry::exists('{$tableName}') ? [] : ['className' => {$className}::class];"; - $construct = "TableRegistry::get('{$tableName}', \$config);"; + $pre = "\$config = TableRegistry::getTableLocator()->exists('{$tableName}') ? [] : ['className' => {$className}::class];"; + $construct = "TableRegistry::getTableLocator()->get('{$tableName}', \$config);"; } - if ($type === 'behavior' || $type === 'entity' || $type === 'form') { + if ($type === 'Behavior' || $type === 'Entity' || $type === 'Form') { $construct = "new {$className}();"; } - if ($type === 'helper') { + if ($type === 'Helper') { $pre = "\$view = new View();"; $construct = "new {$className}(\$view);"; } - if ($type === 'component') { + if ($type === 'Command') { + $construct = "\$this->useCommandRunner();"; + } + if ($type === 'Component') { $pre = "\$registry = new ComponentRegistry();"; $construct = "new {$className}(\$registry);"; } - if ($type === 'shell') { + if ($type === 'Shell') { $pre = "\$this->io = \$this->getMockBuilder('Cake\Console\ConsoleIo')->getMock();"; $construct = "new {$className}(\$this->io);"; } - if ($type === 'task') { - $pre = "\$this->io = \$this->getMockBuilder('Cake\Console\ConsoleIo')->getMock();\n"; - $construct = "\$this->getMockBuilder('{$fullClassName}')\n"; - $construct .= " ->setConstructorArgs([\$this->io])\n"; - $construct .= " ->getMock();"; + if ($type === 'Task') { + $pre = "\$this->io = \$this->getMockBuilder('Cake\Console\ConsoleIo')->getMock();"; + $construct = "new {$className}(\$this->io);"; } - if ($type === 'cell') { + if ($type === 'Cell') { $pre = "\$this->request = \$this->getMockBuilder('Cake\Http\ServerRequest')->getMock();\n"; $pre .= " \$this->response = \$this->getMockBuilder('Cake\Http\Response')->getMock();"; $construct = "new {$className}(\$this->request, \$this->response);"; } - if ($type === 'shell_helper') { + if ($type === 'ShellHelper') { $pre = "\$this->stub = new ConsoleOutput();\n"; $pre .= " \$this->io = new ConsoleIo(\$this->stub);"; $construct = "new {$className}(\$this->io);"; @@ -582,11 +576,9 @@ public function generateConstructor($type, $fullClassName) */ public function generateProperties($type, $subject, $fullClassName) { - $type = strtolower($type); - $properties = []; - switch (strtolower($type)) { - case 'cell': + switch ($type) { + case 'Cell': $properties[] = [ 'description' => 'Request mock', 'type' => '\Cake\Http\ServerRequest|\PHPUnit_Framework_MockObject_MockObject', @@ -599,8 +591,8 @@ public function generateProperties($type, $subject, $fullClassName) ]; break; - case 'shell': - case 'task': + case 'Shell': + case 'Task': $properties[] = [ 'description' => 'ConsoleIo mock', 'type' => '\Cake\Console\ConsoleIo|\PHPUnit_Framework_MockObject_MockObject', @@ -608,7 +600,7 @@ public function generateProperties($type, $subject, $fullClassName) ]; break; - case 'shell_helper': + case 'ShellHelper': $properties[] = [ 'description' => 'ConsoleOutput stub', 'type' => '\Cake\TestSuite\Stub\ConsoleOutput', @@ -622,7 +614,7 @@ public function generateProperties($type, $subject, $fullClassName) break; } - if ($type !== 'controller') { + if (!in_array($type, ['Controller', 'Command'])) { $properties[] = [ 'description' => 'Test subject', 'type' => '\\' . $fullClassName, @@ -643,17 +635,16 @@ public function generateProperties($type, $subject, $fullClassName) public function generateUses($type, $fullClassName) { $uses = []; - $type = strtolower($type); - if ($type === 'component') { + if ($type === 'Component') { $uses[] = 'Cake\Controller\ComponentRegistry'; } - if ($type === 'table') { + if ($type === 'Table') { $uses[] = 'Cake\ORM\TableRegistry'; } - if ($type === 'helper') { + if ($type === 'Helper') { $uses[] = 'Cake\View\View'; } - if ($type === 'shell_helper') { + if ($type === 'ShellHelper') { $uses[] = 'Cake\TestSuite\Stub\ConsoleOutput'; $uses[] = 'Cake\Console\ConsoleIo'; } @@ -710,7 +701,7 @@ public function getOptionParser() $parser = parent::getOptionParser(); $types = array_keys($this->classTypes); - $types = array_merge($types, array_map('strtolower', $types)); + $types = array_merge($types, array_map([$this, 'underscore'], $types)); $parser->setDescription( 'Bake test case skeletons for classes.' @@ -736,4 +727,26 @@ public function getOptionParser() return $parser; } + + /** + * Normalizes string into CamelCase format. + * + * @param string $string String to inflect + * @return string + */ + protected function normalize($string) + { + return Inflector::camelize(Inflector::underscore($string)); + } + + /** + * Helper to allow under_score format for CLI env usage. + * + * @param string $string String to inflect + * @return string + */ + protected function underscore($string) + { + return Inflector::underscore($string); + } } diff --git a/app/vendor/cakephp/bake/src/Template/Bake/Command/command.twig b/app/vendor/cakephp/bake/src/Template/Bake/Command/command.twig new file mode 100644 index 000000000..a0e4ccf49 --- /dev/null +++ b/app/vendor/cakephp/bake/src/Template/Bake/Command/command.twig @@ -0,0 +1,55 @@ +{# +/** + * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt + * Redistributions of files must retain the above copyright notice. + * + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://cakephp.org CakePHP(tm) Project + * @since 1.7.4 + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ +#} +add($rules->{{ rule.name }}(['{{ field }}']{{ (rule.extra ? (", '#{rule.extra}'") : '')|raw }})); + $rules->add($rules->{{ rule.name }}(['{{ field }}']{{ (rule.extra is defined and rule.extra ? (", '#{rule.extra}'") : '')|raw }})); {% endfor %} return $rules; diff --git a/app/vendor/cakephp/bake/src/Template/Bake/Plugin/composer.json.twig b/app/vendor/cakephp/bake/src/Template/Bake/Plugin/composer.json.twig index a573d8394..da1adf222 100644 --- a/app/vendor/cakephp/bake/src/Template/Bake/Plugin/composer.json.twig +++ b/app/vendor/cakephp/bake/src/Template/Bake/Plugin/composer.json.twig @@ -20,20 +20,20 @@ "type": "cakephp-plugin", "license": "MIT", "require": { - "cakephp/cakephp": "^3.4" + "cakephp/cakephp": "^3.5" }, "require-dev": { - "phpunit/phpunit": "^5.7|^6.0" + "phpunit/phpunit": "^5.7.14|^6.0" }, "autoload": { "psr-4": { - "{{ namespace }}\\": "src" + "{{ namespace }}\\": "src/" } }, "autoload-dev": { "psr-4": { - "{{ namespace }}\\Test\\": "tests", - "Cake\\Test\\": "./vendor/cakephp/cakephp/tests" + "{{ namespace }}\\Test\\": "tests/", + "Cake\\Test\\": "vendor/cakephp/cakephp/tests/" } } } diff --git a/app/vendor/cakephp/bake/src/Template/Bake/Plugin/phpunit.xml.dist.twig b/app/vendor/cakephp/bake/src/Template/Bake/Plugin/phpunit.xml.dist.twig index bd3feb5a5..cc31f7e37 100644 --- a/app/vendor/cakephp/bake/src/Template/Bake/Plugin/phpunit.xml.dist.twig +++ b/app/vendor/cakephp/bake/src/Template/Bake/Plugin/phpunit.xml.dist.twig @@ -19,7 +19,7 @@ processIsolation="false" stopOnFailure="false" syntaxCheck="false" - bootstrap="./tests/bootstrap.php" + bootstrap="tests/bootstrap.php" > @@ -28,25 +28,23 @@ - - ./tests/TestCase + + tests/TestCase/ - + - + - ./src/ + src/ diff --git a/app/vendor/cakephp/bake/src/Template/Bake/Plugin/src/Plugin.php.twig b/app/vendor/cakephp/bake/src/Template/Bake/Plugin/src/Plugin.php.twig new file mode 100644 index 000000000..3a4cc77fd --- /dev/null +++ b/app/vendor/cakephp/bake/src/Template/Bake/Plugin/src/Plugin.php.twig @@ -0,0 +1,27 @@ +{# +/** + * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * + * Licensed under The MIT License + * For full copyright and license information, please see the LICENSE.txt + * Redistributions of files must retain the above copyright notice. + * + * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @link http://cakephp.org CakePHP(tm) Project + * @since 1.7.0 + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ +#} +records = {{ records|raw }}; + parent::init(); + } {% endif %} } diff --git a/app/vendor/cakephp/bake/src/Template/Bake/tests/test_case.twig b/app/vendor/cakephp/bake/src/Template/Bake/tests/test_case.twig index b5600db2a..d652502df 100644 --- a/app/vendor/cakephp/bake/src/Template/Bake/tests/test_case.twig +++ b/app/vendor/cakephp/bake/src/Template/Bake/tests/test_case.twig @@ -16,11 +16,16 @@ */ #} {% set isController = type|lower == 'controller' %} +{% set isShell = type|lower == 'shell' %} +{% set isCommand = type|lower == 'command' %} {% if isController %} - {%- set uses = uses|merge(['Cake\\TestSuite\\IntegrationTestCase']) %} + {%- set superClassName = 'IntegrationTestCase' %} +{% elseif isShell or isCommand %} + {%- set superClassName = 'ConsoleIntegrationTestCase' %} {% else %} - {%- set uses = uses|merge(['Cake\\TestSuite\\TestCase']) %} + {%- set superClassName = 'TestCase' %} {% endif %} +{%- set uses = uses|merge(["Cake\\TestSuite\\#{superClassName}"]) %} {%- set uses = uses|sort %} {{ (subject ~ ' = ' ~ construction)|raw }} +{% endif %} {% if postConstruct %} {{ postConstruct|raw }} {% endif %} } +{% if not isCommand %} /** * tearDown method @@ -94,6 +98,7 @@ class {{ className }}Test extends TestCase parent::tearDown(); } {% endif %} +{% endif %} {%- for method in methods %} diff --git a/app/vendor/cakephp/bake/src/Utility/Model/AssociationFilter.php b/app/vendor/cakephp/bake/src/Utility/Model/AssociationFilter.php index af7e2038a..058ab1222 100644 --- a/app/vendor/cakephp/bake/src/Utility/Model/AssociationFilter.php +++ b/app/vendor/cakephp/bake/src/Utility/Model/AssociationFilter.php @@ -52,7 +52,7 @@ public function belongsToManyJunctionAliases(Table $table) return $val->junction()->getAlias(); }; - return array_map($extractor, $table->associations()->type('BelongsToMany')); + return array_map($extractor, $table->associations()->getByType('BelongsToMany')); } /** @@ -69,7 +69,7 @@ public function filterAssociations(Table $model) $associations = []; foreach ($keys as $type) { - foreach ($model->associations()->type($type) as $assoc) { + foreach ($model->associations()->getByType($type) as $assoc) { $target = $assoc->getTarget(); $assocName = $assoc->getName(); $alias = $target->getAlias(); diff --git a/app/vendor/cakephp/bake/src/View/Helper/BakeHelper.php b/app/vendor/cakephp/bake/src/View/Helper/BakeHelper.php index 7b47e25ef..191f797ce 100644 --- a/app/vendor/cakephp/bake/src/View/Helper/BakeHelper.php +++ b/app/vendor/cakephp/bake/src/View/Helper/BakeHelper.php @@ -24,7 +24,7 @@ class BakeHelper extends Helper /** * AssociationFilter utility * - * @var AssociationFilter + * @var \Bake\Utility\Model\AssociationFilter|null */ protected $_associationFilter = null; @@ -132,7 +132,7 @@ public function aliasExtractor($table, $assoc) $extractor = function ($val) { return $val->getTarget()->getAlias(); }; - $aliases = array_map($extractor, $table->associations()->type($assoc)); + $aliases = array_map($extractor, $table->associations()->getByType($assoc)); if ($assoc === 'HasMany') { return $this->_filterHasManyAssociationsAliases($table, $aliases); } @@ -191,13 +191,13 @@ public function classInfo($class, $type, $suffix) * @param \Cake\ORM\Table|null $modelObject Model object. * @param array $takeFields Take fields. * @param array $filterTypes Filter field types. - * @return \Cake\Collection\CollectionInterface + * @return array */ public function filterFields($fields, $schema, $modelObject = null, $takeFields = [], $filterTypes = ['binary']) { $fields = collection($fields) ->filter(function ($field) use ($schema, $filterTypes) { - return !in_array($schema->columnType($field), $filterTypes); + return !in_array($schema->getColumnType($field), $filterTypes); }); if (isset($modelObject) && $modelObject->hasBehavior('Tree')) { @@ -239,10 +239,10 @@ public function getViewFieldsData($fields, $schema, $associations) $groupedFields = collection($fields) ->filter(function ($field) use ($schema) { - return $schema->columnType($field) !== 'binary'; + return $schema->getColumnType($field) !== 'binary'; }) ->groupBy(function ($field) use ($schema, $associationFields) { - $type = $schema->columnType($field); + $type = $schema->getColumnType($field); if (isset($associationFields[$field])) { return 'string'; } @@ -284,7 +284,7 @@ public function getViewFieldsData($fields, $schema, $associations) */ public function columnData($field, $schema) { - return $schema->column($field); + return $schema->getColumn($field); } /** @@ -296,7 +296,7 @@ public function columnData($field, $schema) */ public function getAssociatedTableAlias($modelObj, $assoc) { - $association = $modelObj->association($assoc); + $association = $modelObj->getAssociation($assoc); return $association->getTarget()->getAlias(); } diff --git a/app/vendor/cakephp/bake/src/View/Helper/DocBlockHelper.php b/app/vendor/cakephp/bake/src/View/Helper/DocBlockHelper.php index 064fcf5d4..de919a8ac 100644 --- a/app/vendor/cakephp/bake/src/View/Helper/DocBlockHelper.php +++ b/app/vendor/cakephp/bake/src/View/Helper/DocBlockHelper.php @@ -135,7 +135,7 @@ public function buildEntityAssociationHintTypeMap(array $propertySchema) if ($info['association']->type() === Association::MANY_TO_ONE) { $properties = $this->_insertAfter( $properties, - $info['association']->foreignKey(), + $info['association']->getForeignKey(), [$property => $type] ); } else { @@ -243,6 +243,7 @@ public function buildTableAnnotations($associations, $associationInfo, $behavior $annotations[] = "@method \\{$namespace}\\Model\\Entity\\{$entity} newEntity(\$data = null, array \$options = [])"; $annotations[] = "@method \\{$namespace}\\Model\\Entity\\{$entity}[] newEntities(array \$data, array \$options = [])"; $annotations[] = "@method \\{$namespace}\\Model\\Entity\\{$entity}|bool save(\\Cake\\Datasource\\EntityInterface \$entity, \$options = [])"; + $annotations[] = "@method \\{$namespace}\\Model\\Entity\\{$entity}|bool saveOrFail(\\Cake\\Datasource\\EntityInterface \$entity, \$options = [])"; $annotations[] = "@method \\{$namespace}\\Model\\Entity\\{$entity} patchEntity(\\Cake\\Datasource\\EntityInterface \$entity, array \$data, array \$options = [])"; $annotations[] = "@method \\{$namespace}\\Model\\Entity\\{$entity}[] patchEntities(\$entities, array \$data, array \$options = [])"; $annotations[] = "@method \\{$namespace}\\Model\\Entity\\{$entity} findOrCreate(\$search, callable \$callback = null, \$options = [])"; diff --git a/app/vendor/cakephp/bake/tests/Fixture/BakeArticlesFixture.php b/app/vendor/cakephp/bake/tests/Fixture/BakeArticlesFixture.php index 07a5ebc4c..b3d351cd6 100644 --- a/app/vendor/cakephp/bake/tests/Fixture/BakeArticlesFixture.php +++ b/app/vendor/cakephp/bake/tests/Fixture/BakeArticlesFixture.php @@ -32,6 +32,8 @@ class BakeArticlesFixture extends TestFixture 'bake_user_id' => ['type' => 'integer', 'null' => false], 'title' => ['type' => 'string', 'length' => 50, 'null' => false], 'body' => 'text', + 'rating' => ['type' => 'float', 'unsigned' => true, 'default' => 0.0, 'null' => false], + 'score' => ['type' => 'decimal', 'unsigned' => true, 'default' => 0.0, 'null' => false], 'published' => ['type' => 'boolean', 'length' => 1, 'default' => false], 'created' => 'datetime', 'updated' => 'datetime', diff --git a/app/vendor/cakephp/bake/tests/Fixture/CategoryThreadsFixture.php b/app/vendor/cakephp/bake/tests/Fixture/CategoryThreadsFixture.php index 9881936a5..9f12e24ff 100644 --- a/app/vendor/cakephp/bake/tests/Fixture/CategoryThreadsFixture.php +++ b/app/vendor/cakephp/bake/tests/Fixture/CategoryThreadsFixture.php @@ -31,8 +31,8 @@ class CategoryThreadsFixture extends TestFixture 'id' => ['type' => 'integer'], 'parent_id' => ['type' => 'integer'], 'name' => ['type' => 'string', 'null' => false], - 'lft' => ['type' => 'integer'], - 'rght' => ['type' => 'integer'], + 'lft' => ['type' => 'integer', 'unsigned' => true], + 'rght' => ['type' => 'integer', 'unsigned' => true], 'created' => 'datetime', 'updated' => 'datetime', '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]] diff --git a/app/vendor/cakephp/bake/tests/Fixture/NumberTreesFixture.php b/app/vendor/cakephp/bake/tests/Fixture/NumberTreesFixture.php index d06fff4c3..6070da77e 100644 --- a/app/vendor/cakephp/bake/tests/Fixture/NumberTreesFixture.php +++ b/app/vendor/cakephp/bake/tests/Fixture/NumberTreesFixture.php @@ -33,9 +33,9 @@ class NumberTreesFixture extends TestFixture 'id' => ['type' => 'integer'], 'name' => ['type' => 'string', 'length' => 50, 'null' => false], 'parent_id' => 'integer', - 'lft' => ['type' => 'integer'], - 'rght' => ['type' => 'integer'], - 'depth' => ['type' => 'integer'], + 'lft' => ['type' => 'integer', 'unsigned' => true], + 'rght' => ['type' => 'integer', 'unsigned' => true], + 'depth' => ['type' => 'integer', 'unsigned' => true], '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]] ]; diff --git a/app/vendor/cakephp/bake/tests/bootstrap.php b/app/vendor/cakephp/bake/tests/bootstrap.php index 6892be7d8..1d9640033 100644 --- a/app/vendor/cakephp/bake/tests/bootstrap.php +++ b/app/vendor/cakephp/bake/tests/bootstrap.php @@ -54,7 +54,7 @@ if (!getenv('db_dsn')) { putenv('db_dsn=sqlite:///:memory:'); } -ConnectionManager::config('test', ['url' => getenv('db_dsn')]); +ConnectionManager::setConfig('test', ['url' => getenv('db_dsn')]); Plugin::load('Bake', [ 'path' => dirname(dirname(__FILE__)) . DS, diff --git a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php deleted file mode 100644 index 55181fbb6..000000000 --- a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php +++ /dev/null @@ -1,225 +0,0 @@ - - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @link http://pear.php.net/package/PHP_CodeSniffer - */ - -/** - * CakePHP_Sniffs_NamingConventions_UpperCaseConstantNameSniff. - * - * Ensures that constant names are all uppercase. - * - * @category PHP - * @package PHP_CodeSniffer - * @author Greg Sherwood - * @author Marc McIntyre - * @copyright 2006-2012 Squiz Pty Ltd (ABN 77 084 670 600) - * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence - * @version Release: 1.5.0RC3 - * @link http://pear.php.net/package/PHP_CodeSniffer - */ -namespace CakePHP\Sniffs\NamingConventions; - -use PHP_CodeSniffer\Files\File; -use PHP_CodeSniffer\Sniffs\Sniff; - -class UpperCaseConstantNameSniff implements Sniff -{ - - /** - * {@inheritDoc} - */ - public function register() - { - return [T_STRING]; - } - - /** - * {@inheritDoc} - */ - public function process(File $phpcsFile, $stackPtr) - { - $tokens = $phpcsFile->getTokens(); - $constName = $tokens[$stackPtr]['content']; - - // If this token is in a heredoc, ignore it. - if ($phpcsFile->hasCondition($stackPtr, T_START_HEREDOC) === true) { - return; - } - - // Special case for PHPUnit. - if ($constName === 'PHPUnit_MAIN_METHOD') { - return; - } - - // If the next non-whitespace token after this token - // is not an opening parenthesis then it is not a function call. - $openBracket = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); - if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) { - $functionKeyword = $phpcsFile->findPrevious( - [ - T_WHITESPACE, - T_COMMA, - T_COMMENT, - T_STRING, - T_NS_SEPARATOR, - ], - ($stackPtr - 1), - null, - true - ); - - $declarations = [ - T_FUNCTION, - T_CLASS, - T_INTERFACE, - T_TRAIT, - T_IMPLEMENTS, - T_EXTENDS, - T_INSTANCEOF, - T_NEW, - T_NAMESPACE, - T_USE, - T_AS, - T_GOTO, - T_INSTEADOF, - T_PROTECTED, - T_PRIVATE, - T_PUBLIC, - ]; - - if (in_array($tokens[$functionKeyword]['code'], $declarations) === true) { - // This is just a declaration; no constants here. - return; - } - - if ($tokens[$functionKeyword]['code'] === T_CONST) { - // This is a class constant. - if (strtoupper($constName) !== $constName) { - $error = 'Class constants must be uppercase; expected %s but found %s'; - $data = [ - strtoupper($constName), - $constName, - ]; - $phpcsFile->addError($error, $stackPtr, 'ClassConstantNotUpperCase', $data); - } - - return; - } - - // Is this a class name? - $nextPtr = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); - if ($tokens[$nextPtr]['code'] === T_DOUBLE_COLON) { - return; - } - - // Is this a namespace name? - if ($tokens[$nextPtr]['code'] === T_NS_SEPARATOR) { - return; - } - - // Is this an insteadof name? - if ($tokens[$nextPtr]['code'] === T_INSTEADOF) { - return; - } - - // Is this an as name? - if ($tokens[$nextPtr]['code'] === T_AS) { - return; - } - - // Is this a type hint? - if ($tokens[$nextPtr]['code'] === T_VARIABLE - || $phpcsFile->isReference($nextPtr) === true - ) { - return; - } - - // Is this a member var name? - $prevPtr = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); - if ($tokens[$prevPtr]['code'] === T_OBJECT_OPERATOR) { - return; - } - - // Is this a variable name, in the form ${varname} ? - if ($tokens[$prevPtr]['code'] === T_OPEN_CURLY_BRACKET) { - $nextPtr = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); - if ($tokens[$nextPtr]['code'] === T_CLOSE_CURLY_BRACKET) { - return; - } - } - - // Is this a namespace name? - if ($tokens[$prevPtr]['code'] === T_NS_SEPARATOR) { - return; - } - - // Is this an instance of declare() - $prevPtrDeclare = $phpcsFile->findPrevious([T_WHITESPACE, T_OPEN_PARENTHESIS], ($stackPtr - 1), null, true); - if ($tokens[$prevPtrDeclare]['code'] === T_DECLARE) { - return; - } - - // Is this a goto label target? - if ($tokens[$nextPtr]['code'] === T_COLON) { - if (in_array($tokens[$prevPtr]['code'], [T_SEMICOLON, T_OPEN_CURLY_BRACKET, T_COLON], true)) { - return; - } - } - - // This is a real constant. Ignore ::class from php5.5 - if (strtoupper($constName) !== $constName && $constName !== 'class') { - $error = 'Constants must be uppercase; expected %s but found %s'; - $data = [ - strtoupper($constName), - $constName, - ]; - $phpcsFile->addError($error, $stackPtr, 'ConstantNotUpperCase', $data); - } - } elseif (strtolower($constName) === 'define' || strtolower($constName) === 'constant') { - // This may be a "define" or "constant" function call. - - // Make sure this is not a method call. - $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); - if ($tokens[$prev]['code'] === T_OBJECT_OPERATOR - || $tokens[$prev]['code'] === T_DOUBLE_COLON - ) { - return; - } - - // The next non-whitespace token must be the constant name. - $constPtr = $phpcsFile->findNext(T_WHITESPACE, ($openBracket + 1), null, true); - if ($tokens[$constPtr]['code'] !== T_CONSTANT_ENCAPSED_STRING) { - return; - } - - $constName = $tokens[$constPtr]['content']; - - // Check for constants like self::CONSTANT. - $prefix = ''; - $splitPos = strpos($constName, '::'); - if ($splitPos !== false) { - $prefix = substr($constName, 0, ($splitPos + 2)); - $constName = substr($constName, ($splitPos + 2)); - } - - if (strtoupper($constName) !== $constName) { - $error = 'Constants must be uppercase; expected %s but found %s'; - $data = [ - $prefix . strtoupper($constName), - $prefix . $constName, - ]; - $phpcsFile->addError($error, $stackPtr, 'ConstantNotUpperCase', $data); - } - } - } -} diff --git a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Sniffs/WhiteSpace/OperatorSpacingSniff.php b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Sniffs/WhiteSpace/OperatorSpacingSniff.php index d6b20689f..1aca4e799 100644 --- a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Sniffs/WhiteSpace/OperatorSpacingSniff.php +++ b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Sniffs/WhiteSpace/OperatorSpacingSniff.php @@ -57,6 +57,7 @@ public function process(File $phpcsFile, $stackPtr) $tokens = $phpcsFile->getTokens(); // Skip default values in function declarations. + // and declare statements if ($tokens[$stackPtr]['code'] === T_EQUAL || $tokens[$stackPtr]['code'] === T_MINUS ) { @@ -65,7 +66,9 @@ public function process(File $phpcsFile, $stackPtr) $bracket = array_pop($parenthesis); if (isset($tokens[$bracket]['parenthesis_owner']) === true) { $function = $tokens[$bracket]['parenthesis_owner']; - if ($tokens[$function]['code'] === T_FUNCTION) { + if ($tokens[$function]['code'] === T_FUNCTION || + $tokens[$function]['code'] === T_DECLARE + ) { return; } } diff --git a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/NamingConventions/UpperCaseConstantNameUnitTest.inc b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/NamingConventions/UpperCaseConstantNameUnitTest.inc deleted file mode 100644 index c50b175f9..000000000 --- a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/NamingConventions/UpperCaseConstantNameUnitTest.inc +++ /dev/null @@ -1,37 +0,0 @@ - 1, - ]; - } - - /** - * {@inheritDoc} - */ - public function getWarningList() - { - return []; - } -} diff --git a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/WhiteSpace/OperatorSpacingUnitTest.inc b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/WhiteSpace/OperatorSpacingUnitTest.inc index edc4886bf..d04d62a05 100644 --- a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/WhiteSpace/OperatorSpacingUnitTest.inc +++ b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/WhiteSpace/OperatorSpacingUnitTest.inc @@ -1,4 +1,5 @@ 1, 3 => 1, - 4 => 2, - 5 => 1, + 4 => 1, + 5 => 2, 6 => 1, - 7 => 2, + 7 => 1, + 8 => 2, ]; } diff --git a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/WhiteSpace/OperatorSpacingunitTest.inc.fixed b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/WhiteSpace/OperatorSpacingunitTest.inc.fixed index cbe2c5c99..26c56125d 100644 --- a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/WhiteSpace/OperatorSpacingunitTest.inc.fixed +++ b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/Tests/WhiteSpace/OperatorSpacingunitTest.inc.fixed @@ -1,4 +1,5 @@ + @@ -111,6 +112,7 @@ + diff --git a/app/vendor/cakephp/cakephp-codesniffer/LICENSE.txt b/app/vendor/cakephp/cakephp-codesniffer/LICENSE.txt index 414ab1e72..5849d31d4 100644 --- a/app/vendor/cakephp/cakephp-codesniffer/LICENSE.txt +++ b/app/vendor/cakephp/cakephp-codesniffer/LICENSE.txt @@ -1,7 +1,7 @@ The MIT License CakePHP(tm) : The Rapid Development PHP Framework (http://cakephp.org) -Copyright (c) 2005-2013, Cake Software Foundation, Inc. +Copyright (c) 2005-2018, Cake Software Foundation, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,4 +25,4 @@ Cake Software Foundation, Inc. 1785 E. Sahara Avenue, Suite 490-204 Las Vegas, Nevada 89104, -United States of America. \ No newline at end of file +United States of America. diff --git a/app/vendor/cakephp/cakephp-codesniffer/README.md b/app/vendor/cakephp/cakephp-codesniffer/README.md index eb1ee9c6c..7de3b6a92 100644 --- a/app/vendor/cakephp/cakephp-codesniffer/README.md +++ b/app/vendor/cakephp/cakephp-codesniffer/README.md @@ -1,4 +1,9 @@ -# CakePHP Code Sniffer [![Build Status](https://travis-ci.org/cakephp/cakephp-codesniffer.png?branch=master)](http://travis-ci.org/cakephp/cakephp-codesniffer) +# CakePHP Code Sniffer + +[![Build Status](https://img.shields.io/travis/cakephp/cakephp-codesniffer/master.svg?style=flat-square)](https://travis-ci.org/cakephp/cakephp-codesniffer) +[![Coverage Status](https://img.shields.io/codecov/c/github/cakephp/cakephp-codesniffer.svg?style=flat-square)](https://codecov.io/github/cakephp/cakephp-codesniffer) +[![Total Downloads](https://img.shields.io/packagist/dt/cakephp/cakephp-codesniffer.svg?style=flat-square)](https://packagist.org/packages/cakephp/cakephp-codesniffer) +[![Latest Stable Version](https://img.shields.io/packagist/v/cakephp/cakephp-codesniffer.svg?style=flat-square)](https://packagist.org/packages/cakephp/cakephp-codesniffer) This code works with [phpcs](http://pear.php.net/manual/en/package.php.php-codesniffer.php) and checks code against the coding standards used in CakePHP. diff --git a/app/vendor/cakephp/cakephp/.varci.yml b/app/vendor/cakephp/cakephp/.varci.yml index a9fd806f0..d132e01e4 100644 --- a/app/vendor/cakephp/cakephp/.varci.yml +++ b/app/vendor/cakephp/cakephp/.varci.yml @@ -40,5 +40,6 @@ ruleset: - body matches "/\[x\] bug/" - 'not(body matches "/CakePHP Version: v?(\d+\.)?(\d+\.)?(\*|\d+)/")' - 'not(body matches "/CakePHP Version: [0-9a-f]{5,40}/")' + - 'not(body matches "/cakephp\/cakephp\s+\d+\.\d+\.\d+/")' comment: '{{ user.login }}, please include the CakePHP version number you are using in your description. It helps us debug your issue.' diff --git a/app/vendor/cakephp/cakephp/VERSION.txt b/app/vendor/cakephp/cakephp/VERSION.txt index 110f4d625..905aba575 100644 --- a/app/vendor/cakephp/cakephp/VERSION.txt +++ b/app/vendor/cakephp/cakephp/VERSION.txt @@ -16,4 +16,4 @@ // @license https://opensource.org/licenses/mit-license.php MIT License // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -3.6.7 +3.6.11 diff --git a/app/vendor/cakephp/cakephp/config/cacert.pem b/app/vendor/cakephp/cakephp/config/cacert.pem index 45654c0b9..ee25bee11 100644 --- a/app/vendor/cakephp/cakephp/config/cacert.pem +++ b/app/vendor/cakephp/cakephp/config/cacert.pem @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Wed Mar 7 04:12:06 2018 GMT +## Certificate data from Mozilla as of: Wed Jun 20 03:12:06 2018 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.27. -## SHA256: 704f02707ec6b4c4a7597a8c6039b020def11e64f3ef0605a9c3543d48038a57 +## SHA256: c80f571d9f4ebca4a91e0ad3a546f263153d71afffc845c6f8f52ce9d1a2e8ec ## @@ -2635,30 +2635,6 @@ kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su -----END CERTIFICATE----- -TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 -==================================================== ------BEGIN CERTIFICATE----- -MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN -BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp -bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg -RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw -ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w -SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE -n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp -ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537 -jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m -ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP -9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV -4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH -HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI -hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo -BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq -URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl -lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8 -B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU= ------END CERTIFICATE----- - Certinomis - Root CA ==================== -----BEGIN CERTIFICATE----- diff --git a/app/vendor/cakephp/cakephp/phpstan.neon b/app/vendor/cakephp/cakephp/phpstan.neon index bc2248cef..00457a149 100644 --- a/app/vendor/cakephp/cakephp/phpstan.neon +++ b/app/vendor/cakephp/cakephp/phpstan.neon @@ -11,7 +11,6 @@ parameters: - '#Access to undefined constant PDO::SQLSRV_ATTR_ENCODING#' - '#Access to undefined constant PDO::SQLSRV_ENCODING_BINARY#' - '#Constant XC_TYPE_VAR not found#' - - '#Call to an undefined method Psr\\Http\\Message\\ResponseInterface::getCookies\(\)#' - '#Access to an undefined property Psr\\Http\\Message\\UriInterface::\$webroot#' - '#Access to an undefined property Psr\\Http\\Message\\UriInterface::\$base#' - '#Result of method Cake\\Http\\Response::send\(\) \(void\) is used#' @@ -23,12 +22,13 @@ parameters: - '#Variable \$config in isset\(\) is never defined#' - '#Call to static method id\(\) on an unknown class PHPUnit_Runner_Version#' - '#Call to an undefined method DateTimeInterface::i18nFormat\(\)#' - - '#Call to an undefined method object::__toString\(\)#' - - '#Call to an undefined method object::toArray\(\)#' - - '#Call to an undefined method object::__debugInfo\(\)#' - '#Cannot call method lastInsertId\(\) on null#' + - '#Call to an undefined method Cake\\Auth\\Storage\\StorageInterface::getConfig\(\)#' + - '#Call to an undefined method Cake\\Auth\\Storage\\StorageInterface::setConfig\(\)#' + - '#Variable \$_SESSION in isset\(\) always exists and is not nullable#' + - '#PHPDoc tag @throws with type PHPUnit\\Exception is not subtype of Throwable#' earlyTerminatingMethodCalls: - Cake\Shell\Shell: + Cake\Console\Shell: - abort services: diff --git a/app/vendor/cakephp/cakephp/src/Auth/BaseAuthenticate.php b/app/vendor/cakephp/cakephp/src/Auth/BaseAuthenticate.php index d5678d2d1..acdde17dc 100644 --- a/app/vendor/cakephp/cakephp/src/Auth/BaseAuthenticate.php +++ b/app/vendor/cakephp/cakephp/src/Auth/BaseAuthenticate.php @@ -117,8 +117,15 @@ protected function _findUser($username, $password = null) $result = $this->_query($username)->first(); if (empty($result)) { - $hasher = $this->passwordHasher(); - $hasher->hash((string)$password); + // Waste time hashing the password, to prevent + // timing side-channels. However, don't hash + // null passwords as authentication systems + // like digest auth don't use passwords + // and hashing *could* create a timing side-channel. + if ($password !== null) { + $hasher = $this->passwordHasher(); + $hasher->hash($password); + } return false; } diff --git a/app/vendor/cakephp/cakephp/src/Auth/BasicAuthenticate.php b/app/vendor/cakephp/cakephp/src/Auth/BasicAuthenticate.php index 9ca589ade..0108c745f 100644 --- a/app/vendor/cakephp/cakephp/src/Auth/BasicAuthenticate.php +++ b/app/vendor/cakephp/cakephp/src/Auth/BasicAuthenticate.php @@ -27,27 +27,27 @@ * * ### Using Basic auth * - * In your controller's components array, add auth + the required config + * Load `AuthComponent` in your controller's `initialize()` and add 'Basic' in 'authenticate' key * ``` - * public $components = [ - * 'Auth' => [ - * 'authenticate' => ['Basic'] - * ] - * ]; + * $this->loadComponent('Auth', [ + * 'authenticate' => ['Basic'] + * 'storage' => 'Memory', + * 'unauthorizedRedirect' => false, + * ]); * ``` * - * You should also set `AuthComponent::$sessionKey = false;` in your AppController's - * beforeFilter() to prevent CakePHP from sending a session cookie to the client. + * You should set `storage` to `Memory` to prevent CakePHP from sending a + * session cookie to the client. * - * Since HTTP Basic Authentication is stateless you don't need a login() action + * You should set `unauthorizedRedirect` to `false`. This causes `AuthComponent` to + * throw a `ForbiddenException` exception instead of redirecting to another page. + * + * Since HTTP Basic Authentication is stateless you don't need call `setUser()` * in your controller. The user credentials will be checked on each request. If * valid credentials are not provided, required authentication headers will be sent * by this authentication provider which triggers the login dialog in the browser/client. * - * You may also want to use `$this->Auth->unauthorizedRedirect = false;`. - * By default, unauthorized users are redirected to the referrer URL, - * `AuthComponent::$loginAction`, or '/'. If unauthorizedRedirect is set to - * false, a ForbiddenException exception is thrown instead of redirecting. + * @see https://book.cakephp.org/3.0/en/controllers/components/authentication.html */ class BasicAuthenticate extends BaseAuthenticate { diff --git a/app/vendor/cakephp/cakephp/src/Auth/DigestAuthenticate.php b/app/vendor/cakephp/cakephp/src/Auth/DigestAuthenticate.php index 61435294c..327491f73 100644 --- a/app/vendor/cakephp/cakephp/src/Auth/DigestAuthenticate.php +++ b/app/vendor/cakephp/cakephp/src/Auth/DigestAuthenticate.php @@ -25,27 +25,27 @@ * * ### Using Digest auth * - * In your controller's components array, add auth + the required config + * Load `AuthComponent` in your controller's `initialize()` and add 'Digest' in 'authenticate' key + * * ``` - * public $components = [ - * 'Auth' => [ - * 'authenticate' => ['Digest'] - * ] - * ]; + * $this->loadComponent('Auth', [ + * 'authenticate' => ['Digest'], + * 'storage' => 'Memory', + * 'unauthorizedRedirect' => false, + * ]); * ``` * - * You should also set `AuthComponent::$sessionKey = false;` in your AppController's - * beforeFilter() to prevent CakePHP from sending a session cookie to the client. + * You should set `storage` to `Memory` to prevent CakePHP from sending a + * session cookie to the client. + * + * You should set `unauthorizedRedirect` to `false`. This causes `AuthComponent` to + * throw a `ForbiddenException` exception instead of redirecting to another page. * - * Since HTTP Digest Authentication is stateless you don't need a login() action + * Since HTTP Digest Authentication is stateless you don't need call `setUser()` * in your controller. The user credentials will be checked on each request. If * valid credentials are not provided, required authentication headers will be sent * by this authentication provider which triggers the login dialog in the browser/client. * - * You may also want to use `$this->Auth->unauthorizedRedirect = false;`. - * This causes AuthComponent to throw a ForbiddenException exception instead of - * redirecting to another page. - * * ### Generating passwords compatible with Digest authentication. * * DigestAuthenticate requires a special password hash that conforms to RFC2617. @@ -60,6 +60,8 @@ * example `User.digest_pass` could be used for a digest password, while * `User.password` would store the password hash for use with other methods like * Basic or Form. + * + * @see https://book.cakephp.org/3.0/en/controllers/components/authentication.html */ class DigestAuthenticate extends BasicAuthenticate { diff --git a/app/vendor/cakephp/cakephp/src/Auth/FormAuthenticate.php b/app/vendor/cakephp/cakephp/src/Auth/FormAuthenticate.php index d2311c9a0..abd78f90a 100644 --- a/app/vendor/cakephp/cakephp/src/Auth/FormAuthenticate.php +++ b/app/vendor/cakephp/cakephp/src/Auth/FormAuthenticate.php @@ -19,21 +19,30 @@ use Cake\Http\ServerRequest; /** - * An authentication adapter for AuthComponent. Provides the ability to authenticate using POST - * data. Can be used by configuring AuthComponent to use it via the AuthComponent::$authenticate config. + * Form authentication adapter for AuthComponent. + * + * Allows you to authenticate users based on form POST data. + * Usually, this is a login form that users enter information into. + * + * ### Using Form auth + * + * Load `AuthComponent` in your controller's `initialize()` and add 'Form' in 'authenticate' key * * ``` - * $this->Auth->authenticate = [ - * 'Form' => [ - * 'finder' => ['auth' => ['some_finder_option' => 'some_value']] - * ] - * ] + * $this->loadComponent('Auth', [ + * 'authenticate' => [ + * 'Form' => [ + * 'fields' => ['username' => 'email', 'password' => 'passwd'], + * 'finder' => 'auth', + * ] + * ] + * ]); * ``` * - * When configuring FormAuthenticate you can pass in config to which fields, model and additional conditions - * are used. See FormAuthenticate::$_config for more information. + * When configuring FormAuthenticate you can pass in config to which fields, model and finder + * are used. See `BaseAuthenticate::$_defaultConfig` for more information. * - * @see \Cake\Controller\Component\AuthComponent::$authenticate + * @see https://book.cakephp.org/3.0/en/controllers/components/authentication.html */ class FormAuthenticate extends BaseAuthenticate { diff --git a/app/vendor/cakephp/cakephp/src/Cache/Engine/ApcEngine.php b/app/vendor/cakephp/cakephp/src/Cache/Engine/ApcEngine.php index 982ed3113..a106f2e03 100644 --- a/app/vendor/cakephp/cakephp/src/Cache/Engine/ApcEngine.php +++ b/app/vendor/cakephp/cakephp/src/Cache/Engine/ApcEngine.php @@ -14,7 +14,7 @@ */ namespace Cake\Cache\Engine; -// @deprecated Add backwards compat alias. +// @deprecated 3.6.0 Add backwards compat alias. class_alias('Cake\Cache\Engine\ApcuEngine', 'Cake\Cache\Engine\ApcEngine'); deprecationWarning('Use Cake\Cache\Engine\ApcuEngine instead of Cake\Cache\Engine\ApcEngine.'); diff --git a/app/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php b/app/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php index a5367f373..49247cc68 100644 --- a/app/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php +++ b/app/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php @@ -413,7 +413,7 @@ protected function _setKey($key, $createKey = false) } /** - * Determine is cache directory is writable + * Determine if cache directory is writable * * @return bool */ diff --git a/app/vendor/cakephp/cakephp/src/Collection/Iterator/FilterIterator.php b/app/vendor/cakephp/cakephp/src/Collection/Iterator/FilterIterator.php index 4612f2b9f..c5cbdf3aa 100644 --- a/app/vendor/cakephp/cakephp/src/Collection/Iterator/FilterIterator.php +++ b/app/vendor/cakephp/cakephp/src/Collection/Iterator/FilterIterator.php @@ -67,6 +67,7 @@ public function __construct($items, callable $callback) */ public function unwrap() { + /** @var \IteratorIterator $filter */ $filter = $this->getInnerIterator(); $iterator = $filter->getInnerIterator(); diff --git a/app/vendor/cakephp/cakephp/src/Console/CommandRunner.php b/app/vendor/cakephp/cakephp/src/Console/CommandRunner.php index 894c9ae4d..9638d7f18 100644 --- a/app/vendor/cakephp/cakephp/src/Console/CommandRunner.php +++ b/app/vendor/cakephp/cakephp/src/Console/CommandRunner.php @@ -298,7 +298,7 @@ protected function getShell(ConsoleIo $io, CommandCollection $commands, $name) /** * Resolve the command name into a name that exists in the collection. * - * Apply backwards compatibile inflections and aliases. + * Apply backwards compatible inflections and aliases. * * @param \Cake\Console\CommandCollection $commands The command collection to check. * @param \Cake\Console\ConsoleIo $io ConsoleIo object for errors. diff --git a/app/vendor/cakephp/cakephp/src/Console/ConsoleInput.php b/app/vendor/cakephp/cakephp/src/Console/ConsoleInput.php index 118cc1fea..6a45b5865 100644 --- a/app/vendor/cakephp/cakephp/src/Console/ConsoleInput.php +++ b/app/vendor/cakephp/cakephp/src/Console/ConsoleInput.php @@ -77,7 +77,7 @@ public function read() public function dataAvailable($timeout = 0) { $readFds = [$this->_input]; - $readyFds = stream_select($readFds, $writeFds, $errorFds, $timeout); + $readyFds = stream_select($readFds, null, null, $timeout); return ($readyFds > 0); } diff --git a/app/vendor/cakephp/cakephp/src/Console/ConsoleIo.php b/app/vendor/cakephp/cakephp/src/Console/ConsoleIo.php index 65c5eabe3..49042dd20 100644 --- a/app/vendor/cakephp/cakephp/src/Console/ConsoleIo.php +++ b/app/vendor/cakephp/cakephp/src/Console/ConsoleIo.php @@ -84,7 +84,7 @@ class ConsoleIo * * @var int */ - protected $_level = ConsoleIo::NORMAL; + protected $_level = self::NORMAL; /** * The number of bytes last written to the output stream @@ -163,17 +163,17 @@ public function quiet($message, $newlines = 1) * * ### Output levels * - * There are 3 built-in output level. Shell::QUIET, Shell::NORMAL, Shell::VERBOSE. + * There are 3 built-in output level. ConsoleIo::QUIET, ConsoleIo::NORMAL, ConsoleIo::VERBOSE. * The verbose and quiet output levels, map to the `verbose` and `quiet` output switches - * present in most shells. Using Shell::QUIET for a message means it will always display. - * While using Shell::VERBOSE means it will only display when verbose output is toggled. + * present in most shells. Using ConsoleIo::QUIET for a message means it will always display. + * While using ConsoleIo::VERBOSE means it will only display when verbose output is toggled. * * @param string|array $message A string or an array of strings to output * @param int $newlines Number of newlines to append * @param int $level The message's output level, see above. * @return int|bool The number of bytes returned from writing to stdout. */ - public function out($message = '', $newlines = 1, $level = ConsoleIo::NORMAL) + public function out($message = '', $newlines = 1, $level = self::NORMAL) { if ($level <= $this->_level) { $this->_lastWritten = (int)$this->_out->write($message, $newlines); @@ -191,9 +191,9 @@ public function out($message = '', $newlines = 1, $level = ConsoleIo::NORMAL) * @param int $newlines Number of newlines to append * @param int $level The message's output level, see above. * @return int|bool The number of bytes returned from writing to stdout. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::out + * @see https://book.cakephp.org/3.0/en/console-and-shells.html#ConsoleIo::out */ - public function info($message = null, $newlines = 1, $level = Shell::NORMAL) + public function info($message = null, $newlines = 1, $level = self::NORMAL) { $messageType = 'info'; $message = $this->wrapMessageWithType($messageType, $message); @@ -207,7 +207,7 @@ public function info($message = null, $newlines = 1, $level = Shell::NORMAL) * @param string|array|null $message A string or an array of strings to output * @param int $newlines Number of newlines to append * @return int|bool The number of bytes returned from writing to stderr. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::err + * @see https://book.cakephp.org/3.0/en/console-and-shells.html#ConsoleIo::err */ public function warning($message = null, $newlines = 1) { @@ -223,7 +223,7 @@ public function warning($message = null, $newlines = 1) * @param string|array|null $message A string or an array of strings to output * @param int $newlines Number of newlines to append * @return int|bool The number of bytes returned from writing to stderr. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::err + * @see https://book.cakephp.org/3.0/en/console-and-shells.html#ConsoleIo::err */ public function error($message = null, $newlines = 1) { @@ -240,9 +240,9 @@ public function error($message = null, $newlines = 1) * @param int $newlines Number of newlines to append * @param int $level The message's output level, see above. * @return int|bool The number of bytes returned from writing to stdout. - * @see https://book.cakephp.org/3.0/en/console-and-shells.html#Shell::out + * @see https://book.cakephp.org/3.0/en/console-and-shells.html#ConsoleIo::out */ - public function success($message = null, $newlines = 1, $level = Shell::NORMAL) + public function success($message = null, $newlines = 1, $level = self::NORMAL) { $messageType = 'success'; $message = $this->wrapMessageWithType($messageType, $message); diff --git a/app/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php b/app/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php index 23c9b71a3..2cd5061ed 100644 --- a/app/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php +++ b/app/vendor/cakephp/cakephp/src/Controller/Component/AuthComponent.php @@ -881,7 +881,7 @@ public function constructAuthenticate() * * @param \Cake\Auth\Storage\StorageInterface|null $storage Sets provided * object as storage or if null returns configured storage object. - * @return \Cake\Auth\Storage\StorageInterface|\Cake\Core\InstanceConfigTrait|null + * @return \Cake\Auth\Storage\StorageInterface|null */ public function storage(StorageInterface $storage = null) { diff --git a/app/vendor/cakephp/cakephp/src/Controller/Component/CookieComponent.php b/app/vendor/cakephp/cakephp/src/Controller/Component/CookieComponent.php index 7cf09be55..3f6ded2bf 100644 --- a/app/vendor/cakephp/cakephp/src/Controller/Component/CookieComponent.php +++ b/app/vendor/cakephp/cakephp/src/Controller/Component/CookieComponent.php @@ -337,7 +337,7 @@ protected function _delete($name) $controller->response = $controller->response->withCookie($name, [ 'value' => '', - 'expire' => $expires->format('U') - 42000, + 'expire' => (int)$expires->format('U') - 42000, 'path' => $config['path'], 'domain' => $config['domain'], 'secure' => $config['secure'], diff --git a/app/vendor/cakephp/cakephp/src/Controller/Controller.php b/app/vendor/cakephp/cakephp/src/Controller/Controller.php index 7d886b8da..9dc8e6ddf 100644 --- a/app/vendor/cakephp/cakephp/src/Controller/Controller.php +++ b/app/vendor/cakephp/cakephp/src/Controller/Controller.php @@ -498,7 +498,7 @@ public function enableAutoRender() } /** - * Disbale automatic action rendering. + * Disable automatic action rendering. * * @return $this * @since 3.6.0 diff --git a/app/vendor/cakephp/cakephp/src/Core/PluginCollection.php b/app/vendor/cakephp/cakephp/src/Core/PluginCollection.php index 9dfff93c5..dce99e098 100644 --- a/app/vendor/cakephp/cakephp/src/Core/PluginCollection.php +++ b/app/vendor/cakephp/cakephp/src/Core/PluginCollection.php @@ -104,7 +104,7 @@ protected function loadConfig() * * @param string $name The plugin name to locate a path for. Will return '' when a plugin cannot be found. * @return string - * @throws Cake\Core\Exception\MissingPluginException when a plugin path cannot be resolved. + * @throws \Cake\Core\Exception\MissingPluginException when a plugin path cannot be resolved. * @internal */ public function findPath($name) diff --git a/app/vendor/cakephp/cakephp/src/Database/FunctionsBuilder.php b/app/vendor/cakephp/cakephp/src/Database/FunctionsBuilder.php index 0bab11d24..d31664098 100644 --- a/app/vendor/cakephp/cakephp/src/Database/FunctionsBuilder.php +++ b/app/vendor/cakephp/cakephp/src/Database/FunctionsBuilder.php @@ -195,7 +195,7 @@ public function extract($part, $expression, $types = []) * Add the time unit to the date expression * * @param string $expression Expression to obtain the date part from. - * @param string $value Value to be added. Use negative to substract. + * @param string $value Value to be added. Use negative to subtract. * @param string $unit Unit of the value e.g. hour or day. * @param array $types list of types to bind to the arguments * @return \Cake\Database\Expression\FunctionExpression diff --git a/app/vendor/cakephp/cakephp/src/Database/Query.php b/app/vendor/cakephp/cakephp/src/Database/Query.php index 50b48b911..4a7b8b9b7 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Query.php +++ b/app/vendor/cakephp/cakephp/src/Database/Query.php @@ -1149,7 +1149,15 @@ public function orWhere($conditions, $types = []) * $query->order($expression)->order(['title' => 'ASC']); * ``` * - * Will become: + * and + * + * ``` + * $query->order(function ($exp, $query) { + * return [$exp->add(['id % 2 = 0']), 'title' => 'ASC']; + * }); + * ``` + * + * Will both become: * * `ORDER BY (id %2 = 0), title ASC` * @@ -1160,7 +1168,7 @@ public function orWhere($conditions, $types = []) * If you need to set complex expressions as order conditions, you * should use `orderAsc()` or `orderDesc()`. * - * @param array|\Cake\Database\ExpressionInterface|string $fields fields to be added to the list + * @param array|\Cake\Database\ExpressionInterface|callable|string $fields fields to be added to the list * @param bool $overwrite whether to reset order with field list or not * @return $this */ diff --git a/app/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchema.php b/app/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchema.php index 5ca25bf96..52d7fe204 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchema.php +++ b/app/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchema.php @@ -139,7 +139,7 @@ protected function _convertColumn($column) } if (strpos($col, 'blob') !== false || $col === 'binary') { $lengthName = substr($col, 0, -4); - $length = isset(TableSchema::$columnLengths[$lengthName]) ? TableSchema::$columnLengths[$lengthName] : null; + $length = isset(TableSchema::$columnLengths[$lengthName]) ? TableSchema::$columnLengths[$lengthName] : $length; return ['type' => TableSchema::TYPE_BINARY, 'length' => $length]; } diff --git a/app/vendor/cakephp/cakephp/src/Database/Schema/SqliteSchema.php b/app/vendor/cakephp/cakephp/src/Database/Schema/SqliteSchema.php index 1642e18f6..67da6d427 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Schema/SqliteSchema.php +++ b/app/vendor/cakephp/cakephp/src/Database/Schema/SqliteSchema.php @@ -102,8 +102,8 @@ protected function _convertColumn($column) if ($col === 'binary' && $length === 16) { return ['type' => TableSchema::TYPE_BINARY_UUID, 'length' => null]; } - if (in_array($col, ['blob', 'clob'])) { - return ['type' => TableSchema::TYPE_BINARY, 'length' => null]; + if (in_array($col, ['blob', 'clob', 'binary'])) { + return ['type' => TableSchema::TYPE_BINARY, 'length' => $length]; } if (in_array($col, ['date', 'time', 'timestamp', 'datetime'])) { return ['type' => $col, 'length' => null]; diff --git a/app/vendor/cakephp/cakephp/src/Database/Schema/Table.php b/app/vendor/cakephp/cakephp/src/Database/Schema/Table.php index 86d3f0fde..8304e75fc 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Schema/Table.php +++ b/app/vendor/cakephp/cakephp/src/Database/Schema/Table.php @@ -1,4 +1,4 @@ _errors[$f][] = $error; } else { @@ -1093,7 +1093,7 @@ protected function _nestedErrors($field) /** * Read the error(s) from one or many objects. * - * @param array|\Cake\Datasource\EntityTrait $object The object to read errors from. + * @param array|\Cake\Datasource\EntityInterface $object The object to read errors from. * @param string|null $path The field name for errors. * @return array */ diff --git a/app/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php b/app/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php index 286ece9f6..8932fd6af 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php @@ -481,9 +481,11 @@ public function firstOrFail() { $entity = $this->first(); if (!$entity) { + /** @var \Cake\ORM\Table $table */ + $table = $this->getRepository(); throw new RecordNotFoundException(sprintf( 'Record not found in table "%s"', - $this->getRepository()->getTable() + $table->getTable() )); } diff --git a/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php b/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php index b90ae008b..e514204da 100644 --- a/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php +++ b/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php @@ -99,7 +99,10 @@ public function addPlugin($name, array $config = []) $plugin = $name; } if (!$plugin instanceof PluginInterface) { - throw new InvalidArgumentException("The `{$name}` plugin does not implement Cake\Core\PluginInterface."); + throw new InvalidArgumentException(sprintf( + "The `%s` plugin does not implement Cake\Core\PluginInterface.", + get_class($plugin) + )); } $this->plugins->add($plugin); diff --git a/app/vendor/cakephp/cakephp/src/Http/CallbackStream.php b/app/vendor/cakephp/cakephp/src/Http/CallbackStream.php index f165f3123..f6ecbff1e 100644 --- a/app/vendor/cakephp/cakephp/src/Http/CallbackStream.php +++ b/app/vendor/cakephp/cakephp/src/Http/CallbackStream.php @@ -39,7 +39,10 @@ class CallbackStream extends BaseCallbackStream public function getContents() { $callback = $this->detach(); - $result = $callback ? $callback() : ''; + $result = ''; + if (is_callable($callback)) { + $result = $callback(); + } if (!is_string($result)) { return ''; } diff --git a/app/vendor/cakephp/cakephp/src/Http/Client.php b/app/vendor/cakephp/cakephp/src/Http/Client.php index 16dc8a23f..94dd2704a 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client.php @@ -610,5 +610,5 @@ protected function _createAuth($auth, $options) return new $class($this, $options); } } -// @deprecated Backwards compatibility with earler 3.x versions. +// @deprecated 3.4.0 Backwards compatibility with earler 3.x versions. class_alias('Cake\Http\Client', 'Cake\Network\Http\Client'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php b/app/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php index 21cbe972f..06835083b 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php @@ -330,5 +330,5 @@ public function contextOptions() } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\Adapter\Stream', 'Cake\Network\Http\Adapter\Stream'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Basic.php b/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Basic.php index 6debf1bcd..cb4f85dd6 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Basic.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Basic.php @@ -73,5 +73,5 @@ protected function _generateHeader($user, $pass) } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\Auth\Basic', 'Cake\Network\Http\Auth\Basic'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Digest.php b/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Digest.php index 9d4256479..0e110952f 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Digest.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Digest.php @@ -144,5 +144,5 @@ protected function _generateHeader(Request $request, $credentials) } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\Auth\Digest', 'Cake\Network\Http\Auth\Digest'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Oauth.php b/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Oauth.php index 597e853e3..050e60b15 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Oauth.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Auth/Oauth.php @@ -364,5 +364,5 @@ protected function _encode($value) } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\Auth\Oauth', 'Cake\Network\Http\Auth\Oauth'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/CookieCollection.php b/app/vendor/cakephp/cakephp/src/Http/Client/CookieCollection.php index 817bb063c..a93396775 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/CookieCollection.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/CookieCollection.php @@ -117,5 +117,5 @@ protected function convertCookieToArray(CookieInterface $cookie) } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\CookieCollection', 'Cake\Network\Http\CookieCollection'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/FormData.php b/app/vendor/cakephp/cakephp/src/Http/Client/FormData.php index 5e7a32ab0..50e878f18 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/FormData.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/FormData.php @@ -263,5 +263,5 @@ public function __toString() } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\FormData', 'Cake\Network\Http\FormData'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/FormDataPart.php b/app/vendor/cakephp/cakephp/src/Http/Client/FormDataPart.php index a079c7274..6a5d4c892 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/FormDataPart.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/FormDataPart.php @@ -222,5 +222,5 @@ public function __toString() } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\FormDataPart', 'Cake\Network\Http\FormData\Part'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Message.php b/app/vendor/cakephp/cakephp/src/Http/Client/Message.php index eb11e2d87..5b6dccd5c 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Message.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Message.php @@ -200,5 +200,5 @@ public function body($body = null) } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\Message', 'Cake\Network\Http\Message'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Request.php b/app/vendor/cakephp/cakephp/src/Http/Client/Request.php index 7829a9ffc..b27686c84 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Request.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Request.php @@ -283,5 +283,5 @@ public function body($body = null) } } -// @deprecated Add backwards compact alias. +// @deprecated 3.4.0 Add backwards compact alias. class_alias('Cake\Http\Client\Request', 'Cake\Network\Http\Request'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Response.php b/app/vendor/cakephp/cakephp/src/Http/Client/Response.php index 9e896c39b..4e3d61eda 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Response.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Response.php @@ -669,5 +669,5 @@ public function __isset($name) } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Client\Response', 'Cake\Network\Http\Response'); diff --git a/app/vendor/cakephp/cakephp/src/Http/Middleware/EncryptedCookieMiddleware.php b/app/vendor/cakephp/cakephp/src/Http/Middleware/EncryptedCookieMiddleware.php index 6555cfd25..dbb4d3f51 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Middleware/EncryptedCookieMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Http/Middleware/EncryptedCookieMiddleware.php @@ -45,7 +45,7 @@ class EncryptedCookieMiddleware protected $cookieNames; /** - * Encrpytion key to use. + * Encryption key to use. * * @var string */ diff --git a/app/vendor/cakephp/cakephp/src/Http/Response.php b/app/vendor/cakephp/cakephp/src/Http/Response.php index d698983e1..7777a883f 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Response.php +++ b/app/vendor/cakephp/cakephp/src/Http/Response.php @@ -2816,5 +2816,5 @@ public function __debugInfo() } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\Response', 'Cake\Network\Response'); diff --git a/app/vendor/cakephp/cakephp/src/Http/ServerRequest.php b/app/vendor/cakephp/cakephp/src/Http/ServerRequest.php index d2057227e..d9cd48bbc 100644 --- a/app/vendor/cakephp/cakephp/src/Http/ServerRequest.php +++ b/app/vendor/cakephp/cakephp/src/Http/ServerRequest.php @@ -308,7 +308,7 @@ public function __construct($config = []) */ protected function _setConfig($config) { - if (!empty($config['url']) && $config['url'][0] === '/') { + if (strlen($config['url']) > 1 && $config['url'][0] === '/') { $config['url'] = substr($config['url'], 1); } @@ -2446,5 +2446,5 @@ public function offsetUnset($name) } } -// @deprecated Add backwards compat alias. +// @deprecated 3.4.0 Add backwards compat alias. class_alias('Cake\Http\ServerRequest', 'Cake\Network\Request'); diff --git a/app/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php b/app/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php index f86b66b6c..3641a9ed3 100644 --- a/app/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php +++ b/app/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php @@ -79,7 +79,7 @@ public static function createUri(array $server = []) * Build a UriInterface object. * * Add in some CakePHP specific logic/properties that help - * perserve backwards compatibility. + * preserve backwards compatibility. * * @param array $server The server parameters. * @param array $headers The normalized headers diff --git a/app/vendor/cakephp/cakephp/src/Http/Session.php b/app/vendor/cakephp/cakephp/src/Http/Session.php index 165f9e6b2..3ab2254ff 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Session.php +++ b/app/vendor/cakephp/cakephp/src/Http/Session.php @@ -118,6 +118,10 @@ public static function create($sessionConfig = []) unset($sessionConfig['ini']['session.save_handler']); } + if (!isset($sessionConfig['ini']['session.use_strict_mode']) && ini_get('session.use_strict_mode') != 1) { + $sessionConfig['ini']['session.use_strict_mode'] = 1; + } + if (!isset($sessionConfig['ini']['session.cookie_httponly']) && ini_get('session.cookie_httponly') != 1) { $sessionConfig['ini']['session.cookie_httponly'] = 1; } @@ -608,7 +612,7 @@ protected function _timedOut() $result = false; $checkTime = $time !== null && $this->_lifetime > 0; - if ($checkTime && (time() - $time > $this->_lifetime)) { + if ($checkTime && (time() - (int)$time > $this->_lifetime)) { $result = true; } diff --git a/app/vendor/cakephp/cakephp/src/I18n/README.md b/app/vendor/cakephp/cakephp/src/I18n/README.md index 4c9611631..72ff29ff0 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/README.md +++ b/app/vendor/cakephp/cakephp/src/I18n/README.md @@ -29,6 +29,7 @@ I18n::setLocale('en_US'); use Cake\Core\Configure; Configure::write('App.paths.locales', ['/path/with/trailing/slash/']); +``` Please refer to the [CakePHP Manual](https://book.cakephp.org/3.0/en/core-libraries/internationalization-and-localization.html#language-files) for details about expected folder structure and file naming. diff --git a/app/vendor/cakephp/cakephp/src/I18n/RelativeTimeFormatter.php b/app/vendor/cakephp/cakephp/src/I18n/RelativeTimeFormatter.php index 8d2d7d58f..8f4b714c7 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/RelativeTimeFormatter.php +++ b/app/vendor/cakephp/cakephp/src/I18n/RelativeTimeFormatter.php @@ -180,15 +180,15 @@ public function timeAgoInWords(DateTimeInterface $time, array $options = []) /** * Calculate the data needed to format a relative difference string. * - * @param \DateTime $futureTime The time from the future. - * @param \DateTime $pastTime The time from the past. + * @param int|string $futureTime The timestamp from the future. + * @param int|string $pastTime The timestamp from the past. * @param bool $backwards Whether or not the difference was backwards. * @param array $options An array of options. * @return array An array of values. */ protected function _diffData($futureTime, $pastTime, $backwards, $options) { - $diff = $futureTime - $pastTime; + $diff = (int)$futureTime - (int)$pastTime; // If more than a week, then take into account the length of months if ($diff >= 604800) { diff --git a/app/vendor/cakephp/cakephp/src/I18n/functions.php b/app/vendor/cakephp/cakephp/src/I18n/functions.php index 6d015b454..65f46ab68 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/functions.php +++ b/app/vendor/cakephp/cakephp/src/I18n/functions.php @@ -21,7 +21,6 @@ * @param string $singular Text to translate. * @param array ...$args Array with arguments or multiple arguments in function. * @return string|null The translated text, or null if invalid. - * @throws \Aura\Intl\Exception * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__ */ function __($singular, ...$args) @@ -48,7 +47,6 @@ function __($singular, ...$args) * @param int $count Count. * @param array ...$args Array with arguments or multiple arguments in function. * @return string|null Plural form of translated string, or null if invalid. - * @throws \Aura\Intl\Exception * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__n */ function __n($singular, $plural, $count, ...$args) @@ -76,7 +74,6 @@ function __n($singular, $plural, $count, ...$args) * @param string $msg String to translate. * @param array ...$args Array with arguments or multiple arguments in function. * @return string|null Translated string. - * @throws \Aura\Intl\Exception * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__d */ function __d($domain, $msg, ...$args) @@ -105,7 +102,6 @@ function __d($domain, $msg, ...$args) * @param int $count Count. * @param array ...$args Array with arguments or multiple arguments in function. * @return string|null Plural form of translated string. - * @throws \Aura\Intl\Exception * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__dn */ function __dn($domain, $singular, $plural, $count, ...$args) @@ -135,7 +131,6 @@ function __dn($domain, $singular, $plural, $count, ...$args) * @param string $singular Text to translate. * @param array ...$args Array with arguments or multiple arguments in function. * @return string|null Translated string. - * @throws \Aura\Intl\Exception * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__x */ function __x($context, $singular, ...$args) @@ -165,7 +160,6 @@ function __x($context, $singular, ...$args) * @param int $count Count. * @param array ...$args Array with arguments or multiple arguments in function. * @return string|null Plural form of translated string. - * @throws \Aura\Intl\Exception * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__xn */ function __xn($context, $singular, $plural, $count, ...$args) @@ -196,7 +190,6 @@ function __xn($context, $singular, $plural, $count, ...$args) * @param string $msg String to translate. * @param array ...$args Array with arguments or multiple arguments in function. * @return string|null Translated string. - * @throws \Aura\Intl\Exception * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__dx */ function __dx($domain, $context, $msg, ...$args) @@ -230,7 +223,6 @@ function __dx($domain, $context, $msg, ...$args) * @param int $count Count. * @param array ...$args Array with arguments or multiple arguments in function. * @return string|null Plural form of translated string. - * @throws \Aura\Intl\Exception * @link https://book.cakephp.org/3.0/en/core-libraries/global-constants-and-functions.html#__dxn */ function __dxn($domain, $context, $singular, $plural, $count, ...$args) diff --git a/app/vendor/cakephp/cakephp/src/Network/CorsBuilder.php b/app/vendor/cakephp/cakephp/src/Network/CorsBuilder.php index 155ac807f..57ce28b9d 100644 --- a/app/vendor/cakephp/cakephp/src/Network/CorsBuilder.php +++ b/app/vendor/cakephp/cakephp/src/Network/CorsBuilder.php @@ -1,4 +1,4 @@ _junctionAssociationName(); + /** @var array $joins */ $joins = $query->join(); $matching = [ $name => [ @@ -1386,6 +1387,7 @@ protected function _collectJointEntities($sourceEntity, $targetEntities) $assocForeignKey = (array)$belongsTo->getForeignKey(); $sourceKey = $sourceEntity->extract((array)$source->getPrimaryKey()); + $unions = []; foreach ($missing as $key) { $unions[] = $hasMany->find('all') ->where(array_combine($foreignKey, $sourceKey)) diff --git a/app/vendor/cakephp/cakephp/src/ORM/Behavior/TimestampBehavior.php b/app/vendor/cakephp/cakephp/src/ORM/Behavior/TimestampBehavior.php index 68e24af5f..6d2d54fec 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Behavior/TimestampBehavior.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Behavior/TimestampBehavior.php @@ -61,7 +61,7 @@ class TimestampBehavior extends Behavior /** * Current timestamp * - * @var \DateTime + * @var \Cake\I18n\Time */ protected $_ts; @@ -136,7 +136,7 @@ public function implementedEvents() * * @param \DateTime|null $ts Timestamp * @param bool $refreshTimestamp If true timestamp is refreshed. - * @return \DateTime + * @return \Cake\I18n\Time */ public function timestamp(DateTime $ts = null, $refreshTimestamp = false) { diff --git a/app/vendor/cakephp/cakephp/src/ORM/Marshaller.php b/app/vendor/cakephp/cakephp/src/ORM/Marshaller.php index 7eb255187..a38fecb41 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Marshaller.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Marshaller.php @@ -248,6 +248,7 @@ protected function _validate($data, $options, $isNew) } elseif (is_string($options['validate'])) { $validator = $this->_table->getValidator($options['validate']); } elseif (is_object($options['validate'])) { + /** @var \Cake\Validation\Validator $validator */ $validator = $options['validate']; } diff --git a/app/vendor/cakephp/cakephp/src/ORM/Query.php b/app/vendor/cakephp/cakephp/src/ORM/Query.php index 746f25789..1f52d831d 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Query.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Query.php @@ -33,6 +33,7 @@ * * @see \Cake\Collection\CollectionInterface For a full description of the collection methods supported by this class * @method \Cake\Collection\CollectionInterface each(callable $c) Passes each of the query results to the callable + * @method \Cake\Collection\CollectionInterface sortBy($callback, $dir = SORT_DESC, $type = \SORT_NUMERIC) Sorts the query with the callback * @method \Cake\Collection\CollectionInterface filter(callable $c = null) Keeps the results using passing the callable test * @method \Cake\Collection\CollectionInterface reject(callable $c) Removes the results passing the callable test * @method bool every(callable $c) Returns true if all the results pass the callable test @@ -204,7 +205,7 @@ public function __construct($connection, $table) * all the fields in the schema of the table or the association will be added to * the select clause. * - * @param array|\Cake\Database\ExpressionInterface|string|\Cake\ORM\Table|\Cake\ORM\Association $fields fields + * @param array|\Cake\Database\ExpressionInterface|callable|string|\Cake\ORM\Table|\Cake\ORM\Association $fields fields * to be added to the list. * @param bool $overwrite whether to reset fields with passed list or not * @return $this @@ -1083,10 +1084,11 @@ public function all() public function triggerBeforeFind() { if (!$this->_beforeFindFired && $this->_type === 'select') { - $table = $this->getRepository(); $this->_beforeFindFired = true; - /* @var \Cake\Event\EventDispatcherInterface $table */ - $table->dispatchEvent('Model.beforeFind', [ + + /** @var \Cake\Event\EventDispatcherInterface $repository */ + $repository = $this->getRepository(); + $repository->dispatchEvent('Model.beforeFind', [ $this, new ArrayObject($this->_options), !$this->isEagerLoaded() @@ -1145,11 +1147,14 @@ protected function _transformQuery() return; } + /** @var \Cake\ORM\Table $repository */ + $repository = $this->getRepository(); + if (empty($this->_parts['from'])) { - $this->from([$this->_repository->getAlias() => $this->_repository->getTable()]); + $this->from([$repository->getAlias() => $repository->getTable()]); } $this->_addDefaultFields(); - $this->getEagerLoader()->attachAssociations($this, $this->_repository, !$this->_hasFields); + $this->getEagerLoader()->attachAssociations($this, $repository, !$this->_hasFields); $this->_addDefaultSelectTypes(); } @@ -1164,13 +1169,16 @@ protected function _addDefaultFields() $select = $this->clause('select'); $this->_hasFields = true; + /** @var \Cake\ORM\Table $repository */ + $repository = $this->getRepository(); + if (!count($select) || $this->_autoFields === true) { $this->_hasFields = false; - $this->select($this->getRepository()->getSchema()->columns()); + $this->select($repository->getSchema()->columns()); $select = $this->clause('select'); } - $aliased = $this->aliasFields($select, $this->getRepository()->getAlias()); + $aliased = $this->aliasFields($select, $repository->getAlias()); $this->select($aliased, true); } @@ -1207,7 +1215,10 @@ protected function _addDefaultSelectTypes() */ public function find($finder, array $options = []) { - return $this->getRepository()->callFinder($finder, $this, $options); + /** @var \Cake\ORM\Table $table */ + $table = $this->getRepository(); + + return $table->callFinder($finder, $this, $options); } /** @@ -1234,7 +1245,11 @@ protected function _dirty() */ public function update($table = null) { - $table = $table ?: $this->getRepository()->getTable(); + if (!$table) { + /** @var \Cake\ORM\Table $repository */ + $repository = $this->getRepository(); + $table = $repository->getTable(); + } return parent::update($table); } @@ -1250,8 +1265,9 @@ public function update($table = null) */ public function delete($table = null) { - $repo = $this->getRepository(); - $this->from([$repo->getAlias() => $repo->getTable()]); + /** @var \Cake\ORM\Table $repository */ + $repository = $this->getRepository(); + $this->from([$repository->getAlias() => $repository->getTable()]); return parent::delete(); } @@ -1271,7 +1287,9 @@ public function delete($table = null) */ public function insert(array $columns, array $types = []) { - $table = $this->getRepository()->getTable(); + /** @var \Cake\ORM\Table $repository */ + $repository = $this->getRepository(); + $table = $repository->getTable(); $this->into($table); return parent::insert($columns, $types); diff --git a/app/vendor/cakephp/cakephp/src/ORM/README.md b/app/vendor/cakephp/cakephp/src/ORM/README.md index 9cbcbac40..19ac4a00d 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/README.md +++ b/app/vendor/cakephp/cakephp/src/ORM/README.md @@ -163,6 +163,75 @@ $cacheConfig = [ Cache::setConfig('_cake_model_', $cacheConfig); ``` +## Creating Custom Table and Entity Classes + +By default, the Cake ORM uses the `\Cake\ORM\Table` and `\Cake\ORM\Entity` classes to +interact with the database. While using the default classes makes sense for +quick scripts and small applications, you will often want to use your own +classes for adding your custom logic. + +When using the ORM as a standalone package, you are free to choose where to +store these classes. For example, you could use the `Data` folder for this: + +```php +setEntityClass(Article::class); + $this->belongsTo('Users', ['className' => UsersTable::class]); + } +} +``` + +This table class is now setup to connect to the `articles` table in your +database and return instances of `Article` when fetching results. In order to +get an instance of this class, as shown before, you can use the `TableLocator`: + +```php +get('Articles', ['className' => ArticlesTable::class]); +``` + +### Using Conventions-Based Loading + +It may get quite tedious having to specify each time the class name to load. So +the Cake ORM can do most of the work for you if you give it some configuration. + +The convention is to have all ORM related classes inside the `src/Model` folder, +that is the `Model` sub-namespace for your app. So you will usually have the +`src/Model/Table` and `src/Model/Entity` folders in your project. But first, we +need to inform Cake of the namespace your application lives in: + +```php +getRepository(); $this->_statement = $statement; $this->_driver = $query->getConnection()->getDriver(); @@ -447,7 +448,7 @@ protected function _getTypes($table, $fields) { $types = []; $schema = $table->getSchema(); - $map = array_keys(Type::map() + ['string' => 1, 'text' => 1, 'boolean' => 1]); + $map = array_keys((array)Type::getMap() + ['string' => 1, 'text' => 1, 'boolean' => 1]); $typeMap = array_combine( $map, array_map(['Cake\Database\Type', 'build'], $map) diff --git a/app/vendor/cakephp/cakephp/src/ORM/Table.php b/app/vendor/cakephp/cakephp/src/ORM/Table.php index 8feb704a4..065e635d1 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Table.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Table.php @@ -773,7 +773,7 @@ public function getEntityClass() return $this->_entityClass = $default; } - $alias = Inflector::singularize(substr(array_pop($parts), 0, -5)); + $alias = Inflector::classify(Inflector::underscore(substr(array_pop($parts), 0, -5))); $name = implode('\\', array_slice($parts, 0, -1)) . '\\Entity\\' . $alias; if (!class_exists($name)) { return $this->_entityClass = $default; @@ -1848,7 +1848,7 @@ public function exists($conditions) * listeners will receive the entity and the options array as arguments. The type * of operation performed (insert or update) can be determined by checking the * entity's method `isNew`, true meaning an insert and false an update. - * - Model.afterSaveCommit: Will be triggered after the transaction is commited + * - Model.afterSaveCommit: Will be triggered after the transaction is committed * for atomic save, listeners will receive the entity and the options array * as arguments. * @@ -1894,7 +1894,7 @@ public function save(EntityInterface $entity, $options = []) $options = $options->toArray(); } - $options = new ArrayObject($options + [ + $options = new ArrayObject((array)$options + [ 'atomic' => true, 'associated' => true, 'checkRules' => true, @@ -2272,7 +2272,7 @@ public function saveMany($entities, $options = []) */ public function delete(EntityInterface $entity, $options = []) { - $options = new ArrayObject($options + [ + $options = new ArrayObject((array)$options + [ 'atomic' => true, 'checkRules' => true, '_primary' => true, diff --git a/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php b/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php index 9bb0eb852..6d459595c 100644 --- a/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php @@ -124,7 +124,6 @@ protected function prepareRouteCollection() * @param \Psr\Http\Message\ResponseInterface $response The response. * @param callable $next The next middleware to call. * @return \Psr\Http\Message\ResponseInterface A response. - * @throws \Cake\Routing\InvalidArgumentException */ public function __invoke(ServerRequestInterface $request, ResponseInterface $response, $next) { diff --git a/app/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php b/app/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php index 652a435c0..9409f1bce 100644 --- a/app/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php +++ b/app/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php @@ -388,7 +388,7 @@ public function namePrefix($value = null) */ public function resources($name, $options = [], $callback = null) { - if (is_callable($options) && $callback === null) { + if (is_callable($options)) { $callback = $options; $options = []; } @@ -982,7 +982,7 @@ public function plugin($name, $options = [], $callback = null) */ public function scope($path, $params, $callback = null) { - if ($callback === null) { + if (is_callable($params)) { $callback = $params; $params = []; } @@ -1062,7 +1062,7 @@ public function applyMiddleware(...$names) throw new RuntimeException($message); } } - $this->middleware = array_merge($this->middleware, $names); + $this->middleware = array_unique(array_merge($this->middleware, $names)); return $this; } diff --git a/app/vendor/cakephp/cakephp/src/Routing/Router.php b/app/vendor/cakephp/cakephp/src/Routing/Router.php index 6617298c7..5cdba9f34 100644 --- a/app/vendor/cakephp/cakephp/src/Routing/Router.php +++ b/app/vendor/cakephp/cakephp/src/Routing/Router.php @@ -616,23 +616,21 @@ public static function url($url = null, $full = false) 'action' => 'index', '_ext' => null, ]; - $here = $base = $output = $frag = null; + $here = $output = $frag = null; + $context = static::$_requestContext; // In 4.x this should be replaced with state injected via setRequestContext $request = static::getRequest(true); if ($request) { $params = $request->getAttribute('params'); $here = $request->getRequestTarget(); - $base = $request->getAttribute('base'); - } else { - $base = Configure::read('App.base'); - if (isset(static::$_requestContext['_base'])) { - $base = static::$_requestContext['_base']; - } + $context['_base'] = $request->getAttribute('base'); + } elseif (!isset($context['_base'])) { + $context['_base'] = Configure::read('App.base'); } if (empty($url)) { - $output = $base . (isset($here) ? $here : '/'); + $output = $context['_base'] . (isset($here) ? $here : '/'); if ($full) { $output = static::fullBaseUrl() . $output; } @@ -680,8 +678,9 @@ public static function url($url = null, $full = false) if ($full && isset($url['_scheme']) && !isset($url['_host'])) { $url['_host'] = parse_url(static::fullBaseUrl(), PHP_URL_HOST); } + $context['params'] = $params; - $output = static::$_collection->match($url, static::$_requestContext + ['params' => $params]); + $output = static::$_collection->match($url, $context); } else { $plainString = ( strpos($url, 'javascript:') === 0 || @@ -697,7 +696,7 @@ public static function url($url = null, $full = false) if ($plainString) { return $url; } - $output = $base . $url; + $output = $context['_base'] . $url; } $protocol = preg_match('#^[a-z][a-z0-9+\-.]*\://#i', $output); if ($protocol === 0) { diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestCase.php b/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestCase.php index b4c1772b8..34a2f07d1 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestCase.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestCase.php @@ -43,14 +43,14 @@ abstract class ConsoleIntegrationTestCase extends TestCase /** * Console output stub * - * @var \Cake\Console\ConsoleOutput|\PHPUnit_Framework_MockObject_MockObject|null + * @var \Cake\TestSuite\Stub\ConsoleOutput|\PHPUnit_Framework_MockObject_MockObject|null */ protected $_out; /** * Console error output stub * - * @var \Cake\Console\ConsoleOutput|\PHPUnit_Framework_MockObject_MockObject|null + * @var \Cake\TestSuite\Stub\ConsoleOutput|\PHPUnit_Framework_MockObject_MockObject|null */ protected $_err; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/TestCase.php b/app/vendor/cakephp/cakephp/src/TestSuite/TestCase.php index 541de8fac..d990a24dd 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/TestCase.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/TestCase.php @@ -699,7 +699,7 @@ public function getMockForModel($alias, array $methods = [], array $options = [] if (empty($options['entityClass']) && $mock->getEntityClass() === Entity::class) { $parts = explode('\\', $className); - $entityAlias = Inflector::singularize(substr(array_pop($parts), 0, -5)); + $entityAlias = Inflector::classify(Inflector::underscore(substr(array_pop($parts), 0, -5))); $entityClass = implode('\\', array_slice($parts, 0, -1)) . '\\Entity\\' . $entityAlias; if (class_exists($entityClass)) { $mock->setEntityClass($entityClass); diff --git a/app/vendor/cakephp/cakephp/src/Utility/Crypto/Mcrypt.php b/app/vendor/cakephp/cakephp/src/Utility/Crypto/Mcrypt.php index b67c72e91..7d0b7a3b7 100644 --- a/app/vendor/cakephp/cakephp/src/Utility/Crypto/Mcrypt.php +++ b/app/vendor/cakephp/cakephp/src/Utility/Crypto/Mcrypt.php @@ -33,7 +33,7 @@ class Mcrypt * @param string $key Key to use as the encryption key for encrypted data. * @param string $operation Operation to perform, encrypt or decrypt * @throws \LogicException When there are errors. - * @return string Encrytped binary string data, or decrypted data depending on operation. + * @return string Encrypted binary string data, or decrypted data depending on operation. * @deprecated 3.3.0 This method will be removed in 4.0.0. */ public static function rijndael($text, $key, $operation) diff --git a/app/vendor/cakephp/cakephp/src/Utility/String.php b/app/vendor/cakephp/cakephp/src/Utility/String.php index e30ba9cf4..239e03a12 100644 --- a/app/vendor/cakephp/cakephp/src/Utility/String.php +++ b/app/vendor/cakephp/cakephp/src/Utility/String.php @@ -1,5 +1,5 @@ getClientFilename(), $extensions); + } if (is_array($check)) { $check = isset($check['name']) ? $check['name'] : array_shift($check); @@ -1108,7 +1111,7 @@ public static function luhn($check) } for ($position = ($length % 2); $position < $length; $position += 2) { - $number = $check[$position] * 2; + $number = (int)$check[$position] * 2; $sum += ($number < 10) ? $number : $number - 9; } @@ -1258,7 +1261,7 @@ public static function uploadError($check, $allowNoFile = false) * - `optional` - Whether or not this file is optional. Defaults to false. * If true a missing file will pass the validator regardless of other constraints. * - * @param array $file The uploaded file data from PHP. + * @param array|\Psr\Http\Message\UploadedFileInterface $file The uploaded file data from PHP. * @param array $options An array of options for the validation. * @return bool */ @@ -1310,7 +1313,7 @@ public static function uploadedFile($file, array $options = []) /** * Validates the size of an uploaded image. * - * @param array $file The uploaded file data from PHP. + * @param array|\Psr\Http\Message\UploadedFileInterface $file The uploaded file data from PHP. * @param array $options Options to validate width and height. * @return bool */ @@ -1320,11 +1323,7 @@ public static function imageSize($file, $options) throw new InvalidArgumentException('Invalid image size validation parameters! Missing `width` and / or `height`.'); } - if ($file instanceof UploadedFileInterface) { - $file = $file->getStream()->getContents(); - } elseif (is_array($file) && isset($file['tmp_name'])) { - $file = $file['tmp_name']; - } + $file = static::getFilename($file); list($width, $height) = getimagesize($file); @@ -1351,7 +1350,7 @@ public static function imageSize($file, $options) * Validates the image width. * * @param array $file The uploaded file data from PHP. - * @param string $operator Comparision operator. + * @param string $operator Comparison operator. * @param int $width Min or max width. * @return bool */ @@ -1369,7 +1368,7 @@ public static function imageWidth($file, $operator, $width) * Validates the image width. * * @param array $file The uploaded file data from PHP. - * @param string $operator Comparision operator. + * @param string $operator Comparison operator. * @param int $height Min or max width. * @return bool */ diff --git a/app/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php b/app/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php index c632ed77d..c9040c27e 100644 --- a/app/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php +++ b/app/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php @@ -848,6 +848,8 @@ public function error($field, $text = null, array $options = []) * - `for` - Set the for attribute, if its not defined the for attribute * will be generated from the $fieldName parameter using * FormHelper::_domId(). + * - `escape` - Set to `false` to turn off escaping of label text. + * Defaults to `true`. * * Examples: * diff --git a/app/vendor/cakephp/cakephp/src/View/Helper/TimeHelper.php b/app/vendor/cakephp/cakephp/src/View/Helper/TimeHelper.php index bdf75931a..817bfd759 100644 --- a/app/vendor/cakephp/cakephp/src/View/Helper/TimeHelper.php +++ b/app/vendor/cakephp/cakephp/src/View/Helper/TimeHelper.php @@ -371,7 +371,7 @@ public function format($date, $format = null, $invalid = false, $timezone = null */ public function i18nFormat($date, $format = null, $invalid = false, $timezone = null) { - if (!isset($date)) { + if ($date === null) { return $invalid; } $timezone = $this->_getTimezone($timezone); diff --git a/app/vendor/cakephp/cakephp/src/View/Widget/WidgetRegistry.php b/app/vendor/cakephp/cakephp/src/View/Widget/WidgetRegistry.php index 26e197ff2..1a2235e49 100644 --- a/app/vendor/cakephp/cakephp/src/View/Widget/WidgetRegistry.php +++ b/app/vendor/cakephp/cakephp/src/View/Widget/WidgetRegistry.php @@ -12,7 +12,7 @@ * @since 3.0.0 * @license https://opensource.org/licenses/mit-license.php MIT License */ -// @deprecated Add backwards compat alias. +// @deprecated 3.6.0 Add backwards compat alias. class_alias('Cake\View\Widget\WidgetLocator', 'Cake\View\Widget\WidgetRegistry'); deprecationWarning('Use Cake\View\Widget\WidgetLocator instead of Cake\View\Widget\WidgetRegistry.'); diff --git a/app/vendor/cakephp/cakephp/tests/PHPStan/AssociationTableMixinClassReflectionExtension.php b/app/vendor/cakephp/cakephp/tests/PHPStan/AssociationTableMixinClassReflectionExtension.php index d5ae2c0ae..72f733283 100644 --- a/app/vendor/cakephp/cakephp/tests/PHPStan/AssociationTableMixinClassReflectionExtension.php +++ b/app/vendor/cakephp/cakephp/tests/PHPStan/AssociationTableMixinClassReflectionExtension.php @@ -23,7 +23,7 @@ class AssociationTableMixinClassReflectionExtension implements PropertiesClassRe * @param Broker $broker Class reflection broker * @return void */ - public function setBroker(Broker $broker) + public function setBroker(Broker $broker): void { $this->broker = $broker; } diff --git a/app/vendor/cakephp/cakephp/tests/bootstrap.php b/app/vendor/cakephp/cakephp/tests/bootstrap.php index 6f3936e2b..fd8dae281 100644 --- a/app/vendor/cakephp/cakephp/tests/bootstrap.php +++ b/app/vendor/cakephp/cakephp/tests/bootstrap.php @@ -117,11 +117,13 @@ 'engine' => 'Cake\Log\Engine\FileLog', 'levels' => ['notice', 'info', 'debug'], 'file' => 'debug', + 'path' => LOGS, ], 'error' => [ 'engine' => 'Cake\Log\Engine\FileLog', 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], 'file' => 'error', + 'path' => LOGS, ] ]); diff --git a/app/vendor/cakephp/cakephp/tests/phpunit_aliases.php b/app/vendor/cakephp/cakephp/tests/phpunit_aliases.php index e613f3702..7d151bbaa 100644 --- a/app/vendor/cakephp/cakephp/tests/phpunit_aliases.php +++ b/app/vendor/cakephp/cakephp/tests/phpunit_aliases.php @@ -4,12 +4,14 @@ trigger_error(sprintf('Your PHPUnit Version must be at least 5.7.0 to use CakePHP Testsuite, found %s', \PHPUnit_Runner_Version::id()), E_USER_ERROR); } - class_alias('PHPUnit_Framework_Test', 'PHPUnit\Framework\Test'); - class_alias('PHPUnit_Framework_AssertionFailedError', 'PHPUnit\Framework\AssertionFailedError'); - class_alias('PHPUnit_Framework_TestSuite', 'PHPUnit\Framework\TestSuite'); - class_alias('PHPUnit_Framework_TestResult', 'PHPUnit\Framework\TestResult'); - class_alias('PHPUnit_Framework_Error', 'PHPUnit\Framework\Error\Error'); - class_alias('PHPUnit_Framework_Error_Deprecated', 'PHPUnit\Framework\Error\Deprecated'); - class_alias('PHPUnit_Framework_Error_Warning', 'PHPUnit\Framework\Error\Warning'); - class_alias('PHPUnit_Framework_ExpectationFailedException', 'PHPUnit\Framework\ExpectationFailedException'); + if (!class_exists('PHPUnit_Framework_Test') && class_exists('PHPUnit_Framework_TestCase')) { + class_alias('PHPUnit_Framework_Test', 'PHPUnit\Framework\Test'); + class_alias('PHPUnit_Framework_AssertionFailedError', 'PHPUnit\Framework\AssertionFailedError'); + class_alias('PHPUnit_Framework_TestSuite', 'PHPUnit\Framework\TestSuite'); + class_alias('PHPUnit_Framework_TestResult', 'PHPUnit\Framework\TestResult'); + class_alias('PHPUnit_Framework_Error', 'PHPUnit\Framework\Error\Error'); + class_alias('PHPUnit_Framework_Error_Deprecated', 'PHPUnit\Framework\Error\Deprecated'); + class_alias('PHPUnit_Framework_Error_Warning', 'PHPUnit\Framework\Error\Warning'); + class_alias('PHPUnit_Framework_ExpectationFailedException', 'PHPUnit\Framework\ExpectationFailedException'); + } } diff --git a/app/vendor/cakephp/debug_kit/README.md b/app/vendor/cakephp/debug_kit/README.md index c3b16eda9..677594d2c 100644 --- a/app/vendor/cakephp/debug_kit/README.md +++ b/app/vendor/cakephp/debug_kit/README.md @@ -36,6 +36,11 @@ php composer.phar require --dev cakephp/debug_kit "~3.0" * [Load the plugin](http://book.cakephp.org/3.0/en/plugins.html#loading-a-plugin) ```php +// src/Application.php +$this->addPlugin('DebugKit'); +``` +Prior to 3.6.0 +```php Plugin::load('DebugKit', ['bootstrap' => true, 'routes' => true]); ``` * Set `'debug' => true,` in `config/app.php`. diff --git a/app/vendor/cakephp/debug_kit/config/bootstrap.php b/app/vendor/cakephp/debug_kit/config/bootstrap.php index 3ae6cc027..ed3f81522 100644 --- a/app/vendor/cakephp/debug_kit/config/bootstrap.php +++ b/app/vendor/cakephp/debug_kit/config/bootstrap.php @@ -12,10 +12,10 @@ */ use Cake\Core\Configure; use Cake\Core\Plugin as CorePlugin; +use Cake\Database\Query; use Cake\Datasource\ConnectionManager; use Cake\Event\EventManager; use Cake\Log\Log; -use Cake\ORM\Query; use Cake\Routing\DispatcherFactory; use DebugKit\DebugSql; use DebugKit\Middleware\DebugKitMiddleware; diff --git a/app/vendor/cakephp/debug_kit/src/DebugSql.php b/app/vendor/cakephp/debug_kit/src/DebugSql.php index ec78717ee..3bd0b2686 100644 --- a/app/vendor/cakephp/debug_kit/src/DebugSql.php +++ b/app/vendor/cakephp/debug_kit/src/DebugSql.php @@ -14,8 +14,8 @@ namespace DebugKit; use Cake\Core\Configure; +use Cake\Database\Query; use Cake\Error\Debugger; -use Cake\ORM\Query; use SqlFormatter; /** diff --git a/app/vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php index 5f92f1889..0c523ab3e 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php @@ -64,7 +64,11 @@ public function initialize() $logger = new DebugLog($logger, $name, $includeSchemaReflection); $connection->logQueries(true); - $connection->setLogger($logger); + if (method_exists($connection, 'setLogger')) { + $connection->setLogger($logger); + } else { + $connection->logger($logger); + } $this->_loggers[] = $logger; } } diff --git a/app/vendor/cakephp/migrations/LICENSE.txt b/app/vendor/cakephp/migrations/LICENSE.txt index 881440a65..5849d31d4 100644 --- a/app/vendor/cakephp/migrations/LICENSE.txt +++ b/app/vendor/cakephp/migrations/LICENSE.txt @@ -1,7 +1,7 @@ The MIT License CakePHP(tm) : The Rapid Development PHP Framework (http://cakephp.org) -Copyright (c) 2005-2016, Cake Software Foundation, Inc. +Copyright (c) 2005-2018, Cake Software Foundation, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,4 +25,4 @@ Cake Software Foundation, Inc. 1785 E. Sahara Avenue, Suite 490-204 Las Vegas, Nevada 89104, -United States of America. \ No newline at end of file +United States of America. diff --git a/app/vendor/cakephp/migrations/composer.json b/app/vendor/cakephp/migrations/composer.json index 59f8acb70..c4b916c18 100644 --- a/app/vendor/cakephp/migrations/composer.json +++ b/app/vendor/cakephp/migrations/composer.json @@ -18,15 +18,15 @@ "source": "https://github.com/cakephp/migrations" }, "require": { - "php": ">=5.5.9", + "php": ">=5.6.0", "robmorgan/phinx": "0.8.1", - "cakephp/orm": "~3.2", - "cakephp/cache": "~3.2" + "cakephp/orm": "^3.6.0", + "cakephp/cache": "^3.6.0" }, "require-dev": { - "phpunit/phpunit": "~4.1", - "cakephp/cakephp": "~3.2", - "cakephp/bake": "@stable", + "phpunit/phpunit": "^5.7.14", + "cakephp/cakephp": "^3.6.0", + "cakephp/bake": "^1.7.0", "cakephp/cakephp-codesniffer": "^3.0" }, "autoload": { @@ -46,7 +46,7 @@ "suggest": { "cakephp/bake": "Required if you want to generate migrations." }, - "minimum-stability": "stable", + "minimum-stability": "dev", "prefer-stable": true, "scripts": { "check": [ diff --git a/app/vendor/cakephp/migrations/src/CakeAdapter.php b/app/vendor/cakephp/migrations/src/CakeAdapter.php index b7fcf45ed..2b67a268a 100644 --- a/app/vendor/cakephp/migrations/src/CakeAdapter.php +++ b/app/vendor/cakephp/migrations/src/CakeAdapter.php @@ -61,12 +61,12 @@ public function __construct(AdapterInterface $adapter, Connection $connection) } $connection->cacheMetadata(false); - if ($connection->driver() instanceof Postgres) { + if ($connection->getDriver() instanceof Postgres) { $config = $connection->config(); $schema = empty($config['schema']) ? 'public' : $config['schema']; $pdo->exec('SET search_path TO ' . $schema); } - $connection->driver()->connection($pdo); + $connection->getDriver()->setConnection($pdo); } /** diff --git a/app/vendor/cakephp/migrations/src/Command/CacheClear.php b/app/vendor/cakephp/migrations/src/Command/CacheClear.php index 2e99b6593..954cc44ba 100644 --- a/app/vendor/cakephp/migrations/src/Command/CacheClear.php +++ b/app/vendor/cakephp/migrations/src/Command/CacheClear.php @@ -49,7 +49,7 @@ protected function execute(InputInterface $input, OutputInterface $output) if (empty($name)) { $tables = $schema->listTables(); } - $configName = $schema->cacheMetadata(); + $configName = $schema->getCacheMetadata(); foreach ($tables as $table) { $output->writeln(sprintf( diff --git a/app/vendor/cakephp/migrations/src/Command/Dump.php b/app/vendor/cakephp/migrations/src/Command/Dump.php index d62dd311c..45c965456 100644 --- a/app/vendor/cakephp/migrations/src/Command/Dump.php +++ b/app/vendor/cakephp/migrations/src/Command/Dump.php @@ -84,7 +84,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $path = $this->getOperationsPath($input); $connectionName = $input->getOption('connection') ?: 'default'; $connection = ConnectionManager::get($connectionName); - $collection = $connection->schemaCollection(); + $collection = $connection->getSchemaCollection(); $options = [ 'require-table' => false, diff --git a/app/vendor/cakephp/migrations/src/ConfigurationTrait.php b/app/vendor/cakephp/migrations/src/ConfigurationTrait.php index c3a4f8b4f..66da0abf7 100644 --- a/app/vendor/cakephp/migrations/src/ConfigurationTrait.php +++ b/app/vendor/cakephp/migrations/src/ConfigurationTrait.php @@ -78,7 +78,7 @@ public function getConfig($forceRefresh = false) $connection = $this->getConnectionName($this->input); - $connectionConfig = ConnectionManager::config($connection); + $connectionConfig = ConnectionManager::getConfig($connection); $adapterName = $this->getAdapterName($connectionConfig['driver']); $templatePath = Plugin::path('Migrations') . 'src' . DS . 'Template' . DS; diff --git a/app/vendor/cakephp/migrations/src/Shell/Task/MigrationDiffTask.php b/app/vendor/cakephp/migrations/src/Shell/Task/MigrationDiffTask.php index a7faa153d..71a54f2d2 100644 --- a/app/vendor/cakephp/migrations/src/Shell/Task/MigrationDiffTask.php +++ b/app/vendor/cakephp/migrations/src/Shell/Task/MigrationDiffTask.php @@ -114,7 +114,7 @@ public function bake($name) $collection = $this->getCollection($this->connection); EventManager::instance()->on('Bake.initialize', function (Event $event) use ($collection) { - $event->subject->loadHelper('Migrations.Migration', [ + $event->getSubject()->loadHelper('Migrations.Migration', [ 'collection' => $collection ]); }); @@ -134,7 +134,7 @@ public function setup() $this->phinxTable = $this->getPhinxTable($this->plugin); $connection = ConnectionManager::get($this->connection); - $this->tables = $connection->schemaCollection()->listTables(); + $this->tables = $connection->getSchemaCollection()->listTables(); $tableExists = in_array($this->phinxTable, $this->tables); $migratedItems = []; @@ -160,7 +160,7 @@ public function getCollection($connection) { $connection = ConnectionManager::get($connection); - return $connection->schemaCollection(); + return $connection->getSchemaCollection(); } /** @@ -233,7 +233,7 @@ protected function getColumns() // brand new columns $addedColumns = array_diff($currentColumns, $oldColumns); foreach ($addedColumns as $columnName) { - $column = $currentSchema->column($columnName); + $column = $currentSchema->getColumn($columnName); $key = array_search($columnName, $currentColumns); if ($key > 0) { $column['after'] = $currentColumns[$key - 1]; @@ -243,8 +243,8 @@ protected function getColumns() // changes in columns meta-data foreach ($currentColumns as $columnName) { - $column = $currentSchema->column($columnName); - $oldColumn = $this->dumpSchema[$table]->column($columnName); + $column = $currentSchema->getColumn($columnName); + $oldColumn = $this->dumpSchema[$table]->getColumn($columnName); unset($column['collate']); unset($oldColumn['collate']); @@ -282,7 +282,7 @@ protected function getColumns() $removedColumns = array_diff($oldColumns, $currentColumns); if (!empty($removedColumns)) { foreach ($removedColumns as $columnName) { - $column = $this->dumpSchema[$table]->column($columnName); + $column = $this->dumpSchema[$table]->getColumn($columnName); $key = array_search($columnName, $oldColumns); if ($key > 0) { $column['after'] = $oldColumns[$key - 1]; @@ -312,19 +312,19 @@ protected function getConstraints() $addedConstraints = array_diff($currentConstraints, $oldConstraints); foreach ($addedConstraints as $constraintName) { $this->templateData[$table]['constraints']['add'][$constraintName] = - $currentSchema->constraint($constraintName); + $currentSchema->getConstraint($constraintName); } // constraints having the same name between new and old schema // if present in both, check if they are the same : if not, remove the old one and add the new one foreach ($currentConstraints as $constraintName) { - $constraint = $currentSchema->constraint($constraintName); + $constraint = $currentSchema->getConstraint($constraintName); if (in_array($constraintName, $oldConstraints) && - $constraint !== $this->dumpSchema[$table]->constraint($constraintName) + $constraint !== $this->dumpSchema[$table]->getConstraint($constraintName) ) { $this->templateData[$table]['constraints']['remove'][$constraintName] = - $this->dumpSchema[$table]->constraint($constraintName); + $this->dumpSchema[$table]->getConstraint($constraintName); $this->templateData[$table]['constraints']['add'][$constraintName] = $constraint; } @@ -333,7 +333,7 @@ protected function getConstraints() // removed constraints $removedConstraints = array_diff($oldConstraints, $currentConstraints); foreach ($removedConstraints as $constraintName) { - $constraint = $this->dumpSchema[$table]->constraint($constraintName); + $constraint = $this->dumpSchema[$table]->getConstraint($constraintName); if ($constraint['type'] === Table::CONSTRAINT_FOREIGN) { $this->templateData[$table]['constraints']['remove'][$constraintName] = $constraint; } else { @@ -363,19 +363,19 @@ protected function getIndexes() // brand new indexes $addedIndexes = array_diff($currentIndexes, $oldIndexes); foreach ($addedIndexes as $indexName) { - $this->templateData[$table]['indexes']['add'][$indexName] = $currentSchema->index($indexName); + $this->templateData[$table]['indexes']['add'][$indexName] = $currentSchema->getIndex($indexName); } // indexes having the same name between new and old schema // if present in both, check if they are the same : if not, remove the old one and add the new one foreach ($currentIndexes as $indexName) { - $index = $currentSchema->index($indexName); + $index = $currentSchema->getIndex($indexName); if (in_array($indexName, $oldIndexes) && - $index !== $this->dumpSchema[$table]->index($indexName) + $index !== $this->dumpSchema[$table]->getIndex($indexName) ) { $this->templateData[$table]['indexes']['remove'][$indexName] = - $this->dumpSchema[$table]->index($indexName); + $this->dumpSchema[$table]->getIndex($indexName); $this->templateData[$table]['indexes']['add'][$indexName] = $index; } } @@ -389,7 +389,7 @@ protected function getIndexes() $parts = []; if (!empty($removedIndexes)) { foreach ($removedIndexes as $index) { - $parts[$index] = $this->dumpSchema[$table]->index($index); + $parts[$index] = $this->dumpSchema[$table]->getIndex($index); } } $this->templateData[$table]['indexes']['remove'] = array_merge( @@ -499,7 +499,7 @@ protected function getCurrentSchema() return $schema; } - $collection = ConnectionManager::get($this->connection)->schemaCollection(); + $collection = ConnectionManager::get($this->connection)->getSchemaCollection(); foreach ($this->tables as $table) { if (preg_match("/^.*phinxlog$/", $table) === 1) { continue; diff --git a/app/vendor/cakephp/migrations/src/Shell/Task/MigrationSnapshotTask.php b/app/vendor/cakephp/migrations/src/Shell/Task/MigrationSnapshotTask.php index cbac28bc9..af777f593 100644 --- a/app/vendor/cakephp/migrations/src/Shell/Task/MigrationSnapshotTask.php +++ b/app/vendor/cakephp/migrations/src/Shell/Task/MigrationSnapshotTask.php @@ -40,7 +40,7 @@ public function bake($name) { $collection = $this->getCollection($this->connection); EventManager::instance()->on('Bake.initialize', function (Event $event) use ($collection) { - $event->subject->loadHelper('Migrations.Migration', [ + $event->getSubject()->loadHelper('Migrations.Migration', [ 'collection' => $collection ]); }); @@ -106,7 +106,7 @@ public function getCollection($connection) { $connection = ConnectionManager::get($connection); - return $connection->schemaCollection(); + return $connection->getSchemaCollection(); } /** @@ -131,7 +131,7 @@ public function getOptionParser() { $parser = parent::getOptionParser(); - $parser->description( + $parser->setDescription( 'Bake migration snapshot class.' )->addArgument('name', [ 'help' => 'Name of the migration to bake. Can use Plugin.name to bake migration files into plugins.', diff --git a/app/vendor/cakephp/migrations/src/Shell/Task/MigrationTask.php b/app/vendor/cakephp/migrations/src/Shell/Task/MigrationTask.php index d72f76046..94698d194 100644 --- a/app/vendor/cakephp/migrations/src/Shell/Task/MigrationTask.php +++ b/app/vendor/cakephp/migrations/src/Shell/Task/MigrationTask.php @@ -34,7 +34,7 @@ class MigrationTask extends SimpleMigrationTask public function bake($name) { EventManager::instance()->on('Bake.initialize', function (Event $event) { - $event->subject->loadHelper('Migrations.Migration'); + $event->getSubject()->loadHelper('Migrations.Migration'); }); return parent::bake($name); diff --git a/app/vendor/cakephp/migrations/src/Shell/Task/SeedTask.php b/app/vendor/cakephp/migrations/src/Shell/Task/SeedTask.php index c56111051..7e944d027 100644 --- a/app/vendor/cakephp/migrations/src/Shell/Task/SeedTask.php +++ b/app/vendor/cakephp/migrations/src/Shell/Task/SeedTask.php @@ -148,7 +148,7 @@ public function getOptionParser() } } - $parser->description( + $parser->setDescription( 'Bake seed class.' )->addOption('plugin', [ 'short' => 'p', diff --git a/app/vendor/cakephp/migrations/src/Shell/Task/SimpleMigrationTask.php b/app/vendor/cakephp/migrations/src/Shell/Task/SimpleMigrationTask.php index db696bc08..89428d492 100644 --- a/app/vendor/cakephp/migrations/src/Shell/Task/SimpleMigrationTask.php +++ b/app/vendor/cakephp/migrations/src/Shell/Task/SimpleMigrationTask.php @@ -137,7 +137,7 @@ public function getOptionParser() } } - $parser->description( + $parser->setDescription( 'Bake migration class.' ) ->addOption('plugin', [ diff --git a/app/vendor/cakephp/migrations/src/TableFinderTrait.php b/app/vendor/cakephp/migrations/src/TableFinderTrait.php index 7fb9af410..0b2efc6b4 100644 --- a/app/vendor/cakephp/migrations/src/TableFinderTrait.php +++ b/app/vendor/cakephp/migrations/src/TableFinderTrait.php @@ -65,7 +65,7 @@ protected function getTablesToBake(Collection $collection, $options = []) if (strpos($table, '.') !== false) { $splitted = array_reverse(explode('.', $table, 2)); - $config = ConnectionManager::config($this->connection); + $config = ConnectionManager::getConfig($this->connection); $key = isset($config['schema']) ? 'schema' : 'database'; if ($config[$key] === $splitted[1]) { $table = $splitted[0]; @@ -168,13 +168,13 @@ protected function fetchTableName($className, $pluginName = null) $table = TableRegistry::get($className); foreach ($table->associations()->keys() as $key) { if ($table->associations()->get($key)->type() === 'belongsToMany') { - $tables[] = $table->associations()->get($key)->junction()->table(); + $tables[] = $table->associations()->get($key)->junction()->getTable(); } } - $tableName = $table->table(); + $tableName = $table->getTable(); $splitted = array_reverse(explode('.', $tableName, 2)); if (isset($splitted[1])) { - $config = ConnectionManager::config($this->connection); + $config = ConnectionManager::getConfig($this->connection); $key = isset($config['schema']) ? 'schema' : 'database'; if ($config[$key] === $splitted[1]) { $tableName = $splitted[0]; diff --git a/app/vendor/cakephp/migrations/src/Template/Bake/config/diff.ctp b/app/vendor/cakephp/migrations/src/Template/Bake/config/diff.ctp index 5f68b23e5..507457806 100644 --- a/app/vendor/cakephp/migrations/src/Template/Bake/config/diff.ctp +++ b/app/vendor/cakephp/migrations/src/Template/Bake/config/diff.ctp @@ -162,7 +162,7 @@ class <%= $name %> extends AbstractMigration <%- if (!empty($tableDiff['columns']['changed'])): $oldTableDef = $dumpSchema[$tableName]; foreach ($tableDiff['columns']['changed'] as $columnName => $columnAttributes): - $columnAttributes = $oldTableDef->column($columnName); + $columnAttributes = $oldTableDef->getColumn($columnName); $type = $columnAttributes['type']; unset($columnAttributes['type']); $columnAttributes = $this->Migration->getColumnOption($columnAttributes); diff --git a/app/vendor/cakephp/migrations/src/Util/SchemaTrait.php b/app/vendor/cakephp/migrations/src/Util/SchemaTrait.php index 50b5aa0de..01d01c3ec 100644 --- a/app/vendor/cakephp/migrations/src/Util/SchemaTrait.php +++ b/app/vendor/cakephp/migrations/src/Util/SchemaTrait.php @@ -33,10 +33,10 @@ protected function _getSchema(InputInterface $input, OutputInterface $output) $connectionName = $input->getOption('connection'); $connection = ConnectionManager::get($connectionName); - if (!method_exists($connection, 'schemaCollection')) { + if (!method_exists($connection, 'getSchemaCollection')) { $msg = sprintf( 'The "%s" connection is not compatible with orm caching, ' . - 'as it does not implement a "schemaCollection()" method.', + 'as it does not implement a "getSchemaCollection()" method.', $connectionName ); $output->writeln('' . $msg . ''); @@ -54,6 +54,6 @@ protected function _getSchema(InputInterface $input, OutputInterface $output) $connection->cacheMetadata(true); - return $connection->schemaCollection(); + return $connection->getSchemaCollection(); } } diff --git a/app/vendor/cakephp/migrations/src/View/Helper/MigrationHelper.php b/app/vendor/cakephp/migrations/src/View/Helper/MigrationHelper.php index d727b752c..0769bef01 100644 --- a/app/vendor/cakephp/migrations/src/View/Helper/MigrationHelper.php +++ b/app/vendor/cakephp/migrations/src/View/Helper/MigrationHelper.php @@ -122,7 +122,7 @@ protected function schema($table) return $this->schemas[$table->name()] = $table; } - $collection = $this->config('collection'); + $collection = $this->getConfig('collection'); $schema = $collection->describe($table); $this->schemas[$table] = $schema; @@ -170,7 +170,7 @@ public function indexes($table) $indexes = []; if (!empty($tableIndexes)) { foreach ($tableIndexes as $name) { - $indexes[$name] = $tableSchema->index($name); + $indexes[$name] = $tableSchema->getIndex($name); } } @@ -201,7 +201,7 @@ public function constraints($table) } if (!empty($tableConstraints)) { foreach ($tableConstraints as $name) { - $constraint = $tableSchema->constraint($name); + $constraint = $tableSchema->getConstraint($name); if (isset($constraint['update'])) { $constraint['update'] = $this->formatConstraintAction($constraint['update']); $constraint['delete'] = $this->formatConstraintAction($constraint['delete']); @@ -268,7 +268,7 @@ public function hasUnsignedPrimaryKey($tables) $tablePrimaryKeys = $tableSchema->primaryKey(); foreach ($tablePrimaryKeys as $primaryKey) { - $column = $tableSchema->column($primaryKey); + $column = $tableSchema->getColumn($primaryKey); if (isset($column['unsigned']) && $column['unsigned'] === true) { return true; } @@ -303,7 +303,7 @@ public function primaryKeysColumnsList($table) public function column($tableSchema, $column) { return [ - 'columnType' => $tableSchema->columnType($column), + 'columnType' => $tableSchema->getColumnType($column), 'options' => $this->attributes($tableSchema, $column), ]; } @@ -410,7 +410,7 @@ public function attributes($table, $column) ]; $attributes = []; - $options = $tableSchema->column($column); + $options = $tableSchema->getColumn($column); foreach ($options as $_option => $value) { $option = $_option; switch ($_option) { diff --git a/app/vendor/composer/autoload_files.php b/app/vendor/composer/autoload_files.php index b51c9d0db..912a95a82 100644 --- a/app/vendor/composer/autoload_files.php +++ b/app/vendor/composer/autoload_files.php @@ -6,8 +6,8 @@ $baseDir = dirname($vendorDir); return array( - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '34122c0574b76bf21c9a8db62b5b9cf3' => $vendorDir . '/cakephp/chronos/src/carbon_compat.php', 'cf97c57bfe0f23854afd2f3818abb7a0' => $vendorDir . '/zendframework/zend-diactoros/src/functions/create_uploaded_file.php', '9bf37a3d0dad93e29cb4e1b1bfab04e9' => $vendorDir . '/zendframework/zend-diactoros/src/functions/marshal_headers_from_sapi.php', @@ -21,8 +21,7 @@ 'ede59e3a405fb689cd1cebb7bb1db3fb' => $vendorDir . '/cakephp/cakephp/src/Collection/functions.php', '90236b492da7ca2983a2ad6e33e4152e' => $vendorDir . '/cakephp/cakephp/src/I18n/functions.php', 'b1fc73705e1bec51cd2b20a32cf1c60a' => $vendorDir . '/cakephp/cakephp/src/Utility/bootstrap.php', - '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', 'bf9f5270ae66ac6fa0290b4bf47867b7' => $vendorDir . '/adodb/adodb-php/adodb.inc.php', - 'e7223560d890eab89cda23685e711e2c' => $vendorDir . '/psy/psysh/src/Psy/functions.php', + '801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php', ); diff --git a/app/vendor/composer/autoload_namespaces.php b/app/vendor/composer/autoload_namespaces.php index 1138ddf4c..237df62aa 100644 --- a/app/vendor/composer/autoload_namespaces.php +++ b/app/vendor/composer/autoload_namespaces.php @@ -10,7 +10,6 @@ 'Umpirsky\\' => array($vendorDir . '/umpirsky/twig-php-function/src'), 'Twig_' => array($vendorDir . '/twig/twig/lib'), 'JakubOnderka\\PhpConsoleHighlighter' => array($vendorDir . '/jakub-onderka/php-console-highlighter/src'), - 'JakubOnderka\\PhpConsoleColor' => array($vendorDir . '/jakub-onderka/php-console-color/src'), 'Detection' => array($vendorDir . '/mobiledetect/mobiledetectlib/namespaced'), 'Aptoma' => array($vendorDir . '/aptoma/twig-markdown/src'), ); diff --git a/app/vendor/composer/autoload_psr4.php b/app/vendor/composer/autoload_psr4.php index b0c926dcc..e3891cff3 100644 --- a/app/vendor/composer/autoload_psr4.php +++ b/app/vendor/composer/autoload_psr4.php @@ -10,7 +10,6 @@ 'XdgBaseDir\\' => array($vendorDir . '/dnoegel/php-xdg-base-dir/src'), 'WyriHaximus\\TwigView\\' => array($vendorDir . '/wyrihaximus/twig-view/src'), 'Twig\\' => array($vendorDir . '/twig/twig/src'), - 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), 'Symfony\\Component\\Yaml\\' => array($vendorDir . '/symfony/yaml'), @@ -23,8 +22,7 @@ 'Symfony\\Component\\Config\\' => array($vendorDir . '/symfony/config'), 'Seld\\PharUtils\\' => array($vendorDir . '/seld/phar-utils/src'), 'Seld\\JsonLint\\' => array($vendorDir . '/seld/jsonlint/src/Seld/JsonLint'), - 'Seld\\CliPrompt\\' => array($vendorDir . '/seld/cli-prompt/src'), - 'Psy\\' => array($vendorDir . '/psy/psysh/src/Psy'), + 'Psy\\' => array($vendorDir . '/psy/psysh/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), 'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'), @@ -33,8 +31,13 @@ 'M1\\Env\\' => array($vendorDir . '/m1/env/src'), 'JsonSchema\\' => array($vendorDir . '/justinrainbow/json-schema/src/JsonSchema'), 'Jasny\\Twig\\' => array($vendorDir . '/jasny/twig-extensions/src'), + 'JakubOnderka\\PhpConsoleColor\\' => array($vendorDir . '/jakub-onderka/php-console-color/src'), + 'Doctrine\\DBAL\\' => array($vendorDir . '/doctrine/dbal/lib/Doctrine/DBAL'), + 'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'), + 'Doctrine\\Common\\' => array($vendorDir . '/doctrine/event-manager/lib/Doctrine/Common'), 'DebugKit\\Test\\Fixture\\' => array($vendorDir . '/cakephp/debug_kit/tests/Fixture'), 'DebugKit\\' => array($vendorDir . '/cakephp/debug_kit/src'), + 'Composer\\XdebugHandler\\' => array($vendorDir . '/composer/xdebug-handler/src'), 'Composer\\Spdx\\' => array($vendorDir . '/composer/spdx-licenses/src'), 'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'), 'Composer\\CaBundle\\' => array($vendorDir . '/composer/ca-bundle/src'), diff --git a/app/vendor/composer/autoload_static.php b/app/vendor/composer/autoload_static.php index 4a7e21217..7ffd356c1 100644 --- a/app/vendor/composer/autoload_static.php +++ b/app/vendor/composer/autoload_static.php @@ -7,8 +7,8 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 { public static $files = array ( - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '34122c0574b76bf21c9a8db62b5b9cf3' => __DIR__ . '/..' . '/cakephp/chronos/src/carbon_compat.php', 'cf97c57bfe0f23854afd2f3818abb7a0' => __DIR__ . '/..' . '/zendframework/zend-diactoros/src/functions/create_uploaded_file.php', '9bf37a3d0dad93e29cb4e1b1bfab04e9' => __DIR__ . '/..' . '/zendframework/zend-diactoros/src/functions/marshal_headers_from_sapi.php', @@ -22,10 +22,9 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 'ede59e3a405fb689cd1cebb7bb1db3fb' => __DIR__ . '/..' . '/cakephp/cakephp/src/Collection/functions.php', '90236b492da7ca2983a2ad6e33e4152e' => __DIR__ . '/..' . '/cakephp/cakephp/src/I18n/functions.php', 'b1fc73705e1bec51cd2b20a32cf1c60a' => __DIR__ . '/..' . '/cakephp/cakephp/src/Utility/bootstrap.php', - '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', 'bf9f5270ae66ac6fa0290b4bf47867b7' => __DIR__ . '/..' . '/adodb/adodb-php/adodb.inc.php', - 'e7223560d890eab89cda23685e711e2c' => __DIR__ . '/..' . '/psy/psysh/src/Psy/functions.php', + '801c31d8ed748cfa537fa45402288c95' => __DIR__ . '/..' . '/psy/psysh/src/functions.php', ); public static $prefixLengthsPsr4 = array ( @@ -47,7 +46,6 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 ), 'S' => array ( - 'Symfony\\Polyfill\\Php72\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, 'Symfony\\Polyfill\\Ctype\\' => 23, 'Symfony\\Component\\Yaml\\' => 23, @@ -60,7 +58,6 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 'Symfony\\Component\\Config\\' => 25, 'Seld\\PharUtils\\' => 15, 'Seld\\JsonLint\\' => 14, - 'Seld\\CliPrompt\\' => 15, ), 'P' => array ( @@ -79,14 +76,19 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 array ( 'JsonSchema\\' => 11, 'Jasny\\Twig\\' => 11, + 'JakubOnderka\\PhpConsoleColor\\' => 29, ), 'D' => array ( + 'Doctrine\\DBAL\\' => 14, + 'Doctrine\\Common\\Cache\\' => 22, + 'Doctrine\\Common\\' => 16, 'DebugKit\\Test\\Fixture\\' => 22, 'DebugKit\\' => 9, ), 'C' => array ( + 'Composer\\XdebugHandler\\' => 23, 'Composer\\Spdx\\' => 14, 'Composer\\Semver\\' => 16, 'Composer\\CaBundle\\' => 18, @@ -127,10 +129,6 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 array ( 0 => __DIR__ . '/..' . '/twig/twig/src', ), - 'Symfony\\Polyfill\\Php72\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php72', - ), 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', @@ -179,13 +177,9 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 array ( 0 => __DIR__ . '/..' . '/seld/jsonlint/src/Seld/JsonLint', ), - 'Seld\\CliPrompt\\' => - array ( - 0 => __DIR__ . '/..' . '/seld/cli-prompt/src', - ), 'Psy\\' => array ( - 0 => __DIR__ . '/..' . '/psy/psysh/src/Psy', + 0 => __DIR__ . '/..' . '/psy/psysh/src', ), 'Psr\\Log\\' => array ( @@ -219,6 +213,22 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 array ( 0 => __DIR__ . '/..' . '/jasny/twig-extensions/src', ), + 'JakubOnderka\\PhpConsoleColor\\' => + array ( + 0 => __DIR__ . '/..' . '/jakub-onderka/php-console-color/src', + ), + 'Doctrine\\DBAL\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/dbal/lib/Doctrine/DBAL', + ), + 'Doctrine\\Common\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache', + ), + 'Doctrine\\Common\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/event-manager/lib/Doctrine/Common', + ), 'DebugKit\\Test\\Fixture\\' => array ( 0 => __DIR__ . '/..' . '/cakephp/debug_kit/tests/Fixture', @@ -227,6 +237,10 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 array ( 0 => __DIR__ . '/..' . '/cakephp/debug_kit/src', ), + 'Composer\\XdebugHandler\\' => + array ( + 0 => __DIR__ . '/..' . '/composer/xdebug-handler/src', + ), 'Composer\\Spdx\\' => array ( 0 => __DIR__ . '/..' . '/composer/spdx-licenses/src', @@ -318,10 +332,6 @@ class ComposerStaticInit8d81387c26c532d7a48feda4036c56c7 array ( 0 => __DIR__ . '/..' . '/jakub-onderka/php-console-highlighter/src', ), - 'JakubOnderka\\PhpConsoleColor' => - array ( - 0 => __DIR__ . '/..' . '/jakub-onderka/php-console-color/src', - ), ), 'D' => array ( diff --git a/app/vendor/composer/ca-bundle/res/cacert.pem b/app/vendor/composer/ca-bundle/res/cacert.pem index 45654c0b9..ee25bee11 100644 --- a/app/vendor/composer/ca-bundle/res/cacert.pem +++ b/app/vendor/composer/ca-bundle/res/cacert.pem @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Wed Mar 7 04:12:06 2018 GMT +## Certificate data from Mozilla as of: Wed Jun 20 03:12:06 2018 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.27. -## SHA256: 704f02707ec6b4c4a7597a8c6039b020def11e64f3ef0605a9c3543d48038a57 +## SHA256: c80f571d9f4ebca4a91e0ad3a546f263153d71afffc845c6f8f52ce9d1a2e8ec ## @@ -2635,30 +2635,6 @@ kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su -----END CERTIFICATE----- -TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5 -==================================================== ------BEGIN CERTIFICATE----- -MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN -BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp -bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg -RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw -ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w -SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE -n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp -ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB -CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537 -jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m -ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP -9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV -4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH -HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI -hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo -BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq -URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl -lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8 -B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU= ------END CERTIFICATE----- - Certinomis - Root CA ==================== -----BEGIN CERTIFICATE----- diff --git a/app/vendor/composer/composer/.php_cs b/app/vendor/composer/composer/.php_cs index ff43b3584..ac954ab5e 100644 --- a/app/vendor/composer/composer/.php_cs +++ b/app/vendor/composer/composer/.php_cs @@ -20,17 +20,16 @@ $finder = PhpCsFixer\Finder::create() return PhpCsFixer\Config::create() ->setUsingCache(true) - //->setUsingLinter(false) ->setRiskyAllowed(true) ->setRules(array( '@PSR2' => true, + 'array_syntax' => array('syntax' => 'long'), 'binary_operator_spaces' => true, - 'blank_line_before_return' => true, - 'cast_spaces' => true, + 'blank_line_before_statement' => array('statements' => array('declare', 'return')), + 'cast_spaces' => array('space' => 'single'), 'header_comment' => array('header' => $header), 'include' => true, - 'array_syntax' => array('syntax' => 'long'), - 'method_separation' => true, + 'class_attributes_separation' => array('elements' => array('method')), 'no_blank_lines_after_class_opening' => true, 'no_blank_lines_after_phpdoc' => true, 'no_empty_statement' => true, @@ -39,7 +38,6 @@ return PhpCsFixer\Config::create() 'no_leading_namespace_whitespace' => true, 'no_trailing_comma_in_singleline_array' => true, 'no_unused_imports' => true, - 'no_useless_else' => true, 'no_whitespace_in_blank_line' => true, 'object_operator_without_whitespace' => true, 'phpdoc_align' => true, @@ -52,7 +50,6 @@ return PhpCsFixer\Config::create() 'phpdoc_types' => true, 'psr0' => true, 'single_blank_line_before_namespace' => true, - 'short_scalar_cast' => true, 'standardize_not_equals' => true, 'ternary_operator_spaces' => true, 'trailing_comma_in_multiline_array' => true, diff --git a/app/vendor/composer/composer/.travis.yml b/app/vendor/composer/composer/.travis.yml index 5b8cf1391..16a3b073c 100644 --- a/app/vendor/composer/composer/.travis.yml +++ b/app/vendor/composer/composer/.travis.yml @@ -27,23 +27,26 @@ php: matrix: include: - - dist: precise - php: 5.3 + - php: 5.3 + dist: precise + - php: 7.2 + env: deps=high fast_finish: true allow_failures: - php: nightly before_install: - # determine INI file - - if [[ $TRAVIS_PHP_VERSION = hhvm* ]]; then export INI=/etc/hhvm/php.ini; else export INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini; fi - # disable xdebug if available + # disable xdebug if available - phpenv config-rm xdebug.ini || echo "xdebug not available" # disable default memory limit + - export INI=~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini - echo memory_limit = -1 >> $INI install: # flags to pass to install - flags="--ansi --prefer-dist --no-interaction --optimize-autoloader --no-suggest --no-progress" + # update deps to latest in case of high deps build + - if [ "$deps" == "high" ]; then composer config platform.php 7.2.4; composer update $flags; fi # install dependencies using system provided composer binary - composer install $flags # install dependencies using composer from source diff --git a/app/vendor/composer/composer/CHANGELOG.md b/app/vendor/composer/composer/CHANGELOG.md index 4ba36ef1d..b5efd1683 100644 --- a/app/vendor/composer/composer/CHANGELOG.md +++ b/app/vendor/composer/composer/CHANGELOG.md @@ -1,3 +1,39 @@ +### [1.7.2] 2018-08-16 + + * Fixed reporting of authentication/rate limiting issues for GitHub API access + * Fixed `create-project` not checking the checking the latest commit out when a cache was already present + * Fixed reporting of errors when `global` command can not switch the working directory + * Fixed PHP 5.3 JSON encoding issues with complex unicode character sequences + * Updated to latest ca-bundle and xdebug-handler projects, see related changelogs + +### [1.7.1] 2018-08-07 + + * Fixed issue autoloading plugins in require-dev in some conditions + * Fixed handling of SSL to repo.packagist.org on very old PHP versions + +### [1.7.0] 2018-08-03 + + * Added the overridden platform config's PHP version in the `diagnose` command output + * Fixed --no-plugins not being respected in a few commands + * Fixed 1.7.0-RC regression in output showing instead of proper colors + * Fixed 1.7.0-RC regression in output missing "Loading from cache" output on package install + +### [1.7.0-RC] 2018-07-24 + + * Changed default repository URL from packagist.org to repo.packagist.org, this might affect people with strict firewall rules + * Changed output from Updating to Downgrading when performing package downgrades, this might affect anything parsing output + * Several minor performance improvements + * Added basic authentication support for mercurial repos + * Added explicit `i` and `u` aliases for the `install` and `update` commands + * Added support for `show` command to output json format with --tree + * Added support for {glob,braces} support in the path repository's path argument + * Added support in `status` command for showing diffs in vendor dir even for packages installed as dist/zip archives + * Added `--remove-vcs` flag to `create-project` command to avoid prompting for keeping VCS files + * Added `--no-secure-http` flag to `create-project` command to bypass https (use at your own risk) + * Added `pre-command-run` event that lets plugins modify arguments + * Added RemoteFilesystem::getRemoteContents extension point + * Fixed setting scripts via `config` command + ### [1.6.5] 2018-05-04 * Fixed regression in 1.6.4 causing strange update behaviors with dev packages @@ -192,7 +228,7 @@ * Added `COMPOSER_MIRROR_PATH_REPOS` env var to force mirroring of path repositories vs symlinking * Added `COMPOSER_DEV_MODE` env var that is set by Composer to forward the dev mode to script handlers * Fixed support for git 2.11 - * Fixed output from zip and rar leaking out when an error occured + * Fixed output from zip and rar leaking out when an error occurred * Removed `hash` from composer.lock, only `content-hash` is now used which should reduce conflicts * Minor fixes and performance improvements @@ -651,6 +687,10 @@ * Initial release +[1.7.2]: https://github.com/composer/composer/compare/1.7.1...1.7.2 +[1.7.1]: https://github.com/composer/composer/compare/1.7.0...1.7.1 +[1.7.0]: https://github.com/composer/composer/compare/1.7.0-RC...1.7.0 +[1.7.0-RC]: https://github.com/composer/composer/compare/1.6.5...1.7.0-RC [1.6.5]: https://github.com/composer/composer/compare/1.6.4...1.6.5 [1.6.4]: https://github.com/composer/composer/compare/1.6.3...1.6.4 [1.6.3]: https://github.com/composer/composer/compare/1.6.2...1.6.3 diff --git a/app/vendor/composer/composer/README.md b/app/vendor/composer/composer/README.md index 3e1b7815d..c538df803 100644 --- a/app/vendor/composer/composer/README.md +++ b/app/vendor/composer/composer/README.md @@ -6,8 +6,6 @@ Composer helps you declare, manage, and install dependencies of PHP projects. See [https://getcomposer.org/](https://getcomposer.org/) for more information and documentation. [![Build Status](https://travis-ci.org/composer/composer.svg?branch=master)](https://travis-ci.org/composer/composer) -[![Dependency Status](https://www.versioneye.com/php/composer:composer/dev-master/badge.svg)](https://www.versioneye.com/php/composer:composer/dev-master) -[![Reference Status](https://www.versioneye.com/php/composer:composer/reference_badge.svg?style=flat)](https://www.versioneye.com/php/composer:composer/references) Installation / Usage -------------------- @@ -62,5 +60,3 @@ Acknowledgments - This project's Solver started out as a PHP port of openSUSE's [Libzypp satsolver](https://en.opensuse.org/openSUSE:Libzypp_satsolver). -- This project uses hiddeninput.exe to prompt for passwords on windows, sources - and details can be found on the [github page of the project](https://github.com/Seldaek/hidden-input). diff --git a/app/vendor/composer/composer/bin/composer b/app/vendor/composer/composer/bin/composer index 57baebc2e..7a80288b6 100755 --- a/app/vendor/composer/composer/bin/composer +++ b/app/vendor/composer/composer/bin/composer @@ -8,16 +8,13 @@ if (PHP_SAPI !== 'cli') { setlocale(LC_ALL, 'C'); require __DIR__.'/../src/bootstrap.php'; -use Composer\Factory; -use Composer\XdebugHandler; use Composer\Console\Application; +use Composer\XdebugHandler\XdebugHandler; error_reporting(-1); -// Create output for XdebugHandler and Application -$output = Factory::createOutput(); - -$xdebug = new XdebugHandler($output); +// Restart without xdebug +$xdebug = new XdebugHandler('Composer', '--ansi'); $xdebug->check(); unset($xdebug); @@ -57,4 +54,4 @@ putenv('COMPOSER_BINARY='.realpath($_SERVER['argv'][0])); // run the command application $application = new Application(); -$application->run(null, $output); +$application->run(); diff --git a/app/vendor/composer/composer/composer.json b/app/vendor/composer/composer/composer.json index 338a8b29b..91da0ec60 100644 --- a/app/vendor/composer/composer/composer.json +++ b/app/vendor/composer/composer/composer.json @@ -1,9 +1,13 @@ { "name": "composer/composer", + "type": "library", "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", - "keywords": ["package", "dependency", "autoload"], + "keywords": [ + "package", + "dependency", + "autoload" + ], "homepage": "https://getcomposer.org/", - "type": "library", "license": "MIT", "authors": [ { @@ -17,55 +21,61 @@ "homepage": "http://seld.be" } ], - "support": { - "irc": "irc://irc.freenode.org/composer", - "issues": "https://github.com/composer/composer/issues" - }, "require": { "php": "^5.3.2 || ^7.0", - "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", "composer/ca-bundle": "^1.0", "composer/semver": "^1.0", "composer/spdx-licenses": "^1.2", + "composer/xdebug-handler": "^1.1", + "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", + "psr/log": "^1.0", "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", "symfony/console": "^2.7 || ^3.0 || ^4.0", - "symfony/finder": "^2.7 || ^3.0 || ^4.0", - "symfony/process": "^2.7 || ^3.0 || ^4.0", "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", - "seld/phar-utils": "^1.0", - "seld/cli-prompt": "^1.0", - "psr/log": "^1.0" + "symfony/finder": "^2.7 || ^3.0 || ^4.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0" + }, + "conflict": { + "symfony/console": "2.8.38" }, "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7", "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" }, - "conflict": { - "symfony/console": "2.8.38" + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" }, "config": { "platform": { "php": "5.3.9" } }, - "suggest": { - "ext-zip": "Enabling the zip extension allows you to unzip archives", - "ext-zlib": "Allow gzip compression of HTTP requests", - "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages" + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } }, "autoload": { - "psr-4": { "Composer\\": "src/Composer" } + "psr-4": { + "Composer\\": "src/Composer" + } }, "autoload-dev": { - "psr-4": { "Composer\\Test\\": "tests/Composer/Test" } - }, - "bin": ["bin/composer"], - "extra": { - "branch-alias": { - "dev-master": "1.6-dev" + "psr-4": { + "Composer\\Test\\": "tests/Composer/Test" } }, + "bin": [ + "bin/composer" + ], "scripts": { "test": "phpunit" + }, + "support": { + "issues": "https://github.com/composer/composer/issues", + "irc": "irc://irc.freenode.org/composer" } } diff --git a/app/vendor/composer/composer/composer.lock b/app/vendor/composer/composer/composer.lock index edcfa43c8..690aca23e 100644 --- a/app/vendor/composer/composer/composer.lock +++ b/app/vendor/composer/composer/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9296254a03c57515ec82689fffcd8008", + "content-hash": "5c554bae92a73c12f7797833fd44e946", "packages": [ { "name": "composer/ca-bundle", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169" + "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/d2c0a83b7533d6912e8d516756ebd34f893e9169", - "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/46afded9720f40b9dc63542af4e3e43a1177acb0", + "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0", "shasum": "" }, "require": { @@ -60,7 +60,7 @@ "ssl", "tls" ], - "time": "2018-03-29T19:57:20+00:00" + "time": "2018-08-08T08:57:40+00:00" }, { "name": "composer/semver", @@ -126,16 +126,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "7e111c50db92fa2ced140f5ba23b4e261bc77a30" + "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7e111c50db92fa2ced140f5ba23b4e261bc77a30", - "reference": "7e111c50db92fa2ced140f5ba23b4e261bc77a30", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b", + "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b", "shasum": "" }, "require": { @@ -183,7 +183,51 @@ "spdx", "validator" ], - "time": "2018-01-31T13:17:27+00:00" + "time": "2018-04-30T10:33:04+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "e1809da56ce1bd1b547a752936817341ac244d8e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/e1809da56ce1bd1b547a752936817341ac244d8e", + "reference": "e1809da56ce1bd1b547a752936817341ac244d8e", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "time": "2018-08-16T10:54:23+00:00" }, { "name": "justinrainbow/json-schema", @@ -298,54 +342,6 @@ ], "time": "2016-10-10T12:19:37+00:00" }, - { - "name": "seld/cli-prompt", - "version": "1.0.3", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/cli-prompt.git", - "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", - "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Seld\\CliPrompt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", - "keywords": [ - "cli", - "console", - "hidden", - "input", - "prompt" - ], - "time": "2017-03-18T11:32:45+00:00" - }, { "name": "seld/jsonlint", "version": "1.7.1", @@ -441,16 +437,16 @@ }, { "name": "symfony/console", - "version": "v2.8.37", + "version": "v2.8.43", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "390fa4899dbcc47bd41935d87c4572ea4305d3ce" + "reference": "42a0adc7dd656ca2e360285eb6d822df9ce0b160" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/390fa4899dbcc47bd41935d87c4572ea4305d3ce", - "reference": "390fa4899dbcc47bd41935d87c4572ea4305d3ce", + "url": "https://api.github.com/repos/symfony/console/zipball/42a0adc7dd656ca2e360285eb6d822df9ce0b160", + "reference": "42a0adc7dd656ca2e360285eb6d822df9ce0b160", "shasum": "" }, "require": { @@ -464,7 +460,7 @@ "symfony/process": "~2.1|~3.0.0" }, "suggest": { - "psr/log": "For using the console logger", + "psr/log-implementation": "For using the console logger", "symfony/event-dispatcher": "", "symfony/process": "" }, @@ -498,20 +494,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2018-03-19T21:13:58+00:00" + "time": "2018-07-09T12:58:09+00:00" }, { "name": "symfony/debug", - "version": "v2.8.38", + "version": "v2.8.43", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "4486d2be5e068b51fece4c8551c14e709f573c8d" + "reference": "a26ddce7fe4e884097d72435653bc7e703411f26" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/4486d2be5e068b51fece4c8551c14e709f573c8d", - "reference": "4486d2be5e068b51fece4c8551c14e709f573c8d", + "url": "https://api.github.com/repos/symfony/debug/zipball/a26ddce7fe4e884097d72435653bc7e703411f26", + "reference": "a26ddce7fe4e884097d72435653bc7e703411f26", "shasum": "" }, "require": { @@ -555,24 +551,25 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2018-04-03T05:20:27+00:00" + "time": "2018-06-22T15:01:26+00:00" }, { "name": "symfony/filesystem", - "version": "v2.8.38", + "version": "v2.8.43", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "125403a59e4cb4e3ebf46d0162fabcde613d2b97" + "reference": "5cfc856c5b665ef5de0df796e98c54bef0fe595b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/125403a59e4cb4e3ebf46d0162fabcde613d2b97", - "reference": "125403a59e4cb4e3ebf46d0162fabcde613d2b97", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/5cfc856c5b665ef5de0df796e98c54bef0fe595b", + "reference": "5cfc856c5b665ef5de0df796e98c54bef0fe595b", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "type": "library", "extra": { @@ -604,20 +601,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2018-02-19T16:23:47+00:00" + "time": "2018-07-09T13:24:25+00:00" }, { "name": "symfony/finder", - "version": "v2.8.38", + "version": "v2.8.43", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "423746fc18ccf31f9abec43e4f078bb6e024b2d5" + "reference": "995cd7c28a0778cece02e2133b4d813dc509dfc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/423746fc18ccf31f9abec43e4f078bb6e024b2d5", - "reference": "423746fc18ccf31f9abec43e4f078bb6e024b2d5", + "url": "https://api.github.com/repos/symfony/finder/zipball/995cd7c28a0778cece02e2133b4d813dc509dfc3", + "reference": "995cd7c28a0778cece02e2133b4d813dc509dfc3", "shasum": "" }, "require": { @@ -653,20 +650,75 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2018-04-04T13:38:31+00:00" + "time": "2018-06-19T11:07:17+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-04-30T19:57:29+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.7.0", + "version": "v1.8.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" + "reference": "3296adf6a6454a050679cde90f95350ad604b171" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", - "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171", + "reference": "3296adf6a6454a050679cde90f95350ad604b171", "shasum": "" }, "require": { @@ -678,7 +730,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-master": "1.8-dev" } }, "autoload": { @@ -712,20 +764,20 @@ "portable", "shim" ], - "time": "2018-01-30T19:27:44+00:00" + "time": "2018-04-26T10:06:28+00:00" }, { "name": "symfony/process", - "version": "v2.8.38", + "version": "v2.8.43", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ee2c91470ff262b1a00aec27875d38594aa87629" + "reference": "542d88b350c42750fdc14e73860ee96dd423e95d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ee2c91470ff262b1a00aec27875d38594aa87629", - "reference": "ee2c91470ff262b1a00aec27875d38594aa87629", + "url": "https://api.github.com/repos/symfony/process/zipball/542d88b350c42750fdc14e73860ee96dd423e95d", + "reference": "542d88b350c42750fdc14e73860ee96dd423e95d", "shasum": "" }, "require": { @@ -761,7 +813,7 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2018-04-03T05:20:27+00:00" + "time": "2018-05-27T07:40:52+00:00" } ], "packages-dev": [ @@ -870,23 +922,23 @@ }, { "name": "phpspec/prophecy", - "version": "1.7.5", + "version": "1.7.6", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401" + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401", - "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", - "sebastian/comparator": "^1.1|^2.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { @@ -929,7 +981,7 @@ "spy", "stub" ], - "time": "2018-02-19T10:16:54+00:00" + "time": "2018-04-18T13:57:24+00:00" }, { "name": "phpunit/php-code-coverage", @@ -1681,20 +1733,21 @@ }, { "name": "symfony/yaml", - "version": "v2.8.38", + "version": "v2.8.43", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "be720fcfae4614df204190d57795351059946a77" + "reference": "51356b7a2ff7c9fd06b2f1681cc463bb62b5c1ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/be720fcfae4614df204190d57795351059946a77", - "reference": "be720fcfae4614df204190d57795351059946a77", + "url": "https://api.github.com/repos/symfony/yaml/zipball/51356b7a2ff7c9fd06b2f1681cc463bb62b5c1ff", + "reference": "51356b7a2ff7c9fd06b2f1681cc463bb62b5c1ff", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" }, "type": "library", "extra": { @@ -1726,7 +1779,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:36:31+00:00" + "time": "2018-05-01T22:52:40+00:00" } ], "aliases": [], diff --git a/app/vendor/composer/composer/doc/00-intro.md b/app/vendor/composer/composer/doc/00-intro.md index 2470f45fe..046fea8fe 100644 --- a/app/vendor/composer/composer/doc/00-intro.md +++ b/app/vendor/composer/composer/doc/00-intro.md @@ -57,16 +57,15 @@ project, or globally as a system wide executable. #### Locally -Installing Composer locally is a matter of just running the installer in your -project directory. See [the Download page](https://getcomposer.org/download/) -for instructions. +To install Composer locally, run the installer in your project directory. See +[the Download page](https://getcomposer.org/download/) for instructions. -The installer will just check a few PHP settings and then download -`composer.phar` to your working directory. This file is the Composer binary. It -is a PHAR (PHP archive), which is an archive format for PHP which can be run on +The installer will check a few PHP settings and then download `composer.phar` +to your working directory. This file is the Composer binary. It is a PHAR +(PHP archive), which is an archive format for PHP which can be run on the command line, amongst other things. -Now just run `php composer.phar` in order to run Composer. +Now run `php composer.phar` in order to run Composer. You can install Composer to a specific directory by using the `--install-dir` option and additionally (re)name it as well using the `--filename` option. When @@ -78,7 +77,7 @@ following parameters: php composer-setup.php --install-dir=bin --filename=composer ``` -Now just run `php bin/composer` in order to run Composer. +Now run `php bin/composer` in order to run Composer. #### Globally @@ -109,7 +108,7 @@ Linux distributions. > **Note:** For information on changing your PATH, please read the > [Wikipedia article](https://en.wikipedia.org/wiki/PATH_(variable)) and/or use Google. -Now just run `composer` in order to run Composer instead of `php composer.phar`. +Now run `composer` in order to run Composer instead of `php composer.phar`. ## Installation - Windows @@ -119,7 +118,7 @@ This is the easiest way to get Composer set up on your machine. Download and run [Composer-Setup.exe](https://getcomposer.org/Composer-Setup.exe). It will -install the latest Composer version and set up your PATH so that you can just +install the latest Composer version and set up your PATH so that you can call `composer` from any directory in your command line. > **Note:** Close your current terminal. Test usage with a new terminal: This is diff --git a/app/vendor/composer/composer/doc/01-basic-usage.md b/app/vendor/composer/composer/doc/01-basic-usage.md index 3119fd015..ffcb1589e 100644 --- a/app/vendor/composer/composer/doc/01-basic-usage.md +++ b/app/vendor/composer/composer/doc/01-basic-usage.md @@ -44,7 +44,7 @@ about Packagist [below](#packagist), or read more about repositories ### Package Names The package name consists of a vendor name and the project's name. Often these -will be identical - the vendor name just exists to prevent naming clashes. For +will be identical - the vendor name only exists to prevent naming clashes. For example, it would allow two different people to create a library named `json`. One might be named `igorw/json` while the other might be `seldaek/json`. @@ -86,7 +86,7 @@ versions, how versions relate to each other, and on version constraints. ## Installing Dependencies -To install the defined dependencies for your project, just run the +To install the defined dependencies for your project, run the [`install`](03-cli.md#install) command. ```sh @@ -154,8 +154,10 @@ and running `install` again.) ```sh php composer.phar update ``` + > **Note:** Composer will display a Warning when executing an `install` command -> if `composer.lock` and `composer.json` are not synchronized. +> if the `composer.lock` has not been updated since changes were made to the +> `composer.json` that might affect dependency resolution. If you only want to install or update one dependency, you can whitelist them: @@ -188,15 +190,15 @@ installed on the system but are not actually installable by Composer. This includes PHP itself, PHP extensions and some system libraries. * `php` represents the PHP version of the user, allowing you to apply - constraints, e.g. `>=5.4.0`. To require a 64bit version of php, you can + constraints, e.g. `^7.1`. To require a 64bit version of php, you can require the `php-64bit` package. * `hhvm` represents the version of the HHVM runtime and allows you to apply - a constraint, e.g., `>=2.3.3`. + a constraint, e.g., `^2.3`. * `ext-` allows you to require PHP extensions (includes core extensions). Versioning can be quite inconsistent here, so it's often - a good idea to just set the constraint to `*`. An example of an extension + a good idea to set the constraint to `*`. An example of an extension package name is `ext-gd`. * `lib-` allows constraints to be made on versions of libraries used by @@ -258,7 +260,7 @@ more information. See also the docs on [optimizing the autoloader](articles/autoloader-optimization.md). > **Note:** Composer provides its own autoloader. If you don't want to use that -> one, you can just include `vendor/composer/autoload_*.php` files, which return +> one, you can include `vendor/composer/autoload_*.php` files, which return > associative arrays allowing you to configure your own autoloader. ← [Intro](00-intro.md) | [Libraries](02-libraries.md) → diff --git a/app/vendor/composer/composer/doc/03-cli.md b/app/vendor/composer/composer/doc/03-cli.md index 31d0b6b50..0b46e04f5 100644 --- a/app/vendor/composer/composer/doc/03-cli.md +++ b/app/vendor/composer/composer/doc/03-cli.md @@ -65,7 +65,7 @@ php composer.phar init to a `composer` repository or a JSON string which similar to what the [repositories](04-schema.md#repositories) key accepts. -## install +## install / i The `install` command reads the `composer.json` file from the current directory, resolves the dependencies, and installs them into `vendor`. @@ -115,7 +115,7 @@ resolution. requirements and force the installation even if the local machine does not fulfill these. See also the [`platform`](06-config.md#platform) config option. -## update +## update / u In order to get the latest versions of the dependencies and to update the `composer.lock` file, you should use the `update` command. This command is also @@ -129,7 +129,7 @@ php composer.phar update This will resolve all dependencies of the project and write the exact versions into `composer.lock`. -If you just want to update a few packages and not all, you can list them as such: +If you only want to update a few packages and not all, you can list them as such: ```sh php composer.phar update vendor/package vendor/package2 @@ -184,7 +184,7 @@ php composer.phar require After adding/changing the requirements, the modified requirements will be installed or updated. -If you do not want to choose requirements interactively, you can just pass them +If you do not want to choose requirements interactively, you can pass them to the command. ```sh @@ -272,7 +272,7 @@ This can be used to install CLI utilities globally. Here is an example: php composer.phar global require friendsofphp/php-cs-fixer ``` -Now the `php-cs-fixer` binary is available globally. Just make sure your global +Now the `php-cs-fixer` binary is available globally. Make sure your global [vendor binaries](articles/vendor-binaries.md) directory is in your `$PATH` environment variable, you can get its location with the following command : @@ -280,7 +280,7 @@ environment variable, you can get its location with the following command : php composer.phar global config bin-dir --absolute ``` -If you wish to update the binary later on you can just run a global update: +If you wish to update the binary later on you can run a global update: ```sh php composer.phar global update @@ -289,7 +289,7 @@ php composer.phar global update ## search The search command allows you to search through the current project's package -repositories. Usually this will be just packagist. You simply pass it the +repositories. Usually this will be packagist. You simply pass it the terms you want to search for. ```sh @@ -520,7 +520,7 @@ vendor/seld/jsonlint: ## self-update (selfupdate) -To update Composer itself to the latest version, just run the `self-update` +To update Composer itself to the latest version, run the `self-update` command. It will replace your `composer.phar` with the latest version. ```sh @@ -665,6 +665,9 @@ By default the command checks for the packages on packagist.org. package. * **--no-progress:** Removes the progress display that can mess with some terminals or scripts which don't handle backspace characters. +* **--no-secure-http:** Disable the secure-http config option temporarily while + installing the root package. Use at your own risk. Using this flag is a bad + idea. * **--keep-vcs:** Skip the deletion of the VCS metadata for the created project. This is mostly useful if you run the command in non-interactive mode. @@ -721,7 +724,7 @@ Lists the name, version and license of every package installed. Use * **--list (-l):** List user defined scripts. To run [scripts](articles/scripts.md) manually you can use this command, -just give it the script name and optionally any required arguments. +give it the script name and optionally any required arguments. ## exec @@ -762,7 +765,7 @@ php composer.phar archive vendor/package 2.0.21 --format=zip ## help -To get more information about a certain command, just use `help`. +To get more information about a certain command, you can use `help`. ```sh php composer.phar help install diff --git a/app/vendor/composer/composer/doc/04-schema.md b/app/vendor/composer/composer/doc/04-schema.md index 250b4e415..42addb10f 100644 --- a/app/vendor/composer/composer/doc/04-schema.md +++ b/app/vendor/composer/composer/doc/04-schema.md @@ -43,7 +43,7 @@ Required for published packages (libraries). ### description -A short description of the package. Usually this is just one line long. +A short description of the package. Usually this is one line long. Required for published packages (libraries). @@ -104,7 +104,7 @@ Out of the box, Composer supports four types: [dedicated article](articles/custom-installers.md). Only use a custom type if you need custom logic during installation. It is -recommended to omit this field and have it just default to `library`. +recommended to omit this field and have it default to `library`. ### keywords @@ -127,6 +127,12 @@ An URL to the website of the project. Optional. +### readme + +A relative path to the readme document. + +Optional. + ### time Release date of the version. @@ -145,10 +151,10 @@ The recommended notation for the most common licenses is (alphabetical): - BSD-2-Clause - BSD-3-Clause - BSD-4-Clause -- GPL-2.0 -- GPL-3.0 -- LGPL-2.1 -- LGPL-3.0 +- GPL-2.0-only / GPL-2.0-or-later +- GPL-3.0-only / GPL-3.0-or-later +- LGPL-2.1-only / LGPL-2.1-or-later +- LGPL-3.0-only / LGPL-3.0-or-later - MIT Optional, but it is highly recommended to supply this. More identifiers are @@ -172,8 +178,8 @@ An Example for disjunctive licenses: ```json { "license": [ - "LGPL-2.1", - "GPL-3.0+" + "LGPL-2.1-only", + "GPL-3.0-or-later" ] } ``` @@ -182,7 +188,7 @@ Alternatively they can be separated with "or" and enclosed in parenthesis; ```json { - "license": "(LGPL-2.1 or GPL-3.0+)" + "license": "(LGPL-2.1-only or GPL-3.0-or-later)" } ``` @@ -272,7 +278,7 @@ All links are optional fields. `require` and `require-dev` additionally support stability flags ([root-only](04-schema.md#root-package)). These allow you to further restrict or expand the stability of a package beyond the scope of the [minimum-stability](#minimum-stability) setting. You can apply -them to a constraint, or just apply them to an empty constraint if you want to +them to a constraint, or apply them to an empty constraint if you want to allow unstable packages of a dependency for example. Example: @@ -408,7 +414,7 @@ simply list it in `provide`. #### suggest Suggested packages that can enhance or work well with this package. These are -just informational and are displayed after the package is installed, to give +informational and are displayed after the package is installed, to give your users a hint that they could add more packages, even though they are not strictly required. @@ -713,7 +719,7 @@ Use `"prefer-stable": true` to enable. Custom package repositories to use. -By default Composer just uses the packagist repository. By specifying +By default Composer only uses the packagist repository. By specifying repositories you can get packages from elsewhere. Repositories are not resolved recursively. You can only add them to your main @@ -733,7 +739,7 @@ The following repository types are supported: project. * **package:** If you depend on a project that does not have any support for composer whatsoever you can define the package inline using a `package` - repository. You basically just inline the `composer.json` object. + repository. You basically inline the `composer.json` object. For more information on any of these, see [Repositories](05-repositories.md). @@ -863,6 +869,22 @@ The example will include `/dir/foo/bar/file`, `/foo/bar/baz`, `/file.php`, Optional. +### abandoned + +Indicates whether this package has been abandoned. + +It can be boolean or a package name/URL pointing to a recommended alternative. + +Examples: + +Use `"abandoned": true` to indicates this package is abandoned. +Use `"abandoned": "monolog/monolog"` to indicates this package is abandoned and the +recommended alternative is `monolog/monolog`. + +Defaults to false. + +Optional. + ### non-feature-branches A list of regex patterns of branch names that are non-numeric (e.g. "latest" or something), diff --git a/app/vendor/composer/composer/doc/05-repositories.md b/app/vendor/composer/composer/doc/05-repositories.md index c28f34141..9706a07e0 100644 --- a/app/vendor/composer/composer/doc/05-repositories.md +++ b/app/vendor/composer/composer/doc/05-repositories.md @@ -11,7 +11,7 @@ understand some of the basic concepts that Composer is built on. ### Package Composer is a dependency manager. It installs packages locally. A package is -essentially just a directory containing something. In this case it is PHP +essentially a directory containing something. In this case it is PHP code, but in theory it could be anything. And it contains a package description which has a name and a version. The name and the version are used to identify the package. @@ -57,9 +57,9 @@ The main repository type is the `composer` repository. It uses a single `packages.json` file that contains all of the package metadata. This is also the repository type that packagist uses. To reference a -`composer` repository, just supply the path before the `packages.json` file. +`composer` repository, supply the path before the `packages.json` file. In the case of packagist, that file is located at `/packages.json`, so the URL of -the repository would be `packagist.org`. For `example.org/packages.json` the +the repository would be `repo.packagist.org`. For `example.org/packages.json` the repository URL would be `example.org`. #### packages @@ -177,7 +177,7 @@ integrity, for example: The file above declares that acme/foo and acme/bar can be found in this repository, by loading the file referenced by `providers-url`, replacing `%package%` by the vendor namespaced package name and `%hash%` by the -sha256 field. Those files themselves just contain package definitions as +sha256 field. Those files themselves contain package definitions as described [above](#packages). These fields are optional. You probably don't need them for your own custom @@ -305,12 +305,10 @@ After creating an OAuth consumer in the BitBucket control panel, you need to set the credentials like this (more info [here](https://getcomposer.org/doc/06-config.md#bitbucket-oauth)): ```json { - "config": { - "bitbucket-oauth": { - "bitbucket.org": { - "consumer-key": "myKey", - "consumer-secret": "mySecret" - } + "bitbucket-oauth": { + "bitbucket.org": { + "consumer-key": "myKey", + "consumer-secret": "mySecret" } } } @@ -606,7 +604,7 @@ private packages: } ``` -Each zip artifact is just a ZIP archive with `composer.json` in root folder: +Each zip artifact is a ZIP archive with `composer.json` in root folder: ```sh unzip -l acme-corp-parser-10.3.5.zip diff --git a/app/vendor/composer/composer/doc/06-config.md b/app/vendor/composer/composer/doc/06-config.md index 2980e1c31..87ffb02a0 100644 --- a/app/vendor/composer/composer/doc/06-config.md +++ b/app/vendor/composer/composer/doc/06-config.md @@ -65,13 +65,17 @@ an OAuth token for GitHub. A list of domain names and oauth keys. For example using `{"gitlab.com": "oauthtoken"}` as the value of this option will use `oauthtoken` to access -private repositories on gitlab. +private repositories on gitlab. Please note: If the package is not hosted at +gitlab.com the domain names must be also specified with the +[`gitlab-domains`](06-config.md#gitlab-domains) option. ## gitlab-token A list of domain names and private tokens. For example using `{"gitlab.com": "privatetoken"}` as the value of this option will use `privatetoken` to access -private repositories on gitlab. +private repositories on gitlab. Please note: If the package is not hosted at +gitlab.com the domain names must be also specified with the +[`gitlab-domains`](06-config.md#gitlab-domains) option. ## disable-tls @@ -120,7 +124,7 @@ value of this option will let Composer authenticate against example.org. Lets you fake platform packages (PHP and extensions) so that you can emulate a production env or define your target platform in the config. Example: `{"php": -"5.4", "ext-something": "4.0"}`. +"7.0.3", "ext-something": "4.0.3"}`. ## vendor-dir diff --git a/app/vendor/composer/composer/doc/articles/aliases.md b/app/vendor/composer/composer/doc/articles/aliases.md index 49261b22a..98a6d1335 100644 --- a/app/vendor/composer/composer/doc/articles/aliases.md +++ b/app/vendor/composer/composer/doc/articles/aliases.md @@ -60,7 +60,7 @@ Branch aliases are great for aliasing main development lines. But in order to use them you need to have control over the source repository, and you need to commit changes to version control. -This is not really fun when you just want to try a bugfix of some library that +This is not really fun when you want to try a bugfix of some library that is a dependency of your local project. For this reason, you can alias packages in your `require` and `require-dev` @@ -72,7 +72,7 @@ local project. You are using `symfony/monolog-bundle` which requires `monolog/monolog` version `1.*`. So you need your `dev-bugfix` to match that constraint. -Just add this to your project's root `composer.json`: +Add this to your project's root `composer.json`: ```json { diff --git a/app/vendor/composer/composer/doc/articles/handling-private-packages-with-satis.md b/app/vendor/composer/composer/doc/articles/handling-private-packages-with-satis.md index fb799a720..cdf31f6e4 100644 --- a/app/vendor/composer/composer/doc/articles/handling-private-packages-with-satis.md +++ b/app/vendor/composer/composer/doc/articles/handling-private-packages-with-satis.md @@ -77,7 +77,7 @@ or another constraint if you want really specific versions. } ``` -Once you've done this, you just run: +Once you've done this, you run: php bin/satis build @@ -306,7 +306,7 @@ be marked abandoned as well. It is possible to make satis automatically resolve and add all dependencies for your projects. This can be used with the Downloads functionality to have a -complete local mirror of packages. Just add the following to your `satis.json`: +complete local mirror of packages. Add the following to your `satis.json`: ```json { diff --git a/app/vendor/composer/composer/doc/articles/scripts.md b/app/vendor/composer/composer/doc/articles/scripts.md index a93f2f205..79ea01519 100644 --- a/app/vendor/composer/composer/doc/articles/scripts.md +++ b/app/vendor/composer/composer/doc/articles/scripts.md @@ -63,6 +63,9 @@ Composer fires the following named events during its execution process: - **pre-file-download**: occurs before files are downloaded and allows you to manipulate the `RemoteFilesystem` object prior to downloading files based on the URL to be downloaded. +- **pre-command-run**: occurs before a command is executed and allows you to + manipulate the `InputInterface` object's options and arguments to tweak + a command's behavior. > **Note:** Composer makes no assumptions about the state of your dependencies > prior to `install` or `update`. Therefore, you should not specify scripts diff --git a/app/vendor/composer/composer/doc/articles/troubleshooting.md b/app/vendor/composer/composer/doc/articles/troubleshooting.md index 80e639a63..d0a64506f 100644 --- a/app/vendor/composer/composer/doc/articles/troubleshooting.md +++ b/app/vendor/composer/composer/doc/articles/troubleshooting.md @@ -140,6 +140,12 @@ Debian-like systems): memory_limit = -1 ``` +Composer also respects a memory limit defined by the `COMPOSER_MEMORY_LIMIT` environment variable: + +```sh +COMPOSER_MEMORY_LIMIT=-1 composer.phar <...> +``` + Or, you can increase the limit with a command-line argument: ```sh @@ -163,7 +169,7 @@ please report this [issue](https://github.com/composer/composer/issues). 2. Search for an `AutoRun` key inside `HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor`, `HKEY_CURRENT_USER\Software\Microsoft\Command Processor` or `HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Command Processor`. -3. Check if it contains any path to non-existent file, if it's the case, just remove them. +3. Check if it contains any path to non-existent file, if it's the case, remove them. ## API rate limit and OAuth tokens @@ -281,7 +287,7 @@ for everyone. ## Composer hangs with SSH ControlMaster When you try to install packages from a Git repository and you use the `ControlMaster` -setting for your SSH connection, Composer might just hang endlessly and you see a `sh` +setting for your SSH connection, Composer might hang endlessly and you see a `sh` process in the `defunct` state in your process list. The reason for this is a SSH Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1988 diff --git a/app/vendor/composer/composer/doc/articles/vendor-binaries.md b/app/vendor/composer/composer/doc/articles/vendor-binaries.md index 9e678a950..0022b90b9 100644 --- a/app/vendor/composer/composer/doc/articles/vendor-binaries.md +++ b/app/vendor/composer/composer/doc/articles/vendor-binaries.md @@ -66,7 +66,7 @@ Say project `my-vendor/project-b` has requirements setup like this: ``` Running `composer install` for this `composer.json` will look at -all of project-b's dependencies and install them to `vendor/bin`. +all of project-a's binaries and install them to `vendor/bin`. In this case, Composer will make `vendor/my-vendor/project-a/bin/project-a-bin` available as `vendor/bin/project-a-bin`. On a Unix-like platform diff --git a/app/vendor/composer/composer/doc/articles/versions.md b/app/vendor/composer/composer/doc/articles/versions.md index a584d3e88..c1fb25551 100644 --- a/app/vendor/composer/composer/doc/articles/versions.md +++ b/app/vendor/composer/composer/doc/articles/versions.md @@ -74,11 +74,11 @@ correct location in your `vendor` directory. ### Branches -If you want Composer to check out a branch instead of a tag, you need to point it to the branch using the special `dev-*` prefix (or sometimes suffix; see below). If you're checking out a branch, it's assumed that you want to *work* on the branch and Composer actually clones the repo into the correct place in your `vendor` directory. For tags, it just copies the right files without actually cloning the repo. (You can modify this behavior with --prefer-source and --prefer-dist, see [install options](../03-cli.md#install).) +If you want Composer to check out a branch instead of a tag, you need to point it to the branch using the special `dev-*` prefix (or sometimes suffix; see below). If you're checking out a branch, it's assumed that you want to *work* on the branch and Composer actually clones the repo into the correct place in your `vendor` directory. For tags, it copies the right files without actually cloning the repo. (You can modify this behavior with --prefer-source and --prefer-dist, see [install options](../03-cli.md#install).) In the above example, if you wanted to check out the `my-feature` branch, you would specify `dev-my-feature` as the version constraint in your `require` clause. This would result in Composer cloning the `my-library` repository into my `vendor` directory and checking out the `my-feature` branch. -When branch names look like versions, we have to clarify for composer that we're trying to check out a branch and not a tag. In the above example, we have two version branches: `v1` and `v2`. To get Composer to check out one of these branches, you must specify a version constraint that looks like this: `v1.x-dev`. The `.x` is an arbitrary string that Composer requires to tell it that we're talking about the `v1` branch and not a `v1` tag (alternatively, you can just name the branch `v1.x` instead of `v1`). In the case of a branch with a version-like name (`v1`, in this case), you append `-dev` as a suffix, rather than using `dev-` as a prefix. +When branch names look like versions, we have to clarify for composer that we're trying to check out a branch and not a tag. In the above example, we have two version branches: `v1` and `v2`. To get Composer to check out one of these branches, you must specify a version constraint that looks like this: `v1.x-dev`. The `.x` is an arbitrary string that Composer requires to tell it that we're talking about the `v1` branch and not a `v1` tag (alternatively, you can name the branch `v1.x` instead of `v1`). In the case of a branch with a version-like name (`v1`, in this case), you append `-dev` as a suffix, rather than using `dev-` as a prefix. ### Minimum Stability diff --git a/app/vendor/composer/composer/doc/faqs/how-do-i-install-a-package-to-a-custom-path-for-my-framework.md b/app/vendor/composer/composer/doc/faqs/how-do-i-install-a-package-to-a-custom-path-for-my-framework.md index bd38d1e40..20a2e83ae 100644 --- a/app/vendor/composer/composer/doc/faqs/how-do-i-install-a-package-to-a-custom-path-for-my-framework.md +++ b/app/vendor/composer/composer/doc/faqs/how-do-i-install-a-package-to-a-custom-path-for-my-framework.md @@ -23,7 +23,7 @@ WordPress theme: Now when your theme is installed with Composer it will be placed into `wp-content/themes/themename/` folder. Check the -[current supported types](https://github.com/composer/installers#current-supported-types) +[current supported types](https://github.com/composer/installers#current-supported-package-types) for your package. As a **package consumer** you can set or override the install path for a package diff --git a/app/vendor/composer/composer/doc/faqs/how-to-install-composer-programmatically.md b/app/vendor/composer/composer/doc/faqs/how-to-install-composer-programmatically.md index 70568c506..02ca21d2b 100644 --- a/app/vendor/composer/composer/doc/faqs/how-to-install-composer-programmatically.md +++ b/app/vendor/composer/composer/doc/faqs/how-to-install-composer-programmatically.md @@ -2,16 +2,16 @@ As noted on the download page, the installer script contains a signature which changes when the installer code changes and as such -it should not be relied upon long term. +it should not be relied upon in the long term. -An alternative is to use this script which only works with unix utils: +An alternative is to use this script which only works with UNIX utilities: ```bash #!/bin/sh -EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig) +EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)" php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');") +ACTUAL_SIGNATURE="$(php -r "echo hash_file('SHA384', 'composer-setup.php');")" if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] then @@ -29,8 +29,8 @@ exit $RESULT The script will exit with 1 in case of failure, or 0 on success, and is quiet if no error occurs. -Alternatively if you want to rely on an exact copy of the installer you can fetch -a specific version from github's history. The commit hash should be enough to +Alternatively, if you want to rely on an exact copy of the installer, you can fetch +a specific version from GitHub's history. The commit hash should be enough to give it uniqueness and authenticity as long as you can trust the GitHub servers. For example: diff --git a/app/vendor/composer/composer/doc/faqs/which-version-numbering-system-does-composer-itself-use.md b/app/vendor/composer/composer/doc/faqs/which-version-numbering-system-does-composer-itself-use.md new file mode 100644 index 000000000..20095bb01 --- /dev/null +++ b/app/vendor/composer/composer/doc/faqs/which-version-numbering-system-does-composer-itself-use.md @@ -0,0 +1,4 @@ +# Which version numbering system does Composer itself use? + +Composer uses [Semantic Versioning (aka SemVer) +2.0.0](https://semver.org/spec/v2.0.0.html). diff --git a/app/vendor/composer/composer/doc/faqs/why-are-version-constraints-combining-comparisons-and-wildcards-a-bad-idea.md b/app/vendor/composer/composer/doc/faqs/why-are-version-constraints-combining-comparisons-and-wildcards-a-bad-idea.md index bac633a3b..f4aa5b157 100644 --- a/app/vendor/composer/composer/doc/faqs/why-are-version-constraints-combining-comparisons-and-wildcards-a-bad-idea.md +++ b/app/vendor/composer/composer/doc/faqs/why-are-version-constraints-combining-comparisons-and-wildcards-a-bad-idea.md @@ -16,6 +16,6 @@ but it is not possible to determine if when you wrote that you were thinking of a package in version 3.0.0 or not. Should it match because you asked for `>=2` or should it not match because you asked for a `2.*`? -For this reason, Composer just throws an error and says that this is invalid. +For this reason, Composer throws an error and says that this is invalid. The easy way to fix it is to think about what you really mean, and use only one of those rules. \ No newline at end of file diff --git a/app/vendor/composer/composer/res/composer-schema.json b/app/vendor/composer/composer/res/composer-schema.json index 77721edda..2ff405f1e 100644 --- a/app/vendor/composer/composer/res/composer-schema.json +++ b/app/vendor/composer/composer/res/composer-schema.json @@ -685,6 +685,7 @@ } }, "inline-package": { + "type": "object", "required": ["name", "version"], "properties": { "name": { diff --git a/app/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php b/app/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php index 9b9710d9e..d54f3d6f6 100644 --- a/app/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php +++ b/app/vendor/composer/composer/src/Composer/Autoload/AutoloadGenerator.php @@ -157,7 +157,7 @@ public function dump(Config $config, InstalledRepositoryInterface $localRepo, Pa // Collect information from all packages. $packageMap = $this->buildPackageMap($installationManager, $mainPackage, $localRepo->getCanonicalPackages()); - $autoloads = $this->parseAutoloads($packageMap, $mainPackage); + $autoloads = $this->parseAutoloads($packageMap, $mainPackage, $this->devMode === false); // Process the 'psr-0' base directories. foreach ($autoloads['psr-0'] as $namespace => $paths) { @@ -383,11 +383,15 @@ protected function validatePackage(PackageInterface $package) * * @param array $packageMap array of array(package, installDir-relative-to-composer.json) * @param PackageInterface $mainPackage root package instance + * @param bool $filterOutRequireDevPackages whether to filter out require-dev packages * @return array array('psr-0' => array('Ns\\Foo' => array('installDir'))) */ - public function parseAutoloads(array $packageMap, PackageInterface $mainPackage) + public function parseAutoloads(array $packageMap, PackageInterface $mainPackage, $filterOutRequireDevPackages = false) { $mainPackageMap = array_shift($packageMap); + if ($filterOutRequireDevPackages) { + $packageMap = $this->filterPackageMap($packageMap, $mainPackage); + } $sortedPackageMap = $this->sortPackageMap($packageMap); $sortedPackageMap[] = $mainPackageMap; array_unshift($packageMap, $mainPackageMap); @@ -899,6 +903,48 @@ protected function getFileIdentifier(PackageInterface $package, $path) return md5($package->getName() . ':' . $path); } + /** + * Filters out dev-dependencies + * + * @param array $packageMap + * @param PackageInterface $mainPackage + * @return array + */ + protected function filterPackageMap(array $packageMap, PackageInterface $mainPackage) + { + $packages = array(); + $include = array(); + + foreach ($packageMap as $item) { + $package = $item[0]; + $name = $package->getName(); + $packages[$name] = $package; + } + + $add = function (PackageInterface $package) use (&$add, $packages, &$include) { + foreach ($package->getRequires() as $link) { + $target = $link->getTarget(); + if (!isset($include[$target])) { + $include[$target] = true; + if (isset($packages[$target])) { + $add($packages[$target]); + } + } + } + }; + $add($mainPackage); + + return array_filter( + $packageMap, + function ($item) use ($include) { + $package = $item[0]; + $name = $package->getName(); + + return isset($include[$name]); + } + ); + } + /** * Sorts packages by dependency weight * diff --git a/app/vendor/composer/composer/src/Composer/Autoload/ClassLoader.php b/app/vendor/composer/composer/src/Composer/Autoload/ClassLoader.php index dc02dfb11..95f7e0978 100644 --- a/app/vendor/composer/composer/src/Composer/Autoload/ClassLoader.php +++ b/app/vendor/composer/composer/src/Composer/Autoload/ClassLoader.php @@ -377,7 +377,7 @@ private function findFileWithExtension($class, $ext) $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { diff --git a/app/vendor/composer/composer/src/Composer/Cache.php b/app/vendor/composer/composer/src/Composer/Cache.php index c3cba603a..44395c3a2 100644 --- a/app/vendor/composer/composer/src/Composer/Cache.php +++ b/app/vendor/composer/composer/src/Composer/Cache.php @@ -71,11 +71,13 @@ public function getRoot() public function read($file) { - $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); - if ($this->enabled && file_exists($this->root . $file)) { - $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG); + if ($this->enabled) { + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); + if (file_exists($this->root . $file)) { + $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG); - return file_get_contents($this->root . $file); + return file_get_contents($this->root . $file); + } } return false; @@ -142,19 +144,21 @@ public function copyFrom($file, $source) */ public function copyTo($file, $target) { - $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); - if ($this->enabled && file_exists($this->root . $file)) { - try { - touch($this->root . $file, filemtime($this->root . $file), time()); - } catch (\ErrorException $e) { - // fallback in case the above failed due to incorrect ownership - // see https://github.com/composer/composer/issues/4070 - Silencer::call('touch', $this->root . $file); - } + if ($this->enabled) { + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); + if (file_exists($this->root . $file)) { + try { + touch($this->root . $file, filemtime($this->root . $file), time()); + } catch (\ErrorException $e) { + // fallback in case the above failed due to incorrect ownership + // see https://github.com/composer/composer/issues/4070 + Silencer::call('touch', $this->root . $file); + } - $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG); + $this->io->writeError('Reading '.$this->root . $file.' from cache', true, IOInterface::DEBUG); - return copy($this->root . $file, $target); + return copy($this->root . $file, $target); + } } return false; @@ -167,9 +171,11 @@ public function gcIsNecessary() public function remove($file) { - $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); - if ($this->enabled && file_exists($this->root . $file)) { - return $this->filesystem->unlink($this->root . $file); + if ($this->enabled) { + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); + if (file_exists($this->root . $file)) { + return $this->filesystem->unlink($this->root . $file); + } } return false; @@ -216,9 +222,11 @@ public function gc($ttl, $maxSize) public function sha1($file) { - $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); - if ($this->enabled && file_exists($this->root . $file)) { - return sha1_file($this->root . $file); + if ($this->enabled) { + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); + if (file_exists($this->root . $file)) { + return sha1_file($this->root . $file); + } } return false; @@ -226,9 +234,11 @@ public function sha1($file) public function sha256($file) { - $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); - if ($this->enabled && file_exists($this->root . $file)) { - return hash_file('sha256', $this->root . $file); + if ($this->enabled) { + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); + if (file_exists($this->root . $file)) { + return hash_file('sha256', $this->root . $file); + } } return false; diff --git a/app/vendor/composer/composer/src/Composer/Command/AboutCommand.php b/app/vendor/composer/composer/src/Composer/Command/AboutCommand.php index fac42c312..8fbad05a8 100644 --- a/app/vendor/composer/composer/src/Composer/Command/AboutCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/AboutCommand.php @@ -25,7 +25,8 @@ protected function configure() $this ->setName('about') ->setDescription('Shows the short information about Composer.') - ->setHelp(<<setHelp( + <<php composer.phar about EOT ) @@ -34,7 +35,8 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { - $this->getIO()->write(<<getIO()->write( + <<Composer - Package Management for PHP Composer is a dependency manager tracking local dependencies of your projects and libraries. See https://getcomposer.org/ for more information. diff --git a/app/vendor/composer/composer/src/Composer/Command/ArchiveCommand.php b/app/vendor/composer/composer/src/Composer/Command/ArchiveCommand.php index bf64ca47e..29858c6fc 100644 --- a/app/vendor/composer/composer/src/Composer/Command/ArchiveCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/ArchiveCommand.php @@ -48,7 +48,8 @@ protected function configure() .' Note that the format will be appended.'), new InputOption('ignore-filters', false, InputOption::VALUE_NONE, 'Ignore filters when saving package'), )) - ->setHelp(<<setHelp( + <<archive command creates an archive of the specified format containing the files and directories of the Composer project or the specified package in the specified version and writes it to the specified directory. @@ -66,8 +67,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $composer = $this->getComposer(false); if ($composer) { $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'archive', $input, $output); - $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); - $composer->getEventDispatcher()->dispatchScript(ScriptEvents::PRE_ARCHIVE_CMD); + $eventDispatcher = $composer->getEventDispatcher(); + $eventDispatcher->dispatch($commandEvent->getName(), $commandEvent); + $eventDispatcher->dispatchScript(ScriptEvents::PRE_ARCHIVE_CMD); } if (null === $input->getOption('format')) { diff --git a/app/vendor/composer/composer/src/Composer/Command/BaseCommand.php b/app/vendor/composer/composer/src/Composer/Command/BaseCommand.php index d6b695ca8..d6b014d7d 100644 --- a/app/vendor/composer/composer/src/Composer/Command/BaseCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/BaseCommand.php @@ -15,8 +15,11 @@ use Composer\Composer; use Composer\Config; use Composer\Console\Application; +use Composer\Factory; use Composer\IO\IOInterface; use Composer\IO\NullIO; +use Composer\Plugin\PreCommandRunEvent; +use Composer\Plugin\PluginEvents; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Command\Command; @@ -123,6 +126,17 @@ public function setIO(IOInterface $io) */ protected function initialize(InputInterface $input, OutputInterface $output) { + // initialize a plugin-enabled Composer instance, either local or global + $disablePlugins = $input->hasParameterOption('--no-plugins'); + $composer = $this->getComposer(false, $disablePlugins); + if (null === $composer) { + $composer = Factory::createGlobal($this->getIO(), $disablePlugins); + } + if ($composer) { + $preCommandRunEvent = new PreCommandRunEvent(PluginEvents::PRE_COMMAND_RUN, $input, $this->getName()); + $composer->getEventDispatcher()->dispatch($preCommandRunEvent->getName(), $preCommandRunEvent); + } + if (true === $input->hasParameterOption(array('--no-ansi')) && $input->hasOption('no-progress')) { $input->setOption('no-progress', true); } diff --git a/app/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php b/app/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php index 5ca6effa3..4c8766ba3 100644 --- a/app/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/BaseDependencyCommand.php @@ -129,8 +129,11 @@ protected function doExecute(InputInterface $input, OutputInterface $output, $in $results = $repository->getDependents($needles, $constraint, $inverted, $recursive); if (empty($results)) { $extra = (null !== $constraint) ? sprintf(' in versions %smatching %s', $inverted ? 'not ' : '', $textConstraint) : ''; - $this->getIO()->writeError(sprintf('There is no installed package depending on "%s"%s', - $needle, $extra)); + $this->getIO()->writeError(sprintf( + 'There is no installed package depending on "%s"%s', + $needle, + $extra + )); } elseif ($renderTree) { $this->initStyles($output); $root = $packages[0]; @@ -180,8 +183,9 @@ protected function printTable(OutputInterface $output, $results) // Render table $renderer = new Table($output); $renderer->setStyle('compact'); - $renderer->getStyle()->setVerticalBorderChar(''); - $renderer->getStyle()->setCellRowContentFormat('%s '); + $rendererStyle = $renderer->getStyle(); + $rendererStyle->setVerticalBorderChar(''); + $rendererStyle->setCellRowContentFormat('%s '); $renderer->setRows($table)->render(); } diff --git a/app/vendor/composer/composer/src/Composer/Command/CheckPlatformReqsCommand.php b/app/vendor/composer/composer/src/Composer/Command/CheckPlatformReqsCommand.php index 8b59c28ea..5a68661cc 100644 --- a/app/vendor/composer/composer/src/Composer/Command/CheckPlatformReqsCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/CheckPlatformReqsCommand.php @@ -26,7 +26,8 @@ protected function configure() { $this->setName('check-platform-reqs') ->setDescription('Check that platform requirements are satisfied.') - ->setHelp(<<setHelp( + <<php composer.phar check-platform-reqs @@ -142,8 +143,9 @@ protected function printTable(OutputInterface $output, $results) // Render table $renderer = new Table($output); $renderer->setStyle('compact'); - $renderer->getStyle()->setVerticalBorderChar(''); - $renderer->getStyle()->setCellRowContentFormat('%s '); + $rendererStyle = $renderer->getStyle(); + $rendererStyle->setVerticalBorderChar(''); + $rendererStyle->setCellRowContentFormat('%s '); $renderer->setRows($table)->render(); } } diff --git a/app/vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php b/app/vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php index 362d28500..2514f6330 100644 --- a/app/vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/ClearCacheCommand.php @@ -28,7 +28,8 @@ protected function configure() ->setName('clear-cache') ->setAliases(array('clearcache')) ->setDescription('Clears composer\'s internal package cache.') - ->setHelp(<<setHelp( + <<clear-cache deletes all cached packages from composer's cache directory. EOT diff --git a/app/vendor/composer/composer/src/Composer/Command/ConfigCommand.php b/app/vendor/composer/composer/src/Composer/Command/ConfigCommand.php index 6e457dd78..b002fd3a7 100644 --- a/app/vendor/composer/composer/src/Composer/Command/ConfigCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/ConfigCommand.php @@ -75,7 +75,8 @@ protected function configure() new InputArgument('setting-key', null, 'Setting key'), new InputArgument('setting-value', InputArgument::IS_ARRAY, 'Setting value'), )) - ->setHelp(<<setHelp( + <<getOption('unset')) { + return $this->configSource->removeProperty($settingKey); + } + + return $this->configSource->addProperty($settingKey, count($values) > 1 ? $values : $values[0]); + } + throw new \InvalidArgumentException('Setting '.$settingKey.' does not exist or is not supported by this command'); } diff --git a/app/vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php b/app/vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php index b1e711f3a..cca5f1871 100644 --- a/app/vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/CreateProjectCommand.php @@ -80,7 +80,8 @@ protected function configure() new InputOption('no-install', null, InputOption::VALUE_NONE, 'Whether to skip installation of the package dependencies.'), new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'), )) - ->setHelp(<<setHelp( + <<create-project command creates a new project from a given package into a new directory. If executed without params and in a directory with a composer.json file it installs the packages for the current project. @@ -137,16 +138,14 @@ protected function execute(InputInterface $input, OutputInterface $output) $input->getOption('repository') ?: $input->getOption('repository-url'), $input->getOption('no-plugins'), $input->getOption('no-scripts'), - $input->getOption('keep-vcs'), $input->getOption('no-progress'), $input->getOption('no-install'), $input->getOption('ignore-platform-reqs'), - !$input->getOption('no-secure-http'), - $input->getOption('remove-vcs') + !$input->getOption('no-secure-http') ); } - public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false, $secureHttp = true, $removeVcs = false) + public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $noProgress = false, $noInstall = false, $ignorePlatformReqs = false, $secureHttp = true) { $oldCwd = getcwd(); @@ -156,7 +155,7 @@ public function installProject(IOInterface $io, Config $config, InputInterface $ $this->suggestedPackagesReporter = new SuggestedPackagesReporter($io); if ($packageName !== null) { - $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repository, $disablePlugins, $noScripts, $keepVcs, $noProgress, $ignorePlatformReqs, $secureHttp); + $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repository, $disablePlugins, $noScripts, $noProgress, $ignorePlatformReqs, $secureHttp); } else { $installedFromVcs = false; } @@ -198,10 +197,10 @@ public function installProject(IOInterface $io, Config $config, InputInterface $ $hasVcs = $installedFromVcs; if ( - !$keepVcs + !$input->getOption('keep-vcs') && $installedFromVcs && ( - $removeVcs + $input->getOption('remove-vcs') || !$io->isInteractive() || $io->askConfirmation('Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]? ', true) ) @@ -258,7 +257,7 @@ public function installProject(IOInterface $io, Config $config, InputInterface $ return 0; } - protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $keepVcs = false, $noProgress = false, $ignorePlatformReqs = false, $secureHttp = true) + protected function installRootPackage(IOInterface $io, Config $config, $packageName, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repository = null, $disablePlugins = false, $noScripts = false, $noProgress = false, $ignorePlatformReqs = false, $secureHttp = true) { if (!$secureHttp) { $config->merge(array('config' => array('secure-http' => false))); @@ -346,10 +345,6 @@ protected function installRootPackage(IOInterface $io, Config $config, $packageN $package = $package->getAliasOf(); } - if (0 === strpos($package->getPrettyVersion(), 'dev-') && in_array($package->getSourceType(), array('git', 'hg'))) { - $package->setSourceReference(substr($package->getPrettyVersion(), 4)); - } - $dm = $this->createDownloadManager($io, $config); $dm->setPreferSource($preferSource) ->setPreferDist($preferDist) diff --git a/app/vendor/composer/composer/src/Composer/Command/DependsCommand.php b/app/vendor/composer/composer/src/Composer/Command/DependsCommand.php index cbf75f736..acbc89a70 100644 --- a/app/vendor/composer/composer/src/Composer/Command/DependsCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/DependsCommand.php @@ -31,7 +31,8 @@ protected function configure() ->setName('depends') ->setAliases(array('why')) ->setDescription('Shows which packages cause the given package to be installed.') - ->setHelp(<<setHelp( + <<php composer.phar depends composer/composer diff --git a/app/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php b/app/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php index d8977493d..3efb34973 100644 --- a/app/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/DiagnoseCommand.php @@ -16,6 +16,7 @@ use Composer\Factory; use Composer\Config; use Composer\Downloader\TransportException; +use Composer\Repository\PlatformRepository; use Composer\Plugin\CommandEvent; use Composer\Plugin\PluginEvents; use Composer\Util\ConfigValidator; @@ -34,7 +35,7 @@ */ class DiagnoseCommand extends BaseCommand { - /** @var RemoteFileSystem */ + /** @var RemoteFilesystem */ protected $rfs; /** @var ProcessExecutor */ @@ -48,7 +49,8 @@ protected function configure() $this ->setName('diagnose') ->setDescription('Diagnoses the system to identify common errors.') - ->setHelp(<<setHelp( + <<diagnose command checks common errors to help debugging problems. The process exit code will be 1 in case of warnings and 2 for errors. @@ -81,7 +83,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } $config->merge(array('config' => array('secure-http' => false))); - $config->prohibitUrlByConfig('http://packagist.org', new NullIO); + $config->prohibitUrlByConfig('http://repo.packagist.org', new NullIO); $this->rfs = Factory::createRemoteFilesystem($io, $config); $this->process = new ProcessExecutor($io); @@ -152,7 +154,15 @@ protected function execute(InputInterface $input, OutputInterface $output) $io->write(sprintf('Composer version: %s', Composer::VERSION)); - $io->write(sprintf('PHP version: %s', PHP_VERSION)); + $platformOverrides = $config->get('platform') ?: array(); + $platformRepo = new PlatformRepository(array(), $platformOverrides); + $phpPkg = $platformRepo->findPackage('php', '*'); + $phpVersion = $phpPkg->getPrettyVersion(); + if (false !== strpos($phpPkg->getDescription(), 'overridden')) { + $phpVersion .= ' - ' . $phpPkg->getDescription(); + } + + $io->write(sprintf('PHP version: %s', $phpVersion)); if (defined('PHP_BINARY')) { $io->write(sprintf('PHP binary path: %s', PHP_BINARY)); @@ -208,7 +218,7 @@ private function checkHttp($proto, Config $config) } try { - $this->rfs->getContents('packagist.org', $proto . '://packagist.org/packages.json', false); + $this->rfs->getContents('packagist.org', $proto . '://repo.packagist.org/packages.json', false); } catch (TransportException $e) { if (false !== strpos($e->getMessage(), 'cafile')) { $result[] = '[' . get_class($e) . '] ' . $e->getMessage() . ''; @@ -230,11 +240,11 @@ private function checkHttpProxy() { $protocol = extension_loaded('openssl') ? 'https' : 'http'; try { - $json = json_decode($this->rfs->getContents('packagist.org', $protocol . '://packagist.org/packages.json', false), true); + $json = json_decode($this->rfs->getContents('packagist.org', $protocol . '://repo.packagist.org/packages.json', false), true); $hash = reset($json['provider-includes']); $hash = $hash['sha256']; $path = str_replace('%hash%', $hash, key($json['provider-includes'])); - $provider = $this->rfs->getContents('packagist.org', $protocol . '://packagist.org/'.$path, false); + $provider = $this->rfs->getContents('packagist.org', $protocol . '://repo.packagist.org/'.$path, false); if (hash('sha256', $provider) !== $hash) { return 'It seems that your proxy is modifying http traffic on the fly'; @@ -255,7 +265,7 @@ private function checkHttpProxy() */ private function checkHttpProxyFullUriRequestParam() { - $url = 'http://packagist.org/packages.json'; + $url = 'http://repo.packagist.org/packages.json'; try { $this->rfs->getContents('packagist.org', $url, false); } catch (TransportException $e) { diff --git a/app/vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php b/app/vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php index 6c79ef13f..fe80e3760 100644 --- a/app/vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/DumpAutoloadCommand.php @@ -36,7 +36,8 @@ protected function configure() new InputOption('apcu', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables autoload-dev rules.'), )) - ->setHelp(<<setHelp( + <<php composer.phar dump-autoload EOT ) diff --git a/app/vendor/composer/composer/src/Composer/Command/ExecCommand.php b/app/vendor/composer/composer/src/Composer/Command/ExecCommand.php index 2ab36f802..f07bc9d28 100644 --- a/app/vendor/composer/composer/src/Composer/Command/ExecCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/ExecCommand.php @@ -53,7 +53,8 @@ protected function execute(InputInterface $input, OutputInterface $output) throw new \RuntimeException("No binaries found in composer.json or in bin-dir ($binDir)"); } - $this->getIO()->write(<<getIO()->write( + <<Available binaries: EOT ); @@ -66,7 +67,8 @@ protected function execute(InputInterface $input, OutputInterface $output) $previousBin = $bin; $bin = basename($bin); - $this->getIO()->write(<<getIO()->write( + <<- $bin EOT ); diff --git a/app/vendor/composer/composer/src/Composer/Command/GlobalCommand.php b/app/vendor/composer/composer/src/Composer/Command/GlobalCommand.php index d189f44d5..e13b8aaf2 100644 --- a/app/vendor/composer/composer/src/Composer/Command/GlobalCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/GlobalCommand.php @@ -13,6 +13,7 @@ namespace Composer\Command; use Composer\Factory; +use Composer\Util\Filesystem; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\StringInput; @@ -32,7 +33,8 @@ protected function configure() new InputArgument('command-name', InputArgument::REQUIRED, ''), new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''), )) - ->setHelp(<<setHelp( + <<get('home')); - $this->getIO()->writeError('Changed current directory to '.$config->get('home').''); + $home = $config->get('home'); + + if (!is_dir($home)) { + $fs = new Filesystem(); + $fs->ensureDirectoryExists($home); + if (!is_dir($home)) { + throw new \RuntimeException('Could not create home directory'); + } + } + + try { + chdir($home); + } catch (\Exception $e) { + throw new \RuntimeException('Could not switch to home directory "'.$home.'"', 0, $e); + } + $this->getIO()->writeError('Changed current directory to '.$home.''); // create new input without "global" command prefix $input = new StringInput(preg_replace('{\bg(?:l(?:o(?:b(?:a(?:l)?)?)?)?)?\b}', '', $input->__toString(), 1)); diff --git a/app/vendor/composer/composer/src/Composer/Command/HomeCommand.php b/app/vendor/composer/composer/src/Composer/Command/HomeCommand.php index 4a550ff60..a2f0756a1 100644 --- a/app/vendor/composer/composer/src/Composer/Command/HomeCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/HomeCommand.php @@ -42,7 +42,8 @@ protected function configure() new InputOption('homepage', 'H', InputOption::VALUE_NONE, 'Open the homepage instead of the repository URL.'), new InputOption('show', 's', InputOption::VALUE_NONE, 'Only show the homepage or repository URL.'), )) - ->setHelp(<<setHelp( + <<setHelp(<<setHelp( + <<init command creates a basic composer.json file in the current directory. @@ -165,7 +166,7 @@ protected function interact(InputInterface $input, OutputInterface $output) } $repos[] = RepositoryFactory::createRepo($io, $config, array( 'type' => 'composer', - 'url' => 'https://packagist.org', + 'url' => 'https://repo.packagist.org', )); $this->repos = new CompositeRepository($repos); @@ -279,7 +280,7 @@ function ($value) use ($self, $author) { $minimumStability = $input->getOption('stability') ?: null; $minimumStability = $io->askAndValidate( 'Minimum Stability ['.$minimumStability.']: ', - function ($value) use ($self, $minimumStability) { + function ($value) use ($minimumStability) { if (null === $value) { return $minimumStability; } @@ -676,7 +677,7 @@ private function getMinimumStability(InputInterface $input) * @param string|null $requiredVersion * @param string $minimumStability * @throws \InvalidArgumentException - * @return array name version + * @return array name version */ private function findBestVersionAndNameForPackage(InputInterface $input, $name, $phpVersion, $preferredStability = 'stable', $requiredVersion = null, $minimumStability = null) { @@ -694,19 +695,26 @@ private function findBestVersionAndNameForPackage(InputInterface $input, $name, // Check whether the PHP version was the problem if ($phpVersion && $versionSelector->findBestCandidate($name, $requiredVersion, null, $preferredStability)) { throw new \InvalidArgumentException(sprintf( - 'Package %s at version %s has a PHP requirement incompatible with your PHP version (%s)', $name, $requiredVersion, $phpVersion + 'Package %s at version %s has a PHP requirement incompatible with your PHP version (%s)', + $name, + $requiredVersion, + $phpVersion )); } // Check whether the required version was the problem if ($requiredVersion && $versionSelector->findBestCandidate($name, null, $phpVersion, $preferredStability)) { throw new \InvalidArgumentException(sprintf( - 'Could not find package %s in a version matching %s', $name, $requiredVersion + 'Could not find package %s in a version matching %s', + $name, + $requiredVersion )); } // Check whether the PHP version was the problem if ($phpVersion && $versionSelector->findBestCandidate($name)) { throw new \InvalidArgumentException(sprintf( - 'Could not find package %s in any version matching your PHP version (%s)', $name, $phpVersion + 'Could not find package %s in any version matching your PHP version (%s)', + $name, + $phpVersion )); } @@ -738,7 +746,7 @@ private function findBestVersionAndNameForPackage(InputInterface $input, $name, return array( $package->getPrettyName(), - $versionSelector->findRecommendedRequireVersion($package) + $versionSelector->findRecommendedRequireVersion($package), ); } diff --git a/app/vendor/composer/composer/src/Composer/Command/InstallCommand.php b/app/vendor/composer/composer/src/Composer/Command/InstallCommand.php index b6ca802eb..cc590d8c9 100644 --- a/app/vendor/composer/composer/src/Composer/Command/InstallCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/InstallCommand.php @@ -32,6 +32,7 @@ protected function configure() { $this ->setName('install') + ->setAliases(array('i')) ->setDescription('Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json.') ->setDefinition(array( new InputOption('prefer-source', null, InputOption::VALUE_NONE, 'Forces installation from package sources when possible, including VCS information.'), @@ -51,7 +52,8 @@ protected function configure() new InputOption('ignore-platform-reqs', null, InputOption::VALUE_NONE, 'Ignore platform requirements (php & ext- packages).'), new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Should not be provided, use composer require instead to add a given package to composer.json.'), )) - ->setHelp(<<setHelp( + <<install command reads the composer.lock file from the current directory, processes it, and downloads and installs all the libraries and dependencies outlined in that file. If the file does not diff --git a/app/vendor/composer/composer/src/Composer/Command/LicensesCommand.php b/app/vendor/composer/composer/src/Composer/Command/LicensesCommand.php index 0c4537be1..9dec45e1b 100644 --- a/app/vendor/composer/composer/src/Composer/Command/LicensesCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/LicensesCommand.php @@ -36,7 +36,8 @@ protected function configure() new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'), new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables search in require-dev packages.'), )) - ->setHelp(<<setHelp( + <<setStyle('compact'); - $table->getStyle()->setVerticalBorderChar(''); - $table->getStyle()->setCellRowContentFormat('%s '); + $tableStyle = $table->getStyle(); + $tableStyle->setVerticalBorderChar(''); + $tableStyle->setCellRowContentFormat('%s '); $table->setHeaders(array('Name', 'Version', 'License')); foreach ($packages as $package) { $table->addRow(array( diff --git a/app/vendor/composer/composer/src/Composer/Command/OutdatedCommand.php b/app/vendor/composer/composer/src/Composer/Command/OutdatedCommand.php index f356a75b2..f867f75f4 100644 --- a/app/vendor/composer/composer/src/Composer/Command/OutdatedCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/OutdatedCommand.php @@ -37,7 +37,8 @@ protected function configure() new InputOption('minor-only', 'm', InputOption::VALUE_NONE, 'Show only packages that have minor SemVer-compatible updates. Use with the --outdated option.'), new InputOption('format', 'f', InputOption::VALUE_REQUIRED, 'Format of the output: text or json', 'text'), )) - ->setHelp(<<setHelp( + <<setName('prohibits') ->setAliases(array('why-not')) ->setDescription('Shows which packages prevent the given package from being installed.') - ->setHelp(<<setHelp( + <<php composer.phar prohibits composer/composer diff --git a/app/vendor/composer/composer/src/Composer/Command/RemoveCommand.php b/app/vendor/composer/composer/src/Composer/Command/RemoveCommand.php index 200340e9e..c97130c3a 100644 --- a/app/vendor/composer/composer/src/Composer/Command/RemoveCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/RemoveCommand.php @@ -48,7 +48,8 @@ protected function configure() new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'), new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), )) - ->setHelp(<<setHelp( + <<remove command removes a package from the current list of installed packages diff --git a/app/vendor/composer/composer/src/Composer/Command/RequireCommand.php b/app/vendor/composer/composer/src/Composer/Command/RequireCommand.php index 37cec85c7..01439207f 100644 --- a/app/vendor/composer/composer/src/Composer/Command/RequireCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/RequireCommand.php @@ -57,7 +57,8 @@ protected function configure() new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'), new InputOption('apcu-autoloader', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), )) - ->setHelp(<<setHelp( + <<setHelp(<<setHelp( + <<run-script command runs scripts defined in composer.json: php composer.phar run-script post-update-cmd @@ -128,8 +129,9 @@ protected function listScripts(OutputInterface $output) $renderer = new Table($output); $renderer->setStyle('compact'); - $renderer->getStyle()->setVerticalBorderChar(''); - $renderer->getStyle()->setCellRowContentFormat('%s '); + $rendererStyle = $renderer->getStyle(); + $rendererStyle->setVerticalBorderChar(''); + $rendererStyle->setCellRowContentFormat('%s '); $renderer->setRows($table)->render(); return 0; diff --git a/app/vendor/composer/composer/src/Composer/Command/ScriptAliasCommand.php b/app/vendor/composer/composer/src/Composer/Command/ScriptAliasCommand.php index 81f1454da..1aba0b074 100644 --- a/app/vendor/composer/composer/src/Composer/Command/ScriptAliasCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/ScriptAliasCommand.php @@ -43,7 +43,8 @@ protected function configure() new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables the dev mode.'), new InputArgument('args', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, ''), )) - ->setHelp(<<setHelp( + <<run-script command runs scripts defined in composer.json: php composer.phar run-script post-update-cmd diff --git a/app/vendor/composer/composer/src/Composer/Command/SearchCommand.php b/app/vendor/composer/composer/src/Composer/Command/SearchCommand.php index cdcc00dc4..ed180e84c 100644 --- a/app/vendor/composer/composer/src/Composer/Command/SearchCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/SearchCommand.php @@ -44,7 +44,8 @@ protected function configure() new InputOption('type', 't', InputOption::VALUE_REQUIRED, 'Search for a specific package type'), new InputArgument('tokens', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'tokens to search for'), )) - ->setHelp(<<setHelp( + <<php composer.phar search symfony composer @@ -59,7 +60,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $platformRepo = new PlatformRepository; $io = $this->getIO(); if (!($composer = $this->getComposer(false))) { - $composer = Factory::create($this->getIO(), array()); + $composer = Factory::create($this->getIO(), array(), $input->hasParameterOption('--no-plugins')); } $localRepo = $composer->getRepositoryManager()->getLocalRepository(); $installedRepo = new CompositeRepository(array($localRepo, $platformRepo)); diff --git a/app/vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.php b/app/vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.php index 52f7b87f0..2641a922b 100644 --- a/app/vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/SelfUpdateCommand.php @@ -53,7 +53,8 @@ protected function configure() new InputOption('snapshot', null, InputOption::VALUE_NONE, 'Force an update to the snapshot channel'), new InputOption('set-channel-only', null, InputOption::VALUE_NONE, 'Only store the channel as the default one and then exit'), )) - ->setHelp(<<setHelp( + <<self-update command checks getcomposer.org for newer versions of composer and if found, installs the latest. @@ -176,7 +177,9 @@ protected function execute(InputInterface $input, OutputInterface $output) $sigFile = 'file://'.$home.'/' . ($updatingToTag ? 'keys.tags.pub' : 'keys.dev.pub'); if (!file_exists($sigFile)) { - file_put_contents($home.'/keys.dev.pub', <<setHelp(<<setHelp( + <<getOption('tree') && $input->getOption('latest')) { + $io->writeError('The --tree (-t) option is not usable in combination with --latest (-l)'); + + return 1; + } + $format = $input->getOption('format'); if (!in_array($format, array('text', 'json'))) { $io->writeError(sprintf('Unsupported format "%s". See help for supported formats.', $format)); @@ -178,9 +185,6 @@ protected function execute(InputInterface $input, OutputInterface $output) // show single package or single version if (($packageFilter && false === strpos($packageFilter, '*')) || !empty($package)) { - if ('json' === $format) { - $io->writeError('Format "json" is only supported for package listings, falling back to format "text"'); - } if (empty($package)) { list($package, $versions) = $this->getPackage($installedRepo, $repos, $input->getArgument('package'), $input->getArgument('version')); @@ -200,7 +204,13 @@ protected function execute(InputInterface $input, OutputInterface $output) $exitCode = 0; if ($input->getOption('tree')) { - $this->displayPackageTree($package, $installedRepo, $repos); + $arrayTree = $this->generatePackageTree($package, $installedRepo, $repos); + + if ('json' === $format) { + $io->write(JsonFile::encode(array('installed' => array($arrayTree)))); + } else { + $this->displayPackageTree(array($arrayTree)); + } } else { $latestPackage = null; if ($input->getOption('latest')) { @@ -228,18 +238,22 @@ protected function execute(InputInterface $input, OutputInterface $output) // show tree view if requested if ($input->getOption('tree')) { - if ('json' === $format) { - $io->writeError('Format "json" is only supported for package listings, falling back to format "text"'); - } $rootRequires = $this->getRootRequires(); $packages = $installedRepo->getPackages(); usort($packages, 'strcmp'); + $arrayTree = array(); foreach ($packages as $package) { if (in_array($package->getName(), $rootRequires, true)) { - $this->displayPackageTree($package, $installedRepo, $repos); + $arrayTree[] = $this->generatePackageTree($package, $installedRepo, $repos); } } + if ('json' === $format) { + $io->write(JsonFile::encode(array('installed' => $arrayTree))); + } else { + $this->displayPackageTree($arrayTree); + } + return 0; } @@ -383,7 +397,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } if ($latestPackage && $latestPackage->isAbandoned()) { - $replacement = (is_string($latestPackage->getReplacementPackage())) + $replacement = is_string($latestPackage->getReplacementPackage()) ? 'Use ' . $latestPackage->getReplacementPackage() . ' instead' : 'No replacement was suggested'; $packageWarning = sprintf( @@ -706,85 +720,196 @@ protected function initStyles(OutputInterface $output) /** * Display the tree * - * @param PackageInterface|string $package - * @param RepositoryInterface $installedRepo - * @param RepositoryInterface $distantRepos + * @param $arrayTree */ - protected function displayPackageTree(PackageInterface $package, RepositoryInterface $installedRepo, RepositoryInterface $distantRepos) + protected function displayPackageTree(array $arrayTree) { $io = $this->getIO(); - $io->write(sprintf('%s', $package->getPrettyName()), false); - $io->write(' ' . $package->getPrettyVersion(), false); - $io->write(' ' . strtok($package->getDescription(), "\r\n")); + foreach ($arrayTree as $package) { + $io->write(sprintf('%s', $package['name']), false); + $io->write(' ' . $package['version'], false); + $io->write(' ' . strtok($package['description'], "\r\n")); + + if (isset($package['requires'])) { + $requires = $package['requires']; + $treeBar = '├'; + $j = 0; + $total = count($requires); + foreach ($requires as $require) { + $requireName = $require['name']; + $j++; + if ($j === $total) { + $treeBar = '└'; + } + $level = 1; + $color = $this->colors[$level]; + $info = sprintf( + '%s──<%s>%s %s', + $treeBar, + $color, + $requireName, + $color, + $require['version'] + ); + $this->writeTreeLine($info); + + $treeBar = str_replace('└', ' ', $treeBar); + $packagesInTree = array($package['name'], $requireName); + + $this->displayTree($require, $packagesInTree, $treeBar, $level + 1); + } + } + } + } + /** + * Generate the package tree + * + * @param PackageInterface|string $package + * @param RepositoryInterface $installedRepo + * @param RepositoryInterface $distantRepos + * @return array + */ + protected function generatePackageTree( + PackageInterface $package, + RepositoryInterface $installedRepo, + RepositoryInterface $distantRepos + ) { if (is_object($package)) { $requires = $package->getRequires(); ksort($requires); - $treeBar = '├'; - $j = 0; - $total = count($requires); + $children = array(); foreach ($requires as $requireName => $require) { - $j++; - if ($j == 0) { - $this->writeTreeLine($treeBar); - } - if ($j == $total) { - $treeBar = '└'; + $packagesInTree = array($package->getName(), $requireName); + + $treeChildDesc = array( + 'name' => $requireName, + 'version' => $require->getPrettyConstraint(), + ); + + $deepChildren = $this->addTree($requireName, $require, $installedRepo, $distantRepos, $packagesInTree); + + if ($deepChildren) { + $treeChildDesc['requires'] = $deepChildren; } - $level = 1; - $color = $this->colors[$level]; - $info = sprintf('%s──<%s>%s %s', $treeBar, $color, $requireName, $color, $require->getPrettyConstraint()); - $this->writeTreeLine($info); - $treeBar = str_replace('└', ' ', $treeBar); - $packagesInTree = array($package->getName(), $requireName); + $children[] = $treeChildDesc; + } + $tree = array( + 'name' => $package->getPrettyName(), + 'version' => $package->getPrettyVersion(), + 'description' => $package->getDescription(), + ); - $this->displayTree($requireName, $require, $installedRepo, $distantRepos, $packagesInTree, $treeBar, $level + 1); + if ($children) { + $tree['requires'] = $children; } + + return $tree; } } /** * Display a package tree * - * @param string $name * @param PackageInterface|string $package - * @param RepositoryInterface $installedRepo - * @param RepositoryInterface $distantRepos * @param array $packagesInTree * @param string $previousTreeBar * @param int $level */ - protected function displayTree($name, $package, RepositoryInterface $installedRepo, RepositoryInterface $distantRepos, array $packagesInTree, $previousTreeBar = '├', $level = 1) - { + protected function displayTree( + $package, + array $packagesInTree, + $previousTreeBar = '├', + $level = 1 + ) { $previousTreeBar = str_replace('├', '│', $previousTreeBar); - list($package, $versions) = $this->getPackage($installedRepo, $distantRepos, $name, $package->getPrettyConstraint() === 'self.version' ? $package->getConstraint() : $package->getPrettyConstraint()); - if (is_object($package)) { - $requires = $package->getRequires(); - ksort($requires); + if (isset($package['requires'])) { + $requires = $package['requires']; $treeBar = $previousTreeBar . ' ├'; $i = 0; $total = count($requires); - foreach ($requires as $requireName => $require) { + foreach ($requires as $require) { $currentTree = $packagesInTree; $i++; - if ($i == $total) { + if ($i === $total) { $treeBar = $previousTreeBar . ' └'; } $colorIdent = $level % count($this->colors); $color = $this->colors[$colorIdent]; - $circularWarn = in_array($requireName, $currentTree) ? '(circular dependency aborted here)' : ''; - $info = rtrim(sprintf('%s──<%s>%s %s %s', $treeBar, $color, $requireName, $color, $require->getPrettyConstraint(), $circularWarn)); + $circularWarn = in_array( + $require['name'], + $currentTree, + true + ) ? '(circular dependency aborted here)' : ''; + $info = rtrim(sprintf( + '%s──<%s>%s %s %s', + $treeBar, + $color, + $require['name'], + $color, + $require['version'], + $circularWarn + )); $this->writeTreeLine($info); $treeBar = str_replace('└', ' ', $treeBar); - if (!in_array($requireName, $currentTree)) { + + $currentTree[] = $require['name']; + $this->displayTree($require, $currentTree, $treeBar, $level + 1); + } + } + } + + /** + * Display a package tree + * + * @param string $name + * @param PackageInterface|string $package + * @param RepositoryInterface $installedRepo + * @param RepositoryInterface $distantRepos + * @param array $packagesInTree + * @return array + */ + protected function addTree( + $name, + $package, + RepositoryInterface $installedRepo, + RepositoryInterface $distantRepos, + array $packagesInTree + ) { + $children = array(); + list($package, $versions) = $this->getPackage( + $installedRepo, + $distantRepos, + $name, + $package->getPrettyConstraint() === 'self.version' ? $package->getConstraint() : $package->getPrettyConstraint() + ); + if (is_object($package)) { + $requires = $package->getRequires(); + ksort($requires); + foreach ($requires as $requireName => $require) { + $currentTree = $packagesInTree; + + $treeChildDesc = array( + 'name' => $requireName, + 'version' => $require->getPrettyConstraint(), + ); + + if (!in_array($requireName, $currentTree, true)) { $currentTree[] = $requireName; - $this->displayTree($requireName, $require, $installedRepo, $distantRepos, $currentTree, $treeBar, $level + 1); + $deepChildren = $this->addTree($requireName, $require, $installedRepo, $distantRepos, $currentTree); + if ($deepChildren) { + $treeChildDesc['requires'] = $deepChildren; + } } + + $children[] = $treeChildDesc; } } + + return $children; } private function updateStatusToVersionStyle($updateStatus) diff --git a/app/vendor/composer/composer/src/Composer/Command/StatusCommand.php b/app/vendor/composer/composer/src/Composer/Command/StatusCommand.php index 83d646e39..3e46b7fa0 100644 --- a/app/vendor/composer/composer/src/Composer/Command/StatusCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/StatusCommand.php @@ -36,6 +36,9 @@ class StatusCommand extends BaseCommand const EXIT_CODE_UNPUSHED_CHANGES = 2; const EXIT_CODE_VERSION_CHANGES = 4; + /** + * @throws \Symfony\Component\Console\Exception\InvalidArgumentException + */ protected function configure() { $this @@ -44,7 +47,8 @@ protected function configure() ->setDefinition(array( new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Show modified files for each directory that contains changes.'), )) - ->setHelp(<<setHelp( + <<setHelp(<<setHelp( + <<%command.name% command shows a sorted list of suggested packages. diff --git a/app/vendor/composer/composer/src/Composer/Command/UpdateCommand.php b/app/vendor/composer/composer/src/Composer/Command/UpdateCommand.php index 1610d2872..34420b747 100644 --- a/app/vendor/composer/composer/src/Composer/Command/UpdateCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/UpdateCommand.php @@ -34,7 +34,7 @@ protected function configure() { $this ->setName('update') - ->setAliases(array('upgrade')) + ->setAliases(array('u', 'upgrade')) ->setDescription('Upgrades your dependencies to the latest version according to composer.json, and updates the composer.lock file.') ->setDefinition(array( new InputArgument('packages', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, 'Packages that should be updated, if not provided all packages are.'), @@ -61,7 +61,8 @@ protected function configure() new InputOption('interactive', 'i', InputOption::VALUE_NONE, 'Interactive interface with autocompletion to select the packages to update.'), new InputOption('root-reqs', null, InputOption::VALUE_NONE, 'Restricts the update to your first degree dependencies.'), )) - ->setHelp(<<setHelp( + <<update command reads the composer.json file from the current directory, processes it, and updates, removes or installs all the dependencies. diff --git a/app/vendor/composer/composer/src/Composer/Command/ValidateCommand.php b/app/vendor/composer/composer/src/Composer/Command/ValidateCommand.php index c4f78d2df..52bba1838 100644 --- a/app/vendor/composer/composer/src/Composer/Command/ValidateCommand.php +++ b/app/vendor/composer/composer/src/Composer/Command/ValidateCommand.php @@ -46,7 +46,8 @@ protected function configure() new InputOption('strict', null, InputOption::VALUE_NONE, 'Return a non-zero exit code for warnings as well as errors'), new InputArgument('file', InputArgument::OPTIONAL, 'path to composer.json file'), )) - ->setHelp(<<setHelp( + <<validate($file, $checkAll); $lockErrors = array(); - $composer = Factory::create($io, $file); + $composer = Factory::create($io, $file, $input->hasParameterOption('--no-plugins')); $locker = $composer->getLocker(); if ($locker->isLocked() && !$locker->isFresh()) { $lockErrors[] = 'The lock file is not up to date with the latest changes in composer.json, it is recommended that you run `composer update`.'; diff --git a/app/vendor/composer/composer/src/Composer/Compiler.php b/app/vendor/composer/composer/src/Composer/Compiler.php index 34eca8be2..4064b20b5 100644 --- a/app/vendor/composer/composer/src/Composer/Compiler.php +++ b/app/vendor/composer/composer/src/Composer/Compiler.php @@ -105,7 +105,7 @@ public function compile($pharFile = 'composer.phar') foreach ($finder as $file) { $this->addFile($phar, $file, false); } - $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/seld/cli-prompt/res/hiddeninput.exe'), false); + $this->addFile($phar, new \SplFileInfo(__DIR__ . '/../../vendor/symfony/console/Resources/bin/hiddeninput.exe'), false); $finder = new Finder(); $finder->files() @@ -117,11 +117,11 @@ public function compile($pharFile = 'composer.phar') ->exclude('docs') ->in(__DIR__.'/../../vendor/symfony/') ->in(__DIR__.'/../../vendor/seld/jsonlint/') - ->in(__DIR__.'/../../vendor/seld/cli-prompt/') ->in(__DIR__.'/../../vendor/justinrainbow/json-schema/') ->in(__DIR__.'/../../vendor/composer/spdx-licenses/') ->in(__DIR__.'/../../vendor/composer/semver/') ->in(__DIR__.'/../../vendor/composer/ca-bundle/') + ->in(__DIR__.'/../../vendor/composer/xdebug-handler/') ->in(__DIR__.'/../../vendor/psr/') ->sort($finderSort) ; diff --git a/app/vendor/composer/composer/src/Composer/Composer.php b/app/vendor/composer/composer/src/Composer/Composer.php index 4de6fafc7..b1a131a4f 100644 --- a/app/vendor/composer/composer/src/Composer/Composer.php +++ b/app/vendor/composer/composer/src/Composer/Composer.php @@ -29,9 +29,9 @@ */ class Composer { - const VERSION = '1.6.5'; + const VERSION = '1.7.2'; const BRANCH_ALIAS_VERSION = ''; - const RELEASE_DATE = '2018-05-04 11:44:59'; + const RELEASE_DATE = '2018-08-16 16:57:12'; /** * @var Package\RootPackageInterface diff --git a/app/vendor/composer/composer/src/Composer/Config.php b/app/vendor/composer/composer/src/Composer/Config.php index a7fca2988..7b4220724 100644 --- a/app/vendor/composer/composer/src/Composer/Config.php +++ b/app/vendor/composer/composer/src/Composer/Config.php @@ -72,7 +72,7 @@ class Config public static $defaultRepositories = array( 'packagist.org' => array( 'type' => 'composer', - 'url' => 'https?://packagist.org', + 'url' => 'https?://repo.packagist.org', 'allow_ssl_downgrade' => true, ), ); @@ -245,9 +245,11 @@ public function get($key, $flags = 0) case 'g': $size *= 1024; // intentional fallthrough + // no break case 'm': $size *= 1024; // intentional fallthrough + // no break case 'k': $size *= 1024; break; diff --git a/app/vendor/composer/composer/src/Composer/Config/JsonConfigSource.php b/app/vendor/composer/composer/src/Composer/Config/JsonConfigSource.php index 68de49ab3..128ebf8ec 100644 --- a/app/vendor/composer/composer/src/Composer/Config/JsonConfigSource.php +++ b/app/vendor/composer/composer/src/Composer/Config/JsonConfigSource.php @@ -135,10 +135,10 @@ public function removeConfigSetting($name) public function addProperty($name, $value) { $this->manipulateJson('addProperty', $name, $value, function (&$config, $key, $val) { - if (substr($key, 0, 6) === 'extra.') { + if (substr($key, 0, 6) === 'extra.' || substr($key, 0, 8) === 'scripts.') { $bits = explode('.', $key); $last = array_pop($bits); - $arr = &$config['extra']; + $arr = &$config[reset($bits)]; foreach ($bits as $bit) { if (!isset($arr[$bit])) { $arr[$bit] = array(); @@ -159,10 +159,10 @@ public function removeProperty($name) { $authConfig = $this->authConfig; $this->manipulateJson('removeProperty', $name, function (&$config, $key) { - if (substr($key, 0, 6) === 'extra.') { + if (substr($key, 0, 6) === 'extra.' || substr($key, 0, 8) === 'scripts.') { $bits = explode('.', $key); $last = array_pop($bits); - $arr = &$config['extra']; + $arr = &$config[reset($bits)]; foreach ($bits as $bit) { if (!isset($arr[$bit])) { return; diff --git a/app/vendor/composer/composer/src/Composer/Console/Application.php b/app/vendor/composer/composer/src/Composer/Console/Application.php index 655b059d7..a7cf26921 100644 --- a/app/vendor/composer/composer/src/Composer/Console/Application.php +++ b/app/vendor/composer/composer/src/Composer/Console/Application.php @@ -12,6 +12,7 @@ namespace Composer\Console; +use Composer\IO\NullIO; use Composer\Util\Platform; use Composer\Util\Silencer; use Symfony\Component\Console\Application as BaseApplication; @@ -85,6 +86,8 @@ public function __construct() }); } + $this->io = new NullIO(); + parent::__construct('Composer', Composer::VERSION); } diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php index 0af3617d4..df8a2a003 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/GenericRule.php @@ -75,7 +75,7 @@ public function isAssertion() */ public function __toString() { - $result = ($this->isDisabled()) ? 'disabled(' : '('; + $result = $this->isDisabled() ? 'disabled(' : '('; foreach ($this->literals as $i => $literal) { if ($i != 0) { diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php index debc8678c..de24b0991 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/Problem.php @@ -11,6 +11,7 @@ */ namespace Composer\DependencyResolver; + use Composer\Package\CompletePackageInterface; /** @@ -247,6 +248,6 @@ protected function getPackageList($packages) */ protected function constraintToText($constraint) { - return ($constraint) ? ' '.$constraint->getPrettyString() : ''; + return $constraint ? ' '.$constraint->getPrettyString() : ''; } } diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php index b2dd7708d..1fe8cbd30 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/Rule.php @@ -41,6 +41,7 @@ abstract class Rule const BITFIELD_DISABLED = 16; protected $bitfield; + protected $job; protected $reasonData; /** @@ -67,7 +68,7 @@ abstract public function getHash(); public function getJob() { - return isset($this->job) ? $this->job : null; + return $this->job; } abstract public function equals(Rule $rule); diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php index 359fe4f20..6bf47db34 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/Rule2Literals.php @@ -50,9 +50,7 @@ public function getLiterals() public function getHash() { - $data = unpack('ihash', md5($this->literal1.','.$this->literal2, true)); - - return $data['hash']; + return $this->literal1.','.$this->literal2; } /** @@ -65,6 +63,19 @@ public function getHash() */ public function equals(Rule $rule) { + // specialized fast-case + if ($rule instanceof self) { + if ($this->literal1 !== $rule->literal1) { + return false; + } + + if ($this->literal2 !== $rule->literal2) { + return false; + } + + return true; + } + $literals = $rule->getLiterals(); if (2 != count($literals)) { return false; @@ -93,7 +104,7 @@ public function isAssertion() */ public function __toString() { - $result = ($this->isDisabled()) ? 'disabled(' : '('; + $result = $this->isDisabled() ? 'disabled(' : '('; $result .= $this->literal1 . '|' . $this->literal2 . ')'; diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php index 2cf150a33..c534be958 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/RuleSetGenerator.php @@ -199,7 +199,7 @@ protected function addRulesForPackage(PackageInterface $package, $ignorePlatform $possibleRequires = $this->pool->whatProvides($link->getTarget(), $link->getConstraint()); - $this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRequireRule($package, $possibleRequires, Rule::RULE_PACKAGE_REQUIRES, $link)); + $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package, $possibleRequires, Rule::RULE_PACKAGE_REQUIRES, $link)); foreach ($possibleRequires as $require) { $workQueue->enqueue($require); @@ -215,7 +215,7 @@ protected function addRulesForPackage(PackageInterface $package, $ignorePlatform } // check obsoletes and implicit obsoletes of a package - $isInstalled = (isset($this->installedMap[$package->id])); + $isInstalled = isset($this->installedMap[$package->id]); foreach ($package->getReplaces() as $link) { $obsoleteProviders = $this->pool->whatProvides($link->getTarget(), $link->getConstraint()); @@ -226,13 +226,14 @@ protected function addRulesForPackage(PackageInterface $package, $ignorePlatform } if (!$this->obsoleteImpossibleForAlias($package, $provider)) { - $reason = ($isInstalled) ? Rule::RULE_INSTALLED_PACKAGE_OBSOLETES : Rule::RULE_PACKAGE_OBSOLETES; + $reason = $isInstalled ? Rule::RULE_INSTALLED_PACKAGE_OBSOLETES : Rule::RULE_PACKAGE_OBSOLETES; $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRule2Literals($package, $provider, $reason, $link)); } } } - $obsoleteProviders = $this->pool->whatProvides($package->getName(), null); + $packageName = $package->getName(); + $obsoleteProviders = $this->pool->whatProvides($packageName, null); foreach ($obsoleteProviders as $provider) { if ($provider === $package) { @@ -240,10 +241,10 @@ protected function addRulesForPackage(PackageInterface $package, $ignorePlatform } if (($package instanceof AliasPackage) && $package->getAliasOf() === $provider) { - $this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRequireRule($package, array($provider), Rule::RULE_PACKAGE_ALIAS, $package)); + $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRequireRule($package, array($provider), Rule::RULE_PACKAGE_ALIAS, $package)); } elseif (!$this->obsoleteImpossibleForAlias($package, $provider)) { - $reason = ($package->getName() == $provider->getName()) ? Rule::RULE_PACKAGE_SAME_NAME : Rule::RULE_PACKAGE_IMPLICIT_OBSOLETES; - $this->addRule(RuleSet::TYPE_PACKAGE, $rule = $this->createRule2Literals($package, $provider, $reason, $package)); + $reason = ($packageName == $provider->getName()) ? Rule::RULE_PACKAGE_SAME_NAME : Rule::RULE_PACKAGE_IMPLICIT_OBSOLETES; + $this->addRule(RuleSet::TYPE_PACKAGE, $this->createRule2Literals($package, $provider, $reason, $package)); } } } diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/RuleWatchNode.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/RuleWatchNode.php index 3d31a38c5..eeaa54162 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/RuleWatchNode.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/RuleWatchNode.php @@ -37,8 +37,9 @@ public function __construct($rule) $literals = $rule->getLiterals(); - $this->watch1 = count($literals) > 0 ? $literals[0] : 0; - $this->watch2 = count($literals) > 1 ? $literals[1] : 0; + $literalCount = count($literals); + $this->watch1 = $literalCount > 0 ? $literals[0] : 0; + $this->watch2 = $literalCount > 1 ? $literals[1] : 0; } /** diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php index 520109d66..1ed35ad9c 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/Solver.php @@ -30,7 +30,7 @@ class Solver protected $pool; /** @var RepositoryInterface */ protected $installed; - /** @var Ruleset */ + /** @var RuleSet */ protected $rules; /** @var RuleSetGenerator */ protected $ruleSetGenerator; @@ -100,7 +100,7 @@ private function makeAssertionRuleDecisions() $literals = $rule->getLiterals(); $literal = $literals[0]; - if (!$this->decisions->decided(abs($literal))) { + if (!$this->decisions->decided($literal)) { $this->decisions->decide($literal, 1, $rule); continue; } @@ -226,6 +226,7 @@ public function solve(Request $request, $ignorePlatformReqs = false) $this->io->writeError('Resolving dependencies through SAT', true, IOInterface::DEBUG); $before = microtime(true); $this->runSat(true); + $this->io->writeError('', true, IOInterface::DEBUG); $this->io->writeError(sprintf('Dependency resolution completed in %.3f seconds', microtime(true) - $before), true, IOInterface::VERBOSE); // decide to remove everything that's installed and undecided @@ -509,9 +510,8 @@ protected function analyze($level, Rule $rule) */ private function analyzeUnsolvableRule(Problem $problem, Rule $conflictRule) { - $why = spl_object_hash($conflictRule); - if ($conflictRule->getType() == RuleSet::TYPE_LEARNED) { + $why = spl_object_hash($conflictRule); $learnedWhy = $this->learnedWhy[$why]; $problemRules = $this->learnedPool[$learnedWhy]; @@ -759,10 +759,19 @@ private function runSat($disableRules = true) } $rulesCount = count($this->rules); + $pass = 1; + $this->io->writeError('Looking at all rules.', true, IOInterface::DEBUG); for ($i = 0, $n = 0; $n < $rulesCount; $i++, $n++) { if ($i == $rulesCount) { + if (1 === $pass) { + $this->io->writeError("Something's changed, looking at all rules again (pass #$pass)", false, IOInterface::DEBUG); + } else { + $this->io->overwriteError("Something's changed, looking at all rules again (pass #$pass)", false, null, IOInterface::DEBUG); + } + $i = 0; + $pass++; } $rule = $this->rules->ruleById[$i]; @@ -782,14 +791,14 @@ private function runSat($disableRules = true) // foreach ($literals as $literal) { if ($literal <= 0) { - if (!$this->decisions->decidedInstall(abs($literal))) { + if (!$this->decisions->decidedInstall($literal)) { continue 2; // next rule } } else { - if ($this->decisions->decidedInstall(abs($literal))) { + if ($this->decisions->decidedInstall($literal)) { continue 2; // next rule } - if ($this->decisions->undecided(abs($literal))) { + if ($this->decisions->undecided($literal)) { $decisionQueue[] = $literal; } } diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/SolverBugException.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/SolverBugException.php index da44366e5..6920411f5 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/SolverBugException.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/SolverBugException.php @@ -21,6 +21,7 @@ public function __construct($message) { parent::__construct( $message."\nThis exception was most likely caused by a bug in Composer.\n". - "Please report the command you ran, the exact error you received, and your composer.json on https://github.com/composer/composer/issues - thank you!\n"); + "Please report the command you ran, the exact error you received, and your composer.json on https://github.com/composer/composer/issues - thank you!\n" + ); } } diff --git a/app/vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php b/app/vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php index 3674a1989..c8d3bbe53 100644 --- a/app/vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php +++ b/app/vendor/composer/composer/src/Composer/DependencyResolver/Transaction.php @@ -49,7 +49,7 @@ public function getOperations() $package = $this->pool->literalToPackage($literal); // wanted & installed || !wanted & !installed - if (($literal > 0) == (isset($this->installedMap[$package->id]))) { + if (($literal > 0) == isset($this->installedMap[$package->id])) { continue; } diff --git a/app/vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php b/app/vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php index 24256c81f..d041a7f88 100644 --- a/app/vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php +++ b/app/vendor/composer/composer/src/Composer/Downloader/ArchiveDownloader.php @@ -27,6 +27,8 @@ abstract class ArchiveDownloader extends FileDownloader { /** * {@inheritDoc} + * @throws \RuntimeException + * @throws \UnexpectedValueException */ public function download(PackageInterface $package, $path, $output = true) { @@ -35,7 +37,9 @@ public function download(PackageInterface $package, $path, $output = true) while ($retries--) { $fileName = parent::download($package, $path, $output); - $this->io->writeError(' Extracting archive', false, IOInterface::VERBOSE); + if ($output) { + $this->io->writeError(' Extracting archive', false, IOInterface::VERBOSE); + } try { $this->filesystem->ensureDirectoryExists($temporaryDir); diff --git a/app/vendor/composer/composer/src/Composer/Downloader/DownloadManager.php b/app/vendor/composer/composer/src/Composer/Downloader/DownloadManager.php index 0b1affc1d..15c00a6e6 100644 --- a/app/vendor/composer/composer/src/Composer/Downloader/DownloadManager.php +++ b/app/vendor/composer/composer/src/Composer/Downloader/DownloadManager.php @@ -161,7 +161,10 @@ public function getDownloaderForInstalledPackage(PackageInterface $package) if ($installationSource !== $downloader->getInstallationSource()) { throw new \LogicException(sprintf( 'Downloader "%s" is a %s type downloader and can not be used to download %s for package %s', - get_class($downloader), $downloader->getInstallationSource(), $installationSource, $package + get_class($downloader), + $downloader->getInstallationSource(), + $installationSource, + $package )); } diff --git a/app/vendor/composer/composer/src/Composer/Downloader/FileDownloader.php b/app/vendor/composer/composer/src/Composer/Downloader/FileDownloader.php index 0cc531704..6596d9c8b 100644 --- a/app/vendor/composer/composer/src/Composer/Downloader/FileDownloader.php +++ b/app/vendor/composer/composer/src/Composer/Downloader/FileDownloader.php @@ -16,7 +16,10 @@ use Composer\Cache; use Composer\Factory; use Composer\IO\IOInterface; +use Composer\IO\NullIO; +use Composer\Package\Comparer\Comparer; use Composer\Package\PackageInterface; +use Composer\Package\Version\VersionParser; use Composer\Plugin\PluginEvents; use Composer\Plugin\PreFileDownloadEvent; use Composer\EventDispatcher\EventDispatcher; @@ -32,7 +35,7 @@ * @author François Pluchino * @author Nils Adermann */ -class FileDownloader implements DownloaderInterface +class FileDownloader implements DownloaderInterface, ChangeReportInterface { protected $io; protected $config; @@ -134,8 +137,11 @@ protected function doDownload(PackageInterface $package, $path, $url) $checksum = $package->getDistSha1Checksum(); $cacheKey = $this->getCacheKey($package, $processedUrl); - // download if we don't have it in cache or the cache is invalidated - if (!$this->cache || ($checksum && $checksum !== $this->cache->sha1($cacheKey)) || !$this->cache->copyTo($cacheKey, $fileName)) { + // use from cache if it is present and has a valid checksum or we have no checksum to check against + if ($this->cache && (!$checksum || $checksum === $this->cache->sha1($cacheKey)) && $this->cache->copyTo($cacheKey, $fileName)) { + $this->io->writeError('Loading from cache', false); + } else { + // download if cache restore failed if (!$this->outputProgress) { $this->io->writeError('Downloading', false); } @@ -165,8 +171,6 @@ protected function doDownload(PackageInterface $package, $path, $url) $this->lastCacheWrites[$package->getName()] = $cacheKey; $this->cache->copyFrom($cacheKey, $fileName); } - } else { - $this->io->writeError('Loading from cache', false); } if (!file_exists($fileName)) { @@ -214,7 +218,8 @@ public function update(PackageInterface $initial, PackageInterface $target, $pat $from = $initial->getPrettyVersion(); $to = $target->getPrettyVersion(); - $this->io->writeError(" - Updating " . $name . " (" . $from . " => " . $to . "): ", false); + $actionName = VersionParser::isUpgrade($initial->getVersion(), $target->getVersion()) ? 'Updating' : 'Downgrading'; + $this->io->writeError(" - " . $actionName . " " . $name . " (" . $from . " => " . $to . "): ", false); $this->remove($initial, $path, false); $this->download($target, $path, false); @@ -278,4 +283,40 @@ private function getCacheKey(PackageInterface $package, $processedUrl) return $package->getName().'/'.$cacheKey.'.'.$package->getDistType(); } + + /** + * {@inheritDoc} + * @throws \RuntimeException + */ + public function getLocalChanges(PackageInterface $package, $targetDir) + { + $prevIO = $this->io; + $prevProgress = $this->outputProgress; + + $this->io = new NullIO; + $this->io->loadConfiguration($this->config); + $this->outputProgress = false; + $e = null; + + try { + $this->download($package, $targetDir.'_compare', false); + + $comparer = new Comparer(); + $comparer->setSource($targetDir.'_compare'); + $comparer->setUpdate($targetDir); + $comparer->doCompare(); + $output = $comparer->getChanged(true, true); + $this->filesystem->removeDirectory($targetDir.'_compare'); + } catch (\Exception $e) { + } + + $this->io = $prevIO; + $this->outputProgress = $prevProgress; + + if ($e) { + throw $e; + } + + return trim($output); + } } diff --git a/app/vendor/composer/composer/src/Composer/Downloader/HgDownloader.php b/app/vendor/composer/composer/src/Composer/Downloader/HgDownloader.php index 32074be71..2921cc4b7 100644 --- a/app/vendor/composer/composer/src/Composer/Downloader/HgDownloader.php +++ b/app/vendor/composer/composer/src/Composer/Downloader/HgDownloader.php @@ -14,6 +14,7 @@ use Composer\Package\PackageInterface; use Composer\Util\ProcessExecutor; +use Composer\Util\Hg as HgUtils; /** * @author Per Bernhardt @@ -25,16 +26,15 @@ class HgDownloader extends VcsDownloader */ public function doDownload(PackageInterface $package, $path, $url) { - // Ensure we are allowed to use this URL by config - $this->config->prohibitUrlByConfig($url, $this->io); + $hgUtils = new HgUtils($this->io, $this->config, $this->process); + + $cloneCommand = function ($url) use ($path) { + return sprintf('hg clone %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($path)); + }; + + $hgUtils->runCommand($cloneCommand, $url, $path); - $url = ProcessExecutor::escape($url); $ref = ProcessExecutor::escape($package->getSourceReference()); - $this->io->writeError("Cloning ".$package->getSourceReference()); - $command = sprintf('hg clone %s %s', $url, ProcessExecutor::escape($path)); - if (0 !== $this->process->execute($command, $ignoredOutput)) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); - } $command = sprintf('hg up %s', $ref); if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) { throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); @@ -46,21 +46,20 @@ public function doDownload(PackageInterface $package, $path, $url) */ public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url) { - // Ensure we are allowed to use this URL by config - $this->config->prohibitUrlByConfig($url, $this->io); + $hgUtils = new HgUtils($this->io, $this->config, $this->process); - $url = ProcessExecutor::escape($url); - $ref = ProcessExecutor::escape($target->getSourceReference()); + $ref = $target->getSourceReference(); $this->io->writeError(" Updating to ".$target->getSourceReference()); if (!$this->hasMetadataRepository($path)) { throw new \RuntimeException('The .hg directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information'); } - $command = sprintf('hg pull %s && hg up %s', $url, $ref); - if (0 !== $this->process->execute($command, $ignoredOutput, realpath($path))) { - throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput()); - } + $command = function ($url) use ($ref) { + return sprintf('hg pull %s && hg up %s', ProcessExecutor::escape($url), ProcessExecutor::escape($ref)); + }; + + $hgUtils->runCommand($command, $url, $path); } /** diff --git a/app/vendor/composer/composer/src/Composer/Downloader/PathDownloader.php b/app/vendor/composer/composer/src/Composer/Downloader/PathDownloader.php index 250a01c3f..e7084bd97 100644 --- a/app/vendor/composer/composer/src/Composer/Downloader/PathDownloader.php +++ b/app/vendor/composer/composer/src/Composer/Downloader/PathDownloader.php @@ -43,7 +43,9 @@ public function download(PackageInterface $package, $path, $output = true) $realUrl = realpath($url); if (false === $realUrl || !file_exists($realUrl) || !is_dir($realUrl)) { throw new \RuntimeException(sprintf( - 'Source path "%s" is not found for package %s', $url, $package->getName() + 'Source path "%s" is not found for package %s', + $url, + $package->getName() )); } @@ -54,7 +56,9 @@ public function download(PackageInterface $package, $path, $output = true) // for previous attempts that were shut down because they did not work well enough or introduced too many risks. throw new \RuntimeException(sprintf( 'Package %s cannot install to "%s" inside its source at "%s"', - $package->getName(), realpath($path), $realUrl + $package->getName(), + realpath($path), + $realUrl )); } @@ -146,7 +150,7 @@ public function remove(PackageInterface $package, $path, $output = true) $this->io->writeError(" - Removing junction for " . $package->getName() . " (" . $package->getFullPrettyVersion() . ")"); } if (!$this->filesystem->removeJunction($path)) { - $this->io->writeError(" Could not remove junction at " . $path . " - is another process locking it?"); + $this->io->writeError(" Could not remove junction at " . $path . " - is another process locking it?"); throw new \RuntimeException('Could not reliably remove junction for package ' . $package->getName()); } } else { diff --git a/app/vendor/composer/composer/src/Composer/Downloader/VcsDownloader.php b/app/vendor/composer/composer/src/Composer/Downloader/VcsDownloader.php index cdc63e5ec..aa666058e 100644 --- a/app/vendor/composer/composer/src/Composer/Downloader/VcsDownloader.php +++ b/app/vendor/composer/composer/src/Composer/Downloader/VcsDownloader.php @@ -130,7 +130,8 @@ public function update(PackageInterface $initial, PackageInterface $target, $pat $to = $target->getFullPrettyVersion(); } - $this->io->writeError(" - Updating " . $name . " (" . $from . " => " . $to . "): ", false); + $actionName = VersionParser::isUpgrade($initial->getVersion(), $target->getVersion()) ? 'Updating' : 'Downgrading'; + $this->io->writeError(" - " . $actionName . " " . $name . " (" . $from . " => " . $to . "): ", false); $this->cleanChanges($initial, $path, true); $urls = $target->getSourceUrls(); diff --git a/app/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php b/app/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php index 00f7fbd1b..5ca7a2dab 100644 --- a/app/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php +++ b/app/vendor/composer/composer/src/Composer/Downloader/ZipDownloader.php @@ -56,10 +56,6 @@ public function download(PackageInterface $package, $path, $output = true) self::$hasZipArchive = class_exists('ZipArchive'); } - if (null === self::$isWindows) { - self::$isWindows = Platform::isWindows(); - } - if (!self::$hasZipArchive && !self::$hasSystemUnzip) { // php.ini path is added to the error message to help users find the correct file $iniMessage = IniHelper::getMessage(); @@ -68,6 +64,15 @@ public function download(PackageInterface $package, $path, $output = true) throw new \RuntimeException($error); } + if (null === self::$isWindows) { + self::$isWindows = Platform::isWindows(); + + if (!self::$isWindows && !self::$hasSystemUnzip) { + $this->io->writeError("As there is no 'unzip' command installed zip files are being unpacked using the PHP zip extension."); + $this->io->writeError("This may cause invalid reports of corrupted archives. Installing 'unzip' may remediate them."); + } + } + return parent::download($package, $path, $output); } diff --git a/app/vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php b/app/vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php index 7f7a2cd86..145944b07 100644 --- a/app/vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php +++ b/app/vendor/composer/composer/src/Composer/EventDispatcher/EventDispatcher.php @@ -325,22 +325,37 @@ protected function checkListenerExpectedEvent($target, Event $event) if (!$event instanceof $expected && $expected === 'Composer\Script\CommandEvent') { trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED); $event = new \Composer\Script\CommandEvent( - $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), $event->getArguments() + $event->getName(), + $event->getComposer(), + $event->getIO(), + $event->isDevMode(), + $event->getArguments() ); } if (!$event instanceof $expected && $expected === 'Composer\Script\PackageEvent') { trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED); $event = new \Composer\Script\PackageEvent( - $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), - $event->getPolicy(), $event->getPool(), $event->getInstalledRepo(), $event->getRequest(), - $event->getOperations(), $event->getOperation() + $event->getName(), + $event->getComposer(), + $event->getIO(), + $event->isDevMode(), + $event->getPolicy(), + $event->getPool(), + $event->getInstalledRepo(), + $event->getRequest(), + $event->getOperations(), + $event->getOperation() ); } if (!$event instanceof $expected && $expected === 'Composer\Script\Event') { trigger_error('The callback '.$this->serializeCallback($target).' declared at '.$reflected->getDeclaringFunction()->getFileName().' accepts a '.$expected.' but '.$event->getName().' events use a '.get_class($event).' instance. Please adjust your type hint accordingly, see https://getcomposer.org/doc/articles/scripts.md#event-classes', E_USER_DEPRECATED); $event = new \Composer\Script\Event( - $event->getName(), $event->getComposer(), $event->getIO(), $event->isDevMode(), - $event->getArguments(), $event->getFlags() + $event->getName(), + $event->getComposer(), + $event->getIO(), + $event->isDevMode(), + $event->getArguments(), + $event->getFlags() ); } diff --git a/app/vendor/composer/composer/src/Composer/Factory.php b/app/vendor/composer/composer/src/Composer/Factory.php index a68586fbb..d0cf6ee8a 100644 --- a/app/vendor/composer/composer/src/Composer/Factory.php +++ b/app/vendor/composer/composer/src/Composer/Factory.php @@ -546,7 +546,7 @@ protected function createDefaultInstallers(Installer\InstallationManager $im, Co $im->addInstaller(new Installer\LibraryInstaller($io, $composer, null)); $im->addInstaller(new Installer\PearInstaller($io, $composer, 'pear-library')); $im->addInstaller(new Installer\PluginInstaller($io, $composer)); - $im->addInstaller(new Installer\MetapackageInstaller($io)); + $im->addInstaller(new Installer\MetapackageInstaller()); } /** diff --git a/app/vendor/composer/composer/src/Composer/IO/ConsoleIO.php b/app/vendor/composer/composer/src/Composer/IO/ConsoleIO.php index 55c80e29c..c0f235659 100644 --- a/app/vendor/composer/composer/src/Composer/IO/ConsoleIO.php +++ b/app/vendor/composer/composer/src/Composer/IO/ConsoleIO.php @@ -272,9 +272,12 @@ public function askAndValidate($question, $validator, $attempts = null, $default */ public function askAndHideAnswer($question) { - $this->writeError($question, false); + /** @var \Symfony\Component\Console\Helper\QuestionHelper $helper */ + $helper = $this->helperSet->get('question'); + $question = new Question($question); + $question->setHidden(true); - return \Seld\CliPrompt\CliPrompt::hiddenPrompt(true); + return $helper->ask($this->input, $this->getErrorOutput(), $question); } /** diff --git a/app/vendor/composer/composer/src/Composer/Installer.php b/app/vendor/composer/composer/src/Composer/Installer.php index c60b707d6..a729710c0 100644 --- a/app/vendor/composer/composer/src/Composer/Installer.php +++ b/app/vendor/composer/composer/src/Composer/Installer.php @@ -251,7 +251,7 @@ public function run() continue; } - $replacement = (is_string($package->getReplacementPackage())) + $replacement = is_string($package->getReplacementPackage()) ? 'Use ' . $package->getReplacementPackage() . ' instead' : 'No replacement was suggested'; @@ -521,15 +521,15 @@ protected function doInstall($localRepo, $installedRepo, $platformRepo, $aliases } } - $this->io->writeError( - sprintf("Package operations: %d install%s, %d update%s, %d removal%s", + $this->io->writeError(sprintf( + "Package operations: %d install%s, %d update%s, %d removal%s", count($installs), 1 === count($installs) ? '' : 's', count($updates), 1 === count($updates) ? '' : 's', count($uninstalls), - 1 === count($uninstalls) ? '' : 's') - ); + 1 === count($uninstalls) ? '' : 's' + )); if ($installs) { $this->io->writeError("Installs: ".implode(', ', $installs), true, IOInterface::VERBOSE); } @@ -543,16 +543,17 @@ protected function doInstall($localRepo, $installedRepo, $platformRepo, $aliases foreach ($operations as $operation) { // collect suggestions - if ('install' === $operation->getJobType()) { + $jobType = $operation->getJobType(); + if ('install' === $jobType) { $this->suggestedPackagesReporter->addSuggestionsFromPackage($operation->getPackage()); } // updating, force dev packages' references if they're in root package refs if ($this->update) { $package = null; - if ('update' === $operation->getJobType()) { + if ('update' === $jobType) { $package = $operation->getTargetPackage(); - } elseif ('install' === $operation->getJobType()) { + } elseif ('install' === $jobType) { $package = $operation->getPackage(); } if ($package && $package->isDev()) { @@ -561,20 +562,24 @@ protected function doInstall($localRepo, $installedRepo, $platformRepo, $aliases $this->updateInstallReferences($package, $references[$package->getName()]); } } - if ('update' === $operation->getJobType() - && $operation->getTargetPackage()->isDev() - && $operation->getTargetPackage()->getVersion() === $operation->getInitialPackage()->getVersion() - && (!$operation->getTargetPackage()->getSourceReference() || $operation->getTargetPackage()->getSourceReference() === $operation->getInitialPackage()->getSourceReference()) - && (!$operation->getTargetPackage()->getDistReference() || $operation->getTargetPackage()->getDistReference() === $operation->getInitialPackage()->getDistReference()) - ) { - $this->io->writeError(' - Skipping update of '. $operation->getTargetPackage()->getPrettyName().' to the same reference-locked version', true, IOInterface::DEBUG); - $this->io->writeError('', true, IOInterface::DEBUG); + if ('update' === $jobType) { + $targetPackage = $operation->getTargetPackage(); + if ($targetPackage->isDev()) { + $initialPackage = $operation->getInitialPackage(); + if ($targetPackage->getVersion() === $initialPackage->getVersion() + && (!$targetPackage->getSourceReference() || $targetPackage->getSourceReference() === $initialPackage->getSourceReference()) + && (!$targetPackage->getDistReference() || $targetPackage->getDistReference() === $initialPackage->getDistReference()) + ) { + $this->io->writeError(' - Skipping update of ' . $targetPackage->getPrettyName() . ' to the same reference-locked version', true, IOInterface::DEBUG); + $this->io->writeError('', true, IOInterface::DEBUG); - continue; + continue; + } + } } } - $event = 'Composer\Installer\PackageEvents::PRE_PACKAGE_'.strtoupper($operation->getJobType()); + $event = 'Composer\Installer\PackageEvents::PRE_PACKAGE_'.strtoupper($jobType); if (defined($event) && $this->runScripts) { $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation); } @@ -589,7 +594,7 @@ protected function doInstall($localRepo, $installedRepo, $platformRepo, $aliases $this->installationManager->execute($localRepo, $operation); // output reasons why the operation was ran, only for install/update operations - if ($this->verbose && $this->io->isVeryVerbose() && in_array($operation->getJobType(), array('install', 'update'))) { + if ($this->verbose && $this->io->isVeryVerbose() && in_array($jobType, array('install', 'update'))) { $reason = $operation->getReason(); if ($reason instanceof Rule) { switch ($reason->getReason()) { @@ -605,7 +610,7 @@ protected function doInstall($localRepo, $installedRepo, $platformRepo, $aliases } } - $event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($operation->getJobType()); + $event = 'Composer\Installer\PackageEvents::POST_PACKAGE_'.strtoupper($jobType); if (defined($event) && $this->runScripts) { $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $policy, $pool, $installedRepo, $request, $operations, $operation); } @@ -1033,11 +1038,14 @@ private function processDevPackages($localRepo, $pool, $policy, $repositories, $ $package->setReplaces($newPackage->getReplaces()); } - if ($task === 'force-updates' && $newPackage && ( - (($newPackage->getSourceReference() && $newPackage->getSourceReference() !== $package->getSourceReference()) + if ( + $task === 'force-updates' + && $newPackage + && ( + ($newPackage->getSourceReference() && $newPackage->getSourceReference() !== $package->getSourceReference()) || ($newPackage->getDistReference() && $newPackage->getDistReference() !== $package->getDistReference()) ) - )) { + ) { $operations[] = new UpdateOperation($package, $newPackage); continue; @@ -1741,7 +1749,7 @@ public function setWriteLock($writeLock = true) } /** - * Should the operations (packge install, update and removal) be executed on disk? + * Should the operations (package install, update and removal) be executed on disk? * * This is disabled implicitly when enabling dryRun * diff --git a/app/vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php b/app/vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php index a61ea86a1..0f709f60b 100644 --- a/app/vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php +++ b/app/vendor/composer/composer/src/Composer/Installer/BinaryInstaller.php @@ -113,7 +113,7 @@ public function removeBinaries(PackageInterface $package) } // attempt removing the bin dir in case it is left empty - if ((is_dir($this->binDir)) && ($this->filesystem->isDirEmpty($this->binDir))) { + if (is_dir($this->binDir) && $this->filesystem->isDirEmpty($this->binDir)) { Silencer::call('rmdir', $this->binDir); } } diff --git a/app/vendor/composer/composer/src/Composer/Installer/PluginInstaller.php b/app/vendor/composer/composer/src/Composer/Installer/PluginInstaller.php index e2ae07956..c400ca4a6 100644 --- a/app/vendor/composer/composer/src/Composer/Installer/PluginInstaller.php +++ b/app/vendor/composer/composer/src/Composer/Installer/PluginInstaller.php @@ -32,9 +32,8 @@ class PluginInstaller extends LibraryInstaller * * @param IOInterface $io * @param Composer $composer - * @param string $type */ - public function __construct(IOInterface $io, Composer $composer, $type = 'library') + public function __construct(IOInterface $io, Composer $composer) { parent::__construct($io, $composer, 'composer-plugin'); $this->installationManager = $composer->getInstallationManager(); diff --git a/app/vendor/composer/composer/src/Composer/Installer/SuggestedPackagesReporter.php b/app/vendor/composer/composer/src/Composer/Installer/SuggestedPackagesReporter.php index ed89ec02b..25788e547 100644 --- a/app/vendor/composer/composer/src/Composer/Installer/SuggestedPackagesReporter.php +++ b/app/vendor/composer/composer/src/Composer/Installer/SuggestedPackagesReporter.php @@ -115,10 +115,10 @@ public function output(RepositoryInterface $installedRepo = null) } $this->io->writeError(sprintf( - '%s suggests installing %s (%s)', + '%s suggests installing %s%s', $suggestion['source'], $this->escapeOutput($suggestion['target']), - $this->escapeOutput($suggestion['reason']) + $this->escapeOutput('' !== $suggestion['reason'] ? ' ('.$suggestion['reason'].')' : '') )); } diff --git a/app/vendor/composer/composer/src/Composer/Json/JsonFile.php b/app/vendor/composer/composer/src/Composer/Json/JsonFile.php index 0557847d6..b84791420 100644 --- a/app/vendor/composer/composer/src/Composer/Json/JsonFile.php +++ b/app/vendor/composer/composer/src/Composer/Json/JsonFile.php @@ -281,7 +281,6 @@ public static function parseJson($json, $file = null) * @param string $json * @param string $file * @throws \UnexpectedValueException - * @throws JsonValidationException * @throws ParsingException * @return bool true on success */ diff --git a/app/vendor/composer/composer/src/Composer/Json/JsonFormatter.php b/app/vendor/composer/composer/src/Composer/Json/JsonFormatter.php index 8e2005715..44acaff59 100644 --- a/app/vendor/composer/composer/src/Composer/Json/JsonFormatter.php +++ b/app/vendor/composer/composer/src/Composer/Json/JsonFormatter.php @@ -69,6 +69,13 @@ public static function format($json, $unescapeUnicode, $unescapeSlashes) $l = strlen($match[1]); if ($l % 2) { + $code = hexdec($match[2]); + // 0xD800..0xDFFF denotes UTF-16 surrogate pair which won't be unescaped + // see https://github.com/composer/composer/issues/7510 + if (0xD800 <= $code && 0xDFFF >= $code) { + return $match[0]; + } + return str_repeat('\\', $l - 1) . mb_convert_encoding( pack('H*', $match[2]), 'UTF-8', @@ -88,7 +95,7 @@ public static function format($json, $unescapeUnicode, $unescapeSlashes) if (':' === $char) { // Add a space after the : character $char .= ' '; - } elseif (('}' === $char || ']' === $char)) { + } elseif ('}' === $char || ']' === $char) { $pos--; $prevChar = substr($json, $i - 1, 1); diff --git a/app/vendor/composer/composer/src/Composer/Json/JsonManipulator.php b/app/vendor/composer/composer/src/Composer/Json/JsonManipulator.php index cdd22c817..40c0c09a2 100644 --- a/app/vendor/composer/composer/src/Composer/Json/JsonManipulator.php +++ b/app/vendor/composer/composer/src/Composer/Json/JsonManipulator.php @@ -171,6 +171,10 @@ public function addProperty($name, $value) return $this->addSubNode('extra', substr($name, 6), $value); } + if (substr($name, 0, 8) === 'scripts.') { + return $this->addSubNode('scripts', substr($name, 8), $value); + } + return $this->addMainKey($name, $value); } @@ -180,6 +184,10 @@ public function removeProperty($name) return $this->removeSubNode('extra', substr($name, 6)); } + if (substr($name, 0, 8) === 'scripts.') { + return $this->removeSubNode('scripts', substr($name, 8)); + } + return $this->removeMainKey($name); } @@ -188,7 +196,7 @@ public function addSubNode($mainNode, $name, $value) $decoded = JsonFile::parseJson($this->contents); $subName = null; - if (in_array($mainNode, array('config', 'extra')) && false !== strpos($name, '.')) { + if (in_array($mainNode, array('config', 'extra', 'scripts')) && false !== strpos($name, '.')) { list($name, $subName) = explode('.', $name, 2); } @@ -229,7 +237,7 @@ public function addSubNode($mainNode, $name, $value) // child exists $childRegex = '{'.self::$DEFINES.'(?P"'.preg_quote($name).'"\s*:\s*)(?P(?&json))(?P,?)}x'; if ($this->pregMatch($childRegex, $children, $matches)) { - $children = preg_replace_callback($childRegex, function ($matches) use ($name, $subName, $value, $that) { + $children = preg_replace_callback($childRegex, function ($matches) use ($subName, $value, $that) { if ($subName !== null) { $curVal = json_decode($matches['content'], true); if (!is_array($curVal)) { @@ -308,7 +316,7 @@ public function removeSubNode($mainNode, $name) } $subName = null; - if (in_array($mainNode, array('config', 'extra')) && false !== strpos($name, '.')) { + if (in_array($mainNode, array('config', 'extra', 'scripts')) && false !== strpos($name, '.')) { list($name, $subName) = explode('.', $name, 2); } @@ -502,8 +510,7 @@ protected function pregMatch($re, $str, &$matches = array()) if (PHP_VERSION_ID > 70000) { throw new \RuntimeException('Failed to execute regex: PREG_JIT_STACKLIMIT_ERROR', 6); } - // fallthrough - + // no break default: throw new \RuntimeException('Failed to execute regex: Unknown error'); } diff --git a/app/vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php b/app/vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php index 35a3d3467..22f8eeafe 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php +++ b/app/vendor/composer/composer/src/Composer/Package/Archiver/ArchiveManager.php @@ -75,9 +75,9 @@ public function getPackageFilename(PackageInterface $package) $nameParts = array(preg_replace('#[^a-z0-9-_]#i', '-', $package->getName())); if (preg_match('{^[a-f0-9]{40}$}', $package->getDistReference())) { - $nameParts = array_merge($nameParts, array($package->getDistReference(), $package->getDistType())); + array_push($nameParts, $package->getDistReference(), $package->getDistType()); } else { - $nameParts = array_merge($nameParts, array($package->getPrettyVersion(), $package->getDistReference())); + array_push($nameParts, $package->getPrettyVersion(), $package->getDistReference()); } if ($package->getSourceReference()) { diff --git a/app/vendor/composer/composer/src/Composer/Package/Archiver/BaseExcludeFilter.php b/app/vendor/composer/composer/src/Composer/Package/Archiver/BaseExcludeFilter.php index 99ba24431..18fa05404 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Archiver/BaseExcludeFilter.php +++ b/app/vendor/composer/composer/src/Composer/Package/Archiver/BaseExcludeFilter.php @@ -71,7 +71,7 @@ public function filter($relativePath, $exclude) * Processes a file containing exclude rules of different formats per line * * @param array $lines A set of lines to be parsed - * @param callback $lineParser The parser to be used on each line + * @param callable $lineParser The parser to be used on each line * * @return array Exclude patterns to be used in filter() */ diff --git a/app/vendor/composer/composer/src/Composer/Package/Archiver/GitExcludeFilter.php b/app/vendor/composer/composer/src/Composer/Package/Archiver/GitExcludeFilter.php index 894a45a84..0cdc98c81 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Archiver/GitExcludeFilter.php +++ b/app/vendor/composer/composer/src/Composer/Package/Archiver/GitExcludeFilter.php @@ -42,7 +42,8 @@ public function __construct($sourcePath) $this->parseLines( file($sourcePath.'/.gitattributes'), array($this, 'parseGitAttributesLine') - )); + ) + ); } } diff --git a/app/vendor/composer/composer/src/Composer/Package/Archiver/PharArchiver.php b/app/vendor/composer/composer/src/Composer/Package/Archiver/PharArchiver.php index cbab4ba23..f9a392353 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Archiver/PharArchiver.php +++ b/app/vendor/composer/composer/src/Composer/Package/Archiver/PharArchiver.php @@ -76,7 +76,8 @@ public function archive($sources, $target, $format, array $excludes = array(), $ return $target; } catch (\UnexpectedValueException $e) { - $message = sprintf("Could not create archive '%s' from '%s': %s", + $message = sprintf( + "Could not create archive '%s' from '%s': %s", $target, $sources, $e->getMessage() diff --git a/app/vendor/composer/composer/src/Composer/Package/Archiver/ZipArchiver.php b/app/vendor/composer/composer/src/Composer/Package/Archiver/ZipArchiver.php index aaa41aea3..d1d7573f3 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Archiver/ZipArchiver.php +++ b/app/vendor/composer/composer/src/Composer/Package/Archiver/ZipArchiver.php @@ -50,7 +50,8 @@ public function archive($sources, $target, $format, array $excludes = array(), $ return $target; } } - $message = sprintf("Could not create archive '%s' from '%s': %s", + $message = sprintf( + "Could not create archive '%s' from '%s': %s", $target, $sources, $zip->getStatusString() diff --git a/app/vendor/composer/composer/src/Composer/Package/Comparer/Comparer.php b/app/vendor/composer/composer/src/Composer/Package/Comparer/Comparer.php new file mode 100644 index 000000000..ed1931e82 --- /dev/null +++ b/app/vendor/composer/composer/src/Composer/Package/Comparer/Comparer.php @@ -0,0 +1,128 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Package\Comparer; + +/** + * class Comparer + * + * @author Hector Prats + */ +class Comparer +{ + private $source; + private $update; + private $changed; + + public function setSource($source) + { + $this->source = $source; + } + + public function setUpdate($update) + { + $this->update = $update; + } + + public function getChanged($toString = false, $explicated = false) + { + $changed = $this->changed; + if (!count($changed)) { + return false; + } + if ($explicated) { + foreach ($changed as $sectionKey => $itemSection) { + foreach ($itemSection as $itemKey => $item) { + $changed[$sectionKey][$itemKey] = $item.' ('.$sectionKey.')'; + } + } + } + + if ($toString) { + foreach ($changed as $sectionKey => $itemSection) { + foreach ($itemSection as $itemKey => $item) { + $changed['string'][] = $item."\r\n"; + } + } + $changed = implode("\r\n", $changed['string']); + } + + return $changed; + } + + public function doCompare() + { + $source = array(); + $destination = array(); + $this->changed = array(); + $currentDirectory = getcwd(); + chdir($this->source); + $source = $this->doTree('.', $source); + if (!is_array($source)) { + return; + } + chdir($this->update); + $destination = $this->doTree('.', $destination); + if (!is_array($destination)) { + exit; + } + chdir($currentDirectory); + foreach ($source as $dir => $value) { + foreach ($value as $file => $hash) { + if (isset($destination[$dir][$file])) { + if ($hash !== $destination[$dir][$file]) { + $this->changed['changed'][] = $dir.'/'.$file; + } + } else { + $this->changed['removed'][] = $dir.'/'.$file; + } + } + } + foreach ($destination as $dir => $value) { + foreach ($value as $file => $hash) { + if (!isset($source[$dir][$file])) { + $this->changed['added'][] = $dir.'/'.$file; + } + } + } + } + + private function doTree($dir, &$array) + { + if ($dh = opendir($dir)) { + while ($file = readdir($dh)) { + if ($file !== '.' && $file !== '..') { + if (is_dir($dir.'/'.$file)) { + if (!count($array)) { + $array[0] = 'Temp'; + } + if (!$this->doTree($dir.'/'.$file, $array)) { + return false; + } + } else { + if (filesize($dir.'/'.$file)) { + set_time_limit(30); + $array[$dir][$file] = md5_file($dir.'/'.$file); + } + } + } + } + if (count($array) > 1 && isset($array['0'])) { + unset($array['0']); + } + + return $array; + } + + return false; + } +} diff --git a/app/vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php b/app/vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php index 6593143d5..ab8b4d45b 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php +++ b/app/vendor/composer/composer/src/Composer/Package/Dumper/ArrayDumper.php @@ -45,7 +45,7 @@ public function dump(PackageInterface $package) $data['target-dir'] = $package->getTargetDir(); } - if ($package->getSourceType()) { + if ($package->getSourceType() && $package->getType() !== 'metapackage') { $data['source']['type'] = $package->getSourceType(); $data['source']['url'] = $package->getSourceUrl(); $data['source']['reference'] = $package->getSourceReference(); @@ -54,7 +54,7 @@ public function dump(PackageInterface $package) } } - if ($package->getDistType()) { + if ($package->getDistType() && $package->getType() !== 'metapackage') { $data['dist']['type'] = $package->getDistType(); $data['dist']['url'] = $package->getDistUrl(); $data['dist']['reference'] = $package->getDistReference(); diff --git a/app/vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php b/app/vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php index 04b44f7b6..f917eb838 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php +++ b/app/vendor/composer/composer/src/Composer/Package/Loader/RootPackageLoader.php @@ -230,7 +230,7 @@ private function extractReferences(array $requires, array $references) { foreach ($requires as $reqName => $reqVersion) { $reqVersion = preg_replace('{^([^,\s@]+) as .+$}', '$1', $reqVersion); - if (preg_match('{^[^,\s@]+?#([a-f0-9]+)$}', $reqVersion, $match) && 'dev' === ($stabilityName = VersionParser::parseStability($reqVersion))) { + if (preg_match('{^[^,\s@]+?#([a-f0-9]+)$}', $reqVersion, $match) && 'dev' === VersionParser::parseStability($reqVersion)) { $name = strtolower($reqName); $references[$name] = $match[1]; } diff --git a/app/vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php b/app/vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php index fb2eafd93..2a71be6cb 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php +++ b/app/vendor/composer/composer/src/Composer/Package/Loader/ValidatingArrayLoader.php @@ -12,7 +12,6 @@ namespace Composer\Package\Loader; -use Composer\Package; use Composer\Package\BasePackage; use Composer\Semver\Constraint\Constraint; use Composer\Package\Version\VersionParser; diff --git a/app/vendor/composer/composer/src/Composer/Package/Locker.php b/app/vendor/composer/composer/src/Composer/Package/Locker.php index 7fbe536f2..57ec74233 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Locker.php +++ b/app/vendor/composer/composer/src/Composer/Package/Locker.php @@ -360,7 +360,8 @@ private function lockPackages(array $packages) if (!$name || !$version) { throw new \LogicException(sprintf( - 'Package "%s" has no version or name and can not be locked', $package + 'Package "%s" has no version or name and can not be locked', + $package )); } diff --git a/app/vendor/composer/composer/src/Composer/Package/Version/VersionParser.php b/app/vendor/composer/composer/src/Composer/Package/Version/VersionParser.php index 22b6dad50..831c61d5f 100644 --- a/app/vendor/composer/composer/src/Composer/Package/Version/VersionParser.php +++ b/app/vendor/composer/composer/src/Composer/Package/Version/VersionParser.php @@ -14,6 +14,7 @@ use Composer\Repository\PlatformRepository; use Composer\Semver\VersionParser as SemverVersionParser; +use Composer\Semver\Semver; class VersionParser extends SemverVersionParser { @@ -63,4 +64,18 @@ public function parseNameVersionPairs(array $pairs) return $result; } + + /** + * @return bool + */ + public static function isUpgrade($normalizedFrom, $normalizedTo) + { + if (substr($normalizedFrom, 0, 4) === 'dev-' || substr($normalizedTo, 0, 4) === 'dev-') { + return true; + } + + $sorted = Semver::sort(array($normalizedTo, $normalizedFrom)); + + return $sorted[0] === $normalizedFrom; + } } diff --git a/app/vendor/composer/composer/src/Composer/Plugin/PluginEvents.php b/app/vendor/composer/composer/src/Composer/Plugin/PluginEvents.php index 0304ebb9a..1fb368baf 100644 --- a/app/vendor/composer/composer/src/Composer/Plugin/PluginEvents.php +++ b/app/vendor/composer/composer/src/Composer/Plugin/PluginEvents.php @@ -48,4 +48,14 @@ class PluginEvents * @var string */ const PRE_FILE_DOWNLOAD = 'pre-file-download'; + + /** + * The PRE_COMMAND_RUN event occurs before a command is executed and lets you modify the input arguments/options + * + * The event listener method receives a + * Composer\Plugin\PreCommandRunEvent instance. + * + * @var string + */ + const PRE_COMMAND_RUN = 'pre-command-run'; } diff --git a/app/vendor/composer/composer/src/Composer/Plugin/PluginManager.php b/app/vendor/composer/composer/src/Composer/Plugin/PluginManager.php index 9cae9ee5d..e8f4b58c3 100644 --- a/app/vendor/composer/composer/src/Composer/Plugin/PluginManager.php +++ b/app/vendor/composer/composer/src/Composer/Plugin/PluginManager.php @@ -169,7 +169,7 @@ public function registerPackage(PackageInterface $package, $failOnMissingClasses $generator = $this->composer->getAutoloadGenerator(); $autoloads = array(); foreach ($autoloadPackages as $autoloadPackage) { - $downloadPath = $this->getInstallPath($autoloadPackage, ($globalRepo && $globalRepo->hasPackage($autoloadPackage))); + $downloadPath = $this->getInstallPath($autoloadPackage, $globalRepo && $globalRepo->hasPackage($autoloadPackage)); $autoloads[] = array($autoloadPackage, $downloadPath); } @@ -307,7 +307,7 @@ private function lookupInstalledPackage(Pool $pool, Link $link) { $packages = $pool->whatProvides($link->getTarget(), $link->getConstraint()); - return (!empty($packages)) ? $packages[0] : null; + return !empty($packages) ? $packages[0] : null; } /** diff --git a/app/vendor/composer/composer/src/Composer/Plugin/PreCommandRunEvent.php b/app/vendor/composer/composer/src/Composer/Plugin/PreCommandRunEvent.php new file mode 100644 index 000000000..60ad05b4a --- /dev/null +++ b/app/vendor/composer/composer/src/Composer/Plugin/PreCommandRunEvent.php @@ -0,0 +1,68 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Plugin; + +use Composer\EventDispatcher\Event; +use Symfony\Component\Console\Input\InputInterface; + +/** + * The pre command run event. + * + * @author Jordi Boggiano + */ +class PreCommandRunEvent extends Event +{ + /** + * @var InputInterface + */ + private $input; + + /** + * @var string + */ + private $command; + + /** + * Constructor. + * + * @param string $name The event name + * @param InputInterface $input + * @param string $command The command about to be executed + */ + public function __construct($name, InputInterface $input, $command) + { + parent::__construct($name); + $this->input = $input; + $this->command = $command; + } + + /** + * Returns the console input + * + * @return InputInterface + */ + public function getInput() + { + return $this->input; + } + + /** + * Returns the command about to be executed + * + * @return string + */ + public function getCommand() + { + return $this->command; + } +} diff --git a/app/vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php b/app/vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php index a8002123a..2383b2dd3 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php +++ b/app/vendor/composer/composer/src/Composer/Repository/ArtifactRepository.php @@ -129,15 +129,20 @@ private function getComposerInformation(\SplFileInfo $file) $zip->open($file->getPathname()); if (0 == $zip->numFiles) { + $zip->close(); + return false; } $foundFileIndex = $this->locateFile($zip, 'composer.json'); if (false === $foundFileIndex) { + $zip->close(); + return false; } $configurationFileName = $zip->getNameIndex($foundFileIndex); + $zip->close(); $composerFile = "zip://{$file->getPathname()}#$configurationFileName"; $json = file_get_contents($composerFile); diff --git a/app/vendor/composer/composer/src/Composer/Repository/ComposerRepository.php b/app/vendor/composer/composer/src/Composer/Repository/ComposerRepository.php index 60ab0dfbd..8a5da2b23 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/ComposerRepository.php +++ b/app/vendor/composer/composer/src/Composer/Repository/ComposerRepository.php @@ -90,6 +90,12 @@ public function __construct(array $repoConfig, IOInterface $io, Config $config, $this->config = $config; $this->options = $repoConfig['options']; $this->url = $repoConfig['url']; + + // force url for packagist.org to repo.packagist.org + if (preg_match('{^(?Phttps?)://packagist\.org/?$}i', $this->url, $match)) { + $this->url = $match['proto'].'://repo.packagist.org'; + } + $this->baseUrl = rtrim(preg_replace('{(?:/[^/\\\\]+\.json)?(?:[?#].*)?$}', '', $this->url), '/'); $this->io = $io; $this->cache = new Cache($io, $config->get('cache-repo-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $this->url), 'a-z0-9.$'); @@ -201,9 +207,21 @@ public function search($query, $mode = 0, $type = null) $hostname = parse_url($url, PHP_URL_HOST) ?: $url; $json = $this->rfs->getContents($hostname, $url, false); - $results = JsonFile::parseJson($json, $url); + $search = JsonFile::parseJson($json, $url); + + if (empty($search['results'])) { + return array(); + } - return $results['results']; + $results = array(); + foreach ($search['results'] as $result) { + // do not show virtual packages in results as they are not directly useful from a composer perspective + if (empty($result['virtual'])) { + $results[] = $result; + } + } + + return $results; } if ($this->hasProviders()) { @@ -527,10 +545,10 @@ protected function loadRootServerFile() } // force values for packagist - if (preg_match('{^https?://packagist.org/?$}i', $this->url) && !empty($this->repoConfig['force-lazy-providers'])) { - $this->url = 'https://packagist.org'; - $this->baseUrl = 'https://packagist.org'; - $this->lazyProvidersUrl = $this->canonicalizeUrl('https://packagist.org/p/%package%.json'); + if (preg_match('{^https?://repo\.packagist\.org/?$}i', $this->url) && !empty($this->repoConfig['force-lazy-providers'])) { + $this->url = 'https://repo.packagist.org'; + $this->baseUrl = 'https://repo.packagist.org'; + $this->lazyProvidersUrl = $this->canonicalizeUrl('https://repo.packagist.org/p/%package%.json'); $this->providersUrl = null; } elseif (!empty($this->repoConfig['force-lazy-providers'])) { $this->lazyProvidersUrl = $this->canonicalizeUrl('/p/%package%.json'); diff --git a/app/vendor/composer/composer/src/Composer/Repository/PathRepository.php b/app/vendor/composer/composer/src/Composer/Repository/PathRepository.php index ee5d702fa..61ebc8d8c 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/PathRepository.php +++ b/app/vendor/composer/composer/src/Composer/Repository/PathRepository.php @@ -174,9 +174,17 @@ protected function initialize() */ private function getUrlMatches() { + $flags = GLOB_MARK | GLOB_ONLYDIR; + + if (defined('GLOB_BRACE')) { + $flags |= GLOB_BRACE; + } elseif (strpos($this->url, '{') !== false || strpos($this->url, '}') !== false) { + throw new \RuntimeException('The operating system does not support GLOB_BRACE which is required for the url '. $this->url); + } + // Ensure environment-specific path separators are normalized to URL separators return array_map(function ($val) { return rtrim(str_replace(DIRECTORY_SEPARATOR, '/', $val), '/'); - }, glob($this->url, GLOB_MARK | GLOB_ONLYDIR)); + }, glob($this->url, $flags)); } } diff --git a/app/vendor/composer/composer/src/Composer/Repository/PlatformRepository.php b/app/vendor/composer/composer/src/Composer/Repository/PlatformRepository.php index da5c9ab73..02d552424 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/PlatformRepository.php +++ b/app/vendor/composer/composer/src/Composer/Repository/PlatformRepository.php @@ -12,12 +12,12 @@ namespace Composer\Repository; -use Composer\XdebugHandler; use Composer\Package\CompletePackage; use Composer\Package\PackageInterface; use Composer\Package\Version\VersionParser; use Composer\Plugin\PluginInterface; use Composer\Util\Silencer; +use Composer\XdebugHandler\XdebugHandler; /** * @author Jordi Boggiano @@ -120,7 +120,7 @@ protected function initialize() } // Check for xdebug in a restarted process - if (!in_array('xdebug', $loadedExtensions, true) && ($prettyVersion = strval(getenv(XdebugHandler::ENV_VERSION)))) { + if (!in_array('xdebug', $loadedExtensions, true) && ($prettyVersion = XdebugHandler::getSkippedVersion())) { $this->addExtension('xdebug', $prettyVersion); } diff --git a/app/vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php b/app/vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php index 4e8e478f4..9a2aaf3b5 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php +++ b/app/vendor/composer/composer/src/Composer/Repository/RepositoryInterface.php @@ -68,7 +68,7 @@ public function getPackages(); * @param string $query search query * @param int $mode a set of SEARCH_* constants to search on, implementations should do a best effort only * - * @return \array[] an array of array('name' => '...', 'description' => '...') + * @return array[] an array of array('name' => '...', 'description' => '...') */ public function search($query, $mode = 0); } diff --git a/app/vendor/composer/composer/src/Composer/Repository/RepositoryManager.php b/app/vendor/composer/composer/src/Composer/Repository/RepositoryManager.php index 7a7fc0a9b..87b82d14d 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/RepositoryManager.php +++ b/app/vendor/composer/composer/src/Composer/Repository/RepositoryManager.php @@ -54,6 +54,7 @@ public function __construct(IOInterface $io, Config $config, EventDispatcher $ev public function findPackage($name, $constraint) { foreach ($this->repositories as $repository) { + /** @var RepositoryInterface $repository */ if ($package = $repository->findPackage($name, $constraint)) { return $package; } @@ -68,13 +69,13 @@ public function findPackage($name, $constraint) * @param string $name package name * @param string|\Composer\Semver\Constraint\ConstraintInterface $constraint package version or version constraint to match against * - * @return array + * @return PackageInterface[] */ public function findPackages($name, $constraint) { $packages = array(); - foreach ($this->repositories as $repository) { + foreach ($this->getRepositories() as $repository) { $packages = array_merge($packages, $repository->findPackages($name, $constraint)); } @@ -147,7 +148,7 @@ public function setRepositoryClass($type, $class) /** * Returns all repositories, except local one. * - * @return array + * @return RepositoryInterface[] */ public function getRepositories() { diff --git a/app/vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php b/app/vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php index 5c5c08cf2..e150ccd10 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php +++ b/app/vendor/composer/composer/src/Composer/Repository/Vcs/GitHubDriver.php @@ -378,12 +378,7 @@ protected function getContents($url, $fetchingRepoData = false) return $this->attemptCloneFallback(); } - $rateLimited = false; - foreach ($e->getHeaders() as $header) { - if (preg_match('{^X-RateLimit-Remaining: *0$}i', trim($header))) { - $rateLimited = true; - } - } + $rateLimited = $githubUtil->isRateLimited($e->getHeaders()); if (!$this->io->hasAuthentication($this->originUrl)) { if (!$this->io->isInteractive()) { @@ -397,7 +392,7 @@ protected function getContents($url, $fetchingRepoData = false) } if ($rateLimited) { - $rateLimit = $this->getRateLimit($e->getHeaders()); + $rateLimit = $githubUtil->getRateLimit($e->getHeaders()); $this->io->writeError(sprintf( 'GitHub API limit (%d calls/hr) is exhausted. You are already authorized so you have to wait until %s before doing more requests', $rateLimit['limit'], @@ -413,39 +408,6 @@ protected function getContents($url, $fetchingRepoData = false) } } - /** - * Extract ratelimit from response. - * - * @param array $headers Headers from Composer\Downloader\TransportException. - * - * @return array Associative array with the keys limit and reset. - */ - protected function getRateLimit(array $headers) - { - $rateLimit = array( - 'limit' => '?', - 'reset' => '?', - ); - - foreach ($headers as $header) { - $header = trim($header); - if (false === strpos($header, 'X-RateLimit-')) { - continue; - } - list($type, $value) = explode(':', $header, 2); - switch ($type) { - case 'X-RateLimit-Limit': - $rateLimit['limit'] = (int) trim($value); - break; - case 'X-RateLimit-Reset': - $rateLimit['reset'] = date('Y-m-d H:i:s', (int) trim($value)); - break; - } - } - - return $rateLimit; - } - /** * Fetch root identifier from GitHub * diff --git a/app/vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php b/app/vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php index dcaf646ec..2044ff702 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php +++ b/app/vendor/composer/composer/src/Composer/Repository/Vcs/GitLabDriver.php @@ -129,7 +129,7 @@ public function getFileContent($file, $identifier) return $this->gitDriver->getFileContent($file, $identifier); } - // Convert the root identifier to a cachable commit id + // Convert the root identifier to a cacheable commit id if (!preg_match('{[a-f0-9]{40}}i', $identifier)) { $branches = $this->getBranches(); if (isset($branches[$identifier])) { diff --git a/app/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php b/app/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php index bf7c91552..2db995e2e 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php +++ b/app/vendor/composer/composer/src/Composer/Repository/Vcs/HgDriver.php @@ -13,6 +13,7 @@ namespace Composer\Repository\Vcs; use Composer\Config; +use Composer\Util\Hg as HgUtils; use Composer\Util\ProcessExecutor; use Composer\Util\Filesystem; use Composer\IO\IOInterface; @@ -49,6 +50,8 @@ public function initialize() // Ensure we are allowed to use this URL by config $this->config->prohibitUrlByConfig($this->url, $this->io); + $hgUtils = new HgUtils($this->io, $this->config, $this->process); + // update the repo if it is a valid hg repository if (is_dir($this->repoDir) && 0 === $this->process->execute('hg summary', $output, $this->repoDir)) { if (0 !== $this->process->execute('hg pull', $output, $this->repoDir)) { @@ -58,15 +61,11 @@ public function initialize() // clean up directory and do a fresh clone into it $fs->removeDirectory($this->repoDir); - if (0 !== $this->process->execute(sprintf('hg clone --noupdate %s %s', ProcessExecutor::escape($this->url), ProcessExecutor::escape($this->repoDir)), $output, $cacheDir)) { - $output = $this->process->getErrorOutput(); - - if (0 !== $this->process->execute('hg --version', $ignoredOutput)) { - throw new \RuntimeException('Failed to clone '.$this->url.', hg was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput()); - } + $command = function ($url) { + return sprintf('hg clone --noupdate %s %s', ProcessExecutor::escape($url), ProcessExecutor::escape($this->repoDir)); + }; - throw new \RuntimeException('Failed to clone '.$this->url.', could not read packages from it' . "\n\n" .$output); - } + $hgUtils->runCommand($command, $this->url, $this->repoDir); } } diff --git a/app/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php b/app/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php index 822510601..96434517a 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php +++ b/app/vendor/composer/composer/src/Composer/Repository/Vcs/SvnDriver.php @@ -135,7 +135,7 @@ public function getComposerInformation($identifier) try { $composer = $this->getBaseComposerInformation($identifier); - } catch(TransportException $e) { + } catch (TransportException $e) { $message = $e->getMessage(); if (stripos($message, 'path not found') === false && stripos($message, 'svn: warning: W160013') === false) { throw $e; diff --git a/app/vendor/composer/composer/src/Composer/Repository/VcsRepository.php b/app/vendor/composer/composer/src/Composer/Repository/VcsRepository.php index a1771c554..57639cdea 100644 --- a/app/vendor/composer/composer/src/Composer/Repository/VcsRepository.php +++ b/app/vendor/composer/composer/src/Composer/Repository/VcsRepository.php @@ -188,6 +188,13 @@ protected function initialize() continue; } + if ($existingPackage = $this->findPackage($data['name'], $data['version_normalized'])) { + if ($verbose) { + $this->io->writeError('Skipped tag '.$tag.', it conflicts with an another tag ('.$existingPackage->getPrettyVersion().') as both resolve to '.$data['version_normalized'].' internally'); + } + continue; + } + if ($verbose) { $this->io->writeError('Importing tag '.$tag.' ('.$data['version_normalized'].')'); } @@ -205,7 +212,8 @@ protected function initialize() $this->io->overwriteError('', false); } - foreach ($driver->getBranches() as $branch => $identifier) { + $branches = $driver->getBranches(); + foreach ($branches as $branch => $identifier) { $msg = 'Reading composer.json of ' . ($this->packageName ?: $this->url) . ' (' . $branch . ')'; if ($verbose) { $this->io->writeError($msg); @@ -213,6 +221,13 @@ protected function initialize() $this->io->overwriteError($msg, false); } + if ($branch === 'trunk' && isset($branches['master'])) { + if ($verbose) { + $this->io->writeError('Skipped branch '.$branch.', can not parse both master and trunk branches as they both resolve to 9999999-dev internally'); + } + continue; + } + if (!$parsedBranch = $this->validateBranch($branch)) { if ($verbose) { $this->io->writeError('Skipped branch '.$branch.', invalid name'); diff --git a/app/vendor/composer/composer/src/Composer/Util/ConfigValidator.php b/app/vendor/composer/composer/src/Composer/Util/ConfigValidator.php index c5f762f92..e1200fee1 100644 --- a/app/vendor/composer/composer/src/Composer/Util/ConfigValidator.php +++ b/app/vendor/composer/composer/src/Composer/Util/ConfigValidator.php @@ -151,6 +151,18 @@ public function validate($file, $arrayLoaderValidationFlags = ValidatingArrayLoa } } + // report scripts-descriptions for non-existent scripts + $scriptsDescriptions = isset($manifest['scripts-descriptions']) ? $manifest['scripts-descriptions'] : array(); + $scripts = isset($manifest['scripts']) ? $manifest['scripts'] : array(); + foreach ($scriptsDescriptions as $scriptName => $scriptDescription) { + if (!array_key_exists($scriptName, $scripts)) { + $warnings[] = sprintf( + 'Description for non-existent script "%s" found in "scripts-descriptions"', + $scriptName + ); + } + } + // check for empty psr-0/psr-4 namespace prefixes if (isset($manifest['autoload']['psr-0'][''])) { $warnings[] = "Defining autoload.psr-0 with an empty namespace prefix is a bad idea for performance"; diff --git a/app/vendor/composer/composer/src/Composer/Util/Filesystem.php b/app/vendor/composer/composer/src/Composer/Util/Filesystem.php index 2daa1ceb1..04df84ecd 100644 --- a/app/vendor/composer/composer/src/Composer/Util/Filesystem.php +++ b/app/vendor/composer/composer/src/Composer/Util/Filesystem.php @@ -565,7 +565,7 @@ public function relativeSymlink($target, $link) chdir($cwd); - return (bool) $result; + return $result; } /** @@ -634,9 +634,11 @@ public function junction($target, $junction) if (!is_dir($target)) { throw new IOException(sprintf('Cannot junction to "%s" as it is not a directory.', $target), 0, null, $target); } - $cmd = sprintf('mklink /J %s %s', - ProcessExecutor::escape(str_replace('/', DIRECTORY_SEPARATOR, $junction)), - ProcessExecutor::escape(realpath($target))); + $cmd = sprintf( + 'mklink /J %s %s', + ProcessExecutor::escape(str_replace('/', DIRECTORY_SEPARATOR, $junction)), + ProcessExecutor::escape(realpath($target)) + ); if ($this->getProcess()->execute($cmd, $output) !== 0) { throw new IOException(sprintf('Failed to create junction to "%s" at "%s".', $target, $junction), 0, null, $target); } diff --git a/app/vendor/composer/composer/src/Composer/Util/Git.php b/app/vendor/composer/composer/src/Composer/Util/Git.php index e4d6bd803..37410eecd 100644 --- a/app/vendor/composer/composer/src/Composer/Util/Git.php +++ b/app/vendor/composer/composer/src/Composer/Util/Git.php @@ -57,7 +57,7 @@ public function runCommand($commandCallable, $url, $cwd, $initialClone = false) // capture username/password from URL if there is one $this->process->execute('git remote -v', $output, $cwd); if (preg_match('{^(?:composer|origin)\s+https?://(.+):(.+)@([^/]+)}im', $output, $match)) { - $this->io->setAuthentication($match[3], urldecode($match[1]), urldecode($match[2])); + $this->io->setAuthentication($match[3], rawurldecode($match[1]), rawurldecode($match[2])); } } @@ -245,7 +245,7 @@ public function fetchRefOrSyncMirror($url, $dir, $ref) private function isAuthenticationFailure($url, &$match) { - if (!preg_match('{(https?://)([^/]+)(.*)$}i', $url, $match)) { + if (!preg_match('{^(https?://)([^/]+)(.*)$}i', $url, $match)) { return false; } @@ -254,10 +254,12 @@ private function isAuthenticationFailure($url, &$match) 'remote error: Invalid username or password.', 'error: 401 Unauthorized', 'fatal: unable to access', + 'fatal: could not read Username', ); + $errorOutput = $this->process->getErrorOutput(); foreach ($authFailures as $authFailure) { - if (strpos($this->process->getErrorOutput(), $authFailure) !== false) { + if (strpos($errorOutput, $authFailure) !== false) { return true; } } diff --git a/app/vendor/composer/composer/src/Composer/Util/GitHub.php b/app/vendor/composer/composer/src/Composer/Util/GitHub.php index 8415c9a5c..2f5dbe5cd 100644 --- a/app/vendor/composer/composer/src/Composer/Util/GitHub.php +++ b/app/vendor/composer/composer/src/Composer/Util/GitHub.php @@ -126,4 +126,55 @@ public function authorizeOAuthInteractively($originUrl, $message = null) return true; } + + /** + * Extract ratelimit from response. + * + * @param array $headers Headers from Composer\Downloader\TransportException. + * + * @return array Associative array with the keys limit and reset. + */ + public function getRateLimit(array $headers) + { + $rateLimit = array( + 'limit' => '?', + 'reset' => '?', + ); + + foreach ($headers as $header) { + $header = trim($header); + if (false === strpos($header, 'X-RateLimit-')) { + continue; + } + list($type, $value) = explode(':', $header, 2); + switch ($type) { + case 'X-RateLimit-Limit': + $rateLimit['limit'] = (int) trim($value); + break; + case 'X-RateLimit-Reset': + $rateLimit['reset'] = date('Y-m-d H:i:s', (int) trim($value)); + break; + } + } + + return $rateLimit; + } + + /** + * Finds whether a request failed due to rate limiting + * + * @param array $headers Headers from Composer\Downloader\TransportException. + * + * @return bool + */ + public function isRateLimited(array $headers) + { + foreach ($headers as $header) { + if (preg_match('{^X-RateLimit-Remaining: *0$}i', trim($header))) { + return true; + } + } + + return false; + } } diff --git a/app/vendor/composer/composer/src/Composer/Util/Hg.php b/app/vendor/composer/composer/src/Composer/Util/Hg.php new file mode 100644 index 000000000..8cf6241a6 --- /dev/null +++ b/app/vendor/composer/composer/src/Composer/Util/Hg.php @@ -0,0 +1,94 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Util; + +use Composer\Config; +use Composer\IO\IOInterface; + +/** + * @author Jonas Renaudot + */ +class Hg +{ + /** + * @var \Composer\IO\IOInterface + */ + private $io; + + /** + * @var \Composer\Config + */ + private $config; + + /** + * @var \Composer\Util\ProcessExecutor + */ + private $process; + + public function __construct(IOInterface $io, Config $config, ProcessExecutor $process) + { + $this->io = $io; + $this->config = $config; + $this->process = $process; + } + + public function runCommand($commandCallable, $url, $cwd) + { + $this->config->prohibitUrlByConfig($url, $this->io); + + // Try as is + $command = call_user_func($commandCallable, $url); + + if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) { + return; + } + + // Try with the authentication informations available + if (preg_match('{^(https?)://((.+)(?:\:(.+))?@)?([^/]+)(/.*)?}mi', $url, $match) && $this->io->hasAuthentication($match[5])) { + $auth = $this->io->getAuthentication($match[5]); + $authenticatedUrl = $match[1] . '://' . rawurlencode($auth['username']) . ':' . rawurlencode($auth['password']) . '@' . $match[5] . (!empty($match[6]) ? $match[6] : null); + + $command = call_user_func($commandCallable, $authenticatedUrl); + + if (0 === $this->process->execute($command, $ignoredOutput, $cwd)) { + return; + } + + $error = $this->process->getErrorOutput(); + } else { + $error = 'The given URL (' . $url . ') does not match the required format (http(s)://(username:password@)example.com/path-to-repository)'; + } + + $this->throwException('Failed to clone ' . $url . ', ' . "\n\n" . $error, $url); + } + + public static function sanitizeUrl($message) + { + return preg_replace_callback('{://(?P[^@]+?):(?P.+?)@}', function ($m) { + if (preg_match('{^[a-f0-9]{12,}$}', $m[1])) { + return '://***:***@'; + } + + return '://' . $m[1] . ':***@'; + }, $message); + } + + private function throwException($message, $url) + { + if (0 !== $this->process->execute('hg --version', $ignoredOutput)) { + throw new \RuntimeException(self::sanitizeUrl('Failed to clone ' . $url . ', hg was not found, check that it is installed and in your PATH env.' . "\n\n" . $this->process->getErrorOutput())); + } + + throw new \RuntimeException(self::sanitizeUrl($message)); + } +} diff --git a/app/vendor/composer/composer/src/Composer/Util/IniHelper.php b/app/vendor/composer/composer/src/Composer/Util/IniHelper.php index de1065320..d655419fc 100644 --- a/app/vendor/composer/composer/src/Composer/Util/IniHelper.php +++ b/app/vendor/composer/composer/src/Composer/Util/IniHelper.php @@ -12,6 +12,8 @@ namespace Composer\Util; +use Composer\XdebugHandler\XdebugHandler; + /** * Provides ini file location functions that work with and without a restart. * When the process has restarted it uses a tmp ini and stores the original @@ -21,8 +23,6 @@ */ class IniHelper { - const ENV_ORIGINAL = 'COMPOSER_ORIGINAL_INIS'; - /** * Returns an array of php.ini locations with at least one entry * @@ -33,19 +33,7 @@ class IniHelper */ public static function getAll() { - $env = getenv(self::ENV_ORIGINAL); - - if (false !== $env) { - return explode(PATH_SEPARATOR, $env); - } - - $paths = array(strval(php_ini_loaded_file())); - - if ($scanned = php_ini_scanned_files()) { - $paths = array_merge($paths, array_map('trim', explode(',', $scanned))); - } - - return $paths; + return XdebugHandler::getAllIniFiles(); } /** diff --git a/app/vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php b/app/vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php index 66c78a69c..dc2b33089 100644 --- a/app/vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php +++ b/app/vendor/composer/composer/src/Composer/Util/RemoteFilesystem.php @@ -243,7 +243,7 @@ protected function get($originUrl, $fileUrl, $additionalOptions = array(), $file // capture username/password from URL if there is one if (preg_match('{^https?://([^:/]+):([^@/]+)@([^/]+)}i', $fileUrl, $match)) { - $this->io->setAuthentication($originUrl, urldecode($match[1]), urldecode($match[2])); + $this->io->setAuthentication($originUrl, rawurldecode($match[1]), rawurldecode($match[2])); } $tempAdditionalOptions = $additionalOptions; @@ -283,9 +283,9 @@ protected function get($originUrl, $fileUrl, $additionalOptions = array(), $file $options['http']['ignore_errors'] = true; } - if ($this->degradedMode && substr($fileUrl, 0, 21) === 'http://packagist.org/') { + if ($this->degradedMode && substr($fileUrl, 0, 26) === 'http://repo.packagist.org/') { // access packagist using the resolved IPv4 instead of the hostname to force IPv4 protocol - $fileUrl = 'http://' . gethostbyname('packagist.org') . substr($fileUrl, 20); + $fileUrl = 'http://' . gethostbyname('repo.packagist.org') . substr($fileUrl, 20); $degradedPackagist = true; } @@ -297,7 +297,7 @@ protected function get($originUrl, $fileUrl, $additionalOptions = array(), $file unset($origFileUrl, $actualContextOptions); // Check for secure HTTP, but allow insecure Packagist calls to $hashed providers as file integrity is verified with sha256 - if ((substr($fileUrl, 0, 23) !== 'http://packagist.org/p/' || (false === strpos($fileUrl, '$') && false === strpos($fileUrl, '%24'))) && empty($degradedPackagist) && $this->config) { + if ((!preg_match('{^http://(repo\.)?packagist\.org/p/}', $fileUrl) || (false === strpos($fileUrl, '$') && false === strpos($fileUrl, '%24'))) && empty($degradedPackagist) && $this->config) { $this->config->prohibitUrlByConfig($fileUrl, $this->io); } @@ -315,7 +315,7 @@ protected function get($originUrl, $fileUrl, $additionalOptions = array(), $file $errorMessage .= preg_replace('{^file_get_contents\(.*?\): }', '', $msg); }); try { - $result = file_get_contents($fileUrl, false, $ctx); + $result = $this->getRemoteContents($originUrl, $fileUrl, $ctx, $http_response_header); if (!empty($http_response_header[0])) { $statusCode = $this->findStatusCode($http_response_header); @@ -327,7 +327,7 @@ protected function get($originUrl, $fileUrl, $additionalOptions = array(), $file $warning = $data['warning']; } } - $this->promptAuthAndRetry($statusCode, $this->findStatusMessage($http_response_header), $warning); + $this->promptAuthAndRetry($statusCode, $this->findStatusMessage($http_response_header), $warning, $http_response_header); } } @@ -570,6 +570,33 @@ protected function get($originUrl, $fileUrl, $additionalOptions = array(), $file return $result; } + /** + * Get contents of remote URL. + * + * @param string $originUrl The origin URL + * @param string $fileUrl The file URL + * @param resource $context The stream context + * + * @return string|false The response contents or false on failure + */ + protected function getRemoteContents($originUrl, $fileUrl, $context, array &$responseHeaders = null) + { + try { + $e = null; + $result = file_get_contents($fileUrl, false, $context); + } catch (\Throwable $e) { + } catch (\Exception $e) { + } + + $responseHeaders = isset($http_response_header) ? $http_response_header : array(); + + if (null !== $e) { + throw $e; + } + + return $result; + } + /** * Get notification action. * @@ -612,11 +639,35 @@ protected function callbackGet($notificationCode, $severity, $message, $messageC } } - protected function promptAuthAndRetry($httpStatus, $reason = null, $warning = null) + protected function promptAuthAndRetry($httpStatus, $reason = null, $warning = null, $headers = array()) { if ($this->config && in_array($this->originUrl, $this->config->get('github-domains'), true)) { - $message = "\n".'Could not fetch '.$this->fileUrl.', please create a GitHub OAuth token '.($httpStatus === 404 ? 'to access private repos' : 'to go over the API rate limit'); $gitHubUtil = new GitHub($this->io, $this->config, null); + $message = "\n"; + + $rateLimited = $gitHubUtil->isRateLimited($headers); + if ($rateLimited) { + $rateLimit = $gitHubUtil->getRateLimit($headers); + if ($this->io->hasAuthentication($this->originUrl)) { + $message = 'Review your configured GitHub OAuth token or enter a new one to go over the API rate limit.'; + } else { + $message = 'Create a GitHub OAuth token to go over the API rate limit.'; + } + + $message = sprintf( + 'GitHub API limit (%d calls/hr) is exhausted, could not fetch '.$this->fileUrl.'. '.$message.' You can also wait until %s for the rate limit to reset.', + $rateLimit['limit'], + $rateLimit['reset'] + )."\n"; + } else { + $message .= 'Could not fetch '.$this->fileUrl.', please '; + if ($this->io->hasAuthentication($this->originUrl)) { + $message .= 'review your configured GitHub OAuth token or enter a new one to access private repos'; + } else { + $message .= 'create a GitHub OAuth token to access private repos'; + } + } + if (!$gitHubUtil->authorizeOAuth($this->originUrl) && (!$this->io->isInteractive() || !$gitHubUtil->authorizeOAuthInteractively($this->originUrl, $message)) ) { @@ -734,6 +785,9 @@ protected function getOptionsForUrl($originUrl, $additionalOptions) $tlsOptions['ssl']['CN_match'] = $certMap['cn']; $tlsOptions['ssl']['peer_fingerprint'] = $certMap['fp']; + } elseif (!CaBundle::isOpensslParseSafe() && $host === 'repo.packagist.org') { + // handle subjectAltName for packagist.org's repo domain on very old PHPs + $tlsOptions['ssl']['CN_match'] = 'packagist.org'; } } diff --git a/app/vendor/composer/composer/src/Composer/Util/StreamContextFactory.php b/app/vendor/composer/composer/src/Composer/Util/StreamContextFactory.php index b8290086c..f5f12d315 100644 --- a/app/vendor/composer/composer/src/Composer/Util/StreamContextFactory.php +++ b/app/vendor/composer/composer/src/Composer/Util/StreamContextFactory.php @@ -109,9 +109,9 @@ public static function getContext($url, array $defaultOptions = array(), array $ // handle proxy auth if present if (isset($proxy['user'])) { - $auth = urldecode($proxy['user']); + $auth = rawurldecode($proxy['user']); if (isset($proxy['pass'])) { - $auth .= ':' . urldecode($proxy['pass']); + $auth .= ':' . rawurldecode($proxy['pass']); } $auth = base64_encode($auth); @@ -169,7 +169,7 @@ private static function fixHttpHeaderField($header) $header = explode("\r\n", $header); } uasort($header, function ($el) { - return preg_match('{^content-type}i', $el) ? 1 : -1; + return stripos($el, 'content-type') === 0 ? 1 : -1; }); return $header; diff --git a/app/vendor/composer/composer/src/Composer/Util/Svn.php b/app/vendor/composer/composer/src/Composer/Util/Svn.php index 898fadce0..df31ccbbf 100644 --- a/app/vendor/composer/composer/src/Composer/Util/Svn.php +++ b/app/vendor/composer/composer/src/Composer/Util/Svn.php @@ -66,7 +66,7 @@ class Svn /** * @var string|null */ - static private $version; + private static $version; /** * @param string $url @@ -223,7 +223,8 @@ protected function doAuthDance() */ protected function getCommand($cmd, $url, $path = null) { - $cmd = sprintf('%s %s%s %s', + $cmd = sprintf( + '%s %s%s %s', $cmd, '--non-interactive ', $this->getCredentialString(), diff --git a/app/vendor/composer/composer/src/Composer/Util/TlsHelper.php b/app/vendor/composer/composer/src/Composer/Util/TlsHelper.php index b261f47a5..e04c7157e 100644 --- a/app/vendor/composer/composer/src/Composer/Util/TlsHelper.php +++ b/app/vendor/composer/composer/src/Composer/Util/TlsHelper.php @@ -140,7 +140,7 @@ public static function getCertificateFingerprint($certificate) //Convert PEM to DER before SHA1'ing $start = '-----BEGIN PUBLIC KEY-----'; $end = '-----END PUBLIC KEY-----'; - $pemtrim = substr($pubkeypem, (strpos($pubkeypem, $start) + strlen($start)), (strlen($pubkeypem) - strpos($pubkeypem, $end)) * (-1)); + $pemtrim = substr($pubkeypem, strpos($pubkeypem, $start) + strlen($start), (strlen($pubkeypem) - strpos($pubkeypem, $end)) * (-1)); $der = base64_decode($pemtrim); return sha1($der); diff --git a/app/vendor/composer/composer/src/Composer/Util/Url.php b/app/vendor/composer/composer/src/Composer/Util/Url.php index f8d4b446d..4a5d5f90c 100644 --- a/app/vendor/composer/composer/src/Composer/Util/Url.php +++ b/app/vendor/composer/composer/src/Composer/Util/Url.php @@ -13,7 +13,6 @@ namespace Composer\Util; use Composer\Config; -use Composer\IO\IOInterface; /** * @author Jordi Boggiano diff --git a/app/vendor/composer/composer/src/Composer/XdebugHandler.php b/app/vendor/composer/composer/src/Composer/XdebugHandler.php index 7031e6ff8..eb94e93f4 100644 --- a/app/vendor/composer/composer/src/Composer/XdebugHandler.php +++ b/app/vendor/composer/composer/src/Composer/XdebugHandler.php @@ -12,290 +12,20 @@ namespace Composer; -use Composer\Util\IniHelper; use Symfony\Component\Console\Output\OutputInterface; +trigger_error('The ' . __NAMESPACE__ . '\XdebugHandler class is deprecated, use Composer\XdebugHandler\XdebugHandler instead,', E_USER_DEPRECATED); + /** - * @author John Stevenson + * @deprecated use Composer\XdebugHandler\XdebugHandler instead */ -class XdebugHandler +class XdebugHandler extends XdebugHandler\XdebugHandler { const ENV_ALLOW = 'COMPOSER_ALLOW_XDEBUG'; const ENV_VERSION = 'COMPOSER_XDEBUG_VERSION'; - const RESTART_ID = 'internal'; - - private $output; - private $loaded; - private $envScanDir; - private $version; - private $tmpIni; - /** - * Constructor - */ public function __construct(OutputInterface $output) { - $this->output = $output; - $this->loaded = extension_loaded('xdebug'); - $this->envScanDir = getenv('PHP_INI_SCAN_DIR'); - - if ($this->loaded) { - $ext = new \ReflectionExtension('xdebug'); - $this->version = strval($ext->getVersion()); - } - } - - /** - * Checks if xdebug is loaded and composer needs to be restarted - * - * If so, then a tmp ini is created with the xdebug ini entry commented out. - * If additional inis have been loaded, these are combined into the tmp ini - * and PHP_INI_SCAN_DIR is set to an empty value. Current ini locations are - * are stored in COMPOSER_ORIGINAL_INIS, for use in the restarted process. - * - * This behaviour can be disabled by setting the COMPOSER_ALLOW_XDEBUG - * environment variable to 1. This variable is used internally so that the - * restarted process is created only once and PHP_INI_SCAN_DIR can be - * restored to its original value. - */ - public function check() - { - $args = explode('|', strval(getenv(self::ENV_ALLOW)), 2); - - if ($this->needsRestart($args[0])) { - if ($this->prepareRestart()) { - $command = $this->getCommand(); - $this->restart($command); - } - - return; - } - - // Restore environment variables if we are restarting - if (self::RESTART_ID === $args[0]) { - putenv(self::ENV_ALLOW); - - if (false !== $this->envScanDir) { - // $args[1] contains the original value - if (isset($args[1])) { - putenv('PHP_INI_SCAN_DIR='.$args[1]); - } else { - putenv('PHP_INI_SCAN_DIR'); - } - } - - // Clear version if the restart failed to disable xdebug - if ($this->loaded) { - putenv(self::ENV_VERSION); - } - } - } - - /** - * Executes the restarted command then deletes the tmp ini - * - * @param string $command - */ - protected function restart($command) - { - passthru($command, $exitCode); - - if (!empty($this->tmpIni)) { - @unlink($this->tmpIni); - } - - exit($exitCode); - } - - /** - * Returns true if a restart is needed - * - * @param string $allow Environment value - * - * @return bool - */ - private function needsRestart($allow) - { - if (PHP_SAPI !== 'cli' || !defined('PHP_BINARY')) { - return false; - } - - return empty($allow) && $this->loaded; - } - - /** - * Returns true if everything was written for the restart - * - * If any of the following fails (however unlikely) we must return false to - * stop potential recursion: - * - tmp ini file creation - * - environment variable creation - * - * @return bool - */ - private function prepareRestart() - { - $this->tmpIni = ''; - $iniPaths = IniHelper::getAll(); - $additional = count($iniPaths) > 1; - - if ($this->writeTmpIni($iniPaths)) { - return $this->setEnvironment($additional, $iniPaths); - } - - return false; - } - - /** - * Returns true if the tmp ini file was written - * - * The filename is passed as the -c option when the process restarts. - * - * @param array $iniPaths Locations reported by the current process - * - * @return bool - */ - private function writeTmpIni(array $iniPaths) - { - if (!$this->tmpIni = tempnam(sys_get_temp_dir(), '')) { - return false; - } - - // $iniPaths has at least one item and it may be empty - if (empty($iniPaths[0])) { - array_shift($iniPaths); - } - - $content = ''; - $regex = '/^\s*(zend_extension\s*=.*xdebug.*)$/mi'; - - foreach ($iniPaths as $file) { - $data = preg_replace($regex, ';$1', file_get_contents($file)); - $content .= $data.PHP_EOL; - } - - $content .= 'allow_url_fopen='.ini_get('allow_url_fopen').PHP_EOL; - $content .= 'disable_functions="'.ini_get('disable_functions').'"'.PHP_EOL; - $content .= 'memory_limit='.ini_get('memory_limit').PHP_EOL; - - if (defined('PHP_WINDOWS_VERSION_BUILD')) { - // Work-around for PHP windows bug, see issue #6052 - $content .= 'opcache.enable_cli=0'.PHP_EOL; - } - - return @file_put_contents($this->tmpIni, $content); - } - - /** - * Returns the restart command line - * - * @return string - */ - private function getCommand() - { - $phpArgs = array(PHP_BINARY, '-c', $this->tmpIni); - $params = array_merge($phpArgs, $this->getScriptArgs($_SERVER['argv'])); - - return implode(' ', array_map(array($this, 'escape'), $params)); - } - - /** - * Returns true if the restart environment variables were set - * - * @param bool $additional Whether there were additional inis - * @param array $iniPaths Locations reported by the current process - * - * @return bool - */ - private function setEnvironment($additional, array $iniPaths) - { - // Set scan dir to an empty value if additional ini files were used - if ($additional && !putenv('PHP_INI_SCAN_DIR=')) { - return false; - } - - // Make original inis available to restarted process - if (!putenv(IniHelper::ENV_ORIGINAL.'='.implode(PATH_SEPARATOR, $iniPaths))) { - return false; - } - - // Make xdebug version available to restarted process - if (!putenv(self::ENV_VERSION.'='.$this->version)) { - return false; - } - - // Flag restarted process and save env scan dir state - $args = array(self::RESTART_ID); - - if (false !== $this->envScanDir) { - // Save current PHP_INI_SCAN_DIR - $args[] = $this->envScanDir; - } - - return putenv(self::ENV_ALLOW.'='.implode('|', $args)); - } - - /** - * Returns the restart script arguments, adding --ansi if required - * - * If we are a terminal with color support we must ensure that the --ansi - * option is set, because the restarted output is piped. - * - * @param array $args The argv array - * - * @return array - */ - private function getScriptArgs(array $args) - { - if (in_array('--no-ansi', $args) || in_array('--ansi', $args)) { - return $args; - } - - if ($this->output->isDecorated()) { - $offset = count($args) > 1 ? 2 : 1; - array_splice($args, $offset, 0, '--ansi'); - } - - return $args; - } - - /** - * Escapes a string to be used as a shell argument. - * - * From https://github.com/johnstevenson/winbox-args - * MIT Licensed (c) John Stevenson - * - * @param string $arg The argument to be escaped - * @param bool $meta Additionally escape cmd.exe meta characters - * - * @return string The escaped argument - */ - private function escape($arg, $meta = true) - { - if (!defined('PHP_WINDOWS_VERSION_BUILD')) { - return escapeshellarg($arg); - } - - $quote = strpbrk($arg, " \t") !== false || $arg === ''; - $arg = preg_replace('/(\\\\*)"/', '$1$1\\"', $arg, -1, $dquotes); - - if ($meta) { - $meta = $dquotes || preg_match('/%[^%]+%/', $arg); - - if (!$meta && !$quote) { - $quote = strpbrk($arg, '^&|<>()') !== false; - } - } - - if ($quote) { - $arg = preg_replace('/(\\\\*)$/', '$1$1', $arg); - $arg = '"'.$arg.'"'; - } - - if ($meta) { - $arg = preg_replace('/(["^&|<>()%])/', '^$1', $arg); - } - - return $arg; + parent::__construct('composer', '--ansi'); } } diff --git a/app/vendor/composer/installed.json b/app/vendor/composer/installed.json index 0be90bf28..7d2a5e7c6 100644 --- a/app/vendor/composer/installed.json +++ b/app/vendor/composer/installed.json @@ -1,23 +1,23 @@ [ { "name": "adodb/adodb-php", - "version": "v5.20.9", - "version_normalized": "5.20.9.0", + "version": "v5.20.13", + "version_normalized": "5.20.13.0", "source": { "type": "git", "url": "https://github.com/ADOdb/ADOdb.git", - "reference": "f601748cca1ccb86dfd427620a1692a70e681075" + "reference": "1141326db4b5092cee95841a1c056f876b9b4c83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ADOdb/ADOdb/zipball/f601748cca1ccb86dfd427620a1692a70e681075", - "reference": "f601748cca1ccb86dfd427620a1692a70e681075", + "url": "https://api.github.com/repos/ADOdb/ADOdb/zipball/1141326db4b5092cee95841a1c056f876b9b4c83", + "reference": "1141326db4b5092cee95841a1c056f876b9b4c83", "shasum": "" }, "require": { "php": ">=5.3.2" }, - "time": "2016-12-21T17:19:42+00:00", + "time": "2018-08-06T16:04:33+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -28,7 +28,7 @@ "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause", - "LGPL-2.1" + "LGPL-2.1-or-later" ], "authors": [ { @@ -282,30 +282,30 @@ }, { "name": "cakephp/bake", - "version": "1.6.1", - "version_normalized": "1.6.1.0", + "version": "1.8.4", + "version_normalized": "1.8.4.0", "source": { "type": "git", "url": "https://github.com/cakephp/bake.git", - "reference": "6c2d86bf7d39262b63716c150dedcb02d56e53c1" + "reference": "7356656e236bb62733f4fdd4894ce1f26f9e14f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/bake/zipball/6c2d86bf7d39262b63716c150dedcb02d56e53c1", - "reference": "6c2d86bf7d39262b63716c150dedcb02d56e53c1", + "url": "https://api.github.com/repos/cakephp/bake/zipball/7356656e236bb62733f4fdd4894ce1f26f9e14f6", + "reference": "7356656e236bb62733f4fdd4894ce1f26f9e14f6", "shasum": "" }, "require": { - "cakephp/cakephp": "^3.5.10", + "cakephp/cakephp": "^3.6.0", "cakephp/plugin-installer": "^1.0", "php": ">=5.6.0", - "wyrihaximus/twig-view": "^4.2.1" + "wyrihaximus/twig-view": "^4.3.4" }, "require-dev": { "cakephp/cakephp-codesniffer": "^3.0", - "phpunit/phpunit": "^5.7 | ^6.0" + "phpunit/phpunit": "^5.7.14|^6.0" }, - "time": "2018-02-07T17:03:13+00:00", + "time": "2018-08-21T01:28:47+00:00", "type": "cakephp-plugin", "installation-source": "dist", "autoload": { @@ -332,17 +332,17 @@ }, { "name": "cakephp/cakephp", - "version": "3.6.7", - "version_normalized": "3.6.7.0", + "version": "3.6.11", + "version_normalized": "3.6.11.0", "source": { "type": "git", "url": "https://github.com/cakephp/cakephp.git", - "reference": "9a67c9d7158d5e299418f9956d1a8af39128cf57" + "reference": "ddbfcdb479cfaa59f6e8c3433bf85aa71bff492d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/cakephp/zipball/9a67c9d7158d5e299418f9956d1a8af39128cf57", - "reference": "9a67c9d7158d5e299418f9956d1a8af39128cf57", + "url": "https://api.github.com/repos/cakephp/cakephp/zipball/ddbfcdb479cfaa59f6e8c3433bf85aa71bff492d", + "reference": "ddbfcdb479cfaa59f6e8c3433bf85aa71bff492d", "shasum": "" }, "require": { @@ -380,7 +380,7 @@ "ext-openssl": "To use Security::encrypt() or have secure CSRF token generation.", "lib-ICU": "The intl PHP library, to use Text::transliterate() or Text::slug()" }, - "time": "2018-07-08T18:02:23+00:00", + "time": "2018-09-03T01:33:56+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -420,17 +420,17 @@ }, { "name": "cakephp/cakephp-codesniffer", - "version": "3.0.3", - "version_normalized": "3.0.3.0", + "version": "3.0.5", + "version_normalized": "3.0.5.0", "source": { "type": "git", "url": "https://github.com/cakephp/cakephp-codesniffer.git", - "reference": "d77ac81199f2f1e5a8d8ebf96a5d6d7cd4e0542b" + "reference": "7f467fee00fd016b62cf8c85a57750ab2a895e81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/d77ac81199f2f1e5a8d8ebf96a5d6d7cd4e0542b", - "reference": "d77ac81199f2f1e5a8d8ebf96a5d6d7cd4e0542b", + "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/7f467fee00fd016b62cf8c85a57750ab2a895e81", + "reference": "7f467fee00fd016b62cf8c85a57750ab2a895e81", "shasum": "" }, "require": { @@ -440,7 +440,7 @@ "require-dev": { "phpunit/phpunit": "<6.0" }, - "time": "2017-12-21T20:01:35+00:00", + "time": "2018-06-09T16:01:01+00:00", "type": "phpcodesniffer-standard", "installation-source": "dist", "autoload": { @@ -526,17 +526,17 @@ }, { "name": "cakephp/debug_kit", - "version": "3.16.3", - "version_normalized": "3.16.3.0", + "version": "3.16.4", + "version_normalized": "3.16.4.0", "source": { "type": "git", "url": "https://github.com/cakephp/debug_kit.git", - "reference": "aabaecb032f7e91d2c4df9c79806992cf60e07ee" + "reference": "d5cd81818b65da0849089a66316744e4cc453d70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/debug_kit/zipball/aabaecb032f7e91d2c4df9c79806992cf60e07ee", - "reference": "aabaecb032f7e91d2c4df9c79806992cf60e07ee", + "url": "https://api.github.com/repos/cakephp/debug_kit/zipball/d5cd81818b65da0849089a66316744e4cc453d70", + "reference": "d5cd81818b65da0849089a66316744e4cc453d70", "shasum": "" }, "require": { @@ -554,7 +554,7 @@ "suggest": { "ext-pdo_sqlite": "DebugKit needs to store panel data in a database. SQLite is simple and easy to use." }, - "time": "2018-06-11T02:33:52+00:00", + "time": "2018-08-03T13:57:51+00:00", "type": "cakephp-plugin", "installation-source": "dist", "autoload": { @@ -588,35 +588,35 @@ }, { "name": "cakephp/migrations", - "version": "1.7.2", - "version_normalized": "1.7.2.0", + "version": "1.8.1", + "version_normalized": "1.8.1.0", "source": { "type": "git", "url": "https://github.com/cakephp/migrations.git", - "reference": "a5612adfd2efa8c90d29cb3b0c969de872a99eda" + "reference": "cd65daa9fae933bc0ccc69d5b5d92460375da9e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/migrations/zipball/a5612adfd2efa8c90d29cb3b0c969de872a99eda", - "reference": "a5612adfd2efa8c90d29cb3b0c969de872a99eda", + "url": "https://api.github.com/repos/cakephp/migrations/zipball/cd65daa9fae933bc0ccc69d5b5d92460375da9e2", + "reference": "cd65daa9fae933bc0ccc69d5b5d92460375da9e2", "shasum": "" }, "require": { - "cakephp/cache": "~3.2", - "cakephp/orm": "~3.2", - "php": ">=5.5.9", + "cakephp/cache": "^3.6.0", + "cakephp/orm": "^3.6.0", + "php": ">=5.6.0", "robmorgan/phinx": "0.8.1" }, "require-dev": { - "cakephp/bake": "@stable", - "cakephp/cakephp": "~3.2", + "cakephp/bake": "^1.7.0", + "cakephp/cakephp": "^3.6.0", "cakephp/cakephp-codesniffer": "^3.0", - "phpunit/phpunit": "~4.1" + "phpunit/phpunit": "^5.7.14" }, "suggest": { "cakephp/bake": "Required if you want to generate migrations." }, - "time": "2017-12-12T21:01:38+00:00", + "time": "2018-04-16T01:35:59+00:00", "type": "cakephp-plugin", "installation-source": "dist", "autoload": { @@ -686,17 +686,17 @@ }, { "name": "composer/ca-bundle", - "version": "1.1.1", - "version_normalized": "1.1.1.0", + "version": "1.1.2", + "version_normalized": "1.1.2.0", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169" + "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/d2c0a83b7533d6912e8d516756ebd34f893e9169", - "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/46afded9720f40b9dc63542af4e3e43a1177acb0", + "reference": "46afded9720f40b9dc63542af4e3e43a1177acb0", "shasum": "" }, "require": { @@ -709,7 +709,7 @@ "psr/log": "^1.0", "symfony/process": "^2.5 || ^3.0 || ^4.0" }, - "time": "2018-03-29T19:57:20+00:00", + "time": "2018-08-08T08:57:40+00:00", "type": "library", "extra": { "branch-alias": { @@ -744,27 +744,27 @@ }, { "name": "composer/composer", - "version": "1.6.5", - "version_normalized": "1.6.5.0", + "version": "1.7.2", + "version_normalized": "1.7.2.0", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "b184a92419cc9a9c4c6a09db555a94d441cb11c9" + "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/b184a92419cc9a9c4c6a09db555a94d441cb11c9", - "reference": "b184a92419cc9a9c4c6a09db555a94d441cb11c9", + "url": "https://api.github.com/repos/composer/composer/zipball/576aab9b5abb2ed11a1c52353a759363216a4ad2", + "reference": "576aab9b5abb2ed11a1c52353a759363216a4ad2", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", "composer/semver": "^1.0", "composer/spdx-licenses": "^1.2", + "composer/xdebug-handler": "^1.1", "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", "php": "^5.3.2 || ^7.0", "psr/log": "^1.0", - "seld/cli-prompt": "^1.0", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.0", "symfony/console": "^2.7 || ^3.0 || ^4.0", @@ -784,14 +784,14 @@ "ext-zip": "Enabling the zip extension allows you to unzip archives", "ext-zlib": "Allow gzip compression of HTTP requests" }, - "time": "2018-05-04T09:44:59+00:00", + "time": "2018-08-16T14:57:12+00:00", "bin": [ "bin/composer" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } }, "installation-source": "dist", @@ -951,6 +951,52 @@ "validator" ] }, + { + "name": "composer/xdebug-handler", + "version": "1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/b8e9745fb9b06ea6664d8872c4505fb16df4611c", + "reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "time": "2018-08-31T19:07:57+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without xdebug.", + "keywords": [ + "Xdebug", + "performance" + ] + }, { "name": "dnoegel/php-xdg-base-dir", "version": "0.1", @@ -986,37 +1032,274 @@ ], "description": "implementation of xdg base directory specification for php" }, + { + "name": "doctrine/cache", + "version": "v1.8.0", + "version_normalized": "1.8.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57", + "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57", + "shasum": "" + }, + "require": { + "php": "~7.1" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "doctrine/coding-standard": "^4.0", + "mongodb/mongodb": "^1.1", + "phpunit/phpunit": "^7.0", + "predis/predis": "~1.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + }, + "time": "2018-08-21T18:01:43+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Caching library offering an object-oriented API for many cache backends", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "cache", + "caching" + ] + }, + { + "name": "doctrine/dbal", + "version": "v2.9.2", + "version_normalized": "2.9.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", + "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9", + "shasum": "" + }, + "require": { + "doctrine/cache": "^1.0", + "doctrine/event-manager": "^1.0", + "ext-pdo": "*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/coding-standard": "^5.0", + "jetbrains/phpstorm-stubs": "^2018.1.2", + "phpstan/phpstan": "^0.10.1", + "phpunit/phpunit": "^7.4", + "symfony/console": "^2.0.5|^3.0|^4.0", + "symfony/phpunit-bridge": "^3.4.5|^4.0.5" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "time": "2018-12-31T03:27:51+00:00", + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.9.x-dev", + "dev-develop": "3.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "dbal", + "mysql", + "persistence", + "pgsql", + "php", + "queryobject" + ] + }, + { + "name": "doctrine/event-manager", + "version": "v1.0.0", + "version_normalized": "1.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^4.0", + "phpunit/phpunit": "^7.0" + }, + "time": "2018-06-11T11:59:03+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Doctrine Event Manager component", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "eventdispatcher", + "eventmanager" + ] + }, { "name": "jakub-onderka/php-console-color", - "version": "0.1", - "version_normalized": "0.1.0.0", + "version": "v0.2", + "version_normalized": "0.2.0.0", "source": { "type": "git", "url": "https://github.com/JakubOnderka/PHP-Console-Color.git", - "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1" + "reference": "d5deaecff52a0d61ccb613bb3804088da0307191" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1", - "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1", + "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/d5deaecff52a0d61ccb613bb3804088da0307191", + "reference": "d5deaecff52a0d61ccb613bb3804088da0307191", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": ">=5.4.0" }, "require-dev": { "jakub-onderka/php-code-style": "1.0", - "jakub-onderka/php-parallel-lint": "0.*", + "jakub-onderka/php-parallel-lint": "1.0", "jakub-onderka/php-var-dump-check": "0.*", - "phpunit/phpunit": "3.7.*", + "phpunit/phpunit": "~4.3", "squizlabs/php_codesniffer": "1.*" }, - "time": "2014-04-08T15:00:19+00:00", + "time": "2018-09-29T17:23:10+00:00", "type": "library", "installation-source": "dist", "autoload": { - "psr-0": { - "JakubOnderka\\PhpConsoleColor": "src/" + "psr-4": { + "JakubOnderka\\PhpConsoleColor\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1026,8 +1309,7 @@ "authors": [ { "name": "Jakub Onderka", - "email": "jakub.onderka@gmail.com", - "homepage": "http://www.acci.cz" + "email": "jakub.onderka@gmail.com" } ] }, @@ -1315,17 +1597,17 @@ }, { "name": "m1/env", - "version": "2.1.0", - "version_normalized": "2.1.0.0", + "version": "2.1.2", + "version_normalized": "2.1.2.0", "source": { "type": "git", "url": "https://github.com/m1/Env.git", - "reference": "d87eddd031f2aa5450fa04bb1325de8a489b3cd0" + "reference": "294addeedf15e1149eeb96ec829f2029d2017d39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/m1/Env/zipball/d87eddd031f2aa5450fa04bb1325de8a489b3cd0", - "reference": "d87eddd031f2aa5450fa04bb1325de8a489b3cd0", + "url": "https://api.github.com/repos/m1/Env/zipball/294addeedf15e1149eeb96ec829f2029d2017d39", + "reference": "294addeedf15e1149eeb96ec829f2029d2017d39", "shasum": "" }, "require": { @@ -1340,7 +1622,7 @@ "josegonzalez/dotenv": "For loading of .env", "m1/vars": "For loading of configs" }, - "time": "2016-10-06T19:31:28+00:00", + "time": "2018-06-19T18:55:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1375,17 +1657,17 @@ }, { "name": "mobiledetect/mobiledetectlib", - "version": "2.8.30", - "version_normalized": "2.8.30.0", + "version": "2.8.33", + "version_normalized": "2.8.33.0", "source": { "type": "git", "url": "https://github.com/serbanghita/Mobile-Detect.git", - "reference": "5500bbbf312fe77ef0c7223858dad84fe49ee0c3" + "reference": "cd385290f9a0d609d2eddd165a1e44ec1bf12102" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/5500bbbf312fe77ef0c7223858dad84fe49ee0c3", - "reference": "5500bbbf312fe77ef0c7223858dad84fe49ee0c3", + "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/cd385290f9a0d609d2eddd165a1e44ec1bf12102", + "reference": "cd385290f9a0d609d2eddd165a1e44ec1bf12102", "shasum": "" }, "require": { @@ -1394,7 +1676,7 @@ "require-dev": { "phpunit/phpunit": "~4.8.35||~5.7" }, - "time": "2017-12-18T10:38:51+00:00", + "time": "2018-09-01T15:05:15+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1429,34 +1711,34 @@ }, { "name": "nikic/php-parser", - "version": "v3.1.4", - "version_normalized": "3.1.4.0", + "version": "v4.0.4", + "version_normalized": "4.0.4.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "e57b3a09784f846411aa7ed664eedb73e3399078" + "reference": "fa6ee28600d21d49b2b4e1006b48426cec8e579c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/e57b3a09784f846411aa7ed664eedb73e3399078", - "reference": "e57b3a09784f846411aa7ed664eedb73e3399078", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/fa6ee28600d21d49b2b4e1006b48426cec8e579c", + "reference": "fa6ee28600d21d49b2b4e1006b48426cec8e579c", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.5" + "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" + "phpunit/phpunit": "^6.5 || ^7.0" }, - "time": "2018-01-25T21:31:33+00:00", + "time": "2018-09-18T07:03:24+00:00", "bin": [ "bin/php-parse" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "installation-source": "dist", @@ -1583,31 +1865,33 @@ }, { "name": "psy/psysh", - "version": "v0.8.17", - "version_normalized": "0.8.17.0", + "version": "v0.9.8", + "version_normalized": "0.9.8.0", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "5069b70e8c4ea492c2b5939b6eddc78bfe41cfec" + "reference": "ed3c32c4304e1a678a6e0f9dc11dd2d927d89555" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/5069b70e8c4ea492c2b5939b6eddc78bfe41cfec", - "reference": "5069b70e8c4ea492c2b5939b6eddc78bfe41cfec", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/ed3c32c4304e1a678a6e0f9dc11dd2d927d89555", + "reference": "ed3c32c4304e1a678a6e0f9dc11dd2d927d89555", "shasum": "" }, "require": { "dnoegel/php-xdg-base-dir": "0.1", + "ext-json": "*", + "ext-tokenizer": "*", "jakub-onderka/php-console-highlighter": "0.3.*", - "nikic/php-parser": "~1.3|~2.0|~3.0", - "php": ">=5.3.9", + "nikic/php-parser": "~1.3|~2.0|~3.0|~4.0", + "php": ">=5.4.0", "symfony/console": "~2.3.10|^2.4.2|~3.0|~4.0", "symfony/var-dumper": "~2.7|~3.0|~4.0" }, "require-dev": { - "hoa/console": "~3.16|~1.14", - "phpunit/phpunit": "^4.8.35|^5.4.3", - "symfony/finder": "~2.1|~3.0|~4.0" + "bamarni/composer-bin-plugin": "^1.2", + "hoa/console": "~2.15|~3.16", + "phpunit/phpunit": "~4.8.35|~5.0|~6.0|~7.0" }, "suggest": { "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", @@ -1616,23 +1900,23 @@ "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." }, - "time": "2017-12-28T16:14:16+00:00", + "time": "2018-09-05T11:40:09+00:00", "bin": [ "bin/psysh" ], "type": "library", "extra": { "branch-alias": { - "dev-develop": "0.8.x-dev" + "dev-develop": "0.9.x-dev" } }, "installation-source": "dist", "autoload": { "files": [ - "src/Psy/functions.php" + "src/functions.php" ], "psr-4": { - "Psy\\": "src/Psy/" + "Psy\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1723,56 +2007,6 @@ "phinx" ] }, - { - "name": "seld/cli-prompt", - "version": "1.0.3", - "version_normalized": "1.0.3.0", - "source": { - "type": "git", - "url": "https://github.com/Seldaek/cli-prompt.git", - "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", - "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", - "shasum": "" - }, - "require": { - "php": ">=5.3" - }, - "time": "2017-03-18T11:32:45+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Seld\\CliPrompt\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", - "keywords": [ - "cli", - "console", - "hidden", - "input", - "prompt" - ] - }, { "name": "seld/jsonlint", "version": "1.7.1", @@ -1872,17 +2106,17 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.2.2", - "version_normalized": "3.2.2.0", + "version": "3.3.2", + "version_normalized": "3.3.2.0", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1" + "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7c00c3000ac0ce79c96fcbfef86b49a71158cd1", - "reference": "d7c00c3000ac0ce79c96fcbfef86b49a71158cd1", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6ad28354c04b364c3c71a34e4a18b629cc3b231e", + "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e", "shasum": "" }, "require": { @@ -1892,9 +2126,9 @@ "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, - "time": "2017-12-19T21:44:46+00:00", + "time": "2018-09-23T23:08:17+00:00", "bin": [ "bin/phpcs", "bin/phpcbf" @@ -1925,22 +2159,23 @@ }, { "name": "symfony/config", - "version": "v3.4.4", - "version_normalized": "3.4.4.0", + "version": "v3.4.16", + "version_normalized": "3.4.16.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "72689b934d6c6ecf73eca874e98933bf055313c9" + "reference": "e5389132dc6320682de3643091121c048ff796b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/72689b934d6c6ecf73eca874e98933bf055313c9", - "reference": "72689b934d6c6ecf73eca874e98933bf055313c9", + "url": "https://api.github.com/repos/symfony/config/zipball/e5389132dc6320682de3643091121c048ff796b3", + "reference": "e5389132dc6320682de3643091121c048ff796b3", "shasum": "" }, "require": { "php": "^5.5.9|>=7.0.8", - "symfony/filesystem": "~2.8|~3.0|~4.0" + "symfony/filesystem": "~2.8|~3.0|~4.0", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/dependency-injection": "<3.3", @@ -1948,13 +2183,14 @@ }, "require-dev": { "symfony/dependency-injection": "~3.3|~4.0", + "symfony/event-dispatcher": "~3.3|~4.0", "symfony/finder": "~3.3|~4.0", "symfony/yaml": "~3.0|~4.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" }, - "time": "2018-01-21T19:05:02+00:00", + "time": "2018-09-08T13:15:14+00:00", "type": "library", "extra": { "branch-alias": { @@ -1989,17 +2225,17 @@ }, { "name": "symfony/console", - "version": "v3.4.12", - "version_normalized": "3.4.12.0", + "version": "v3.4.16", + "version_normalized": "3.4.16.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "1b97071a26d028c9bd4588264e101e14f6e7cd00" + "reference": "1cbaac35024c9dfc9612b7e2310e82677bf85709" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/1b97071a26d028c9bd4588264e101e14f6e7cd00", - "reference": "1b97071a26d028c9bd4588264e101e14f6e7cd00", + "url": "https://api.github.com/repos/symfony/console/zipball/1cbaac35024c9dfc9612b7e2310e82677bf85709", + "reference": "1cbaac35024c9dfc9612b7e2310e82677bf85709", "shasum": "" }, "require": { @@ -2025,7 +2261,7 @@ "symfony/lock": "", "symfony/process": "" }, - "time": "2018-05-23T05:02:55+00:00", + "time": "2018-09-30T03:37:36+00:00", "type": "library", "extra": { "branch-alias": { @@ -2060,34 +2296,34 @@ }, { "name": "symfony/debug", - "version": "v4.1.1", - "version_normalized": "4.1.1.0", + "version": "v3.4.16", + "version_normalized": "3.4.16.0", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "dbe0fad88046a755dcf9379f2964c61a02f5ae3d" + "reference": "b70cfaae39009ecde3164bb8cba4d029220d27b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/dbe0fad88046a755dcf9379f2964c61a02f5ae3d", - "reference": "dbe0fad88046a755dcf9379f2964c61a02f5ae3d", + "url": "https://api.github.com/repos/symfony/debug/zipball/b70cfaae39009ecde3164bb8cba4d029220d27b1", + "reference": "b70cfaae39009ecde3164bb8cba4d029220d27b1", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": "^5.5.9|>=7.0.8", "psr/log": "~1.0" }, "conflict": { - "symfony/http-kernel": "<3.4" + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" }, "require-dev": { - "symfony/http-kernel": "~3.4|~4.0" + "symfony/http-kernel": "~2.8|~3.0|~4.0" }, - "time": "2018-06-08T09:39:36+00:00", + "time": "2018-09-22T18:25:03+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "3.4-dev" } }, "installation-source": "dist", @@ -2118,28 +2354,28 @@ }, { "name": "symfony/filesystem", - "version": "v4.1.1", - "version_normalized": "4.1.1.0", + "version": "v3.4.16", + "version_normalized": "3.4.16.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "562bf7005b55fd80d26b582d28e3e10f2dd5ae9c" + "reference": "f89ab242d915d188fca95ee3291c72c5a094a195" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/562bf7005b55fd80d26b582d28e3e10f2dd5ae9c", - "reference": "562bf7005b55fd80d26b582d28e3e10f2dd5ae9c", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/f89ab242d915d188fca95ee3291c72c5a094a195", + "reference": "f89ab242d915d188fca95ee3291c72c5a094a195", "shasum": "" }, "require": { - "php": "^7.1.3", + "php": "^5.5.9|>=7.0.8", "symfony/polyfill-ctype": "~1.8" }, - "time": "2018-05-30T07:26:09+00:00", + "time": "2018-09-30T03:32:28+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "3.4-dev" } }, "installation-source": "dist", @@ -2170,27 +2406,27 @@ }, { "name": "symfony/finder", - "version": "v4.1.1", - "version_normalized": "4.1.1.0", + "version": "v3.4.16", + "version_normalized": "3.4.16.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "84714b8417d19e4ba02ea78a41a975b3efaafddb" + "reference": "e8db87d755e14271e920e31ba834a4ae99483232" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/84714b8417d19e4ba02ea78a41a975b3efaafddb", - "reference": "84714b8417d19e4ba02ea78a41a975b3efaafddb", + "url": "https://api.github.com/repos/symfony/finder/zipball/e8db87d755e14271e920e31ba834a4ae99483232", + "reference": "e8db87d755e14271e920e31ba834a4ae99483232", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^5.5.9|>=7.0.8" }, - "time": "2018-06-19T21:38:16+00:00", + "time": "2018-09-21T12:47:54+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "3.4-dev" } }, "installation-source": "dist", @@ -2221,27 +2457,30 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.8.0", - "version_normalized": "1.8.0.0", + "version": "v1.9.0", + "version_normalized": "1.9.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae" + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/7cc359f1b7b80fc25ed7796be7d96adc9b354bae", - "reference": "7cc359f1b7b80fc25ed7796be7d96adc9b354bae", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", "shasum": "" }, "require": { "php": ">=5.3.3" }, - "time": "2018-04-30T19:57:29+00:00", + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2018-08-06T14:22:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "installation-source": "dist", @@ -2278,17 +2517,17 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.8.0", - "version_normalized": "1.8.0.0", + "version": "v1.9.0", + "version_normalized": "1.9.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "3296adf6a6454a050679cde90f95350ad604b171" + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171", - "reference": "3296adf6a6454a050679cde90f95350ad604b171", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d0cd638f4634c16d8df4508e847f14e9e43168b8", + "reference": "d0cd638f4634c16d8df4508e847f14e9e43168b8", "shasum": "" }, "require": { @@ -2297,11 +2536,11 @@ "suggest": { "ext-mbstring": "For best performance" }, - "time": "2018-04-26T10:06:28+00:00", + "time": "2018-08-06T14:22:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "installation-source": "dist", @@ -2337,86 +2576,29 @@ "shim" ] }, - { - "name": "symfony/polyfill-php72", - "version": "v1.7.0", - "version_normalized": "1.7.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "8eca20c8a369e069d4f4c2ac9895144112867422" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/8eca20c8a369e069d4f4c2ac9895144112867422", - "reference": "8eca20c8a369e069d4f4c2ac9895144112867422", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "time": "2018-01-31T17:43:24+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.7-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ] - }, { "name": "symfony/process", - "version": "v4.1.1", - "version_normalized": "4.1.1.0", + "version": "v3.4.16", + "version_normalized": "3.4.16.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "1d1677391ecf00d1c5b9482d6050c0c27aa3ac3a" + "reference": "8b87aca97f341d65dee430c60863f2442605c88b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/1d1677391ecf00d1c5b9482d6050c0c27aa3ac3a", - "reference": "1d1677391ecf00d1c5b9482d6050c0c27aa3ac3a", + "url": "https://api.github.com/repos/symfony/process/zipball/8b87aca97f341d65dee430c60863f2442605c88b", + "reference": "8b87aca97f341d65dee430c60863f2442605c88b", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": "^5.5.9|>=7.0.8" }, - "time": "2018-05-31T10:17:53+00:00", + "time": "2018-09-08T13:15:14+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "3.4-dev" } }, "installation-source": "dist", @@ -2447,23 +2629,22 @@ }, { "name": "symfony/var-dumper", - "version": "v4.0.4", - "version_normalized": "4.0.4.0", + "version": "v3.4.16", + "version_normalized": "3.4.16.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "6d63cc74f3e2d4961411ccb77389a00332653104" + "reference": "e57a24dc13accad1d5f90d232c5564910c5eb7b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/6d63cc74f3e2d4961411ccb77389a00332653104", - "reference": "6d63cc74f3e2d4961411ccb77389a00332653104", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/e57a24dc13accad1d5f90d232c5564910c5eb7b0", + "reference": "e57a24dc13accad1d5f90d232c5564910c5eb7b0", "shasum": "" }, "require": { - "php": "^7.1.3", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5" + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" @@ -2474,13 +2655,14 @@ }, "suggest": { "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump" + "ext-intl": "To show region name in time zone dump", + "ext-symfony_debug": "" }, - "time": "2018-01-29T09:06:29+00:00", + "time": "2018-09-18T08:05:59+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "3.4-dev" } }, "installation-source": "dist", @@ -2518,21 +2700,22 @@ }, { "name": "symfony/yaml", - "version": "v3.4.4", - "version_normalized": "3.4.4.0", + "version": "v3.4.16", + "version_normalized": "3.4.16.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "eab73b6c21d27ae4cd037c417618dfd4befb0bfe" + "reference": "61973ecda60e9f3561e929e19c07d4878b960fc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/eab73b6c21d27ae4cd037c417618dfd4befb0bfe", - "reference": "eab73b6c21d27ae4cd037c417618dfd4befb0bfe", + "url": "https://api.github.com/repos/symfony/yaml/zipball/61973ecda60e9f3561e929e19c07d4878b960fc1", + "reference": "61973ecda60e9f3561e929e19c07d4878b960fc1", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8" + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "symfony/console": "<3.4" @@ -2543,7 +2726,7 @@ "suggest": { "symfony/console": "For validating YAML files using the lint command" }, - "time": "2018-01-21T19:05:02+00:00", + "time": "2018-09-24T08:15:45+00:00", "type": "library", "extra": { "branch-alias": { @@ -2578,28 +2761,29 @@ }, { "name": "twig/twig", - "version": "v1.35.0", - "version_normalized": "1.35.0.0", + "version": "v1.35.4", + "version_normalized": "1.35.4.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "daa657073e55b0a78cce8fdd22682fddecc6385f" + "reference": "7e081e98378a1e78c29cc9eba4aefa5d78a05d2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/daa657073e55b0a78cce8fdd22682fddecc6385f", - "reference": "daa657073e55b0a78cce8fdd22682fddecc6385f", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/7e081e98378a1e78c29cc9eba4aefa5d78a05d2a", + "reference": "7e081e98378a1e78c29cc9eba4aefa5d78a05d2a", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.3", + "symfony/polyfill-ctype": "^1.8" }, "require-dev": { "psr/container": "^1.0", - "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~3.3@dev" + "symfony/debug": "^2.7", + "symfony/phpunit-bridge": "^3.3" }, - "time": "2017-09-27T18:06:46+00:00", + "time": "2018-07-13T07:12:17+00:00", "type": "library", "extra": { "branch-alias": { @@ -2633,12 +2817,12 @@ }, { "name": "Twig Team", - "homepage": "http://twig.sensiolabs.org/contributors", + "homepage": "https://twig.symfony.com/contributors", "role": "Contributors" } ], "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org", + "homepage": "https://twig.symfony.com", "keywords": [ "templating" ] @@ -2688,17 +2872,17 @@ }, { "name": "wyrihaximus/twig-view", - "version": "4.3.1", - "version_normalized": "4.3.1.0", + "version": "4.3.5", + "version_normalized": "4.3.5.0", "source": { "type": "git", "url": "https://github.com/WyriHaximus/TwigView.git", - "reference": "0bdce795bbf7f667209a9ed4a2d4b4db485e110c" + "reference": "ec2771e6a1fe799f9b16eff19da424cd04d593b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WyriHaximus/TwigView/zipball/0bdce795bbf7f667209a9ed4a2d4b4db485e110c", - "reference": "0bdce795bbf7f667209a9ed4a2d4b4db485e110c", + "url": "https://api.github.com/repos/WyriHaximus/TwigView/zipball/ec2771e6a1fe799f9b16eff19da424cd04d593b7", + "reference": "ec2771e6a1fe799f9b16eff19da424cd04d593b7", "shasum": "" }, "require": { @@ -2708,7 +2892,7 @@ "cakephp/cakephp": "^3.5", "jasny/twig-extensions": "^1.0", "php": "^5.6 || ^7.0", - "twig/twig": "^1.18", + "twig/twig": "^1.27", "umpirsky/twig-php-function": "0.1" }, "require-dev": { @@ -2719,7 +2903,7 @@ "squizlabs/php_codesniffer": "^1.5.6", "wyrihaximus/phpunit-class-reflection-helpers": "dev-master" }, - "time": "2018-01-28T22:18:29+00:00", + "time": "2018-07-03T15:46:29+00:00", "type": "cakephp-plugin", "installation-source": "dist", "autoload": { @@ -2748,17 +2932,17 @@ }, { "name": "zendframework/zend-diactoros", - "version": "1.8.1", - "version_normalized": "1.8.1.0", + "version": "1.8.6", + "version_normalized": "1.8.6.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-diactoros.git", - "reference": "63d920d1c9ebc009d860c3666593a66298727dd6" + "reference": "20da13beba0dde8fb648be3cc19765732790f46e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/63d920d1c9ebc009d860c3666593a66298727dd6", - "reference": "63d920d1c9ebc009d860c3666593a66298727dd6", + "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/20da13beba0dde8fb648be3cc19765732790f46e", + "reference": "20da13beba0dde8fb648be3cc19765732790f46e", "shasum": "" }, "require": { @@ -2771,10 +2955,11 @@ "require-dev": { "ext-dom": "*", "ext-libxml": "*", - "phpunit/phpunit": "^5.7.16 || ^6.0.8", + "php-http/psr7-integration-tests": "dev-master", + "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7", "zendframework/zend-coding-standard": "~1.0" }, - "time": "2018-07-09T21:17:27+00:00", + "time": "2018-09-05T19:29:37+00:00", "type": "library", "extra": { "branch-alias": { diff --git a/app/vendor/composer/xdebug-handler/CHANGELOG.md b/app/vendor/composer/xdebug-handler/CHANGELOG.md new file mode 100644 index 000000000..ac3893314 --- /dev/null +++ b/app/vendor/composer/xdebug-handler/CHANGELOG.md @@ -0,0 +1,46 @@ +## [Unreleased] + +## [1.3.0] - 2018-08-31 + * Added: `setPersistent` method to use environment variables for the restart. + * Fixed: improved debugging by writing output to stderr. + * Fixed: no restart when `php_ini_scanned_files` is not functional and is needed. + +## [1.2.1] - 2018-08-23 + * Fixed: fatal error with apc, when using `apc.mmap_file_mask`. + +## [1.2.0] - 2018-08-16 + * Added: debug information using `XDEBUG_HANDLER_DEBUG`. + * Added: fluent interface for setters. + * Added: `PhpConfig` helper class for calling PHP sub-processes. + * Added: `PHPRC` original value to restart stettings, for use in a restarted process. + * Changed: internal procedure to disable ini-scanning, using `-n` command-line option. + * Fixed: replaced `escapeshellarg` usage to avoid locale problems. + * Fixed: improved color-option handling to respect double-dash delimiter. + * Fixed: color-option handling regression from main script changes. + * Fixed: improved handling when checking main script. + * Fixed: handling for standard input, that never actually did anything. + * Fixed: fatal error when ctype extension is not available. + +## [1.1.0] - 2018-04-11 + * Added: `getRestartSettings` method for calling PHP processes in a restarted process. + * Added: API definition and @internal class annotations. + * Added: protected `requiresRestart` method for extending classes. + * Added: `setMainScript` method for applications that change the working directory. + * Changed: private `tmpIni` variable to protected for extending classes. + * Fixed: environment variables not available in $_SERVER when restored in the restart. + * Fixed: relative path problems caused by Phar::interceptFileFuncs. + * Fixed: incorrect handling when script file cannot be found. + +## [1.0.0] - 2018-03-08 + * Added: PSR3 logging for optional status output. + * Added: existing ini settings are merged to catch command-line overrides. + * Added: code, tests and other artefacts to decouple from Composer. + * Break: the following class was renamed: + - `Composer\XdebugHandler` -> `Composer\XdebugHandler\XdebugHandler` + +[Unreleased]: https://github.com/composer/xdebug-handler/compare/1.3.0...HEAD +[1.3.0]: https://github.com/composer/xdebug-handler/compare/1.2.1...1.3.0 +[1.2.1]: https://github.com/composer/xdebug-handler/compare/1.2.0...1.2.1 +[1.2.0]: https://github.com/composer/xdebug-handler/compare/1.1.0...1.2.0 +[1.1.0]: https://github.com/composer/xdebug-handler/compare/1.0.0...1.1.0 +[1.0.0]: https://github.com/composer/xdebug-handler/compare/d66f0d15cb57...1.0.0 diff --git a/app/vendor/seld/cli-prompt/LICENSE b/app/vendor/composer/xdebug-handler/LICENSE similarity index 87% rename from app/vendor/seld/cli-prompt/LICENSE rename to app/vendor/composer/xdebug-handler/LICENSE index c1b62a35f..963618a14 100644 --- a/app/vendor/seld/cli-prompt/LICENSE +++ b/app/vendor/composer/xdebug-handler/LICENSE @@ -1,11 +1,13 @@ -Copyright (c) 2015 Jordi Boggiano +MIT License + +Copyright (c) 2017 Composer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -15,5 +17,5 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/vendor/composer/xdebug-handler/README.md b/app/vendor/composer/xdebug-handler/README.md new file mode 100644 index 000000000..5d6648788 --- /dev/null +++ b/app/vendor/composer/xdebug-handler/README.md @@ -0,0 +1,280 @@ +# composer/xdebug-handler + +[![packagist](https://img.shields.io/packagist/v/composer/xdebug-handler.svg)](https://packagist.org/packages/composer/xdebug-handler) +[![linux build](https://img.shields.io/travis/composer/xdebug-handler/master.svg?label=linux+build)](https://travis-ci.org/composer/xdebug-handler) +[![windows build](https://img.shields.io/appveyor/ci/Seldaek/xdebug-handler/master.svg?label=windows+build)](https://ci.appveyor.com/project/Seldaek/xdebug-handler) +![license](https://img.shields.io/github/license/composer/xdebug-handler.svg) +![php](https://img.shields.io/packagist/php-v/composer/xdebug-handler.svg?colorB=8892BF&label=php) + +Restart a CLI process without loading the xdebug extension. + +Originally written as part of [composer/composer](https://github.com/composer/composer), +now extracted and made available as a stand-alone library. + +## Installation + +Install the latest version with: + +```bash +$ composer require composer/xdebug-handler +``` + +## Requirements + +* PHP 5.3.2 minimum, although functionality is disabled below PHP 5.4.0. Using the latest PHP version is highly recommended. + +## Basic Usage +```php +use Composer\XdebugHandler\XdebugHandler; + +$xdebug = new XdebugHandler('myapp'); +$xdebug->check(); +unset($xdebug); +``` + +The constructor takes two parameters: + +#### _$envPrefix_ +This is used to create distinct environment variables and is upper-cased and prepended to default base values. The above example enables the use of: + +- `MYAPP_ALLOW_XDEBUG=1` to override automatic restart and allow xdebug +- `MYAPP_ORIGINAL_INIS` to obtain ini file locations in a restarted process + +#### _$colorOption_ +This optional value is added to the restart command-line and is needed to force color output in a piped child process. Only long-options are supported, for example `--ansi` or `--colors=always` etc. + +If the original command-line contains an argument that pattern matches this value (for example `--no-ansi`, `--colors=never`) then _$colorOption_ is ignored. + +If the pattern match ends with `=auto` (for example `--colors=auto`), the argument is replaced by _$colorOption_. Otherwise it is added at either the end of the command-line, or preceeding the first double-dash `--` delimiter. + +## Advanced Usage + +* [How it works](#how-it-works) +* [Limitations](#limitations) +* [Helper methods](#helper-methods) +* [Setter methods](#setter-methods) +* [Process configuration](#process-configuration) +* [Troubleshooting](#troubleshooting) +* [Extending the library](#extending-the-library) + +### How it works + +A temporary ini file is created from the loaded (and scanned) ini files, with any references to the xdebug extension commented out. Current ini settings are merged, so that most ini settings made on the command-line or by the application are included (see [Limitations](#limitations)) + +* `MYAPP_ALLOW_XDEBUG` is set with internal data to flag and use in the restart. +* The command-line and environment are [configured](#process-configuration) for the restart. +* The application is restarted in a new process using `passthru`. + * The restart settings are stored in the environment. + * `MYAPP_ALLOW_XDEBUG` is unset. + * The application runs and exits. +* The main process exits with the exit code from the restarted process. + +### Limitations +There are a few things to be aware of when running inside a restarted process. + +* Extensions set on the command-line will not be loaded. +* Ini file locations will be reported as per the restart - see [getAllIniFiles()](#getallinifiles). +* Php sub-processes may be loaded with xdebug enabled - see [Process configuration](#process-configuration). + +### Helper methods +These static methods provide information from the current process, regardless of whether it has been restarted or not. + +#### _getAllIniFiles()_ +Returns an array of the original ini file locations. Use this instead of calling `php_ini_loaded_file` and `php_ini_scanned_files`, which will report the wrong values in a restarted process. + +```php +use Composer\XdebugHandler\XdebugHandler; + +$files = XdebugHandler::getAllIniFiles(); + +# $files[0] always exists, it could be an empty string +$loadedIni = array_shift($files); +$scannedInis = $files; +``` + +These locations are also available in the `MYAPP_ORIGINAL_INIS` environment variable. This is a path-separated string comprising the location returned from `php_ini_loaded_file`, which could be empty, followed by locations parsed from calling `php_ini_scanned_files`. + +#### _getRestartSettings()_ +Returns an array of settings that can be used with PHP [sub-processes](#sub-processes), or null if the process was not restarted. + +```php +use Composer\XdebugHandler\XdebugHandler; + +$settings = XdebugHandler::getRestartSettings(); +/** + * $settings: array (if the current process was restarted, + * or called with the settings from a previous restart), or null + * + * 'tmpIni' => the temporary ini file used in the restart (string) + * 'scannedInis' => if there were any scanned inis (bool) + * 'scanDir' => the original PHP_INI_SCAN_DIR value (false|string) + * 'phprc' => the original PHPRC value (false|string) + * 'inis' => the original inis from getAllIniFiles (array) + * 'skipped' => the skipped version from getSkippedVersion (string) + */ +``` + +#### _getSkippedVersion()_ +Returns the xdebug version string that was skipped by the restart, or an empty value if there was no restart (or xdebug is still loaded, perhaps by an extending class restarting for a reason other than removing xdebug). + +```php +use Composer\XdebugHandler\XdebugHandler; + +$version = XdebugHandler::getSkippedVersion(); +# $version: '2.6.0' (for example), or an empty string +``` + +### Setter methods +These methods implement a fluent interface and must be called before the main `check()` method. + +#### _setLogger($logger)_ +Enables the output of status messages to an external PSR3 logger. All messages are reported with either `DEBUG` or `WARNING` log levels. For example (showing the level and message): + +``` +// Restart overridden +DEBUG Checking MYAPP_ALLOW_XDEBUG +DEBUG The xdebug extension is loaded (2.5.0) +DEBUG No restart (MYAPP_ALLOW_XDEBUG=1) + +// Failed restart +DEBUG Checking MYAPP_ALLOW_XDEBUG +DEBUG The xdebug extension is loaded (2.5.0) +WARNING No restart (Unable to create temporary ini file) +``` + +Status messages can also be output with `XDEBUG_HANDLER_DEBUG`. See [Troubleshooting](#troubleshooting). + +#### _setMainScript($script)_ +Sets the location of the main script to run in the restart. This is only needed in more esoteric use-cases, or if the `argv[0]` location is inaccessible. The script name `--` is supported for standard input. + +#### _setPersistent()_ +Configures the restart using [persistent settings](#persistent-settings), so that xdebug is not loaded in any sub-process. + +Use this method if your application invokes one or more PHP sub-process and the xdebug extension is not needed. This avoids the overhead of implementing specific [sub-process](#sub-processes) strategies. + +Alternatively, this method can be used to set up a _default_ xdebug-free environment which can be changed if a sub-process requires xdebug, then restored afterwards: + +```php +function SubProcessWithXdebug() +{ + $phpConfig = new Composer\XdebugHandler\PhpConfig(); + + # Set the environment to the original configuration + $phpConfig->useOriginal(); + + # run the process with xdebug loaded + ... + + # Restore xdebug-free environment + $phpConfig->usePersistent(); +} +``` + +### Process configuration +The library offers two strategies to invoke a new PHP process without loading xdebug, using either _standard_ or _persistent_ settings. Note that this is only important if the application calls a PHP sub-process. + +#### Standard settings +Uses command-line options to remove xdebug from the new process only. + +* The -n option is added to the command-line. This tells PHP not to scan for additional inis. +* The temporary ini is added to the command-line with the -c option. + +>_If the new process calls a PHP sub-process, xdebug will be loaded in that sub-process (unless it implements xdebug-handler, in which case there will be another restart)._ + +This is the default strategy used in the restart. + +#### Persistent settings +Uses environment variables to remove xdebug from the new process and persist these settings to any sub-process. + +* `PHP_INI_SCAN_DIR` is set to an empty string. This tells PHP not to scan for additional inis. +* `PHPRC` is set to the temporary ini. + +>_If the new process calls a PHP sub-process, xdebug will not be loaded in that sub-process._ + +This strategy can be used in the restart by calling [setPersistent()](#setpersistent). + +#### Sub-processes +The `PhpConfig` helper class makes it easy to invoke a PHP sub-process (with or without xdebug loaded), regardless of whether there has been a restart. + +Each of its methods returns an array of PHP options (to add to the command-line) and sets up the environment for the required strategy. The [getRestartSettings()](#getrestartsettings) method is used internally. + +* `useOriginal()` - xdebug will be loaded in the new process. +* `useStandard()` - xdebug will **not** be loaded in the new process - see [standard settings](#standard-settings). +* `userPersistent()` - xdebug will **not** be loaded in the new process - see [persistent settings](#persistent-settings) + +If there was no restart, an empty options array is returned and the environment is not changed. + +```php +use Composer\XdebugHandler\PhpConfig; + +$config = new PhpConfig; + +$options = $config->useOriginal(); +# $options: empty array +# environment: PHPRC and PHP_INI_SCAN_DIR set to original values + +$options = $config->useStandard(); +# $options: [-n, -c, tmpIni] +# environment: PHPRC and PHP_INI_SCAN_DIR set to original values + +$options = $config->usePersistent(); +# $options: empty array +# environment: PHPRC=tmpIni, PHP_INI_SCAN_DIR='' +``` + +### Troubleshooting +The following environment settings can be used to troubleshoot unexpected behavior: + +* `XDEBUG_HANDLER_DEBUG=1` Outputs status messages to `STDERR`, if it is defined, irrespective of any PSR3 logger. Each message is prefixed `xdebug-handler[pid]`, where pid is the process identifier. + +* `XDEBUG_HANDLER_DEBUG=2` As above, but additionally saves the temporary ini file and reports its location in a status message. + +### Extending the library +The API is defined by classes and their accessible elements that are not annotated as @internal. The main class has two protected methods that can be overridden to provide additional functionality: + +#### _requiresRestart($isLoaded)_ +By default the process will restart if xdebug is loaded. Extending this method allows an application to decide, by returning a boolean (or equivalent) value. It is only called if `MYAPP_ALLOW_XDEBUG` is empty, so it will not be called in the restarted process (where this variable contains internal data), or if the restart has been overridden. + +Note that the [setMainScript()](#setmainscriptscript) and [setPersistent()](#setpersistent) setters can be used here, if required. + +#### _restart($command)_ +An application can extend this to modify the temporary ini file, its location given in the `tmpIni` property. Remember to finish with `parent::restart($command)`. + +Note that the `$command` parameter is the escaped command-line string that will be used for the new process and must be treated accordingly. + +#### Example +This either forces a restart if `phar.readonly` is set (even when xdebug is not loaded) and unsets it in the temporary ini file for the new process, or skips the restart if a help command has been called. + +```php +use Composer\XdebugHandler\XdebugHandler; +use MyApp\Command; + +class MyRestarter extends XdebugHandler +{ + private $required; + + protected function requiresRestart($isLoaded) + { + if (Command::isHelp()) { + return false; + } + + $this->required = (bool) ini_get('phar.readonly'); + return $isLoaded || $this->required; + } + + protected function restart($command) + { + if ($this->required) { + $content = file_get_contents($this->tmpIni); + $content .= 'phar.readonly=0'.PHP_EOL; + file_put_contents($this->tmpIni, $content); + } + + parent::restart($command); + } +} +``` + +## License +composer/xdebug-handler is licensed under the MIT License, see the LICENSE file for details. diff --git a/app/vendor/composer/xdebug-handler/composer.json b/app/vendor/composer/xdebug-handler/composer.json new file mode 100644 index 000000000..b93de4d5d --- /dev/null +++ b/app/vendor/composer/xdebug-handler/composer.json @@ -0,0 +1,40 @@ +{ + "name": "composer/xdebug-handler", + "description": "Restarts a process without xdebug.", + "type": "library", + "license": "MIT", + "keywords": [ + "xdebug", + "performance" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Composer\\XdebugHandler\\": "tests" + } + }, + "scripts": { + "test": "phpunit" + } +} diff --git a/app/vendor/composer/xdebug-handler/src/PhpConfig.php b/app/vendor/composer/xdebug-handler/src/PhpConfig.php new file mode 100644 index 000000000..5535eca56 --- /dev/null +++ b/app/vendor/composer/xdebug-handler/src/PhpConfig.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\XdebugHandler; + +/** + * @author John Stevenson + */ +class PhpConfig +{ + /** + * Use the original PHP configuration + * + * @return array PHP cli options + */ + public function useOriginal() + { + $this->getDataAndReset(); + return array(); + } + + /** + * Use standard restart settings + * + * @return array PHP cli options + */ + public function useStandard() + { + if ($data = $this->getDataAndReset()) { + return array('-n', '-c', $data['tmpIni']); + } + + return array(); + } + + /** + * Use environment variables to persist settings + * + * @return array PHP cli options + */ + public function usePersistent() + { + if ($data = $this->getDataAndReset()) { + Process::setEnv('PHPRC', $data['tmpIni']); + Process::setEnv('PHP_INI_SCAN_DIR', ''); + } + + return array(); + } + + /** + * Returns restart data if available and resets the environment + * + * @return array|null + */ + private function getDataAndReset() + { + if ($data = XdebugHandler::getRestartSettings()) { + Process::setEnv('PHPRC', $data['phprc']); + Process::setEnv('PHP_INI_SCAN_DIR', $data['scanDir']); + } + + return $data; + } +} diff --git a/app/vendor/composer/xdebug-handler/src/Process.php b/app/vendor/composer/xdebug-handler/src/Process.php new file mode 100644 index 000000000..5ce877baa --- /dev/null +++ b/app/vendor/composer/xdebug-handler/src/Process.php @@ -0,0 +1,160 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\XdebugHandler; + +/** + * Provides utility functions to prepare a child process command-line and set + * environment variables in that process. + * + * @author John Stevenson + * @internal + */ +class Process +{ + /** + * Returns an array of parameters, including a color option if required + * + * A color option is needed because child process output is piped. + * + * @param array $args The script parameters + * @param string $colorOption The long option to force color output + * + * @return array + */ + public static function addColorOption(array $args, $colorOption) + { + if (!$colorOption + || in_array($colorOption, $args) + || !preg_match('/^--([a-z]+$)|(^--[a-z]+=)/', $colorOption, $matches)) { + return $args; + } + + if (isset($matches[2])) { + // Handle --color(s)= options + if (false !== ($index = array_search($matches[2].'auto', $args))) { + $args[$index] = $colorOption; + return $args; + } elseif (preg_grep('/^'.$matches[2].'/', $args)) { + return $args; + } + } elseif (in_array('--no-'.$matches[1], $args)) { + return $args; + } + + if (false !== ($index = array_search('--', $args))) { + // Position option before double-dash delimiter + array_splice($args, $index, 0, $colorOption); + } else { + $args[] = $colorOption; + } + + return $args; + } + + /** + * Escapes a string to be used as a shell argument. + * + * From https://github.com/johnstevenson/winbox-args + * MIT Licensed (c) John Stevenson + * + * @param string $arg The argument to be escaped + * @param bool $meta Additionally escape cmd.exe meta characters + * @param bool $module The argument is the module to invoke + * + * @return string The escaped argument + */ + public static function escape($arg, $meta = true, $module = false) + { + if (!defined('PHP_WINDOWS_VERSION_BUILD')) { + return "'".str_replace("'", "'\\''", $arg)."'"; + } + + $quote = strpbrk($arg, " \t") !== false || $arg === ''; + + $arg = preg_replace('/(\\\\*)"/', '$1$1\\"', $arg, -1, $dquotes); + + if ($meta) { + $meta = $dquotes || preg_match('/%[^%]+%/', $arg); + + if (!$meta) { + $quote = $quote || strpbrk($arg, '^&|<>()') !== false; + } elseif ($module && !$dquotes && $quote) { + $meta = false; + } + } + + if ($quote) { + $arg = '"'.preg_replace('/(\\\\*)$/', '$1$1', $arg).'"'; + } + + if ($meta) { + $arg = preg_replace('/(["^&|<>()%])/', '^$1', $arg); + } + + return $arg; + } + + /** + * Returns true if the output stream supports colors + * + * This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo + * terminals via named pipes, so we can only check the environment. + * + * @param mixed $output A valid CLI output stream + * + * @return bool + */ + public static function supportsColor($output) + { + if (defined('PHP_WINDOWS_VERSION_BUILD')) { + return (function_exists('sapi_windows_vt100_support') + && sapi_windows_vt100_support($output)) + || false !== getenv('ANSICON') + || 'ON' === getenv('ConEmuANSI') + || 'xterm' === getenv('TERM'); + } + + if (function_exists('stream_isatty')) { + return stream_isatty($output); + } elseif (function_exists('posix_isatty')) { + return posix_isatty($output); + } + + $stat = fstat($output); + // Check if formatted mode is S_IFCHR + return $stat ? 0020000 === ($stat['mode'] & 0170000) : false; + } + + /** + * Makes putenv environment changes available in $_SERVER + * + * @param string $name + * @param string|false $value A false value unsets the variable + * + * @return bool Whether the environment variable was set + */ + public static function setEnv($name, $value = false) + { + $unset = false === $value; + + if (!putenv($unset ? $name : $name.'='.$value)) { + return false; + } + + if ($unset) { + unset($_SERVER[$name]); + } else { + $_SERVER[$name] = $value; + } + return true; + } +} diff --git a/app/vendor/composer/xdebug-handler/src/Status.php b/app/vendor/composer/xdebug-handler/src/Status.php new file mode 100644 index 000000000..24002777a --- /dev/null +++ b/app/vendor/composer/xdebug-handler/src/Status.php @@ -0,0 +1,163 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\XdebugHandler; + +use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; + +/** + * @author John Stevenson + * @internal + */ +class Status +{ + const ENV_RESTART = 'XDEBUG_HANDLER_RESTART'; + const CHECK = 'Check'; + const ERROR = 'Error'; + const INFO = 'Info'; + const NORESTART = 'NoRestart'; + const RESTART = 'Restart'; + const RESTARTING = 'Restarting'; + const RESTARTED = 'Restarted'; + + private $debug; + private $envAllowXdebug; + private $loaded; + private $logger; + private $time; + + /** + * Constructor + * + * @param string $envAllowXdebug Prefixed _ALLOW_XDEBUG name + * @param bool $debug Whether debug output is required + */ + public function __construct($envAllowXdebug, $debug) + { + $start = getenv(self::ENV_RESTART); + Process::setEnv(self::ENV_RESTART); + $this->time = $start ? round((microtime(true) - $start) * 1000) : 0; + + $this->envAllowXdebug = $envAllowXdebug; + $this->debug = $debug && defined('STDERR'); + } + + /** + * @param LoggerInterface $logger + */ + public function setLogger(LoggerInterface $logger) + { + $this->logger = $logger; + } + + /** + * Calls a handler method to report a message + * + * @param string $op The handler constant + * @param null|string $data Data required by the handler + */ + public function report($op, $data) + { + if ($this->logger || $this->debug) { + call_user_func(array($this, 'report'.$op), $data); + } + } + + /** + * Outputs a status message + * + * @param string $text + * @param string $level + */ + private function output($text, $level = null) + { + if ($this->logger) { + $this->logger->log($level ?: LogLevel::DEBUG, $text); + } + + if ($this->debug) { + fwrite(STDERR, sprintf('xdebug-handler[%d] %s', getmypid(), $text.PHP_EOL)); + } + } + + private function reportCheck($loaded) + { + $this->loaded = $loaded; + $this->output('Checking '.$this->envAllowXdebug); + } + + private function reportError($error) + { + $this->output(sprintf('No restart (%s)', $error), LogLevel::WARNING); + } + + private function reportInfo($info) + { + $this->output($info); + } + + private function reportNoRestart() + { + $this->output($this->getLoadedMessage()); + + if ($this->loaded) { + $text = sprintf('No restart (%s)', $this->getEnvAllow()); + if (!getenv($this->envAllowXdebug)) { + $text .= ' Allowed by application'; + } + $this->output($text); + } + } + + private function reportRestart() + { + $this->output($this->getLoadedMessage()); + Process::setEnv(self::ENV_RESTART, (string) microtime(true)); + } + + private function reportRestarted() + { + $loaded = $this->getLoadedMessage(); + $text = sprintf('Restarted (%d ms). %s', $this->time, $loaded); + $level = $this->loaded ? LogLevel::WARNING : null; + $this->output($text, $level); + } + + private function reportRestarting($command) + { + $text = sprintf('Process restarting (%s)', $this->getEnvAllow()); + $this->output($text); + $text = 'Running '.$command; + $this->output($text); + } + + /** + * Returns the _ALLOW_XDEBUG environment variable as name=value + * + * @return string + */ + private function getEnvAllow() + { + return $this->envAllowXdebug.'='.getenv($this->envAllowXdebug); + } + + /** + * Returns the xdebug status and version + * + * @return string + */ + private function getLoadedMessage() + { + $loaded = $this->loaded ? sprintf('loaded (%s)', $this->loaded) : 'not loaded'; + return 'The xdebug extension is '.$loaded; + } +} diff --git a/app/vendor/composer/xdebug-handler/src/XdebugHandler.php b/app/vendor/composer/xdebug-handler/src/XdebugHandler.php new file mode 100644 index 000000000..c91152df0 --- /dev/null +++ b/app/vendor/composer/xdebug-handler/src/XdebugHandler.php @@ -0,0 +1,531 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +namespace Composer\XdebugHandler; + +use Psr\Log\LoggerInterface; + +/** + * @author John Stevenson + */ +class XdebugHandler +{ + const SUFFIX_ALLOW = '_ALLOW_XDEBUG'; + const SUFFIX_INIS = '_ORIGINAL_INIS'; + const RESTART_ID = 'internal'; + const RESTART_SETTINGS = 'XDEBUG_HANDLER_SETTINGS'; + const DEBUG = 'XDEBUG_HANDLER_DEBUG'; + + /** @var string|null */ + protected $tmpIni; + + private static $inRestart; + private static $name; + private static $skipped; + + private $cli; + private $colorOption; + private $debug; + private $envAllowXdebug; + private $envOriginalInis; + private $loaded; + private $persistent; + private $script; + /** @var Status|null */ + private $statusWriter; + + /** + * Constructor + * + * The $envPrefix is used to create distinct environment variables. It is + * uppercased and prepended to the default base values. For example 'myapp' + * would result in MYAPP_ALLOW_XDEBUG and MYAPP_ORIGINAL_INIS. + * + * @param string $envPrefix Value used in environment variables + * @param string $colorOption Command-line long option to force color output + * @throws \RuntimeException If a parameter is invalid + */ + public function __construct($envPrefix, $colorOption = '') + { + if (!is_string($envPrefix) || empty($envPrefix) || !is_string($colorOption)) { + throw new \RuntimeException('Invalid constructor parameter'); + } + + self::$name = strtoupper($envPrefix); + $this->envAllowXdebug = self::$name.self::SUFFIX_ALLOW; + $this->envOriginalInis = self::$name.self::SUFFIX_INIS; + + $this->colorOption = $colorOption; + + if (extension_loaded('xdebug')) { + $ext = new \ReflectionExtension('xdebug'); + $this->loaded = $ext->getVersion() ?: 'unknown'; + } + + if ($this->cli = PHP_SAPI === 'cli') { + $this->debug = getenv(self::DEBUG); + } + + $this->statusWriter = new Status($this->envAllowXdebug, (bool) $this->debug); + } + + /** + * Activates status message output to a PSR3 logger + * + * @param LoggerInterface $logger + * + * @return $this + */ + public function setLogger(LoggerInterface $logger) + { + $this->statusWriter->setLogger($logger); + return $this; + } + + /** + * Sets the main script location if it cannot be called from argv + * + * @param string $script + * + * @return $this + */ + public function setMainScript($script) + { + $this->script = $script; + return $this; + } + + /** + * Persist the settings to keep xdebug out of sub-processes + * + * @return $this + */ + public function setPersistent() + { + $this->persistent = true; + return $this; + } + + /** + * Checks if xdebug is loaded and the process needs to be restarted + * + * This behaviour can be disabled by setting the MYAPP_ALLOW_XDEBUG + * environment variable to 1. This variable is used internally so that + * restarted process is created only once. + */ + public function check() + { + $this->notify(Status::CHECK, $this->loaded); + $envArgs = explode('|', (string) getenv($this->envAllowXdebug)); + + if (empty($envArgs[0]) && $this->requiresRestart((bool) $this->loaded)) { + // Restart required + $this->notify(Status::RESTART); + + if ($this->prepareRestart()) { + $command = $this->getCommand(); + $this->notify(Status::RESTARTING, $command); + $this->restart($command); + } + return; + } + + if (self::RESTART_ID === $envArgs[0] && count($envArgs) === 5) { + // Restarting, so unset environment variable and use saved values + $this->notify(Status::RESTARTED); + + Process::setEnv($this->envAllowXdebug); + self::$inRestart = true; + + if (!$this->loaded) { + // Skipped version is only set if xdebug is not loaded + self::$skipped = $envArgs[1]; + } + + // Put restart settings in the environment + $this->setEnvRestartSettings($envArgs); + return; + } + + $this->notify(Status::NORESTART); + + if ($settings = self::getRestartSettings()) { + // Called with existing settings, so sync our settings + $this->syncSettings($settings); + } + } + + /** + * Returns an array of php.ini locations with at least one entry + * + * The equivalent of calling php_ini_loaded_file then php_ini_scanned_files. + * The loaded ini location is the first entry and may be empty. + * + * @return array + */ + public static function getAllIniFiles() + { + if (!empty(self::$name)) { + $env = getenv(self::$name.self::SUFFIX_INIS); + + if (false !== $env) { + return explode(PATH_SEPARATOR, $env); + } + } + + $paths = array((string) php_ini_loaded_file()); + + if ($scanned = php_ini_scanned_files()) { + $paths = array_merge($paths, array_map('trim', explode(',', $scanned))); + } + + return $paths; + } + + /** + * Returns an array of restart settings or null + * + * Settings will be available if the current process was restarted, or + * called with the settings from an existing restart. + * + * @return array|null + */ + public static function getRestartSettings() + { + $envArgs = explode('|', (string) getenv(self::RESTART_SETTINGS)); + + if (count($envArgs) !== 6 + || (!self::$inRestart && php_ini_loaded_file() !== $envArgs[0])) { + return; + } + + return array( + 'tmpIni' => $envArgs[0], + 'scannedInis' => (bool) $envArgs[1], + 'scanDir' => '*' === $envArgs[2] ? false : $envArgs[2], + 'phprc' => '*' === $envArgs[3] ? false : $envArgs[3], + 'inis' => explode(PATH_SEPARATOR, $envArgs[4]), + 'skipped' => $envArgs[5], + ); + } + + /** + * Returns the xdebug version that triggered a successful restart + * + * @return string + */ + public static function getSkippedVersion() + { + return (string) self::$skipped; + } + + /** + * Returns true if xdebug is loaded, or as directed by an extending class + * + * @param bool $isLoaded Whether xdebug is loaded + * + * @return bool + */ + protected function requiresRestart($isLoaded) + { + return $isLoaded; + } + + /** + * Allows an extending class to access the tmpIni + * + * @param string $command + */ + protected function restart($command) + { + $this->doRestart($command); + } + + /** + * Executes the restarted command then deletes the tmp ini + * + * @param string $command + */ + private function doRestart($command) + { + passthru($command, $exitCode); + $this->notify(Status::INFO, 'Restarted process exited '.$exitCode); + + if ($this->debug === '2') { + $this->notify(Status::INFO, 'Temp ini saved: '.$this->tmpIni); + } else { + @unlink($this->tmpIni); + } + + exit($exitCode); + } + + /** + * Returns true if everything was written for the restart + * + * If any of the following fails (however unlikely) we must return false to + * stop potential recursion: + * - tmp ini file creation + * - environment variable creation + * + * @return bool + */ + private function prepareRestart() + { + $error = ''; + $iniFiles = self::getAllIniFiles(); + $scannedInis = count($iniFiles) > 1; + + if (!$this->cli) { + $error = 'Unsupported SAPI: '.PHP_SAPI; + } elseif (!defined('PHP_BINARY')) { + $error = 'PHP version is too old: '.PHP_VERSION; + } elseif (!$this->checkScanDirConfig()) { + $error = 'PHP version does not report scanned inis: '.PHP_VERSION; + } elseif (!$this->checkMainScript()) { + $error = 'Unable to access main script: '.$this->script; + } elseif (!$this->writeTmpIni($iniFiles)) { + $error = 'Unable to create temporary ini file'; + } elseif (!$this->setEnvironment($scannedInis, $iniFiles)) { + $error = 'Unable to set environment variables'; + } + + if ($error) { + $this->notify(Status::ERROR, $error); + } + + return empty($error); + } + + /** + * Returns true if the tmp ini file was written + * + * @param array $iniFiles All ini files used in the current process + * + * @return bool + */ + private function writeTmpIni(array $iniFiles) + { + if (!$this->tmpIni = tempnam(sys_get_temp_dir(), '')) { + return false; + } + + // $iniFiles has at least one item and it may be empty + if (empty($iniFiles[0])) { + array_shift($iniFiles); + } + + $content = ''; + $regex = '/^\s*(zend_extension\s*=.*xdebug.*)$/mi'; + + foreach ($iniFiles as $file) { + $data = preg_replace($regex, ';$1', file_get_contents($file)); + $content .= $data.PHP_EOL; + } + + // Merge loaded settings into our ini content, if it is valid + if ($config = parse_ini_string($content)) { + $loaded = ini_get_all(null, false); + $content .= $this->mergeLoadedConfig($loaded, $config); + } + + // Work-around for https://bugs.php.net/bug.php?id=75932 + $content .= 'opcache.enable_cli=0'.PHP_EOL; + + return @file_put_contents($this->tmpIni, $content); + } + + /** + * Returns the restart command line + * + * @return string + */ + private function getCommand() + { + $php = array(PHP_BINARY); + $args = array_slice($_SERVER['argv'], 1); + + if (!$this->persistent) { + // Use command-line options + array_push($php, '-n', '-c', $this->tmpIni); + } + + if (defined('STDOUT') && Process::supportsColor(STDOUT)) { + $args = Process::addColorOption($args, $this->colorOption); + } + + $args = array_merge($php, array($this->script), $args); + + $cmd = Process::escape(array_shift($args), true, true); + foreach ($args as $arg) { + $cmd .= ' '.Process::escape($arg); + } + + return $cmd; + } + + /** + * Returns true if the restart environment variables were set + * + * No need to update $_SERVER since this is set in the restarted process. + * + * @param bool $scannedInis Whether there were scanned ini files + * @param array $iniFiles All ini files used in the current process + * + * @return bool + */ + private function setEnvironment($scannedInis, array $iniFiles) + { + $scanDir = getenv('PHP_INI_SCAN_DIR'); + $phprc = getenv('PHPRC'); + + // Make original inis available to restarted process + if (!putenv($this->envOriginalInis.'='.implode(PATH_SEPARATOR, $iniFiles))) { + return false; + } + + if ($this->persistent) { + // Use the environment to persist the settings + if (!putenv('PHP_INI_SCAN_DIR=') || !putenv('PHPRC='.$this->tmpIni)) { + return false; + } + } + + // Flag restarted process and save values for it to use + $envArgs = array( + self::RESTART_ID, + $this->loaded, + (int) $scannedInis, + false === $scanDir ? '*' : $scanDir, + false === $phprc ? '*' : $phprc, + ); + + return putenv($this->envAllowXdebug.'='.implode('|', $envArgs)); + } + + /** + * Logs status messages + * + * @param string $op Status handler constant + * @param null|string $data Optional data + */ + private function notify($op, $data = null) + { + $this->statusWriter->report($op, $data); + } + + /** + * Returns default, changed and command-line ini settings + * + * @param array $loadedConfig All current ini settings + * @param array $iniConfig Settings from user ini files + * + * @return string + */ + private function mergeLoadedConfig(array $loadedConfig, array $iniConfig) + { + $content = ''; + + foreach ($loadedConfig as $name => $value) { + // Value will either be null, string or array (HHVM only) + if (!is_string($value) + || strpos($name, 'xdebug') === 0 + || $name === 'apc.mmap_file_mask') { + continue; + } + + if (!isset($iniConfig[$name]) || $iniConfig[$name] !== $value) { + // Double-quote escape each value + $content .= $name.'="'.addcslashes($value, '\\"').'"'.PHP_EOL; + } + } + + return $content; + } + + /** + * Returns true if the script name can be used + * + * @return bool + */ + private function checkMainScript() + { + if (null !== $this->script) { + // Allow an application to set -- for standard input + return file_exists($this->script) || '--' === $this->script; + } + + if (file_exists($this->script = $_SERVER['argv'][0])) { + return true; + } + + // Use a backtrace to resolve Phar and chdir issues + $options = PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : false; + $trace = debug_backtrace($options); + + if (($main = end($trace)) && isset($main['file'])) { + return file_exists($this->script = $main['file']); + } + + return false; + } + + /** + * Adds restart settings to the environment + * + * @param string $envArgs + */ + private function setEnvRestartSettings($envArgs) + { + $settings = array( + php_ini_loaded_file(), + $envArgs[2], + $envArgs[3], + $envArgs[4], + getenv($this->envOriginalInis), + self::$skipped, + ); + + Process::setEnv(self::RESTART_SETTINGS, implode('|', $settings)); + } + + /** + * Syncs settings and the environment if called with existing settings + * + * @param array $settings + */ + private function syncSettings(array $settings) + { + if (false === getenv($this->envOriginalInis)) { + // Called by another app, so make original inis available + Process::setEnv($this->envOriginalInis, implode(PATH_SEPARATOR, $settings['inis'])); + } + + self::$skipped = $settings['skipped']; + $this->notify(Status::INFO, 'Process called with existing restart settings'); + } + + /** + * Returns true if there are scanned inis and PHP is able to report them + * + * php_ini_scanned_files will fail when PHP_CONFIG_FILE_SCAN_DIR is empty. + * Fixed in 7.1.13 and 7.2.1 + * + * @return bool + */ + private function checkScanDirConfig() + { + return !(getenv('PHP_INI_SCAN_DIR') + && !PHP_CONFIG_FILE_SCAN_DIR + && (PHP_VERSION_ID < 70113 + || PHP_VERSION_ID === 70200)); + } +} diff --git a/app/vendor/symfony/polyfill-php72/LICENSE b/app/vendor/doctrine/cache/LICENSE similarity index 59% rename from app/vendor/symfony/polyfill-php72/LICENSE rename to app/vendor/doctrine/cache/LICENSE index 24fa32c2e..8c38cc1bc 100644 --- a/app/vendor/symfony/polyfill-php72/LICENSE +++ b/app/vendor/doctrine/cache/LICENSE @@ -1,11 +1,11 @@ -Copyright (c) 2015-2018 Fabien Potencier +Copyright (c) 2006-2015 Doctrine Project -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. @@ -15,5 +15,5 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/vendor/doctrine/cache/README.md b/app/vendor/doctrine/cache/README.md new file mode 100644 index 000000000..9d35e9348 --- /dev/null +++ b/app/vendor/doctrine/cache/README.md @@ -0,0 +1,10 @@ +# Doctrine Cache + +[![Build Status](https://img.shields.io/travis/doctrine/cache/master.svg?style=flat-square)](http://travis-ci.org/doctrine/cache) +[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/doctrine/cache/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/doctrine/cache/?branch=master) +[![Code Coverage](https://img.shields.io/scrutinizer/coverage/g/doctrine/cache/master.svg?style=flat-square)](https://scrutinizer-ci.com/g/doctrine/cache/?branch=master) + +[![Latest Stable Version](https://img.shields.io/packagist/v/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache) +[![Total Downloads](https://img.shields.io/packagist/dt/doctrine/cache.svg?style=flat-square)](https://packagist.org/packages/doctrine/cache) + +Cache component extracted from the Doctrine Common project. [Documentation](http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/reference/caching.html) diff --git a/app/vendor/doctrine/cache/UPGRADE.md b/app/vendor/doctrine/cache/UPGRADE.md new file mode 100644 index 000000000..e1f8a503e --- /dev/null +++ b/app/vendor/doctrine/cache/UPGRADE.md @@ -0,0 +1,16 @@ +# Upgrade to 1.4 + +## Minor BC Break: `Doctrine\Common\Cache\FileCache#$extension` is now `private`. + +If you need to override the value of `Doctrine\Common\Cache\FileCache#$extension`, then use the +second parameter of `Doctrine\Common\Cache\FileCache#__construct()` instead of overriding +the property in your own implementation. + +## Minor BC Break: file based caches paths changed + +`Doctrine\Common\Cache\FileCache`, `Doctrine\Common\Cache\PhpFileCache` and +`Doctrine\Common\Cache\FilesystemCache` are using a different cache paths structure. + +If you rely on warmed up caches for deployments, consider that caches generated +with `doctrine/cache` `<1.4` are not compatible with the new directory structure, +and will be ignored. diff --git a/app/vendor/doctrine/cache/composer.json b/app/vendor/doctrine/cache/composer.json new file mode 100644 index 000000000..2ee5d25bf --- /dev/null +++ b/app/vendor/doctrine/cache/composer.json @@ -0,0 +1,42 @@ +{ + "name": "doctrine/cache", + "type": "library", + "description": "Caching library offering an object-oriented API for many cache backends", + "keywords": ["cache", "caching"], + "homepage": "https://www.doctrine-project.org", + "license": "MIT", + "authors": [ + {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, + {"name": "Roman Borschel", "email": "roman@code-factory.org"}, + {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, + {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, + {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} + ], + "require": { + "php": "~7.1" + }, + "require-dev": { + "alcaeus/mongo-php-adapter": "^1.1", + "mongodb/mongodb": "^1.1", + "phpunit/phpunit": "^7.0", + "predis/predis": "~1.0", + "doctrine/coding-standard": "^4.0" + }, + "suggest": { + "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "autoload": { + "psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" } + }, + "autoload-dev": { + "psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" } + }, + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + } +} diff --git a/app/vendor/doctrine/cache/docs/en/index.rst b/app/vendor/doctrine/cache/docs/en/index.rst new file mode 100644 index 000000000..f08ab41ef --- /dev/null +++ b/app/vendor/doctrine/cache/docs/en/index.rst @@ -0,0 +1,274 @@ +Introduction +============ + +Doctrine Cache is a library that provides an interface for caching data. +It comes with implementations for some of the most popular caching data +stores. Here is what the ``Cache`` interface looks like. + +.. code-block:: php + namespace Doctrine\Common\Cache; + + interface Cache + { + public function fetch($id); + public function contains($id); + public function save($id, $data, $lifeTime = 0); + public function delete($id); + public function getStats(); + } + +Here is an example that uses Memcache. + +.. code-block:: php + use Doctrine\Common\Cache\MemcacheCache; + + $memcache = new Memcache(); + $cache = new MemcacheCache(); + $cache->setMemcache($memcache); + + $cache->set('key', 'value'); + + echo $cache->get('key') // prints "value" + +Drivers +======= + +Doctrine ships with several common drivers that you can easily use. +Below you can find information about all the available drivers. + +ApcCache +-------- + +The ``ApcCache`` driver uses the ``apc_fetch``, ``apc_exists``, etc. functions that come +with PHP so no additional setup is required in order to use it. + +.. code-block:: php + $cache = new ApcCache(); + +ApcuCache +--------- + +The ``ApcuCache`` driver uses the ``apcu_fetch``, ``apcu_exists``, etc. functions that come +with PHP so no additional setup is required in order to use it. + +.. code-block:: php + $cache = new ApcuCache(); + +ArrayCache +---------- + +The ``ArrayCache`` driver stores the cache data in PHPs memory and is not persisted anywhere. +This can be useful for caching things in memory for a single process when you don't need +the cache to be persistent across processes. + +.. code-block:: php + $cache = new ArrayCache(); + +ChainCache +---------- + +The ``ChainCache`` driver lets you chain multiple other drivers together easily. + +.. code-block:: php + $arrayCache = new ArrayCache(); + $apcuCache = new ApcuCache(); + + $cache = new ChainCache([$arrayCache, $apcuCache]); + +CouchbaseBucketCache +-------------------- + +The ``CouchbaseBucketCache`` driver uses Couchbase to store the cache data. + +.. code-block:: php + $bucketName = 'bucket-name'; + + $authenticator = new Couchbase\PasswordAuthenticator(); + $authenticator->username('username')->password('password'); + + $cluster = new CouchbaseCluster('couchbase://127.0.0.1'); + + $cluster->authenticate($authenticator); + $bucket = $cluster->openBucket($bucketName); + + $cache = new CouchbaseBucketCache($bucket); + +FilesystemCache +--------------- + +The ``FilesystemCache`` driver stores the cache data on the local filesystem. + +.. code-block:: php + $cache = new FilesystemCache('/path/to/cache/directory'); + +MemecacheCache +-------------- + +The ``MemcacheCache`` drivers stores the cache data in Memcache. + +.. code-block:: php + $memcache = new Memcache(); + $memcache->connect('localhost', 11211); + + $cache = new MemcacheCache(); + $cache->setMemcache($memcache); + +MemcachedCache +-------------- + +The ``MemcachedCache`` drivers stores the cache data in Memcached. + +.. code-block:: php + $memcached = new Memcached(); + + $cache = new MemcachedCache(); + $cache->setMemcached($memcached); + +MongoDBCache +------------ + +The ``MongoDBCache`` drivers stores the cache data in a MongoDB collection. + +.. code-block:: php + $manager = new MongoDB\Driver\Manager("mongodb://localhost:27017"); + + $collection = new MongoDB\Collection($manager, 'database_name', 'collection_name'); + + $cache = new MongoDBCache($collection); + +PhpFileCache +------------ + +The ``PhpFileCache`` driver stores the cache data on the local filesystem like the +``FilesystemCache`` driver except the data is serialized using the ``serialize()`` +and ``unserialize()`` functions available in PHP. The files are included so this means +that the data can be cached in PHPs opcache. + +.. code-block:: php + $cache = new PhpFileCache('/path/to/cache/directory'); + +PredisCache +----------- + +The ``PredisCache`` driver stores the cache data in Redis +and depends on the ``predis/predis`` package which can be installed with composer. + +.. code-block:: bash + $ composer require predis/predis + +Then you can use the ``Predis\Client`` class to pass to the ``PredisCache`` class. + +.. code-block:: php + $client = new Predis\Client(); + + $cache = new PredisCache($client); + +RedisCache +---------- + +The ``RedisCache`` driver stores the cache data in Redis and depends on the +``phpredis`` extension which can be found `here `_. + +.. code-block:: php + $redis = new Redis(); + + $cache = new RedisCache($redis); + +RiakCache +--------- + +The ``RiakCache`` driver stores the cache data in Riak and depends on the +``riak`` extension which can be found `here `_. + +.. code-block:: php + $connection = new Riak\Connection('localhost', 8087); + + $bucket = new Riak\Bucket($connection, 'bucket_name'); + + $cache = new RiakCache($bucket); + +SQLite3Cache +------------ + +The ``SQLite3Cache`` driver stores the cache data in a SQLite database and depends on the +``sqlite3`` extension which can be found `here `_. + +.. code-block:: php + $db = new SQLite3('mydatabase.db'); + + $cache = new SQLite3Cache($db, 'table_name'); + +VoidCache +--------- + +The ``VoidCache`` driver does not store the cache data anywhere. This can +be useful for test environments where you don't want to cache the data +anywhere but need to satisfy the dependency for the ``Doctrine\Common\Cache\Cache`` +interface. + +.. code-block:: php + $cache = new VoidCache(); + +WinCacheCache +------------- + +The ``WinCacheCache`` driver uses the ``wincache_ucache_get``, ``wincache_ucache_exists``, etc. functions that come +with the ``wincache`` extension which can be found `here `_. + +.. code-block:: php + $cache = new WinCacheCache(); + +XcacheCache +----------- + +The ``XcacheCache`` driver uses functions that come with the ``xcache`` +extension which can be found `here `_. + +.. code-block:: php + $cache = new XcacheCache(); + +ZendDataCache +------------- + +The ``ZendDataCache`` driver uses the Zend Data Cache API available in the Zend Platform. + +.. code-block:: php + $cache = new ZendDataCache(); + +Custom Drivers +============== + +If you want to implement your own cache driver, you just need to implement +the ``Doctrine\Common\Cache\Cache`` interface. Here is an example implementation +skeleton. + +.. code-block:: php + use Doctrine\Common\Cache\Cache; + + class MyCacheDriver implements Cache + { + public function fetch($id) + { + // fetch $id from the cache + } + + public function contains($id) + { + // check if $id exists in the cache + } + + public function save($id, $data, $lifeTime = 0) + { + // save $data under $id in the cache for $lifetime + } + + public function delete($id) + { + // delete $id from the cache + } + + public function getStats() + { + // get cache stats + } + } diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php new file mode 100644 index 000000000..451865e3b --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcCache.php @@ -0,0 +1,104 @@ += 50500) { + $info['num_hits'] = $info['num_hits'] ?? $info['nhits']; + $info['num_misses'] = $info['num_misses'] ?? $info['nmisses']; + $info['start_time'] = $info['start_time'] ?? $info['stime']; + } + + return [ + Cache::STATS_HITS => $info['num_hits'], + Cache::STATS_MISSES => $info['num_misses'], + Cache::STATS_UPTIME => $info['start_time'], + Cache::STATS_MEMORY_USAGE => $info['mem_size'], + Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'], + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php new file mode 100644 index 000000000..a72521361 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ApcuCache.php @@ -0,0 +1,106 @@ + $info['num_hits'], + Cache::STATS_MISSES => $info['num_misses'], + Cache::STATS_UPTIME => $info['start_time'], + Cache::STATS_MEMORY_USAGE => $info['mem_size'], + Cache::STATS_MEMORY_AVAILABLE => $sma['avail_mem'], + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php new file mode 100644 index 000000000..1beb7098f --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php @@ -0,0 +1,113 @@ +upTime = time(); + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + if (! $this->doContains($id)) { + $this->missesCount += 1; + + return false; + } + + $this->hitsCount += 1; + + return $this->data[$id][0]; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + if (! isset($this->data[$id])) { + return false; + } + + $expiration = $this->data[$id][1]; + + if ($expiration && $expiration < time()) { + $this->doDelete($id); + + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + $this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false]; + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + unset($this->data[$id]); + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + $this->data = []; + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + return [ + Cache::STATS_HITS => $this->hitsCount, + Cache::STATS_MISSES => $this->missesCount, + Cache::STATS_UPTIME => $this->upTime, + Cache::STATS_MEMORY_USAGE => null, + Cache::STATS_MEMORY_AVAILABLE => null, + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php new file mode 100644 index 000000000..456974427 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php @@ -0,0 +1,90 @@ +hits + * Number of keys that have been requested and found present. + * + * - misses + * Number of items that have been requested and not found. + * + * - uptime + * Time that the server is running. + * + * - memory_usage + * Memory used by this server to store items. + * + * - memory_available + * Memory allowed to use for storage. + * + * @return array|null An associative array with server's statistics if available, NULL otherwise. + */ + public function getStats(); +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php new file mode 100644 index 000000000..3be5454fe --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php @@ -0,0 +1,325 @@ +namespace = (string) $namespace; + $this->namespaceVersion = null; + } + + /** + * Retrieves the namespace that prefixes all cache ids. + * + * @return string + */ + public function getNamespace() + { + return $this->namespace; + } + + /** + * {@inheritdoc} + */ + public function fetch($id) + { + return $this->doFetch($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function fetchMultiple(array $keys) + { + if (empty($keys)) { + return []; + } + + // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys + $namespacedKeys = array_combine($keys, array_map([$this, 'getNamespacedId'], $keys)); + $items = $this->doFetchMultiple($namespacedKeys); + $foundItems = []; + + // no internal array function supports this sort of mapping: needs to be iterative + // this filters and combines keys in one pass + foreach ($namespacedKeys as $requestedKey => $namespacedKey) { + if (! isset($items[$namespacedKey]) && ! array_key_exists($namespacedKey, $items)) { + continue; + } + + $foundItems[$requestedKey] = $items[$namespacedKey]; + } + + return $foundItems; + } + + /** + * {@inheritdoc} + */ + public function saveMultiple(array $keysAndValues, $lifetime = 0) + { + $namespacedKeysAndValues = []; + foreach ($keysAndValues as $key => $value) { + $namespacedKeysAndValues[$this->getNamespacedId($key)] = $value; + } + + return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime); + } + + /** + * {@inheritdoc} + */ + public function contains($id) + { + return $this->doContains($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function save($id, $data, $lifeTime = 0) + { + return $this->doSave($this->getNamespacedId($id), $data, $lifeTime); + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple(array $keys) + { + return $this->doDeleteMultiple(array_map([$this, 'getNamespacedId'], $keys)); + } + + /** + * {@inheritdoc} + */ + public function delete($id) + { + return $this->doDelete($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function getStats() + { + return $this->doGetStats(); + } + + /** + * {@inheritDoc} + */ + public function flushAll() + { + return $this->doFlush(); + } + + /** + * {@inheritDoc} + */ + public function deleteAll() + { + $namespaceCacheKey = $this->getNamespaceCacheKey(); + $namespaceVersion = $this->getNamespaceVersion() + 1; + + if ($this->doSave($namespaceCacheKey, $namespaceVersion)) { + $this->namespaceVersion = $namespaceVersion; + + return true; + } + + return false; + } + + /** + * Prefixes the passed id with the configured namespace value. + * + * @param string $id The id to namespace. + * + * @return string The namespaced id. + */ + private function getNamespacedId(string $id) : string + { + $namespaceVersion = $this->getNamespaceVersion(); + + return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion); + } + + /** + * Returns the namespace cache key. + */ + private function getNamespaceCacheKey() : string + { + return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace); + } + + /** + * Returns the namespace version. + */ + private function getNamespaceVersion() : int + { + if ($this->namespaceVersion !== null) { + return $this->namespaceVersion; + } + + $namespaceCacheKey = $this->getNamespaceCacheKey(); + $this->namespaceVersion = (int) $this->doFetch($namespaceCacheKey) ?: 1; + + return $this->namespaceVersion; + } + + /** + * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it. + * + * @param array $keys Array of keys to retrieve from cache + * @return array Array of values retrieved for the given keys. + */ + protected function doFetchMultiple(array $keys) + { + $returnValues = []; + + foreach ($keys as $key) { + $item = $this->doFetch($key); + if ($item === false && ! $this->doContains($key)) { + continue; + } + + $returnValues[$key] = $item; + } + + return $returnValues; + } + + /** + * Fetches an entry from the cache. + * + * @param string $id The id of the cache entry to fetch. + * + * @return mixed|false The cached data or FALSE, if no cache entry exists for the given id. + */ + abstract protected function doFetch($id); + + /** + * Tests if an entry exists in the cache. + * + * @param string $id The cache id of the entry to check for. + * + * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise. + */ + abstract protected function doContains($id); + + /** + * Default implementation of doSaveMultiple. Each driver that supports multi-put should override it. + * + * @param array $keysAndValues Array of keys and values to save in cache + * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these + * cache entries (0 => infinite lifeTime). + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't. + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + $success = true; + + foreach ($keysAndValues as $key => $value) { + if ($this->doSave($key, $value, $lifetime)) { + continue; + } + + $success = false; + } + + return $success; + } + + /** + * Puts data into the cache. + * + * @param string $id The cache id. + * @param string $data The cache entry/data. + * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this + * cache entry (0 => infinite lifeTime). + * + * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise. + */ + abstract protected function doSave($id, $data, $lifeTime = 0); + + /** + * Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it. + * + * @param array $keys Array of keys to delete from cache + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't + */ + protected function doDeleteMultiple(array $keys) + { + $success = true; + + foreach ($keys as $key) { + if ($this->doDelete($key)) { + continue; + } + + $success = false; + } + + return $success; + } + + /** + * Deletes a cache entry. + * + * @param string $id The cache id. + * + * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise. + */ + abstract protected function doDelete($id); + + /** + * Flushes all cache entries. + * + * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise. + */ + abstract protected function doFlush(); + + /** + * Retrieves cached information from the data store. + * + * @return array|null An associative array with server's statistics if available, NULL otherwise. + */ + abstract protected function doGetStats(); +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php new file mode 100644 index 000000000..1307fae7d --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ChainCache.php @@ -0,0 +1,186 @@ +cacheProviders = $cacheProviders instanceof \Traversable + ? iterator_to_array($cacheProviders, false) + : array_values($cacheProviders); + } + + /** + * {@inheritDoc} + */ + public function setNamespace($namespace) + { + parent::setNamespace($namespace); + + foreach ($this->cacheProviders as $cacheProvider) { + $cacheProvider->setNamespace($namespace); + } + } + + /** + * {@inheritDoc} + */ + protected function doFetch($id) + { + foreach ($this->cacheProviders as $key => $cacheProvider) { + if ($cacheProvider->doContains($id)) { + $value = $cacheProvider->doFetch($id); + + // We populate all the previous cache layers (that are assumed to be faster) + for ($subKey = $key - 1; $subKey >= 0; $subKey--) { + $this->cacheProviders[$subKey]->doSave($id, $value); + } + + return $value; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doFetchMultiple(array $keys) + { + /** @var CacheProvider[] $traversedProviders */ + $traversedProviders = []; + $keysCount = count($keys); + $fetchedValues = []; + + foreach ($this->cacheProviders as $key => $cacheProvider) { + $fetchedValues = $cacheProvider->doFetchMultiple($keys); + + // We populate all the previous cache layers (that are assumed to be faster) + if (count($fetchedValues) === $keysCount) { + foreach ($traversedProviders as $previousCacheProvider) { + $previousCacheProvider->doSaveMultiple($fetchedValues); + } + + return $fetchedValues; + } + + $traversedProviders[] = $cacheProvider; + } + + return $fetchedValues; + } + + /** + * {@inheritDoc} + */ + protected function doContains($id) + { + foreach ($this->cacheProviders as $cacheProvider) { + if ($cacheProvider->doContains($id)) { + return true; + } + } + + return false; + } + + /** + * {@inheritDoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + $stored = true; + + foreach ($this->cacheProviders as $cacheProvider) { + $stored = $cacheProvider->doSave($id, $data, $lifeTime) && $stored; + } + + return $stored; + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + $stored = true; + + foreach ($this->cacheProviders as $cacheProvider) { + $stored = $cacheProvider->doSaveMultiple($keysAndValues, $lifetime) && $stored; + } + + return $stored; + } + + /** + * {@inheritDoc} + */ + protected function doDelete($id) + { + $deleted = true; + + foreach ($this->cacheProviders as $cacheProvider) { + $deleted = $cacheProvider->doDelete($id) && $deleted; + } + + return $deleted; + } + + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + $deleted = true; + + foreach ($this->cacheProviders as $cacheProvider) { + $deleted = $cacheProvider->doDeleteMultiple($keys) && $deleted; + } + + return $deleted; + } + + /** + * {@inheritDoc} + */ + protected function doFlush() + { + $flushed = true; + + foreach ($this->cacheProviders as $cacheProvider) { + $flushed = $cacheProvider->doFlush() && $flushed; + } + + return $flushed; + } + + /** + * {@inheritDoc} + */ + protected function doGetStats() + { + // We return all the stats from all adapters + $stats = []; + + foreach ($this->cacheProviders as $cacheProvider) { + $stats[] = $cacheProvider->doGetStats(); + } + + return $stats; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php new file mode 100644 index 000000000..b94618e46 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php @@ -0,0 +1,21 @@ +bucket = $bucket; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + $id = $this->normalizeKey($id); + + try { + $document = $this->bucket->get($id); + } catch (Exception $e) { + return false; + } + + if ($document instanceof Document && $document->value !== false) { + return unserialize($document->value); + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $id = $this->normalizeKey($id); + + try { + $document = $this->bucket->get($id); + } catch (Exception $e) { + return false; + } + + if ($document instanceof Document) { + return ! $document->error; + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + $id = $this->normalizeKey($id); + + $lifeTime = $this->normalizeExpiry($lifeTime); + + try { + $encoded = serialize($data); + + $document = $this->bucket->upsert($id, $encoded, [ + 'expiry' => (int) $lifeTime, + ]); + } catch (Exception $e) { + return false; + } + + if ($document instanceof Document) { + return ! $document->error; + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + $id = $this->normalizeKey($id); + + try { + $document = $this->bucket->remove($id); + } catch (Exception $e) { + return $e->getCode() === self::KEY_NOT_FOUND; + } + + if ($document instanceof Document) { + return ! $document->error; + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + $manager = $this->bucket->manager(); + + // Flush does not return with success or failure, and must be enabled per bucket on the server. + // Store a marker item so that we will know if it was successful. + $this->doSave(__METHOD__, true, 60); + + $manager->flush(); + + if ($this->doContains(__METHOD__)) { + $this->doDelete(__METHOD__); + + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $manager = $this->bucket->manager(); + $stats = $manager->info(); + $nodes = $stats['nodes']; + $node = $nodes[0]; + $interestingStats = $node['interestingStats']; + + return [ + Cache::STATS_HITS => $interestingStats['get_hits'], + Cache::STATS_MISSES => $interestingStats['cmd_get'] - $interestingStats['get_hits'], + Cache::STATS_UPTIME => $node['uptime'], + Cache::STATS_MEMORY_USAGE => $interestingStats['mem_used'], + Cache::STATS_MEMORY_AVAILABLE => $node['memoryFree'], + ]; + } + + private function normalizeKey(string $id) : string + { + $normalized = substr($id, 0, self::MAX_KEY_LENGTH); + + if ($normalized === false) { + return $id; + } + + return $normalized; + } + + /** + * Expiry treated as a unix timestamp instead of an offset if expiry is greater than 30 days. + * @src https://developer.couchbase.com/documentation/server/4.1/developer-guide/expiry.html + */ + private function normalizeExpiry(int $expiry) : int + { + if ($expiry > self::THIRTY_DAYS_IN_SECONDS) { + return time() + $expiry; + } + + return $expiry; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php new file mode 100644 index 000000000..4c2b9bd2c --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CouchbaseCache.php @@ -0,0 +1,102 @@ +couchbase = $couchbase; + } + + /** + * Gets the Couchbase instance used by the cache. + * + * @return Couchbase|null + */ + public function getCouchbase() + { + return $this->couchbase; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return $this->couchbase->get($id) ?: false; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return $this->couchbase->get($id) !== null; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + if ($lifeTime > 30 * 24 * 3600) { + $lifeTime = time() + $lifeTime; + } + return $this->couchbase->set($id, $data, (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return $this->couchbase->delete($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->couchbase->flush(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $stats = $this->couchbase->getStats(); + $servers = $this->couchbase->getServers(); + $server = explode(':', $servers[0]); + $key = $server[0] . ':11210'; + $stats = $stats[$key]; + return [ + Cache::STATS_HITS => $stats['get_hits'], + Cache::STATS_MISSES => $stats['get_misses'], + Cache::STATS_UPTIME => $stats['uptime'], + Cache::STATS_MEMORY_USAGE => $stats['bytes'], + Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php new file mode 100644 index 000000000..95ab5be1a --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ExtMongoDBCache.php @@ -0,0 +1,196 @@ +collection = $collection->withOptions(['typeMap' => null]); + $this->database = new Database($collection->getManager(), $collection->getDatabaseName()); + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::DATA_FIELD, MongoDBCache::EXPIRATION_FIELD]); + + if ($document === null) { + return false; + } + + if ($this->isExpired($document)) { + $this->createExpirationIndex(); + $this->doDelete($id); + return false; + } + + return unserialize($document[MongoDBCache::DATA_FIELD]->getData()); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::EXPIRATION_FIELD]); + + if ($document === null) { + return false; + } + + if ($this->isExpired($document)) { + $this->createExpirationIndex(); + $this->doDelete($id); + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + try { + $this->collection->updateOne( + ['_id' => $id], + [ + '$set' => [ + MongoDBCache::EXPIRATION_FIELD => ($lifeTime > 0 ? new UTCDateTime((time() + $lifeTime) * 1000): null), + MongoDBCache::DATA_FIELD => new Binary(serialize($data), Binary::TYPE_GENERIC), + ], + ], + ['upsert' => true] + ); + } catch (Exception $e) { + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + try { + $this->collection->deleteOne(['_id' => $id]); + } catch (Exception $e) { + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + try { + // Use remove() in lieu of drop() to maintain any collection indexes + $this->collection->deleteMany([]); + } catch (Exception $e) { + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $uptime = null; + $memoryUsage = null; + + try { + $serverStatus = $this->database->command([ + 'serverStatus' => 1, + 'locks' => 0, + 'metrics' => 0, + 'recordStats' => 0, + 'repl' => 0, + ])->toArray()[0]; + $uptime = $serverStatus['uptime'] ?? null; + } catch (Exception $e) { + } + + try { + $collStats = $this->database->command(['collStats' => $this->collection->getCollectionName()])->toArray()[0]; + $memoryUsage = $collStats['size'] ?? null; + } catch (Exception $e) { + } + + return [ + Cache::STATS_HITS => null, + Cache::STATS_MISSES => null, + Cache::STATS_UPTIME => $uptime, + Cache::STATS_MEMORY_USAGE => $memoryUsage, + Cache::STATS_MEMORY_AVAILABLE => null, + ]; + } + + /** + * Check if the document is expired. + */ + private function isExpired(BSONDocument $document) : bool + { + return isset($document[MongoDBCache::EXPIRATION_FIELD]) && + $document[MongoDBCache::EXPIRATION_FIELD] instanceof UTCDateTime && + $document[MongoDBCache::EXPIRATION_FIELD]->toDateTime() < new \DateTime(); + } + + private function createExpirationIndex() : void + { + if ($this->expirationIndexCreated) { + return; + } + + $this->collection->createIndex([MongoDBCache::EXPIRATION_FIELD => 1], ['background' => true, 'expireAfterSeconds' => 0]); + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php new file mode 100644 index 000000000..184680c0c --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FileCache.php @@ -0,0 +1,276 @@ +umask = $umask; + + if (! $this->createPathIfNeeded($directory)) { + throw new \InvalidArgumentException(sprintf( + 'The directory "%s" does not exist and could not be created.', + $directory + )); + } + + if (! is_writable($directory)) { + throw new \InvalidArgumentException(sprintf( + 'The directory "%s" is not writable.', + $directory + )); + } + + // YES, this needs to be *after* createPathIfNeeded() + $this->directory = realpath($directory); + $this->extension = (string) $extension; + + $this->directoryStringLength = strlen($this->directory); + $this->extensionStringLength = strlen($this->extension); + $this->isRunningOnWindows = defined('PHP_WINDOWS_VERSION_BUILD'); + } + + /** + * Gets the cache directory. + * + * @return string + */ + public function getDirectory() + { + return $this->directory; + } + + /** + * Gets the cache file extension. + * + * @return string + */ + public function getExtension() + { + return $this->extension; + } + + /** + * @param string $id + * + * @return string + */ + protected function getFilename($id) + { + $hash = hash('sha256', $id); + + // This ensures that the filename is unique and that there are no invalid chars in it. + if ($id === '' + || ((strlen($id) * 2 + $this->extensionStringLength) > 255) + || ($this->isRunningOnWindows && ($this->directoryStringLength + 4 + strlen($id) * 2 + $this->extensionStringLength) > 258) + ) { + // Most filesystems have a limit of 255 chars for each path component. On Windows the the whole path is limited + // to 260 chars (including terminating null char). Using long UNC ("\\?\" prefix) does not work with the PHP API. + // And there is a bug in PHP (https://bugs.php.net/bug.php?id=70943) with path lengths of 259. + // So if the id in hex representation would surpass the limit, we use the hash instead. The prefix prevents + // collisions between the hash and bin2hex. + $filename = '_' . $hash; + } else { + $filename = bin2hex($id); + } + + return $this->directory + . DIRECTORY_SEPARATOR + . substr($hash, 0, 2) + . DIRECTORY_SEPARATOR + . $filename + . $this->extension; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + $filename = $this->getFilename($id); + + return @unlink($filename) || ! file_exists($filename); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + foreach ($this->getIterator() as $name => $file) { + if ($file->isDir()) { + // Remove the intermediate directories which have been created to balance the tree. It only takes effect + // if the directory is empty. If several caches share the same directory but with different file extensions, + // the other ones are not removed. + @rmdir($name); + } elseif ($this->isFilenameEndingWithExtension($name)) { + // If an extension is set, only remove files which end with the given extension. + // If no extension is set, we have no other choice than removing everything. + @unlink($name); + } + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $usage = 0; + foreach ($this->getIterator() as $name => $file) { + if ($file->isDir() || ! $this->isFilenameEndingWithExtension($name)) { + continue; + } + + $usage += $file->getSize(); + } + + $free = disk_free_space($this->directory); + + return [ + Cache::STATS_HITS => null, + Cache::STATS_MISSES => null, + Cache::STATS_UPTIME => null, + Cache::STATS_MEMORY_USAGE => $usage, + Cache::STATS_MEMORY_AVAILABLE => $free, + ]; + } + + /** + * Create path if needed. + * + * @return bool TRUE on success or if path already exists, FALSE if path cannot be created. + */ + private function createPathIfNeeded(string $path) : bool + { + if (! is_dir($path)) { + if (@mkdir($path, 0777 & (~$this->umask), true) === false && ! is_dir($path)) { + return false; + } + } + + return true; + } + + /** + * Writes a string content to file in an atomic way. + * + * @param string $filename Path to the file where to write the data. + * @param string $content The content to write + * + * @return bool TRUE on success, FALSE if path cannot be created, if path is not writable or an any other error. + */ + protected function writeFile(string $filename, string $content) : bool + { + $filepath = pathinfo($filename, PATHINFO_DIRNAME); + + if (! $this->createPathIfNeeded($filepath)) { + return false; + } + + if (! is_writable($filepath)) { + return false; + } + + $tmpFile = tempnam($filepath, 'swap'); + @chmod($tmpFile, 0666 & (~$this->umask)); + + if (file_put_contents($tmpFile, $content) !== false) { + @chmod($tmpFile, 0666 & (~$this->umask)); + if (@rename($tmpFile, $filename)) { + return true; + } + + @unlink($tmpFile); + } + + return false; + } + + private function getIterator() : \Iterator + { + return new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($this->directory, \FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::CHILD_FIRST + ); + } + + /** + * @param string $name The filename + */ + private function isFilenameEndingWithExtension(string $name) : bool + { + return $this->extension === '' + || strrpos($name, $this->extension) === (strlen($name) - $this->extensionStringLength); + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php new file mode 100644 index 000000000..8f34c9cb4 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FilesystemCache.php @@ -0,0 +1,102 @@ +getFilename($id); + + if (! is_file($filename)) { + return false; + } + + $resource = fopen($filename, 'r'); + $line = fgets($resource); + + if ($line !== false) { + $lifetime = (int) $line; + } + + if ($lifetime !== 0 && $lifetime < time()) { + fclose($resource); + + return false; + } + + while (($line = fgets($resource)) !== false) { + $data .= $line; + } + + fclose($resource); + + return unserialize($data); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $lifetime = -1; + $filename = $this->getFilename($id); + + if (! is_file($filename)) { + return false; + } + + $resource = fopen($filename, 'r'); + $line = fgets($resource); + + if ($line !== false) { + $lifetime = (int) $line; + } + + fclose($resource); + + return $lifetime === 0 || $lifetime > time(); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + if ($lifeTime > 0) { + $lifeTime = time() + $lifeTime; + } + + $data = serialize($data); + $filename = $this->getFilename($id); + + return $this->writeFile($filename, $lifeTime . PHP_EOL . $data); + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php new file mode 100644 index 000000000..ee7ce984e --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/FlushableCache.php @@ -0,0 +1,18 @@ +collection = $collection; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::DATA_FIELD, MongoDBCache::EXPIRATION_FIELD]); + + if ($document === null) { + return false; + } + + if ($this->isExpired($document)) { + $this->createExpirationIndex(); + $this->doDelete($id); + return false; + } + + return unserialize($document[MongoDBCache::DATA_FIELD]->bin); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $document = $this->collection->findOne(['_id' => $id], [MongoDBCache::EXPIRATION_FIELD]); + + if ($document === null) { + return false; + } + + if ($this->isExpired($document)) { + $this->createExpirationIndex(); + $this->doDelete($id); + return false; + } + + return true; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + try { + $result = $this->collection->update( + ['_id' => $id], + [ + '$set' => [ + MongoDBCache::EXPIRATION_FIELD => ($lifeTime > 0 ? new MongoDate(time() + $lifeTime) : null), + MongoDBCache::DATA_FIELD => new MongoBinData(serialize($data), MongoBinData::BYTE_ARRAY), + ], + ], + ['upsert' => true, 'multiple' => false] + ); + } catch (MongoCursorException $e) { + return false; + } + + return ($result['ok'] ?? 1) == 1; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + $result = $this->collection->remove(['_id' => $id]); + + return ($result['ok'] ?? 1) == 1; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + // Use remove() in lieu of drop() to maintain any collection indexes + $result = $this->collection->remove(); + + return ($result['ok'] ?? 1) == 1; + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $serverStatus = $this->collection->db->command([ + 'serverStatus' => 1, + 'locks' => 0, + 'metrics' => 0, + 'recordStats' => 0, + 'repl' => 0, + ]); + + $collStats = $this->collection->db->command(['collStats' => 1]); + + return [ + Cache::STATS_HITS => null, + Cache::STATS_MISSES => null, + Cache::STATS_UPTIME => $serverStatus['uptime'] ?? null, + Cache::STATS_MEMORY_USAGE => $collStats['size'] ?? null, + Cache::STATS_MEMORY_AVAILABLE => null, + ]; + } + + /** + * Check if the document is expired. + * + * @param array $document + */ + private function isExpired(array $document) : bool + { + return isset($document[MongoDBCache::EXPIRATION_FIELD]) && + $document[MongoDBCache::EXPIRATION_FIELD] instanceof MongoDate && + $document[MongoDBCache::EXPIRATION_FIELD]->sec < time(); + } + + + private function createExpirationIndex() : void + { + if ($this->expirationIndexCreated) { + return; + } + + $this->expirationIndexCreated = true; + $this->collection->createIndex([MongoDBCache::EXPIRATION_FIELD => 1], ['background' => true, 'expireAfterSeconds' => 0]); + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php new file mode 100644 index 000000000..1597ff7b1 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcacheCache.php @@ -0,0 +1,102 @@ +memcache = $memcache; + } + + /** + * Gets the memcache instance used by the cache. + * + * @return Memcache|null + */ + public function getMemcache() + { + return $this->memcache; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return $this->memcache->get($id); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $flags = null; + $this->memcache->get($id, $flags); + + //if memcache has changed the value of "flags", it means the value exists + return $flags !== null; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + if ($lifeTime > 30 * 24 * 3600) { + $lifeTime = time() + $lifeTime; + } + return $this->memcache->set($id, $data, 0, (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + // Memcache::delete() returns false if entry does not exist + return $this->memcache->delete($id) || ! $this->doContains($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->memcache->flush(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $stats = $this->memcache->getStats(); + return [ + Cache::STATS_HITS => $stats['get_hits'], + Cache::STATS_MISSES => $stats['get_misses'], + Cache::STATS_UPTIME => $stats['uptime'], + Cache::STATS_MEMORY_USAGE => $stats['bytes'], + Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php new file mode 100644 index 000000000..6591b926d --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MemcachedCache.php @@ -0,0 +1,130 @@ +memcached = $memcached; + } + + /** + * Gets the memcached instance used by the cache. + * + * @return Memcached|null + */ + public function getMemcached() + { + return $this->memcached; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return $this->memcached->get($id); + } + + /** + * {@inheritdoc} + */ + protected function doFetchMultiple(array $keys) + { + return $this->memcached->getMulti($keys) ?: []; + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + if ($lifetime > 30 * 24 * 3600) { + $lifetime = time() + $lifetime; + } + + return $this->memcached->setMulti($keysAndValues, $lifetime); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $this->memcached->get($id); + + return $this->memcached->getResultCode() === Memcached::RES_SUCCESS; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + if ($lifeTime > 30 * 24 * 3600) { + $lifeTime = time() + $lifeTime; + } + return $this->memcached->set($id, $data, (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + return $this->memcached->deleteMulti($keys) + || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return $this->memcached->delete($id) + || $this->memcached->getResultCode() === Memcached::RES_NOTFOUND; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->memcached->flush(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $stats = $this->memcached->getStats(); + $servers = $this->memcached->getServerList(); + $key = $servers[0]['host'] . ':' . $servers[0]['port']; + $stats = $stats[$key]; + return [ + Cache::STATS_HITS => $stats['get_hits'], + Cache::STATS_MISSES => $stats['get_misses'], + Cache::STATS_UPTIME => $stats['uptime'], + Cache::STATS_MEMORY_USAGE => $stats['bytes'], + Cache::STATS_MEMORY_AVAILABLE => $stats['limit_maxbytes'], + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php new file mode 100644 index 000000000..05ac4f875 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MongoDBCache.php @@ -0,0 +1,110 @@ +provider = new LegacyMongoDBCache($collection); + } elseif ($collection instanceof Collection) { + $this->provider = new ExtMongoDBCache($collection); + } else { + throw new \InvalidArgumentException('Invalid collection given - expected a MongoCollection or MongoDB\Collection instance'); + } + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return $this->provider->doFetch($id); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return $this->provider->doContains($id); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + return $this->provider->doSave($id, $data, $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return $this->provider->doDelete($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->provider->doFlush(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + return $this->provider->doGetStats(); + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php new file mode 100644 index 000000000..b4faa41f9 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/MultiDeleteCache.php @@ -0,0 +1,21 @@ + infinite lifeTime). + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't. + */ + public function saveMultiple(array $keysAndValues, $lifetime = 0); +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php new file mode 100644 index 000000000..132b15426 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PhpFileCache.php @@ -0,0 +1,118 @@ +includeFileForId($id); + + if ($value === null) { + return false; + } + + if ($value['lifetime'] !== 0 && $value['lifetime'] < time()) { + return false; + } + + return $value['data']; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $value = $this->includeFileForId($id); + + if ($value === null) { + return false; + } + + return $value['lifetime'] === 0 || $value['lifetime'] > time(); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + if ($lifeTime > 0) { + $lifeTime = time() + $lifeTime; + } + + $filename = $this->getFilename($id); + + $value = [ + 'lifetime' => $lifeTime, + 'data' => $data, + ]; + + if (is_object($data) && method_exists($data, '__set_state')) { + $value = var_export($value, true); + $code = sprintf('writeFile($filename, $code); + } + + /** + * @return array|null + */ + private function includeFileForId(string $id) : ?array + { + $fileName = $this->getFilename($id); + + // note: error suppression is still faster than `file_exists`, `is_file` and `is_readable` + set_error_handler(self::$emptyErrorHandler); + + $value = include $fileName; + + restore_error_handler(); + + if (! isset($value['lifetime'])) { + return null; + } + + return $value; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php new file mode 100644 index 000000000..40803de16 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/PredisCache.php @@ -0,0 +1,143 @@ +client = $client; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + $result = $this->client->get($id); + if ($result === null) { + return false; + } + + return unserialize($result); + } + + /** + * {@inheritdoc} + */ + protected function doFetchMultiple(array $keys) + { + $fetchedItems = call_user_func_array([$this->client, 'mget'], $keys); + + return array_map('unserialize', array_filter(array_combine($keys, $fetchedItems))); + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + if ($lifetime) { + $success = true; + + // Keys have lifetime, use SETEX for each of them + foreach ($keysAndValues as $key => $value) { + $response = (string) $this->client->setex($key, $lifetime, serialize($value)); + + if ($response == 'OK') { + continue; + } + + $success = false; + } + + return $success; + } + + // No lifetime, use MSET + $response = $this->client->mset(array_map(function ($value) { + return serialize($value); + }, $keysAndValues)); + + return (string) $response == 'OK'; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return (bool) $this->client->exists($id); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + $data = serialize($data); + if ($lifeTime > 0) { + $response = $this->client->setex($id, $lifeTime, $data); + } else { + $response = $this->client->set($id, $data); + } + + return $response === true || $response == 'OK'; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return $this->client->del($id) >= 0; + } + + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + return $this->client->del($keys) >= 0; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + $response = $this->client->flushdb(); + + return $response === true || $response == 'OK'; + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $info = $this->client->info(); + + return [ + Cache::STATS_HITS => $info['Stats']['keyspace_hits'], + Cache::STATS_MISSES => $info['Stats']['keyspace_misses'], + Cache::STATS_UPTIME => $info['Server']['uptime_in_seconds'], + Cache::STATS_MEMORY_USAGE => $info['Memory']['used_memory'], + Cache::STATS_MEMORY_AVAILABLE => false, + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php new file mode 100644 index 000000000..463886042 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RedisCache.php @@ -0,0 +1,175 @@ +setOption(Redis::OPT_SERIALIZER, $this->getSerializerValue()); + $this->redis = $redis; + } + + /** + * Gets the redis instance used by the cache. + * + * @return Redis|null + */ + public function getRedis() + { + return $this->redis; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + return $this->redis->get($id); + } + + /** + * {@inheritdoc} + */ + protected function doFetchMultiple(array $keys) + { + $fetchedItems = array_combine($keys, $this->redis->mget($keys)); + + // Redis mget returns false for keys that do not exist. So we need to filter those out unless it's the real data. + $foundItems = []; + + foreach ($fetchedItems as $key => $value) { + if ($value === false && ! $this->redis->exists($key)) { + continue; + } + + $foundItems[$key] = $value; + } + + return $foundItems; + } + + /** + * {@inheritdoc} + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + if ($lifetime) { + $success = true; + + // Keys have lifetime, use SETEX for each of them + foreach ($keysAndValues as $key => $value) { + if ($this->redis->setex($key, $lifetime, $value)) { + continue; + } + + $success = false; + } + + return $success; + } + + // No lifetime, use MSET + return (bool) $this->redis->mset($keysAndValues); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + $exists = $this->redis->exists($id); + + if (is_bool($exists)) { + return $exists; + } + + return $exists > 0; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + if ($lifeTime > 0) { + return $this->redis->setex($id, $lifeTime, $data); + } + + return $this->redis->set($id, $data); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return $this->redis->delete($id) >= 0; + } + + /** + * {@inheritdoc} + */ + protected function doDeleteMultiple(array $keys) + { + return $this->redis->delete($keys) >= 0; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->redis->flushDB(); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $info = $this->redis->info(); + return [ + Cache::STATS_HITS => $info['keyspace_hits'], + Cache::STATS_MISSES => $info['keyspace_misses'], + Cache::STATS_UPTIME => $info['uptime_in_seconds'], + Cache::STATS_MEMORY_USAGE => $info['used_memory'], + Cache::STATS_MEMORY_AVAILABLE => false, + ]; + } + + /** + * Returns the serializer constant to use. If Redis is compiled with + * igbinary support, that is used. Otherwise the default PHP serializer is + * used. + * + * @return int One of the Redis::SERIALIZER_* constants + */ + protected function getSerializerValue() + { + if (defined('Redis::SERIALIZER_IGBINARY') && extension_loaded('igbinary')) { + return Redis::SERIALIZER_IGBINARY; + } + + return Redis::SERIALIZER_PHP; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php new file mode 100644 index 000000000..0ae220688 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/RiakCache.php @@ -0,0 +1,228 @@ +bucket = $bucket; + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + try { + $response = $this->bucket->get($id); + + // No objects found + if (! $response->hasObject()) { + return false; + } + + // Check for attempted siblings + $object = ($response->hasSiblings()) + ? $this->resolveConflict($id, $response->getVClock(), $response->getObjectList()) + : $response->getFirstObject(); + + // Check for expired object + if ($this->isExpired($object)) { + $this->bucket->delete($object); + + return false; + } + + return unserialize($object->getContent()); + } catch (Exception\RiakException $e) { + // Covers: + // - Riak\ConnectionException + // - Riak\CommunicationException + // - Riak\UnexpectedResponseException + // - Riak\NotFoundException + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + try { + // We only need the HEAD, not the entire object + $input = new Input\GetInput(); + + $input->setReturnHead(true); + + $response = $this->bucket->get($id, $input); + + // No objects found + if (! $response->hasObject()) { + return false; + } + + $object = $response->getFirstObject(); + + // Check for expired object + if ($this->isExpired($object)) { + $this->bucket->delete($object); + + return false; + } + + return true; + } catch (Exception\RiakException $e) { + // Do nothing + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + try { + $object = new Object($id); + + $object->setContent(serialize($data)); + + if ($lifeTime > 0) { + $object->addMetadata(self::EXPIRES_HEADER, (string) (time() + $lifeTime)); + } + + $this->bucket->put($object); + + return true; + } catch (Exception\RiakException $e) { + // Do nothing + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + try { + $this->bucket->delete($id); + + return true; + } catch (Exception\BadArgumentsException $e) { + // Key did not exist on cluster already + } catch (Exception\RiakException $e) { + // Covers: + // - Riak\Exception\ConnectionException + // - Riak\Exception\CommunicationException + // - Riak\Exception\UnexpectedResponseException + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + try { + $keyList = $this->bucket->getKeyList(); + + foreach ($keyList as $key) { + $this->bucket->delete($key); + } + + return true; + } catch (Exception\RiakException $e) { + // Do nothing + } + + return false; + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + // Only exposed through HTTP stats API, not Protocol Buffers API + return null; + } + + /** + * Check if a given Riak Object have expired. + */ + private function isExpired(Object $object) : bool + { + $metadataMap = $object->getMetadataMap(); + + return isset($metadataMap[self::EXPIRES_HEADER]) + && $metadataMap[self::EXPIRES_HEADER] < time(); + } + + /** + * On-read conflict resolution. Applied approach here is last write wins. + * Specific needs may override this method to apply alternate conflict resolutions. + * + * {@internal Riak does not attempt to resolve a write conflict, and store + * it as sibling of conflicted one. By following this approach, it is up to + * the next read to resolve the conflict. When this happens, your fetched + * object will have a list of siblings (read as a list of objects). + * In our specific case, we do not care about the intermediate ones since + * they are all the same read from storage, and we do apply a last sibling + * (last write) wins logic. + * If by any means our resolution generates another conflict, it'll up to + * next read to properly solve it.} + * + * @param string $id + * @param string $vClock + * @param array $objectList + * + * @return Object + */ + protected function resolveConflict($id, $vClock, array $objectList) + { + // Our approach here is last-write wins + $winner = $objectList[count($objectList) - 1]; + + $putInput = new Input\PutInput(); + $putInput->setVClock($vClock); + + $mergedObject = new Object($id); + $mergedObject->setContent($winner->getContent()); + + $this->bucket->put($mergedObject, $putInput); + + return $mergedObject; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php new file mode 100644 index 000000000..8b3111f4a --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/SQLite3Cache.php @@ -0,0 +1,206 @@ +sqlite = $sqlite; + $this->table = (string) $table; + + $this->ensureTableExists(); + } + + private function ensureTableExists() : void + { + $this->sqlite->exec( + sprintf( + 'CREATE TABLE IF NOT EXISTS %s(%s TEXT PRIMARY KEY NOT NULL, %s BLOB, %s INTEGER)', + $this->table, + static::ID_FIELD, + static::DATA_FIELD, + static::EXPIRATION_FIELD + ) + ); + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + $item = $this->findById($id); + + if (! $item) { + return false; + } + + return unserialize($item[self::DATA_FIELD]); + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return $this->findById($id, false) !== null; + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + $statement = $this->sqlite->prepare(sprintf( + 'INSERT OR REPLACE INTO %s (%s) VALUES (:id, :data, :expire)', + $this->table, + implode(',', $this->getFields()) + )); + + $statement->bindValue(':id', $id); + $statement->bindValue(':data', serialize($data), SQLITE3_BLOB); + $statement->bindValue(':expire', $lifeTime > 0 ? time() + $lifeTime : null); + + return $statement->execute() instanceof SQLite3Result; + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + list($idField) = $this->getFields(); + + $statement = $this->sqlite->prepare(sprintf( + 'DELETE FROM %s WHERE %s = :id', + $this->table, + $idField + )); + + $statement->bindValue(':id', $id); + + return $statement->execute() instanceof SQLite3Result; + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + return $this->sqlite->exec(sprintf('DELETE FROM %s', $this->table)); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + // no-op. + } + + /** + * Find a single row by ID. + * + * @param mixed $id + * + * @return array|null + */ + private function findById($id, bool $includeData = true) : ?array + { + list($idField) = $fields = $this->getFields(); + + if (! $includeData) { + $key = array_search(static::DATA_FIELD, $fields); + unset($fields[$key]); + } + + $statement = $this->sqlite->prepare(sprintf( + 'SELECT %s FROM %s WHERE %s = :id LIMIT 1', + implode(',', $fields), + $this->table, + $idField + )); + + $statement->bindValue(':id', $id, SQLITE3_TEXT); + + $item = $statement->execute()->fetchArray(SQLITE3_ASSOC); + + if ($item === false) { + return null; + } + + if ($this->isExpired($item)) { + $this->doDelete($id); + + return null; + } + + return $item; + } + + /** + * Gets an array of the fields in our table. + * + * @return array + */ + private function getFields() : array + { + return [static::ID_FIELD, static::DATA_FIELD, static::EXPIRATION_FIELD]; + } + + /** + * Check if the item is expired. + * + * @param array $item + */ + private function isExpired(array $item) : bool + { + return isset($item[static::EXPIRATION_FIELD]) && + $item[self::EXPIRATION_FIELD] !== null && + $item[self::EXPIRATION_FIELD] < time(); + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php new file mode 100644 index 000000000..dbf55f42b --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Version.php @@ -0,0 +1,8 @@ + $info['total_hit_count'], + Cache::STATS_MISSES => $info['total_miss_count'], + Cache::STATS_UPTIME => $info['total_cache_uptime'], + Cache::STATS_MEMORY_USAGE => $meminfo['memory_total'], + Cache::STATS_MEMORY_AVAILABLE => $meminfo['memory_free'], + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php new file mode 100644 index 000000000..2d5c10abe --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/XcacheCache.php @@ -0,0 +1,102 @@ +doContains($id) ? unserialize(xcache_get($id)) : false; + } + + /** + * {@inheritdoc} + */ + protected function doContains($id) + { + return xcache_isset($id); + } + + /** + * {@inheritdoc} + */ + protected function doSave($id, $data, $lifeTime = 0) + { + return xcache_set($id, serialize($data), (int) $lifeTime); + } + + /** + * {@inheritdoc} + */ + protected function doDelete($id) + { + return xcache_unset($id); + } + + /** + * {@inheritdoc} + */ + protected function doFlush() + { + $this->checkAuthorization(); + + xcache_clear_cache(XC_TYPE_VAR); + + return true; + } + + /** + * Checks that xcache.admin.enable_auth is Off. + * + * @return void + * + * @throws \BadMethodCallException When xcache.admin.enable_auth is On. + */ + protected function checkAuthorization() + { + if (ini_get('xcache.admin.enable_auth')) { + throw new \BadMethodCallException( + 'To use all features of \Doctrine\Common\Cache\XcacheCache, ' + . 'you must set "xcache.admin.enable_auth" to "Off" in your php.ini.' + ); + } + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + $this->checkAuthorization(); + + $info = xcache_info(XC_TYPE_VAR, 0); + return [ + Cache::STATS_HITS => $info['hits'], + Cache::STATS_MISSES => $info['misses'], + Cache::STATS_UPTIME => null, + Cache::STATS_MEMORY_USAGE => $info['size'], + Cache::STATS_MEMORY_AVAILABLE => $info['avail'], + ]; + } +} diff --git a/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php new file mode 100644 index 000000000..275f3c497 --- /dev/null +++ b/app/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ZendDataCache.php @@ -0,0 +1,68 @@ +getNamespace(); + if (empty($namespace)) { + return zend_shm_cache_clear(); + } + return zend_shm_cache_clear($namespace); + } + + /** + * {@inheritdoc} + */ + protected function doGetStats() + { + return null; + } +} diff --git a/app/vendor/doctrine/dbal/.doctrine-project.json b/app/vendor/doctrine/dbal/.doctrine-project.json new file mode 100644 index 000000000..9fb3d836c --- /dev/null +++ b/app/vendor/doctrine/dbal/.doctrine-project.json @@ -0,0 +1,49 @@ +{ + "active": true, + "name": "Database Abstraction Layer", + "shortName": "DBAL", + "slug": "dbal", + "docsSlug": "doctrine-dbal", + "versions": [ + { + "name": "3.0", + "branchName": "develop", + "slug": "latest", + "upcoming": true + }, + { + "name": "2.9", + "branchName": "master", + "slug": "2.9", + "upcoming": true + }, + { + "name": "2.8", + "branchName": "2.8", + "slug": "2.8", + "current": true, + "aliases": [ + "current", + "stable" + ] + }, + { + "name": "2.7", + "branchName": "2.7", + "slug": "2.7", + "maintained": false + }, + { + "name": "2.6", + "branchName": "2.6", + "slug": "2.6", + "maintained": false + }, + { + "name": "2.5", + "branchName": "2.5", + "slug": "2.5", + "maintained": false + } + ] +} diff --git a/app/vendor/doctrine/dbal/LICENSE b/app/vendor/doctrine/dbal/LICENSE new file mode 100644 index 000000000..e8fdec4af --- /dev/null +++ b/app/vendor/doctrine/dbal/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006-2018 Doctrine Project + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/vendor/doctrine/dbal/README.md b/app/vendor/doctrine/dbal/README.md new file mode 100644 index 000000000..8a5767338 --- /dev/null +++ b/app/vendor/doctrine/dbal/README.md @@ -0,0 +1,45 @@ +# Doctrine DBAL + +| [Master][Master] | [2.8][2.8] | [Develop][develop] | +|:----------------:|:----------:|:------------------:| +| [![Build status][Master image]][Master] | [![Build status][2.8 image]][2.8] | [![Build status][develop image]][develop] | +| [![Build Status][ContinuousPHP image]][ContinuousPHP] | [![Build Status][ContinuousPHP 2.8 image]][ContinuousPHP] | [![Build Status][ContinuousPHP develop image]][ContinuousPHP] | +| [![Code Coverage][Coverage image]][Scrutinizer Master] | [![Code Coverage][Coverage 2.8 image]][Scrutinizer 2.8] | [![Code Coverage][Coverage develop image]][Scrutinizer develop] | +| [![Code Quality][Quality image]][Scrutinizer Master] | [![Code Quality][Quality 2.8 image]][Scrutinizer 2.8] | [![Code Quality][Quality develop image]][Scrutinizer develop] | +| [![AppVeyor][AppVeyor master image]][AppVeyor master] | [![AppVeyor][AppVeyor 2.8 image]][AppVeyor 2.8] | [![AppVeyor][AppVeyor develop image]][AppVeyor develop] | + +Powerful database abstraction layer with many features for database schema introspection, schema management and PDO abstraction. + +## More resources: + +* [Website](http://www.doctrine-project.org/projects/dbal.html) +* [Documentation](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/) +* [Issue Tracker](https://github.com/doctrine/dbal/issues) + + + [Master image]: https://img.shields.io/travis/doctrine/dbal/master.svg?style=flat-square + [Coverage image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/master.svg?style=flat-square + [Quality image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/master.svg?style=flat-square + [ContinuousPHP image]: https://img.shields.io/continuousphp/git-hub/doctrine/dbal/master.svg?style=flat-square + [Master]: https://travis-ci.org/doctrine/dbal + [Scrutinizer Master]: https://scrutinizer-ci.com/g/doctrine/dbal/ + [AppVeyor master]: https://ci.appveyor.com/project/doctrine/dbal/branch/master + [AppVeyor master image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/master?svg=true + [ContinuousPHP]: https://continuousphp.com/git-hub/doctrine/dbal + [2.8 image]: https://img.shields.io/travis/doctrine/dbal/2.8.svg?style=flat-square + [Coverage 2.8 image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/2.8.svg?style=flat-square + [Quality 2.8 image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/2.8.svg?style=flat-square + [ContinuousPHP 2.8 image]: https://img.shields.io/continuousphp/git-hub/doctrine/dbal/2.8.svg?style=flat-square + [2.8]: https://github.com/doctrine/dbal/tree/2.8 + [Scrutinizer 2.8]: https://scrutinizer-ci.com/g/doctrine/dbal/?branch=2.8 + [AppVeyor 2.8]: https://ci.appveyor.com/project/doctrine/dbal/branch/2.8 + [AppVeyor 2.8 image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/2.8?svg=true + [develop]: https://github.com/doctrine/dbal/tree/develop + [develop image]: https://img.shields.io/travis/doctrine/dbal/develop.svg?style=flat-square + [Coverage develop image]: https://img.shields.io/scrutinizer/coverage/g/doctrine/dbal/develop.svg?style=flat-square + [Quality develop image]: https://img.shields.io/scrutinizer/g/doctrine/dbal/develop.svg?style=flat-square + [ContinuousPHP develop image]: https://img.shields.io/continuousphp/git-hub/doctrine/dbal/develop.svg?style=flat-square + [develop]: https://github.com/doctrine/dbal/tree/develop + [Scrutinizer develop]: https://scrutinizer-ci.com/g/doctrine/dbal/?branch=develop + [AppVeyor develop]: https://ci.appveyor.com/project/doctrine/dbal/branch/develop + [AppVeyor develop image]: https://ci.appveyor.com/api/projects/status/i88kitq8qpbm0vie/branch/develop?svg=true diff --git a/app/vendor/doctrine/dbal/SECURITY.md b/app/vendor/doctrine/dbal/SECURITY.md new file mode 100644 index 000000000..e18f0dd78 --- /dev/null +++ b/app/vendor/doctrine/dbal/SECURITY.md @@ -0,0 +1,14 @@ +Security +======== + +The Doctrine library is operating very close to your database and as such needs +to handle and make assumptions about SQL injection vulnerabilities. + +It is vital that you understand how Doctrine approaches security, because +we cannot protect you from SQL injection. + +Please read the documentation chapter on Security in Doctrine DBAL to +understand the assumptions we make. + +- [Latest security.rst page on Github](https://github.com/doctrine/dbal/blob/master/docs/en/reference/security.rst) +- [Security Page in rendered documentation](http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/security.html) diff --git a/app/vendor/doctrine/dbal/UPGRADE.md b/app/vendor/doctrine/dbal/UPGRADE.md new file mode 100644 index 000000000..53bf9420d --- /dev/null +++ b/app/vendor/doctrine/dbal/UPGRADE.md @@ -0,0 +1,359 @@ +# Upgrade to 2.9 + +## Deprecated `Statement::fetchColumn()` with an invalid index + +Calls to `Statement::fetchColumn()` with an invalid column index currently return `NULL`. In the future, such calls will result in a exception. + +## Deprecated `Configuration::getFilterSchemaAssetsExpression()`, `::setFilterSchemaAssetsExpression()` and `AbstractSchemaManager::getFilterSchemaAssetsExpression()`. + +Regular expression-based filters are hard to extend by combining together. Instead, you may use callback-based filers via `::getSchemaAssetsFilter()` and `::getSchemaAssetsFilter()`. Callbacks can use regular expressions internally. + +## Deprecated `Doctrine\DBAL\Types\Type::getDefaultLength()` + +This method was never used by DBAL internally. It is now deprecated and will be removed in DBAL 3.0. + +## Deprecated `Doctrine\DBAL\Types\Type::__toString()` + +Relying on string representation is discouraged and will be removed in DBAL 3.0. + +## Deprecated `NULL` value of `$offset` in LIMIT queries + +The `NULL` value of the `$offset` argument in `AbstractPlatform::(do)?ModifyLimitQuery()` methods is deprecated. If explicitly used in the method call, the absence of the offset should be indicated with a `0`. + +## Deprecated dbal:import CLI command + +The `dbal:import` CLI command has been deprecated since it only works with PDO-based drivers by relying on a non-documented behavior of the extension, and it's impossible to make it work with other drivers. +Please use other database client applications for import, e.g.: + + * For MySQL and MariaDB: `mysql [dbname] < data.sql`. + * For PostgreSQL: `psql [dbname] < data.sql`. + * For SQLite: `sqlite3 /path/to/file.db < data.sql`. + +# Upgrade to 2.8 + +## Deprecated usage of DB-generated UUIDs + +The format of DB-generated UUIDs is inconsistent across supported platforms and therefore is not portable. Some of the platforms produce UUIDv1, some produce UUIDv4, some produce the values which are not even UUID. + +Unless UUIDs are used in stored procedures which DBAL doesn't support, there's no real benefit of DB-generated UUIDs comparing to the application-generated ones. + +Use a PHP library (e.g. [ramsey/uuid](https://packagist.org/packages/ramsey/uuid)) to generate UUIDs on the application side. + +## Deprecated usage of binary fields whose length exceeds the platform maximum + +- The usage of binary fields whose length exceeds the maximum field size on a given platform is deprecated. + Use binary fields of a size which fits all target platforms, or use blob explicitly instead. + +## Removed dependency on doctrine/common + +The dependency on doctrine/common package has been removed. +DBAL now depends on doctrine/cache and doctrine/event-manager instead. +If you are using any other component from doctrine/common package, +you will have to add an explicit dependency to your composer.json. + +## Corrected exception thrown by ``Doctrine\DBAL\Platforms\SQLAnywhere16Platform::getAdvancedIndexOptionsSQL()`` + +This method now throws SPL ``UnexpectedValueException`` instead of accidentally throwing ``Doctrine\Common\Proxy\Exception\UnexpectedValueException``. + +# Upgrade to 2.7 + +## Doctrine\DBAL\Platforms\AbstractPlatform::DATE_INTERVAL_UNIT_* constants deprecated + +``Doctrine\DBAL\Platforms\AbstractPlatform::DATE_INTERVAL_UNIT_*`` constants were moved into ``Doctrine\DBAL\Platforms\DateIntervalUnit`` class without the ``DATE_INTERVAL_UNIT_`` prefix. + +## Doctrine\DBAL\Platforms\AbstractPlatform::TRIM_* constants deprecated + +``Doctrine\DBAL\Platforms\AbstractPlatform::TRIM_*`` constants were moved into ``Doctrine\DBAL\Platforms\TrimMode`` class without the ``TRIM_`` prefix. + +## Doctrine\DBAL\Connection::TRANSACTION_* constants deprecated + +``Doctrine\DBAL\Connection::TRANSACTION_*`` were moved into ``Doctrine\DBAL\TransactionIsolationLevel`` class without the ``TRANSACTION_`` prefix. + +## DEPRECATION: direct usage of the PDO APIs in the DBAL API + +1. When calling `Doctrine\DBAL\Driver\Statement` methods, instead of `PDO::PARAM_*` constants, `Doctrine\DBAL\ParameterType` constants should be used. +2. When calling `Doctrine\DBAL\Driver\ResultStatement` methods, instead of `PDO::FETCH_*` constants, `Doctrine\DBAL\FetchMode` constants should be used. +3. When configuring `Doctrine\DBAL\Portability\Connection`, instead of `PDO::CASE_*` constants, `Doctrine\DBAL\ColumnCase` constants should be used. +4. Usage of `PDO::PARAM_INPUT_OUTPUT` in `Doctrine\DBAL\Driver\Statement::bindValue()` is deprecated. +5. Usage of `PDO::FETCH_FUNC` in `Doctrine\DBAL\Driver\ResultStatement::fetch()` is deprecated. +6. Calls to `\PDOStatement` methods on a `\Doctrine\DBAL\Driver\PDOStatement` instance (e.g. `fetchObject()`) are deprecated. + +# Upgrade to 2.6 + +## MINOR BC BREAK: `fetch()` and `fetchAll()` method signatures in `Doctrine\DBAL\Driver\ResultStatement` + +1. ``Doctrine\DBAL\Driver\ResultStatement::fetch()`` now has 3 arguments instead of 1, respecting +``PDO::fetch()`` signature. + +Before: + + Doctrine\DBAL\Driver\ResultStatement::fetch($fetchMode); + +After: + + Doctrine\DBAL\Driver\ResultStatement::fetch($fetchMode, $cursorOrientation, $cursorOffset); + +2. ``Doctrine\DBAL\Driver\ResultStatement::fetchAll()`` now has 3 arguments instead of 1, respecting +``PDO::fetchAll()`` signature. + +Before: + + Doctrine\DBAL\Driver\ResultStatement::fetchAll($fetchMode); + +After: + + Doctrine\DBAL\Driver\ResultStatement::fetch($fetchMode, $fetchArgument, $ctorArgs); + + +## MINOR BC BREAK: URL-style DSN with percentage sign in password + +URL-style DSNs (e.g. ``mysql://foo@bar:localhost/db``) are now assumed to be percent-encoded +in order to allow certain special characters in usernames, paswords and database names. If +you are using a URL-style DSN and have a username, password or database name containing a +percentage sign, you need to update your DSN. If your password is, say, ``foo%foo``, it +should be encoded as ``foo%25foo``. + +# Upgrade to 2.5.1 + +## MINOR BC BREAK: Doctrine\DBAL\Schema\Table + +When adding indexes to ``Doctrine\DBAL\Schema\Table`` via ``addIndex()`` or ``addUniqueIndex()``, +duplicate indexes are not silently ignored/dropped anymore (based on semantics, not naming!). +Duplicate indexes are considered indexes that pass ``isFullfilledBy()`` or ``overrules()`` +in ``Doctrine\DBAL\Schema\Index``. +This is required to make the index renaming feature introduced in 2.5.0 work properly and avoid +issues in the ORM schema tool / DBAL schema manager which pretends users from updating +their schemas and migrate to DBAL 2.5.*. +Additionally it offers more flexibility in declaring indexes for the user and potentially fixes +related issues in the ORM. +With this change, the responsibility to decide which index is a "duplicate" is completely deferred +to the user. +Please also note that adding foreign key constraints to a table via ``addForeignKeyConstraint()``, +``addUnnamedForeignKeyConstraint()`` or ``addNamedForeignKeyConstraint()`` now first checks if an +appropriate index is already present and avoids adding an additional auto-generated one eventually. + +# Upgrade to 2.5 + +## BC BREAK: time type resets date fields to UNIX epoch + +When mapping `time` type field to PHP's `DateTime` instance all unused date fields are +reset to UNIX epoch (i.e. 1970-01-01). This might break any logic which relies on comparing +`DateTime` instances with date fields set to the current date. + +Use `!` format prefix (see http://php.net/manual/en/datetime.createfromformat.php) for parsing +time strings to prevent having different date fields when comparing user input and `DateTime` +instances as mapped by Doctrine. + +## BC BREAK: Doctrine\DBAL\Schema\Table + +The methods ``addIndex()`` and ``addUniqueIndex()`` in ``Doctrine\DBAL\Schema\Table`` +have an additional, optional parameter. If you override these methods, you should +add this new parameter to the declaration of your overridden methods. + +## BC BREAK: Doctrine\DBAL\Connection + +The visibility of the property ``$_platform`` in ``Doctrine\DBAL\Connection`` +was changed from protected to private. If you have subclassed ``Doctrine\DBAL\Connection`` +in your application and accessed ``$_platform`` directly, you have to change the code +portions to use ``getDatabasePlatform()`` instead to retrieve the underlying database +platform. +The reason for this change is the new automatic platform version detection feature, +which lazily evaluates the appropriate platform class to use for the underlying database +server version at runtime. +Please also note, that calling ``getDatabasePlatform()`` now needs to establish a connection +in order to evaluate the appropriate platform class if ``Doctrine\DBAL\Connection`` is not +already connected. Under the following circumstances, it is not possible anymore to retrieve +the platform instance from the connection object without having to do a real connect: + +1. ``Doctrine\DBAL\Connection`` was instantiated without the ``platform`` connection parameter. +2. ``Doctrine\DBAL\Connection`` was instantiated without the ``serverVersion`` connection parameter. +3. The underlying driver is "version aware" and can provide different platform instances + for different versions. +4. The underlying driver connection is "version aware" and can provide the database server + version without having to query for it. + +If one of the above conditions is NOT met, there is no need for ``Doctrine\DBAL\Connection`` +to do a connect when calling ``getDatabasePlatform()``. + +## datetime Type uses date_create() as fallback + +Before 2.5 the DateTime type always required a specific format, defined in +`$platform->getDateTimeFormatString()`, which could cause quite some troubles +on platforms that had various microtime precision formats. Starting with 2.5 +whenever the parsing of a date fails with the predefined platform format, +the `date_create()` function will be used to parse the date. + +This could cause some troubles when your date format is weird and not parsed +correctly by `date_create`, however since databases are rather strict on dates +there should be no problem. + +## Support for pdo_ibm driver removed + +The ``pdo_ibm`` driver is buggy and does not work well with Doctrine. Therefore it will no +longer be supported and has been removed from the ``Doctrine\DBAL\DriverManager`` drivers +map. It is highly encouraged to to use `ibm_db2` driver instead if you want to connect +to an IBM DB2 database as it is much more stable and secure. + +If for some reason you have to utilize the ``pdo_ibm`` driver you can still use the `driverClass` +connection parameter to explicitly specify the ``Doctrine\DBAL\Driver\PDOIbm\Driver`` class. +However be aware that you are doing this at your own risk and it will not be guaranteed that +Doctrine will work as expected. + +# Upgrade to 2.4 + +## Doctrine\DBAL\Schema\Constraint + +If you have custom classes that implement the constraint interface, you have to implement +an additional method ``getQuotedColumns`` now. This method is used to build proper constraint +SQL for columns that need to be quoted, like keywords reserved by the specific platform used. +The method has to return the same values as ``getColumns`` only that those column names that +need quotation have to be returned quoted for the given platform. + +# Upgrade to 2.3 + +## Oracle Session Init now sets Numeric Character + +Before 2.3 the Oracle Session Init did not care about the numeric character of the Session. +This could lead to problems on non english locale systems that required a comma as a floating +point seperator in Oracle. Since 2.3, using the Oracle Session Init on connection start the +client session will be altered to set the numeric character to ".,": + + ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,' + +See [DBAL-345](http://www.doctrine-project.org/jira/browse/DBAL-345) for more details. + +## Doctrine\DBAL\Connection and Doctrine\DBAL\Statement + +The query related methods including but not limited to executeQuery, exec, query, and executeUpdate +now wrap the driver exceptions such as PDOException with DBALException to add more debugging +information such as the executed SQL statement, and any bound parameters. + +If you want to retrieve the driver specific exception, you can retrieve it by calling the +``getPrevious()`` method on DBALException. + +Before: + + catch(\PDOException $ex) { + // ... + } + +After: + + catch(\Doctrine\DBAL\DBALException $ex) { + $pdoException = $ex->getPrevious(); + // ... + } + +## Doctrine\DBAL\Connection#setCharsetSQL() removed + +This method only worked on MySQL and it is considered unsafe on MySQL to use SET NAMES UTF-8 instead +of setting the charset directly on connection already. Replace this behavior with the +connection charset option: + +Before: + + $conn = DriverManager::getConnection(array(..)); + $conn->setCharset('UTF8'); + +After: + + $conn = DriverManager::getConnection(array('charset' => 'UTF8', ..)); + +## Doctrine\DBAL\Schema\Table#renameColumn() removed + +Doctrine\DBAL\Schema\Table#renameColumn() was removed, because it drops and recreates +the column instead. There is no fix available, because a schema diff +cannot reliably detect if a column was renamed or one column was created +and another one dropped. + +You should use explicit SQL ALTER TABLE statements to change columns names. + +## Schema Filter paths + +The Filter Schema assets expression is not wrapped in () anymore for the regexp automatically. + +Before: + + $config->setFilterSchemaAssetsExpression('foo'); + +After: + + $config->setFilterSchemaAssetsExpression('(foo)'); + +## Creating MySQL Tables now defaults to UTF-8 + +If you are creating a new MySQL Table through the Doctrine API, charset/collate are +now set to 'utf8'/'utf8_unicode_ci' by default. Previously the MySQL server defaults were used. + +# Upgrade to 2.2 + +## Doctrine\DBAL\Connection#insert and Doctrine\DBAL\Connection#update + +Both methods now accept an optional last parameter $types with binding types of the values passed. +This can potentially break child classes that have overwritten one of these methods. + +## Doctrine\DBAL\Connection#executeQuery + +Doctrine\DBAL\Connection#executeQuery() got a new last parameter "QueryCacheProfile $qcp" + +## Doctrine\DBAL\Driver\Statement split + +The Driver statement was split into a ResultStatement and the normal statement extending from it. +This separates the configuration and the retrieval API from a statement. + +## MsSql Platform/SchemaManager renamed + +The MsSqlPlatform was renamed to SQLServerPlatform, the MsSqlSchemaManager was renamed +to SQLServerSchemaManager. + +## Cleanup SQLServer Platform version mess + +DBAL 2.1 and before were actually only compatible to SQL Server 2008, not earlier versions. +Still other parts of the platform did use old features instead of newly introduced datatypes +in SQL Server 2005. Starting with DBAL 2.2 you can pick the Doctrine abstraction exactly +matching your SQL Server version. + +The PDO SqlSrv driver now uses the new `SQLServer2008Platform` as default platform. +This platform uses new features of SQL Server as of version 2008. This also includes a switch +in the used fields for "text" and "blob" field types to: + + "text" => "VARCHAR(MAX)" + "blob" => "VARBINARY(MAX)" + +Additionally `SQLServerPlatform` in DBAL 2.1 and before used "DATE", "TIME" and "DATETIME2" for dates. +This types are only available since version 2008 and the introduction of an explicit +SQLServer 2008 platform makes this dependency explicit. + +An `SQLServer2005Platform` was also introduced to differentiate the features between +versions 2003, earlier and 2005. + +With this change the `SQLServerPlatform` now throws an exception for using limit queries +with an offset, since SQLServer 2003 and lower do not support this feature. + +To use the old SQL Server Platform, because you are using SQL Server 2003 and below use +the following configuration code: + + use Doctrine\DBAL\DriverManager; + use Doctrine\DBAL\Platforms\SQLServerPlatform; + use Doctrine\DBAL\Platforms\SQLServer2005Platform; + + // You are using SQL Server 2003 or earlier + $conn = DriverManager::getConnection(array( + 'driver' => 'pdo_sqlsrv', + 'platform' => new SQLServerPlatform() + // .. additional parameters + )); + + // You are using SQL Server 2005 + $conn = DriverManager::getConnection(array( + 'driver' => 'pdo_sqlsrv', + 'platform' => new SQLServer2005Platform() + // .. additional parameters + )); + + // You are using SQL Server 2008 + $conn = DriverManager::getConnection(array( + 'driver' => 'pdo_sqlsrv', + // 2008 is default platform + // .. additional parameters + )); diff --git a/app/vendor/doctrine/dbal/bin/doctrine-dbal b/app/vendor/doctrine/dbal/bin/doctrine-dbal new file mode 100755 index 000000000..0531527dd --- /dev/null +++ b/app/vendor/doctrine/dbal/bin/doctrine-dbal @@ -0,0 +1,4 @@ +#!/usr/bin/env php +data = $data; + if (! count($data)) { + return; + } + + $this->columnCount = count($data[0]); + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + unset($this->data); + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return $this->columnCount; + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + if ($arg2 !== null || $arg3 !== null) { + throw new InvalidArgumentException('Caching layer does not support 2nd/3rd argument to setFetchMode()'); + } + + $this->defaultFetchMode = $fetchMode; + + return true; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + $data = $this->fetchAll(); + + return new ArrayIterator($data); + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + if (! isset($this->data[$this->num])) { + return false; + } + + $row = $this->data[$this->num++]; + $fetchMode = $fetchMode ?: $this->defaultFetchMode; + + if ($fetchMode === FetchMode::ASSOCIATIVE) { + return $row; + } + + if ($fetchMode === FetchMode::NUMERIC) { + return array_values($row); + } + + if ($fetchMode === FetchMode::MIXED) { + return array_merge($row, array_values($row)); + } + + if ($fetchMode === FetchMode::COLUMN) { + return reset($row); + } + + throw new InvalidArgumentException('Invalid fetch-style given for fetching result.'); + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $rows = []; + while ($row = $this->fetch($fetchMode)) { + $rows[] = $row; + } + + return $rows; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(FetchMode::NUMERIC); + + // TODO: verify that return false is the correct behavior + return $row[$columnIndex] ?? false; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php new file mode 100644 index 000000000..636c948a6 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/CacheException.php @@ -0,0 +1,24 @@ +lifetime = $lifetime; + $this->cacheKey = $cacheKey; + $this->resultCacheDriver = $resultCache; + } + + /** + * @return Cache|null + */ + public function getResultCacheDriver() + { + return $this->resultCacheDriver; + } + + /** + * @return int + */ + public function getLifetime() + { + return $this->lifetime; + } + + /** + * @return string + * + * @throws CacheException + */ + public function getCacheKey() + { + if ($this->cacheKey === null) { + throw CacheException::noCacheKey(); + } + + return $this->cacheKey; + } + + /** + * Generates the real cache key from query, params, types and connection parameters. + * + * @param string $query + * @param mixed[] $params + * @param int[]|string[] $types + * @param mixed[] $connectionParams + * + * @return string[] + */ + public function generateCacheKeys($query, $params, $types, array $connectionParams = []) + { + $realCacheKey = 'query=' . $query . + '¶ms=' . serialize($params) . + '&types=' . serialize($types) . + '&connectionParams=' . hash('sha256', serialize($connectionParams)); + + // should the key be automatically generated using the inputs or is the cache key set? + if ($this->cacheKey === null) { + $cacheKey = sha1($realCacheKey); + } else { + $cacheKey = $this->cacheKey; + } + + return [$cacheKey, $realCacheKey]; + } + + /** + * @return \Doctrine\DBAL\Cache\QueryCacheProfile + */ + public function setResultCacheDriver(Cache $cache) + { + return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache); + } + + /** + * @param string|null $cacheKey + * + * @return \Doctrine\DBAL\Cache\QueryCacheProfile + */ + public function setCacheKey($cacheKey) + { + return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCacheDriver); + } + + /** + * @param int $lifetime + * + * @return \Doctrine\DBAL\Cache\QueryCacheProfile + */ + public function setLifetime($lifetime) + { + return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCacheDriver); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php new file mode 100644 index 000000000..721709a0d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Cache/ResultCacheStatement.php @@ -0,0 +1,201 @@ +statement = $stmt; + $this->resultCache = $resultCache; + $this->cacheKey = $cacheKey; + $this->realKey = $realKey; + $this->lifetime = $lifetime; + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + $this->statement->closeCursor(); + if (! $this->emptied || $this->data === null) { + return true; + } + + $data = $this->resultCache->fetch($this->cacheKey); + if (! $data) { + $data = []; + } + $data[$this->realKey] = $this->data; + + $this->resultCache->save($this->cacheKey, $data, $this->lifetime); + unset($this->data); + + return true; + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return $this->statement->columnCount(); + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + $this->defaultFetchMode = $fetchMode; + + return true; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + $data = $this->fetchAll(); + + return new ArrayIterator($data); + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + if ($this->data === null) { + $this->data = []; + } + + $row = $this->statement->fetch(FetchMode::ASSOCIATIVE); + + if ($row) { + $this->data[] = $row; + + $fetchMode = $fetchMode ?: $this->defaultFetchMode; + + if ($fetchMode === FetchMode::ASSOCIATIVE) { + return $row; + } + + if ($fetchMode === FetchMode::NUMERIC) { + return array_values($row); + } + + if ($fetchMode === FetchMode::MIXED) { + return array_merge($row, array_values($row)); + } + + if ($fetchMode === FetchMode::COLUMN) { + return reset($row); + } + + throw new InvalidArgumentException('Invalid fetch-style given for caching result.'); + } + + $this->emptied = true; + + return false; + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $this->data = $this->statement->fetchAll($fetchMode, $fetchArgument, $ctorArgs); + $this->emptied = true; + + return $this->data; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(FetchMode::NUMERIC); + + // TODO: verify that return false is the correct behavior + return $row[$columnIndex] ?? false; + } + + /** + * Returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement + * executed by the corresponding object. + * + * If the last SQL statement executed by the associated Statement object was a SELECT statement, + * some databases may return the number of rows returned by that statement. However, + * this behaviour is not guaranteed for all databases and should not be + * relied on for portable applications. + * + * @return int The number of rows. + */ + public function rowCount() + { + return $this->statement->rowCount(); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ColumnCase.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ColumnCase.php new file mode 100644 index 000000000..872d3ede8 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ColumnCase.php @@ -0,0 +1,32 @@ +_attributes['sqlLogger'] = $logger; + } + + /** + * Gets the SQL logger that is used. + * + * @return SQLLogger|null + */ + public function getSQLLogger() + { + return $this->_attributes['sqlLogger'] ?? null; + } + + /** + * Gets the cache driver implementation that is used for query result caching. + * + * @return Cache|null + */ + public function getResultCacheImpl() + { + return $this->_attributes['resultCacheImpl'] ?? null; + } + + /** + * Sets the cache driver implementation that is used for query result caching. + * + * @return void + */ + public function setResultCacheImpl(Cache $cacheImpl) + { + $this->_attributes['resultCacheImpl'] = $cacheImpl; + } + + /** + * Sets the filter schema assets expression. + * + * Only include tables/sequences matching the filter expression regexp in + * schema instances generated for the active connection when calling + * {AbstractSchemaManager#createSchema()}. + * + * @deprecated Use Configuration::setSchemaAssetsFilter() instead + * + * @param string $filterExpression + * + * @return void + */ + public function setFilterSchemaAssetsExpression($filterExpression) + { + $this->_attributes['filterSchemaAssetsExpression'] = $filterExpression; + if ($filterExpression) { + $this->_attributes['filterSchemaAssetsExpressionCallable'] = $this->buildSchemaAssetsFilterFromExpression($filterExpression); + } else { + $this->_attributes['filterSchemaAssetsExpressionCallable'] = null; + } + } + + /** + * Returns filter schema assets expression. + * + * @deprecated Use Configuration::getSchemaAssetsFilter() instead + * + * @return string|null + */ + public function getFilterSchemaAssetsExpression() + { + return $this->_attributes['filterSchemaAssetsExpression'] ?? null; + } + + /** + * @param string $filterExpression + */ + private function buildSchemaAssetsFilterFromExpression($filterExpression) : callable + { + return static function ($assetName) use ($filterExpression) { + if ($assetName instanceof AbstractAsset) { + $assetName = $assetName->getName(); + } + return preg_match($filterExpression, $assetName); + }; + } + + /** + * Sets the callable to use to filter schema assets. + */ + public function setSchemaAssetsFilter(?callable $callable = null) : ?callable + { + $this->_attributes['filterSchemaAssetsExpression'] = null; + return $this->_attributes['filterSchemaAssetsExpressionCallable'] = $callable; + } + + /** + * Returns the callable to use to filter schema assets. + */ + public function getSchemaAssetsFilter() : ?callable + { + return $this->_attributes['filterSchemaAssetsExpressionCallable'] ?? null; + } + + /** + * Sets the default auto-commit mode for connections. + * + * If a connection is in auto-commit mode, then all its SQL statements will be executed and committed as individual + * transactions. Otherwise, its SQL statements are grouped into transactions that are terminated by a call to either + * the method commit or the method rollback. By default, new connections are in auto-commit mode. + * + * @see getAutoCommit + * + * @param bool $autoCommit True to enable auto-commit mode; false to disable it. + */ + public function setAutoCommit($autoCommit) + { + $this->_attributes['autoCommit'] = (bool) $autoCommit; + } + + /** + * Returns the default auto-commit mode for connections. + * + * @see setAutoCommit + * + * @return bool True if auto-commit mode is enabled by default for connections, false otherwise. + */ + public function getAutoCommit() + { + return $this->_attributes['autoCommit'] ?? true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php new file mode 100644 index 000000000..85761fcca --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php @@ -0,0 +1,1678 @@ +_driver = $driver; + $this->params = $params; + + if (isset($params['pdo'])) { + $this->_conn = $params['pdo']; + $this->isConnected = true; + unset($this->params['pdo']); + } + + if (isset($params['platform'])) { + if (! $params['platform'] instanceof Platforms\AbstractPlatform) { + throw DBALException::invalidPlatformType($params['platform']); + } + + $this->platform = $params['platform']; + unset($this->params['platform']); + } + + // Create default config and event manager if none given + if (! $config) { + $config = new Configuration(); + } + + if (! $eventManager) { + $eventManager = new EventManager(); + } + + $this->_config = $config; + $this->_eventManager = $eventManager; + + $this->_expr = new Query\Expression\ExpressionBuilder($this); + + $this->autoCommit = $config->getAutoCommit(); + } + + /** + * Gets the parameters used during instantiation. + * + * @return mixed[] + */ + public function getParams() + { + return $this->params; + } + + /** + * Gets the name of the database this Connection is connected to. + * + * @return string + */ + public function getDatabase() + { + return $this->_driver->getDatabase($this); + } + + /** + * Gets the hostname of the currently connected database. + * + * @return string|null + */ + public function getHost() + { + return $this->params['host'] ?? null; + } + + /** + * Gets the port of the currently connected database. + * + * @return mixed + */ + public function getPort() + { + return $this->params['port'] ?? null; + } + + /** + * Gets the username used by this connection. + * + * @return string|null + */ + public function getUsername() + { + return $this->params['user'] ?? null; + } + + /** + * Gets the password used by this connection. + * + * @return string|null + */ + public function getPassword() + { + return $this->params['password'] ?? null; + } + + /** + * Gets the DBAL driver instance. + * + * @return Driver + */ + public function getDriver() + { + return $this->_driver; + } + + /** + * Gets the Configuration used by the Connection. + * + * @return Configuration + */ + public function getConfiguration() + { + return $this->_config; + } + + /** + * Gets the EventManager used by the Connection. + * + * @return EventManager + */ + public function getEventManager() + { + return $this->_eventManager; + } + + /** + * Gets the DatabasePlatform for the connection. + * + * @return AbstractPlatform + * + * @throws DBALException + */ + public function getDatabasePlatform() + { + if ($this->platform === null) { + $this->detectDatabasePlatform(); + } + + return $this->platform; + } + + /** + * Gets the ExpressionBuilder for the connection. + * + * @return ExpressionBuilder + */ + public function getExpressionBuilder() + { + return $this->_expr; + } + + /** + * Establishes the connection with the database. + * + * @return bool TRUE if the connection was successfully established, FALSE if + * the connection is already open. + */ + public function connect() + { + if ($this->isConnected) { + return false; + } + + $driverOptions = $this->params['driverOptions'] ?? []; + $user = $this->params['user'] ?? null; + $password = $this->params['password'] ?? null; + + $this->_conn = $this->_driver->connect($this->params, $user, $password, $driverOptions); + $this->isConnected = true; + + if ($this->autoCommit === false) { + $this->beginTransaction(); + } + + if ($this->_eventManager->hasListeners(Events::postConnect)) { + $eventArgs = new Event\ConnectionEventArgs($this); + $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs); + } + + return true; + } + + /** + * Detects and sets the database platform. + * + * Evaluates custom platform class and version in order to set the correct platform. + * + * @throws DBALException If an invalid platform was specified for this connection. + */ + private function detectDatabasePlatform() + { + $version = $this->getDatabasePlatformVersion(); + + if ($version !== null) { + assert($this->_driver instanceof VersionAwarePlatformDriver); + + $this->platform = $this->_driver->createDatabasePlatformForVersion($version); + } else { + $this->platform = $this->_driver->getDatabasePlatform(); + } + + $this->platform->setEventManager($this->_eventManager); + } + + /** + * Returns the version of the related platform if applicable. + * + * Returns null if either the driver is not capable to create version + * specific platform instances, no explicit server version was specified + * or the underlying driver connection cannot determine the platform + * version without having to query it (performance reasons). + * + * @return string|null + * + * @throws Exception + */ + private function getDatabasePlatformVersion() + { + // Driver does not support version specific platforms. + if (! $this->_driver instanceof VersionAwarePlatformDriver) { + return null; + } + + // Explicit platform version requested (supersedes auto-detection). + if (isset($this->params['serverVersion'])) { + return $this->params['serverVersion']; + } + + // If not connected, we need to connect now to determine the platform version. + if ($this->_conn === null) { + try { + $this->connect(); + } catch (Throwable $originalException) { + if (empty($this->params['dbname'])) { + throw $originalException; + } + + // The database to connect to might not yet exist. + // Retry detection without database name connection parameter. + $databaseName = $this->params['dbname']; + $this->params['dbname'] = null; + + try { + $this->connect(); + } catch (Throwable $fallbackException) { + // Either the platform does not support database-less connections + // or something else went wrong. + // Reset connection parameters and rethrow the original exception. + $this->params['dbname'] = $databaseName; + + throw $originalException; + } + + // Reset connection parameters. + $this->params['dbname'] = $databaseName; + $serverVersion = $this->getServerVersion(); + + // Close "temporary" connection to allow connecting to the real database again. + $this->close(); + + return $serverVersion; + } + } + + return $this->getServerVersion(); + } + + /** + * Returns the database server version if the underlying driver supports it. + * + * @return string|null + */ + private function getServerVersion() + { + // Automatic platform version detection. + if ($this->_conn instanceof ServerInfoAwareConnection && + ! $this->_conn->requiresQueryForServerVersion() + ) { + return $this->_conn->getServerVersion(); + } + + // Unable to detect platform version. + return null; + } + + /** + * Returns the current auto-commit mode for this connection. + * + * @see setAutoCommit + * + * @return bool True if auto-commit mode is currently enabled for this connection, false otherwise. + */ + public function isAutoCommit() + { + return $this->autoCommit === true; + } + + /** + * Sets auto-commit mode for this connection. + * + * If a connection is in auto-commit mode, then all its SQL statements will be executed and committed as individual + * transactions. Otherwise, its SQL statements are grouped into transactions that are terminated by a call to either + * the method commit or the method rollback. By default, new connections are in auto-commit mode. + * + * NOTE: If this method is called during a transaction and the auto-commit mode is changed, the transaction is + * committed. If this method is called and the auto-commit mode is not changed, the call is a no-op. + * + * @see isAutoCommit + * + * @param bool $autoCommit True to enable auto-commit mode; false to disable it. + */ + public function setAutoCommit($autoCommit) + { + $autoCommit = (bool) $autoCommit; + + // Mode not changed, no-op. + if ($autoCommit === $this->autoCommit) { + return; + } + + $this->autoCommit = $autoCommit; + + // Commit all currently active transactions if any when switching auto-commit mode. + if ($this->isConnected !== true || $this->transactionNestingLevel === 0) { + return; + } + + $this->commitAll(); + } + + /** + * Sets the fetch mode. + * + * @param int $fetchMode + * + * @return void + */ + public function setFetchMode($fetchMode) + { + $this->defaultFetchMode = $fetchMode; + } + + /** + * Prepares and executes an SQL query and returns the first row of the result + * as an associative array. + * + * @param string $statement The SQL query. + * @param mixed[] $params The query parameters. + * @param int[]|string[] $types The query parameter types. + * + * @return mixed[]|false False is returned if no rows are found. + * + * @throws DBALException + */ + public function fetchAssoc($statement, array $params = [], array $types = []) + { + return $this->executeQuery($statement, $params, $types)->fetch(FetchMode::ASSOCIATIVE); + } + + /** + * Prepares and executes an SQL query and returns the first row of the result + * as a numerically indexed array. + * + * @param string $statement The SQL query to be executed. + * @param mixed[] $params The prepared statement params. + * @param int[]|string[] $types The query parameter types. + * + * @return mixed[]|false False is returned if no rows are found. + */ + public function fetchArray($statement, array $params = [], array $types = []) + { + return $this->executeQuery($statement, $params, $types)->fetch(FetchMode::NUMERIC); + } + + /** + * Prepares and executes an SQL query and returns the value of a single column + * of the first row of the result. + * + * @param string $statement The SQL query to be executed. + * @param mixed[] $params The prepared statement params. + * @param int $column The 0-indexed column number to retrieve. + * @param int[]|string[] $types The query parameter types. + * + * @return mixed|false False is returned if no rows are found. + * + * @throws DBALException + */ + public function fetchColumn($statement, array $params = [], $column = 0, array $types = []) + { + return $this->executeQuery($statement, $params, $types)->fetchColumn($column); + } + + /** + * Whether an actual connection to the database is established. + * + * @return bool + */ + public function isConnected() + { + return $this->isConnected; + } + + /** + * Checks whether a transaction is currently active. + * + * @return bool TRUE if a transaction is currently active, FALSE otherwise. + */ + public function isTransactionActive() + { + return $this->transactionNestingLevel > 0; + } + + /** + * Gathers conditions for an update or delete call. + * + * @param mixed[] $identifiers Input array of columns to values + * + * @return string[][] a triplet with: + * - the first key being the columns + * - the second key being the values + * - the third key being the conditions + */ + private function gatherConditions(array $identifiers) + { + $columns = []; + $values = []; + $conditions = []; + + foreach ($identifiers as $columnName => $value) { + if ($value === null) { + $conditions[] = $this->getDatabasePlatform()->getIsNullExpression($columnName); + continue; + } + + $columns[] = $columnName; + $values[] = $value; + $conditions[] = $columnName . ' = ?'; + } + + return [$columns, $values, $conditions]; + } + + /** + * Executes an SQL DELETE statement on a table. + * + * Table expression and columns are not escaped and are not safe for user-input. + * + * @param string $tableExpression The expression of the table on which to delete. + * @param mixed[] $identifier The deletion criteria. An associative array containing column-value pairs. + * @param int[]|string[] $types The types of identifiers. + * + * @return int The number of affected rows. + * + * @throws DBALException + * @throws InvalidArgumentException + */ + public function delete($tableExpression, array $identifier, array $types = []) + { + if (empty($identifier)) { + throw InvalidArgumentException::fromEmptyCriteria(); + } + + [$columns, $values, $conditions] = $this->gatherConditions($identifier); + + return $this->executeUpdate( + 'DELETE FROM ' . $tableExpression . ' WHERE ' . implode(' AND ', $conditions), + $values, + is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types + ); + } + + /** + * Closes the connection. + * + * @return void + */ + public function close() + { + $this->_conn = null; + + $this->isConnected = false; + } + + /** + * Sets the transaction isolation level. + * + * @param int $level The level to set. + * + * @return int + */ + public function setTransactionIsolation($level) + { + $this->transactionIsolationLevel = $level; + + return $this->executeUpdate($this->getDatabasePlatform()->getSetTransactionIsolationSQL($level)); + } + + /** + * Gets the currently active transaction isolation level. + * + * @return int The current transaction isolation level. + */ + public function getTransactionIsolation() + { + if ($this->transactionIsolationLevel === null) { + $this->transactionIsolationLevel = $this->getDatabasePlatform()->getDefaultTransactionIsolationLevel(); + } + + return $this->transactionIsolationLevel; + } + + /** + * Executes an SQL UPDATE statement on a table. + * + * Table expression and columns are not escaped and are not safe for user-input. + * + * @param string $tableExpression The expression of the table to update quoted or unquoted. + * @param mixed[] $data An associative array containing column-value pairs. + * @param mixed[] $identifier The update criteria. An associative array containing column-value pairs. + * @param int[]|string[] $types Types of the merged $data and $identifier arrays in that order. + * + * @return int The number of affected rows. + * + * @throws DBALException + */ + public function update($tableExpression, array $data, array $identifier, array $types = []) + { + $setColumns = []; + $setValues = []; + $set = []; + + foreach ($data as $columnName => $value) { + $setColumns[] = $columnName; + $setValues[] = $value; + $set[] = $columnName . ' = ?'; + } + + [$conditionColumns, $conditionValues, $conditions] = $this->gatherConditions($identifier); + $columns = array_merge($setColumns, $conditionColumns); + $values = array_merge($setValues, $conditionValues); + + if (is_string(key($types))) { + $types = $this->extractTypeValues($columns, $types); + } + + $sql = 'UPDATE ' . $tableExpression . ' SET ' . implode(', ', $set) + . ' WHERE ' . implode(' AND ', $conditions); + + return $this->executeUpdate($sql, $values, $types); + } + + /** + * Inserts a table row with specified data. + * + * Table expression and columns are not escaped and are not safe for user-input. + * + * @param string $tableExpression The expression of the table to insert data into, quoted or unquoted. + * @param mixed[] $data An associative array containing column-value pairs. + * @param int[]|string[] $types Types of the inserted data. + * + * @return int The number of affected rows. + * + * @throws DBALException + */ + public function insert($tableExpression, array $data, array $types = []) + { + if (empty($data)) { + return $this->executeUpdate('INSERT INTO ' . $tableExpression . ' () VALUES ()'); + } + + $columns = []; + $values = []; + $set = []; + + foreach ($data as $columnName => $value) { + $columns[] = $columnName; + $values[] = $value; + $set[] = '?'; + } + + return $this->executeUpdate( + 'INSERT INTO ' . $tableExpression . ' (' . implode(', ', $columns) . ')' . + ' VALUES (' . implode(', ', $set) . ')', + $values, + is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types + ); + } + + /** + * Extract ordered type list from an ordered column list and type map. + * + * @param string[] $columnList + * @param int[]|string[] $types + * + * @return int[]|string[] + */ + private function extractTypeValues(array $columnList, array $types) + { + $typeValues = []; + + foreach ($columnList as $columnIndex => $columnName) { + $typeValues[] = $types[$columnName] ?? ParameterType::STRING; + } + + return $typeValues; + } + + /** + * Quotes a string so it can be safely used as a table or column name, even if + * it is a reserved name. + * + * Delimiting style depends on the underlying database platform that is being used. + * + * NOTE: Just because you CAN use quoted identifiers does not mean + * you SHOULD use them. In general, they end up causing way more + * problems than they solve. + * + * @param string $str The name to be quoted. + * + * @return string The quoted name. + */ + public function quoteIdentifier($str) + { + return $this->getDatabasePlatform()->quoteIdentifier($str); + } + + /** + * Quotes a given input parameter. + * + * @param mixed $input The parameter to be quoted. + * @param int|null $type The type of the parameter. + * + * @return string The quoted parameter. + */ + public function quote($input, $type = null) + { + $this->connect(); + + [$value, $bindingType] = $this->getBindingInfo($input, $type); + + return $this->_conn->quote($value, $bindingType); + } + + /** + * Prepares and executes an SQL query and returns the result as an associative array. + * + * @param string $sql The SQL query. + * @param mixed[] $params The query parameters. + * @param int[]|string[] $types The query parameter types. + * + * @return mixed[] + */ + public function fetchAll($sql, array $params = [], $types = []) + { + return $this->executeQuery($sql, $params, $types)->fetchAll(); + } + + /** + * Prepares an SQL statement. + * + * @param string $statement The SQL statement to prepare. + * + * @return DriverStatement The prepared statement. + * + * @throws DBALException + */ + public function prepare($statement) + { + try { + $stmt = new Statement($statement, $this); + } catch (Throwable $ex) { + throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement); + } + + $stmt->setFetchMode($this->defaultFetchMode); + + return $stmt; + } + + /** + * Executes an, optionally parametrized, SQL query. + * + * If the query is parametrized, a prepared statement is used. + * If an SQLLogger is configured, the execution is logged. + * + * @param string $query The SQL query to execute. + * @param mixed[] $params The parameters to bind to the query, if any. + * @param int[]|string[] $types The types the previous parameters are in. + * @param QueryCacheProfile|null $qcp The query cache profile, optional. + * + * @return ResultStatement The executed statement. + * + * @throws DBALException + */ + public function executeQuery($query, array $params = [], $types = [], ?QueryCacheProfile $qcp = null) + { + if ($qcp !== null) { + return $this->executeCacheQuery($query, $params, $types, $qcp); + } + + $this->connect(); + + $logger = $this->_config->getSQLLogger(); + if ($logger) { + $logger->startQuery($query, $params, $types); + } + + try { + if ($params) { + [$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types); + + $stmt = $this->_conn->prepare($query); + if ($types) { + $this->_bindTypedValues($stmt, $params, $types); + $stmt->execute(); + } else { + $stmt->execute($params); + } + } else { + $stmt = $this->_conn->query($query); + } + } catch (Throwable $ex) { + throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types)); + } + + $stmt->setFetchMode($this->defaultFetchMode); + + if ($logger) { + $logger->stopQuery(); + } + + return $stmt; + } + + /** + * Executes a caching query. + * + * @param string $query The SQL query to execute. + * @param mixed[] $params The parameters to bind to the query, if any. + * @param int[]|string[] $types The types the previous parameters are in. + * @param QueryCacheProfile $qcp The query cache profile. + * + * @return ResultStatement + * + * @throws CacheException + */ + public function executeCacheQuery($query, $params, $types, QueryCacheProfile $qcp) + { + $resultCache = $qcp->getResultCacheDriver() ?: $this->_config->getResultCacheImpl(); + if (! $resultCache) { + throw CacheException::noResultDriverConfigured(); + } + + [$cacheKey, $realKey] = $qcp->generateCacheKeys($query, $params, $types, $this->getParams()); + + // fetch the row pointers entry + $data = $resultCache->fetch($cacheKey); + + if ($data !== false) { + // is the real key part of this row pointers map or is the cache only pointing to other cache keys? + if (isset($data[$realKey])) { + $stmt = new ArrayStatement($data[$realKey]); + } elseif (array_key_exists($realKey, $data)) { + $stmt = new ArrayStatement([]); + } + } + + if (! isset($stmt)) { + $stmt = new ResultCacheStatement($this->executeQuery($query, $params, $types), $resultCache, $cacheKey, $realKey, $qcp->getLifetime()); + } + + $stmt->setFetchMode($this->defaultFetchMode); + + return $stmt; + } + + /** + * Executes an, optionally parametrized, SQL query and returns the result, + * applying a given projection/transformation function on each row of the result. + * + * @param string $query The SQL query to execute. + * @param mixed[] $params The parameters, if any. + * @param Closure $function The transformation function that is applied on each row. + * The function receives a single parameter, an array, that + * represents a row of the result set. + * + * @return mixed[] The projected result of the query. + */ + public function project($query, array $params, Closure $function) + { + $result = []; + $stmt = $this->executeQuery($query, $params); + + while ($row = $stmt->fetch()) { + $result[] = $function($row); + } + + $stmt->closeCursor(); + + return $result; + } + + /** + * Executes an SQL statement, returning a result set as a Statement object. + * + * @return \Doctrine\DBAL\Driver\Statement + * + * @throws DBALException + */ + public function query() + { + $this->connect(); + + $args = func_get_args(); + + $logger = $this->_config->getSQLLogger(); + if ($logger) { + $logger->startQuery($args[0]); + } + + try { + $statement = $this->_conn->query(...$args); + } catch (Throwable $ex) { + throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $args[0]); + } + + $statement->setFetchMode($this->defaultFetchMode); + + if ($logger) { + $logger->stopQuery(); + } + + return $statement; + } + + /** + * Executes an SQL INSERT/UPDATE/DELETE query with the given parameters + * and returns the number of affected rows. + * + * This method supports PDO binding types as well as DBAL mapping types. + * + * @param string $query The SQL query. + * @param mixed[] $params The query parameters. + * @param int[]|string[] $types The parameter types. + * + * @return int The number of affected rows. + * + * @throws DBALException + */ + public function executeUpdate($query, array $params = [], array $types = []) + { + $this->connect(); + + $logger = $this->_config->getSQLLogger(); + if ($logger) { + $logger->startQuery($query, $params, $types); + } + + try { + if ($params) { + [$query, $params, $types] = SQLParserUtils::expandListParameters($query, $params, $types); + + $stmt = $this->_conn->prepare($query); + if ($types) { + $this->_bindTypedValues($stmt, $params, $types); + $stmt->execute(); + } else { + $stmt->execute($params); + } + $result = $stmt->rowCount(); + } else { + $result = $this->_conn->exec($query); + } + } catch (Throwable $ex) { + throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $query, $this->resolveParams($params, $types)); + } + + if ($logger) { + $logger->stopQuery(); + } + + return $result; + } + + /** + * Executes an SQL statement and return the number of affected rows. + * + * @param string $statement + * + * @return int The number of affected rows. + * + * @throws DBALException + */ + public function exec($statement) + { + $this->connect(); + + $logger = $this->_config->getSQLLogger(); + if ($logger) { + $logger->startQuery($statement); + } + + try { + $result = $this->_conn->exec($statement); + } catch (Throwable $ex) { + throw DBALException::driverExceptionDuringQuery($this->_driver, $ex, $statement); + } + + if ($logger) { + $logger->stopQuery(); + } + + return $result; + } + + /** + * Returns the current transaction nesting level. + * + * @return int The nesting level. A value of 0 means there's no active transaction. + */ + public function getTransactionNestingLevel() + { + return $this->transactionNestingLevel; + } + + /** + * Fetches the SQLSTATE associated with the last database operation. + * + * @return string|null The last error code. + */ + public function errorCode() + { + $this->connect(); + + return $this->_conn->errorCode(); + } + + /** + * {@inheritDoc} + */ + public function errorInfo() + { + $this->connect(); + + return $this->_conn->errorInfo(); + } + + /** + * Returns the ID of the last inserted row, or the last value from a sequence object, + * depending on the underlying driver. + * + * Note: This method may not return a meaningful or consistent result across different drivers, + * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY + * columns or sequences. + * + * @param string|null $seqName Name of the sequence object from which the ID should be returned. + * + * @return string A string representation of the last inserted ID. + */ + public function lastInsertId($seqName = null) + { + $this->connect(); + + return $this->_conn->lastInsertId($seqName); + } + + /** + * Executes a function in a transaction. + * + * The function gets passed this Connection instance as an (optional) parameter. + * + * If an exception occurs during execution of the function or transaction commit, + * the transaction is rolled back and the exception re-thrown. + * + * @param Closure $func The function to execute transactionally. + * + * @return mixed The value returned by $func + * + * @throws Exception + * @throws Throwable + */ + public function transactional(Closure $func) + { + $this->beginTransaction(); + try { + $res = $func($this); + $this->commit(); + return $res; + } catch (Exception $e) { + $this->rollBack(); + throw $e; + } catch (Throwable $e) { + $this->rollBack(); + throw $e; + } + } + + /** + * Sets if nested transactions should use savepoints. + * + * @param bool $nestTransactionsWithSavepoints + * + * @return void + * + * @throws ConnectionException + */ + public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints) + { + if ($this->transactionNestingLevel > 0) { + throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction(); + } + + if (! $this->getDatabasePlatform()->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->nestTransactionsWithSavepoints = (bool) $nestTransactionsWithSavepoints; + } + + /** + * Gets if nested transactions should use savepoints. + * + * @return bool + */ + public function getNestTransactionsWithSavepoints() + { + return $this->nestTransactionsWithSavepoints; + } + + /** + * Returns the savepoint name to use for nested transactions are false if they are not supported + * "savepointFormat" parameter is not set + * + * @return mixed A string with the savepoint name or false. + */ + protected function _getNestedTransactionSavePointName() + { + return 'DOCTRINE2_SAVEPOINT_' . $this->transactionNestingLevel; + } + + /** + * Starts a transaction by suspending auto-commit mode. + * + * @return void + */ + public function beginTransaction() + { + $this->connect(); + + ++$this->transactionNestingLevel; + + $logger = $this->_config->getSQLLogger(); + + if ($this->transactionNestingLevel === 1) { + if ($logger) { + $logger->startQuery('"START TRANSACTION"'); + } + $this->_conn->beginTransaction(); + if ($logger) { + $logger->stopQuery(); + } + } elseif ($this->nestTransactionsWithSavepoints) { + if ($logger) { + $logger->startQuery('"SAVEPOINT"'); + } + $this->createSavepoint($this->_getNestedTransactionSavePointName()); + if ($logger) { + $logger->stopQuery(); + } + } + } + + /** + * Commits the current transaction. + * + * @return void + * + * @throws ConnectionException If the commit failed due to no active transaction or + * because the transaction was marked for rollback only. + */ + public function commit() + { + if ($this->transactionNestingLevel === 0) { + throw ConnectionException::noActiveTransaction(); + } + if ($this->isRollbackOnly) { + throw ConnectionException::commitFailedRollbackOnly(); + } + + $this->connect(); + + $logger = $this->_config->getSQLLogger(); + + if ($this->transactionNestingLevel === 1) { + if ($logger) { + $logger->startQuery('"COMMIT"'); + } + $this->_conn->commit(); + if ($logger) { + $logger->stopQuery(); + } + } elseif ($this->nestTransactionsWithSavepoints) { + if ($logger) { + $logger->startQuery('"RELEASE SAVEPOINT"'); + } + $this->releaseSavepoint($this->_getNestedTransactionSavePointName()); + if ($logger) { + $logger->stopQuery(); + } + } + + --$this->transactionNestingLevel; + + if ($this->autoCommit !== false || $this->transactionNestingLevel !== 0) { + return; + } + + $this->beginTransaction(); + } + + /** + * Commits all current nesting transactions. + */ + private function commitAll() + { + while ($this->transactionNestingLevel !== 0) { + if ($this->autoCommit === false && $this->transactionNestingLevel === 1) { + // When in no auto-commit mode, the last nesting commit immediately starts a new transaction. + // Therefore we need to do the final commit here and then leave to avoid an infinite loop. + $this->commit(); + + return; + } + + $this->commit(); + } + } + + /** + * Cancels any database changes done during the current transaction. + * + * @throws ConnectionException If the rollback operation failed. + */ + public function rollBack() + { + if ($this->transactionNestingLevel === 0) { + throw ConnectionException::noActiveTransaction(); + } + + $this->connect(); + + $logger = $this->_config->getSQLLogger(); + + if ($this->transactionNestingLevel === 1) { + if ($logger) { + $logger->startQuery('"ROLLBACK"'); + } + $this->transactionNestingLevel = 0; + $this->_conn->rollBack(); + $this->isRollbackOnly = false; + if ($logger) { + $logger->stopQuery(); + } + + if ($this->autoCommit === false) { + $this->beginTransaction(); + } + } elseif ($this->nestTransactionsWithSavepoints) { + if ($logger) { + $logger->startQuery('"ROLLBACK TO SAVEPOINT"'); + } + $this->rollbackSavepoint($this->_getNestedTransactionSavePointName()); + --$this->transactionNestingLevel; + if ($logger) { + $logger->stopQuery(); + } + } else { + $this->isRollbackOnly = true; + --$this->transactionNestingLevel; + } + } + + /** + * Creates a new savepoint. + * + * @param string $savepoint The name of the savepoint to create. + * + * @return void + * + * @throws ConnectionException + */ + public function createSavepoint($savepoint) + { + if (! $this->getDatabasePlatform()->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->_conn->exec($this->platform->createSavePoint($savepoint)); + } + + /** + * Releases the given savepoint. + * + * @param string $savepoint The name of the savepoint to release. + * + * @return void + * + * @throws ConnectionException + */ + public function releaseSavepoint($savepoint) + { + if (! $this->getDatabasePlatform()->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + if (! $this->platform->supportsReleaseSavepoints()) { + return; + } + + $this->_conn->exec($this->platform->releaseSavePoint($savepoint)); + } + + /** + * Rolls back to the given savepoint. + * + * @param string $savepoint The name of the savepoint to rollback to. + * + * @return void + * + * @throws ConnectionException + */ + public function rollbackSavepoint($savepoint) + { + if (! $this->getDatabasePlatform()->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->_conn->exec($this->platform->rollbackSavePoint($savepoint)); + } + + /** + * Gets the wrapped driver connection. + * + * @return \Doctrine\DBAL\Driver\Connection + */ + public function getWrappedConnection() + { + $this->connect(); + + return $this->_conn; + } + + /** + * Gets the SchemaManager that can be used to inspect or change the + * database schema through the connection. + * + * @return AbstractSchemaManager + */ + public function getSchemaManager() + { + if (! $this->_schemaManager) { + $this->_schemaManager = $this->_driver->getSchemaManager($this); + } + + return $this->_schemaManager; + } + + /** + * Marks the current transaction so that the only possible + * outcome for the transaction to be rolled back. + * + * @return void + * + * @throws ConnectionException If no transaction is active. + */ + public function setRollbackOnly() + { + if ($this->transactionNestingLevel === 0) { + throw ConnectionException::noActiveTransaction(); + } + $this->isRollbackOnly = true; + } + + /** + * Checks whether the current transaction is marked for rollback only. + * + * @return bool + * + * @throws ConnectionException If no transaction is active. + */ + public function isRollbackOnly() + { + if ($this->transactionNestingLevel === 0) { + throw ConnectionException::noActiveTransaction(); + } + + return $this->isRollbackOnly; + } + + /** + * Converts a given value to its database representation according to the conversion + * rules of a specific DBAL mapping type. + * + * @param mixed $value The value to convert. + * @param string $type The name of the DBAL mapping type. + * + * @return mixed The converted value. + */ + public function convertToDatabaseValue($value, $type) + { + return Type::getType($type)->convertToDatabaseValue($value, $this->getDatabasePlatform()); + } + + /** + * Converts a given value to its PHP representation according to the conversion + * rules of a specific DBAL mapping type. + * + * @param mixed $value The value to convert. + * @param string $type The name of the DBAL mapping type. + * + * @return mixed The converted type. + */ + public function convertToPHPValue($value, $type) + { + return Type::getType($type)->convertToPHPValue($value, $this->getDatabasePlatform()); + } + + /** + * Binds a set of parameters, some or all of which are typed with a PDO binding type + * or DBAL mapping type, to a given statement. + * + * @internal Duck-typing used on the $stmt parameter to support driver statements as well as + * raw PDOStatement instances. + * + * @param \Doctrine\DBAL\Driver\Statement $stmt The statement to bind the values to. + * @param mixed[] $params The map/list of named/positional parameters. + * @param int[]|string[] $types The parameter types (PDO binding types or DBAL mapping types). + * + * @return void + */ + private function _bindTypedValues($stmt, array $params, array $types) + { + // Check whether parameters are positional or named. Mixing is not allowed, just like in PDO. + if (is_int(key($params))) { + // Positional parameters + $typeOffset = array_key_exists(0, $types) ? -1 : 0; + $bindIndex = 1; + foreach ($params as $value) { + $typeIndex = $bindIndex + $typeOffset; + if (isset($types[$typeIndex])) { + $type = $types[$typeIndex]; + [$value, $bindingType] = $this->getBindingInfo($value, $type); + $stmt->bindValue($bindIndex, $value, $bindingType); + } else { + $stmt->bindValue($bindIndex, $value); + } + ++$bindIndex; + } + } else { + // Named parameters + foreach ($params as $name => $value) { + if (isset($types[$name])) { + $type = $types[$name]; + [$value, $bindingType] = $this->getBindingInfo($value, $type); + $stmt->bindValue($name, $value, $bindingType); + } else { + $stmt->bindValue($name, $value); + } + } + } + } + + /** + * Gets the binding type of a given type. The given type can be a PDO or DBAL mapping type. + * + * @param mixed $value The value to bind. + * @param int|string $type The type to bind (PDO or DBAL). + * + * @return mixed[] [0] => the (escaped) value, [1] => the binding type. + */ + private function getBindingInfo($value, $type) + { + if (is_string($type)) { + $type = Type::getType($type); + } + if ($type instanceof Type) { + $value = $type->convertToDatabaseValue($value, $this->getDatabasePlatform()); + $bindingType = $type->getBindingType(); + } else { + $bindingType = $type; + } + + return [$value, $bindingType]; + } + + /** + * Resolves the parameters to a format which can be displayed. + * + * @internal This is a purely internal method. If you rely on this method, you are advised to + * copy/paste the code as this method may change, or be removed without prior notice. + * + * @param mixed[] $params + * @param int[]|string[] $types + * + * @return mixed[] + */ + public function resolveParams(array $params, array $types) + { + $resolvedParams = []; + + // Check whether parameters are positional or named. Mixing is not allowed, just like in PDO. + if (is_int(key($params))) { + // Positional parameters + $typeOffset = array_key_exists(0, $types) ? -1 : 0; + $bindIndex = 1; + foreach ($params as $value) { + $typeIndex = $bindIndex + $typeOffset; + if (isset($types[$typeIndex])) { + $type = $types[$typeIndex]; + [$value] = $this->getBindingInfo($value, $type); + $resolvedParams[$bindIndex] = $value; + } else { + $resolvedParams[$bindIndex] = $value; + } + ++$bindIndex; + } + } else { + // Named parameters + foreach ($params as $name => $value) { + if (isset($types[$name])) { + $type = $types[$name]; + [$value] = $this->getBindingInfo($value, $type); + $resolvedParams[$name] = $value; + } else { + $resolvedParams[$name] = $value; + } + } + } + + return $resolvedParams; + } + + /** + * Creates a new instance of a SQL query builder. + * + * @return QueryBuilder + */ + public function createQueryBuilder() + { + return new Query\QueryBuilder($this); + } + + /** + * Ping the server + * + * When the server is not available the method returns FALSE. + * It is responsibility of the developer to handle this case + * and abort the request or reconnect manually: + * + * @return bool + * + * @example + * + * if ($conn->ping() === false) { + * $conn->close(); + * $conn->connect(); + * } + * + * It is undefined if the underlying driver attempts to reconnect + * or disconnect when the connection is not available anymore + * as long it returns TRUE when a reconnect succeeded and + * FALSE when the connection was dropped. + */ + public function ping() + { + $this->connect(); + + if ($this->_conn instanceof PingableConnection) { + return $this->_conn->ping(); + } + + try { + $this->query($this->getDatabasePlatform()->getDummySelectSQL()); + + return true; + } catch (DBALException $e) { + return false; + } + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php new file mode 100644 index 000000000..d3d11bc67 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/ConnectionException.php @@ -0,0 +1,38 @@ +executeQuery("DELETE FROM table"); + * + * Be aware that Connection#executeQuery is a method specifically for READ + * operations only. + * + * This connection is limited to slave operations using the + * Connection#executeQuery operation only, because it wouldn't be compatible + * with the ORM or SchemaManager code otherwise. Both use all the other + * operations in a context where writes could happen to a slave, which makes + * this restricted approach necessary. + * + * You can manually connect to the master at any time by calling: + * + * $conn->connect('master'); + * + * Instantiation through the DriverManager looks like: + * + * @example + * + * $conn = DriverManager::getConnection(array( + * 'wrapperClass' => 'Doctrine\DBAL\Connections\MasterSlaveConnection', + * 'driver' => 'pdo_mysql', + * 'master' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''), + * 'slaves' => array( + * array('user' => 'slave1', 'password', 'host' => '', 'dbname' => ''), + * array('user' => 'slave2', 'password', 'host' => '', 'dbname' => ''), + * ) + * )); + * + * You can also pass 'driverOptions' and any other documented option to each of this drivers to pass additional information. + */ +class MasterSlaveConnection extends Connection +{ + /** + * Master and slave connection (one of the randomly picked slaves). + * + * @var DriverConnection[]|null[] + */ + protected $connections = ['master' => null, 'slave' => null]; + + /** + * You can keep the slave connection and then switch back to it + * during the request if you know what you are doing. + * + * @var bool + */ + protected $keepSlave = false; + + /** + * Creates Master Slave Connection. + * + * @param mixed[] $params + * + * @throws InvalidArgumentException + */ + public function __construct(array $params, Driver $driver, ?Configuration $config = null, ?EventManager $eventManager = null) + { + if (! isset($params['slaves'], $params['master'])) { + throw new InvalidArgumentException('master or slaves configuration missing'); + } + if (count($params['slaves']) === 0) { + throw new InvalidArgumentException('You have to configure at least one slaves.'); + } + + $params['master']['driver'] = $params['driver']; + foreach ($params['slaves'] as $slaveKey => $slave) { + $params['slaves'][$slaveKey]['driver'] = $params['driver']; + } + + $this->keepSlave = (bool) ($params['keepSlave'] ?? false); + + parent::__construct($params, $driver, $config, $eventManager); + } + + /** + * Checks if the connection is currently towards the master or not. + * + * @return bool + */ + public function isConnectedToMaster() + { + return $this->_conn !== null && $this->_conn === $this->connections['master']; + } + + /** + * {@inheritDoc} + */ + public function connect($connectionName = null) + { + $requestedConnectionChange = ($connectionName !== null); + $connectionName = $connectionName ?: 'slave'; + + if ($connectionName !== 'slave' && $connectionName !== 'master') { + throw new InvalidArgumentException('Invalid option to connect(), only master or slave allowed.'); + } + + // If we have a connection open, and this is not an explicit connection + // change request, then abort right here, because we are already done. + // This prevents writes to the slave in case of "keepSlave" option enabled. + if (isset($this->_conn) && $this->_conn && ! $requestedConnectionChange) { + return false; + } + + $forceMasterAsSlave = false; + + if ($this->getTransactionNestingLevel() > 0) { + $connectionName = 'master'; + $forceMasterAsSlave = true; + } + + if (isset($this->connections[$connectionName]) && $this->connections[$connectionName]) { + $this->_conn = $this->connections[$connectionName]; + + if ($forceMasterAsSlave && ! $this->keepSlave) { + $this->connections['slave'] = $this->_conn; + } + + return false; + } + + if ($connectionName === 'master') { + $this->connections['master'] = $this->_conn = $this->connectTo($connectionName); + + // Set slave connection to master to avoid invalid reads + if (! $this->keepSlave) { + $this->connections['slave'] = $this->connections['master']; + } + } else { + $this->connections['slave'] = $this->_conn = $this->connectTo($connectionName); + } + + if ($this->_eventManager->hasListeners(Events::postConnect)) { + $eventArgs = new ConnectionEventArgs($this); + $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs); + } + + return true; + } + + /** + * Connects to a specific connection. + * + * @param string $connectionName + * + * @return DriverConnection + */ + protected function connectTo($connectionName) + { + $params = $this->getParams(); + + $driverOptions = $params['driverOptions'] ?? []; + + $connectionParams = $this->chooseConnectionConfiguration($connectionName, $params); + + $user = $connectionParams['user'] ?? null; + $password = $connectionParams['password'] ?? null; + + return $this->_driver->connect($connectionParams, $user, $password, $driverOptions); + } + + /** + * @param string $connectionName + * @param mixed[] $params + * + * @return mixed + */ + protected function chooseConnectionConfiguration($connectionName, $params) + { + if ($connectionName === 'master') { + return $params['master']; + } + + $config = $params['slaves'][array_rand($params['slaves'])]; + + if (! isset($config['charset']) && isset($params['master']['charset'])) { + $config['charset'] = $params['master']['charset']; + } + + return $config; + } + + /** + * {@inheritDoc} + */ + public function executeUpdate($query, array $params = [], array $types = []) + { + $this->connect('master'); + + return parent::executeUpdate($query, $params, $types); + } + + /** + * {@inheritDoc} + */ + public function beginTransaction() + { + $this->connect('master'); + + parent::beginTransaction(); + } + + /** + * {@inheritDoc} + */ + public function commit() + { + $this->connect('master'); + + parent::commit(); + } + + /** + * {@inheritDoc} + */ + public function rollBack() + { + $this->connect('master'); + + return parent::rollBack(); + } + + /** + * {@inheritDoc} + */ + public function delete($tableName, array $identifier, array $types = []) + { + $this->connect('master'); + + return parent::delete($tableName, $identifier, $types); + } + + /** + * {@inheritDoc} + */ + public function close() + { + unset($this->connections['master'], $this->connections['slave']); + + parent::close(); + + $this->_conn = null; + $this->connections = ['master' => null, 'slave' => null]; + } + + /** + * {@inheritDoc} + */ + public function update($tableName, array $data, array $identifier, array $types = []) + { + $this->connect('master'); + + return parent::update($tableName, $data, $identifier, $types); + } + + /** + * {@inheritDoc} + */ + public function insert($tableName, array $data, array $types = []) + { + $this->connect('master'); + + return parent::insert($tableName, $data, $types); + } + + /** + * {@inheritDoc} + */ + public function exec($statement) + { + $this->connect('master'); + + return parent::exec($statement); + } + + /** + * {@inheritDoc} + */ + public function createSavepoint($savepoint) + { + $this->connect('master'); + + parent::createSavepoint($savepoint); + } + + /** + * {@inheritDoc} + */ + public function releaseSavepoint($savepoint) + { + $this->connect('master'); + + parent::releaseSavepoint($savepoint); + } + + /** + * {@inheritDoc} + */ + public function rollbackSavepoint($savepoint) + { + $this->connect('master'); + + parent::rollbackSavepoint($savepoint); + } + + /** + * {@inheritDoc} + */ + public function query() + { + $this->connect('master'); + + $args = func_get_args(); + + $logger = $this->getConfiguration()->getSQLLogger(); + if ($logger) { + $logger->startQuery($args[0]); + } + + $statement = $this->_conn->query(...$args); + + $statement->setFetchMode($this->defaultFetchMode); + + if ($logger) { + $logger->stopQuery(); + } + + return $statement; + } + + /** + * {@inheritDoc} + */ + public function prepare($statement) + { + $this->connect('master'); + + return parent::prepare($statement); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php new file mode 100644 index 000000000..15bac7f0f --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php @@ -0,0 +1,285 @@ +getMessage(); + + return static::wrapException($driver, $driverEx, $msg); + } + + /** + * @param Exception $driverEx + * + * @return \Doctrine\DBAL\DBALException + */ + public static function driverException(Driver $driver, Throwable $driverEx) + { + return static::wrapException($driver, $driverEx, 'An exception occurred in driver: ' . $driverEx->getMessage()); + } + + /** + * @param Exception $driverEx + * + * @return \Doctrine\DBAL\DBALException + */ + private static function wrapException(Driver $driver, Throwable $driverEx, $msg) + { + if ($driverEx instanceof DriverException) { + return $driverEx; + } + if ($driver instanceof ExceptionConverterDriver && $driverEx instanceof DriverExceptionInterface) { + return $driver->convertException($msg, $driverEx); + } + + return new self($msg, 0, $driverEx); + } + + /** + * Returns a human-readable representation of an array of parameters. + * This properly handles binary data by returning a hex representation. + * + * @param mixed[] $params + * + * @return string + */ + private static function formatParameters(array $params) + { + return '[' . implode(', ', array_map(static function ($param) { + if (is_resource($param)) { + return (string) $param; + } + + $json = @json_encode($param); + + if (! is_string($json) || $json === 'null' && is_string($param)) { + // JSON encoding failed, this is not a UTF-8 string. + return '"\x' . implode('\x', str_split(bin2hex($param), 2)) . '"'; + } + + return $json; + }, $params)) . ']'; + } + + /** + * @param string $wrapperClass + * + * @return \Doctrine\DBAL\DBALException + */ + public static function invalidWrapperClass($wrapperClass) + { + return new self("The given 'wrapperClass' " . $wrapperClass . ' has to be a ' . + 'subtype of \Doctrine\DBAL\Connection.'); + } + + /** + * @param string $driverClass + * + * @return \Doctrine\DBAL\DBALException + */ + public static function invalidDriverClass($driverClass) + { + return new self("The given 'driverClass' " . $driverClass . ' has to implement the ' . Driver::class . ' interface.'); + } + + /** + * @param string $tableName + * + * @return \Doctrine\DBAL\DBALException + */ + public static function invalidTableName($tableName) + { + return new self('Invalid table name specified: ' . $tableName); + } + + /** + * @param string $tableName + * + * @return \Doctrine\DBAL\DBALException + */ + public static function noColumnsSpecifiedForTable($tableName) + { + return new self('No columns specified for table ' . $tableName); + } + + /** + * @return \Doctrine\DBAL\DBALException + */ + public static function limitOffsetInvalid() + { + return new self('Invalid Offset in Limit Query, it has to be larger than or equal to 0.'); + } + + /** + * @param string $name + * + * @return \Doctrine\DBAL\DBALException + */ + public static function typeExists($name) + { + return new self('Type ' . $name . ' already exists.'); + } + + /** + * @param string $name + * + * @return \Doctrine\DBAL\DBALException + */ + public static function unknownColumnType($name) + { + return new self('Unknown column type "' . $name . '" requested. Any Doctrine type that you use has ' . + 'to be registered with \Doctrine\DBAL\Types\Type::addType(). You can get a list of all the ' . + 'known types with \Doctrine\DBAL\Types\Type::getTypesMap(). If this error occurs during database ' . + 'introspection then you might have forgotten to register all database types for a Doctrine Type. Use ' . + 'AbstractPlatform#registerDoctrineTypeMapping() or have your custom types implement ' . + 'Type#getMappedDatabaseTypes(). If the type name is empty you might ' . + 'have a problem with the cache or forgot some mapping information.'); + } + + /** + * @param string $name + * + * @return \Doctrine\DBAL\DBALException + */ + public static function typeNotFound($name) + { + return new self('Type to be overwritten ' . $name . ' does not exist.'); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver.php new file mode 100644 index 000000000..dcb03b294 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver.php @@ -0,0 +1,55 @@ +getParams(); + + return $params['dbname']; + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new DB2Platform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(Connection $conn) + { + return new DB2SchemaManager($conn); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractDriverException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractDriverException.php new file mode 100644 index 000000000..d9af92d17 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractDriverException.php @@ -0,0 +1,54 @@ +errorCode = $errorCode; + $this->sqlState = $sqlState; + } + + /** + * {@inheritdoc} + */ + public function getErrorCode() + { + return $this->errorCode; + } + + /** + * {@inheritdoc} + */ + public function getSQLState() + { + return $this->sqlState; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php new file mode 100644 index 000000000..c46ddc63d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php @@ -0,0 +1,218 @@ +getErrorCode()) { + case '1213': + return new Exception\DeadlockException($message, $exception); + case '1205': + return new Exception\LockWaitTimeoutException($message, $exception); + case '1050': + return new Exception\TableExistsException($message, $exception); + + case '1051': + case '1146': + return new Exception\TableNotFoundException($message, $exception); + + case '1216': + case '1217': + case '1451': + case '1452': + case '1701': + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + + case '1062': + case '1557': + case '1569': + case '1586': + return new Exception\UniqueConstraintViolationException($message, $exception); + + case '1054': + case '1166': + case '1611': + return new Exception\InvalidFieldNameException($message, $exception); + + case '1052': + case '1060': + case '1110': + return new Exception\NonUniqueFieldNameException($message, $exception); + + case '1064': + case '1149': + case '1287': + case '1341': + case '1342': + case '1343': + case '1344': + case '1382': + case '1479': + case '1541': + case '1554': + case '1626': + return new Exception\SyntaxErrorException($message, $exception); + + case '1044': + case '1045': + case '1046': + case '1049': + case '1095': + case '1142': + case '1143': + case '1227': + case '1370': + case '1429': + case '2002': + case '2005': + return new Exception\ConnectionException($message, $exception); + + case '1048': + case '1121': + case '1138': + case '1171': + case '1252': + case '1263': + case '1364': + case '1566': + return new Exception\NotNullConstraintViolationException($message, $exception); + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + * + * @throws DBALException + */ + public function createDatabasePlatformForVersion($version) + { + $mariadb = stripos($version, 'mariadb') !== false; + if ($mariadb && version_compare($this->getMariaDbMysqlVersionNumber($version), '10.2.7', '>=')) { + return new MariaDb1027Platform(); + } + + if (! $mariadb) { + $oracleMysqlVersion = $this->getOracleMysqlVersionNumber($version); + if (version_compare($oracleMysqlVersion, '8', '>=')) { + return new MySQL80Platform(); + } + if (version_compare($oracleMysqlVersion, '5.7.9', '>=')) { + return new MySQL57Platform(); + } + } + + return $this->getDatabasePlatform(); + } + + /** + * Get a normalized 'version number' from the server string + * returned by Oracle MySQL servers. + * + * @param string $versionString Version string returned by the driver, i.e. '5.7.10' + * + * @throws DBALException + */ + private function getOracleMysqlVersionNumber(string $versionString) : string + { + if (! preg_match( + '/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', + $versionString, + $versionParts + )) { + throw DBALException::invalidPlatformVersionSpecified( + $versionString, + '..' + ); + } + $majorVersion = $versionParts['major']; + $minorVersion = $versionParts['minor'] ?? 0; + $patchVersion = $versionParts['patch'] ?? null; + + if ($majorVersion === '5' && $minorVersion === '7' && $patchVersion === null) { + $patchVersion = '9'; + } + + return $majorVersion . '.' . $minorVersion . '.' . $patchVersion; + } + + /** + * Detect MariaDB server version, including hack for some mariadb distributions + * that starts with the prefix '5.5.5-' + * + * @param string $versionString Version string as returned by mariadb server, i.e. '5.5.5-Mariadb-10.0.8-xenial' + * + * @throws DBALException + */ + private function getMariaDbMysqlVersionNumber(string $versionString) : string + { + if (! preg_match( + '/^(?:5\.5\.5-)?(mariadb-)?(?P\d+)\.(?P\d+)\.(?P\d+)/i', + $versionString, + $versionParts + )) { + throw DBALException::invalidPlatformVersionSpecified( + $versionString, + '^(?:5\.5\.5-)?(mariadb-)?..' + ); + } + + return $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch']; + } + + /** + * {@inheritdoc} + */ + public function getDatabase(Connection $conn) + { + $params = $conn->getParams(); + + return $params['dbname'] ?? $conn->query('SELECT DATABASE()')->fetchColumn(); + } + + /** + * {@inheritdoc} + * + * @return MySqlPlatform + */ + public function getDatabasePlatform() + { + return new MySqlPlatform(); + } + + /** + * {@inheritdoc} + * + * @return MySqlSchemaManager + */ + public function getSchemaManager(Connection $conn) + { + return new MySqlSchemaManager($conn); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php new file mode 100644 index 000000000..dcbaaf097 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractOracleDriver.php @@ -0,0 +1,97 @@ +getErrorCode()) { + case '1': + case '2299': + case '38911': + return new Exception\UniqueConstraintViolationException($message, $exception); + + case '904': + return new Exception\InvalidFieldNameException($message, $exception); + + case '918': + case '960': + return new Exception\NonUniqueFieldNameException($message, $exception); + + case '923': + return new Exception\SyntaxErrorException($message, $exception); + + case '942': + return new Exception\TableNotFoundException($message, $exception); + + case '955': + return new Exception\TableExistsException($message, $exception); + + case '1017': + case '12545': + return new Exception\ConnectionException($message, $exception); + + case '1400': + return new Exception\NotNullConstraintViolationException($message, $exception); + + case '2266': + case '2291': + case '2292': + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function getDatabase(Connection $conn) + { + $params = $conn->getParams(); + + return $params['user']; + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new OraclePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(Connection $conn) + { + return new OracleSchemaManager($conn); + } + + /** + * Returns an appropriate Easy Connect String for the given parameters. + * + * @param mixed[] $params The connection parameters to return the Easy Connect String for. + * + * @return string + */ + protected function getEasyConnectString(array $params) + { + return (string) EasyConnectString::fromConnectionParameters($params); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractOracleDriver/EasyConnectString.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractOracleDriver/EasyConnectString.php new file mode 100644 index 000000000..01f648b3b --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractOracleDriver/EasyConnectString.php @@ -0,0 +1,121 @@ +string = $string; + } + + public function __toString() : string + { + return $this->string; + } + + /** + * Creates the object from an array representation + * + * @param mixed[] $params + */ + public static function fromArray(array $params) : self + { + return new self(self::renderParams($params)); + } + + /** + * Creates the object from the given DBAL connection parameters. + * + * @param mixed[] $params + */ + public static function fromConnectionParameters(array $params) : self + { + if (! empty($params['connectstring'])) { + return new self($params['connectstring']); + } + + if (empty($params['host'])) { + return new self($params['dbname'] ?? ''); + } + + $connectData = []; + + if (isset($params['servicename']) || isset($params['dbname'])) { + $serviceKey = 'SID'; + + if (! empty($params['service'])) { + $serviceKey = 'SERVICE_NAME'; + } + + $serviceName = $params['servicename'] ?? $params['dbname']; + + $connectData[$serviceKey] = $serviceName; + } + + if (! empty($params['instancename'])) { + $connectData['INSTANCE_NAME'] = $params['instancename']; + } + + if (! empty($params['pooled'])) { + $connectData['SERVER'] = 'POOLED'; + } + + return self::fromArray([ + 'DESCRIPTION' => [ + 'ADDRESS' => [ + 'PROTOCOL' => 'TCP', + 'HOST' => $params['host'], + 'PORT' => $params['port'] ?? 1521, + ], + 'CONNECT_DATA' => $connectData, + ], + ]); + } + + /** + * @param mixed[] $params + */ + private static function renderParams(array $params) : string + { + $chunks = []; + + foreach ($params as $key => $value) { + $string = self::renderValue($value); + + if ($string === '') { + continue; + } + + $chunks[] = sprintf('(%s=%s)', $key, $string); + } + + return implode('', $chunks); + } + + /** + * @param mixed $value + */ + private static function renderValue($value) : string + { + if (is_array($value)) { + return self::renderParams($value); + } + + return (string) $value; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php new file mode 100644 index 000000000..916d92498 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractPostgreSQLDriver.php @@ -0,0 +1,138 @@ +getSQLState()) { + case '40001': + case '40P01': + return new Exception\DeadlockException($message, $exception); + case '0A000': + // Foreign key constraint violations during a TRUNCATE operation + // are considered "feature not supported" in PostgreSQL. + if (strpos($exception->getMessage(), 'truncate') !== false) { + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + } + + break; + case '23502': + return new Exception\NotNullConstraintViolationException($message, $exception); + + case '23503': + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + + case '23505': + return new Exception\UniqueConstraintViolationException($message, $exception); + + case '42601': + return new Exception\SyntaxErrorException($message, $exception); + + case '42702': + return new Exception\NonUniqueFieldNameException($message, $exception); + + case '42703': + return new Exception\InvalidFieldNameException($message, $exception); + + case '42P01': + return new Exception\TableNotFoundException($message, $exception); + + case '42P07': + return new Exception\TableExistsException($message, $exception); + + case '7': + // In some case (mainly connection errors) the PDO exception does not provide a SQLSTATE via its code. + // The exception code is always set to 7 here. + // We have to match against the SQLSTATE in the error message in these cases. + if (strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) { + return new Exception\ConnectionException($message, $exception); + } + + break; + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version) + { + if (! preg_match('/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', $version, $versionParts)) { + throw DBALException::invalidPlatformVersionSpecified( + $version, + '..' + ); + } + + $majorVersion = $versionParts['major']; + $minorVersion = $versionParts['minor'] ?? 0; + $patchVersion = $versionParts['patch'] ?? 0; + $version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion; + + switch (true) { + case version_compare($version, '10.0', '>='): + return new PostgreSQL100Platform(); + case version_compare($version, '9.4', '>='): + return new PostgreSQL94Platform(); + case version_compare($version, '9.2', '>='): + return new PostgreSQL92Platform(); + case version_compare($version, '9.1', '>='): + return new PostgreSQL91Platform(); + default: + return new PostgreSqlPlatform(); + } + } + + /** + * {@inheritdoc} + */ + public function getDatabase(Connection $conn) + { + $params = $conn->getParams(); + + return $params['dbname'] ?? $conn->query('SELECT CURRENT_DATABASE()')->fetchColumn(); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new PostgreSqlPlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(Connection $conn) + { + return new PostgreSqlSchemaManager($conn); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php new file mode 100644 index 000000000..88f26ce7d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLAnywhereDriver.php @@ -0,0 +1,127 @@ +getErrorCode()) { + case '-306': + case '-307': + case '-684': + return new Exception\DeadlockException($message, $exception); + case '-210': + case '-1175': + case '-1281': + return new Exception\LockWaitTimeoutException($message, $exception); + case '-100': + case '-103': + case '-832': + return new Exception\ConnectionException($message, $exception); + case '-143': + return new Exception\InvalidFieldNameException($message, $exception); + case '-193': + case '-196': + return new Exception\UniqueConstraintViolationException($message, $exception); + case '-194': + case '-198': + return new Exception\ForeignKeyConstraintViolationException($message, $exception); + case '-144': + return new Exception\NonUniqueFieldNameException($message, $exception); + case '-184': + case '-195': + return new Exception\NotNullConstraintViolationException($message, $exception); + case '-131': + return new Exception\SyntaxErrorException($message, $exception); + case '-110': + return new Exception\TableExistsException($message, $exception); + case '-141': + case '-1041': + return new Exception\TableNotFoundException($message, $exception); + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version) + { + if (! preg_match( + '/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?)?/', + $version, + $versionParts + )) { + throw DBALException::invalidPlatformVersionSpecified( + $version, + '...' + ); + } + + $majorVersion = $versionParts['major']; + $minorVersion = $versionParts['minor'] ?? 0; + $patchVersion = $versionParts['patch'] ?? 0; + $buildVersion = $versionParts['build'] ?? 0; + $version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion . '.' . $buildVersion; + + switch (true) { + case version_compare($version, '16', '>='): + return new SQLAnywhere16Platform(); + case version_compare($version, '12', '>='): + return new SQLAnywhere12Platform(); + case version_compare($version, '11', '>='): + return new SQLAnywhere11Platform(); + default: + return new SQLAnywherePlatform(); + } + } + + /** + * {@inheritdoc} + */ + public function getDatabase(Connection $conn) + { + $params = $conn->getParams(); + + return $params['dbname'] ?? $conn->query('SELECT DB_NAME()')->fetchColumn(); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new SQLAnywhere12Platform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(Connection $conn) + { + return new SQLAnywhereSchemaManager($conn); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php new file mode 100644 index 000000000..421d82b39 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLServerDriver.php @@ -0,0 +1,81 @@ +\d+)(?:\.(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?)?/', + $version, + $versionParts + )) { + throw DBALException::invalidPlatformVersionSpecified( + $version, + '...' + ); + } + + $majorVersion = $versionParts['major']; + $minorVersion = $versionParts['minor'] ?? 0; + $patchVersion = $versionParts['patch'] ?? 0; + $buildVersion = $versionParts['build'] ?? 0; + $version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion . '.' . $buildVersion; + + switch (true) { + case version_compare($version, '11.00.2100', '>='): + return new SQLServer2012Platform(); + case version_compare($version, '10.00.1600', '>='): + return new SQLServer2008Platform(); + case version_compare($version, '9.00.1399', '>='): + return new SQLServer2005Platform(); + default: + return new SQLServerPlatform(); + } + } + + /** + * {@inheritdoc} + */ + public function getDatabase(Connection $conn) + { + $params = $conn->getParams(); + + return $params['dbname'] ?? $conn->query('SELECT DB_NAME()')->fetchColumn(); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new SQLServer2008Platform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(Connection $conn) + { + return new SQLServerSchemaManager($conn); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php new file mode 100644 index 000000000..582f7cae2 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractSQLiteDriver.php @@ -0,0 +1,98 @@ +getMessage(), 'database is locked') !== false) { + return new Exception\LockWaitTimeoutException($message, $exception); + } + + if (strpos($exception->getMessage(), 'must be unique') !== false || + strpos($exception->getMessage(), 'is not unique') !== false || + strpos($exception->getMessage(), 'are not unique') !== false || + strpos($exception->getMessage(), 'UNIQUE constraint failed') !== false + ) { + return new Exception\UniqueConstraintViolationException($message, $exception); + } + + if (strpos($exception->getMessage(), 'may not be NULL') !== false || + strpos($exception->getMessage(), 'NOT NULL constraint failed') !== false + ) { + return new Exception\NotNullConstraintViolationException($message, $exception); + } + + if (strpos($exception->getMessage(), 'no such table:') !== false) { + return new Exception\TableNotFoundException($message, $exception); + } + + if (strpos($exception->getMessage(), 'already exists') !== false) { + return new Exception\TableExistsException($message, $exception); + } + + if (strpos($exception->getMessage(), 'has no column named') !== false) { + return new Exception\InvalidFieldNameException($message, $exception); + } + + if (strpos($exception->getMessage(), 'ambiguous column name') !== false) { + return new Exception\NonUniqueFieldNameException($message, $exception); + } + + if (strpos($exception->getMessage(), 'syntax error') !== false) { + return new Exception\SyntaxErrorException($message, $exception); + } + + if (strpos($exception->getMessage(), 'attempt to write a readonly database') !== false) { + return new Exception\ReadOnlyException($message, $exception); + } + + if (strpos($exception->getMessage(), 'unable to open database file') !== false) { + return new Exception\ConnectionException($message, $exception); + } + + return new Exception\DriverException($message, $exception); + } + + /** + * {@inheritdoc} + */ + public function getDatabase(Connection $conn) + { + $params = $conn->getParams(); + + return $params['path'] ?? null; + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new SqlitePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(Connection $conn) + { + return new SqliteSchemaManager($conn); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php new file mode 100644 index 000000000..1574581c2 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php @@ -0,0 +1,93 @@ +constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + } + + /** + * {@inheritdoc} + */ + public function createDatabasePlatformForVersion($version) + { + return $this->getDatabasePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getDatabasePlatform() + { + return new DrizzlePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getSchemaManager(\Doctrine\DBAL\Connection $conn) + { + return new DrizzleSchemaManager($conn); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'drizzle_pdo_mysql'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php new file mode 100644 index 000000000..9b79e240c --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php @@ -0,0 +1,22 @@ +conn = db2_pconnect($params['dbname'], $username, $password, $driverOptions); + } else { + $this->conn = db2_connect($params['dbname'], $username, $password, $driverOptions); + } + if (! $this->conn) { + throw new DB2Exception(db2_conn_errormsg()); + } + } + + /** + * {@inheritdoc} + */ + public function getServerVersion() + { + /** @var stdClass $serverInfo */ + $serverInfo = db2_server_info($this->conn); + + return $serverInfo->DBMS_VER; + } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function prepare($sql) + { + $stmt = @db2_prepare($this->conn, $sql); + if (! $stmt) { + throw new DB2Exception(db2_stmt_errormsg()); + } + + return new DB2Statement($stmt); + } + + /** + * {@inheritdoc} + */ + public function query() + { + $args = func_get_args(); + $sql = $args[0]; + $stmt = $this->prepare($sql); + $stmt->execute(); + + return $stmt; + } + + /** + * {@inheritdoc} + */ + public function quote($input, $type = ParameterType::STRING) + { + $input = db2_escape_string($input); + + if ($type === ParameterType::INTEGER) { + return $input; + } + + return "'" . $input . "'"; + } + + /** + * {@inheritdoc} + */ + public function exec($statement) + { + $stmt = @db2_exec($this->conn, $statement); + + if ($stmt === false) { + throw new DB2Exception(db2_stmt_errormsg()); + } + + return db2_num_rows($stmt); + } + + /** + * {@inheritdoc} + */ + public function lastInsertId($name = null) + { + return db2_last_insert_id($this->conn); + } + + /** + * {@inheritdoc} + */ + public function beginTransaction() + { + db2_autocommit($this->conn, DB2_AUTOCOMMIT_OFF); + } + + /** + * {@inheritdoc} + */ + public function commit() + { + if (! db2_commit($this->conn)) { + throw new DB2Exception(db2_conn_errormsg($this->conn)); + } + db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON); + } + + /** + * {@inheritdoc} + */ + public function rollBack() + { + if (! db2_rollback($this->conn)) { + throw new DB2Exception(db2_conn_errormsg($this->conn)); + } + db2_autocommit($this->conn, DB2_AUTOCOMMIT_ON); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return db2_conn_error($this->conn); + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return [ + 0 => db2_conn_errormsg($this->conn), + 1 => $this->errorCode(), + ]; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php new file mode 100644 index 000000000..712cbe419 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/IBMDB2/DB2Driver.php @@ -0,0 +1,47 @@ +stmt = $stmt; + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + return $this->bindParam($param, $value, $type); + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) + { + switch ($type) { + case ParameterType::INTEGER: + $this->bind($column, $variable, DB2_PARAM_IN, DB2_LONG); + break; + + case ParameterType::LARGE_OBJECT: + if (isset($this->lobs[$column])) { + [, $handle] = $this->lobs[$column]; + fclose($handle); + } + + $handle = $this->createTemporaryFile(); + $path = stream_get_meta_data($handle)['uri']; + + $this->bind($column, $path, DB2_PARAM_FILE, DB2_BINARY); + + $this->lobs[$column] = [&$variable, $handle]; + break; + + default: + $this->bind($column, $variable, DB2_PARAM_IN, DB2_CHAR); + break; + } + + return true; + } + + /** + * @param int|string $parameter Parameter position or name + * @param mixed $variable + * + * @throws DB2Exception + */ + private function bind($parameter, &$variable, int $parameterType, int $dataType) : void + { + $this->bindParam[$parameter] =& $variable; + + if (! db2_bind_param($this->stmt, $parameter, 'variable', $parameterType, $dataType)) { + throw new DB2Exception(db2_stmt_errormsg()); + } + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + if (! $this->stmt) { + return false; + } + + $this->bindParam = []; + + if (! db2_free_result($this->stmt)) { + return false; + } + + $this->result = false; + + return true; + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + if (! $this->stmt) { + return false; + } + + return db2_num_fields($this->stmt); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return db2_stmt_error(); + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return [ + db2_stmt_errormsg(), + db2_stmt_error(), + ]; + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + if (! $this->stmt) { + return false; + } + + if ($params === null) { + ksort($this->bindParam); + + $params = []; + + foreach ($this->bindParam as $column => $value) { + $params[] = $value; + } + } + + foreach ($this->lobs as [$source, $target]) { + if (is_resource($source)) { + $this->copyStreamToStream($source, $target); + + continue; + } + + $this->writeStringToStream($source, $target); + } + + $retval = db2_execute($this->stmt, $params); + + foreach ($this->lobs as [, $handle]) { + fclose($handle); + } + + $this->lobs = []; + + if ($retval === false) { + throw new DB2Exception(db2_stmt_errormsg()); + } + + $this->result = true; + + return $retval; + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + $this->defaultFetchMode = $fetchMode; + $this->defaultFetchClass = $arg2 ?: $this->defaultFetchClass; + $this->defaultFetchClassCtorArgs = $arg3 ? (array) $arg3 : $this->defaultFetchClassCtorArgs; + + return true; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + return new StatementIterator($this); + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + // do not try fetching from the statement if it's not expected to contain result + // in order to prevent exceptional situation + if (! $this->result) { + return false; + } + + $fetchMode = $fetchMode ?: $this->defaultFetchMode; + switch ($fetchMode) { + case FetchMode::COLUMN: + return $this->fetchColumn(); + + case FetchMode::MIXED: + return db2_fetch_both($this->stmt); + + case FetchMode::ASSOCIATIVE: + return db2_fetch_assoc($this->stmt); + + case FetchMode::CUSTOM_OBJECT: + $className = $this->defaultFetchClass; + $ctorArgs = $this->defaultFetchClassCtorArgs; + + if (func_num_args() >= 2) { + $args = func_get_args(); + $className = $args[1]; + $ctorArgs = $args[2] ?? []; + } + + $result = db2_fetch_object($this->stmt); + + if ($result instanceof stdClass) { + $result = $this->castObject($result, $className, $ctorArgs); + } + + return $result; + + case FetchMode::NUMERIC: + return db2_fetch_array($this->stmt); + + case FetchMode::STANDARD_OBJECT: + return db2_fetch_object($this->stmt); + + default: + throw new DB2Exception('Given Fetch-Style ' . $fetchMode . ' is not supported.'); + } + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $rows = []; + + switch ($fetchMode) { + case FetchMode::CUSTOM_OBJECT: + while (($row = $this->fetch(...func_get_args())) !== false) { + $rows[] = $row; + } + break; + case FetchMode::COLUMN: + while (($row = $this->fetchColumn()) !== false) { + $rows[] = $row; + } + break; + default: + while (($row = $this->fetch($fetchMode)) !== false) { + $rows[] = $row; + } + } + + return $rows; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(FetchMode::NUMERIC); + + if ($row === false) { + return false; + } + + return $row[$columnIndex] ?? null; + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + return @db2_num_rows($this->stmt) ? : 0; + } + + /** + * Casts a stdClass object to the given class name mapping its' properties. + * + * @param stdClass $sourceObject Object to cast from. + * @param string|object $destinationClass Name of the class or class instance to cast to. + * @param mixed[] $ctorArgs Arguments to use for constructing the destination class instance. + * + * @return object + * + * @throws DB2Exception + */ + private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = []) + { + if (! is_string($destinationClass)) { + if (! is_object($destinationClass)) { + throw new DB2Exception(sprintf( + 'Destination class has to be of type string or object, %s given.', + gettype($destinationClass) + )); + } + } else { + $destinationClass = new ReflectionClass($destinationClass); + $destinationClass = $destinationClass->newInstanceArgs($ctorArgs); + } + + $sourceReflection = new ReflectionObject($sourceObject); + $destinationClassReflection = new ReflectionObject($destinationClass); + /** @var ReflectionProperty[] $destinationProperties */ + $destinationProperties = array_change_key_case($destinationClassReflection->getProperties(), CASE_LOWER); + + foreach ($sourceReflection->getProperties() as $sourceProperty) { + $sourceProperty->setAccessible(true); + + $name = $sourceProperty->getName(); + $value = $sourceProperty->getValue($sourceObject); + + // Try to find a case-matching property. + if ($destinationClassReflection->hasProperty($name)) { + $destinationProperty = $destinationClassReflection->getProperty($name); + + $destinationProperty->setAccessible(true); + $destinationProperty->setValue($destinationClass, $value); + + continue; + } + + $name = strtolower($name); + + // Try to find a property without matching case. + // Fallback for the driver returning either all uppercase or all lowercase column names. + if (isset($destinationProperties[$name])) { + $destinationProperty = $destinationProperties[$name]; + + $destinationProperty->setAccessible(true); + $destinationProperty->setValue($destinationClass, $value); + + continue; + } + + $destinationClass->$name = $value; + } + + return $destinationClass; + } + + /** + * @return resource + * + * @throws DB2Exception + */ + private function createTemporaryFile() + { + $handle = @tmpfile(); + + if ($handle === false) { + throw new DB2Exception('Could not create temporary file: ' . error_get_last()['message']); + } + + return $handle; + } + + /** + * @param resource $source + * @param resource $target + * + * @throws DB2Exception + */ + private function copyStreamToStream($source, $target) : void + { + if (@stream_copy_to_stream($source, $target) === false) { + throw new DB2Exception('Could not copy source stream to temporary file: ' . error_get_last()['message']); + } + } + + /** + * @param resource $target + * + * @throws DB2Exception + */ + private function writeStringToStream(string $string, $target) : void + { + if (@fwrite($target, $string) === false) { + throw new DB2Exception('Could not write string to temporary file: ' . error_get_last()['message']); + } + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php new file mode 100644 index 000000000..aaf4f2bd9 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/Driver.php @@ -0,0 +1,29 @@ +conn = mysqli_init(); + + $this->setSecureConnection($params); + $this->setDriverOptions($driverOptions); + + set_error_handler(static function () { + }); + try { + if (! $this->conn->real_connect($params['host'], $username, $password, $dbname, $port, $socket, $flags)) { + throw new MysqliException($this->conn->connect_error, $this->conn->sqlstate ?? 'HY000', $this->conn->connect_errno); + } + } finally { + restore_error_handler(); + } + + if (! isset($params['charset'])) { + return; + } + + $this->conn->set_charset($params['charset']); + } + + /** + * Retrieves mysqli native resource handle. + * + * Could be used if part of your application is not using DBAL. + * + * @return mysqli + */ + public function getWrappedResourceHandle() + { + return $this->conn; + } + + /** + * {@inheritdoc} + * + * The server version detection includes a special case for MariaDB + * to support '5.5.5-' prefixed versions introduced in Maria 10+ + * + * @link https://jira.mariadb.org/browse/MDEV-4088 + */ + public function getServerVersion() + { + $serverInfos = $this->conn->get_server_info(); + if (stripos($serverInfos, 'mariadb') !== false) { + return $serverInfos; + } + + $majorVersion = floor($this->conn->server_version / 10000); + $minorVersion = floor(($this->conn->server_version - $majorVersion * 10000) / 100); + $patchVersion = floor($this->conn->server_version - $majorVersion * 10000 - $minorVersion * 100); + + return $majorVersion . '.' . $minorVersion . '.' . $patchVersion; + } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function prepare($prepareString) + { + return new MysqliStatement($this->conn, $prepareString); + } + + /** + * {@inheritdoc} + */ + public function query() + { + $args = func_get_args(); + $sql = $args[0]; + $stmt = $this->prepare($sql); + $stmt->execute(); + + return $stmt; + } + + /** + * {@inheritdoc} + */ + public function quote($input, $type = ParameterType::STRING) + { + return "'" . $this->conn->escape_string($input) . "'"; + } + + /** + * {@inheritdoc} + */ + public function exec($statement) + { + if ($this->conn->query($statement) === false) { + throw new MysqliException($this->conn->error, $this->conn->sqlstate, $this->conn->errno); + } + + return $this->conn->affected_rows; + } + + /** + * {@inheritdoc} + */ + public function lastInsertId($name = null) + { + return $this->conn->insert_id; + } + + /** + * {@inheritdoc} + */ + public function beginTransaction() + { + $this->conn->query('START TRANSACTION'); + + return true; + } + + /** + * {@inheritdoc} + */ + public function commit() + { + return $this->conn->commit(); + } + + /** + * {@inheritdoc}non-PHPdoc) + */ + public function rollBack() + { + return $this->conn->rollback(); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return $this->conn->errno; + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return $this->conn->error; + } + + /** + * Apply the driver options to the connection. + * + * @param mixed[] $driverOptions + * + * @throws MysqliException When one of of the options is not supported. + * @throws MysqliException When applying doesn't work - e.g. due to incorrect value. + */ + private function setDriverOptions(array $driverOptions = []) + { + $supportedDriverOptions = [ + MYSQLI_OPT_CONNECT_TIMEOUT, + MYSQLI_OPT_LOCAL_INFILE, + MYSQLI_INIT_COMMAND, + MYSQLI_READ_DEFAULT_FILE, + MYSQLI_READ_DEFAULT_GROUP, + ]; + + if (defined('MYSQLI_SERVER_PUBLIC_KEY')) { + $supportedDriverOptions[] = MYSQLI_SERVER_PUBLIC_KEY; + } + + $exceptionMsg = "%s option '%s' with value '%s'"; + + foreach ($driverOptions as $option => $value) { + if ($option === static::OPTION_FLAGS) { + continue; + } + + if (! in_array($option, $supportedDriverOptions, true)) { + throw new MysqliException( + sprintf($exceptionMsg, 'Unsupported', $option, $value) + ); + } + + if (@mysqli_options($this->conn, $option, $value)) { + continue; + } + + $msg = sprintf($exceptionMsg, 'Failed to set', $option, $value); + $msg .= sprintf(', error: %s (%d)', mysqli_error($this->conn), mysqli_errno($this->conn)); + + throw new MysqliException( + $msg, + $this->conn->sqlstate, + $this->conn->errno + ); + } + } + + /** + * Pings the server and re-connects when `mysqli.reconnect = 1` + * + * @return bool + */ + public function ping() + { + return $this->conn->ping(); + } + + /** + * Establish a secure connection + * + * @param mixed[] $params + * + * @throws MysqliException + */ + private function setSecureConnection(array $params) + { + if (! isset($params['ssl_key']) && + ! isset($params['ssl_cert']) && + ! isset($params['ssl_ca']) && + ! isset($params['ssl_capath']) && + ! isset($params['ssl_cipher']) + ) { + return; + } + + $this->conn->ssl_set( + $params['ssl_key'] ?? null, + $params['ssl_cert'] ?? null, + $params['ssl_ca'] ?? null, + $params['ssl_capath'] ?? null, + $params['ssl_cipher'] ?? null + ); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php new file mode 100644 index 000000000..1fa0c900f --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Mysqli/MysqliException.php @@ -0,0 +1,12 @@ + 's', + ParameterType::BINARY => 's', + ParameterType::BOOLEAN => 'i', + ParameterType::NULL => 's', + ParameterType::INTEGER => 'i', + ParameterType::LARGE_OBJECT => 'b', + ]; + + /** @var mysqli */ + protected $_conn; + + /** @var mysqli_stmt */ + protected $_stmt; + + /** @var string[]|bool|null */ + protected $_columnNames; + + /** @var mixed[]|null */ + protected $_rowBindedValues; + + /** @var mixed[] */ + protected $_bindedValues; + + /** @var string */ + protected $types; + + /** + * Contains ref values for bindValue(). + * + * @var mixed[] + */ + protected $_values = []; + + /** @var int */ + protected $_defaultFetchMode = FetchMode::MIXED; + + /** + * Indicates whether the statement is in the state when fetching results is possible + * + * @var bool + */ + private $result = false; + + /** + * @param string $prepareString + * + * @throws MysqliException + */ + public function __construct(mysqli $conn, $prepareString) + { + $this->_conn = $conn; + $this->_stmt = $conn->prepare($prepareString); + if ($this->_stmt === false) { + throw new MysqliException($this->_conn->error, $this->_conn->sqlstate, $this->_conn->errno); + } + + $paramCount = $this->_stmt->param_count; + if (0 >= $paramCount) { + return; + } + + $this->types = str_repeat('s', $paramCount); + $this->_bindedValues = array_fill(1, $paramCount, null); + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) + { + if ($type === null) { + $type = 's'; + } else { + if (! isset(self::$_paramTypeMap[$type])) { + throw new MysqliException(sprintf("Unknown type: '%s'", $type)); + } + + $type = self::$_paramTypeMap[$type]; + } + + $this->_bindedValues[$column] =& $variable; + $this->types[$column - 1] = $type; + + return true; + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + if ($type === null) { + $type = 's'; + } else { + if (! isset(self::$_paramTypeMap[$type])) { + throw new MysqliException(sprintf("Unknown type: '%s'", $type)); + } + + $type = self::$_paramTypeMap[$type]; + } + + $this->_values[$param] = $value; + $this->_bindedValues[$param] =& $this->_values[$param]; + $this->types[$param - 1] = $type; + + return true; + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + if ($this->_bindedValues !== null) { + if ($params !== null) { + if (! $this->_bindValues($params)) { + throw new MysqliException($this->_stmt->error, $this->_stmt->errno); + } + } else { + [$types, $values, $streams] = $this->separateBoundValues(); + if (! $this->_stmt->bind_param($types, ...$values)) { + throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno); + } + $this->sendLongData($streams); + } + } + + if (! $this->_stmt->execute()) { + throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno); + } + + if ($this->_columnNames === null) { + $meta = $this->_stmt->result_metadata(); + if ($meta !== false) { + $columnNames = []; + foreach ($meta->fetch_fields() as $col) { + $columnNames[] = $col->name; + } + $meta->free(); + + $this->_columnNames = $columnNames; + } else { + $this->_columnNames = false; + } + } + + if ($this->_columnNames !== false) { + // Store result of every execution which has it. Otherwise it will be impossible + // to execute a new statement in case if the previous one has non-fetched rows + // @link http://dev.mysql.com/doc/refman/5.7/en/commands-out-of-sync.html + $this->_stmt->store_result(); + + // Bind row values _after_ storing the result. Otherwise, if mysqli is compiled with libmysql, + // it will have to allocate as much memory as it may be needed for the given column type + // (e.g. for a LONGBLOB field it's 4 gigabytes) + // @link https://bugs.php.net/bug.php?id=51386#1270673122 + // + // Make sure that the values are bound after each execution. Otherwise, if closeCursor() has been + // previously called on the statement, the values are unbound making the statement unusable. + // + // It's also important that row values are bound after _each_ call to store_result(). Otherwise, + // if mysqli is compiled with libmysql, subsequently fetched string values will get truncated + // to the length of the ones fetched during the previous execution. + $this->_rowBindedValues = array_fill(0, count($this->_columnNames), null); + + $refs = []; + foreach ($this->_rowBindedValues as $key => &$value) { + $refs[$key] =& $value; + } + + if (! $this->_stmt->bind_result(...$refs)) { + throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno); + } + } + + $this->result = true; + + return true; + } + + /** + * Split $this->_bindedValues into those values that need to be sent using mysqli::send_long_data() + * and those that can be bound the usual way. + * + * @return array|string> + */ + private function separateBoundValues() + { + $streams = $values = []; + $types = $this->types; + + foreach ($this->_bindedValues as $parameter => $value) { + if (! isset($types[$parameter - 1])) { + $types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING]; + } + + if ($types[$parameter - 1] === static::$_paramTypeMap[ParameterType::LARGE_OBJECT]) { + if (is_resource($value)) { + if (get_resource_type($value) !== 'stream') { + throw new InvalidArgumentException('Resources passed with the LARGE_OBJECT parameter type must be stream resources.'); + } + $streams[$parameter] = $value; + $values[$parameter] = null; + continue; + } else { + $types[$parameter - 1] = static::$_paramTypeMap[ParameterType::STRING]; + } + } + + $values[$parameter] = $value; + } + + return [$types, $values, $streams]; + } + + /** + * Handle $this->_longData after regular query parameters have been bound + * + * @throws MysqliException + */ + private function sendLongData($streams) + { + foreach ($streams as $paramNr => $stream) { + while (! feof($stream)) { + $chunk = fread($stream, 8192); + + if ($chunk === false) { + throw new MysqliException("Failed reading the stream resource for parameter offset ${paramNr}."); + } + + if (! $this->_stmt->send_long_data($paramNr - 1, $chunk)) { + throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno); + } + } + } + } + + /** + * Binds a array of values to bound parameters. + * + * @param mixed[] $values + * + * @return bool + */ + private function _bindValues($values) + { + $params = []; + $types = str_repeat('s', count($values)); + + foreach ($values as &$v) { + $params[] =& $v; + } + + return $this->_stmt->bind_param($types, ...$params); + } + + /** + * @return mixed[]|false + */ + private function _fetch() + { + $ret = $this->_stmt->fetch(); + + if ($ret === true) { + $values = []; + foreach ($this->_rowBindedValues as $v) { + $values[] = $v; + } + + return $values; + } + + return $ret; + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + // do not try fetching from the statement if it's not expected to contain result + // in order to prevent exceptional situation + if (! $this->result) { + return false; + } + + $fetchMode = $fetchMode ?: $this->_defaultFetchMode; + + if ($fetchMode === FetchMode::COLUMN) { + return $this->fetchColumn(); + } + + $values = $this->_fetch(); + if ($values === null) { + return false; + } + + if ($values === false) { + throw new MysqliException($this->_stmt->error, $this->_stmt->sqlstate, $this->_stmt->errno); + } + + switch ($fetchMode) { + case FetchMode::NUMERIC: + return $values; + + case FetchMode::ASSOCIATIVE: + return array_combine($this->_columnNames, $values); + + case FetchMode::MIXED: + $ret = array_combine($this->_columnNames, $values); + $ret += $values; + + return $ret; + + case FetchMode::STANDARD_OBJECT: + $assoc = array_combine($this->_columnNames, $values); + $ret = new stdClass(); + + foreach ($assoc as $column => $value) { + $ret->$column = $value; + } + + return $ret; + + default: + throw new MysqliException(sprintf("Unknown fetch type '%s'", $fetchMode)); + } + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $fetchMode = $fetchMode ?: $this->_defaultFetchMode; + + $rows = []; + + if ($fetchMode === FetchMode::COLUMN) { + while (($row = $this->fetchColumn()) !== false) { + $rows[] = $row; + } + } else { + while (($row = $this->fetch($fetchMode)) !== false) { + $rows[] = $row; + } + } + + return $rows; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(FetchMode::NUMERIC); + + if ($row === false) { + return false; + } + + return $row[$columnIndex] ?? null; + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return $this->_stmt->errno; + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return $this->_stmt->error; + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + $this->_stmt->free_result(); + $this->result = false; + + return true; + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + if ($this->_columnNames === false) { + return $this->_stmt->affected_rows; + } + + return $this->_stmt->num_rows; + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return $this->_stmt->field_count; + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + $this->_defaultFetchMode = $fetchMode; + + return true; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + return new StatementIterator($this); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php new file mode 100644 index 000000000..872582d80 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/Driver.php @@ -0,0 +1,52 @@ +_constructDsn($params), + $params['charset'] ?? null, + $params['sessionMode'] ?? OCI_DEFAULT, + $params['persistent'] ?? false + ); + } catch (OCI8Exception $e) { + throw DBALException::driverException($this, $e); + } + } + + /** + * Constructs the Oracle DSN. + * + * @param mixed[] $params + * + * @return string The DSN. + */ + protected function _constructDsn(array $params) + { + return $this->getEasyConnectString($params); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'oci8'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php new file mode 100644 index 000000000..5ebc877a8 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Connection.php @@ -0,0 +1,227 @@ +dbh = $persistent + ? @oci_pconnect($username, $password, $db, $charset, $sessionMode) + : @oci_connect($username, $password, $db, $charset, $sessionMode); + + if (! $this->dbh) { + throw OCI8Exception::fromErrorInfo(oci_error()); + } + } + + /** + * {@inheritdoc} + * + * @throws UnexpectedValueException If the version string returned by the database server + * does not contain a parsable version number. + */ + public function getServerVersion() + { + if (! preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', oci_server_version($this->dbh), $version)) { + throw new UnexpectedValueException( + sprintf( + 'Unexpected database version string "%s". Cannot parse an appropriate version number from it. ' . + 'Please report this database version string to the Doctrine team.', + oci_server_version($this->dbh) + ) + ); + } + + return $version[1]; + } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function prepare($prepareString) + { + return new OCI8Statement($this->dbh, $prepareString, $this); + } + + /** + * {@inheritdoc} + */ + public function query() + { + $args = func_get_args(); + $sql = $args[0]; + //$fetchMode = $args[1]; + $stmt = $this->prepare($sql); + $stmt->execute(); + + return $stmt; + } + + /** + * {@inheritdoc} + */ + public function quote($value, $type = ParameterType::STRING) + { + if (is_int($value) || is_float($value)) { + return $value; + } + $value = str_replace("'", "''", $value); + + return "'" . addcslashes($value, "\000\n\r\\\032") . "'"; + } + + /** + * {@inheritdoc} + */ + public function exec($statement) + { + $stmt = $this->prepare($statement); + $stmt->execute(); + + return $stmt->rowCount(); + } + + /** + * {@inheritdoc} + */ + public function lastInsertId($name = null) + { + if ($name === null) { + return false; + } + + $sql = 'SELECT ' . $name . '.CURRVAL FROM DUAL'; + $stmt = $this->query($sql); + $result = $stmt->fetchColumn(); + + if ($result === false) { + throw new OCI8Exception('lastInsertId failed: Query was executed but no result was returned.'); + } + + return (int) $result; + } + + /** + * Returns the current execution mode. + * + * @return int + */ + public function getExecuteMode() + { + return $this->executeMode; + } + + /** + * {@inheritdoc} + */ + public function beginTransaction() + { + $this->executeMode = OCI_NO_AUTO_COMMIT; + + return true; + } + + /** + * {@inheritdoc} + */ + public function commit() + { + if (! oci_commit($this->dbh)) { + throw OCI8Exception::fromErrorInfo($this->errorInfo()); + } + $this->executeMode = OCI_COMMIT_ON_SUCCESS; + + return true; + } + + /** + * {@inheritdoc} + */ + public function rollBack() + { + if (! oci_rollback($this->dbh)) { + throw OCI8Exception::fromErrorInfo($this->errorInfo()); + } + $this->executeMode = OCI_COMMIT_ON_SUCCESS; + + return true; + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + $error = oci_error($this->dbh); + if ($error !== false) { + $error = $error['code']; + } + + return $error; + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return oci_error($this->dbh); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php new file mode 100644 index 000000000..9d61ad42d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/OCI8/OCI8Exception.php @@ -0,0 +1,18 @@ + OCI_BOTH, + FetchMode::ASSOCIATIVE => OCI_ASSOC, + FetchMode::NUMERIC => OCI_NUM, + FetchMode::COLUMN => OCI_NUM, + ]; + + /** @var int */ + protected $_defaultFetchMode = FetchMode::MIXED; + + /** @var string[] */ + protected $_paramMap = []; + + /** + * Holds references to bound parameter values. + * + * This is a new requirement for PHP7's oci8 extension that prevents bound values from being garbage collected. + * + * @var mixed[] + */ + private $boundValues = []; + + /** + * Indicates whether the statement is in the state when fetching results is possible + * + * @var bool + */ + private $result = false; + + /** + * Creates a new OCI8Statement that uses the given connection handle and SQL statement. + * + * @param resource $dbh The connection handle. + * @param string $statement The SQL statement. + */ + public function __construct($dbh, $statement, OCI8Connection $conn) + { + [$statement, $paramMap] = self::convertPositionalToNamedPlaceholders($statement); + $this->_sth = oci_parse($dbh, $statement); + $this->_dbh = $dbh; + $this->_paramMap = $paramMap; + $this->_conn = $conn; + } + + /** + * Converts positional (?) into named placeholders (:param). + * + * Oracle does not support positional parameters, hence this method converts all + * positional parameters into artificially named parameters. Note that this conversion + * is not perfect. All question marks (?) in the original statement are treated as + * placeholders and converted to a named parameter. + * + * The algorithm uses a state machine with two possible states: InLiteral and NotInLiteral. + * Question marks inside literal strings are therefore handled correctly by this method. + * This comes at a cost, the whole sql statement has to be looped over. + * + * @param string $statement The SQL statement to convert. + * + * @return mixed[] [0] => the statement value (string), [1] => the paramMap value (array). + * + * @throws OCI8Exception + * + * @todo extract into utility class in Doctrine\DBAL\Util namespace + * @todo review and test for lost spaces. we experienced missing spaces with oci8 in some sql statements. + */ + public static function convertPositionalToNamedPlaceholders($statement) + { + $fragmentOffset = $tokenOffset = 0; + $fragments = $paramMap = []; + $currentLiteralDelimiter = null; + + do { + if (! $currentLiteralDelimiter) { + $result = self::findPlaceholderOrOpeningQuote( + $statement, + $tokenOffset, + $fragmentOffset, + $fragments, + $currentLiteralDelimiter, + $paramMap + ); + } else { + $result = self::findClosingQuote($statement, $tokenOffset, $currentLiteralDelimiter); + } + } while ($result); + + if ($currentLiteralDelimiter) { + throw new OCI8Exception(sprintf( + 'The statement contains non-terminated string literal starting at offset %d', + $tokenOffset - 1 + )); + } + + $fragments[] = substr($statement, $fragmentOffset); + $statement = implode('', $fragments); + + return [$statement, $paramMap]; + } + + /** + * Finds next placeholder or opening quote. + * + * @param string $statement The SQL statement to parse + * @param string $tokenOffset The offset to start searching from + * @param int $fragmentOffset The offset to build the next fragment from + * @param string[] $fragments Fragments of the original statement not containing placeholders + * @param string|null $currentLiteralDelimiter The delimiter of the current string literal + * or NULL if not currently in a literal + * @param array $paramMap Mapping of the original parameter positions to their named replacements + * + * @return bool Whether the token was found + */ + private static function findPlaceholderOrOpeningQuote( + $statement, + &$tokenOffset, + &$fragmentOffset, + &$fragments, + &$currentLiteralDelimiter, + &$paramMap + ) { + $token = self::findToken($statement, $tokenOffset, '/[?\'"]/'); + + if (! $token) { + return false; + } + + if ($token === '?') { + $position = count($paramMap) + 1; + $param = ':param' . $position; + $fragments[] = substr($statement, $fragmentOffset, $tokenOffset - $fragmentOffset); + $fragments[] = $param; + $paramMap[$position] = $param; + $tokenOffset += 1; + $fragmentOffset = $tokenOffset; + + return true; + } + + $currentLiteralDelimiter = $token; + ++$tokenOffset; + + return true; + } + + /** + * Finds closing quote + * + * @param string $statement The SQL statement to parse + * @param string $tokenOffset The offset to start searching from + * @param string|null $currentLiteralDelimiter The delimiter of the current string literal + * or NULL if not currently in a literal + * + * @return bool Whether the token was found + */ + private static function findClosingQuote( + $statement, + &$tokenOffset, + &$currentLiteralDelimiter + ) { + $token = self::findToken( + $statement, + $tokenOffset, + '/' . preg_quote($currentLiteralDelimiter, '/') . '/' + ); + + if (! $token) { + return false; + } + + $currentLiteralDelimiter = false; + ++$tokenOffset; + + return true; + } + + /** + * Finds the token described by regex starting from the given offset. Updates the offset with the position + * where the token was found. + * + * @param string $statement The SQL statement to parse + * @param string $offset The offset to start searching from + * @param string $regex The regex containing token pattern + * + * @return string|null Token or NULL if not found + */ + private static function findToken($statement, &$offset, $regex) + { + if (preg_match($regex, $statement, $matches, PREG_OFFSET_CAPTURE, $offset)) { + $offset = $matches[0][1]; + return $matches[0][0]; + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + return $this->bindParam($param, $value, $type, null); + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) + { + $column = $this->_paramMap[$column] ?? $column; + + if ($type === ParameterType::LARGE_OBJECT) { + $lob = oci_new_descriptor($this->_dbh, OCI_D_LOB); + $lob->writeTemporary($variable, OCI_TEMP_BLOB); + + $variable =& $lob; + } + + $this->boundValues[$column] =& $variable; + + return oci_bind_by_name( + $this->_sth, + $column, + $variable, + $length ?? -1, + $this->convertParameterType($type) + ); + } + + /** + * Converts DBAL parameter type to oci8 parameter type + */ + private function convertParameterType(int $type) : int + { + switch ($type) { + case ParameterType::BINARY: + return OCI_B_BIN; + + case ParameterType::LARGE_OBJECT: + return OCI_B_BLOB; + + default: + return SQLT_CHR; + } + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + // not having the result means there's nothing to close + if (! $this->result) { + return true; + } + + oci_cancel($this->_sth); + + $this->result = false; + + return true; + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return oci_num_fields($this->_sth); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + $error = oci_error($this->_sth); + if ($error !== false) { + $error = $error['code']; + } + + return $error; + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return oci_error($this->_sth); + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + if ($params) { + $hasZeroIndex = array_key_exists(0, $params); + foreach ($params as $key => $val) { + if ($hasZeroIndex && is_numeric($key)) { + $this->bindValue($key + 1, $val); + } else { + $this->bindValue($key, $val); + } + } + } + + $ret = @oci_execute($this->_sth, $this->_conn->getExecuteMode()); + if (! $ret) { + throw OCI8Exception::fromErrorInfo($this->errorInfo()); + } + + $this->result = true; + + return $ret; + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + $this->_defaultFetchMode = $fetchMode; + + return true; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + return new StatementIterator($this); + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + // do not try fetching from the statement if it's not expected to contain result + // in order to prevent exceptional situation + if (! $this->result) { + return false; + } + + $fetchMode = $fetchMode ?: $this->_defaultFetchMode; + + if ($fetchMode === FetchMode::COLUMN) { + return $this->fetchColumn(); + } + + if ($fetchMode === FetchMode::STANDARD_OBJECT) { + return oci_fetch_object($this->_sth); + } + + if (! isset(self::$fetchModeMap[$fetchMode])) { + throw new InvalidArgumentException('Invalid fetch style: ' . $fetchMode); + } + + return oci_fetch_array( + $this->_sth, + self::$fetchModeMap[$fetchMode] | OCI_RETURN_NULLS | OCI_RETURN_LOBS + ); + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $fetchMode = $fetchMode ?: $this->_defaultFetchMode; + + $result = []; + + if ($fetchMode === FetchMode::STANDARD_OBJECT) { + while ($row = $this->fetch($fetchMode)) { + $result[] = $row; + } + + return $result; + } + + if (! isset(self::$fetchModeMap[$fetchMode])) { + throw new InvalidArgumentException('Invalid fetch style: ' . $fetchMode); + } + + if (self::$fetchModeMap[$fetchMode] === OCI_BOTH) { + while ($row = $this->fetch($fetchMode)) { + $result[] = $row; + } + } else { + $fetchStructure = OCI_FETCHSTATEMENT_BY_ROW; + + if ($fetchMode === FetchMode::COLUMN) { + $fetchStructure = OCI_FETCHSTATEMENT_BY_COLUMN; + } + + // do not try fetching from the statement if it's not expected to contain result + // in order to prevent exceptional situation + if (! $this->result) { + return []; + } + + oci_fetch_all( + $this->_sth, + $result, + 0, + -1, + self::$fetchModeMap[$fetchMode] | OCI_RETURN_NULLS | $fetchStructure | OCI_RETURN_LOBS + ); + + if ($fetchMode === FetchMode::COLUMN) { + $result = $result[0]; + } + } + + return $result; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + // do not try fetching from the statement if it's not expected to contain result + // in order to prevent exceptional situation + if (! $this->result) { + return false; + } + + $row = oci_fetch_array($this->_sth, OCI_NUM | OCI_RETURN_NULLS | OCI_RETURN_LOBS); + + if ($row === false) { + return false; + } + + return $row[$columnIndex] ?? null; + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + return oci_num_rows($this->_sth); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php new file mode 100644 index 000000000..2155140b2 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php @@ -0,0 +1,121 @@ +setAttribute(PDO::ATTR_STATEMENT_CLASS, [PDOStatement::class, []]); + $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function exec($statement) + { + try { + return parent::exec($statement); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function getServerVersion() + { + return PDO::getAttribute(PDO::ATTR_SERVER_VERSION); + } + + /** + * {@inheritdoc} + */ + public function prepare($prepareString, $driverOptions = []) + { + try { + return parent::prepare($prepareString, $driverOptions); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function query() + { + $args = func_get_args(); + $argsCount = count($args); + + try { + if ($argsCount === 4) { + return parent::query($args[0], $args[1], $args[2], $args[3]); + } + + if ($argsCount === 3) { + return parent::query($args[0], $args[1], $args[2]); + } + + if ($argsCount === 2) { + return parent::query($args[0], $args[1]); + } + + return parent::query($args[0]); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function quote($input, $type = ParameterType::STRING) + { + return parent::quote($input, $type); + } + + /** + * {@inheritdoc} + */ + public function lastInsertId($name = null) + { + try { + return parent::lastInsertId($name); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return false; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOException.php new file mode 100644 index 000000000..277d7a625 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOException.php @@ -0,0 +1,52 @@ +getMessage(), 0, $exception); + + $this->code = $exception->getCode(); + $this->errorInfo = $exception->errorInfo; + $this->errorCode = $exception->errorInfo[1] ?? $exception->getCode(); + $this->sqlState = $exception->errorInfo[0] ?? $exception->getCode(); + } + + /** + * {@inheritdoc} + */ + public function getErrorCode() + { + return $this->errorCode; + } + + /** + * {@inheritdoc} + */ + public function getSQLState() + { + return $this->sqlState; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php new file mode 100644 index 000000000..4291e1e17 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOIbm/Driver.php @@ -0,0 +1,57 @@ +_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + } + + /** + * Constructs the IBM PDO DSN. + * + * @param mixed[] $params + * + * @return string The DSN. + */ + private function _constructPdoDsn(array $params) + { + $dsn = 'ibm:'; + if (isset($params['host'])) { + $dsn .= 'HOSTNAME=' . $params['host'] . ';'; + } + if (isset($params['port'])) { + $dsn .= 'PORT=' . $params['port'] . ';'; + } + $dsn .= 'PROTOCOL=TCPIP;'; + if (isset($params['dbname'])) { + $dsn .= 'DATABASE=' . $params['dbname'] . ';'; + } + + return $dsn; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_ibm'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php new file mode 100644 index 000000000..59d27d384 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php @@ -0,0 +1,70 @@ +constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + } catch (PDOException $e) { + throw DBALException::driverException($this, $e); + } + + return $conn; + } + + /** + * Constructs the MySql PDO DSN. + * + * @param mixed[] $params + * + * @return string The DSN. + */ + protected function constructPdoDsn(array $params) + { + $dsn = 'mysql:'; + if (isset($params['host']) && $params['host'] !== '') { + $dsn .= 'host=' . $params['host'] . ';'; + } + if (isset($params['port'])) { + $dsn .= 'port=' . $params['port'] . ';'; + } + if (isset($params['dbname'])) { + $dsn .= 'dbname=' . $params['dbname'] . ';'; + } + if (isset($params['unix_socket'])) { + $dsn .= 'unix_socket=' . $params['unix_socket'] . ';'; + } + if (isset($params['charset'])) { + $dsn .= 'charset=' . $params['charset'] . ';'; + } + + return $dsn; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_mysql'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php new file mode 100644 index 000000000..f1239eafb --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOOracle/Driver.php @@ -0,0 +1,62 @@ +constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + } catch (PDOException $e) { + throw DBALException::driverException($this, $e); + } + } + + /** + * Constructs the Oracle PDO DSN. + * + * @param mixed[] $params + * + * @return string The DSN. + */ + private function constructPdoDsn(array $params) + { + $dsn = 'oci:dbname=' . $this->getEasyConnectString($params); + + if (isset($params['charset'])) { + $dsn .= ';charset=' . $params['charset']; + } + + return $dsn; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_oracle'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php new file mode 100644 index 000000000..972dbadcd --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOPgSql/Driver.php @@ -0,0 +1,116 @@ +_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + + if (defined('PDO::PGSQL_ATTR_DISABLE_PREPARES') + && (! isset($driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES]) + || $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true + ) + ) { + $pdo->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true); + } + + /* defining client_encoding via SET NAMES to avoid inconsistent DSN support + * - the 'client_encoding' connection param only works with postgres >= 9.1 + * - passing client_encoding via the 'options' param breaks pgbouncer support + */ + if (isset($params['charset'])) { + $pdo->exec('SET NAMES \'' . $params['charset'] . '\''); + } + + return $pdo; + } catch (PDOException $e) { + throw DBALException::driverException($this, $e); + } + } + + /** + * Constructs the Postgres PDO DSN. + * + * @param mixed[] $params + * + * @return string The DSN. + */ + private function _constructPdoDsn(array $params) + { + $dsn = 'pgsql:'; + + if (isset($params['host']) && $params['host'] !== '') { + $dsn .= 'host=' . $params['host'] . ';'; + } + + if (isset($params['port']) && $params['port'] !== '') { + $dsn .= 'port=' . $params['port'] . ';'; + } + + if (isset($params['dbname'])) { + $dsn .= 'dbname=' . $params['dbname'] . ';'; + } elseif (isset($params['default_dbname'])) { + $dsn .= 'dbname=' . $params['default_dbname'] . ';'; + } else { + // Used for temporary connections to allow operations like dropping the database currently connected to. + // Connecting without an explicit database does not work, therefore "postgres" database is used + // as it is mostly present in every server setup. + $dsn .= 'dbname=postgres;'; + } + + if (isset($params['sslmode'])) { + $dsn .= 'sslmode=' . $params['sslmode'] . ';'; + } + + if (isset($params['sslrootcert'])) { + $dsn .= 'sslrootcert=' . $params['sslrootcert'] . ';'; + } + + if (isset($params['sslcert'])) { + $dsn .= 'sslcert=' . $params['sslcert'] . ';'; + } + + if (isset($params['sslkey'])) { + $dsn .= 'sslkey=' . $params['sslkey'] . ';'; + } + + if (isset($params['sslcrl'])) { + $dsn .= 'sslcrl=' . $params['sslcrl'] . ';'; + } + + if (isset($params['application_name'])) { + $dsn .= 'application_name=' . $params['application_name'] . ';'; + } + + return $dsn; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_pgsql'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php new file mode 100644 index 000000000..7a28b8310 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlite/Driver.php @@ -0,0 +1,81 @@ + ['callback' => [SqlitePlatform::class, 'udfSqrt'], 'numArgs' => 1], + 'mod' => ['callback' => [SqlitePlatform::class, 'udfMod'], 'numArgs' => 2], + 'locate' => ['callback' => [SqlitePlatform::class, 'udfLocate'], 'numArgs' => -1], + ]; + + /** + * {@inheritdoc} + */ + public function connect(array $params, $username = null, $password = null, array $driverOptions = []) + { + if (isset($driverOptions['userDefinedFunctions'])) { + $this->_userDefinedFunctions = array_merge( + $this->_userDefinedFunctions, + $driverOptions['userDefinedFunctions'] + ); + unset($driverOptions['userDefinedFunctions']); + } + + try { + $pdo = new PDOConnection( + $this->_constructPdoDsn($params), + $username, + $password, + $driverOptions + ); + } catch (PDOException $ex) { + throw DBALException::driverException($this, $ex); + } + + foreach ($this->_userDefinedFunctions as $fn => $data) { + $pdo->sqliteCreateFunction($fn, $data['callback'], $data['numArgs']); + } + + return $pdo; + } + + /** + * Constructs the Sqlite PDO DSN. + * + * @param mixed[] $params + * + * @return string The DSN. + */ + protected function _constructPdoDsn(array $params) + { + $dsn = 'sqlite:'; + if (isset($params['path'])) { + $dsn .= $params['path']; + } elseif (isset($params['memory'])) { + $dsn .= ':memory:'; + } + + return $dsn; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_sqlite'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php new file mode 100644 index 000000000..bd3894477 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Connection.php @@ -0,0 +1,54 @@ +setAttribute(PDO::ATTR_STATEMENT_CLASS, [Statement::class, []]); + } + + /** + * {@inheritDoc} + */ + public function lastInsertId($name = null) + { + if ($name === null) { + return parent::lastInsertId($name); + } + + $stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?'); + $stmt->execute([$name]); + + return $stmt->fetchColumn(); + } + + /** + * {@inheritDoc} + */ + public function quote($value, $type = ParameterType::STRING) + { + $val = parent::quote($value, $type); + + // Fix for a driver version terminating all values with null byte + if (strpos($val, "\0") !== false) { + $val = substr($val, 0, -1); + } + + return $val; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php new file mode 100644 index 000000000..6543e3239 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Driver.php @@ -0,0 +1,106 @@ +splitOptions($driverOptions); + + return new Connection( + $this->_constructPdoDsn($params, $connectionOptions), + $username, + $password, + $driverOptions + ); + } + + /** + * Constructs the Sqlsrv PDO DSN. + * + * @param mixed[] $params + * @param string[] $connectionOptions + * + * @return string The DSN. + */ + private function _constructPdoDsn(array $params, array $connectionOptions) + { + $dsn = 'sqlsrv:server='; + + if (isset($params['host'])) { + $dsn .= $params['host']; + } + + if (isset($params['port']) && ! empty($params['port'])) { + $dsn .= ',' . $params['port']; + } + + if (isset($params['dbname'])) { + $connectionOptions['Database'] = $params['dbname']; + } + + if (isset($params['MultipleActiveResultSets'])) { + $connectionOptions['MultipleActiveResultSets'] = $params['MultipleActiveResultSets'] ? 'true' : 'false'; + } + + return $dsn . $this->getConnectionOptionsDsn($connectionOptions); + } + + /** + * Separates a connection options from a driver options + * + * @param int[]|string[] $options + * + * @return int[][]|string[][] + */ + private function splitOptions(array $options) : array + { + $driverOptions = []; + $connectionOptions = []; + + foreach ($options as $optionKey => $optionValue) { + if (is_int($optionKey)) { + $driverOptions[$optionKey] = $optionValue; + } else { + $connectionOptions[$optionKey] = $optionValue; + } + } + + return [$driverOptions, $connectionOptions]; + } + + /** + * Converts a connection options array to the DSN + * + * @param string[] $connectionOptions + */ + private function getConnectionOptionsDsn(array $connectionOptions) : string + { + $connectionOptionsDsn = ''; + + foreach ($connectionOptions as $paramName => $paramValue) { + $connectionOptionsDsn .= sprintf(';%s=%s', $paramName, $paramValue); + } + + return $connectionOptionsDsn; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_sqlsrv'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Statement.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Statement.php new file mode 100644 index 000000000..6803bb14e --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOSqlsrv/Statement.php @@ -0,0 +1,35 @@ +bindParam($param, $value, $type); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php new file mode 100644 index 000000000..2aed89fbf --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php @@ -0,0 +1,231 @@ + PDO::PARAM_NULL, + ParameterType::INTEGER => PDO::PARAM_INT, + ParameterType::STRING => PDO::PARAM_STR, + ParameterType::BINARY => PDO::PARAM_LOB, + ParameterType::LARGE_OBJECT => PDO::PARAM_LOB, + ParameterType::BOOLEAN => PDO::PARAM_BOOL, + ]; + + private const FETCH_MODE_MAP = [ + FetchMode::ASSOCIATIVE => PDO::FETCH_ASSOC, + FetchMode::NUMERIC => PDO::FETCH_NUM, + FetchMode::MIXED => PDO::FETCH_BOTH, + FetchMode::STANDARD_OBJECT => PDO::FETCH_OBJ, + FetchMode::COLUMN => PDO::FETCH_COLUMN, + FetchMode::CUSTOM_OBJECT => PDO::FETCH_CLASS, + ]; + + /** + * Protected constructor. + */ + protected function __construct() + { + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + $fetchMode = $this->convertFetchMode($fetchMode); + + // This thin wrapper is necessary to shield against the weird signature + // of PDOStatement::setFetchMode(): even if the second and third + // parameters are optional, PHP will not let us remove it from this + // declaration. + try { + if ($arg2 === null && $arg3 === null) { + return parent::setFetchMode($fetchMode); + } + + if ($arg3 === null) { + return parent::setFetchMode($fetchMode, $arg2); + } + + return parent::setFetchMode($fetchMode, $arg2, $arg3); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + $type = $this->convertParamType($type); + + try { + return parent::bindValue($param, $value, $type); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null, $driverOptions = null) + { + $type = $this->convertParamType($type); + + try { + return parent::bindParam($column, $variable, $type, $length, $driverOptions); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + try { + return parent::closeCursor(); + } catch (\PDOException $exception) { + // Exceptions not allowed by the interface. + // In case driver implementations do not adhere to the interface, silence exceptions here. + return true; + } + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + try { + return parent::execute($params); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + $fetchMode = $this->convertFetchMode($fetchMode); + + try { + if ($fetchMode === null && $cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) { + return parent::fetch(); + } + + if ($cursorOrientation === PDO::FETCH_ORI_NEXT && $cursorOffset === 0) { + return parent::fetch($fetchMode); + } + + if ($cursorOffset === 0) { + return parent::fetch($fetchMode, $cursorOrientation); + } + + return parent::fetch($fetchMode, $cursorOrientation, $cursorOffset); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $fetchMode = $this->convertFetchMode($fetchMode); + + try { + if ($fetchMode === null && $fetchArgument === null && $ctorArgs === null) { + return parent::fetchAll(); + } + + if ($fetchArgument === null && $ctorArgs === null) { + return parent::fetchAll($fetchMode); + } + + if ($ctorArgs === null) { + return parent::fetchAll($fetchMode, $fetchArgument); + } + + return parent::fetchAll($fetchMode, $fetchArgument, $ctorArgs); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + try { + return parent::fetchColumn($columnIndex); + } catch (\PDOException $exception) { + throw new PDOException($exception); + } + } + + /** + * Converts DBAL parameter type to PDO parameter type + * + * @param int $type Parameter type + */ + private function convertParamType(int $type) : int + { + if (! isset(self::PARAM_TYPE_MAP[$type])) { + // TODO: next major: throw an exception + @trigger_error(sprintf( + 'Using a PDO parameter type (%d given) is deprecated and will cause an error in Doctrine 3.0', + $type + ), E_USER_DEPRECATED); + + return $type; + } + + return self::PARAM_TYPE_MAP[$type]; + } + + /** + * Converts DBAL fetch mode to PDO fetch mode + * + * @param int|null $fetchMode Fetch mode + */ + private function convertFetchMode(?int $fetchMode) : ?int + { + if ($fetchMode === null) { + return null; + } + + if (! isset(self::FETCH_MODE_MAP[$fetchMode])) { + // TODO: next major: throw an exception + @trigger_error(sprintf( + 'Using a PDO fetch mode or their combination (%d given)' . + ' is deprecated and will cause an error in Doctrine 3.0', + $fetchMode + ), E_USER_DEPRECATED); + + return $fetchMode; + } + + return self::FETCH_MODE_MAP[$fetchMode]; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PingableConnection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PingableConnection.php new file mode 100644 index 000000000..06bfb9a7f --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PingableConnection.php @@ -0,0 +1,17 @@ +buildDsn( + $params['host'] ?? null, + $params['port'] ?? null, + $params['server'] ?? null, + $params['dbname'] ?? null, + $username, + $password, + $driverOptions + ), + $params['persistent'] ?? false + ); + } catch (SQLAnywhereException $e) { + throw DBALException::driverException($this, $e); + } + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'sqlanywhere'; + } + + /** + * Build the connection string for given connection parameters and driver options. + * + * @param string $host Host address to connect to. + * @param int $port Port to use for the connection (default to SQL Anywhere standard port 2638). + * @param string $server Database server name on the host to connect to. + * SQL Anywhere allows multiple database server instances on the same host, + * therefore specifying the server instance name to use is mandatory. + * @param string $dbname Name of the database on the server instance to connect to. + * @param string $username User name to use for connection authentication. + * @param string $password Password to use for connection authentication. + * @param mixed[] $driverOptions Additional parameters to use for the connection. + * + * @return string + */ + private function buildDsn($host, $port, $server, $dbname, $username = null, $password = null, array $driverOptions = []) + { + $host = $host ?: 'localhost'; + $port = $port ?: 2638; + + if (! empty($server)) { + $server = ';ServerName=' . $server; + } + + return 'HOST=' . $host . ':' . $port . + $server . + ';DBN=' . $dbname . + ';UID=' . $username . + ';PWD=' . $password . + ';' . implode( + ';', + array_map(static function ($key, $value) { + return $key . '=' . $value; + }, array_keys($driverOptions), $driverOptions) + ); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php new file mode 100644 index 000000000..d47782003 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereConnection.php @@ -0,0 +1,215 @@ +connection = $persistent ? @sasql_pconnect($dsn) : @sasql_connect($dsn); + + if (! is_resource($this->connection)) { + throw SQLAnywhereException::fromSQLAnywhereError(); + } + + // Disable PHP warnings on error. + if (! sasql_set_option($this->connection, 'verbose_errors', false)) { + throw SQLAnywhereException::fromSQLAnywhereError($this->connection); + } + + // Enable auto committing by default. + if (! sasql_set_option($this->connection, 'auto_commit', 'on')) { + throw SQLAnywhereException::fromSQLAnywhereError($this->connection); + } + } + + /** + * {@inheritdoc} + * + * @throws SQLAnywhereException + */ + public function beginTransaction() + { + if (! sasql_set_option($this->connection, 'auto_commit', 'off')) { + throw SQLAnywhereException::fromSQLAnywhereError($this->connection); + } + + return true; + } + + /** + * {@inheritdoc} + * + * @throws SQLAnywhereException + */ + public function commit() + { + if (! sasql_commit($this->connection)) { + throw SQLAnywhereException::fromSQLAnywhereError($this->connection); + } + + $this->endTransaction(); + + return true; + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return sasql_errorcode($this->connection); + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return sasql_error($this->connection); + } + + /** + * {@inheritdoc} + */ + public function exec($statement) + { + if (sasql_real_query($this->connection, $statement) === false) { + throw SQLAnywhereException::fromSQLAnywhereError($this->connection); + } + + return sasql_affected_rows($this->connection); + } + + /** + * {@inheritdoc} + */ + public function getServerVersion() + { + $version = $this->query("SELECT PROPERTY('ProductVersion')")->fetchColumn(); + + assert(is_string($version)); + + return $version; + } + + /** + * {@inheritdoc} + */ + public function lastInsertId($name = null) + { + if ($name === null) { + return sasql_insert_id($this->connection); + } + + return $this->query('SELECT ' . $name . '.CURRVAL')->fetchColumn(); + } + + /** + * {@inheritdoc} + */ + public function prepare($prepareString) + { + return new SQLAnywhereStatement($this->connection, $prepareString); + } + + /** + * {@inheritdoc} + */ + public function query() + { + $args = func_get_args(); + $stmt = $this->prepare($args[0]); + + $stmt->execute(); + + return $stmt; + } + + /** + * {@inheritdoc} + */ + public function quote($input, $type = ParameterType::STRING) + { + if (is_int($input) || is_float($input)) { + return $input; + } + + return "'" . sasql_escape_string($this->connection, $input) . "'"; + } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return true; + } + + /** + * {@inheritdoc} + * + * @throws SQLAnywhereException + */ + public function rollBack() + { + if (! sasql_rollback($this->connection)) { + throw SQLAnywhereException::fromSQLAnywhereError($this->connection); + } + + $this->endTransaction(); + + return true; + } + + /** + * Ends transactional mode and enables auto commit again. + * + * @return bool Whether or not ending transactional mode succeeded. + * + * @throws SQLAnywhereException + */ + private function endTransaction() + { + if (! sasql_set_option($this->connection, 'auto_commit', 'on')) { + throw SQLAnywhereException::fromSQLAnywhereError($this->connection); + } + + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php new file mode 100644 index 000000000..9f8aac060 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLAnywhere/SQLAnywhereException.php @@ -0,0 +1,80 @@ +conn = $conn; + $this->stmt = sasql_prepare($conn, $sql); + + if (! is_resource($this->stmt)) { + throw SQLAnywhereException::fromSQLAnywhereError($conn); + } + } + + /** + * {@inheritdoc} + * + * @throws SQLAnywhereException + */ + public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) + { + switch ($type) { + case ParameterType::INTEGER: + case ParameterType::BOOLEAN: + $type = 'i'; + break; + + case ParameterType::LARGE_OBJECT: + $type = 'b'; + break; + + case ParameterType::NULL: + case ParameterType::STRING: + case ParameterType::BINARY: + $type = 's'; + break; + + default: + throw new SQLAnywhereException('Unknown type: ' . $type); + } + + $this->boundValues[$column] =& $variable; + + if (! sasql_stmt_bind_param_ex($this->stmt, $column - 1, $variable, $type, $variable === null)) { + throw SQLAnywhereException::fromSQLAnywhereError($this->conn, $this->stmt); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + return $this->bindParam($param, $value, $type); + } + + /** + * {@inheritdoc} + * + * @throws SQLAnywhereException + */ + public function closeCursor() + { + if (! sasql_stmt_reset($this->stmt)) { + throw SQLAnywhereException::fromSQLAnywhereError($this->conn, $this->stmt); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return sasql_stmt_field_count($this->stmt); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return sasql_stmt_errno($this->stmt); + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return sasql_stmt_error($this->stmt); + } + + /** + * {@inheritdoc} + * + * @throws SQLAnywhereException + */ + public function execute($params = null) + { + if (is_array($params)) { + $hasZeroIndex = array_key_exists(0, $params); + + foreach ($params as $key => $val) { + $key = $hasZeroIndex && is_numeric($key) ? $key + 1 : $key; + + $this->bindValue($key, $val); + } + } + + if (! sasql_stmt_execute($this->stmt)) { + throw SQLAnywhereException::fromSQLAnywhereError($this->conn, $this->stmt); + } + + $this->result = sasql_stmt_result_metadata($this->stmt); + + return true; + } + + /** + * {@inheritdoc} + * + * @throws SQLAnywhereException + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + if (! is_resource($this->result)) { + return false; + } + + $fetchMode = $fetchMode ?: $this->defaultFetchMode; + + switch ($fetchMode) { + case FetchMode::COLUMN: + return $this->fetchColumn(); + + case FetchMode::ASSOCIATIVE: + return sasql_fetch_assoc($this->result); + + case FetchMode::MIXED: + return sasql_fetch_array($this->result, SASQL_BOTH); + + case FetchMode::CUSTOM_OBJECT: + $className = $this->defaultFetchClass; + $ctorArgs = $this->defaultFetchClassCtorArgs; + + if (func_num_args() >= 2) { + $args = func_get_args(); + $className = $args[1]; + $ctorArgs = $args[2] ?? []; + } + + $result = sasql_fetch_object($this->result); + + if ($result instanceof stdClass) { + $result = $this->castObject($result, $className, $ctorArgs); + } + + return $result; + + case FetchMode::NUMERIC: + return sasql_fetch_row($this->result); + + case FetchMode::STANDARD_OBJECT: + return sasql_fetch_object($this->result); + + default: + throw new SQLAnywhereException('Fetch mode is not supported: ' . $fetchMode); + } + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $rows = []; + + switch ($fetchMode) { + case FetchMode::CUSTOM_OBJECT: + while (($row = $this->fetch(...func_get_args())) !== false) { + $rows[] = $row; + } + break; + + case FetchMode::COLUMN: + while (($row = $this->fetchColumn()) !== false) { + $rows[] = $row; + } + break; + + default: + while (($row = $this->fetch($fetchMode)) !== false) { + $rows[] = $row; + } + } + + return $rows; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(FetchMode::NUMERIC); + + if ($row === false) { + return false; + } + + return $row[$columnIndex] ?? null; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + return new StatementIterator($this); + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + return sasql_stmt_affected_rows($this->stmt); + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + $this->defaultFetchMode = $fetchMode; + $this->defaultFetchClass = $arg2 ?: $this->defaultFetchClass; + $this->defaultFetchClassCtorArgs = $arg3 ? (array) $arg3 : $this->defaultFetchClassCtorArgs; + } + + /** + * Casts a stdClass object to the given class name mapping its' properties. + * + * @param stdClass $sourceObject Object to cast from. + * @param string|object $destinationClass Name of the class or class instance to cast to. + * @param mixed[] $ctorArgs Arguments to use for constructing the destination class instance. + * + * @return object + * + * @throws SQLAnywhereException + */ + private function castObject(stdClass $sourceObject, $destinationClass, array $ctorArgs = []) + { + if (! is_string($destinationClass)) { + if (! is_object($destinationClass)) { + throw new SQLAnywhereException(sprintf( + 'Destination class has to be of type string or object, %s given.', + gettype($destinationClass) + )); + } + } else { + $destinationClass = new ReflectionClass($destinationClass); + $destinationClass = $destinationClass->newInstanceArgs($ctorArgs); + } + + $sourceReflection = new ReflectionObject($sourceObject); + $destinationClassReflection = new ReflectionObject($destinationClass); + + foreach ($sourceReflection->getProperties() as $sourceProperty) { + $sourceProperty->setAccessible(true); + + $name = $sourceProperty->getName(); + $value = $sourceProperty->getValue($sourceObject); + + if ($destinationClassReflection->hasProperty($name)) { + $destinationProperty = $destinationClassReflection->getProperty($name); + + $destinationProperty->setAccessible(true); + $destinationProperty->setValue($destinationClass, $value); + } else { + $destinationClass->$name = $value; + } + } + + return $destinationClass; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php new file mode 100644 index 000000000..a9be26e9d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/Driver.php @@ -0,0 +1,56 @@ +id = $id; + } + + /** + * @return int + */ + public function getId() + { + return $this->id; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php new file mode 100644 index 000000000..f1f9ddd1d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvConnection.php @@ -0,0 +1,186 @@ +conn = sqlsrv_connect($serverName, $connectionOptions); + if (! $this->conn) { + throw SQLSrvException::fromSqlSrvErrors(); + } + $this->lastInsertId = new LastInsertId(); + } + + /** + * {@inheritdoc} + */ + public function getServerVersion() + { + $serverInfo = sqlsrv_server_info($this->conn); + + return $serverInfo['SQLServerVersion']; + } + + /** + * {@inheritdoc} + */ + public function requiresQueryForServerVersion() + { + return false; + } + + /** + * {@inheritDoc} + */ + public function prepare($sql) + { + return new SQLSrvStatement($this->conn, $sql, $this->lastInsertId); + } + + /** + * {@inheritDoc} + */ + public function query() + { + $args = func_get_args(); + $sql = $args[0]; + $stmt = $this->prepare($sql); + $stmt->execute(); + + return $stmt; + } + + /** + * {@inheritDoc} + */ + public function quote($value, $type = ParameterType::STRING) + { + if (is_int($value)) { + return $value; + } elseif (is_float($value)) { + return sprintf('%F', $value); + } + + return "'" . str_replace("'", "''", $value) . "'"; + } + + /** + * {@inheritDoc} + */ + public function exec($statement) + { + $stmt = sqlsrv_query($this->conn, $statement); + + if ($stmt === false) { + throw SQLSrvException::fromSqlSrvErrors(); + } + + return sqlsrv_rows_affected($stmt); + } + + /** + * {@inheritDoc} + */ + public function lastInsertId($name = null) + { + if ($name !== null) { + $stmt = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?'); + $stmt->execute([$name]); + } else { + $stmt = $this->query('SELECT @@IDENTITY'); + } + + return $stmt->fetchColumn(); + } + + /** + * {@inheritDoc} + */ + public function beginTransaction() + { + if (! sqlsrv_begin_transaction($this->conn)) { + throw SQLSrvException::fromSqlSrvErrors(); + } + } + + /** + * {@inheritDoc} + */ + public function commit() + { + if (! sqlsrv_commit($this->conn)) { + throw SQLSrvException::fromSqlSrvErrors(); + } + } + + /** + * {@inheritDoc} + */ + public function rollBack() + { + if (! sqlsrv_rollback($this->conn)) { + throw SQLSrvException::fromSqlSrvErrors(); + } + } + + /** + * {@inheritDoc} + */ + public function errorCode() + { + $errors = sqlsrv_errors(SQLSRV_ERR_ERRORS); + if ($errors) { + return $errors[0]['code']; + } + + return false; + } + + /** + * {@inheritDoc} + */ + public function errorInfo() + { + return sqlsrv_errors(SQLSRV_ERR_ERRORS); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php new file mode 100644 index 000000000..796f5d129 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/SQLSrv/SQLSrvException.php @@ -0,0 +1,43 @@ + SQLSRV_FETCH_BOTH, + FetchMode::ASSOCIATIVE => SQLSRV_FETCH_ASSOC, + FetchMode::NUMERIC => SQLSRV_FETCH_NUMERIC, + ]; + + /** + * The name of the default class to instantiate when fetching class instances. + * + * @var string + */ + private $defaultFetchClass = '\stdClass'; + + /** + * The constructor arguments for the default class to instantiate when fetching class instances. + * + * @var mixed[] + */ + private $defaultFetchClassCtorArgs = []; + + /** + * The fetch style. + * + * @var int + */ + private $defaultFetchMode = FetchMode::MIXED; + + /** + * The last insert ID. + * + * @var LastInsertId|null + */ + private $lastInsertId; + + /** + * Indicates whether the statement is in the state when fetching results is possible + * + * @var bool + */ + private $result = false; + + /** + * Append to any INSERT query to retrieve the last insert id. + */ + public const LAST_INSERT_ID_SQL = ';SELECT SCOPE_IDENTITY() AS LastInsertId;'; + + /** + * @param resource $conn + * @param string $sql + */ + public function __construct($conn, $sql, ?LastInsertId $lastInsertId = null) + { + $this->conn = $conn; + $this->sql = $sql; + + if (stripos($sql, 'INSERT INTO ') !== 0) { + return; + } + + $this->sql .= self::LAST_INSERT_ID_SQL; + $this->lastInsertId = $lastInsertId; + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + if (! is_numeric($param)) { + throw new SQLSrvException( + 'sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead.' + ); + } + + $this->variables[$param] = $value; + $this->types[$param] = $type; + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) + { + if (! is_numeric($column)) { + throw new SQLSrvException('sqlsrv does not support named parameters to queries, use question mark (?) placeholders instead.'); + } + + $this->variables[$column] =& $variable; + $this->types[$column] = $type; + + // unset the statement resource if it exists as the new one will need to be bound to the new variable + $this->stmt = null; + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + // not having the result means there's nothing to close + if (! $this->result) { + return true; + } + + // emulate it by fetching and discarding rows, similarly to what PDO does in this case + // @link http://php.net/manual/en/pdostatement.closecursor.php + // @link https://github.com/php/php-src/blob/php-7.0.11/ext/pdo/pdo_stmt.c#L2075 + // deliberately do not consider multiple result sets, since doctrine/dbal doesn't support them + while (sqlsrv_fetch($this->stmt)) { + } + + $this->result = false; + + return true; + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return sqlsrv_num_fields($this->stmt); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + $errors = sqlsrv_errors(SQLSRV_ERR_ERRORS); + if ($errors) { + return $errors[0]['code']; + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return sqlsrv_errors(SQLSRV_ERR_ERRORS); + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + if ($params) { + $hasZeroIndex = array_key_exists(0, $params); + foreach ($params as $key => $val) { + $key = $hasZeroIndex && is_numeric($key) ? $key + 1 : $key; + $this->bindValue($key, $val); + } + } + + if (! $this->stmt) { + $this->stmt = $this->prepare(); + } + + if (! sqlsrv_execute($this->stmt)) { + throw SQLSrvException::fromSqlSrvErrors(); + } + + if ($this->lastInsertId) { + sqlsrv_next_result($this->stmt); + sqlsrv_fetch($this->stmt); + $this->lastInsertId->setId(sqlsrv_get_field($this->stmt, 0)); + } + + $this->result = true; + } + + /** + * Prepares SQL Server statement resource + * + * @return resource + * + * @throws SQLSrvException + */ + private function prepare() + { + $params = []; + + foreach ($this->variables as $column => &$variable) { + switch ($this->types[$column]) { + case ParameterType::LARGE_OBJECT: + $params[$column - 1] = [ + &$variable, + SQLSRV_PARAM_IN, + SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_VARBINARY('max'), + ]; + break; + + case ParameterType::BINARY: + $params[$column - 1] = [ + &$variable, + SQLSRV_PARAM_IN, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + ]; + break; + + default: + $params[$column - 1] =& $variable; + break; + } + } + + $stmt = sqlsrv_prepare($this->conn, $this->sql, $params); + + if (! $stmt) { + throw SQLSrvException::fromSqlSrvErrors(); + } + + return $stmt; + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + $this->defaultFetchMode = $fetchMode; + $this->defaultFetchClass = $arg2 ?: $this->defaultFetchClass; + $this->defaultFetchClassCtorArgs = $arg3 ? (array) $arg3 : $this->defaultFetchClassCtorArgs; + + return true; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + return new StatementIterator($this); + } + + /** + * {@inheritdoc} + * + * @throws SQLSrvException + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + // do not try fetching from the statement if it's not expected to contain result + // in order to prevent exceptional situation + if (! $this->result) { + return false; + } + + $args = func_get_args(); + $fetchMode = $fetchMode ?: $this->defaultFetchMode; + + if ($fetchMode === FetchMode::COLUMN) { + return $this->fetchColumn(); + } + + if (isset(self::$fetchMap[$fetchMode])) { + return sqlsrv_fetch_array($this->stmt, self::$fetchMap[$fetchMode]) ?: false; + } + + if (in_array($fetchMode, [FetchMode::STANDARD_OBJECT, FetchMode::CUSTOM_OBJECT], true)) { + $className = $this->defaultFetchClass; + $ctorArgs = $this->defaultFetchClassCtorArgs; + + if (count($args) >= 2) { + $className = $args[1]; + $ctorArgs = $args[2] ?? []; + } + + return sqlsrv_fetch_object($this->stmt, $className, $ctorArgs) ?: false; + } + + throw new SQLSrvException('Fetch mode is not supported!'); + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $rows = []; + + switch ($fetchMode) { + case FetchMode::CUSTOM_OBJECT: + while (($row = $this->fetch(...func_get_args())) !== false) { + $rows[] = $row; + } + break; + + case FetchMode::COLUMN: + while (($row = $this->fetchColumn()) !== false) { + $rows[] = $row; + } + break; + + default: + while (($row = $this->fetch($fetchMode)) !== false) { + $rows[] = $row; + } + } + + return $rows; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $row = $this->fetch(FetchMode::NUMERIC); + + if ($row === false) { + return false; + } + + return $row[$columnIndex] ?? null; + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + return sqlsrv_rows_affected($this->stmt); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php new file mode 100644 index 000000000..c97a60fa3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php @@ -0,0 +1,23 @@ +bindValue(), + * the variable is bound as a reference and will only be evaluated at the time + * that PDOStatement->execute() is called. + * + * As mentioned above, the named parameters are not natively supported by the mysqli driver, use executeQuery(), + * fetchAll(), fetchArray(), fetchColumn(), fetchAssoc() methods to have the named parameter emulated by doctrine. + * + * Most parameters are input parameters, that is, parameters that are + * used in a read-only fashion to build up the query. Some drivers support the invocation + * of stored procedures that return data as output parameters, and some also as input/output + * parameters that both send in data and are updated to receive it. + * + * @param mixed $column Parameter identifier. For a prepared statement using named placeholders, + * this will be a parameter name of the form :name. For a prepared statement using + * question mark placeholders, this will be the 1-indexed position of the parameter. + * @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter. + * @param int|null $type Explicit data type for the parameter using the {@link \Doctrine\DBAL\ParameterType} + * constants. To return an INOUT parameter from a stored procedure, use the bitwise + * OR operator to set the PDO::PARAM_INPUT_OUTPUT bits for the data_type parameter. + * @param int|null $length You must specify maxlength when using an OUT bind + * so that PHP allocates enough memory to hold the returned value. + * + * @return bool TRUE on success or FALSE on failure. + */ + public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null); + + /** + * Fetches the SQLSTATE associated with the last operation on the statement handle. + * + * @see Doctrine_Adapter_Interface::errorCode() + * + * @return string|int|bool The error code string. + */ + public function errorCode(); + + /** + * Fetches extended error information associated with the last operation on the statement handle. + * + * @return mixed[] The error info array. + */ + public function errorInfo(); + + /** + * Executes a prepared statement + * + * If the prepared statement included parameter markers, you must either: + * call PDOStatement->bindParam() to bind PHP variables to the parameter markers: + * bound variables pass their value as input and receive the output value, + * if any, of their associated parameter markers or pass an array of input-only + * parameter values. + * + * @param mixed[]|null $params An array of values with as many elements as there are + * bound parameters in the SQL statement being executed. + * + * @return bool TRUE on success or FALSE on failure. + */ + public function execute($params = null); + + /** + * Returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement + * executed by the corresponding object. + * + * If the last SQL statement executed by the associated Statement object was a SELECT statement, + * some databases may return the number of rows returned by that statement. However, + * this behaviour is not guaranteed for all databases and should not be + * relied on for portable applications. + * + * @return int The number of rows. + */ + public function rowCount(); +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/StatementIterator.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/StatementIterator.php new file mode 100644 index 000000000..5246b38a4 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/StatementIterator.php @@ -0,0 +1,26 @@ +statement = $statement; + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + while (($result = $this->statement->fetch()) !== false) { + yield $result; + } + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php new file mode 100644 index 000000000..658123199 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/DriverManager.php @@ -0,0 +1,435 @@ + PDOMySQLDriver::class, + 'pdo_sqlite' => PDOSQLiteDriver::class, + 'pdo_pgsql' => PDOPgSQLDriver::class, + 'pdo_oci' => PDOOCIDriver::class, + 'oci8' => OCI8Driver::class, + 'ibm_db2' => DB2Driver::class, + 'pdo_sqlsrv' => PDOSQLSrvDriver::class, + 'mysqli' => MySQLiDriver::class, + 'drizzle_pdo_mysql' => DrizzlePDOMySQLDriver::class, + 'sqlanywhere' => SQLAnywhereDriver::class, + 'sqlsrv' => SQLSrvDriver::class, + ]; + + /** + * List of URL schemes from a database URL and their mappings to driver. + * + * @var string[] + */ + private static $driverSchemeAliases = [ + 'db2' => 'ibm_db2', + 'mssql' => 'pdo_sqlsrv', + 'mysql' => 'pdo_mysql', + 'mysql2' => 'pdo_mysql', // Amazon RDS, for some weird reason + 'postgres' => 'pdo_pgsql', + 'postgresql' => 'pdo_pgsql', + 'pgsql' => 'pdo_pgsql', + 'sqlite' => 'pdo_sqlite', + 'sqlite3' => 'pdo_sqlite', + ]; + + /** + * Private constructor. This class cannot be instantiated. + */ + private function __construct() + { + } + + /** + * Creates a connection object based on the specified parameters. + * This method returns a Doctrine\DBAL\Connection which wraps the underlying + * driver connection. + * + * $params must contain at least one of the following. + * + * Either 'driver' with one of the following values: + * + * pdo_mysql + * pdo_sqlite + * pdo_pgsql + * pdo_oci (unstable) + * pdo_sqlsrv + * pdo_sqlsrv + * mysqli + * sqlanywhere + * sqlsrv + * ibm_db2 (unstable) + * drizzle_pdo_mysql + * + * OR 'driverClass' that contains the full class name (with namespace) of the + * driver class to instantiate. + * + * Other (optional) parameters: + * + * user (string): + * The username to use when connecting. + * + * password (string): + * The password to use when connecting. + * + * driverOptions (array): + * Any additional driver-specific options for the driver. These are just passed + * through to the driver. + * + * pdo: + * You can pass an existing PDO instance through this parameter. The PDO + * instance will be wrapped in a Doctrine\DBAL\Connection. + * + * wrapperClass: + * You may specify a custom wrapper class through the 'wrapperClass' + * parameter but this class MUST inherit from Doctrine\DBAL\Connection. + * + * driverClass: + * The driver class to use. + * + * @param mixed[] $params The parameters. + * @param Configuration|null $config The configuration to use. + * @param EventManager|null $eventManager The event manager to use. + * + * @throws DBALException + */ + public static function getConnection( + array $params, + ?Configuration $config = null, + ?EventManager $eventManager = null + ) : Connection { + // create default config and event manager, if not set + if (! $config) { + $config = new Configuration(); + } + if (! $eventManager) { + $eventManager = new EventManager(); + } + + $params = self::parseDatabaseUrl($params); + + // URL support for MasterSlaveConnection + if (isset($params['master'])) { + $params['master'] = self::parseDatabaseUrl($params['master']); + } + + if (isset($params['slaves'])) { + foreach ($params['slaves'] as $key => $slaveParams) { + $params['slaves'][$key] = self::parseDatabaseUrl($slaveParams); + } + } + + // URL support for PoolingShardConnection + if (isset($params['global'])) { + $params['global'] = self::parseDatabaseUrl($params['global']); + } + + if (isset($params['shards'])) { + foreach ($params['shards'] as $key => $shardParams) { + $params['shards'][$key] = self::parseDatabaseUrl($shardParams); + } + } + + // check for existing pdo object + if (isset($params['pdo']) && ! $params['pdo'] instanceof PDO) { + throw DBALException::invalidPdoInstance(); + } elseif (isset($params['pdo'])) { + $params['pdo']->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $params['driver'] = 'pdo_' . $params['pdo']->getAttribute(PDO::ATTR_DRIVER_NAME); + } else { + self::_checkParams($params); + } + + $className = $params['driverClass'] ?? self::$_driverMap[$params['driver']]; + + $driver = new $className(); + + $wrapperClass = Connection::class; + if (isset($params['wrapperClass'])) { + if (! is_subclass_of($params['wrapperClass'], $wrapperClass)) { + throw DBALException::invalidWrapperClass($params['wrapperClass']); + } + + $wrapperClass = $params['wrapperClass']; + } + + return new $wrapperClass($params, $driver, $config, $eventManager); + } + + /** + * Returns the list of supported drivers. + * + * @return string[] + */ + public static function getAvailableDrivers() : array + { + return array_keys(self::$_driverMap); + } + + /** + * Checks the list of parameters. + * + * @param mixed[] $params The list of parameters. + * + * @throws DBALException + */ + private static function _checkParams(array $params) : void + { + // check existence of mandatory parameters + + // driver + if (! isset($params['driver']) && ! isset($params['driverClass'])) { + throw DBALException::driverRequired(); + } + + // check validity of parameters + + // driver + if (isset($params['driver']) && ! isset(self::$_driverMap[$params['driver']])) { + throw DBALException::unknownDriver($params['driver'], array_keys(self::$_driverMap)); + } + + if (isset($params['driverClass']) && ! in_array(Driver::class, class_implements($params['driverClass'], true))) { + throw DBALException::invalidDriverClass($params['driverClass']); + } + } + + /** + * Normalizes the given connection URL path. + * + * @return string The normalized connection URL path + */ + private static function normalizeDatabaseUrlPath(string $urlPath) : string + { + // Trim leading slash from URL path. + return substr($urlPath, 1); + } + + /** + * Extracts parts from a database URL, if present, and returns an + * updated list of parameters. + * + * @param mixed[] $params The list of parameters. + * + * @return mixed[] A modified list of parameters with info from a database + * URL extracted into indidivual parameter parts. + * + * @throws DBALException + */ + private static function parseDatabaseUrl(array $params) : array + { + if (! isset($params['url'])) { + return $params; + } + + // (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid + $url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $params['url']); + $url = parse_url($url); + + if ($url === false) { + throw new DBALException('Malformed parameter "url".'); + } + + $url = array_map('rawurldecode', $url); + + // If we have a connection URL, we have to unset the default PDO instance connection parameter (if any) + // as we cannot merge connection details from the URL into the PDO instance (URL takes precedence). + unset($params['pdo']); + + $params = self::parseDatabaseUrlScheme($url, $params); + + if (isset($url['host'])) { + $params['host'] = $url['host']; + } + if (isset($url['port'])) { + $params['port'] = $url['port']; + } + if (isset($url['user'])) { + $params['user'] = $url['user']; + } + if (isset($url['pass'])) { + $params['password'] = $url['pass']; + } + + $params = self::parseDatabaseUrlPath($url, $params); + $params = self::parseDatabaseUrlQuery($url, $params); + + return $params; + } + + /** + * Parses the given connection URL and resolves the given connection parameters. + * + * Assumes that the connection URL scheme is already parsed and resolved into the given connection parameters + * via {@link parseDatabaseUrlScheme}. + * + * @see parseDatabaseUrlScheme + * + * @param mixed[] $url The URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + */ + private static function parseDatabaseUrlPath(array $url, array $params) : array + { + if (! isset($url['path'])) { + return $params; + } + + $url['path'] = self::normalizeDatabaseUrlPath($url['path']); + + // If we do not have a known DBAL driver, we do not know any connection URL path semantics to evaluate + // and therefore treat the path as regular DBAL connection URL path. + if (! isset($params['driver'])) { + return self::parseRegularDatabaseUrlPath($url, $params); + } + + if (strpos($params['driver'], 'sqlite') !== false) { + return self::parseSqliteDatabaseUrlPath($url, $params); + } + + return self::parseRegularDatabaseUrlPath($url, $params); + } + + /** + * Parses the query part of the given connection URL and resolves the given connection parameters. + * + * @param mixed[] $url The connection URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + */ + private static function parseDatabaseUrlQuery(array $url, array $params) : array + { + if (! isset($url['query'])) { + return $params; + } + + $query = []; + + parse_str($url['query'], $query); // simply ingest query as extra params, e.g. charset or sslmode + + return array_merge($params, $query); // parse_str wipes existing array elements + } + + /** + * Parses the given regular connection URL and resolves the given connection parameters. + * + * Assumes that the "path" URL part is already normalized via {@link normalizeDatabaseUrlPath}. + * + * @see normalizeDatabaseUrlPath + * + * @param mixed[] $url The regular connection URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + */ + private static function parseRegularDatabaseUrlPath(array $url, array $params) : array + { + $params['dbname'] = $url['path']; + + return $params; + } + + /** + * Parses the given SQLite connection URL and resolves the given connection parameters. + * + * Assumes that the "path" URL part is already normalized via {@link normalizeDatabaseUrlPath}. + * + * @see normalizeDatabaseUrlPath + * + * @param mixed[] $url The SQLite connection URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + */ + private static function parseSqliteDatabaseUrlPath(array $url, array $params) : array + { + if ($url['path'] === ':memory:') { + $params['memory'] = true; + + return $params; + } + + $params['path'] = $url['path']; // pdo_sqlite driver uses 'path' instead of 'dbname' key + + return $params; + } + + /** + * Parses the scheme part from given connection URL and resolves the given connection parameters. + * + * @param mixed[] $url The connection URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + * + * @throws DBALException If parsing failed or resolution is not possible. + */ + private static function parseDatabaseUrlScheme(array $url, array $params) : array + { + if (isset($url['scheme'])) { + // The requested driver from the URL scheme takes precedence + // over the default custom driver from the connection parameters (if any). + unset($params['driverClass']); + + // URL schemes must not contain underscores, but dashes are ok + $driver = str_replace('-', '_', $url['scheme']); + + // The requested driver from the URL scheme takes precedence over the + // default driver from the connection parameters. If the driver is + // an alias (e.g. "postgres"), map it to the actual name ("pdo-pgsql"). + // Otherwise, let checkParams decide later if the driver exists. + $params['driver'] = self::$driverSchemeAliases[$driver] ?? $driver; + + return $params; + } + + // If a schemeless connection URL is given, we require a default driver or default custom driver + // as connection parameter. + if (! isset($params['driverClass']) && ! isset($params['driver'])) { + throw DBALException::driverRequired($params['url']); + } + + return $params; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php new file mode 100644 index 000000000..bb0ca886d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/ConnectionEventArgs.php @@ -0,0 +1,55 @@ +connection = $connection; + } + + /** + * @return Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * @return Driver + */ + public function getDriver() + { + return $this->connection->getDriver(); + } + + /** + * @return AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->connection->getDatabasePlatform(); + } + + /** + * @return AbstractSchemaManager + */ + public function getSchemaManager() + { + return $this->connection->getSchemaManager(); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php new file mode 100644 index 000000000..9e7229040 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/MysqlSessionInit.php @@ -0,0 +1,58 @@ +charset = $charset; + $this->collation = $collation; + } + + /** + * @return void + */ + public function postConnect(ConnectionEventArgs $args) + { + $collation = $this->collation ? ' COLLATE ' . $this->collation : ''; + $args->getConnection()->executeUpdate('SET NAMES ' . $this->charset . $collation); + } + + /** + * {@inheritdoc} + */ + public function getSubscribedEvents() + { + return [Events::postConnect]; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php new file mode 100644 index 000000000..19f2b3fd3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/OracleSessionInit.php @@ -0,0 +1,72 @@ + 'HH24:MI:SS', + 'NLS_DATE_FORMAT' => 'YYYY-MM-DD HH24:MI:SS', + 'NLS_TIMESTAMP_FORMAT' => 'YYYY-MM-DD HH24:MI:SS', + 'NLS_TIMESTAMP_TZ_FORMAT' => 'YYYY-MM-DD HH24:MI:SS TZH:TZM', + 'NLS_NUMERIC_CHARACTERS' => '.,', + ]; + + /** + * @param string[] $oracleSessionVars + */ + public function __construct(array $oracleSessionVars = []) + { + $this->_defaultSessionVars = array_merge($this->_defaultSessionVars, $oracleSessionVars); + } + + /** + * @return void + */ + public function postConnect(ConnectionEventArgs $args) + { + if (! count($this->_defaultSessionVars)) { + return; + } + + array_change_key_case($this->_defaultSessionVars, CASE_UPPER); + $vars = []; + foreach ($this->_defaultSessionVars as $option => $value) { + if ($option === 'CURRENT_SCHEMA') { + $vars[] = $option . ' = ' . $value; + } else { + $vars[] = $option . " = '" . $value . "'"; + } + } + $sql = 'ALTER SESSION SET ' . implode(' ', $vars); + $args->getConnection()->executeUpdate($sql); + } + + /** + * {@inheritdoc} + */ + public function getSubscribedEvents() + { + return [Events::postConnect]; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php new file mode 100644 index 000000000..ea63cab43 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/Listeners/SQLSessionInit.php @@ -0,0 +1,41 @@ +sql = $sql; + } + + /** + * @return void + */ + public function postConnect(ConnectionEventArgs $args) + { + $conn = $args->getConnection(); + $conn->exec($this->sql); + } + + /** + * {@inheritdoc} + */ + public function getSubscribedEvents() + { + return [Events::postConnect]; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php new file mode 100644 index 000000000..2f9edfea6 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableAddColumnEventArgs.php @@ -0,0 +1,82 @@ +column = $column; + $this->tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** + * @return Column + */ + public function getColumn() + { + return $this->column; + } + + /** + * @return TableDiff + */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** + * @return AbstractPlatform + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string|string[] $sql + * + * @return \Doctrine\DBAL\Event\SchemaAlterTableAddColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->sql = array_merge($this->sql, $sql); + } else { + $this->sql[] = $sql; + } + + return $this; + } + + /** + * @return string[] + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php new file mode 100644 index 000000000..55661d5d3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableChangeColumnEventArgs.php @@ -0,0 +1,82 @@ +columnDiff = $columnDiff; + $this->tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** + * @return ColumnDiff + */ + public function getColumnDiff() + { + return $this->columnDiff; + } + + /** + * @return TableDiff + */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** + * @return AbstractPlatform + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string|string[] $sql + * + * @return \Doctrine\DBAL\Event\SchemaAlterTableChangeColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->sql = array_merge($this->sql, $sql); + } else { + $this->sql[] = $sql; + } + + return $this; + } + + /** + * @return string[] + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php new file mode 100644 index 000000000..8f5f0ecf5 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableEventArgs.php @@ -0,0 +1,69 @@ +tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** + * @return TableDiff + */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** + * @return AbstractPlatform + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string|string[] $sql + * + * @return \Doctrine\DBAL\Event\SchemaAlterTableEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->sql = array_merge($this->sql, $sql); + } else { + $this->sql[] = $sql; + } + + return $this; + } + + /** + * @return string[] + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php new file mode 100644 index 000000000..1bc9f5901 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRemoveColumnEventArgs.php @@ -0,0 +1,82 @@ +column = $column; + $this->tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** + * @return Column + */ + public function getColumn() + { + return $this->column; + } + + /** + * @return TableDiff + */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** + * @return AbstractPlatform + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string|string[] $sql + * + * @return \Doctrine\DBAL\Event\SchemaAlterTableRemoveColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->sql = array_merge($this->sql, $sql); + } else { + $this->sql[] = $sql; + } + + return $this; + } + + /** + * @return string[] + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php new file mode 100644 index 000000000..911ea8b4a --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaAlterTableRenameColumnEventArgs.php @@ -0,0 +1,97 @@ +oldColumnName = $oldColumnName; + $this->column = $column; + $this->tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** + * @return string + */ + public function getOldColumnName() + { + return $this->oldColumnName; + } + + /** + * @return Column + */ + public function getColumn() + { + return $this->column; + } + + /** + * @return TableDiff + */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** + * @return AbstractPlatform + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string|string[] $sql + * + * @return \Doctrine\DBAL\Event\SchemaAlterTableRenameColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->sql = array_merge($this->sql, $sql); + } else { + $this->sql[] = $sql; + } + + return $this; + } + + /** + * @return string[] + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php new file mode 100644 index 000000000..19d9f93a3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaColumnDefinitionEventArgs.php @@ -0,0 +1,106 @@ +tableColumn = $tableColumn; + $this->table = $table; + $this->database = $database; + $this->connection = $connection; + } + + /** + * Allows to clear the column which means the column will be excluded from + * tables column list. + * + * @return \Doctrine\DBAL\Event\SchemaColumnDefinitionEventArgs + */ + public function setColumn(?Column $column = null) + { + $this->column = $column; + + return $this; + } + + /** + * @return Column|null + */ + public function getColumn() + { + return $this->column; + } + + /** + * @return mixed[] + */ + public function getTableColumn() + { + return $this->tableColumn; + } + + /** + * @return string + */ + public function getTable() + { + return $this->table; + } + + /** + * @return string + */ + public function getDatabase() + { + return $this->database; + } + + /** + * @return Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * @return AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->connection->getDatabasePlatform(); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php new file mode 100644 index 000000000..9d24b8b90 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableColumnEventArgs.php @@ -0,0 +1,82 @@ +column = $column; + $this->table = $table; + $this->platform = $platform; + } + + /** + * @return Column + */ + public function getColumn() + { + return $this->column; + } + + /** + * @return Table + */ + public function getTable() + { + return $this->table; + } + + /** + * @return AbstractPlatform + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string|string[] $sql + * + * @return \Doctrine\DBAL\Event\SchemaCreateTableColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->sql = array_merge($this->sql, $sql); + } else { + $this->sql[] = $sql; + } + + return $this; + } + + /** + * @return string[] + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php new file mode 100644 index 000000000..538617cc3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaCreateTableEventArgs.php @@ -0,0 +1,98 @@ +table = $table; + $this->columns = $columns; + $this->options = $options; + $this->platform = $platform; + } + + /** + * @return Table + */ + public function getTable() + { + return $this->table; + } + + /** + * @return Column[] + */ + public function getColumns() + { + return $this->columns; + } + + /** + * @return mixed[] + */ + public function getOptions() + { + return $this->options; + } + + /** + * @return AbstractPlatform + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string|string[] $sql + * + * @return \Doctrine\DBAL\Event\SchemaCreateTableEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + $this->sql = array_merge($this->sql, $sql); + } else { + $this->sql[] = $sql; + } + + return $this; + } + + /** + * @return string[] + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php new file mode 100644 index 000000000..900b9fbfd --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaDropTableEventArgs.php @@ -0,0 +1,74 @@ +table = $table; + $this->platform = $platform; + } + + /** + * @return string|Table + */ + public function getTable() + { + return $this->table; + } + + /** + * @return AbstractPlatform + */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string $sql + * + * @return \Doctrine\DBAL\Event\SchemaDropTableEventArgs + */ + public function setSql($sql) + { + $this->sql = $sql; + + return $this; + } + + /** + * @return string|null + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaEventArgs.php new file mode 100644 index 000000000..0db0689c5 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaEventArgs.php @@ -0,0 +1,32 @@ +preventDefault = true; + + return $this; + } + + /** + * @return bool + */ + public function isDefaultPrevented() + { + return $this->preventDefault; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php new file mode 100644 index 000000000..317f352b8 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Event/SchemaIndexDefinitionEventArgs.php @@ -0,0 +1,92 @@ +tableIndex = $tableIndex; + $this->table = $table; + $this->connection = $connection; + } + + /** + * Allows to clear the index which means the index will be excluded from tables index list. + * + * @return SchemaIndexDefinitionEventArgs + */ + public function setIndex(?Index $index = null) + { + $this->index = $index; + + return $this; + } + + /** + * @return Index|null + */ + public function getIndex() + { + return $this->index; + } + + /** + * @return mixed[] + */ + public function getTableIndex() + { + return $this->tableIndex; + } + + /** + * @return string + */ + public function getTable() + { + return $this->table; + } + + /** + * @return Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * @return AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->connection->getDatabasePlatform(); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Events.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Events.php new file mode 100644 index 000000000..5398d0f84 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Events.php @@ -0,0 +1,31 @@ +driverException = $driverException; + } + + /** + * Returns the driver specific error code if given. + * + * Returns null if no error code was given by the driver. + * + * @return int|string|null + */ + public function getErrorCode() + { + return $this->driverException->getErrorCode(); + } + + /** + * Returns the SQLSTATE the driver was in at the time the error occurred, if given. + * + * Returns null if no SQLSTATE was given by the driver. + * + * @return string|null + */ + public function getSQLState() + { + return $this->driverException->getSQLState(); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Exception/ForeignKeyConstraintViolationException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Exception/ForeignKeyConstraintViolationException.php new file mode 100644 index 000000000..48d736f9e --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Exception/ForeignKeyConstraintViolationException.php @@ -0,0 +1,10 @@ +getParams(); + if ($params['driver'] === 'pdo_sqlite') { + throw new DBALException('Cannot use TableGenerator with SQLite.'); + } + $this->conn = DriverManager::getConnection($params, $conn->getConfiguration(), $conn->getEventManager()); + $this->generatorTableName = $generatorTableName; + } + + /** + * Generates the next unused value for the given sequence name. + * + * @param string $sequenceName + * + * @return int + * + * @throws DBALException + */ + public function nextValue($sequenceName) + { + if (isset($this->sequences[$sequenceName])) { + $value = $this->sequences[$sequenceName]['value']; + $this->sequences[$sequenceName]['value']++; + if ($this->sequences[$sequenceName]['value'] >= $this->sequences[$sequenceName]['max']) { + unset($this->sequences[$sequenceName]); + } + + return $value; + } + + $this->conn->beginTransaction(); + + try { + $platform = $this->conn->getDatabasePlatform(); + $sql = 'SELECT sequence_value, sequence_increment_by' + . ' FROM ' . $platform->appendLockHint($this->generatorTableName, LockMode::PESSIMISTIC_WRITE) + . ' WHERE sequence_name = ? ' . $platform->getWriteLockSQL(); + $stmt = $this->conn->executeQuery($sql, [$sequenceName]); + $row = $stmt->fetch(FetchMode::ASSOCIATIVE); + + if ($row !== false) { + $row = array_change_key_case($row, CASE_LOWER); + + $value = $row['sequence_value']; + $value++; + + if ($row['sequence_increment_by'] > 1) { + $this->sequences[$sequenceName] = [ + 'value' => $value, + 'max' => $row['sequence_value'] + $row['sequence_increment_by'], + ]; + } + + $sql = 'UPDATE ' . $this->generatorTableName . ' ' . + 'SET sequence_value = sequence_value + sequence_increment_by ' . + 'WHERE sequence_name = ? AND sequence_value = ?'; + $rows = $this->conn->executeUpdate($sql, [$sequenceName, $row['sequence_value']]); + + if ($rows !== 1) { + throw new DBALException('Race-condition detected while updating sequence. Aborting generation'); + } + } else { + $this->conn->insert( + $this->generatorTableName, + ['sequence_name' => $sequenceName, 'sequence_value' => 1, 'sequence_increment_by' => 1] + ); + $value = 1; + } + + $this->conn->commit(); + } catch (Throwable $e) { + $this->conn->rollBack(); + throw new DBALException('Error occurred while generating ID with TableGenerator, aborted generation: ' . $e->getMessage(), 0, $e); + } + + return $value; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Id/TableGeneratorSchemaVisitor.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Id/TableGeneratorSchemaVisitor.php new file mode 100644 index 000000000..3ec22f37c --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Id/TableGeneratorSchemaVisitor.php @@ -0,0 +1,71 @@ +generatorTableName = $generatorTableName; + } + + /** + * {@inheritdoc} + */ + public function acceptSchema(Schema $schema) + { + $table = $schema->createTable($this->generatorTableName); + $table->addColumn('sequence_name', 'string'); + $table->addColumn('sequence_value', 'integer', ['default' => 1]); + $table->addColumn('sequence_increment_by', 'integer', ['default' => 1]); + } + + /** + * {@inheritdoc} + */ + public function acceptTable(Table $table) + { + } + + /** + * {@inheritdoc} + */ + public function acceptColumn(Table $table, Column $column) + { + } + + /** + * {@inheritdoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + } + + /** + * {@inheritdoc} + */ + public function acceptIndex(Table $table, Index $index) + { + } + + /** + * {@inheritdoc} + */ + public function acceptSequence(Sequence $sequence) + { + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php new file mode 100644 index 000000000..14e81432b --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/LockMode.php @@ -0,0 +1,21 @@ +enabled) { + return; + } + + $this->start = microtime(true); + $this->queries[++$this->currentQuery] = ['sql' => $sql, 'params' => $params, 'types' => $types, 'executionMS' => 0]; + } + + /** + * {@inheritdoc} + */ + public function stopQuery() + { + if (! $this->enabled) { + return; + } + + $this->queries[$this->currentQuery]['executionMS'] = microtime(true) - $this->start; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php new file mode 100644 index 000000000..657abb4d3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/EchoSQLLogger.php @@ -0,0 +1,37 @@ +loggers[] = $logger; + } + + /** + * {@inheritdoc} + */ + public function startQuery($sql, ?array $params = null, ?array $types = null) + { + foreach ($this->loggers as $logger) { + $logger->startQuery($sql, $params, $types); + } + } + + /** + * {@inheritdoc} + */ + public function stopQuery() + { + foreach ($this->loggers as $logger) { + $logger->stopQuery(); + } + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php new file mode 100644 index 000000000..2e94611b6 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Logging/SQLLogger.php @@ -0,0 +1,27 @@ +_eventManager = $eventManager; + } + + /** + * Gets the EventManager used by the Platform. + * + * @return EventManager + */ + public function getEventManager() + { + return $this->_eventManager; + } + + /** + * Returns the SQL snippet that declares a boolean column. + * + * @param mixed[] $columnDef + * + * @return string + */ + abstract public function getBooleanTypeDeclarationSQL(array $columnDef); + + /** + * Returns the SQL snippet that declares a 4 byte integer column. + * + * @param mixed[] $columnDef + * + * @return string + */ + abstract public function getIntegerTypeDeclarationSQL(array $columnDef); + + /** + * Returns the SQL snippet that declares an 8 byte integer column. + * + * @param mixed[] $columnDef + * + * @return string + */ + abstract public function getBigIntTypeDeclarationSQL(array $columnDef); + + /** + * Returns the SQL snippet that declares a 2 byte integer column. + * + * @param mixed[] $columnDef + * + * @return string + */ + abstract public function getSmallIntTypeDeclarationSQL(array $columnDef); + + /** + * Returns the SQL snippet that declares common properties of an integer column. + * + * @param mixed[] $columnDef + * + * @return string + */ + abstract protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef); + + /** + * Lazy load Doctrine Type Mappings. + * + * @return void + */ + abstract protected function initializeDoctrineTypeMappings(); + + /** + * Initializes Doctrine Type Mappings with the platform defaults + * and with all additional type mappings. + * + * @return void + */ + private function initializeAllDoctrineTypeMappings() + { + $this->initializeDoctrineTypeMappings(); + + foreach (Type::getTypesMap() as $typeName => $className) { + foreach (Type::getType($typeName)->getMappedDatabaseTypes($this) as $dbType) { + $this->doctrineTypeMapping[$dbType] = $typeName; + } + } + } + + /** + * Returns the SQL snippet used to declare a VARCHAR column type. + * + * @param mixed[] $field + * + * @return string + */ + public function getVarcharTypeDeclarationSQL(array $field) + { + if (! isset($field['length'])) { + $field['length'] = $this->getVarcharDefaultLength(); + } + + $fixed = $field['fixed'] ?? false; + + $maxLength = $fixed + ? $this->getCharMaxLength() + : $this->getVarcharMaxLength(); + + if ($field['length'] > $maxLength) { + return $this->getClobTypeDeclarationSQL($field); + } + + return $this->getVarcharTypeDeclarationSQLSnippet($field['length'], $fixed); + } + + /** + * Returns the SQL snippet used to declare a BINARY/VARBINARY column type. + * + * @param mixed[] $field The column definition. + * + * @return string + */ + public function getBinaryTypeDeclarationSQL(array $field) + { + if (! isset($field['length'])) { + $field['length'] = $this->getBinaryDefaultLength(); + } + + $fixed = $field['fixed'] ?? false; + + $maxLength = $this->getBinaryMaxLength(); + + if ($field['length'] > $maxLength) { + if ($maxLength > 0) { + @trigger_error(sprintf( + 'Binary field length %d is greater than supported by the platform (%d). Reduce the field length or use a BLOB field instead.', + $field['length'], + $maxLength + ), E_USER_DEPRECATED); + } + + return $this->getBlobTypeDeclarationSQL($field); + } + + return $this->getBinaryTypeDeclarationSQLSnippet($field['length'], $fixed); + } + + /** + * Returns the SQL snippet to declare a GUID/UUID field. + * + * By default this maps directly to a CHAR(36) and only maps to more + * special datatypes when the underlying databases support this datatype. + * + * @param mixed[] $field + * + * @return string + */ + public function getGuidTypeDeclarationSQL(array $field) + { + $field['length'] = 36; + $field['fixed'] = true; + + return $this->getVarcharTypeDeclarationSQL($field); + } + + /** + * Returns the SQL snippet to declare a JSON field. + * + * By default this maps directly to a CLOB and only maps to more + * special datatypes when the underlying databases support this datatype. + * + * @param mixed[] $field + * + * @return string + */ + public function getJsonTypeDeclarationSQL(array $field) + { + return $this->getClobTypeDeclarationSQL($field); + } + + /** + * @param int $length + * @param bool $fixed + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + throw DBALException::notSupported('VARCHARs not supported by Platform.'); + } + + /** + * Returns the SQL snippet used to declare a BINARY/VARBINARY column type. + * + * @param int $length The length of the column. + * @param bool $fixed Whether the column length is fixed. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + throw DBALException::notSupported('BINARY/VARBINARY column types are not supported by this platform.'); + } + + /** + * Returns the SQL snippet used to declare a CLOB column type. + * + * @param mixed[] $field + * + * @return string + */ + abstract public function getClobTypeDeclarationSQL(array $field); + + /** + * Returns the SQL Snippet used to declare a BLOB column type. + * + * @param mixed[] $field + * + * @return string + */ + abstract public function getBlobTypeDeclarationSQL(array $field); + + /** + * Gets the name of the platform. + * + * @return string + */ + abstract public function getName(); + + /** + * Registers a doctrine type to be used in conjunction with a column type of this platform. + * + * @param string $dbType + * @param string $doctrineType + * + * @throws DBALException If the type is not found. + */ + public function registerDoctrineTypeMapping($dbType, $doctrineType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeAllDoctrineTypeMappings(); + } + + if (! Types\Type::hasType($doctrineType)) { + throw DBALException::typeNotFound($doctrineType); + } + + $dbType = strtolower($dbType); + $this->doctrineTypeMapping[$dbType] = $doctrineType; + + $doctrineType = Type::getType($doctrineType); + + if (! $doctrineType->requiresSQLCommentHint($this)) { + return; + } + + $this->markDoctrineTypeCommented($doctrineType); + } + + /** + * Gets the Doctrine type that is mapped for the given database column type. + * + * @param string $dbType + * + * @return string + * + * @throws DBALException + */ + public function getDoctrineTypeMapping($dbType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeAllDoctrineTypeMappings(); + } + + $dbType = strtolower($dbType); + + if (! isset($this->doctrineTypeMapping[$dbType])) { + throw new DBALException('Unknown database type ' . $dbType . ' requested, ' . static::class . ' may not support it.'); + } + + return $this->doctrineTypeMapping[$dbType]; + } + + /** + * Checks if a database type is currently supported by this platform. + * + * @param string $dbType + * + * @return bool + */ + public function hasDoctrineTypeMappingFor($dbType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeAllDoctrineTypeMappings(); + } + + $dbType = strtolower($dbType); + + return isset($this->doctrineTypeMapping[$dbType]); + } + + /** + * Initializes the Doctrine Type comments instance variable for in_array() checks. + * + * @return void + */ + protected function initializeCommentedDoctrineTypes() + { + $this->doctrineTypeComments = []; + + foreach (Type::getTypesMap() as $typeName => $className) { + $type = Type::getType($typeName); + + if (! $type->requiresSQLCommentHint($this)) { + continue; + } + + $this->doctrineTypeComments[] = $typeName; + } + } + + /** + * Is it necessary for the platform to add a parsable type comment to allow reverse engineering the given type? + * + * @return bool + */ + public function isCommentedDoctrineType(Type $doctrineType) + { + if ($this->doctrineTypeComments === null) { + $this->initializeCommentedDoctrineTypes(); + } + + return in_array($doctrineType->getName(), $this->doctrineTypeComments); + } + + /** + * Marks this type as to be commented in ALTER TABLE and CREATE TABLE statements. + * + * @param string|Type $doctrineType + * + * @return void + */ + public function markDoctrineTypeCommented($doctrineType) + { + if ($this->doctrineTypeComments === null) { + $this->initializeCommentedDoctrineTypes(); + } + + $this->doctrineTypeComments[] = $doctrineType instanceof Type ? $doctrineType->getName() : $doctrineType; + } + + /** + * Gets the comment to append to a column comment that helps parsing this type in reverse engineering. + * + * @return string + */ + public function getDoctrineTypeComment(Type $doctrineType) + { + return '(DC2Type:' . $doctrineType->getName() . ')'; + } + + /** + * Gets the comment of a passed column modified by potential doctrine type comment hints. + * + * @return string + */ + protected function getColumnComment(Column $column) + { + $comment = $column->getComment(); + + if ($this->isCommentedDoctrineType($column->getType())) { + $comment .= $this->getDoctrineTypeComment($column->getType()); + } + + return $comment; + } + + /** + * Gets the character used for identifier quoting. + * + * @return string + */ + public function getIdentifierQuoteCharacter() + { + return '"'; + } + + /** + * Gets the string portion that starts an SQL comment. + * + * @return string + */ + public function getSqlCommentStartString() + { + return '--'; + } + + /** + * Gets the string portion that ends an SQL comment. + * + * @return string + */ + public function getSqlCommentEndString() + { + return "\n"; + } + + /** + * Gets the maximum length of a char field. + */ + public function getCharMaxLength() : int + { + return $this->getVarcharMaxLength(); + } + + /** + * Gets the maximum length of a varchar field. + * + * @return int + */ + public function getVarcharMaxLength() + { + return 4000; + } + + /** + * Gets the default length of a varchar field. + * + * @return int + */ + public function getVarcharDefaultLength() + { + return 255; + } + + /** + * Gets the maximum length of a binary field. + * + * @return int + */ + public function getBinaryMaxLength() + { + return 4000; + } + + /** + * Gets the default length of a binary field. + * + * @return int + */ + public function getBinaryDefaultLength() + { + return 255; + } + + /** + * Gets all SQL wildcard characters of the platform. + * + * @return string[] + */ + public function getWildcards() + { + return ['%', '_']; + } + + /** + * Returns the regular expression operator. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getRegexpExpression() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the global unique identifier expression. + * + * @deprecated Use application-generated UUIDs instead + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getGuidExpression() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL snippet to get the average value of a column. + * + * @param string $column The column to use. + * + * @return string Generated SQL including an AVG aggregate function. + */ + public function getAvgExpression($column) + { + return 'AVG(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the number of rows (without a NULL value) of a column. + * + * If a '*' is used instead of a column the number of selected rows is returned. + * + * @param string|int $column The column to use. + * + * @return string Generated SQL including a COUNT aggregate function. + */ + public function getCountExpression($column) + { + return 'COUNT(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the highest value of a column. + * + * @param string $column The column to use. + * + * @return string Generated SQL including a MAX aggregate function. + */ + public function getMaxExpression($column) + { + return 'MAX(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the lowest value of a column. + * + * @param string $column The column to use. + * + * @return string Generated SQL including a MIN aggregate function. + */ + public function getMinExpression($column) + { + return 'MIN(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the total sum of a column. + * + * @param string $column The column to use. + * + * @return string Generated SQL including a SUM aggregate function. + */ + public function getSumExpression($column) + { + return 'SUM(' . $column . ')'; + } + + // scalar functions + + /** + * Returns the SQL snippet to get the md5 sum of a field. + * + * Note: Not SQL92, but common functionality. + * + * @param string $column + * + * @return string + */ + public function getMd5Expression($column) + { + return 'MD5(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the length of a text field. + * + * @param string $column + * + * @return string + */ + public function getLengthExpression($column) + { + return 'LENGTH(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the squared value of a column. + * + * @param string $column The column to use. + * + * @return string Generated SQL including an SQRT aggregate function. + */ + public function getSqrtExpression($column) + { + return 'SQRT(' . $column . ')'; + } + + /** + * Returns the SQL snippet to round a numeric field to the number of decimals specified. + * + * @param string $column + * @param int $decimals + * + * @return string + */ + public function getRoundExpression($column, $decimals = 0) + { + return 'ROUND(' . $column . ', ' . $decimals . ')'; + } + + /** + * Returns the SQL snippet to get the remainder of the division operation $expression1 / $expression2. + * + * @param string $expression1 + * @param string $expression2 + * + * @return string + */ + public function getModExpression($expression1, $expression2) + { + return 'MOD(' . $expression1 . ', ' . $expression2 . ')'; + } + + /** + * Returns the SQL snippet to trim a string. + * + * @param string $str The expression to apply the trim to. + * @param int $mode The position of the trim (leading/trailing/both). + * @param string|bool $char The char to trim, has to be quoted already. Defaults to space. + * + * @return string + */ + public function getTrimExpression($str, $mode = TrimMode::UNSPECIFIED, $char = false) + { + $expression = ''; + + switch ($mode) { + case TrimMode::LEADING: + $expression = 'LEADING '; + break; + + case TrimMode::TRAILING: + $expression = 'TRAILING '; + break; + + case TrimMode::BOTH: + $expression = 'BOTH '; + break; + } + + if ($char !== false) { + $expression .= $char . ' '; + } + + if ($mode || $char !== false) { + $expression .= 'FROM '; + } + + return 'TRIM(' . $expression . $str . ')'; + } + + /** + * Returns the SQL snippet to trim trailing space characters from the expression. + * + * @param string $str Literal string or column name. + * + * @return string + */ + public function getRtrimExpression($str) + { + return 'RTRIM(' . $str . ')'; + } + + /** + * Returns the SQL snippet to trim leading space characters from the expression. + * + * @param string $str Literal string or column name. + * + * @return string + */ + public function getLtrimExpression($str) + { + return 'LTRIM(' . $str . ')'; + } + + /** + * Returns the SQL snippet to change all characters from the expression to uppercase, + * according to the current character set mapping. + * + * @param string $str Literal string or column name. + * + * @return string + */ + public function getUpperExpression($str) + { + return 'UPPER(' . $str . ')'; + } + + /** + * Returns the SQL snippet to change all characters from the expression to lowercase, + * according to the current character set mapping. + * + * @param string $str Literal string or column name. + * + * @return string + */ + public function getLowerExpression($str) + { + return 'LOWER(' . $str . ')'; + } + + /** + * Returns the SQL snippet to get the position of the first occurrence of substring $substr in string $str. + * + * @param string $str Literal string. + * @param string $substr Literal string to find. + * @param int|bool $startPos Position to start at, beginning of string by default. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL snippet to get the current system date. + * + * @return string + */ + public function getNowExpression() + { + return 'NOW()'; + } + + /** + * Returns a SQL snippet to get a substring inside an SQL statement. + * + * Note: Not SQL92, but common functionality. + * + * SQLite only supports the 2 parameter variant of this function. + * + * @param string $value An sql string literal or column name/alias. + * @param int $from Where to start the substring portion. + * @param int|null $length The substring portion length. + * + * @return string + */ + public function getSubstringExpression($value, $from, $length = null) + { + if ($length === null) { + return 'SUBSTRING(' . $value . ' FROM ' . $from . ')'; + } + + return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $length . ')'; + } + + /** + * Returns a SQL snippet to concatenate the given expressions. + * + * Accepts an arbitrary number of string parameters. Each parameter must contain an expression. + * + * @return string + */ + public function getConcatExpression() + { + return implode(' || ', func_get_args()); + } + + /** + * Returns the SQL for a logical not. + * + * Example: + * + * $q = new Doctrine_Query(); + * $e = $q->expr; + * $q->select('*')->from('table') + * ->where($e->eq('id', $e->not('null')); + * + * + * @param string $expression + * + * @return string The logical expression. + */ + public function getNotExpression($expression) + { + return 'NOT(' . $expression . ')'; + } + + /** + * Returns the SQL that checks if an expression is null. + * + * @param string $expression The expression that should be compared to null. + * + * @return string The logical expression. + */ + public function getIsNullExpression($expression) + { + return $expression . ' IS NULL'; + } + + /** + * Returns the SQL that checks if an expression is not null. + * + * @param string $expression The expression that should be compared to null. + * + * @return string The logical expression. + */ + public function getIsNotNullExpression($expression) + { + return $expression . ' IS NOT NULL'; + } + + /** + * Returns the SQL that checks if an expression evaluates to a value between two values. + * + * The parameter $expression is checked if it is between $value1 and $value2. + * + * Note: There is a slight difference in the way BETWEEN works on some databases. + * http://www.w3schools.com/sql/sql_between.asp. If you want complete database + * independence you should avoid using between(). + * + * @param string $expression The value to compare to. + * @param string $value1 The lower value to compare with. + * @param string $value2 The higher value to compare with. + * + * @return string The logical expression. + */ + public function getBetweenExpression($expression, $value1, $value2) + { + return $expression . ' BETWEEN ' . $value1 . ' AND ' . $value2; + } + + /** + * Returns the SQL to get the arccosine of a value. + * + * @param string $value + * + * @return string + */ + public function getAcosExpression($value) + { + return 'ACOS(' . $value . ')'; + } + + /** + * Returns the SQL to get the sine of a value. + * + * @param string $value + * + * @return string + */ + public function getSinExpression($value) + { + return 'SIN(' . $value . ')'; + } + + /** + * Returns the SQL to get the PI value. + * + * @return string + */ + public function getPiExpression() + { + return 'PI()'; + } + + /** + * Returns the SQL to get the cosine of a value. + * + * @param string $value + * + * @return string + */ + public function getCosExpression($value) + { + return 'COS(' . $value . ')'; + } + + /** + * Returns the SQL to calculate the difference in days between the two passed dates. + * + * Computes diff = date1 - date2. + * + * @param string $date1 + * @param string $date2 + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateDiffExpression($date1, $date2) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL to add the number of given seconds to a date. + * + * @param string $date + * @param int $seconds + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateAddSecondsExpression($date, $seconds) + { + return $this->getDateArithmeticIntervalExpression($date, '+', $seconds, DateIntervalUnit::SECOND); + } + + /** + * Returns the SQL to subtract the number of given seconds from a date. + * + * @param string $date + * @param int $seconds + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateSubSecondsExpression($date, $seconds) + { + return $this->getDateArithmeticIntervalExpression($date, '-', $seconds, DateIntervalUnit::SECOND); + } + + /** + * Returns the SQL to add the number of given minutes to a date. + * + * @param string $date + * @param int $minutes + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateAddMinutesExpression($date, $minutes) + { + return $this->getDateArithmeticIntervalExpression($date, '+', $minutes, DateIntervalUnit::MINUTE); + } + + /** + * Returns the SQL to subtract the number of given minutes from a date. + * + * @param string $date + * @param int $minutes + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateSubMinutesExpression($date, $minutes) + { + return $this->getDateArithmeticIntervalExpression($date, '-', $minutes, DateIntervalUnit::MINUTE); + } + + /** + * Returns the SQL to add the number of given hours to a date. + * + * @param string $date + * @param int $hours + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateAddHourExpression($date, $hours) + { + return $this->getDateArithmeticIntervalExpression($date, '+', $hours, DateIntervalUnit::HOUR); + } + + /** + * Returns the SQL to subtract the number of given hours to a date. + * + * @param string $date + * @param int $hours + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateSubHourExpression($date, $hours) + { + return $this->getDateArithmeticIntervalExpression($date, '-', $hours, DateIntervalUnit::HOUR); + } + + /** + * Returns the SQL to add the number of given days to a date. + * + * @param string $date + * @param int $days + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateAddDaysExpression($date, $days) + { + return $this->getDateArithmeticIntervalExpression($date, '+', $days, DateIntervalUnit::DAY); + } + + /** + * Returns the SQL to subtract the number of given days to a date. + * + * @param string $date + * @param int $days + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateSubDaysExpression($date, $days) + { + return $this->getDateArithmeticIntervalExpression($date, '-', $days, DateIntervalUnit::DAY); + } + + /** + * Returns the SQL to add the number of given weeks to a date. + * + * @param string $date + * @param int $weeks + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateAddWeeksExpression($date, $weeks) + { + return $this->getDateArithmeticIntervalExpression($date, '+', $weeks, DateIntervalUnit::WEEK); + } + + /** + * Returns the SQL to subtract the number of given weeks from a date. + * + * @param string $date + * @param int $weeks + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateSubWeeksExpression($date, $weeks) + { + return $this->getDateArithmeticIntervalExpression($date, '-', $weeks, DateIntervalUnit::WEEK); + } + + /** + * Returns the SQL to add the number of given months to a date. + * + * @param string $date + * @param int $months + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateAddMonthExpression($date, $months) + { + return $this->getDateArithmeticIntervalExpression($date, '+', $months, DateIntervalUnit::MONTH); + } + + /** + * Returns the SQL to subtract the number of given months to a date. + * + * @param string $date + * @param int $months + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateSubMonthExpression($date, $months) + { + return $this->getDateArithmeticIntervalExpression($date, '-', $months, DateIntervalUnit::MONTH); + } + + /** + * Returns the SQL to add the number of given quarters to a date. + * + * @param string $date + * @param int $quarters + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateAddQuartersExpression($date, $quarters) + { + return $this->getDateArithmeticIntervalExpression($date, '+', $quarters, DateIntervalUnit::QUARTER); + } + + /** + * Returns the SQL to subtract the number of given quarters from a date. + * + * @param string $date + * @param int $quarters + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateSubQuartersExpression($date, $quarters) + { + return $this->getDateArithmeticIntervalExpression($date, '-', $quarters, DateIntervalUnit::QUARTER); + } + + /** + * Returns the SQL to add the number of given years to a date. + * + * @param string $date + * @param int $years + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateAddYearsExpression($date, $years) + { + return $this->getDateArithmeticIntervalExpression($date, '+', $years, DateIntervalUnit::YEAR); + } + + /** + * Returns the SQL to subtract the number of given years from a date. + * + * @param string $date + * @param int $years + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateSubYearsExpression($date, $years) + { + return $this->getDateArithmeticIntervalExpression($date, '-', $years, DateIntervalUnit::YEAR); + } + + /** + * Returns the SQL for a date arithmetic expression. + * + * @param string $date The column or literal representing a date to perform the arithmetic operation on. + * @param string $operator The arithmetic operator (+ or -). + * @param int $interval The interval that shall be calculated into the date. + * @param string $unit The unit of the interval that shall be calculated into the date. + * One of the DATE_INTERVAL_UNIT_* constants. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL bit AND comparison expression. + * + * @param string $value1 + * @param string $value2 + * + * @return string + */ + public function getBitAndComparisonExpression($value1, $value2) + { + return '(' . $value1 . ' & ' . $value2 . ')'; + } + + /** + * Returns the SQL bit OR comparison expression. + * + * @param string $value1 + * @param string $value2 + * + * @return string + */ + public function getBitOrComparisonExpression($value1, $value2) + { + return '(' . $value1 . ' | ' . $value2 . ')'; + } + + /** + * Returns the FOR UPDATE expression. + * + * @return string + */ + public function getForUpdateSQL() + { + return 'FOR UPDATE'; + } + + /** + * Honors that some SQL vendors such as MsSql use table hints for locking instead of the ANSI SQL FOR UPDATE specification. + * + * @param string $fromClause The FROM clause to append the hint for the given lock mode to. + * @param int|null $lockMode One of the Doctrine\DBAL\LockMode::* constants. If null is given, nothing will + * be appended to the FROM clause. + * + * @return string + */ + public function appendLockHint($fromClause, $lockMode) + { + return $fromClause; + } + + /** + * Returns the SQL snippet to append to any SELECT statement which locks rows in shared read lock. + * + * This defaults to the ANSI SQL "FOR UPDATE", which is an exclusive lock (Write). Some database + * vendors allow to lighten this constraint up to be a real read lock. + * + * @return string + */ + public function getReadLockSQL() + { + return $this->getForUpdateSQL(); + } + + /** + * Returns the SQL snippet to append to any SELECT statement which obtains an exclusive lock on the rows. + * + * The semantics of this lock mode should equal the SELECT .. FOR UPDATE of the ANSI SQL standard. + * + * @return string + */ + public function getWriteLockSQL() + { + return $this->getForUpdateSQL(); + } + + /** + * Returns the SQL snippet to drop an existing database. + * + * @param string $database The name of the database that should be dropped. + * + * @return string + */ + public function getDropDatabaseSQL($database) + { + return 'DROP DATABASE ' . $database; + } + + /** + * Returns the SQL snippet to drop an existing table. + * + * @param Table|string $table + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getDropTableSQL($table) + { + $tableArg = $table; + + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + + if (! is_string($table)) { + throw new InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaDropTable)) { + $eventArgs = new SchemaDropTableEventArgs($tableArg, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs); + + if ($eventArgs->isDefaultPrevented()) { + return $eventArgs->getSql(); + } + } + + return 'DROP TABLE ' . $table; + } + + /** + * Returns the SQL to safely drop a temporary table WITHOUT implicitly committing an open transaction. + * + * @param Table|string $table + * + * @return string + */ + public function getDropTemporaryTableSQL($table) + { + return $this->getDropTableSQL($table); + } + + /** + * Returns the SQL to drop an index from a table. + * + * @param Index|string $index + * @param Table|string $table + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index) { + $index = $index->getQuotedName($this); + } elseif (! is_string($index)) { + throw new InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'); + } + + return 'DROP INDEX ' . $index; + } + + /** + * Returns the SQL to drop a constraint. + * + * @param Constraint|string $constraint + * @param Table|string $table + * + * @return string + */ + public function getDropConstraintSQL($constraint, $table) + { + if (! $constraint instanceof Constraint) { + $constraint = new Identifier($constraint); + } + + if (! $table instanceof Table) { + $table = new Identifier($table); + } + + $constraint = $constraint->getQuotedName($this); + $table = $table->getQuotedName($this); + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $constraint; + } + + /** + * Returns the SQL to drop a foreign key. + * + * @param ForeignKeyConstraint|string $foreignKey + * @param Table|string $table + * + * @return string + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if (! $foreignKey instanceof ForeignKeyConstraint) { + $foreignKey = new Identifier($foreignKey); + } + + if (! $table instanceof Table) { + $table = new Identifier($table); + } + + $foreignKey = $foreignKey->getQuotedName($this); + $table = $table->getQuotedName($this); + + return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $foreignKey; + } + + /** + * Returns the SQL statement(s) to create a table with the specified name, columns and constraints + * on this platform. + * + * @param int $createFlags + * + * @return string[] The sequence of SQL statements. + * + * @throws DBALException + * @throws InvalidArgumentException + */ + public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES) + { + if (! is_int($createFlags)) { + throw new InvalidArgumentException('Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.'); + } + + if (count($table->getColumns()) === 0) { + throw DBALException::noColumnsSpecifiedForTable($table->getName()); + } + + $tableName = $table->getQuotedName($this); + $options = $table->getOptions(); + $options['uniqueConstraints'] = []; + $options['indexes'] = []; + $options['primary'] = []; + + if (($createFlags&self::CREATE_INDEXES) > 0) { + foreach ($table->getIndexes() as $index) { + /** @var $index Index */ + if ($index->isPrimary()) { + $options['primary'] = $index->getQuotedColumns($this); + $options['primary_index'] = $index; + } else { + $options['indexes'][$index->getQuotedName($this)] = $index; + } + } + } + + $columnSql = []; + $columns = []; + + foreach ($table->getColumns() as $column) { + if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn)) { + $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + if ($eventArgs->isDefaultPrevented()) { + continue; + } + } + + $columnData = $column->toArray(); + $columnData['name'] = $column->getQuotedName($this); + $columnData['version'] = $column->hasPlatformOption('version') ? $column->getPlatformOption('version') : false; + $columnData['comment'] = $this->getColumnComment($column); + + if ($columnData['type'] instanceof Types\StringType && $columnData['length'] === null) { + $columnData['length'] = 255; + } + + if (in_array($column->getName(), $options['primary'])) { + $columnData['primary'] = true; + } + + $columns[$columnData['name']] = $columnData; + } + + if (($createFlags&self::CREATE_FOREIGNKEYS) > 0) { + $options['foreignKeys'] = []; + foreach ($table->getForeignKeys() as $fkConstraint) { + $options['foreignKeys'][] = $fkConstraint; + } + } + + if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) { + $eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs); + + if ($eventArgs->isDefaultPrevented()) { + return array_merge($eventArgs->getSql(), $columnSql); + } + } + + $sql = $this->_getCreateTableSQL($tableName, $columns, $options); + if ($this->supportsCommentOnStatement()) { + foreach ($table->getColumns() as $column) { + $comment = $this->getColumnComment($column); + + if ($comment === null || $comment === '') { + continue; + } + + $sql[] = $this->getCommentOnColumnSQL($tableName, $column->getQuotedName($this), $comment); + } + } + + return array_merge($sql, $columnSql); + } + + /** + * @param string $tableName + * @param string $columnName + * @param string $comment + * + * @return string + */ + public function getCommentOnColumnSQL($tableName, $columnName, $comment) + { + $tableName = new Identifier($tableName); + $columnName = new Identifier($columnName); + $comment = $this->quoteStringLiteral($comment); + + return sprintf( + 'COMMENT ON COLUMN %s.%s IS %s', + $tableName->getQuotedName($this), + $columnName->getQuotedName($this), + $comment + ); + } + + /** + * Returns the SQL to create inline comment on a column. + * + * @param string $comment + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getInlineColumnCommentSQL($comment) + { + if (! $this->supportsInlineColumnComments()) { + throw DBALException::notSupported(__METHOD__); + } + + return 'COMMENT ' . $this->quoteStringLiteral($comment); + } + + /** + * Returns the SQL used to create a table. + * + * @param string $tableName + * @param mixed[][] $columns + * @param mixed[] $options + * + * @return string[] + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = []) + { + $columnListSql = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $name => $definition) { + $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); + } + } + + if (isset($options['primary']) && ! empty($options['primary'])) { + $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')'; + } + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index => $definition) { + $columnListSql .= ', ' . $this->getIndexDeclarationSQL($index, $definition); + } + } + + $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; + + $check = $this->getCheckDeclarationSQL($columns); + if (! empty($check)) { + $query .= ', ' . $check; + } + $query .= ')'; + + $sql[] = $query; + + if (isset($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return $sql; + } + + /** + * @return string + */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'CREATE TEMPORARY TABLE'; + } + + /** + * Returns the SQL to create a sequence on this platform. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getCreateSequenceSQL(Sequence $sequence) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL to change a sequence on this platform. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getAlterSequenceSQL(Sequence $sequence) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL to create a constraint on a table on this platform. + * + * @param Table|string $table + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getCreateConstraintSQL(Constraint $constraint, $table) + { + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + + $query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $constraint->getQuotedName($this); + + $columnList = '(' . implode(', ', $constraint->getQuotedColumns($this)) . ')'; + + $referencesClause = ''; + if ($constraint instanceof Index) { + if ($constraint->isPrimary()) { + $query .= ' PRIMARY KEY'; + } elseif ($constraint->isUnique()) { + $query .= ' UNIQUE'; + } else { + throw new InvalidArgumentException( + 'Can only create primary or unique constraints, no common indexes with getCreateConstraintSQL().' + ); + } + } elseif ($constraint instanceof ForeignKeyConstraint) { + $query .= ' FOREIGN KEY'; + + $referencesClause = ' REFERENCES ' . $constraint->getQuotedForeignTableName($this) . + ' (' . implode(', ', $constraint->getQuotedForeignColumns($this)) . ')'; + } + $query .= ' ' . $columnList . $referencesClause; + + return $query; + } + + /** + * Returns the SQL to create an index on a table on this platform. + * + * @param Table|string $table The name of the table on which the index is to be created. + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getCreateIndexSQL(Index $index, $table) + { + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + $name = $index->getQuotedName($this); + $columns = $index->getColumns(); + + if (count($columns) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + if ($index->isPrimary()) { + return $this->getCreatePrimaryKeySQL($index, $table); + } + + $query = 'CREATE ' . $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name . ' ON ' . $table; + $query .= ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')' . $this->getPartialIndexSQL($index); + + return $query; + } + + /** + * Adds condition for partial index. + * + * @return string + */ + protected function getPartialIndexSQL(Index $index) + { + if ($this->supportsPartialIndexes() && $index->hasOption('where')) { + return ' WHERE ' . $index->getOption('where'); + } + + return ''; + } + + /** + * Adds additional flags for index generation. + * + * @return string + */ + protected function getCreateIndexSQLFlags(Index $index) + { + return $index->isUnique() ? 'UNIQUE ' : ''; + } + + /** + * Returns the SQL to create an unnamed primary key constraint. + * + * @param Table|string $table + * + * @return string + */ + public function getCreatePrimaryKeySQL(Index $index, $table) + { + return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index) . ')'; + } + + /** + * Returns the SQL to create a named schema. + * + * @param string $schemaName + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getCreateSchemaSQL($schemaName) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Quotes a string so that it can be safely used as a table or column name, + * even if it is a reserved word of the platform. This also detects identifier + * chains separated by dot and quotes them independently. + * + * NOTE: Just because you CAN use quoted identifiers doesn't mean + * you SHOULD use them. In general, they end up causing way more + * problems than they solve. + * + * @param string $str The identifier name to be quoted. + * + * @return string The quoted identifier string. + */ + public function quoteIdentifier($str) + { + if (strpos($str, '.') !== false) { + $parts = array_map([$this, 'quoteSingleIdentifier'], explode('.', $str)); + + return implode('.', $parts); + } + + return $this->quoteSingleIdentifier($str); + } + + /** + * Quotes a single identifier (no dot chain separation). + * + * @param string $str The identifier name to be quoted. + * + * @return string The quoted identifier string. + */ + public function quoteSingleIdentifier($str) + { + $c = $this->getIdentifierQuoteCharacter(); + + return $c . str_replace($c, $c . $c, $str) . $c; + } + + /** + * Returns the SQL to create a new foreign key. + * + * @param ForeignKeyConstraint $foreignKey The foreign key constraint. + * @param Table|string $table The name of the table on which the foreign key is to be created. + * + * @return string + */ + public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table) + { + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' ADD ' . $this->getForeignKeyDeclarationSQL($foreignKey); + } + + /** + * Gets the SQL statements for altering an existing table. + * + * This method returns an array of SQL statements, since some platforms need several statements. + * + * @return string[] + * + * @throws DBALException If not supported on this platform. + */ + public function getAlterTableSQL(TableDiff $diff) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param mixed[] $columnSql + * + * @return bool + */ + protected function onSchemaAlterTableAddColumn(Column $column, TableDiff $diff, &$columnSql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTableAddColumn)) { + return false; + } + + $eventArgs = new SchemaAlterTableAddColumnEventArgs($column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableAddColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string[] $columnSql + * + * @return bool + */ + protected function onSchemaAlterTableRemoveColumn(Column $column, TableDiff $diff, &$columnSql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTableRemoveColumn)) { + return false; + } + + $eventArgs = new SchemaAlterTableRemoveColumnEventArgs($column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRemoveColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string[] $columnSql + * + * @return bool + */ + protected function onSchemaAlterTableChangeColumn(ColumnDiff $columnDiff, TableDiff $diff, &$columnSql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTableChangeColumn)) { + return false; + } + + $eventArgs = new SchemaAlterTableChangeColumnEventArgs($columnDiff, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableChangeColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string $oldColumnName + * @param string[] $columnSql + * + * @return bool + */ + protected function onSchemaAlterTableRenameColumn($oldColumnName, Column $column, TableDiff $diff, &$columnSql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTableRenameColumn)) { + return false; + } + + $eventArgs = new SchemaAlterTableRenameColumnEventArgs($oldColumnName, $column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRenameColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string[] $sql + * + * @return bool + */ + protected function onSchemaAlterTable(TableDiff $diff, &$sql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTable)) { + return false; + } + + $eventArgs = new SchemaAlterTableEventArgs($diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTable, $eventArgs); + + $sql = array_merge($sql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @return string[] + */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $tableName = $diff->getName($this)->getQuotedName($this); + + $sql = []; + if ($this->supportsForeignKeyConstraints()) { + foreach ($diff->removedForeignKeys as $foreignKey) { + $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName); + } + foreach ($diff->changedForeignKeys as $foreignKey) { + $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName); + } + } + + foreach ($diff->removedIndexes as $index) { + $sql[] = $this->getDropIndexSQL($index, $tableName); + } + foreach ($diff->changedIndexes as $index) { + $sql[] = $this->getDropIndexSQL($index, $tableName); + } + + return $sql; + } + + /** + * @return string[] + */ + protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $tableName = $diff->newName !== false + ? $diff->getNewName()->getQuotedName($this) + : $diff->getName($this)->getQuotedName($this); + + $sql = []; + + if ($this->supportsForeignKeyConstraints()) { + foreach ($diff->addedForeignKeys as $foreignKey) { + $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName); + } + + foreach ($diff->changedForeignKeys as $foreignKey) { + $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName); + } + } + + foreach ($diff->addedIndexes as $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableName); + } + + foreach ($diff->changedIndexes as $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableName); + } + + foreach ($diff->renamedIndexes as $oldIndexName => $index) { + $oldIndexName = new Identifier($oldIndexName); + $sql = array_merge( + $sql, + $this->getRenameIndexSQL($oldIndexName->getQuotedName($this), $index, $tableName) + ); + } + + return $sql; + } + + /** + * Returns the SQL for renaming an index on a table. + * + * @param string $oldIndexName The name of the index to rename from. + * @param Index $index The definition of the index to rename to. + * @param string $tableName The table to rename the given index on. + * + * @return string[] The sequence of SQL statements for renaming the given index. + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + return [ + $this->getDropIndexSQL($oldIndexName, $tableName), + $this->getCreateIndexSQL($index, $tableName), + ]; + } + + /** + * Common code for alter table statement generation that updates the changed Index and Foreign Key definitions. + * + * @return string[] + */ + protected function _getAlterTableIndexForeignKeySQL(TableDiff $diff) + { + return array_merge($this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPostAlterTableIndexForeignKeySQL($diff)); + } + + /** + * Gets declaration of a number of fields in bulk. + * + * @param mixed[][] $fields A multidimensional associative array. + * The first dimension determines the field name, while the second + * dimension is keyed with the name of the properties + * of the field being declared as array indexes. Currently, the types + * of supported field properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * field. If this argument is missing the field should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this field. + * + * notnull + * Boolean flag that indicates whether this field is constrained + * to not be set to null. + * charset + * Text value with the default CHARACTER SET for this field. + * collation + * Text value with the default COLLATION for this field. + * unique + * unique constraint + * + * @return string + */ + public function getColumnDeclarationListSQL(array $fields) + { + $queryFields = []; + + foreach ($fields as $fieldName => $field) { + $queryFields[] = $this->getColumnDeclarationSQL($fieldName, $field); + } + + return implode(', ', $queryFields); + } + + /** + * Obtains DBMS specific SQL code portion needed to declare a generic type + * field to be used in statements like CREATE TABLE. + * + * @param string $name The name the field to be declared. + * @param mixed[] $field An associative array with the name of the properties + * of the field being declared as array indexes. Currently, the types + * of supported field properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * field. If this argument is missing the field should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this field. + * + * notnull + * Boolean flag that indicates whether this field is constrained + * to not be set to null. + * charset + * Text value with the default CHARACTER SET for this field. + * collation + * Text value with the default COLLATION for this field. + * unique + * unique constraint + * check + * column check constraint + * columnDefinition + * a string that defines the complete column + * + * @return string DBMS specific SQL code portion that should be used to declare the column. + */ + public function getColumnDeclarationSQL($name, array $field) + { + if (isset($field['columnDefinition'])) { + $columnDef = $this->getCustomTypeDeclarationSQL($field); + } else { + $default = $this->getDefaultValueDeclarationSQL($field); + + $charset = isset($field['charset']) && $field['charset'] ? + ' ' . $this->getColumnCharsetDeclarationSQL($field['charset']) : ''; + + $collation = isset($field['collation']) && $field['collation'] ? + ' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : ''; + + $notnull = isset($field['notnull']) && $field['notnull'] ? ' NOT NULL' : ''; + + $unique = isset($field['unique']) && $field['unique'] ? + ' ' . $this->getUniqueFieldDeclarationSQL() : ''; + + $check = isset($field['check']) && $field['check'] ? + ' ' . $field['check'] : ''; + + $typeDecl = $field['type']->getSQLDeclaration($field, $this); + $columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation; + + if ($this->supportsInlineColumnComments() && isset($field['comment']) && $field['comment'] !== '') { + $columnDef .= ' ' . $this->getInlineColumnCommentSQL($field['comment']); + } + } + + return $name . ' ' . $columnDef; + } + + /** + * Returns the SQL snippet that declares a floating point column of arbitrary precision. + * + * @param mixed[] $columnDef + * + * @return string + */ + public function getDecimalTypeDeclarationSQL(array $columnDef) + { + $columnDef['precision'] = ! isset($columnDef['precision']) || empty($columnDef['precision']) + ? 10 : $columnDef['precision']; + $columnDef['scale'] = ! isset($columnDef['scale']) || empty($columnDef['scale']) + ? 0 : $columnDef['scale']; + + return 'NUMERIC(' . $columnDef['precision'] . ', ' . $columnDef['scale'] . ')'; + } + + /** + * Obtains DBMS specific SQL code portion needed to set a default value + * declaration to be used in statements like CREATE TABLE. + * + * @param mixed[] $field The field definition array. + * + * @return string DBMS specific SQL code portion needed to set a default value. + */ + public function getDefaultValueDeclarationSQL($field) + { + if (! isset($field['default'])) { + return empty($field['notnull']) ? ' DEFAULT NULL' : ''; + } + + $default = $field['default']; + + if (! isset($field['type'])) { + return " DEFAULT '" . $default . "'"; + } + + $type = $field['type']; + + if ($type instanceof Types\PhpIntegerMappingType) { + return ' DEFAULT ' . $default; + } + + if ($type instanceof Types\PhpDateTimeMappingType && $default === $this->getCurrentTimestampSQL()) { + return ' DEFAULT ' . $this->getCurrentTimestampSQL(); + } + + if ($type instanceof Types\TimeType && $default === $this->getCurrentTimeSQL()) { + return ' DEFAULT ' . $this->getCurrentTimeSQL(); + } + + if ($type instanceof Types\DateType && $default === $this->getCurrentDateSQL()) { + return ' DEFAULT ' . $this->getCurrentDateSQL(); + } + + if ($type instanceof Types\BooleanType) { + return " DEFAULT '" . $this->convertBooleans($default) . "'"; + } + + return " DEFAULT '" . $default . "'"; + } + + /** + * Obtains DBMS specific SQL code portion needed to set a CHECK constraint + * declaration to be used in statements like CREATE TABLE. + * + * @param mixed[][] $definition The check definition. + * + * @return string DBMS specific SQL code portion needed to set a CHECK constraint. + */ + public function getCheckDeclarationSQL(array $definition) + { + $constraints = []; + foreach ($definition as $field => $def) { + if (is_string($def)) { + $constraints[] = 'CHECK (' . $def . ')'; + } else { + if (isset($def['min'])) { + $constraints[] = 'CHECK (' . $field . ' >= ' . $def['min'] . ')'; + } + + if (isset($def['max'])) { + $constraints[] = 'CHECK (' . $field . ' <= ' . $def['max'] . ')'; + } + } + } + + return implode(', ', $constraints); + } + + /** + * Obtains DBMS specific SQL code portion needed to set a unique + * constraint declaration to be used in statements like CREATE TABLE. + * + * @param string $name The name of the unique constraint. + * @param Index $index The index definition. + * + * @return string DBMS specific SQL code portion needed to set a constraint. + * + * @throws InvalidArgumentException + */ + public function getUniqueConstraintDeclarationSQL($name, Index $index) + { + $columns = $index->getColumns(); + $name = new Identifier($name); + + if (count($columns) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + return 'CONSTRAINT ' . $name->getQuotedName($this) . ' UNIQUE (' + . $this->getIndexFieldDeclarationListSQL($index) + . ')' . $this->getPartialIndexSQL($index); + } + + /** + * Obtains DBMS specific SQL code portion needed to set an index + * declaration to be used in statements like CREATE TABLE. + * + * @param string $name The name of the index. + * @param Index $index The index definition. + * + * @return string DBMS specific SQL code portion needed to set an index. + * + * @throws InvalidArgumentException + */ + public function getIndexDeclarationSQL($name, Index $index) + { + $columns = $index->getColumns(); + $name = new Identifier($name); + + if (count($columns) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + return $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name->getQuotedName($this) . ' (' + . $this->getIndexFieldDeclarationListSQL($index) + . ')' . $this->getPartialIndexSQL($index); + } + + /** + * Obtains SQL code portion needed to create a custom column, + * e.g. when a field has the "columnDefinition" keyword. + * Only "AUTOINCREMENT" and "PRIMARY KEY" are added if appropriate. + * + * @param mixed[] $columnDef + * + * @return string + */ + public function getCustomTypeDeclarationSQL(array $columnDef) + { + return $columnDef['columnDefinition']; + } + + /** + * Obtains DBMS specific SQL code portion needed to set an index + * declaration to be used in statements like CREATE TABLE. + * + * @param mixed[]|Index $columnsOrIndex array declaration is deprecated, prefer passing Index to this method + */ + public function getIndexFieldDeclarationListSQL($columnsOrIndex) : string + { + if ($columnsOrIndex instanceof Index) { + return implode(', ', $columnsOrIndex->getQuotedColumns($this)); + } + + if (! is_array($columnsOrIndex)) { + throw new InvalidArgumentException('Fields argument should be an Index or array.'); + } + + $ret = []; + + foreach ($columnsOrIndex as $column => $definition) { + if (is_array($definition)) { + $ret[] = $column; + } else { + $ret[] = $definition; + } + } + + return implode(', ', $ret); + } + + /** + * Returns the required SQL string that fits between CREATE ... TABLE + * to create the table as a temporary table. + * + * Should be overridden in driver classes to return the correct string for the + * specific database type. + * + * The default is to return the string "TEMPORARY" - this will result in a + * SQL error for any database that does not support temporary tables, or that + * requires a different SQL command from "CREATE TEMPORARY TABLE". + * + * @return string The string required to be placed between "CREATE" and "TABLE" + * to generate a temporary table, if possible. + */ + public function getTemporaryTableSQL() + { + return 'TEMPORARY'; + } + + /** + * Some vendors require temporary table names to be qualified specially. + * + * @param string $tableName + * + * @return string + */ + public function getTemporaryTableName($tableName) + { + return $tableName; + } + + /** + * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a field declaration to be used in statements like CREATE TABLE. + * + * @return string DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a field declaration. + */ + public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + $sql = $this->getForeignKeyBaseDeclarationSQL($foreignKey); + $sql .= $this->getAdvancedForeignKeyOptionsSQL($foreignKey); + + return $sql; + } + + /** + * Returns the FOREIGN KEY query section dealing with non-standard options + * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... + * + * @param ForeignKeyConstraint $foreignKey The foreign key definition. + * + * @return string + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = ''; + if ($this->supportsForeignKeyOnUpdate() && $foreignKey->hasOption('onUpdate')) { + $query .= ' ON UPDATE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onUpdate')); + } + if ($foreignKey->hasOption('onDelete')) { + $query .= ' ON DELETE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete')); + } + + return $query; + } + + /** + * Returns the given referential action in uppercase if valid, otherwise throws an exception. + * + * @param string $action The foreign key referential action. + * + * @return string + * + * @throws InvalidArgumentException If unknown referential action given. + */ + public function getForeignKeyReferentialActionSQL($action) + { + $upper = strtoupper($action); + switch ($upper) { + case 'CASCADE': + case 'SET NULL': + case 'NO ACTION': + case 'RESTRICT': + case 'SET DEFAULT': + return $upper; + default: + throw new InvalidArgumentException('Invalid foreign key action: ' . $upper); + } + } + + /** + * Obtains DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a field declaration to be used in statements like CREATE TABLE. + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + $sql = ''; + if (strlen($foreignKey->getName())) { + $sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' '; + } + $sql .= 'FOREIGN KEY ('; + + if (count($foreignKey->getLocalColumns()) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'local' required."); + } + if (count($foreignKey->getForeignColumns()) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'foreign' required."); + } + if (strlen($foreignKey->getForeignTableName()) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'foreignTable' required."); + } + + return $sql . implode(', ', $foreignKey->getQuotedLocalColumns($this)) + . ') REFERENCES ' + . $foreignKey->getQuotedForeignTableName($this) . ' (' + . implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')'; + } + + /** + * Obtains DBMS specific SQL code portion needed to set the UNIQUE constraint + * of a field declaration to be used in statements like CREATE TABLE. + * + * @return string DBMS specific SQL code portion needed to set the UNIQUE constraint + * of a field declaration. + */ + public function getUniqueFieldDeclarationSQL() + { + return 'UNIQUE'; + } + + /** + * Obtains DBMS specific SQL code portion needed to set the CHARACTER SET + * of a field declaration to be used in statements like CREATE TABLE. + * + * @param string $charset The name of the charset. + * + * @return string DBMS specific SQL code portion needed to set the CHARACTER SET + * of a field declaration. + */ + public function getColumnCharsetDeclarationSQL($charset) + { + return ''; + } + + /** + * Obtains DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration to be used in statements like CREATE TABLE. + * + * @param string $collation The name of the collation. + * + * @return string DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration. + */ + public function getColumnCollationDeclarationSQL($collation) + { + return $this->supportsColumnCollation() ? 'COLLATE ' . $collation : ''; + } + + /** + * Whether the platform prefers sequences for ID generation. + * Subclasses should override this method to return TRUE if they prefer sequences. + * + * @return bool + */ + public function prefersSequences() + { + return false; + } + + /** + * Whether the platform prefers identity columns (eg. autoincrement) for ID generation. + * Subclasses should override this method to return TRUE if they prefer identity columns. + * + * @return bool + */ + public function prefersIdentityColumns() + { + return false; + } + + /** + * Some platforms need the boolean values to be converted. + * + * The default conversion in this implementation converts to integers (false => 0, true => 1). + * + * Note: if the input is not a boolean the original input might be returned. + * + * There are two contexts when converting booleans: Literals and Prepared Statements. + * This method should handle the literal case + * + * @param mixed $item A boolean or an array of them. + * + * @return mixed A boolean database value or an array of them. + */ + public function convertBooleans($item) + { + if (is_array($item)) { + foreach ($item as $k => $value) { + if (! is_bool($value)) { + continue; + } + + $item[$k] = (int) $value; + } + } elseif (is_bool($item)) { + $item = (int) $item; + } + + return $item; + } + + /** + * Some platforms have boolean literals that needs to be correctly converted + * + * The default conversion tries to convert value into bool "(bool)$item" + * + * @param mixed $item + * + * @return bool|null + */ + public function convertFromBoolean($item) + { + return $item === null ? null: (bool) $item; + } + + /** + * This method should handle the prepared statements case. When there is no + * distinction, it's OK to use the same method. + * + * Note: if the input is not a boolean the original input might be returned. + * + * @param mixed $item A boolean or an array of them. + * + * @return mixed A boolean database value or an array of them. + */ + public function convertBooleansToDatabaseValue($item) + { + return $this->convertBooleans($item); + } + + /** + * Returns the SQL specific for the platform to get the current date. + * + * @return string + */ + public function getCurrentDateSQL() + { + return 'CURRENT_DATE'; + } + + /** + * Returns the SQL specific for the platform to get the current time. + * + * @return string + */ + public function getCurrentTimeSQL() + { + return 'CURRENT_TIME'; + } + + /** + * Returns the SQL specific for the platform to get the current timestamp + * + * @return string + */ + public function getCurrentTimestampSQL() + { + return 'CURRENT_TIMESTAMP'; + } + + /** + * Returns the SQL for a given transaction isolation level Connection constant. + * + * @param int $level + * + * @return string + * + * @throws InvalidArgumentException + */ + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case TransactionIsolationLevel::READ_UNCOMMITTED: + return 'READ UNCOMMITTED'; + case TransactionIsolationLevel::READ_COMMITTED: + return 'READ COMMITTED'; + case TransactionIsolationLevel::REPEATABLE_READ: + return 'REPEATABLE READ'; + case TransactionIsolationLevel::SERIALIZABLE: + return 'SERIALIZABLE'; + default: + throw new InvalidArgumentException('Invalid isolation level:' . $level); + } + } + + /** + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListDatabasesSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL statement for retrieving the namespaces defined in the database. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListNamespacesSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param string $database + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListSequencesSQL($database) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param string $table + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListTableConstraintsSQL($table) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param string $table + * @param string|null $database + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListTableColumnsSQL($table, $database = null) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListTablesSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListUsersSQL() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL to list all views of a database or user. + * + * @param string $database + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListViewsSQL($database) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the list of indexes for the current database. + * + * The current database parameter is optional but will always be passed + * when using the SchemaManager API and is the database the given table is in. + * + * Attention: Some platforms only support currentDatabase when they + * are connected with that database. Cross-database information schema + * requests may be impossible. + * + * @param string $table + * @param string $currentDatabase + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param string $table + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getListTableForeignKeysSQL($table) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param string $name + * @param string $sql + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getCreateViewSQL($name, $sql) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param string $name + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDropViewSQL($name) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL snippet to drop an existing sequence. + * + * @param Sequence|string $sequence + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDropSequenceSQL($sequence) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param string $sequenceName + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getSequenceNextValSQL($sequenceName) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL to create a new database. + * + * @param string $database The name of the database that should be created. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getCreateDatabaseSQL($database) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Returns the SQL to set the transaction isolation level. + * + * @param int $level + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getSetTransactionIsolationSQL($level) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Obtains DBMS specific SQL to be used to create datetime fields in + * statements like CREATE TABLE. + * + * @param mixed[] $fieldDeclaration + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Obtains DBMS specific SQL to be used to create datetime with timezone offset fields. + * + * @param mixed[] $fieldDeclaration + * + * @return string + */ + public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) + { + return $this->getDateTimeTypeDeclarationSQL($fieldDeclaration); + } + + + /** + * Obtains DBMS specific SQL to be used to create date fields in statements + * like CREATE TABLE. + * + * @param mixed[] $fieldDeclaration + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Obtains DBMS specific SQL to be used to create time fields in statements + * like CREATE TABLE. + * + * @param mixed[] $fieldDeclaration + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * @param mixed[] $fieldDeclaration + * + * @return string + */ + public function getFloatDeclarationSQL(array $fieldDeclaration) + { + return 'DOUBLE PRECISION'; + } + + /** + * Gets the default transaction isolation level of the platform. + * + * @see TransactionIsolationLevel + * + * @return int The default isolation level. + */ + public function getDefaultTransactionIsolationLevel() + { + return TransactionIsolationLevel::READ_COMMITTED; + } + + /* supports*() methods */ + + /** + * Whether the platform supports sequences. + * + * @return bool + */ + public function supportsSequences() + { + return false; + } + + /** + * Whether the platform supports identity columns. + * + * Identity columns are columns that receive an auto-generated value from the + * database on insert of a row. + * + * @return bool + */ + public function supportsIdentityColumns() + { + return false; + } + + /** + * Whether the platform emulates identity columns through sequences. + * + * Some platforms that do not support identity columns natively + * but support sequences can emulate identity columns by using + * sequences. + * + * @return bool + */ + public function usesSequenceEmulatedIdentityColumns() + { + return false; + } + + /** + * Returns the name of the sequence for a particular identity column in a particular table. + * + * @see usesSequenceEmulatedIdentityColumns + * + * @param string $tableName The name of the table to return the sequence name for. + * @param string $columnName The name of the identity column in the table to return the sequence name for. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getIdentitySequenceName($tableName, $columnName) + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Whether the platform supports indexes. + * + * @return bool + */ + public function supportsIndexes() + { + return true; + } + + /** + * Whether the platform supports partial indexes. + * + * @return bool + */ + public function supportsPartialIndexes() + { + return false; + } + + /** + * Whether the platform supports indexes with column length definitions. + */ + public function supportsColumnLengthIndexes() : bool + { + return false; + } + + /** + * Whether the platform supports altering tables. + * + * @return bool + */ + public function supportsAlterTable() + { + return true; + } + + /** + * Whether the platform supports transactions. + * + * @return bool + */ + public function supportsTransactions() + { + return true; + } + + /** + * Whether the platform supports savepoints. + * + * @return bool + */ + public function supportsSavepoints() + { + return true; + } + + /** + * Whether the platform supports releasing savepoints. + * + * @return bool + */ + public function supportsReleaseSavepoints() + { + return $this->supportsSavepoints(); + } + + /** + * Whether the platform supports primary key constraints. + * + * @return bool + */ + public function supportsPrimaryConstraints() + { + return true; + } + + /** + * Whether the platform supports foreign key constraints. + * + * @return bool + */ + public function supportsForeignKeyConstraints() + { + return true; + } + + /** + * Whether this platform supports onUpdate in foreign key constraints. + * + * @return bool + */ + public function supportsForeignKeyOnUpdate() + { + return $this->supportsForeignKeyConstraints() && true; + } + + /** + * Whether the platform supports database schemas. + * + * @return bool + */ + public function supportsSchemas() + { + return false; + } + + /** + * Whether this platform can emulate schemas. + * + * Platforms that either support or emulate schemas don't automatically + * filter a schema for the namespaced elements in {@link + * AbstractManager#createSchema}. + * + * @return bool + */ + public function canEmulateSchemas() + { + return false; + } + + /** + * Returns the default schema name. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + public function getDefaultSchemaName() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Whether this platform supports create database. + * + * Some databases don't allow to create and drop databases at all or only with certain tools. + * + * @return bool + */ + public function supportsCreateDropDatabase() + { + return true; + } + + /** + * Whether the platform supports getting the affected rows of a recent update/delete type query. + * + * @return bool + */ + public function supportsGettingAffectedRows() + { + return true; + } + + /** + * Whether this platform support to add inline column comments as postfix. + * + * @return bool + */ + public function supportsInlineColumnComments() + { + return false; + } + + /** + * Whether this platform support the proprietary syntax "COMMENT ON asset". + * + * @return bool + */ + public function supportsCommentOnStatement() + { + return false; + } + + /** + * Does this platform have native guid type. + * + * @return bool + */ + public function hasNativeGuidType() + { + return false; + } + + /** + * Does this platform have native JSON type. + * + * @return bool + */ + public function hasNativeJsonType() + { + return false; + } + + /** + * @deprecated + * + * @todo Remove in 3.0 + */ + public function getIdentityColumnNullInsertSQL() + { + return ''; + } + + /** + * Whether this platform supports views. + * + * @return bool + */ + public function supportsViews() + { + return true; + } + + /** + * Does this platform support column collation? + * + * @return bool + */ + public function supportsColumnCollation() + { + return false; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored datetime value of this platform. + * + * @return string The format string. + */ + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:s'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored datetime with timezone value of this platform. + * + * @return string The format string. + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:s'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored date value of this platform. + * + * @return string The format string. + */ + public function getDateFormatString() + { + return 'Y-m-d'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored time value of this platform. + * + * @return string The format string. + */ + public function getTimeFormatString() + { + return 'H:i:s'; + } + + /** + * Adds an driver-specific LIMIT clause to the query. + * + * @param string $query + * @param int|null $limit + * @param int|null $offset + * + * @return string + * + * @throws DBALException + */ + final public function modifyLimitQuery($query, $limit, $offset = null) + { + if ($limit !== null) { + $limit = (int) $limit; + } + + $offset = (int) $offset; + + if ($offset < 0) { + throw new DBALException(sprintf( + 'Offset must be a positive integer or zero, %d given', + $offset + )); + } + + if ($offset > 0 && ! $this->supportsLimitOffset()) { + throw new DBALException(sprintf( + 'Platform %s does not support offset values in limit queries.', + $this->getName() + )); + } + + return $this->doModifyLimitQuery($query, $limit, $offset); + } + + /** + * Adds an platform-specific LIMIT clause to the query. + * + * @param string $query + * @param int|null $limit + * @param int|null $offset + * + * @return string + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + if ($limit !== null) { + $query .= ' LIMIT ' . $limit; + } + + if ($offset > 0) { + $query .= ' OFFSET ' . $offset; + } + + return $query; + } + + /** + * Whether the database platform support offsets in modify limit clauses. + * + * @return bool + */ + public function supportsLimitOffset() + { + return true; + } + + /** + * Gets the character casing of a column in an SQL result set of this platform. + * + * @param string $column The column name for which to get the correct character casing. + * + * @return string The column name in the character casing used in SQL result sets. + */ + public function getSQLResultCasing($column) + { + return $column; + } + + /** + * Makes any fixes to a name of a schema element (table, sequence, ...) that are required + * by restrictions of the platform, like a maximum length. + * + * @param string $schemaElementName + * + * @return string + */ + public function fixSchemaElementName($schemaElementName) + { + return $schemaElementName; + } + + /** + * Maximum length of any given database identifier, like tables or column names. + * + * @return int + */ + public function getMaxIdentifierLength() + { + return 63; + } + + /** + * Returns the insert SQL for an empty insert statement. + * + * @param string $tableName + * @param string $identifierColumnName + * + * @return string + */ + public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName) + { + return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (null)'; + } + + /** + * Generates a Truncate Table SQL statement for a given table. + * + * Cascade is not supported on many platforms but would optionally cascade the truncate by + * following the foreign keys. + * + * @param string $tableName + * @param bool $cascade + * + * @return string + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE ' . $tableIdentifier->getQuotedName($this); + } + + /** + * This is for test reasons, many vendors have special requirements for dummy statements. + * + * @return string + */ + public function getDummySelectSQL() + { + $expression = func_num_args() > 0 ? func_get_arg(0) : '1'; + + return sprintf('SELECT %s', $expression); + } + + /** + * Returns the SQL to create a new savepoint. + * + * @param string $savepoint + * + * @return string + */ + public function createSavePoint($savepoint) + { + return 'SAVEPOINT ' . $savepoint; + } + + /** + * Returns the SQL to release a savepoint. + * + * @param string $savepoint + * + * @return string + */ + public function releaseSavePoint($savepoint) + { + return 'RELEASE SAVEPOINT ' . $savepoint; + } + + /** + * Returns the SQL to rollback a savepoint. + * + * @param string $savepoint + * + * @return string + */ + public function rollbackSavePoint($savepoint) + { + return 'ROLLBACK TO SAVEPOINT ' . $savepoint; + } + + /** + * Returns the keyword list instance of this platform. + * + * @return KeywordList + * + * @throws DBALException If no keyword list is specified. + */ + final public function getReservedKeywordsList() + { + // Check for an existing instantiation of the keywords class. + if ($this->_keywords) { + return $this->_keywords; + } + + $class = $this->getReservedKeywordsClass(); + $keywords = new $class(); + if (! $keywords instanceof KeywordList) { + throw DBALException::notSupported(__METHOD__); + } + + // Store the instance so it doesn't need to be generated on every request. + $this->_keywords = $keywords; + + return $keywords; + } + + /** + * Returns the class name of the reserved keywords list. + * + * @return string + * + * @throws DBALException If not supported on this platform. + */ + protected function getReservedKeywordsClass() + { + throw DBALException::notSupported(__METHOD__); + } + + /** + * Quotes a literal string. + * This method is NOT meant to fix SQL injections! + * It is only meant to escape this platform's string literal + * quote character inside the given literal string. + * + * @param string $str The literal string to be quoted. + * + * @return string The quoted literal string. + */ + public function quoteStringLiteral($str) + { + $c = $this->getStringLiteralQuoteCharacter(); + + return $c . str_replace($c, $c . $c, $str) . $c; + } + + /** + * Gets the character used for string literal quoting. + * + * @return string + */ + public function getStringLiteralQuoteCharacter() + { + return "'"; + } + + /** + * Escapes metacharacters in a string intended to be used with a LIKE + * operator. + * + * @param string $inputString a literal, unquoted string + * @param string $escapeChar should be reused by the caller in the LIKE + * expression. + */ + final public function escapeStringForLike(string $inputString, string $escapeChar) : string + { + return preg_replace( + '~([' . preg_quote($this->getLikeWildcardCharacters() . $escapeChar, '~') . '])~u', + addcslashes($escapeChar, '\\') . '$1', + $inputString + ); + } + + protected function getLikeWildcardCharacters() : string + { + return '%_'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php new file mode 100644 index 000000000..605122115 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DB2Platform.php @@ -0,0 +1,896 @@ +getCharMaxLength(); + } + + return parent::getVarcharTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $field) + { + // todo blob(n) with $field['length']; + return 'BLOB(1M)'; + } + + /** + * {@inheritDoc} + */ + public function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'smallint' => 'smallint', + 'bigint' => 'bigint', + 'integer' => 'integer', + 'time' => 'time', + 'date' => 'date', + 'varchar' => 'string', + 'character' => 'string', + 'varbinary' => 'binary', + 'binary' => 'binary', + 'clob' => 'text', + 'blob' => 'blob', + 'decimal' => 'decimal', + 'double' => 'float', + 'real' => 'float', + 'timestamp' => 'datetime', + ]; + } + + /** + * {@inheritdoc} + */ + public function isCommentedDoctrineType(Type $doctrineType) + { + if ($doctrineType->getName() === Type::BOOLEAN) { + // We require a commented boolean type in order to distinguish between boolean and smallint + // as both (have to) map to the same native type. + return true; + } + + return parent::isCommentedDoctrineType($doctrineType); + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(254)') + : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** + * {@inheritdoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return $this->getVarcharTypeDeclarationSQLSnippet($length, $fixed) . ' FOR BIT DATA'; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $field) + { + // todo clob(n) with $field['length']; + return 'CLOB(1M)'; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return 'db2'; + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $columnDef) + { + return 'SMALLINT'; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $columnDef) + { + return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $columnDef) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $columnDef) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + $autoinc = ''; + if (! empty($columnDef['autoincrement'])) { + $autoinc = ' GENERATED BY DEFAULT AS IDENTITY'; + } + + return $autoinc; + } + + /** + * {@inheritdoc} + */ + public function getBitAndComparisonExpression($value1, $value2) + { + return 'BITAND(' . $value1 . ', ' . $value2 . ')'; + } + + /** + * {@inheritdoc} + */ + public function getBitOrComparisonExpression($value1, $value2) + { + return 'BITOR(' . $value1 . ', ' . $value2 . ')'; + } + + /** + * {@inheritdoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + switch ($unit) { + case DateIntervalUnit::WEEK: + $interval *= 7; + $unit = DateIntervalUnit::DAY; + break; + + case DateIntervalUnit::QUARTER: + $interval *= 3; + $unit = DateIntervalUnit::MONTH; + break; + } + + return $date . ' ' . $operator . ' ' . $interval . ' ' . $unit; + } + + /** + * {@inheritdoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return 'DAYS(' . $date1 . ') - DAYS(' . $date2 . ')'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] === true) { + return 'TIMESTAMP(0) WITH DEFAULT'; + } + + return 'TIMESTAMP(0)'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME'; + } + + /** + * {@inheritdoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE ' . $tableIdentifier->getQuotedName($this) . ' IMMEDIATE'; + } + + /** + * This code fragment is originally from the Zend_Db_Adapter_Db2 class, but has been edited. + * + * @param string $table + * @param string $database + * + * @return string + */ + public function getListTableColumnsSQL($table, $database = null) + { + $table = $this->quoteStringLiteral($table); + + // We do the funky subquery and join syscat.columns.default this crazy way because + // as of db2 v10, the column is CLOB(64k) and the distinct operator won't allow a CLOB, + // it wants shorter stuff like a varchar. + return " + SELECT + cols.default, + subq.* + FROM ( + SELECT DISTINCT + c.tabschema, + c.tabname, + c.colname, + c.colno, + c.typename, + c.nulls, + c.length, + c.scale, + c.identity, + tc.type AS tabconsttype, + c.remarks AS comment, + k.colseq, + CASE + WHEN c.generated = 'D' THEN 1 + ELSE 0 + END AS autoincrement + FROM syscat.columns c + LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc + ON (k.tabschema = tc.tabschema + AND k.tabname = tc.tabname + AND tc.type = 'P')) + ON (c.tabschema = k.tabschema + AND c.tabname = k.tabname + AND c.colname = k.colname) + WHERE UPPER(c.tabname) = UPPER(" . $table . ') + ORDER BY c.colno + ) subq + JOIN syscat.columns cols + ON subq.tabschema = cols.tabschema + AND subq.tabname = cols.tabname + AND subq.colno = cols.colno + ORDER BY subq.colno + '; + } + + /** + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return "SELECT NAME FROM SYSIBM.SYSTABLES WHERE TYPE = 'T'"; + } + + /** + * {@inheritDoc} + */ + public function getListViewsSQL($database) + { + return 'SELECT NAME, TEXT FROM SYSIBM.SYSVIEWS'; + } + + /** + * {@inheritDoc} + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + $table = $this->quoteStringLiteral($table); + + return "SELECT idx.INDNAME AS key_name, + idxcol.COLNAME AS column_name, + CASE + WHEN idx.UNIQUERULE = 'P' THEN 1 + ELSE 0 + END AS primary, + CASE + WHEN idx.UNIQUERULE = 'D' THEN 1 + ELSE 0 + END AS non_unique + FROM SYSCAT.INDEXES AS idx + JOIN SYSCAT.INDEXCOLUSE AS idxcol + ON idx.INDSCHEMA = idxcol.INDSCHEMA AND idx.INDNAME = idxcol.INDNAME + WHERE idx.TABNAME = UPPER(" . $table . ') + ORDER BY idxcol.COLSEQ ASC'; + } + + /** + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table) + { + $table = $this->quoteStringLiteral($table); + + return "SELECT fkcol.COLNAME AS local_column, + fk.REFTABNAME AS foreign_table, + pkcol.COLNAME AS foreign_column, + fk.CONSTNAME AS index_name, + CASE + WHEN fk.UPDATERULE = 'R' THEN 'RESTRICT' + ELSE NULL + END AS on_update, + CASE + WHEN fk.DELETERULE = 'C' THEN 'CASCADE' + WHEN fk.DELETERULE = 'N' THEN 'SET NULL' + WHEN fk.DELETERULE = 'R' THEN 'RESTRICT' + ELSE NULL + END AS on_delete + FROM SYSCAT.REFERENCES AS fk + JOIN SYSCAT.KEYCOLUSE AS fkcol + ON fk.CONSTNAME = fkcol.CONSTNAME + AND fk.TABSCHEMA = fkcol.TABSCHEMA + AND fk.TABNAME = fkcol.TABNAME + JOIN SYSCAT.KEYCOLUSE AS pkcol + ON fk.REFKEYNAME = pkcol.CONSTNAME + AND fk.REFTABSCHEMA = pkcol.TABSCHEMA + AND fk.REFTABNAME = pkcol.TABNAME + WHERE fk.TABNAME = UPPER(" . $table . ') + ORDER BY fkcol.COLSEQ ASC'; + } + + /** + * {@inheritDoc} + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * {@inheritDoc} + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * {@inheritDoc} + */ + public function getCreateDatabaseSQL($database) + { + return 'CREATE DATABASE ' . $database; + } + + /** + * {@inheritDoc} + */ + public function getDropDatabaseSQL($database) + { + return 'DROP DATABASE ' . $database; + } + + /** + * {@inheritDoc} + */ + public function supportsCreateDropDatabase() + { + return false; + } + + /** + * {@inheritDoc} + */ + public function supportsReleaseSavepoints() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function supportsCommentOnStatement() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getCurrentDateSQL() + { + return 'CURRENT DATE'; + } + + /** + * {@inheritDoc} + */ + public function getCurrentTimeSQL() + { + return 'CURRENT TIME'; + } + + /** + * {@inheritDoc} + */ + public function getCurrentTimestampSQL() + { + return 'CURRENT TIMESTAMP'; + } + + /** + * {@inheritDoc} + */ + public function getIndexDeclarationSQL($name, Index $index) + { + // Index declaration in statements like CREATE TABLE is not supported. + throw DBALException::notSupported(__METHOD__); + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = []) + { + $indexes = []; + if (isset($options['indexes'])) { + $indexes = $options['indexes']; + } + $options['indexes'] = []; + + $sqls = parent::_getCreateTableSQL($tableName, $columns, $options); + + foreach ($indexes as $definition) { + $sqls[] = $this->getCreateIndexSQL($definition, $tableName); + } + return $sqls; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = []; + $columnSql = []; + $commentsSQL = []; + + $queryParts = []; + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columnDef = $column->toArray(); + $queryPart = 'ADD COLUMN ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef); + + // Adding non-nullable columns to a table requires a default value to be specified. + if (! empty($columnDef['notnull']) && + ! isset($columnDef['default']) && + empty($columnDef['autoincrement']) + ) { + $queryPart .= ' WITH DEFAULT'; + } + + $queryParts[] = $queryPart; + + $comment = $this->getColumnComment($column); + + if ($comment === null || $comment === '') { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $diff->getName($this)->getQuotedName($this), + $column->getQuotedName($this), + $comment + ); + } + + foreach ($diff->removedColumns as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this); + } + + foreach ($diff->changedColumns as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + if ($columnDiff->hasChanged('comment')) { + $commentsSQL[] = $this->getCommentOnColumnSQL( + $diff->getName($this)->getQuotedName($this), + $columnDiff->column->getQuotedName($this), + $this->getColumnComment($columnDiff->column) + ); + + if (count($columnDiff->changedProperties) === 1) { + continue; + } + } + + $this->gatherAlterColumnSQL($diff->fromTable, $columnDiff, $sql, $queryParts); + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $queryParts[] = 'RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . + ' TO ' . $column->getQuotedName($this); + } + + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + if (count($queryParts) > 0) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(' ', $queryParts); + } + + // Some table alteration operations require a table reorganization. + if (! empty($diff->removedColumns) || ! empty($diff->changedColumns)) { + $sql[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE " . $diff->getName($this)->getQuotedName($this) . "')"; + } + + $sql = array_merge($sql, $commentsSQL); + + if ($diff->newName !== false) { + $sql[] = 'RENAME TABLE ' . $diff->getName($this)->getQuotedName($this) . ' TO ' . $diff->getNewName()->getQuotedName($this); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff) + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Gathers the table alteration SQL for a given column diff. + * + * @param Table $table The table to gather the SQL for. + * @param ColumnDiff $columnDiff The column diff to evaluate. + * @param string[] $sql The sequence of table alteration statements to fill. + * @param mixed[] $queryParts The sequence of column alteration clauses to fill. + */ + private function gatherAlterColumnSQL(Table $table, ColumnDiff $columnDiff, array &$sql, array &$queryParts) + { + $alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff); + + if (empty($alterColumnClauses)) { + return; + } + + // If we have a single column alteration, we can append the clause to the main query. + if (count($alterColumnClauses) === 1) { + $queryParts[] = current($alterColumnClauses); + + return; + } + + // We have multiple alterations for the same column, + // so we need to trigger a complete ALTER TABLE statement + // for each ALTER COLUMN clause. + foreach ($alterColumnClauses as $alterColumnClause) { + $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ' . $alterColumnClause; + } + } + + /** + * Returns the ALTER COLUMN SQL clauses for altering a column described by the given column diff. + * + * @param ColumnDiff $columnDiff The column diff to evaluate. + * + * @return string[] + */ + private function getAlterColumnClausesSQL(ColumnDiff $columnDiff) + { + $column = $columnDiff->column->toArray(); + + $alterClause = 'ALTER COLUMN ' . $columnDiff->column->getQuotedName($this); + + if ($column['columnDefinition']) { + return [$alterClause . ' ' . $column['columnDefinition']]; + } + + $clauses = []; + + if ($columnDiff->hasChanged('type') || + $columnDiff->hasChanged('length') || + $columnDiff->hasChanged('precision') || + $columnDiff->hasChanged('scale') || + $columnDiff->hasChanged('fixed') + ) { + $clauses[] = $alterClause . ' SET DATA TYPE ' . $column['type']->getSQLDeclaration($column, $this); + } + + if ($columnDiff->hasChanged('notnull')) { + $clauses[] = $column['notnull'] ? $alterClause . ' SET NOT NULL' : $alterClause . ' DROP NOT NULL'; + } + + if ($columnDiff->hasChanged('default')) { + if (isset($column['default'])) { + $defaultClause = $this->getDefaultValueDeclarationSQL($column); + + if ($defaultClause) { + $clauses[] = $alterClause . ' SET' . $defaultClause; + } + } else { + $clauses[] = $alterClause . ' DROP DEFAULT'; + } + } + + return $clauses; + } + + /** + * {@inheritDoc} + */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + $table = $diff->getName($this)->getQuotedName($this); + + foreach ($diff->removedIndexes as $remKey => $remIndex) { + foreach ($diff->addedIndexes as $addKey => $addIndex) { + if ($remIndex->getColumns() === $addIndex->getColumns()) { + if ($remIndex->isPrimary()) { + $sql[] = 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY'; + } elseif ($remIndex->isUnique()) { + $sql[] = 'ALTER TABLE ' . $table . ' DROP UNIQUE ' . $remIndex->getQuotedName($this); + } else { + $sql[] = $this->getDropIndexSQL($remIndex, $table); + } + + $sql[] = $this->getCreateIndexSQL($addIndex, $table); + + unset($diff->removedIndexes[$remKey], $diff->addedIndexes[$addKey]); + + break; + } + } + } + + $sql = array_merge($sql, parent::getPreAlterTableIndexForeignKeySQL($diff)); + + return $sql; + } + + /** + * {@inheritdoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + if (strpos($tableName, '.') !== false) { + [$schema] = explode('.', $tableName); + $oldIndexName = $schema . '.' . $oldIndexName; + } + + return ['RENAME INDEX ' . $oldIndexName . ' TO ' . $index->getQuotedName($this)]; + } + + /** + * {@inheritDoc} + */ + public function getDefaultValueDeclarationSQL($field) + { + if (! empty($field['autoincrement'])) { + return ''; + } + + if (isset($field['version']) && $field['version']) { + if ((string) $field['type'] !== 'DateTime') { + $field['default'] = '1'; + } + } + + return parent::getDefaultValueDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getEmptyIdentityInsertSQL($tableName, $identifierColumnName) + { + return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (DEFAULT)'; + } + + /** + * {@inheritDoc} + */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'DECLARE GLOBAL TEMPORARY TABLE'; + } + + /** + * {@inheritDoc} + */ + public function getTemporaryTableName($tableName) + { + return 'SESSION.' . $tableName; + } + + /** + * {@inheritDoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset = null) + { + $where = []; + + if ($offset > 0) { + $where[] = sprintf('db22.DC_ROWNUM >= %d', $offset + 1); + } + + if ($limit !== null) { + $where[] = sprintf('db22.DC_ROWNUM <= %d', $offset + $limit); + } + + if (empty($where)) { + return $query; + } + + // Todo OVER() needs ORDER BY data! + return sprintf( + 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (%s) db21) db22 WHERE %s', + $query, + implode(' AND ', $where) + ); + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos === false) { + return 'LOCATE(' . $substr . ', ' . $str . ')'; + } + + return 'LOCATE(' . $substr . ', ' . $str . ', ' . $startPos . ')'; + } + + /** + * {@inheritDoc} + */ + public function getSubstringExpression($value, $from, $length = null) + { + if ($length === null) { + return 'SUBSTR(' . $value . ', ' . $from . ')'; + } + + return 'SUBSTR(' . $value . ', ' . $from . ', ' . $length . ')'; + } + + /** + * {@inheritDoc} + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + * + * DB2 returns all column names in SQL result sets in uppercase. + */ + public function getSQLResultCasing($column) + { + return strtoupper($column); + } + + /** + * {@inheritDoc} + */ + public function getForUpdateSQL() + { + return ' WITH RR USE AND KEEP UPDATE LOCKS'; + } + + /** + * {@inheritDoc} + */ + public function getDummySelectSQL() + { + $expression = func_num_args() > 0 ? func_get_arg(0) : '1'; + + return sprintf('SELECT %s FROM sysibm.sysdummy1', $expression); + } + + /** + * {@inheritDoc} + * + * DB2 supports savepoints, but they work semantically different than on other vendor platforms. + * + * TODO: We have to investigate how to get DB2 up and running with savepoints. + */ + public function supportsSavepoints() + { + return false; + } + + /** + * {@inheritDoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\DB2Keywords::class; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DateIntervalUnit.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DateIntervalUnit.php new file mode 100644 index 000000000..ec97d0ef3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/DateIntervalUnit.php @@ -0,0 +1,28 @@ +_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + $autoinc = ''; + if (! empty($columnDef['autoincrement'])) { + $autoinc = ' AUTO_INCREMENT'; + } + + return $autoinc; + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'; + } + + /** + * {@inheritdoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return 'VARBINARY(' . ($length ?: 255) . ')'; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'boolean' => 'boolean', + 'varchar' => 'string', + 'varbinary' => 'binary', + 'integer' => 'integer', + 'blob' => 'blob', + 'decimal' => 'decimal', + 'datetime' => 'datetime', + 'date' => 'date', + 'time' => 'time', + 'text' => 'text', + 'timestamp' => 'datetime', + 'double' => 'float', + 'bigint' => 'bigint', + ]; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'TEXT'; + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'BLOB'; + } + + /** + * {@inheritDoc} + */ + public function getCreateDatabaseSQL($name) + { + return 'CREATE DATABASE ' . $name; + } + + /** + * {@inheritDoc} + */ + public function getDropDatabaseSQL($name) + { + return 'DROP DATABASE ' . $name; + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = []) + { + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $index => $definition) { + $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition); + } + } + + // add all indexes + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index => $definition) { + $queryFields .= ', ' . $this->getIndexDeclarationSQL($index, $definition); + } + } + + // attach all primary keys + if (isset($options['primary']) && ! empty($options['primary'])) { + $keyColumns = array_unique(array_values($options['primary'])); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + $query = 'CREATE '; + + if (! empty($options['temporary'])) { + $query .= 'TEMPORARY '; + } + + $query .= 'TABLE ' . $tableName . ' (' . $queryFields . ') '; + $query .= $this->buildTableOptions($options); + $query .= $this->buildPartitionOptions($options); + + $sql = [$query]; + + if (isset($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return $sql; + } + + /** + * Build SQL for table options + * + * @param mixed[] $options + * + * @return string + */ + private function buildTableOptions(array $options) + { + if (isset($options['table_options'])) { + return $options['table_options']; + } + + $tableOptions = []; + + // Collate + if (! isset($options['collate'])) { + $options['collate'] = 'utf8_unicode_ci'; + } + + $tableOptions[] = sprintf('COLLATE %s', $options['collate']); + + // Engine + if (! isset($options['engine'])) { + $options['engine'] = 'InnoDB'; + } + + $tableOptions[] = sprintf('ENGINE = %s', $options['engine']); + + // Auto increment + if (isset($options['auto_increment'])) { + $tableOptions[] = sprintf('AUTO_INCREMENT = %s', $options['auto_increment']); + } + + // Comment + if (isset($options['comment'])) { + $comment = trim($options['comment'], " '"); + + $tableOptions[] = sprintf('COMMENT = %s ', $this->quoteStringLiteral($comment)); + } + + // Row format + if (isset($options['row_format'])) { + $tableOptions[] = sprintf('ROW_FORMAT = %s', $options['row_format']); + } + + return implode(' ', $tableOptions); + } + + /** + * Build SQL for partition options. + * + * @param mixed[] $options + * + * @return string + */ + private function buildPartitionOptions(array $options) + { + return isset($options['partition_options']) + ? ' ' . $options['partition_options'] + : ''; + } + + /** + * {@inheritDoc} + */ + public function getListDatabasesSQL() + { + return "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE CATALOG_NAME='LOCAL'"; + } + + /** + * {@inheritDoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\DrizzleKeywords::class; + } + + /** + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE' AND TABLE_SCHEMA=DATABASE()"; + } + + /** + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + if ($database) { + $databaseSQL = $this->quoteStringLiteral($database); + } else { + $databaseSQL = 'DATABASE()'; + } + + return 'SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT, IS_NULLABLE, IS_AUTO_INCREMENT, CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT,' . + ' NUMERIC_PRECISION, NUMERIC_SCALE, COLLATION_NAME' . + ' FROM DATA_DICTIONARY.COLUMNS' . + ' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME = ' . $this->quoteStringLiteral($table); + } + + /** + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + if ($database) { + $databaseSQL = $this->quoteStringLiteral($database); + } else { + $databaseSQL = 'DATABASE()'; + } + + return 'SELECT CONSTRAINT_NAME, CONSTRAINT_COLUMNS, REFERENCED_TABLE_NAME, REFERENCED_TABLE_COLUMNS, UPDATE_RULE, DELETE_RULE' . + ' FROM DATA_DICTIONARY.FOREIGN_KEYS' . + ' WHERE CONSTRAINT_SCHEMA=' . $databaseSQL . ' AND CONSTRAINT_TABLE=' . $this->quoteStringLiteral($table); + } + + /** + * {@inheritDoc} + */ + public function getListTableIndexesSQL($table, $database = null) + { + if ($database) { + $databaseSQL = $this->quoteStringLiteral($database); + } else { + $databaseSQL = 'DATABASE()'; + } + + return "SELECT INDEX_NAME AS 'key_name', COLUMN_NAME AS 'column_name', IS_USED_IN_PRIMARY AS 'primary', IS_UNIQUE=0 AS 'non_unique'" . + ' FROM DATA_DICTIONARY.INDEX_PARTS' . + ' WHERE TABLE_SCHEMA=' . $databaseSQL . ' AND TABLE_NAME=' . $this->quoteStringLiteral($table); + } + + /** + * {@inheritDoc} + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsInlineColumnComments() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsViews() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function supportsColumnCollation() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index) { + $indexName = $index->getQuotedName($this); + } elseif (is_string($index)) { + $indexName = $index; + } else { + throw new InvalidArgumentException('DrizzlePlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'); + } + + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } elseif (! is_string($table)) { + throw new InvalidArgumentException('DrizzlePlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + if ($index instanceof Index && $index->isPrimary()) { + // drizzle primary keys are always named "PRIMARY", + // so we cannot use them in statements because of them being keyword. + return $this->getDropPrimaryKeySQL($table); + } + + return 'DROP INDEX ' . $indexName . ' ON ' . $table; + } + + /** + * {@inheritDoc} + */ + protected function getDropPrimaryKeySQL($table) + { + return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] === true) { + return 'TIMESTAMP'; + } + + return 'DATETIME'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $columnSql = []; + $queryParts = []; + + if ($diff->newName !== false) { + $queryParts[] = 'RENAME TO ' . $diff->getNewName()->getQuotedName($this); + } + + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columnArray = $column->toArray(); + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + foreach ($diff->removedColumns as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP ' . $column->getQuotedName($this); + } + + foreach ($diff->changedColumns as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $column = $columnDiff->column; + $columnArray = $column->toArray(); + + // Do not generate column alteration clause if type is binary and only fixed property has changed. + // Drizzle only supports binary type columns with variable length. + // Avoids unnecessary table alteration statements. + if ($columnArray['type'] instanceof BinaryType && + $columnDiff->hasChanged('fixed') && + count($columnDiff->changedProperties) === 1 + ) { + continue; + } + + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'CHANGE ' . ($columnDiff->getOldColumnName()->getQuotedName($this)) . ' ' + . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $columnArray = $column->toArray(); + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'CHANGE ' . $oldColumnName->getQuotedName($this) . ' ' + . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + $sql = []; + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + if (count($queryParts) > 0) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(', ', $queryParts); + } + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff) + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * {@inheritDoc} + */ + public function getDropTemporaryTableSQL($table) + { + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } elseif (! is_string($table)) { + throw new InvalidArgumentException('getDropTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + return 'DROP TEMPORARY TABLE ' . $table; + } + + /** + * {@inheritDoc} + */ + public function convertBooleans($item) + { + if (is_array($item)) { + foreach ($item as $key => $value) { + if (! is_bool($value) && ! is_numeric($item)) { + continue; + } + + $item[$key] = $value ? 'true' : 'false'; + } + } elseif (is_bool($item) || is_numeric($item)) { + $item = $item ? 'true' : 'false'; + } + + return $item; + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos === false) { + return 'LOCATE(' . $substr . ', ' . $str . ')'; + } + + return 'LOCATE(' . $substr . ', ' . $str . ', ' . $startPos . ')'; + } + + /** + * {@inheritDoc} + * + * @deprecated Use application-generated UUIDs instead + */ + public function getGuidExpression() + { + return 'UUID()'; + } + + /** + * {@inheritDoc} + */ + public function getRegexpExpression() + { + return 'RLIKE'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php new file mode 100644 index 000000000..8533f579d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/DB2Keywords.php @@ -0,0 +1,420 @@ +keywords === null) { + $this->initializeKeywords(); + } + + return isset($this->keywords[strtoupper($word)]); + } + + /** + * @return void + */ + protected function initializeKeywords() + { + $this->keywords = array_flip(array_map('strtoupper', $this->getKeywords())); + } + + /** + * Returns the list of keywords. + * + * @return string[] + */ + abstract protected function getKeywords(); + + /** + * Returns the name of this keyword list. + * + * @return string + */ + abstract public function getName(); +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MariaDb102Keywords.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MariaDb102Keywords.php new file mode 100644 index 000000000..1b31c7682 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MariaDb102Keywords.php @@ -0,0 +1,274 @@ +keywordLists = $keywordLists; + } + + /** + * @return string[] + */ + public function getViolations() + { + return $this->violations; + } + + /** + * @param string $word + * + * @return string[] + */ + private function isReservedWord($word) + { + if ($word[0] === '`') { + $word = str_replace('`', '', $word); + } + + $keywordLists = []; + foreach ($this->keywordLists as $keywordList) { + if (! $keywordList->isKeyword($word)) { + continue; + } + + $keywordLists[] = $keywordList->getName(); + } + + return $keywordLists; + } + + /** + * @param string $asset + * @param string[] $violatedPlatforms + * + * @return void + */ + private function addViolation($asset, $violatedPlatforms) + { + if (! $violatedPlatforms) { + return; + } + + $this->violations[] = $asset . ' keyword violations: ' . implode(', ', $violatedPlatforms); + } + + /** + * {@inheritdoc} + */ + public function acceptColumn(Table $table, Column $column) + { + $this->addViolation( + 'Table ' . $table->getName() . ' column ' . $column->getName(), + $this->isReservedWord($column->getName()) + ); + } + + /** + * {@inheritdoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + } + + /** + * {@inheritdoc} + */ + public function acceptIndex(Table $table, Index $index) + { + } + + /** + * {@inheritdoc} + */ + public function acceptSchema(Schema $schema) + { + } + + /** + * {@inheritdoc} + */ + public function acceptSequence(Sequence $sequence) + { + } + + /** + * {@inheritdoc} + */ + public function acceptTable(Table $table) + { + $this->addViolation( + 'Table ' . $table->getName(), + $this->isReservedWord($table->getName()) + ); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLAnywhere11Keywords.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLAnywhere11Keywords.php new file mode 100644 index 000000000..09513c577 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/SQLAnywhere11Keywords.php @@ -0,0 +1,39 @@ +doctrineTypeMapping['json'] = Type::JSON; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php new file mode 100644 index 000000000..71ef6ca96 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL57Platform.php @@ -0,0 +1,71 @@ +getQuotedName($this)]; + } + + /** + * {@inheritdoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\MySQL57Keywords::class; + } + + /** + * {@inheritdoc} + */ + protected function initializeDoctrineTypeMappings() + { + parent::initializeDoctrineTypeMappings(); + + $this->doctrineTypeMapping['json'] = Type::JSON; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL80Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL80Platform.php new file mode 100644 index 000000000..f6d4be9dc --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySQL80Platform.php @@ -0,0 +1,17 @@ + 0) { + $query .= ' OFFSET ' . $offset; + } + } elseif ($offset > 0) { + // 2^64-1 is the maximum of unsigned BIGINT, the biggest limit possible + $query .= ' LIMIT 18446744073709551615 OFFSET ' . $offset; + } + + return $query; + } + + /** + * {@inheritDoc} + */ + public function getIdentifierQuoteCharacter() + { + return '`'; + } + + /** + * {@inheritDoc} + */ + public function getRegexpExpression() + { + return 'RLIKE'; + } + + /** + * {@inheritDoc} + * + * @deprecated Use application-generated UUIDs instead + */ + public function getGuidExpression() + { + return 'UUID()'; + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos === false) { + return 'LOCATE(' . $substr . ', ' . $str . ')'; + } + + return 'LOCATE(' . $substr . ', ' . $str . ', ' . $startPos . ')'; + } + + /** + * {@inheritDoc} + */ + public function getConcatExpression() + { + return sprintf('CONCAT(%s)', implode(', ', func_get_args())); + } + + /** + * {@inheritdoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + $function = $operator === '+' ? 'DATE_ADD' : 'DATE_SUB'; + + return $function . '(' . $date . ', INTERVAL ' . $interval . ' ' . $unit . ')'; + } + + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return 'DATEDIFF(' . $date1 . ', ' . $date2 . ')'; + } + + /** + * {@inheritDoc} + */ + public function getListDatabasesSQL() + { + return 'SHOW DATABASES'; + } + + /** + * {@inheritDoc} + */ + public function getListTableConstraintsSQL($table) + { + return 'SHOW INDEX FROM ' . $table; + } + + /** + * {@inheritDoc} + * + * Two approaches to listing the table indexes. The information_schema is + * preferred, because it doesn't cause problems with SQL keywords such as "order" or "table". + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + if ($currentDatabase) { + $currentDatabase = $this->quoteStringLiteral($currentDatabase); + $table = $this->quoteStringLiteral($table); + + return 'SELECT TABLE_NAME AS `Table`, NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, ' . + 'SEQ_IN_INDEX AS Seq_in_index, COLUMN_NAME AS Column_Name, COLLATION AS Collation, ' . + 'CARDINALITY AS Cardinality, SUB_PART AS Sub_Part, PACKED AS Packed, ' . + 'NULLABLE AS `Null`, INDEX_TYPE AS Index_Type, COMMENT AS Comment ' . + 'FROM information_schema.STATISTICS WHERE TABLE_NAME = ' . $table . ' AND TABLE_SCHEMA = ' . $currentDatabase . + ' ORDER BY SEQ_IN_INDEX ASC'; + } + + return 'SHOW INDEX FROM ' . $table; + } + + /** + * {@inheritDoc} + */ + public function getListViewsSQL($database) + { + $database = $this->quoteStringLiteral($database); + + return 'SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = ' . $database; + } + + /** + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + $table = $this->quoteStringLiteral($table); + + if ($database !== null) { + $database = $this->quoteStringLiteral($database); + } + + $sql = 'SELECT DISTINCT k.`CONSTRAINT_NAME`, k.`COLUMN_NAME`, k.`REFERENCED_TABLE_NAME`, ' . + 'k.`REFERENCED_COLUMN_NAME` /*!50116 , c.update_rule, c.delete_rule */ ' . + 'FROM information_schema.key_column_usage k /*!50116 ' . + 'INNER JOIN information_schema.referential_constraints c ON ' . + ' c.constraint_name = k.constraint_name AND ' . + ' c.table_name = ' . $table . ' */ WHERE k.table_name = ' . $table; + + $databaseNameSql = $database ?? 'DATABASE()'; + + $sql .= ' AND k.table_schema = ' . $databaseNameSql . ' /*!50116 AND c.constraint_schema = ' . $databaseNameSql . ' */'; + $sql .= ' AND k.`REFERENCED_COLUMN_NAME` is not NULL'; + + return $sql; + } + + /** + * {@inheritDoc} + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * {@inheritDoc} + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** + * {@inheritdoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? 'BINARY(' . ($length ?: 255) . ')' : 'VARBINARY(' . ($length ?: 255) . ')'; + } + + /** + * Gets the SQL snippet used to declare a CLOB column type. + * TINYTEXT : 2 ^ 8 - 1 = 255 + * TEXT : 2 ^ 16 - 1 = 65535 + * MEDIUMTEXT : 2 ^ 24 - 1 = 16777215 + * LONGTEXT : 2 ^ 32 - 1 = 4294967295 + * + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $field) + { + if (! empty($field['length']) && is_numeric($field['length'])) { + $length = $field['length']; + + if ($length <= static::LENGTH_LIMIT_TINYTEXT) { + return 'TINYTEXT'; + } + + if ($length <= static::LENGTH_LIMIT_TEXT) { + return 'TEXT'; + } + + if ($length <= static::LENGTH_LIMIT_MEDIUMTEXT) { + return 'MEDIUMTEXT'; + } + } + + return 'LONGTEXT'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + if (isset($fieldDeclaration['version']) && $fieldDeclaration['version'] === true) { + return 'TIMESTAMP'; + } + + return 'DATETIME'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME'; + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'TINYINT(1)'; + } + + /** + * Obtain DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration to be used in statements like CREATE TABLE. + * + * @deprecated Deprecated since version 2.5, Use {@link self::getColumnCollationDeclarationSQL()} instead. + * + * @param string $collation name of the collation + * + * @return string DBMS specific SQL code portion needed to set the COLLATION + * of a field declaration. + */ + public function getCollationFieldDeclaration($collation) + { + return $this->getColumnCollationDeclarationSQL($collation); + } + + /** + * {@inheritDoc} + * + * MySql prefers "autoincrement" identity columns since sequences can only + * be emulated with a table. + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + * + * MySql supports this through AUTO_INCREMENT columns. + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsInlineColumnComments() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsColumnCollation() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'"; + } + + /** + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + $table = $this->quoteStringLiteral($table); + + if ($database) { + $database = $this->quoteStringLiteral($database); + } else { + $database = 'DATABASE()'; + } + + return 'SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, ' . + 'COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, ' . + 'CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS Collation ' . + 'FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ' . $database . ' AND TABLE_NAME = ' . $table . + ' ORDER BY ORDINAL_POSITION ASC'; + } + + public function getListTableMetadataSQL(string $table, ?string $database = null) : string + { + return sprintf( + <<<'SQL' +SELECT ENGINE, AUTO_INCREMENT, TABLE_COLLATION, TABLE_COMMENT, CREATE_OPTIONS +FROM information_schema.TABLES +WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = %s AND TABLE_NAME = %s +SQL + , + $database ? $this->quoteStringLiteral($database) : 'DATABASE()', + $this->quoteStringLiteral($table) + ); + } + + /** + * {@inheritDoc} + */ + public function getCreateDatabaseSQL($name) + { + return 'CREATE DATABASE ' . $name; + } + + /** + * {@inheritDoc} + */ + public function getDropDatabaseSQL($name) + { + return 'DROP DATABASE ' . $name; + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = []) + { + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $index => $definition) { + $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition); + } + } + + // add all indexes + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index => $definition) { + $queryFields .= ', ' . $this->getIndexDeclarationSQL($index, $definition); + } + } + + // attach all primary keys + if (isset($options['primary']) && ! empty($options['primary'])) { + $keyColumns = array_unique(array_values($options['primary'])); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + $query = 'CREATE '; + + if (! empty($options['temporary'])) { + $query .= 'TEMPORARY '; + } + + $query .= 'TABLE ' . $tableName . ' (' . $queryFields . ') '; + $query .= $this->buildTableOptions($options); + $query .= $this->buildPartitionOptions($options); + + $sql = [$query]; + $engine = 'INNODB'; + + if (isset($options['engine'])) { + $engine = strtoupper(trim($options['engine'])); + } + + // Propagate foreign key constraints only for InnoDB. + if (isset($options['foreignKeys']) && $engine === 'INNODB') { + foreach ((array) $options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return $sql; + } + + /** + * {@inheritdoc} + */ + public function getDefaultValueDeclarationSQL($field) + { + // Unset the default value if the given field definition does not allow default values. + if ($field['type'] instanceof TextType || $field['type'] instanceof BlobType) { + $field['default'] = null; + } + + return parent::getDefaultValueDeclarationSQL($field); + } + + /** + * Build SQL for table options + * + * @param mixed[] $options + * + * @return string + */ + private function buildTableOptions(array $options) + { + if (isset($options['table_options'])) { + return $options['table_options']; + } + + $tableOptions = []; + + // Charset + if (! isset($options['charset'])) { + $options['charset'] = 'utf8'; + } + + $tableOptions[] = sprintf('DEFAULT CHARACTER SET %s', $options['charset']); + + // Collate + if (! isset($options['collate'])) { + $options['collate'] = $options['charset'] . '_unicode_ci'; + } + + $tableOptions[] = sprintf('COLLATE %s', $options['collate']); + + // Engine + if (! isset($options['engine'])) { + $options['engine'] = 'InnoDB'; + } + + $tableOptions[] = sprintf('ENGINE = %s', $options['engine']); + + // Auto increment + if (isset($options['auto_increment'])) { + $tableOptions[] = sprintf('AUTO_INCREMENT = %s', $options['auto_increment']); + } + + // Comment + if (isset($options['comment'])) { + $comment = trim($options['comment'], " '"); + + $tableOptions[] = sprintf('COMMENT = %s ', $this->quoteStringLiteral($comment)); + } + + // Row format + if (isset($options['row_format'])) { + $tableOptions[] = sprintf('ROW_FORMAT = %s', $options['row_format']); + } + + return implode(' ', $tableOptions); + } + + /** + * Build SQL for partition options. + * + * @param mixed[] $options + * + * @return string + */ + private function buildPartitionOptions(array $options) + { + return isset($options['partition_options']) + ? ' ' . $options['partition_options'] + : ''; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $columnSql = []; + $queryParts = []; + if ($diff->newName !== false) { + $queryParts[] = 'RENAME TO ' . $diff->getNewName()->getQuotedName($this); + } + + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columnArray = $column->toArray(); + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + foreach ($diff->removedColumns as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP ' . $column->getQuotedName($this); + } + + foreach ($diff->changedColumns as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $column = $columnDiff->column; + $columnArray = $column->toArray(); + + // Don't propagate default value changes for unsupported column types. + if ($columnDiff->hasChanged('default') && + count($columnDiff->changedProperties) === 1 && + ($columnArray['type'] instanceof TextType || $columnArray['type'] instanceof BlobType) + ) { + continue; + } + + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'CHANGE ' . ($columnDiff->getOldColumnName()->getQuotedName($this)) . ' ' + . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + $columnArray = $column->toArray(); + $columnArray['comment'] = $this->getColumnComment($column); + $queryParts[] = 'CHANGE ' . $oldColumnName->getQuotedName($this) . ' ' + . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnArray); + } + + if (isset($diff->addedIndexes['primary'])) { + $keyColumns = array_unique(array_values($diff->addedIndexes['primary']->getColumns())); + $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')'; + unset($diff->addedIndexes['primary']); + } + + $sql = []; + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + if (count($queryParts) > 0) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(', ', $queryParts); + } + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff) + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * {@inheritDoc} + */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + $table = $diff->getName($this)->getQuotedName($this); + + foreach ($diff->changedIndexes as $changedIndex) { + $sql = array_merge($sql, $this->getPreAlterTableAlterPrimaryKeySQL($diff, $changedIndex)); + } + + foreach ($diff->removedIndexes as $remKey => $remIndex) { + $sql = array_merge($sql, $this->getPreAlterTableAlterPrimaryKeySQL($diff, $remIndex)); + + foreach ($diff->addedIndexes as $addKey => $addIndex) { + if ($remIndex->getColumns() === $addIndex->getColumns()) { + $indexClause = 'INDEX ' . $addIndex->getName(); + + if ($addIndex->isPrimary()) { + $indexClause = 'PRIMARY KEY'; + } elseif ($addIndex->isUnique()) { + $indexClause = 'UNIQUE INDEX ' . $addIndex->getName(); + } + + $query = 'ALTER TABLE ' . $table . ' DROP INDEX ' . $remIndex->getName() . ', '; + $query .= 'ADD ' . $indexClause; + $query .= ' (' . $this->getIndexFieldDeclarationListSQL($addIndex) . ')'; + + $sql[] = $query; + + unset($diff->removedIndexes[$remKey], $diff->addedIndexes[$addKey]); + + break; + } + } + } + + $engine = 'INNODB'; + + if ($diff->fromTable instanceof Table && $diff->fromTable->hasOption('engine')) { + $engine = strtoupper(trim($diff->fromTable->getOption('engine'))); + } + + // Suppress foreign key constraint propagation on non-supporting engines. + if ($engine !== 'INNODB') { + $diff->addedForeignKeys = []; + $diff->changedForeignKeys = []; + $diff->removedForeignKeys = []; + } + + $sql = array_merge( + $sql, + $this->getPreAlterTableAlterIndexForeignKeySQL($diff), + parent::getPreAlterTableIndexForeignKeySQL($diff), + $this->getPreAlterTableRenameIndexForeignKeySQL($diff) + ); + + return $sql; + } + + /** + * @return string[] + */ + private function getPreAlterTableAlterPrimaryKeySQL(TableDiff $diff, Index $index) + { + $sql = []; + + if (! $index->isPrimary() || ! $diff->fromTable instanceof Table) { + return $sql; + } + + $tableName = $diff->getName($this)->getQuotedName($this); + + // Dropping primary keys requires to unset autoincrement attribute on the particular column first. + foreach ($index->getColumns() as $columnName) { + if (! $diff->fromTable->hasColumn($columnName)) { + continue; + } + + $column = $diff->fromTable->getColumn($columnName); + + if ($column->getAutoincrement() !== true) { + continue; + } + + $column->setAutoincrement(false); + + $sql[] = 'ALTER TABLE ' . $tableName . ' MODIFY ' . + $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + + // original autoincrement information might be needed later on by other parts of the table alteration + $column->setAutoincrement(true); + } + + return $sql; + } + + /** + * @param TableDiff $diff The table diff to gather the SQL for. + * + * @return string[] + */ + private function getPreAlterTableAlterIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + $table = $diff->getName($this)->getQuotedName($this); + + foreach ($diff->changedIndexes as $changedIndex) { + // Changed primary key + if (! $changedIndex->isPrimary() || ! ($diff->fromTable instanceof Table)) { + continue; + } + + foreach ($diff->fromTable->getPrimaryKeyColumns() as $columnName) { + $column = $diff->fromTable->getColumn($columnName); + + // Check if an autoincrement column was dropped from the primary key. + if (! $column->getAutoincrement() || in_array($columnName, $changedIndex->getColumns())) { + continue; + } + + // The autoincrement attribute needs to be removed from the dropped column + // before we can drop and recreate the primary key. + $column->setAutoincrement(false); + + $sql[] = 'ALTER TABLE ' . $table . ' MODIFY ' . + $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + + // Restore the autoincrement attribute as it might be needed later on + // by other parts of the table alteration. + $column->setAutoincrement(true); + } + } + + return $sql; + } + + /** + * @param TableDiff $diff The table diff to gather the SQL for. + * + * @return string[] + */ + protected function getPreAlterTableRenameIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + $tableName = $diff->getName($this)->getQuotedName($this); + + foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) { + if (in_array($foreignKey, $diff->changedForeignKeys, true)) { + continue; + } + + $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableName); + } + + return $sql; + } + + /** + * Returns the remaining foreign key constraints that require one of the renamed indexes. + * + * "Remaining" here refers to the diff between the foreign keys currently defined in the associated + * table and the foreign keys to be removed. + * + * @param TableDiff $diff The table diff to evaluate. + * + * @return ForeignKeyConstraint[] + */ + private function getRemainingForeignKeyConstraintsRequiringRenamedIndexes(TableDiff $diff) + { + if (empty($diff->renamedIndexes) || ! $diff->fromTable instanceof Table) { + return []; + } + + $foreignKeys = []; + /** @var ForeignKeyConstraint[] $remainingForeignKeys */ + $remainingForeignKeys = array_diff_key( + $diff->fromTable->getForeignKeys(), + $diff->removedForeignKeys + ); + + foreach ($remainingForeignKeys as $foreignKey) { + foreach ($diff->renamedIndexes as $index) { + if ($foreignKey->intersectsIndexColumns($index)) { + $foreignKeys[] = $foreignKey; + + break; + } + } + } + + return $foreignKeys; + } + + /** + * {@inheritdoc} + */ + protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) + { + return array_merge( + parent::getPostAlterTableIndexForeignKeySQL($diff), + $this->getPostAlterTableRenameIndexForeignKeySQL($diff) + ); + } + + /** + * @param TableDiff $diff The table diff to gather the SQL for. + * + * @return string[] + */ + protected function getPostAlterTableRenameIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + $tableName = $diff->newName !== false + ? $diff->getNewName()->getQuotedName($this) + : $diff->getName($this)->getQuotedName($this); + + foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) { + if (in_array($foreignKey, $diff->changedForeignKeys, true)) { + continue; + } + + $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableName); + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + protected function getCreateIndexSQLFlags(Index $index) + { + $type = ''; + if ($index->isUnique()) { + $type .= 'UNIQUE '; + } elseif ($index->hasFlag('fulltext')) { + $type .= 'FULLTEXT '; + } elseif ($index->hasFlag('spatial')) { + $type .= 'SPATIAL '; + } + + return $type; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritdoc} + */ + public function getFloatDeclarationSQL(array $field) + { + return 'DOUBLE PRECISION' . $this->getUnsignedDeclaration($field); + } + + /** + * {@inheritdoc} + */ + public function getDecimalTypeDeclarationSQL(array $columnDef) + { + return parent::getDecimalTypeDeclarationSQL($columnDef) . $this->getUnsignedDeclaration($columnDef); + } + + /** + * Get unsigned declaration for a column. + * + * @param mixed[] $columnDef + * + * @return string + */ + private function getUnsignedDeclaration(array $columnDef) + { + return ! empty($columnDef['unsigned']) ? ' UNSIGNED' : ''; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + $autoinc = ''; + if (! empty($columnDef['autoincrement'])) { + $autoinc = ' AUTO_INCREMENT'; + } + + return $this->getUnsignedDeclaration($columnDef) . $autoinc; + } + + /** + * {@inheritDoc} + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = ''; + if ($foreignKey->hasOption('match')) { + $query .= ' MATCH ' . $foreignKey->getOption('match'); + } + $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + + return $query; + } + + /** + * {@inheritDoc} + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index) { + $indexName = $index->getQuotedName($this); + } elseif (is_string($index)) { + $indexName = $index; + } else { + throw new InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'); + } + + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } elseif (! is_string($table)) { + throw new InvalidArgumentException('MysqlPlatform::getDropIndexSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + if ($index instanceof Index && $index->isPrimary()) { + // mysql primary keys are always named "PRIMARY", + // so we cannot use them in statements because of them being keyword. + return $this->getDropPrimaryKeySQL($table); + } + + return 'DROP INDEX ' . $indexName . ' ON ' . $table; + } + + /** + * @param string $table + * + * @return string + */ + protected function getDropPrimaryKeySQL($table) + { + return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY'; + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return 'mysql'; + } + + /** + * {@inheritDoc} + */ + public function getReadLockSQL() + { + return 'LOCK IN SHARE MODE'; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'tinyint' => 'boolean', + 'smallint' => 'smallint', + 'mediumint' => 'integer', + 'int' => 'integer', + 'integer' => 'integer', + 'bigint' => 'bigint', + 'tinytext' => 'text', + 'mediumtext' => 'text', + 'longtext' => 'text', + 'text' => 'text', + 'varchar' => 'string', + 'string' => 'string', + 'char' => 'string', + 'date' => 'date', + 'datetime' => 'datetime', + 'timestamp' => 'datetime', + 'time' => 'time', + 'float' => 'float', + 'double' => 'float', + 'real' => 'float', + 'decimal' => 'decimal', + 'numeric' => 'decimal', + 'year' => 'date', + 'longblob' => 'blob', + 'blob' => 'blob', + 'mediumblob' => 'blob', + 'tinyblob' => 'blob', + 'binary' => 'binary', + 'varbinary' => 'binary', + 'set' => 'simple_array', + ]; + } + + /** + * {@inheritDoc} + */ + public function getVarcharMaxLength() + { + return 65535; + } + + /** + * {@inheritdoc} + */ + public function getBinaryMaxLength() + { + return 65535; + } + + /** + * {@inheritDoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\MySQLKeywords::class; + } + + /** + * {@inheritDoc} + * + * MySQL commits a transaction implicitly when DROP TABLE is executed, however not + * if DROP TEMPORARY TABLE is executed. + */ + public function getDropTemporaryTableSQL($table) + { + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } elseif (! is_string($table)) { + throw new InvalidArgumentException('getDropTemporaryTableSQL() expects $table parameter to be string or \Doctrine\DBAL\Schema\Table.'); + } + + return 'DROP TEMPORARY TABLE ' . $table; + } + + /** + * Gets the SQL Snippet used to declare a BLOB column type. + * TINYBLOB : 2 ^ 8 - 1 = 255 + * BLOB : 2 ^ 16 - 1 = 65535 + * MEDIUMBLOB : 2 ^ 24 - 1 = 16777215 + * LONGBLOB : 2 ^ 32 - 1 = 4294967295 + * + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $field) + { + if (! empty($field['length']) && is_numeric($field['length'])) { + $length = $field['length']; + + if ($length <= static::LENGTH_LIMIT_TINYBLOB) { + return 'TINYBLOB'; + } + + if ($length <= static::LENGTH_LIMIT_BLOB) { + return 'BLOB'; + } + + if ($length <= static::LENGTH_LIMIT_MEDIUMBLOB) { + return 'MEDIUMBLOB'; + } + } + + return 'LONGBLOB'; + } + + /** + * {@inheritdoc} + */ + public function quoteStringLiteral($str) + { + $str = str_replace('\\', '\\\\', $str); // MySQL requires backslashes to be escaped aswell. + + return parent::quoteStringLiteral($str); + } + + /** + * {@inheritdoc} + */ + public function getDefaultTransactionIsolationLevel() + { + return TransactionIsolationLevel::REPEATABLE_READ; + } + + /** + * {@inheritdoc} + */ + public function supportsColumnLengthIndexes() : bool + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php new file mode 100644 index 000000000..537a566ba --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -0,0 +1,1175 @@ +getBitAndComparisonExpression($value1, $value2) + . '+' . $value2 . ')'; + } + + /** + * {@inheritDoc} + * + * Need to specifiy minvalue, since start with is hidden in the system and MINVALUE <= START WITH. + * Therefore we can use MINVALUE to be able to get a hint what START WITH was for later introspection + * in {@see listSequences()} + */ + public function getCreateSequenceSQL(Sequence $sequence) + { + return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . + ' START WITH ' . $sequence->getInitialValue() . + ' MINVALUE ' . $sequence->getInitialValue() . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + $this->getSequenceCacheSQL($sequence); + } + + /** + * {@inheritDoc} + */ + public function getAlterSequenceSQL(Sequence $sequence) + { + return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize() + . $this->getSequenceCacheSQL($sequence); + } + + /** + * Cache definition for sequences + * + * @return string + */ + private function getSequenceCacheSQL(Sequence $sequence) + { + if ($sequence->getCache() === 0) { + return ' NOCACHE'; + } elseif ($sequence->getCache() === 1) { + return ' NOCACHE'; + } elseif ($sequence->getCache() > 1) { + return ' CACHE ' . $sequence->getCache(); + } + + return ''; + } + + /** + * {@inheritDoc} + */ + public function getSequenceNextValSQL($sequenceName) + { + return 'SELECT ' . $sequenceName . '.nextval FROM DUAL'; + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case TransactionIsolationLevel::READ_UNCOMMITTED: + return 'READ UNCOMMITTED'; + case TransactionIsolationLevel::READ_COMMITTED: + return 'READ COMMITTED'; + case TransactionIsolationLevel::REPEATABLE_READ: + case TransactionIsolationLevel::SERIALIZABLE: + return 'SERIALIZABLE'; + default: + return parent::_getTransactionIsolationLevelSQL($level); + } + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'NUMBER(1)'; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + return 'NUMBER(10)'; + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + return 'NUMBER(20)'; + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'NUMBER(5)'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP(0)'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP(0) WITH TIME ZONE'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + return ''; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(2000)') + : ($length ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)'); + } + + /** + * {@inheritdoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return 'RAW(' . ($length ?: $this->getBinaryMaxLength()) . ')'; + } + + /** + * {@inheritdoc} + */ + public function getBinaryMaxLength() + { + return 2000; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'CLOB'; + } + + /** + * {@inheritDoc} + */ + public function getListDatabasesSQL() + { + return 'SELECT username FROM all_users'; + } + + /** + * {@inheritDoc} + */ + public function getListSequencesSQL($database) + { + $database = $this->normalizeIdentifier($database); + $database = $this->quoteStringLiteral($database->getName()); + + return 'SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ' . + 'WHERE SEQUENCE_OWNER = ' . $database; + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($table, array $columns, array $options = []) + { + $indexes = $options['indexes'] ?? []; + $options['indexes'] = []; + $sql = parent::_getCreateTableSQL($table, $columns, $options); + + foreach ($columns as $name => $column) { + if (isset($column['sequence'])) { + $sql[] = $this->getCreateSequenceSQL($column['sequence']); + } + + if (! isset($column['autoincrement']) || ! $column['autoincrement'] && + (! isset($column['autoinc']) || ! $column['autoinc'])) { + continue; + } + + $sql = array_merge($sql, $this->getCreateAutoincrementSql($name, $table)); + } + + if (isset($indexes) && ! empty($indexes)) { + foreach ($indexes as $index) { + $sql[] = $this->getCreateIndexSQL($index, $table); + } + } + + return $sql; + } + + /** + * {@inheritDoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaOracleReader.html + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return "SELECT uind_col.index_name AS name, + ( + SELECT uind.index_type + FROM user_indexes uind + WHERE uind.index_name = uind_col.index_name + ) AS type, + decode( + ( + SELECT uind.uniqueness + FROM user_indexes uind + WHERE uind.index_name = uind_col.index_name + ), + 'NONUNIQUE', + 0, + 'UNIQUE', + 1 + ) AS is_unique, + uind_col.column_name AS column_name, + uind_col.column_position AS column_pos, + ( + SELECT ucon.constraint_type + FROM user_constraints ucon + WHERE ucon.index_name = uind_col.index_name + ) AS is_primary + FROM user_ind_columns uind_col + WHERE uind_col.table_name = " . $table . ' + ORDER BY uind_col.column_position ASC'; + } + + /** + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return 'SELECT * FROM sys.user_tables'; + } + + /** + * {@inheritDoc} + */ + public function getListViewsSQL($database) + { + return 'SELECT view_name, text FROM sys.user_views'; + } + + /** + * {@inheritDoc} + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * {@inheritDoc} + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * @param string $name + * @param string $table + * @param int $start + * + * @return string[] + */ + public function getCreateAutoincrementSql($name, $table, $start = 1) + { + $tableIdentifier = $this->normalizeIdentifier($table); + $quotedTableName = $tableIdentifier->getQuotedName($this); + $unquotedTableName = $tableIdentifier->getName(); + + $nameIdentifier = $this->normalizeIdentifier($name); + $quotedName = $nameIdentifier->getQuotedName($this); + $unquotedName = $nameIdentifier->getName(); + + $sql = []; + + $autoincrementIdentifierName = $this->getAutoincrementIdentifierName($tableIdentifier); + + $idx = new Index($autoincrementIdentifierName, [$quotedName], true, true); + + $sql[] = 'DECLARE + constraints_Count NUMBER; +BEGIN + SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \'' . $unquotedTableName . '\' AND CONSTRAINT_TYPE = \'P\'; + IF constraints_Count = 0 OR constraints_Count = \'\' THEN + EXECUTE IMMEDIATE \'' . $this->getCreateConstraintSQL($idx, $quotedTableName) . '\'; + END IF; +END;'; + + $sequenceName = $this->getIdentitySequenceName( + $tableIdentifier->isQuoted() ? $quotedTableName : $unquotedTableName, + $nameIdentifier->isQuoted() ? $quotedName : $unquotedName + ); + $sequence = new Sequence($sequenceName, $start); + $sql[] = $this->getCreateSequenceSQL($sequence); + + $sql[] = 'CREATE TRIGGER ' . $autoincrementIdentifierName . ' + BEFORE INSERT + ON ' . $quotedTableName . ' + FOR EACH ROW +DECLARE + last_Sequence NUMBER; + last_InsertID NUMBER; +BEGIN + SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $quotedName . ' FROM DUAL; + IF (:NEW.' . $quotedName . ' IS NULL OR :NEW.' . $quotedName . ' = 0) THEN + SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $quotedName . ' FROM DUAL; + ELSE + SELECT NVL(Last_Number, 0) INTO last_Sequence + FROM User_Sequences + WHERE Sequence_Name = \'' . $sequence->getName() . '\'; + SELECT :NEW.' . $quotedName . ' INTO last_InsertID FROM DUAL; + WHILE (last_InsertID > last_Sequence) LOOP + SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL; + END LOOP; + END IF; +END;'; + + return $sql; + } + + /** + * Returns the SQL statements to drop the autoincrement for the given table name. + * + * @param string $table The table name to drop the autoincrement for. + * + * @return string[] + */ + public function getDropAutoincrementSql($table) + { + $table = $this->normalizeIdentifier($table); + $autoincrementIdentifierName = $this->getAutoincrementIdentifierName($table); + $identitySequenceName = $this->getIdentitySequenceName( + $table->isQuoted() ? $table->getQuotedName($this) : $table->getName(), + '' + ); + + return [ + 'DROP TRIGGER ' . $autoincrementIdentifierName, + $this->getDropSequenceSQL($identitySequenceName), + $this->getDropConstraintSQL($autoincrementIdentifierName, $table->getQuotedName($this)), + ]; + } + + /** + * Normalizes the given identifier. + * + * Uppercases the given identifier if it is not quoted by intention + * to reflect Oracle's internal auto uppercasing strategy of unquoted identifiers. + * + * @param string $name The identifier to normalize. + * + * @return Identifier The normalized identifier. + */ + private function normalizeIdentifier($name) + { + $identifier = new Identifier($name); + + return $identifier->isQuoted() ? $identifier : new Identifier(strtoupper($name)); + } + + /** + * Returns the autoincrement primary key identifier name for the given table identifier. + * + * Quotes the autoincrement primary key identifier name + * if the given table name is quoted by intention. + * + * @param Identifier $table The table identifier to return the autoincrement primary key identifier name for. + * + * @return string + */ + private function getAutoincrementIdentifierName(Identifier $table) + { + $identifierName = $table->getName() . '_AI_PK'; + + return $table->isQuoted() + ? $this->quoteSingleIdentifier($identifierName) + : $identifierName; + } + + /** + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table) + { + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return "SELECT alc.constraint_name, + alc.DELETE_RULE, + cols.column_name \"local_column\", + cols.position, + ( + SELECT r_cols.table_name + FROM user_cons_columns r_cols + WHERE alc.r_constraint_name = r_cols.constraint_name + AND r_cols.position = cols.position + ) AS \"references_table\", + ( + SELECT r_cols.column_name + FROM user_cons_columns r_cols + WHERE alc.r_constraint_name = r_cols.constraint_name + AND r_cols.position = cols.position + ) AS \"foreign_column\" + FROM user_cons_columns cols + JOIN user_constraints alc + ON alc.constraint_name = cols.constraint_name + AND alc.constraint_type = 'R' + AND alc.table_name = " . $table . ' + ORDER BY cols.constraint_name ASC, cols.position ASC'; + } + + /** + * {@inheritDoc} + */ + public function getListTableConstraintsSQL($table) + { + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return 'SELECT * FROM user_constraints WHERE table_name = ' . $table; + } + + /** + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + $tabColumnsTableName = 'user_tab_columns'; + $colCommentsTableName = 'user_col_comments'; + $tabColumnsOwnerCondition = ''; + $colCommentsOwnerCondition = ''; + + if ($database !== null && $database !== '/') { + $database = $this->normalizeIdentifier($database); + $database = $this->quoteStringLiteral($database->getName()); + $tabColumnsTableName = 'all_tab_columns'; + $colCommentsTableName = 'all_col_comments'; + $tabColumnsOwnerCondition = ' AND c.owner = ' . $database; + $colCommentsOwnerCondition = ' AND d.OWNER = c.OWNER'; + } + + return sprintf( + <<<'SQL' +SELECT c.*, + ( + SELECT d.comments + FROM %s d + WHERE d.TABLE_NAME = c.TABLE_NAME%s + AND d.COLUMN_NAME = c.COLUMN_NAME + ) AS comments +FROM %s c +WHERE c.table_name = %s%s +ORDER BY c.column_id +SQL + , + $colCommentsTableName, + $colCommentsOwnerCondition, + $tabColumnsTableName, + $table, + $tabColumnsOwnerCondition + ); + } + + /** + * {@inheritDoc} + */ + public function getDropSequenceSQL($sequence) + { + if ($sequence instanceof Sequence) { + $sequence = $sequence->getQuotedName($this); + } + + return 'DROP SEQUENCE ' . $sequence; + } + + /** + * {@inheritDoc} + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if (! $foreignKey instanceof ForeignKeyConstraint) { + $foreignKey = new Identifier($foreignKey); + } + + if (! $table instanceof Table) { + $table = new Identifier($table); + } + + $foreignKey = $foreignKey->getQuotedName($this); + $table = $table->getQuotedName($this); + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey; + } + + /** + * {@inheritdoc} + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $referentialAction = null; + + if ($foreignKey->hasOption('onDelete')) { + $referentialAction = $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete')); + } + + return $referentialAction ? ' ON DELETE ' . $referentialAction : ''; + } + + /** + * {@inheritdoc} + */ + public function getForeignKeyReferentialActionSQL($action) + { + $action = strtoupper($action); + + switch ($action) { + case 'RESTRICT': // RESTRICT is not supported, therefore falling back to NO ACTION. + case 'NO ACTION': + // NO ACTION cannot be declared explicitly, + // therefore returning empty string to indicate to OMIT the referential clause. + return ''; + + case 'CASCADE': + case 'SET NULL': + return $action; + + default: + // SET DEFAULT is not supported, throw exception instead. + throw new InvalidArgumentException('Invalid foreign key action: ' . $action); + } + } + + /** + * {@inheritDoc} + */ + public function getDropDatabaseSQL($database) + { + return 'DROP USER ' . $database . ' CASCADE'; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = []; + $commentsSQL = []; + $columnSql = []; + + $fields = []; + + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $fields[] = $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + $comment = $this->getColumnComment($column); + + if (! $comment) { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $diff->getName($this)->getQuotedName($this), + $column->getQuotedName($this), + $comment + ); + } + + if (count($fields)) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ADD (' . implode(', ', $fields) . ')'; + } + + $fields = []; + foreach ($diff->changedColumns as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $column = $columnDiff->column; + + // Do not generate column alteration clause if type is binary and only fixed property has changed. + // Oracle only supports binary type columns with variable length. + // Avoids unnecessary table alteration statements. + if ($column->getType() instanceof BinaryType && + $columnDiff->hasChanged('fixed') && + count($columnDiff->changedProperties) === 1 + ) { + continue; + } + + $columnHasChangedComment = $columnDiff->hasChanged('comment'); + + /** + * Do not add query part if only comment has changed + */ + if (! ($columnHasChangedComment && count($columnDiff->changedProperties) === 1)) { + $columnInfo = $column->toArray(); + + if (! $columnDiff->hasChanged('notnull')) { + unset($columnInfo['notnull']); + } + + $fields[] = $column->getQuotedName($this) . $this->getColumnDeclarationSQL('', $columnInfo); + } + + if (! $columnHasChangedComment) { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $diff->getName($this)->getQuotedName($this), + $column->getQuotedName($this), + $this->getColumnComment($column) + ); + } + + if (count($fields)) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' MODIFY (' . implode(', ', $fields) . ')'; + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . + ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . ' TO ' . $column->getQuotedName($this); + } + + $fields = []; + foreach ($diff->removedColumns as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $fields[] = $column->getQuotedName($this); + } + + if (count($fields)) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' DROP (' . implode(', ', $fields) . ')'; + } + + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + $sql = array_merge($sql, $commentsSQL); + + if ($diff->newName !== false) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' RENAME TO ' . $diff->getNewName()->getQuotedName($this); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff) + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * {@inheritdoc} + */ + public function getColumnDeclarationSQL($name, array $field) + { + if (isset($field['columnDefinition'])) { + $columnDef = $this->getCustomTypeDeclarationSQL($field); + } else { + $default = $this->getDefaultValueDeclarationSQL($field); + + $notnull = ''; + + if (isset($field['notnull'])) { + $notnull = $field['notnull'] ? ' NOT NULL' : ' NULL'; + } + + $unique = isset($field['unique']) && $field['unique'] ? + ' ' . $this->getUniqueFieldDeclarationSQL() : ''; + + $check = isset($field['check']) && $field['check'] ? + ' ' . $field['check'] : ''; + + $typeDecl = $field['type']->getSQLDeclaration($field, $this); + $columnDef = $typeDecl . $default . $notnull . $unique . $check; + } + + return $name . ' ' . $columnDef; + } + + /** + * {@inheritdoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + if (strpos($tableName, '.') !== false) { + [$schema] = explode('.', $tableName); + $oldIndexName = $schema . '.' . $oldIndexName; + } + + return ['ALTER INDEX ' . $oldIndexName . ' RENAME TO ' . $index->getQuotedName($this)]; + } + + /** + * {@inheritDoc} + */ + public function prefersSequences() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function usesSequenceEmulatedIdentityColumns() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function getIdentitySequenceName($tableName, $columnName) + { + $table = new Identifier($tableName); + + // No usage of column name to preserve BC compatibility with <2.5 + $identitySequenceName = $table->getName() . '_SEQ'; + + if ($table->isQuoted()) { + $identitySequenceName = '"' . $identitySequenceName . '"'; + } + + $identitySequenceIdentifier = $this->normalizeIdentifier($identitySequenceName); + + return $identitySequenceIdentifier->getQuotedName($this); + } + + /** + * {@inheritDoc} + */ + public function supportsCommentOnStatement() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return 'oracle'; + } + + /** + * {@inheritDoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset = null) + { + if ($limit === null && $offset <= 0) { + return $query; + } + + if (preg_match('/^\s*SELECT/i', $query)) { + if (! preg_match('/\sFROM\s/i', $query)) { + $query .= ' FROM dual'; + } + + $columns = ['a.*']; + + if ($offset > 0) { + $columns[] = 'ROWNUM AS doctrine_rownum'; + } + + $query = sprintf('SELECT %s FROM (%s) a', implode(', ', $columns), $query); + + if ($limit !== null) { + $query .= sprintf(' WHERE ROWNUM <= %d', $offset + $limit); + } + + if ($offset > 0) { + $query = sprintf('SELECT * FROM (%s) WHERE doctrine_rownum >= %d', $query, $offset + 1); + } + } + + return $query; + } + + /** + * {@inheritDoc} + * + * Oracle returns all column names in SQL result sets in uppercase. + */ + public function getSQLResultCasing($column) + { + return strtoupper($column); + } + + /** + * {@inheritDoc} + */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'CREATE GLOBAL TEMPORARY TABLE'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:sP'; + } + + /** + * {@inheritDoc} + */ + public function getDateFormatString() + { + return 'Y-m-d 00:00:00'; + } + + /** + * {@inheritDoc} + */ + public function getTimeFormatString() + { + return '1900-01-01 H:i:s'; + } + + /** + * {@inheritDoc} + */ + public function fixSchemaElementName($schemaElementName) + { + if (strlen($schemaElementName) > 30) { + // Trim it + return substr($schemaElementName, 0, 30); + } + + return $schemaElementName; + } + + /** + * {@inheritDoc} + */ + public function getMaxIdentifierLength() + { + return 30; + } + + /** + * {@inheritDoc} + */ + public function supportsSequences() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsForeignKeyOnUpdate() + { + return false; + } + + /** + * {@inheritDoc} + */ + public function supportsReleaseSavepoints() + { + return false; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); + } + + /** + * {@inheritDoc} + */ + public function getDummySelectSQL() + { + $expression = func_num_args() > 0 ? func_get_arg(0) : '1'; + + return sprintf('SELECT %s FROM DUAL', $expression); + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'integer' => 'integer', + 'number' => 'integer', + 'pls_integer' => 'boolean', + 'binary_integer' => 'boolean', + 'varchar' => 'string', + 'varchar2' => 'string', + 'nvarchar2' => 'string', + 'char' => 'string', + 'nchar' => 'string', + 'date' => 'date', + 'timestamp' => 'datetime', + 'timestamptz' => 'datetimetz', + 'float' => 'float', + 'binary_float' => 'float', + 'binary_double' => 'float', + 'long' => 'string', + 'clob' => 'text', + 'nclob' => 'text', + 'raw' => 'binary', + 'long raw' => 'blob', + 'rowid' => 'string', + 'urowid' => 'string', + 'blob' => 'blob', + ]; + } + + /** + * {@inheritDoc} + */ + public function releaseSavePoint($savepoint) + { + return ''; + } + + /** + * {@inheritDoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\OracleKeywords::class; + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'BLOB'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL100Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL100Platform.php new file mode 100644 index 000000000..cfb079f94 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL100Platform.php @@ -0,0 +1,33 @@ +quoteStringLiteral($database) . " + AND sequence_schema NOT LIKE 'pg\_%' + AND sequence_schema != 'information_schema'"; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL91Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL91Platform.php new file mode 100644 index 000000000..f55840983 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL91Platform.php @@ -0,0 +1,46 @@ +quoteSingleIdentifier($collation); + } + + /** + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + $sql = parent::getListTableColumnsSQL($table, $database); + $parts = explode('AS complete_type,', $sql, 2); + + return $parts[0] . 'AS complete_type, (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation,' . $parts[1]; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php new file mode 100644 index 000000000..b302c0ceb --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL92Platform.php @@ -0,0 +1,69 @@ +doctrineTypeMapping['json'] = Type::JSON; + } + + /** + * {@inheritdoc} + */ + public function getCloseActiveDatabaseConnectionsSQL($database) + { + return sprintf( + 'SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = %s', + $this->quoteStringLiteral($database) + ); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php new file mode 100644 index 000000000..9db0ecbbd --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSQL94Platform.php @@ -0,0 +1,41 @@ +doctrineTypeMapping['jsonb'] = Type::JSON; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php new file mode 100644 index 000000000..cb4603f51 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -0,0 +1,1248 @@ + [ + 't', + 'true', + 'y', + 'yes', + 'on', + '1', + ], + 'false' => [ + 'f', + 'false', + 'n', + 'no', + 'off', + '0', + ], + ]; + + /** + * PostgreSQL has different behavior with some drivers + * with regard to how booleans have to be handled. + * + * Enables use of 'true'/'false' or otherwise 1 and 0 instead. + * + * @param bool $flag + */ + public function setUseBooleanTrueFalseStrings($flag) + { + $this->useBooleanTrueFalseStrings = (bool) $flag; + } + + /** + * {@inheritDoc} + */ + public function getSubstringExpression($value, $from, $length = null) + { + if ($length === null) { + return 'SUBSTRING(' . $value . ' FROM ' . $from . ')'; + } + + return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $length . ')'; + } + + /** + * {@inheritDoc} + */ + public function getNowExpression() + { + return 'LOCALTIMESTAMP(0)'; + } + + /** + * {@inheritDoc} + */ + public function getRegexpExpression() + { + return 'SIMILAR TO'; + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos !== false) { + $str = $this->getSubstringExpression($str, $startPos); + + return 'CASE WHEN (POSITION(' . $substr . ' IN ' . $str . ') = 0) THEN 0 ELSE (POSITION(' . $substr . ' IN ' . $str . ') + ' . ($startPos-1) . ') END'; + } + + return 'POSITION(' . $substr . ' IN ' . $str . ')'; + } + + /** + * {@inheritdoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + if ($unit === DateIntervalUnit::QUARTER) { + $interval *= 3; + $unit = DateIntervalUnit::MONTH; + } + + return '(' . $date . ' ' . $operator . ' (' . $interval . " || ' " . $unit . "')::interval)"; + } + + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))'; + } + + /** + * {@inheritDoc} + */ + public function supportsSequences() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsSchemas() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function getDefaultSchemaName() + { + return 'public'; + } + + /** + * {@inheritDoc} + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function supportsPartialIndexes() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function usesSequenceEmulatedIdentityColumns() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function getIdentitySequenceName($tableName, $columnName) + { + return $tableName . '_' . $columnName . '_seq'; + } + + /** + * {@inheritDoc} + */ + public function supportsCommentOnStatement() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function prefersSequences() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function hasNativeGuidType() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getListDatabasesSQL() + { + return 'SELECT datname FROM pg_database'; + } + + /** + * {@inheritDoc} + */ + public function getListNamespacesSQL() + { + return "SELECT schema_name AS nspname + FROM information_schema.schemata + WHERE schema_name NOT LIKE 'pg\_%' + AND schema_name != 'information_schema'"; + } + + /** + * {@inheritDoc} + */ + public function getListSequencesSQL($database) + { + return "SELECT sequence_name AS relname, + sequence_schema AS schemaname + FROM information_schema.sequences + WHERE sequence_schema NOT LIKE 'pg\_%' + AND sequence_schema != 'information_schema'"; + } + + /** + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return "SELECT quote_ident(table_name) AS table_name, + table_schema AS schema_name + FROM information_schema.tables + WHERE table_schema NOT LIKE 'pg\_%' + AND table_schema != 'information_schema' + AND table_name != 'geometry_columns' + AND table_name != 'spatial_ref_sys' + AND table_type != 'VIEW'"; + } + + /** + * {@inheritDoc} + */ + public function getListViewsSQL($database) + { + return 'SELECT quote_ident(table_name) AS viewname, + table_schema AS schemaname, + view_definition AS definition + FROM information_schema.views + WHERE view_definition IS NOT NULL'; + } + + /** + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + return 'SELECT quote_ident(r.conname) as conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef + FROM pg_catalog.pg_constraint r + WHERE r.conrelid = + ( + SELECT c.oid + FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n + WHERE ' . $this->getTableWhereClause($table) . " AND n.oid = c.relnamespace + ) + AND r.contype = 'f'"; + } + + /** + * {@inheritDoc} + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * {@inheritDoc} + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * {@inheritDoc} + */ + public function getListTableConstraintsSQL($table) + { + $table = new Identifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return sprintf( + <<<'SQL' +SELECT + quote_ident(relname) as relname +FROM + pg_class +WHERE oid IN ( + SELECT indexrelid + FROM pg_index, pg_class + WHERE pg_class.relname = %s + AND pg_class.oid = pg_index.indrelid + AND (indisunique = 't' OR indisprimary = 't') + ) +SQL + , + $table + ); + } + + /** + * {@inheritDoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + return 'SELECT quote_ident(relname) as relname, pg_index.indisunique, pg_index.indisprimary, + pg_index.indkey, pg_index.indrelid, + pg_get_expr(indpred, indrelid) AS where + FROM pg_class, pg_index + WHERE oid IN ( + SELECT indexrelid + FROM pg_index si, pg_class sc, pg_namespace sn + WHERE ' . $this->getTableWhereClause($table, 'sc', 'sn') . ' AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid + ) AND pg_index.indexrelid = oid'; + } + + /** + * @param string $table + * @param string $classAlias + * @param string $namespaceAlias + * + * @return string + */ + private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n') + { + $whereClause = $namespaceAlias . ".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND "; + if (strpos($table, '.') !== false) { + [$schema, $table] = explode('.', $table); + $schema = $this->quoteStringLiteral($schema); + } else { + $schema = "ANY(string_to_array((select replace(replace(setting,'\"\$user\"',user),' ','') from pg_catalog.pg_settings where name = 'search_path'),','))"; + } + + $table = new Identifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return $whereClause . sprintf( + '%s.relname = %s AND %s.nspname = %s', + $classAlias, + $table, + $namespaceAlias, + $schema + ); + } + + /** + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + return "SELECT + a.attnum, + quote_ident(a.attname) AS field, + t.typname AS type, + format_type(a.atttypid, a.atttypmod) AS complete_type, + (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type, + (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM + pg_catalog.pg_type t2 WHERE t2.typtype = 'd' AND t2.oid = a.atttypid) AS domain_complete_type, + a.attnotnull AS isnotnull, + (SELECT 't' + FROM pg_index + WHERE c.oid = pg_index.indrelid + AND pg_index.indkey[0] = a.attnum + AND pg_index.indisprimary = 't' + ) AS pri, + (SELECT pg_get_expr(adbin, adrelid) + FROM pg_attrdef + WHERE c.oid = pg_attrdef.adrelid + AND pg_attrdef.adnum=a.attnum + ) AS default, + (SELECT pg_description.description + FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid + ) AS comment + FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n + WHERE " . $this->getTableWhereClause($table, 'c', 'n') . ' + AND a.attnum > 0 + AND a.attrelid = c.oid + AND a.atttypid = t.oid + AND n.oid = c.relnamespace + ORDER BY a.attnum'; + } + + /** + * {@inheritDoc} + */ + public function getCreateDatabaseSQL($name) + { + return 'CREATE DATABASE ' . $name; + } + + /** + * Returns the SQL statement for disallowing new connections on the given database. + * + * This is useful to force DROP DATABASE operations which could fail because of active connections. + * + * @param string $database The name of the database to disallow new connections for. + * + * @return string + */ + public function getDisallowDatabaseConnectionsSQL($database) + { + return "UPDATE pg_database SET datallowconn = 'false' WHERE datname = " . $this->quoteStringLiteral($database); + } + + /** + * Returns the SQL statement for closing currently active connections on the given database. + * + * This is useful to force DROP DATABASE operations which could fail because of active connections. + * + * @param string $database The name of the database to close currently active connections for. + * + * @return string + */ + public function getCloseActiveDatabaseConnectionsSQL($database) + { + return 'SELECT pg_terminate_backend(procpid) FROM pg_stat_activity WHERE datname = ' + . $this->quoteStringLiteral($database); + } + + /** + * {@inheritDoc} + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = ''; + + if ($foreignKey->hasOption('match')) { + $query .= ' MATCH ' . $foreignKey->getOption('match'); + } + + $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + + if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) { + $query .= ' DEFERRABLE'; + } else { + $query .= ' NOT DEFERRABLE'; + } + + if (($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false) + || ($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false) + ) { + $query .= ' INITIALLY DEFERRED'; + } else { + $query .= ' INITIALLY IMMEDIATE'; + } + + return $query; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = []; + $commentsSQL = []; + $columnSql = []; + + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + + $comment = $this->getColumnComment($column); + + if ($comment === null || $comment === '') { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $diff->getName($this)->getQuotedName($this), + $column->getQuotedName($this), + $comment + ); + } + + foreach ($diff->removedColumns as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $query = 'DROP ' . $column->getQuotedName($this); + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + } + + foreach ($diff->changedColumns as $columnDiff) { + /** @var $columnDiff \Doctrine\DBAL\Schema\ColumnDiff */ + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + if ($this->isUnchangedBinaryColumn($columnDiff)) { + continue; + } + + $oldColumnName = $columnDiff->getOldColumnName()->getQuotedName($this); + $column = $columnDiff->column; + + if ($columnDiff->hasChanged('type') || $columnDiff->hasChanged('precision') || $columnDiff->hasChanged('scale') || $columnDiff->hasChanged('fixed')) { + $type = $column->getType(); + + // SERIAL/BIGSERIAL are not "real" types and we can't alter a column to that type + $columnDefinition = $column->toArray(); + $columnDefinition['autoincrement'] = false; + + // here was a server version check before, but DBAL API does not support this anymore. + $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSQLDeclaration($columnDefinition, $this); + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + } + + if ($columnDiff->hasChanged('default') || $this->typeChangeBreaksDefaultValue($columnDiff)) { + $defaultClause = $column->getDefault() === null + ? ' DROP DEFAULT' + : ' SET' . $this->getDefaultValueDeclarationSQL($column->toArray()); + $query = 'ALTER ' . $oldColumnName . $defaultClause; + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + } + + if ($columnDiff->hasChanged('notnull')) { + $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotnull() ? 'SET' : 'DROP') . ' NOT NULL'; + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + } + + if ($columnDiff->hasChanged('autoincrement')) { + if ($column->getAutoincrement()) { + // add autoincrement + $seqName = $this->getIdentitySequenceName($diff->name, $oldColumnName); + + $sql[] = 'CREATE SEQUENCE ' . $seqName; + $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ') FROM ' . $diff->getName($this)->getQuotedName($this) . '))'; + $query = 'ALTER ' . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')"; + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + } else { + // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have + $query = 'ALTER ' . $oldColumnName . ' DROP DEFAULT'; + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + } + } + + $newComment = $this->getColumnComment($column); + $oldComment = $this->getOldColumnComment($columnDiff); + + if ($columnDiff->hasChanged('comment') || ($columnDiff->fromColumn !== null && $oldComment !== $newComment)) { + $commentsSQL[] = $this->getCommentOnColumnSQL( + $diff->getName($this)->getQuotedName($this), + $column->getQuotedName($this), + $newComment + ); + } + + if (! $columnDiff->hasChanged('length')) { + continue; + } + + $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $column->getType()->getSQLDeclaration($column->toArray(), $this); + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . + ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . ' TO ' . $column->getQuotedName($this); + } + + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + $sql = array_merge($sql, $commentsSQL); + + if ($diff->newName !== false) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' RENAME TO ' . $diff->getNewName()->getQuotedName($this); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff) + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Checks whether a given column diff is a logically unchanged binary type column. + * + * Used to determine whether a column alteration for a binary type column can be skipped. + * Doctrine's {@link \Doctrine\DBAL\Types\BinaryType} and {@link \Doctrine\DBAL\Types\BlobType} + * are mapped to the same database column type on this platform as this platform + * does not have a native VARBINARY/BINARY column type. Therefore the {@link \Doctrine\DBAL\Schema\Comparator} + * might detect differences for binary type columns which do not have to be propagated + * to database as there actually is no difference at database level. + * + * @param ColumnDiff $columnDiff The column diff to check against. + * + * @return bool True if the given column diff is an unchanged binary type column, false otherwise. + */ + private function isUnchangedBinaryColumn(ColumnDiff $columnDiff) + { + $columnType = $columnDiff->column->getType(); + + if (! $columnType instanceof BinaryType && ! $columnType instanceof BlobType) { + return false; + } + + $fromColumn = $columnDiff->fromColumn instanceof Column ? $columnDiff->fromColumn : null; + + if ($fromColumn) { + $fromColumnType = $fromColumn->getType(); + + if (! $fromColumnType instanceof BinaryType && ! $fromColumnType instanceof BlobType) { + return false; + } + + return count(array_diff($columnDiff->changedProperties, ['type', 'length', 'fixed'])) === 0; + } + + if ($columnDiff->hasChanged('type')) { + return false; + } + + return count(array_diff($columnDiff->changedProperties, ['length', 'fixed'])) === 0; + } + + /** + * {@inheritdoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + if (strpos($tableName, '.') !== false) { + [$schema] = explode('.', $tableName); + $oldIndexName = $schema . '.' . $oldIndexName; + } + + return ['ALTER INDEX ' . $oldIndexName . ' RENAME TO ' . $index->getQuotedName($this)]; + } + + /** + * {@inheritdoc} + */ + public function getCommentOnColumnSQL($tableName, $columnName, $comment) + { + $tableName = new Identifier($tableName); + $columnName = new Identifier($columnName); + $comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment); + + return sprintf( + 'COMMENT ON COLUMN %s.%s IS %s', + $tableName->getQuotedName($this), + $columnName->getQuotedName($this), + $comment + ); + } + + /** + * {@inheritDoc} + */ + public function getCreateSequenceSQL(Sequence $sequence) + { + return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + ' MINVALUE ' . $sequence->getInitialValue() . + ' START ' . $sequence->getInitialValue() . + $this->getSequenceCacheSQL($sequence); + } + + /** + * {@inheritDoc} + */ + public function getAlterSequenceSQL(Sequence $sequence) + { + return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + $this->getSequenceCacheSQL($sequence); + } + + /** + * Cache definition for sequences + * + * @return string + */ + private function getSequenceCacheSQL(Sequence $sequence) + { + if ($sequence->getCache() > 1) { + return ' CACHE ' . $sequence->getCache(); + } + + return ''; + } + + /** + * {@inheritDoc} + */ + public function getDropSequenceSQL($sequence) + { + if ($sequence instanceof Sequence) { + $sequence = $sequence->getQuotedName($this); + } + + return 'DROP SEQUENCE ' . $sequence . ' CASCADE'; + } + + /** + * {@inheritDoc} + */ + public function getCreateSchemaSQL($schemaName) + { + return 'CREATE SCHEMA ' . $schemaName; + } + + /** + * {@inheritDoc} + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + return $this->getDropConstraintSQL($foreignKey, $table); + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = []) + { + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['primary']) && ! empty($options['primary'])) { + $keyColumns = array_unique(array_values($options['primary'])); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + $query = 'CREATE TABLE ' . $tableName . ' (' . $queryFields . ')'; + + $sql = [$query]; + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableName); + } + } + + if (isset($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return $sql; + } + + /** + * Converts a single boolean value. + * + * First converts the value to its native PHP boolean type + * and passes it to the given callback function to be reconverted + * into any custom representation. + * + * @param mixed $value The value to convert. + * @param callable $callback The callback function to use for converting the real boolean value. + * + * @return mixed + * + * @throws UnexpectedValueException + */ + private function convertSingleBooleanValue($value, $callback) + { + if ($value === null) { + return $callback(null); + } + + if (is_bool($value) || is_numeric($value)) { + return $callback($value ? true : false); + } + + if (! is_string($value)) { + return $callback(true); + } + + /** + * Better safe than sorry: http://php.net/in_array#106319 + */ + if (in_array(strtolower(trim($value)), $this->booleanLiterals['false'], true)) { + return $callback(false); + } + + if (in_array(strtolower(trim($value)), $this->booleanLiterals['true'], true)) { + return $callback(true); + } + + throw new UnexpectedValueException("Unrecognized boolean literal '${value}'"); + } + + /** + * Converts one or multiple boolean values. + * + * First converts the value(s) to their native PHP boolean type + * and passes them to the given callback function to be reconverted + * into any custom representation. + * + * @param mixed $item The value(s) to convert. + * @param callable $callback The callback function to use for converting the real boolean value(s). + * + * @return mixed + */ + private function doConvertBooleans($item, $callback) + { + if (is_array($item)) { + foreach ($item as $key => $value) { + $item[$key] = $this->convertSingleBooleanValue($value, $callback); + } + + return $item; + } + + return $this->convertSingleBooleanValue($item, $callback); + } + + /** + * {@inheritDoc} + * + * Postgres wants boolean values converted to the strings 'true'/'false'. + */ + public function convertBooleans($item) + { + if (! $this->useBooleanTrueFalseStrings) { + return parent::convertBooleans($item); + } + + return $this->doConvertBooleans( + $item, + static function ($boolean) { + if ($boolean === null) { + return 'NULL'; + } + + return $boolean === true ? 'true' : 'false'; + } + ); + } + + /** + * {@inheritDoc} + */ + public function convertBooleansToDatabaseValue($item) + { + if (! $this->useBooleanTrueFalseStrings) { + return parent::convertBooleansToDatabaseValue($item); + } + + return $this->doConvertBooleans( + $item, + static function ($boolean) { + return $boolean === null ? null : (int) $boolean; + } + ); + } + + /** + * {@inheritDoc} + */ + public function convertFromBoolean($item) + { + if (in_array(strtolower($item), $this->booleanLiterals['false'], true)) { + return false; + } + + return parent::convertFromBoolean($item); + } + + /** + * {@inheritDoc} + */ + public function getSequenceNextValSQL($sequenceName) + { + return "SELECT NEXTVAL('" . $sequenceName . "')"; + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' + . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'BOOLEAN'; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + if (! empty($field['autoincrement'])) { + return 'SERIAL'; + } + + return 'INT'; + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + if (! empty($field['autoincrement'])) { + return 'BIGSERIAL'; + } + + return 'BIGINT'; + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'SMALLINT'; + } + + /** + * {@inheritDoc} + */ + public function getGuidTypeDeclarationSQL(array $field) + { + return 'UUID'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP(0) WITHOUT TIME ZONE'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP(0) WITH TIME ZONE'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME(0) WITHOUT TIME ZONE'; + } + + /** + * {@inheritDoc} + * + * @deprecated Use application-generated UUIDs instead + */ + public function getGuidExpression() + { + return 'UUID_GENERATE_V4()'; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + return ''; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** + * {@inheritdoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return 'BYTEA'; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'TEXT'; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return 'postgresql'; + } + + /** + * {@inheritDoc} + * + * PostgreSQL returns all column names in SQL result sets in lowercase. + */ + public function getSQLResultCasing($column) + { + return strtolower($column); + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:sO'; + } + + /** + * {@inheritDoc} + */ + public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) + { + return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)'; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + $sql = 'TRUNCATE ' . $tableIdentifier->getQuotedName($this); + + if ($cascade) { + $sql .= ' CASCADE'; + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + public function getReadLockSQL() + { + return 'FOR SHARE'; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'smallint' => 'smallint', + 'int2' => 'smallint', + 'serial' => 'integer', + 'serial4' => 'integer', + 'int' => 'integer', + 'int4' => 'integer', + 'integer' => 'integer', + 'bigserial' => 'bigint', + 'serial8' => 'bigint', + 'bigint' => 'bigint', + 'int8' => 'bigint', + 'bool' => 'boolean', + 'boolean' => 'boolean', + 'text' => 'text', + 'tsvector' => 'text', + 'varchar' => 'string', + 'interval' => 'string', + '_varchar' => 'string', + 'char' => 'string', + 'bpchar' => 'string', + 'inet' => 'string', + 'date' => 'date', + 'datetime' => 'datetime', + 'timestamp' => 'datetime', + 'timestamptz' => 'datetimetz', + 'time' => 'time', + 'timetz' => 'time', + 'float' => 'float', + 'float4' => 'float', + 'float8' => 'float', + 'double' => 'float', + 'double precision' => 'float', + 'real' => 'float', + 'decimal' => 'decimal', + 'money' => 'decimal', + 'numeric' => 'decimal', + 'year' => 'date', + 'uuid' => 'guid', + 'bytea' => 'blob', + ]; + } + + /** + * {@inheritDoc} + */ + public function getVarcharMaxLength() + { + return 65535; + } + + /** + * {@inheritdoc} + */ + public function getBinaryMaxLength() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function getBinaryDefaultLength() + { + return 0; + } + + /** + * {@inheritDoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\PostgreSQLKeywords::class; + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'BYTEA'; + } + + /** + * {@inheritdoc} + */ + public function getDefaultValueDeclarationSQL($field) + { + if ($this->isSerialField($field)) { + return ''; + } + + return parent::getDefaultValueDeclarationSQL($field); + } + + /** + * @param mixed[] $field + */ + private function isSerialField(array $field) : bool + { + return $field['autoincrement'] ?? false === true && isset($field['type']) + && $this->isNumericType($field['type']); + } + + /** + * Check whether the type of a column is changed in a way that invalidates the default value for the column + */ + private function typeChangeBreaksDefaultValue(ColumnDiff $columnDiff) : bool + { + if (! $columnDiff->fromColumn) { + return $columnDiff->hasChanged('type'); + } + + $oldTypeIsNumeric = $this->isNumericType($columnDiff->fromColumn->getType()); + $newTypeIsNumeric = $this->isNumericType($columnDiff->column->getType()); + + // default should not be changed when switching between numeric types and the default comes from a sequence + return $columnDiff->hasChanged('type') + && ! ($oldTypeIsNumeric && $newTypeIsNumeric && $columnDiff->column->getAutoincrement()); + } + + private function isNumericType(Type $type) : bool + { + return $type instanceof IntegerType || $type instanceof BigIntType; + } + + private function getOldColumnComment(ColumnDiff $columnDiff) : ?string + { + return $columnDiff->fromColumn ? $this->getColumnComment($columnDiff->fromColumn) : null; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere11Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere11Platform.php new file mode 100644 index 000000000..a46ae9352 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere11Platform.php @@ -0,0 +1,26 @@ +getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + ' START WITH ' . $sequence->getInitialValue() . + ' MINVALUE ' . $sequence->getInitialValue(); + } + + /** + * {@inheritdoc} + */ + public function getAlterSequenceSQL(Sequence $sequence) + { + return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize(); + } + + /** + * {@inheritdoc} + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:s.uP'; + } + + /** + * {@inheritdoc} + */ + public function getDateTimeTzTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIMESTAMP WITH TIME ZONE'; + } + + /** + * {@inheritdoc} + */ + public function getDropSequenceSQL($sequence) + { + if ($sequence instanceof Sequence) { + $sequence = $sequence->getQuotedName($this); + } + + return 'DROP SEQUENCE ' . $sequence; + } + + /** + * {@inheritdoc} + */ + public function getListSequencesSQL($database) + { + return 'SELECT sequence_name, increment_by, start_with, min_value FROM SYS.SYSSEQUENCE'; + } + + /** + * {@inheritdoc} + */ + public function getSequenceNextValSQL($sequenceName) + { + return 'SELECT ' . $sequenceName . '.NEXTVAL'; + } + + /** + * {@inheritdoc} + */ + public function supportsSequences() + { + return true; + } + + /** + * {@inheritdoc} + */ + protected function getAdvancedIndexOptionsSQL(Index $index) + { + if (! $index->isPrimary() && $index->isUnique() && $index->hasFlag('with_nulls_not_distinct')) { + return ' WITH NULLS NOT DISTINCT' . parent::getAdvancedIndexOptionsSQL($index); + } + + return parent::getAdvancedIndexOptionsSQL($index); + } + + /** + * {@inheritdoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\SQLAnywhere12Keywords::class; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + parent::initializeDoctrineTypeMappings(); + $this->doctrineTypeMapping['timestamp with time zone'] = 'datetime'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere16Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere16Platform.php new file mode 100644 index 000000000..35d4238e4 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywhere16Platform.php @@ -0,0 +1,39 @@ +hasFlag('with_nulls_distinct') && $index->hasFlag('with_nulls_not_distinct')) { + throw new UnexpectedValueException( + 'An Index can either have a "with_nulls_distinct" or "with_nulls_not_distinct" flag but not both.' + ); + } + + if (! $index->isPrimary() && $index->isUnique() && $index->hasFlag('with_nulls_distinct')) { + return ' WITH NULLS DISTINCT' . parent::getAdvancedIndexOptionsSQL($index); + } + + return parent::getAdvancedIndexOptionsSQL($index); + } + + /** + * {@inheritdoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\SQLAnywhere16Keywords::class; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php new file mode 100644 index 000000000..ec3ef9334 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAnywherePlatform.php @@ -0,0 +1,1501 @@ +getMaxIdentifierLength(); + + if (strlen($schemaElementName) > $maxIdentifierLength) { + return substr($schemaElementName, 0, $maxIdentifierLength); + } + + return $schemaElementName; + } + + /** + * {@inheritdoc} + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = ''; + + if ($foreignKey->hasOption('match')) { + $query = ' MATCH ' . $this->getForeignKeyMatchClauseSQL($foreignKey->getOption('match')); + } + + $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + + if ($foreignKey->hasOption('check_on_commit') && (bool) $foreignKey->getOption('check_on_commit')) { + $query .= ' CHECK ON COMMIT'; + } + + if ($foreignKey->hasOption('clustered') && (bool) $foreignKey->getOption('clustered')) { + $query .= ' CLUSTERED'; + } + + if ($foreignKey->hasOption('for_olap_workload') && (bool) $foreignKey->getOption('for_olap_workload')) { + $query .= ' FOR OLAP WORKLOAD'; + } + + return $query; + } + + /** + * {@inheritdoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = []; + $columnSql = []; + $commentsSQL = []; + $tableSql = []; + $alterClauses = []; + + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $alterClauses[] = $this->getAlterTableAddColumnClause($column); + + $comment = $this->getColumnComment($column); + + if ($comment === null || $comment === '') { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $diff->getName($this)->getQuotedName($this), + $column->getQuotedName($this), + $comment + ); + } + + foreach ($diff->removedColumns as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $alterClauses[] = $this->getAlterTableRemoveColumnClause($column); + } + + foreach ($diff->changedColumns as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $alterClause = $this->getAlterTableChangeColumnClause($columnDiff); + + if ($alterClause !== null) { + $alterClauses[] = $alterClause; + } + + if (! $columnDiff->hasChanged('comment')) { + continue; + } + + $column = $columnDiff->column; + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $diff->getName($this)->getQuotedName($this), + $column->getQuotedName($this), + $this->getColumnComment($column) + ); + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' . + $this->getAlterTableRenameColumnClause($oldColumnName, $column); + } + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + if (! empty($alterClauses)) { + $sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' . implode(', ', $alterClauses); + } + + $sql = array_merge($sql, $commentsSQL); + + if ($diff->newName !== false) { + $sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' . + $this->getAlterTableRenameTableClause($diff->getNewName()); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff) + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Returns the SQL clause for creating a column in a table alteration. + * + * @param Column $column The column to add. + * + * @return string + */ + protected function getAlterTableAddColumnClause(Column $column) + { + return 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + } + + /** + * Returns the SQL clause for altering a table. + * + * @param Identifier $tableName The quoted name of the table to alter. + * + * @return string + */ + protected function getAlterTableClause(Identifier $tableName) + { + return 'ALTER TABLE ' . $tableName->getQuotedName($this); + } + + /** + * Returns the SQL clause for dropping a column in a table alteration. + * + * @param Column $column The column to drop. + * + * @return string + */ + protected function getAlterTableRemoveColumnClause(Column $column) + { + return 'DROP ' . $column->getQuotedName($this); + } + + /** + * Returns the SQL clause for renaming a column in a table alteration. + * + * @param string $oldColumnName The quoted name of the column to rename. + * @param Column $column The column to rename to. + * + * @return string + */ + protected function getAlterTableRenameColumnClause($oldColumnName, Column $column) + { + $oldColumnName = new Identifier($oldColumnName); + + return 'RENAME ' . $oldColumnName->getQuotedName($this) . ' TO ' . $column->getQuotedName($this); + } + + /** + * Returns the SQL clause for renaming a table in a table alteration. + * + * @param Identifier $newTableName The quoted name of the table to rename to. + * + * @return string + */ + protected function getAlterTableRenameTableClause(Identifier $newTableName) + { + return 'RENAME ' . $newTableName->getQuotedName($this); + } + + /** + * Returns the SQL clause for altering a column in a table alteration. + * + * This method returns null in case that only the column comment has changed. + * Changes in column comments have to be handled differently. + * + * @param ColumnDiff $columnDiff The diff of the column to alter. + * + * @return string|null + */ + protected function getAlterTableChangeColumnClause(ColumnDiff $columnDiff) + { + $column = $columnDiff->column; + + // Do not return alter clause if only comment has changed. + if (! ($columnDiff->hasChanged('comment') && count($columnDiff->changedProperties) === 1)) { + $columnAlterationClause = 'ALTER ' . + $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + + if ($columnDiff->hasChanged('default') && $column->getDefault() === null) { + $columnAlterationClause .= ', ALTER ' . $column->getQuotedName($this) . ' DROP DEFAULT'; + } + + return $columnAlterationClause; + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function getBigIntTypeDeclarationSQL(array $columnDef) + { + $columnDef['integer_type'] = 'BIGINT'; + + return $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * {@inheritdoc} + */ + public function getBinaryDefaultLength() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function getBinaryMaxLength() + { + return 32767; + } + + /** + * {@inheritdoc} + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'LONG BINARY'; + } + + /** + * {@inheritdoc} + * + * BIT type columns require an explicit NULL declaration + * in SQL Anywhere if they shall be nullable. + * Otherwise by just omitting the NOT NULL clause, + * SQL Anywhere will declare them NOT NULL nonetheless. + */ + public function getBooleanTypeDeclarationSQL(array $columnDef) + { + $nullClause = isset($columnDef['notnull']) && (bool) $columnDef['notnull'] === false ? ' NULL' : ''; + + return 'BIT' . $nullClause; + } + + /** + * {@inheritdoc} + */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'TEXT'; + } + + /** + * {@inheritdoc} + */ + public function getCommentOnColumnSQL($tableName, $columnName, $comment) + { + $tableName = new Identifier($tableName); + $columnName = new Identifier($columnName); + $comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment); + + return sprintf( + 'COMMENT ON COLUMN %s.%s IS %s', + $tableName->getQuotedName($this), + $columnName->getQuotedName($this), + $comment + ); + } + + /** + * {@inheritdoc} + */ + public function getConcatExpression() + { + return 'STRING(' . implode(', ', (array) func_get_args()) . ')'; + } + + /** + * {@inheritdoc} + */ + public function getCreateConstraintSQL(Constraint $constraint, $table) + { + if ($constraint instanceof ForeignKeyConstraint) { + return $this->getCreateForeignKeySQL($constraint, $table); + } + + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . + ' ADD ' . $this->getTableConstraintDeclarationSQL($constraint, $constraint->getQuotedName($this)); + } + + /** + * {@inheritdoc} + */ + public function getCreateDatabaseSQL($database) + { + $database = new Identifier($database); + + return "CREATE DATABASE '" . $database->getName() . "'"; + } + + /** + * {@inheritdoc} + * + * Appends SQL Anywhere specific flags if given. + */ + public function getCreateIndexSQL(Index $index, $table) + { + return parent::getCreateIndexSQL($index, $table) . $this->getAdvancedIndexOptionsSQL($index); + } + + /** + * {@inheritdoc} + */ + public function getCreatePrimaryKeySQL(Index $index, $table) + { + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' ADD ' . $this->getPrimaryKeyDeclarationSQL($index); + } + + /** + * {@inheritdoc} + */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'CREATE ' . $this->getTemporaryTableSQL() . ' TABLE'; + } + + /** + * {@inheritdoc} + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * {@inheritdoc} + */ + public function getCurrentDateSQL() + { + return 'CURRENT DATE'; + } + + /** + * {@inheritdoc} + */ + public function getCurrentTimeSQL() + { + return 'CURRENT TIME'; + } + + /** + * {@inheritdoc} + */ + public function getCurrentTimestampSQL() + { + return 'CURRENT TIMESTAMP'; + } + + /** + * {@inheritdoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + $factorClause = ''; + + if ($operator === '-') { + $factorClause = '-1 * '; + } + + return 'DATEADD(' . $unit . ', ' . $factorClause . $interval . ', ' . $date . ')'; + } + + /** + * {@inheritdoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return 'DATEDIFF(day, ' . $date2 . ', ' . $date1 . ')'; + } + + /** + * {@inheritdoc} + */ + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:s.u'; + } + + /** + * {@inheritdoc} + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * {@inheritdoc} + */ + public function getDateTimeTzFormatString() + { + return $this->getDateTimeFormatString(); + } + + /** + * {@inheritdoc} + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * {@inheritdoc} + */ + public function getDefaultTransactionIsolationLevel() + { + return TransactionIsolationLevel::READ_UNCOMMITTED; + } + + /** + * {@inheritdoc} + */ + public function getDropDatabaseSQL($database) + { + $database = new Identifier($database); + + return "DROP DATABASE '" . $database->getName() . "'"; + } + + /** + * {@inheritdoc} + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index) { + $index = $index->getQuotedName($this); + } + + if (! is_string($index)) { + throw new InvalidArgumentException( + 'SQLAnywherePlatform::getDropIndexSQL() expects $index parameter to be string or ' . Index::class . '.' + ); + } + + if (! isset($table)) { + return 'DROP INDEX ' . $index; + } + + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + + if (! is_string($table)) { + throw new InvalidArgumentException( + 'SQLAnywherePlatform::getDropIndexSQL() expects $table parameter to be string or ' . Index::class . '.' + ); + } + + return 'DROP INDEX ' . $table . '.' . $index; + } + + /** + * {@inheritdoc} + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * {@inheritdoc} + */ + public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + $sql = ''; + $foreignKeyName = $foreignKey->getName(); + $localColumns = $foreignKey->getQuotedLocalColumns($this); + $foreignColumns = $foreignKey->getQuotedForeignColumns($this); + $foreignTableName = $foreignKey->getQuotedForeignTableName($this); + + if (! empty($foreignKeyName)) { + $sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' '; + } + + if (empty($localColumns)) { + throw new InvalidArgumentException("Incomplete definition. 'local' required."); + } + + if (empty($foreignColumns)) { + throw new InvalidArgumentException("Incomplete definition. 'foreign' required."); + } + + if (empty($foreignTableName)) { + throw new InvalidArgumentException("Incomplete definition. 'foreignTable' required."); + } + + if ($foreignKey->hasOption('notnull') && (bool) $foreignKey->getOption('notnull')) { + $sql .= 'NOT NULL '; + } + + return $sql . + 'FOREIGN KEY (' . $this->getIndexFieldDeclarationListSQL($localColumns) . ') ' . + 'REFERENCES ' . $foreignKey->getQuotedForeignTableName($this) . + ' (' . $this->getIndexFieldDeclarationListSQL($foreignColumns) . ')'; + } + + /** + * Returns foreign key MATCH clause for given type. + * + * @param int $type The foreign key match type + * + * @return string + * + * @throws InvalidArgumentException If unknown match type given. + */ + public function getForeignKeyMatchClauseSQL($type) + { + switch ((int) $type) { + case self::FOREIGN_KEY_MATCH_SIMPLE: + return 'SIMPLE'; + break; + case self::FOREIGN_KEY_MATCH_FULL: + return 'FULL'; + break; + case self::FOREIGN_KEY_MATCH_SIMPLE_UNIQUE: + return 'UNIQUE SIMPLE'; + break; + case self::FOREIGN_KEY_MATCH_FULL_UNIQUE: + return 'UNIQUE FULL'; + default: + throw new InvalidArgumentException('Invalid foreign key match type: ' . $type); + } + } + + /** + * {@inheritdoc} + */ + public function getForeignKeyReferentialActionSQL($action) + { + // NO ACTION is not supported, therefore falling back to RESTRICT. + if (strtoupper($action) === 'NO ACTION') { + return 'RESTRICT'; + } + + return parent::getForeignKeyReferentialActionSQL($action); + } + + /** + * {@inheritdoc} + */ + public function getForUpdateSQL() + { + return ''; + } + + /** + * {@inheritdoc} + * + * @deprecated Use application-generated UUIDs instead + */ + public function getGuidExpression() + { + return 'NEWID()'; + } + + /** + * {@inheritdoc} + */ + public function getGuidTypeDeclarationSQL(array $field) + { + return 'UNIQUEIDENTIFIER'; + } + + /** + * {@inheritdoc} + */ + public function getIndexDeclarationSQL($name, Index $index) + { + // Index declaration in statements like CREATE TABLE is not supported. + throw DBALException::notSupported(__METHOD__); + } + + /** + * {@inheritdoc} + */ + public function getIntegerTypeDeclarationSQL(array $columnDef) + { + $columnDef['integer_type'] = 'INT'; + + return $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * {@inheritdoc} + */ + public function getListDatabasesSQL() + { + return 'SELECT db_name(number) AS name FROM sa_db_list()'; + } + + /** + * {@inheritdoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + $user = 'USER_NAME()'; + + if (strpos($table, '.') !== false) { + [$user, $table] = explode('.', $table); + $user = $this->quoteStringLiteral($user); + } + + return sprintf( + <<<'SQL' +SELECT col.column_name, + COALESCE(def.user_type_name, def.domain_name) AS 'type', + def.declared_width AS 'length', + def.scale, + CHARINDEX('unsigned', def.domain_name) AS 'unsigned', + IF col.nulls = 'Y' THEN 0 ELSE 1 ENDIF AS 'notnull', + col."default", + def.is_autoincrement AS 'autoincrement', + rem.remarks AS 'comment' +FROM sa_describe_query('SELECT * FROM "%s"') AS def +JOIN SYS.SYSTABCOL AS col +ON col.table_id = def.base_table_id AND col.column_id = def.base_column_id +LEFT JOIN SYS.SYSREMARK AS rem +ON col.object_id = rem.object_id +WHERE def.base_owner_name = %s +ORDER BY def.base_column_id ASC +SQL + , + $table, + $user + ); + } + + /** + * {@inheritdoc} + * + * @todo Where is this used? Which information should be retrieved? + */ + public function getListTableConstraintsSQL($table) + { + $user = ''; + + if (strpos($table, '.') !== false) { + [$user, $table] = explode('.', $table); + $user = $this->quoteStringLiteral($user); + $table = $this->quoteStringLiteral($table); + } else { + $table = $this->quoteStringLiteral($table); + } + + return sprintf( + <<<'SQL' +SELECT con.* +FROM SYS.SYSCONSTRAINT AS con +JOIN SYS.SYSTAB AS tab ON con.table_object_id = tab.object_id +WHERE tab.table_name = %s +AND tab.creator = USER_ID(%s) +SQL + , + $table, + $user + ); + } + + /** + * {@inheritdoc} + */ + public function getListTableForeignKeysSQL($table) + { + $user = ''; + + if (strpos($table, '.') !== false) { + [$user, $table] = explode('.', $table); + $user = $this->quoteStringLiteral($user); + $table = $this->quoteStringLiteral($table); + } else { + $table = $this->quoteStringLiteral($table); + } + + return sprintf( + <<<'SQL' +SELECT fcol.column_name AS local_column, + ptbl.table_name AS foreign_table, + pcol.column_name AS foreign_column, + idx.index_name, + IF fk.nulls = 'N' + THEN 1 + ELSE NULL + ENDIF AS notnull, + CASE ut.referential_action + WHEN 'C' THEN 'CASCADE' + WHEN 'D' THEN 'SET DEFAULT' + WHEN 'N' THEN 'SET NULL' + WHEN 'R' THEN 'RESTRICT' + ELSE NULL + END AS on_update, + CASE dt.referential_action + WHEN 'C' THEN 'CASCADE' + WHEN 'D' THEN 'SET DEFAULT' + WHEN 'N' THEN 'SET NULL' + WHEN 'R' THEN 'RESTRICT' + ELSE NULL + END AS on_delete, + IF fk.check_on_commit = 'Y' + THEN 1 + ELSE NULL + ENDIF AS check_on_commit, -- check_on_commit flag + IF ftbl.clustered_index_id = idx.index_id + THEN 1 + ELSE NULL + ENDIF AS 'clustered', -- clustered flag + IF fk.match_type = 0 + THEN NULL + ELSE fk.match_type + ENDIF AS 'match', -- match option + IF pidx.max_key_distance = 1 + THEN 1 + ELSE NULL + ENDIF AS for_olap_workload -- for_olap_workload flag +FROM SYS.SYSFKEY AS fk +JOIN SYS.SYSIDX AS idx +ON fk.foreign_table_id = idx.table_id +AND fk.foreign_index_id = idx.index_id +JOIN SYS.SYSPHYSIDX pidx +ON idx.table_id = pidx.table_id +AND idx.phys_index_id = pidx.phys_index_id +JOIN SYS.SYSTAB AS ptbl +ON fk.primary_table_id = ptbl.table_id +JOIN SYS.SYSTAB AS ftbl +ON fk.foreign_table_id = ftbl.table_id +JOIN SYS.SYSIDXCOL AS idxcol +ON idx.table_id = idxcol.table_id +AND idx.index_id = idxcol.index_id +JOIN SYS.SYSTABCOL AS pcol +ON ptbl.table_id = pcol.table_id +AND idxcol.primary_column_id = pcol.column_id +JOIN SYS.SYSTABCOL AS fcol +ON ftbl.table_id = fcol.table_id +AND idxcol.column_id = fcol.column_id +LEFT JOIN SYS.SYSTRIGGER ut +ON fk.foreign_table_id = ut.foreign_table_id +AND fk.foreign_index_id = ut.foreign_key_id +AND ut.event = 'C' +LEFT JOIN SYS.SYSTRIGGER dt +ON fk.foreign_table_id = dt.foreign_table_id +AND fk.foreign_index_id = dt.foreign_key_id +AND dt.event = 'D' +WHERE ftbl.table_name = %s +AND ftbl.creator = USER_ID(%s) +ORDER BY fk.foreign_index_id ASC, idxcol.sequence ASC +SQL + , + $table, + $user + ); + } + + /** + * {@inheritdoc} + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + $user = ''; + + if (strpos($table, '.') !== false) { + [$user, $table] = explode('.', $table); + $user = $this->quoteStringLiteral($user); + $table = $this->quoteStringLiteral($table); + } else { + $table = $this->quoteStringLiteral($table); + } + + return sprintf( + <<<'SQL' +SELECT idx.index_name AS key_name, + IF idx.index_category = 1 + THEN 1 + ELSE 0 + ENDIF AS 'primary', + col.column_name, + IF idx."unique" IN(1, 2, 5) + THEN 0 + ELSE 1 + ENDIF AS non_unique, + IF tbl.clustered_index_id = idx.index_id + THEN 1 + ELSE NULL + ENDIF AS 'clustered', -- clustered flag + IF idx."unique" = 5 + THEN 1 + ELSE NULL + ENDIF AS with_nulls_not_distinct, -- with_nulls_not_distinct flag + IF pidx.max_key_distance = 1 + THEN 1 + ELSE NULL + ENDIF AS for_olap_workload -- for_olap_workload flag +FROM SYS.SYSIDX AS idx +JOIN SYS.SYSPHYSIDX pidx +ON idx.table_id = pidx.table_id +AND idx.phys_index_id = pidx.phys_index_id +JOIN SYS.SYSIDXCOL AS idxcol +ON idx.table_id = idxcol.table_id AND idx.index_id = idxcol.index_id +JOIN SYS.SYSTABCOL AS col +ON idxcol.table_id = col.table_id AND idxcol.column_id = col.column_id +JOIN SYS.SYSTAB AS tbl +ON idx.table_id = tbl.table_id +WHERE tbl.table_name = %s +AND tbl.creator = USER_ID(%s) +AND idx.index_category != 2 -- exclude indexes implicitly created by foreign key constraints +ORDER BY idx.index_id ASC, idxcol.sequence ASC +SQL + , + $table, + $user + ); + } + + /** + * {@inheritdoc} + */ + public function getListTablesSQL() + { + return "SELECT tbl.table_name + FROM SYS.SYSTAB AS tbl + JOIN SYS.SYSUSER AS usr ON tbl.creator = usr.user_id + JOIN dbo.SYSOBJECTS AS obj ON tbl.object_id = obj.id + WHERE tbl.table_type IN(1, 3) -- 'BASE', 'GBL TEMP' + AND usr.user_name NOT IN('SYS', 'dbo', 'rs_systabgroup') -- exclude system users + AND obj.type = 'U' -- user created tables only + ORDER BY tbl.table_name ASC"; + } + + /** + * {@inheritdoc} + * + * @todo Where is this used? Which information should be retrieved? + */ + public function getListUsersSQL() + { + return 'SELECT * FROM SYS.SYSUSER ORDER BY user_name ASC'; + } + + /** + * {@inheritdoc} + */ + public function getListViewsSQL($database) + { + return "SELECT tbl.table_name, v.view_def + FROM SYS.SYSVIEW v + JOIN SYS.SYSTAB tbl ON v.view_object_id = tbl.object_id + JOIN SYS.SYSUSER usr ON tbl.creator = usr.user_id + JOIN dbo.SYSOBJECTS obj ON tbl.object_id = obj.id + WHERE usr.user_name NOT IN('SYS', 'dbo', 'rs_systabgroup') -- exclude system users + ORDER BY tbl.table_name ASC"; + } + + /** + * {@inheritdoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos === false) { + return 'LOCATE(' . $str . ', ' . $substr . ')'; + } + + return 'LOCATE(' . $str . ', ' . $substr . ', ' . $startPos . ')'; + } + + /** + * {@inheritdoc} + */ + public function getMaxIdentifierLength() + { + return 128; + } + + /** + * {@inheritdoc} + */ + public function getMd5Expression($column) + { + return 'HASH(' . $column . ", 'MD5')"; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'sqlanywhere'; + } + + /** + * Obtain DBMS specific SQL code portion needed to set a primary key + * declaration to be used in statements like ALTER TABLE. + * + * @param Index $index Index definition + * @param string $name Name of the primary key + * + * @return string DBMS specific SQL code portion needed to set a primary key + * + * @throws InvalidArgumentException If the given index is not a primary key. + */ + public function getPrimaryKeyDeclarationSQL(Index $index, $name = null) + { + if (! $index->isPrimary()) { + throw new InvalidArgumentException( + 'Can only create primary key declarations with getPrimaryKeyDeclarationSQL()' + ); + } + + return $this->getTableConstraintDeclarationSQL($index, $name); + } + + /** + * {@inheritdoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET TEMPORARY OPTION isolation_level = ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritdoc} + */ + public function getSmallIntTypeDeclarationSQL(array $columnDef) + { + $columnDef['integer_type'] = 'SMALLINT'; + + return $this->_getCommonIntegerTypeDeclarationSQL($columnDef); + } + + /** + * Returns the SQL statement for starting an existing database. + * + * In SQL Anywhere you can start and stop databases on a + * database server instance. + * This is a required statement after having created a new database + * as it has to be explicitly started to be usable. + * SQL Anywhere does not automatically start a database after creation! + * + * @param string $database Name of the database to start. + * + * @return string + */ + public function getStartDatabaseSQL($database) + { + $database = new Identifier($database); + + return "START DATABASE '" . $database->getName() . "' AUTOSTOP OFF"; + } + + /** + * Returns the SQL statement for stopping a running database. + * + * In SQL Anywhere you can start and stop databases on a + * database server instance. + * This is a required statement before dropping an existing database + * as it has to be explicitly stopped before it can be dropped. + * + * @param string $database Name of the database to stop. + * + * @return string + */ + public function getStopDatabaseSQL($database) + { + $database = new Identifier($database); + + return 'STOP DATABASE "' . $database->getName() . '" UNCONDITIONALLY'; + } + + /** + * {@inheritdoc} + */ + public function getSubstringExpression($value, $from, $length = null) + { + if ($length === null) { + return 'SUBSTRING(' . $value . ', ' . $from . ')'; + } + + return 'SUBSTRING(' . $value . ', ' . $from . ', ' . $length . ')'; + } + + /** + * {@inheritdoc} + */ + public function getTemporaryTableSQL() + { + return 'GLOBAL TEMPORARY'; + } + + /** + * {@inheritdoc} + */ + public function getTimeFormatString() + { + return 'H:i:s.u'; + } + + /** + * {@inheritdoc} + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME'; + } + + /** + * {@inheritdoc} + */ + public function getTrimExpression($str, $pos = TrimMode::UNSPECIFIED, $char = false) + { + if (! $char) { + switch ($pos) { + case TrimMode::LEADING: + return $this->getLtrimExpression($str); + case TrimMode::TRAILING: + return $this->getRtrimExpression($str); + default: + return 'TRIM(' . $str . ')'; + } + } + + $pattern = "'%[^' + " . $char . " + ']%'"; + + switch ($pos) { + case TrimMode::LEADING: + return 'SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))'; + case TrimMode::TRAILING: + return 'REVERSE(SUBSTR(REVERSE(' . $str . '), PATINDEX(' . $pattern . ', REVERSE(' . $str . '))))'; + default: + return 'REVERSE(SUBSTR(REVERSE(SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))), ' . + 'PATINDEX(' . $pattern . ', REVERSE(SUBSTR(' . $str . ', PATINDEX(' . $pattern . ', ' . $str . '))))))'; + } + } + + /** + * {@inheritdoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); + } + + /** + * {@inheritdoc} + */ + public function getUniqueConstraintDeclarationSQL($name, Index $index) + { + if ($index->isPrimary()) { + throw new InvalidArgumentException( + 'Cannot create primary key constraint declarations with getUniqueConstraintDeclarationSQL().' + ); + } + + if (! $index->isUnique()) { + throw new InvalidArgumentException( + 'Can only create unique constraint declarations, no common index declarations with ' . + 'getUniqueConstraintDeclarationSQL().' + ); + } + + return $this->getTableConstraintDeclarationSQL($index, $name); + } + + /** + * {@inheritdoc} + */ + public function getVarcharDefaultLength() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function getVarcharMaxLength() + { + return 32767; + } + + /** + * {@inheritdoc} + */ + public function hasNativeGuidType() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function supportsCommentOnStatement() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritdoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + $unsigned = ! empty($columnDef['unsigned']) ? 'UNSIGNED ' : ''; + $autoincrement = ! empty($columnDef['autoincrement']) ? ' IDENTITY' : ''; + + return $unsigned . $columnDef['integer_type'] . $autoincrement; + } + + /** + * {@inheritdoc} + */ + protected function _getCreateTableSQL($tableName, array $columns, array $options = []) + { + $columnListSql = $this->getColumnDeclarationListSQL($columns); + $indexSql = []; + + if (! empty($options['uniqueConstraints'])) { + foreach ((array) $options['uniqueConstraints'] as $name => $definition) { + $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); + } + } + + if (! empty($options['indexes'])) { + /** @var Index $index */ + foreach ((array) $options['indexes'] as $index) { + $indexSql[] = $this->getCreateIndexSQL($index, $tableName); + } + } + + if (! empty($options['primary'])) { + $flags = ''; + + if (isset($options['primary_index']) && $options['primary_index']->hasFlag('clustered')) { + $flags = ' CLUSTERED '; + } + + $columnListSql .= ', PRIMARY KEY' . $flags . ' (' . implode(', ', array_unique(array_values((array) $options['primary']))) . ')'; + } + + if (! empty($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] as $definition) { + $columnListSql .= ', ' . $this->getForeignKeyDeclarationSQL($definition); + } + } + + $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; + $check = $this->getCheckDeclarationSQL($columns); + + if (! empty($check)) { + $query .= ', ' . $check; + } + + $query .= ')'; + + return array_merge([$query], $indexSql); + } + + /** + * {@inheritdoc} + */ + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case TransactionIsolationLevel::READ_UNCOMMITTED: + return 0; + case TransactionIsolationLevel::READ_COMMITTED: + return 1; + case TransactionIsolationLevel::REPEATABLE_READ: + return 2; + case TransactionIsolationLevel::SERIALIZABLE: + return 3; + default: + throw new InvalidArgumentException('Invalid isolation level:' . $level); + } + } + + /** + * {@inheritdoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + $limitOffsetClause = $this->getTopClauseSQL($limit, $offset); + + return $limitOffsetClause === '' + ? $query + : preg_replace('/^\s*(SELECT\s+(DISTINCT\s+)?)/i', '\1' . $limitOffsetClause . ' ', $query); + } + + private function getTopClauseSQL(?int $limit, ?int $offset) : string + { + if ($offset > 0) { + return sprintf('TOP %s START AT %d', $limit ?? 'ALL', $offset + 1); + } + + return $limit === null ? '' : 'TOP ' . $limit; + } + + /** + * Return the INDEX query section dealing with non-standard + * SQL Anywhere options. + * + * @param Index $index Index definition + * + * @return string + */ + protected function getAdvancedIndexOptionsSQL(Index $index) + { + $sql = ''; + + if (! $index->isPrimary() && $index->hasFlag('for_olap_workload')) { + $sql .= ' FOR OLAP WORKLOAD'; + } + + return $sql; + } + + /** + * {@inheritdoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed + ? 'BINARY(' . ($length ?: $this->getBinaryDefaultLength()) . ')' + : 'VARBINARY(' . ($length ?: $this->getBinaryDefaultLength()) . ')'; + } + + /** + * Returns the SQL snippet for creating a table constraint. + * + * @param Constraint $constraint The table constraint to create the SQL snippet for. + * @param string|null $name The table constraint name to use if any. + * + * @return string + * + * @throws InvalidArgumentException If the given table constraint type is not supported by this method. + */ + protected function getTableConstraintDeclarationSQL(Constraint $constraint, $name = null) + { + if ($constraint instanceof ForeignKeyConstraint) { + return $this->getForeignKeyDeclarationSQL($constraint); + } + + if (! $constraint instanceof Index) { + throw new InvalidArgumentException('Unsupported constraint type: ' . get_class($constraint)); + } + + if (! $constraint->isPrimary() && ! $constraint->isUnique()) { + throw new InvalidArgumentException( + 'Can only create primary, unique or foreign key constraint declarations, no common index declarations ' . + 'with getTableConstraintDeclarationSQL().' + ); + } + + $constraintColumns = $constraint->getQuotedColumns($this); + + if (empty($constraintColumns)) { + throw new InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + $sql = ''; + $flags = ''; + + if (! empty($name)) { + $name = new Identifier($name); + $sql .= 'CONSTRAINT ' . $name->getQuotedName($this) . ' '; + } + + if ($constraint->hasFlag('clustered')) { + $flags = 'CLUSTERED '; + } + + if ($constraint->isPrimary()) { + return $sql . 'PRIMARY KEY ' . $flags . '(' . $this->getIndexFieldDeclarationListSQL($constraintColumns) . ')'; + } + + return $sql . 'UNIQUE ' . $flags . '(' . $this->getIndexFieldDeclarationListSQL($constraintColumns) . ')'; + } + + /** + * {@inheritdoc} + */ + protected function getCreateIndexSQLFlags(Index $index) + { + $type = ''; + if ($index->hasFlag('virtual')) { + $type .= 'VIRTUAL '; + } + + if ($index->isUnique()) { + $type .= 'UNIQUE '; + } + + if ($index->hasFlag('clustered')) { + $type .= 'CLUSTERED '; + } + + return $type; + } + + /** + * {@inheritdoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + return ['ALTER INDEX ' . $oldIndexName . ' ON ' . $tableName . ' RENAME TO ' . $index->getQuotedName($this)]; + } + + /** + * {@inheritdoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\SQLAnywhereKeywords::class; + } + + /** + * {@inheritdoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed + ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(' . $this->getVarcharDefaultLength() . ')') + : ($length ? 'VARCHAR(' . $length . ')' : 'VARCHAR(' . $this->getVarcharDefaultLength() . ')'); + } + + /** + * {@inheritdoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'char' => 'string', + 'long nvarchar' => 'text', + 'long varchar' => 'text', + 'nchar' => 'string', + 'ntext' => 'text', + 'nvarchar' => 'string', + 'text' => 'text', + 'uniqueidentifierstr' => 'guid', + 'varchar' => 'string', + 'xml' => 'text', + 'bigint' => 'bigint', + 'unsigned bigint' => 'bigint', + 'bit' => 'boolean', + 'decimal' => 'decimal', + 'double' => 'float', + 'float' => 'float', + 'int' => 'integer', + 'integer' => 'integer', + 'unsigned int' => 'integer', + 'numeric' => 'decimal', + 'smallint' => 'smallint', + 'unsigned smallint' => 'smallint', + 'tinyint' => 'smallint', + 'unsigned tinyint' => 'smallint', + 'money' => 'decimal', + 'smallmoney' => 'decimal', + 'long varbit' => 'text', + 'varbit' => 'string', + 'date' => 'date', + 'datetime' => 'datetime', + 'smalldatetime' => 'datetime', + 'time' => 'time', + 'timestamp' => 'datetime', + 'binary' => 'binary', + 'image' => 'blob', + 'long binary' => 'blob', + 'uniqueidentifier' => 'guid', + 'varbinary' => 'binary', + ]; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAzurePlatform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAzurePlatform.php new file mode 100644 index 000000000..a104848f8 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLAzurePlatform.php @@ -0,0 +1,33 @@ +hasOption('azure.federatedOnColumnName')) { + $distributionName = $table->getOption('azure.federatedOnDistributionName'); + $columnName = $table->getOption('azure.federatedOnColumnName'); + $stmt = ' FEDERATED ON (' . $distributionName . ' = ' . $columnName . ')'; + + $sql[0] .= $stmt; + } + + return $sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php new file mode 100644 index 000000000..1026a934f --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2005Platform.php @@ -0,0 +1,46 @@ +doctrineTypeMapping['datetime2'] = 'datetime'; + $this->doctrineTypeMapping['date'] = 'date'; + $this->doctrineTypeMapping['time'] = 'time'; + $this->doctrineTypeMapping['datetimeoffset'] = 'datetimetz'; + } + + /** + * {@inheritdoc} + * + * Returns Microsoft SQL Server 2008 specific keywords class + */ + protected function getReservedKeywordsClass() + { + return Keywords\SQLServer2008Keywords::class; + } + + protected function getLikeWildcardCharacters() : string + { + return parent::getLikeWildcardCharacters() . '[]^'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php new file mode 100644 index 000000000..009a37d33 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServer2012Platform.php @@ -0,0 +1,143 @@ +getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize(); + } + + /** + * {@inheritdoc} + */ + public function getCreateSequenceSQL(Sequence $sequence) + { + return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . + ' START WITH ' . $sequence->getInitialValue() . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + ' MINVALUE ' . $sequence->getInitialValue(); + } + + /** + * {@inheritdoc} + */ + public function getDropSequenceSQL($sequence) + { + if ($sequence instanceof Sequence) { + $sequence = $sequence->getQuotedName($this); + } + + return 'DROP SEQUENCE ' . $sequence; + } + + /** + * {@inheritdoc} + */ + public function getListSequencesSQL($database) + { + return 'SELECT seq.name, + CAST( + seq.increment AS VARCHAR(MAX) + ) AS increment, -- CAST avoids driver error for sql_variant type + CAST( + seq.start_value AS VARCHAR(MAX) + ) AS start_value -- CAST avoids driver error for sql_variant type + FROM sys.sequences AS seq'; + } + + /** + * {@inheritdoc} + */ + public function getSequenceNextValSQL($sequenceName) + { + return 'SELECT NEXT VALUE FOR ' . $sequenceName; + } + + /** + * {@inheritdoc} + */ + public function supportsSequences() + { + return true; + } + + /** + * {@inheritdoc} + * + * Returns Microsoft SQL Server 2012 specific keywords class + */ + protected function getReservedKeywordsClass() + { + return Keywords\SQLServer2012Keywords::class; + } + + /** + * {@inheritdoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset = null) + { + if ($limit === null && $offset <= 0) { + return $query; + } + + // Queries using OFFSET... FETCH MUST have an ORDER BY clause + // Find the position of the last instance of ORDER BY and ensure it is not within a parenthetical statement + // but can be in a newline + $matches = []; + $matchesCount = preg_match_all('/[\\s]+order\\s+by\\s/im', $query, $matches, PREG_OFFSET_CAPTURE); + $orderByPos = false; + if ($matchesCount > 0) { + $orderByPos = $matches[0][($matchesCount - 1)][1]; + } + + if ($orderByPos === false + || substr_count($query, '(', $orderByPos) - substr_count($query, ')', $orderByPos) + ) { + if (preg_match('/^SELECT\s+DISTINCT/im', $query)) { + // SQL Server won't let us order by a non-selected column in a DISTINCT query, + // so we have to do this madness. This says, order by the first column in the + // result. SQL Server's docs say that a nonordered query's result order is non- + // deterministic anyway, so this won't do anything that a bunch of update and + // deletes to the table wouldn't do anyway. + $query .= ' ORDER BY 1'; + } else { + // In another DBMS, we could do ORDER BY 0, but SQL Server gets angry if you + // use constant expressions in the order by list. + $query .= ' ORDER BY (SELECT 0)'; + } + } + + if ($offset === null) { + $offset = 0; + } + + // This looks somewhat like MYSQL, but limit/offset are in inverse positions + // Supposedly SQL:2008 core standard. + // Per TSQL spec, FETCH NEXT n ROWS ONLY is not valid without OFFSET n ROWS. + $query .= ' OFFSET ' . (int) $offset . ' ROWS'; + + if ($limit !== null) { + $query .= ' FETCH NEXT ' . (int) $limit . ' ROWS ONLY'; + } + + return $query; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php new file mode 100644 index 000000000..dc8775e61 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SQLServerPlatform.php @@ -0,0 +1,1679 @@ +getConvertExpression('date', 'GETDATE()'); + } + + /** + * {@inheritdoc} + */ + public function getCurrentTimeSQL() + { + return $this->getConvertExpression('time', 'GETDATE()'); + } + + /** + * Returns an expression that converts an expression of one data type to another. + * + * @param string $dataType The target native data type. Alias data types cannot be used. + * @param string $expression The SQL expression to convert. + * + * @return string + */ + private function getConvertExpression($dataType, $expression) + { + return sprintf('CONVERT(%s, %s)', $dataType, $expression); + } + + /** + * {@inheritdoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + $factorClause = ''; + + if ($operator === '-') { + $factorClause = '-1 * '; + } + + return 'DATEADD(' . $unit . ', ' . $factorClause . $interval . ', ' . $date . ')'; + } + + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return 'DATEDIFF(day, ' . $date2 . ',' . $date1 . ')'; + } + + /** + * {@inheritDoc} + * + * Microsoft SQL Server prefers "autoincrement" identity columns + * since sequences can only be emulated with a table. + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + * + * Microsoft SQL Server supports this through AUTO_INCREMENT columns. + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsReleaseSavepoints() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function supportsSchemas() + { + return true; + } + + /** + * {@inheritdoc} + */ + public function getDefaultSchemaName() + { + return 'dbo'; + } + + /** + * {@inheritDoc} + */ + public function supportsColumnCollation() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function hasNativeGuidType() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getCreateDatabaseSQL($name) + { + return 'CREATE DATABASE ' . $name; + } + + /** + * {@inheritDoc} + */ + public function getDropDatabaseSQL($name) + { + return 'DROP DATABASE ' . $name; + } + + /** + * {@inheritDoc} + */ + public function supportsCreateDropDatabase() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getCreateSchemaSQL($schemaName) + { + return 'CREATE SCHEMA ' . $schemaName; + } + + /** + * {@inheritDoc} + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if (! $foreignKey instanceof ForeignKeyConstraint) { + $foreignKey = new Identifier($foreignKey); + } + + if (! $table instanceof Table) { + $table = new Identifier($table); + } + + $foreignKey = $foreignKey->getQuotedName($this); + $table = $table->getQuotedName($this); + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey; + } + + /** + * {@inheritDoc} + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index) { + $index = $index->getQuotedName($this); + } elseif (! is_string($index)) { + throw new InvalidArgumentException('AbstractPlatform::getDropIndexSQL() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'); + } + + if (! isset($table)) { + return 'DROP INDEX ' . $index; + } + + if ($table instanceof Table) { + $table = $table->getQuotedName($this); + } + + return sprintf( + <<getDefaultConstraintDeclarationSQL($tableName, $column); + } + + if (empty($column['comment']) && ! is_numeric($column['comment'])) { + continue; + } + + $commentsSql[] = $this->getCreateColumnCommentSQL($tableName, $column['name'], $column['comment']); + } + + $columnListSql = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $name => $definition) { + $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); + } + } + + if (isset($options['primary']) && ! empty($options['primary'])) { + $flags = ''; + if (isset($options['primary_index']) && $options['primary_index']->hasFlag('nonclustered')) { + $flags = ' NONCLUSTERED'; + } + $columnListSql .= ', PRIMARY KEY' . $flags . ' (' . implode(', ', array_unique(array_values($options['primary']))) . ')'; + } + + $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; + + $check = $this->getCheckDeclarationSQL($columns); + if (! empty($check)) { + $query .= ', ' . $check; + } + $query .= ')'; + + $sql = [$query]; + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableName); + } + } + + if (isset($options['foreignKeys'])) { + foreach ((array) $options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $tableName); + } + } + + return array_merge($sql, $commentsSql, $defaultConstraintsSql); + } + + /** + * {@inheritDoc} + */ + public function getCreatePrimaryKeySQL(Index $index, $table) + { + $flags = ''; + if ($index->hasFlag('nonclustered')) { + $flags = ' NONCLUSTERED'; + } + + return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY' . $flags . ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')'; + } + + /** + * Returns the SQL statement for creating a column comment. + * + * SQL Server does not support native column comments, + * therefore the extended properties functionality is used + * as a workaround to store them. + * The property name used to store column comments is "MS_Description" + * which provides compatibility with SQL Server Management Studio, + * as column comments are stored in the same property there when + * specifying a column's "Description" attribute. + * + * @param string $tableName The quoted table name to which the column belongs. + * @param string $columnName The quoted column name to create the comment for. + * @param string $comment The column's comment. + * + * @return string + */ + protected function getCreateColumnCommentSQL($tableName, $columnName, $comment) + { + if (strpos($tableName, '.') !== false) { + [$schemaSQL, $tableSQL] = explode('.', $tableName); + $schemaSQL = $this->quoteStringLiteral($schemaSQL); + $tableSQL = $this->quoteStringLiteral($tableSQL); + } else { + $schemaSQL = "'dbo'"; + $tableSQL = $this->quoteStringLiteral($tableName); + } + + return $this->getAddExtendedPropertySQL( + 'MS_Description', + $comment, + 'SCHEMA', + $schemaSQL, + 'TABLE', + $tableSQL, + 'COLUMN', + $columnName + ); + } + + /** + * Returns the SQL snippet for declaring a default constraint. + * + * @param string $table Name of the table to return the default constraint declaration for. + * @param mixed[] $column Column definition. + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getDefaultConstraintDeclarationSQL($table, array $column) + { + if (! isset($column['default'])) { + throw new InvalidArgumentException("Incomplete column definition. 'default' required."); + } + + $columnName = new Identifier($column['name']); + + return ' CONSTRAINT ' . + $this->generateDefaultConstraintName($table, $column['name']) . + $this->getDefaultValueDeclarationSQL($column) . + ' FOR ' . $columnName->getQuotedName($this); + } + + /** + * {@inheritDoc} + */ + public function getUniqueConstraintDeclarationSQL($name, Index $index) + { + $constraint = parent::getUniqueConstraintDeclarationSQL($name, $index); + + $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index); + + return $constraint; + } + + /** + * {@inheritDoc} + */ + public function getCreateIndexSQL(Index $index, $table) + { + $constraint = parent::getCreateIndexSQL($index, $table); + + if ($index->isUnique() && ! $index->isPrimary()) { + $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index); + } + + return $constraint; + } + + /** + * {@inheritDoc} + */ + protected function getCreateIndexSQLFlags(Index $index) + { + $type = ''; + if ($index->isUnique()) { + $type .= 'UNIQUE '; + } + + if ($index->hasFlag('clustered')) { + $type .= 'CLUSTERED '; + } elseif ($index->hasFlag('nonclustered')) { + $type .= 'NONCLUSTERED '; + } + + return $type; + } + + /** + * Extend unique key constraint with required filters + * + * @param string $sql + * + * @return string + */ + private function _appendUniqueConstraintDefinition($sql, Index $index) + { + $fields = []; + + foreach ($index->getQuotedColumns($this) as $field) { + $fields[] = $field . ' IS NOT NULL'; + } + + return $sql . ' WHERE ' . implode(' AND ', $fields); + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $queryParts = []; + $sql = []; + $columnSql = []; + $commentsSql = []; + + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columnDef = $column->toArray(); + $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef); + + if (isset($columnDef['default'])) { + $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column); + } + + $comment = $this->getColumnComment($column); + + if (empty($comment) && ! is_numeric($comment)) { + continue; + } + + $commentsSql[] = $this->getCreateColumnCommentSQL( + $diff->name, + $column->getQuotedName($this), + $comment + ); + } + + foreach ($diff->removedColumns as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this); + } + + foreach ($diff->changedColumns as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $column = $columnDiff->column; + $comment = $this->getColumnComment($column); + $hasComment = ! empty($comment) || is_numeric($comment); + + if ($columnDiff->fromColumn instanceof Column) { + $fromComment = $this->getColumnComment($columnDiff->fromColumn); + $hasFromComment = ! empty($fromComment) || is_numeric($fromComment); + + if ($hasFromComment && $hasComment && $fromComment !== $comment) { + $commentsSql[] = $this->getAlterColumnCommentSQL( + $diff->name, + $column->getQuotedName($this), + $comment + ); + } elseif ($hasFromComment && ! $hasComment) { + $commentsSql[] = $this->getDropColumnCommentSQL($diff->name, $column->getQuotedName($this)); + } elseif ($hasComment) { + $commentsSql[] = $this->getCreateColumnCommentSQL( + $diff->name, + $column->getQuotedName($this), + $comment + ); + } + } + + // Do not add query part if only comment has changed. + if ($columnDiff->hasChanged('comment') && count($columnDiff->changedProperties) === 1) { + continue; + } + + $requireDropDefaultConstraint = $this->alterColumnRequiresDropDefaultConstraint($columnDiff); + + if ($requireDropDefaultConstraint) { + $queryParts[] = $this->getAlterTableDropDefaultConstraintClause( + $diff->name, + $columnDiff->oldColumnName + ); + } + + $columnDef = $column->toArray(); + + $queryParts[] = 'ALTER COLUMN ' . + $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef); + + if (! isset($columnDef['default']) || (! $requireDropDefaultConstraint && ! $columnDiff->hasChanged('default'))) { + continue; + } + + $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column); + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $sql[] = "sp_RENAME '" . + $diff->getName($this)->getQuotedName($this) . '.' . $oldColumnName->getQuotedName($this) . + "', '" . $column->getQuotedName($this) . "', 'COLUMN'"; + + // Recreate default constraint with new column name if necessary (for future reference). + if ($column->getDefault() === null) { + continue; + } + + $queryParts[] = $this->getAlterTableDropDefaultConstraintClause( + $diff->name, + $oldColumnName->getQuotedName($this) + ); + $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column); + } + + $tableSql = []; + + if ($this->onSchemaAlterTable($diff, $tableSql)) { + return array_merge($tableSql, $columnSql); + } + + foreach ($queryParts as $query) { + $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query; + } + + $sql = array_merge($sql, $commentsSql); + + if ($diff->newName !== false) { + $sql[] = "sp_RENAME '" . $diff->getName($this)->getQuotedName($this) . "', '" . $diff->getNewName()->getName() . "'"; + + /** + * Rename table's default constraints names + * to match the new table name. + * This is necessary to ensure that the default + * constraints can be referenced in future table + * alterations as the table name is encoded in + * default constraints' names. + */ + $sql[] = "DECLARE @sql NVARCHAR(MAX) = N''; " . + "SELECT @sql += N'EXEC sp_rename N''' + dc.name + ''', N''' " . + "+ REPLACE(dc.name, '" . $this->generateIdentifierName($diff->name) . "', " . + "'" . $this->generateIdentifierName($diff->newName) . "') + ''', ''OBJECT'';' " . + 'FROM sys.default_constraints dc ' . + 'JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id ' . + "WHERE tbl.name = '" . $diff->getNewName()->getName() . "';" . + 'EXEC sp_executesql @sql'; + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff) + ); + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Returns the SQL clause for adding a default constraint in an ALTER TABLE statement. + * + * @param string $tableName The name of the table to generate the clause for. + * @param Column $column The column to generate the clause for. + * + * @return string + */ + private function getAlterTableAddDefaultConstraintClause($tableName, Column $column) + { + $columnDef = $column->toArray(); + $columnDef['name'] = $column->getQuotedName($this); + + return 'ADD' . $this->getDefaultConstraintDeclarationSQL($tableName, $columnDef); + } + + /** + * Returns the SQL clause for dropping an existing default constraint in an ALTER TABLE statement. + * + * @param string $tableName The name of the table to generate the clause for. + * @param string $columnName The name of the column to generate the clause for. + * + * @return string + */ + private function getAlterTableDropDefaultConstraintClause($tableName, $columnName) + { + return 'DROP CONSTRAINT ' . $this->generateDefaultConstraintName($tableName, $columnName); + } + + /** + * Checks whether a column alteration requires dropping its default constraint first. + * + * Different to other database vendors SQL Server implements column default values + * as constraints and therefore changes in a column's default value as well as changes + * in a column's type require dropping the default constraint first before being to + * alter the particular column to the new definition. + * + * @param ColumnDiff $columnDiff The column diff to evaluate. + * + * @return bool True if the column alteration requires dropping its default constraint first, false otherwise. + */ + private function alterColumnRequiresDropDefaultConstraint(ColumnDiff $columnDiff) + { + // We can only decide whether to drop an existing default constraint + // if we know the original default value. + if (! $columnDiff->fromColumn instanceof Column) { + return false; + } + + // We only need to drop an existing default constraint if we know the + // column was defined with a default value before. + if ($columnDiff->fromColumn->getDefault() === null) { + return false; + } + + // We need to drop an existing default constraint if the column was + // defined with a default value before and it has changed. + if ($columnDiff->hasChanged('default')) { + return true; + } + + // We need to drop an existing default constraint if the column was + // defined with a default value before and the native column type has changed. + return $columnDiff->hasChanged('type') || $columnDiff->hasChanged('fixed'); + } + + /** + * Returns the SQL statement for altering a column comment. + * + * SQL Server does not support native column comments, + * therefore the extended properties functionality is used + * as a workaround to store them. + * The property name used to store column comments is "MS_Description" + * which provides compatibility with SQL Server Management Studio, + * as column comments are stored in the same property there when + * specifying a column's "Description" attribute. + * + * @param string $tableName The quoted table name to which the column belongs. + * @param string $columnName The quoted column name to alter the comment for. + * @param string $comment The column's comment. + * + * @return string + */ + protected function getAlterColumnCommentSQL($tableName, $columnName, $comment) + { + if (strpos($tableName, '.') !== false) { + [$schemaSQL, $tableSQL] = explode('.', $tableName); + $schemaSQL = $this->quoteStringLiteral($schemaSQL); + $tableSQL = $this->quoteStringLiteral($tableSQL); + } else { + $schemaSQL = "'dbo'"; + $tableSQL = $this->quoteStringLiteral($tableName); + } + + return $this->getUpdateExtendedPropertySQL( + 'MS_Description', + $comment, + 'SCHEMA', + $schemaSQL, + 'TABLE', + $tableSQL, + 'COLUMN', + $columnName + ); + } + + /** + * Returns the SQL statement for dropping a column comment. + * + * SQL Server does not support native column comments, + * therefore the extended properties functionality is used + * as a workaround to store them. + * The property name used to store column comments is "MS_Description" + * which provides compatibility with SQL Server Management Studio, + * as column comments are stored in the same property there when + * specifying a column's "Description" attribute. + * + * @param string $tableName The quoted table name to which the column belongs. + * @param string $columnName The quoted column name to drop the comment for. + * + * @return string + */ + protected function getDropColumnCommentSQL($tableName, $columnName) + { + if (strpos($tableName, '.') !== false) { + [$schemaSQL, $tableSQL] = explode('.', $tableName); + $schemaSQL = $this->quoteStringLiteral($schemaSQL); + $tableSQL = $this->quoteStringLiteral($tableSQL); + } else { + $schemaSQL = "'dbo'"; + $tableSQL = $this->quoteStringLiteral($tableName); + } + + return $this->getDropExtendedPropertySQL( + 'MS_Description', + 'SCHEMA', + $schemaSQL, + 'TABLE', + $tableSQL, + 'COLUMN', + $columnName + ); + } + + /** + * {@inheritdoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + return [sprintf( + "EXEC sp_RENAME N'%s.%s', N'%s', N'INDEX'", + $tableName, + $oldIndexName, + $index->getQuotedName($this) + ), + ]; + } + + /** + * Returns the SQL statement for adding an extended property to a database object. + * + * @link http://msdn.microsoft.com/en-us/library/ms180047%28v=sql.90%29.aspx + * + * @param string $name The name of the property to add. + * @param string|null $value The value of the property to add. + * @param string|null $level0Type The type of the object at level 0 the property belongs to. + * @param string|null $level0Name The name of the object at level 0 the property belongs to. + * @param string|null $level1Type The type of the object at level 1 the property belongs to. + * @param string|null $level1Name The name of the object at level 1 the property belongs to. + * @param string|null $level2Type The type of the object at level 2 the property belongs to. + * @param string|null $level2Name The name of the object at level 2 the property belongs to. + * + * @return string + */ + public function getAddExtendedPropertySQL( + $name, + $value = null, + $level0Type = null, + $level0Name = null, + $level1Type = null, + $level1Name = null, + $level2Type = null, + $level2Name = null + ) { + return 'EXEC sp_addextendedproperty ' . + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value) . ', ' . + 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + } + + /** + * Returns the SQL statement for dropping an extended property from a database object. + * + * @link http://technet.microsoft.com/en-gb/library/ms178595%28v=sql.90%29.aspx + * + * @param string $name The name of the property to drop. + * @param string|null $level0Type The type of the object at level 0 the property belongs to. + * @param string|null $level0Name The name of the object at level 0 the property belongs to. + * @param string|null $level1Type The type of the object at level 1 the property belongs to. + * @param string|null $level1Name The name of the object at level 1 the property belongs to. + * @param string|null $level2Type The type of the object at level 2 the property belongs to. + * @param string|null $level2Name The name of the object at level 2 the property belongs to. + * + * @return string + */ + public function getDropExtendedPropertySQL( + $name, + $level0Type = null, + $level0Name = null, + $level1Type = null, + $level1Name = null, + $level2Type = null, + $level2Name = null + ) { + return 'EXEC sp_dropextendedproperty ' . + 'N' . $this->quoteStringLiteral($name) . ', ' . + 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + } + + /** + * Returns the SQL statement for updating an extended property of a database object. + * + * @link http://msdn.microsoft.com/en-us/library/ms186885%28v=sql.90%29.aspx + * + * @param string $name The name of the property to update. + * @param string|null $value The value of the property to update. + * @param string|null $level0Type The type of the object at level 0 the property belongs to. + * @param string|null $level0Name The name of the object at level 0 the property belongs to. + * @param string|null $level1Type The type of the object at level 1 the property belongs to. + * @param string|null $level1Name The name of the object at level 1 the property belongs to. + * @param string|null $level2Type The type of the object at level 2 the property belongs to. + * @param string|null $level2Name The name of the object at level 2 the property belongs to. + * + * @return string + */ + public function getUpdateExtendedPropertySQL( + $name, + $value = null, + $level0Type = null, + $level0Name = null, + $level1Type = null, + $level1Name = null, + $level2Type = null, + $level2Name = null + ) { + return 'EXEC sp_updateextendedproperty ' . + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value) . ', ' . + 'N' . $this->quoteStringLiteral($level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral($level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral($level2Type) . ', ' . $level2Name; + } + + /** + * {@inheritDoc} + */ + public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) + { + return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES'; + } + + /** + * {@inheritDoc} + */ + public function getListTablesSQL() + { + // "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams + // Category 2 must be ignored as it is "MS SQL Server 'pseudo-system' object[s]" for replication + return "SELECT name FROM sysobjects WHERE type = 'U' AND name != 'sysdiagrams' AND category != 2 ORDER BY name"; + } + + /** + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + return "SELECT col.name, + type.name AS type, + col.max_length AS length, + ~col.is_nullable AS notnull, + def.definition AS [default], + col.scale, + col.precision, + col.is_identity AS autoincrement, + col.collation_name AS collation, + CAST(prop.value AS NVARCHAR(MAX)) AS comment -- CAST avoids driver error for sql_variant type + FROM sys.columns AS col + JOIN sys.types AS type + ON col.user_type_id = type.user_type_id + JOIN sys.objects AS obj + ON col.object_id = obj.object_id + JOIN sys.schemas AS scm + ON obj.schema_id = scm.schema_id + LEFT JOIN sys.default_constraints def + ON col.default_object_id = def.object_id + AND col.object_id = def.parent_object_id + LEFT JOIN sys.extended_properties AS prop + ON obj.object_id = prop.major_id + AND col.column_id = prop.minor_id + AND prop.name = 'MS_Description' + WHERE obj.type = 'U' + AND " . $this->getTableWhereClause($table, 'scm.name', 'obj.name'); + } + + /** + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + return 'SELECT f.name AS ForeignKey, + SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName, + OBJECT_NAME (f.parent_object_id) AS TableName, + COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName, + SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName, + OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, + COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName, + f.delete_referential_action_desc, + f.update_referential_action_desc + FROM sys.foreign_keys AS f + INNER JOIN sys.foreign_key_columns AS fc + INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id + ON f.OBJECT_ID = fc.constraint_object_id + WHERE ' . + $this->getTableWhereClause($table, 'SCHEMA_NAME (f.schema_id)', 'OBJECT_NAME (f.parent_object_id)'); + } + + /** + * {@inheritDoc} + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + return "SELECT idx.name AS key_name, + col.name AS column_name, + ~idx.is_unique AS non_unique, + idx.is_primary_key AS [primary], + CASE idx.type + WHEN '1' THEN 'clustered' + WHEN '2' THEN 'nonclustered' + ELSE NULL + END AS flags + FROM sys.tables AS tbl + JOIN sys.schemas AS scm ON tbl.schema_id = scm.schema_id + JOIN sys.indexes AS idx ON tbl.object_id = idx.object_id + JOIN sys.index_columns AS idxcol ON idx.object_id = idxcol.object_id AND idx.index_id = idxcol.index_id + JOIN sys.columns AS col ON idxcol.object_id = col.object_id AND idxcol.column_id = col.column_id + WHERE " . $this->getTableWhereClause($table, 'scm.name', 'tbl.name') . ' + ORDER BY idx.index_id ASC, idxcol.key_ordinal ASC'; + } + + /** + * {@inheritDoc} + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * {@inheritDoc} + */ + public function getListViewsSQL($database) + { + return "SELECT name FROM sysobjects WHERE type = 'V' ORDER BY name"; + } + + /** + * Returns the where clause to filter schema and table name in a query. + * + * @param string $table The full qualified name of the table. + * @param string $schemaColumn The name of the column to compare the schema to in the where clause. + * @param string $tableColumn The name of the column to compare the table to in the where clause. + * + * @return string + */ + private function getTableWhereClause($table, $schemaColumn, $tableColumn) + { + if (strpos($table, '.') !== false) { + [$schema, $table] = explode('.', $table); + $schema = $this->quoteStringLiteral($schema); + $table = $this->quoteStringLiteral($table); + } else { + $schema = 'SCHEMA_NAME()'; + $table = $this->quoteStringLiteral($table); + } + + return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema); + } + + /** + * {@inheritDoc} + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * {@inheritDoc} + * + * @deprecated Use application-generated UUIDs instead + */ + public function getGuidExpression() + { + return 'NEWID()'; + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos === false) { + return 'CHARINDEX(' . $substr . ', ' . $str . ')'; + } + + return 'CHARINDEX(' . $substr . ', ' . $str . ', ' . $startPos . ')'; + } + + /** + * {@inheritDoc} + */ + public function getModExpression($expression1, $expression2) + { + return $expression1 . ' % ' . $expression2; + } + + /** + * {@inheritDoc} + */ + public function getTrimExpression($str, $pos = TrimMode::UNSPECIFIED, $char = false) + { + if (! $char) { + switch ($pos) { + case TrimMode::LEADING: + $trimFn = 'LTRIM'; + break; + + case TrimMode::TRAILING: + $trimFn = 'RTRIM'; + break; + + default: + return 'LTRIM(RTRIM(' . $str . '))'; + } + + return $trimFn . '(' . $str . ')'; + } + + /** Original query used to get those expressions + declare @c varchar(100) = 'xxxBarxxx', @trim_char char(1) = 'x'; + declare @pat varchar(10) = '%[^' + @trim_char + ']%'; + select @c as string + , @trim_char as trim_char + , stuff(@c, 1, patindex(@pat, @c) - 1, null) as trim_leading + , reverse(stuff(reverse(@c), 1, patindex(@pat, reverse(@c)) - 1, null)) as trim_trailing + , reverse(stuff(reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null)), 1, patindex(@pat, reverse(stuff(@c, 1, patindex(@pat, @c) - 1, null))) - 1, null)) as trim_both; + */ + $pattern = "'%[^' + " . $char . " + ']%'"; + + if ($pos === TrimMode::LEADING) { + return 'stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)'; + } + + if ($pos === TrimMode::TRAILING) { + return 'reverse(stuff(reverse(' . $str . '), 1, patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))'; + } + + return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)), 1, patindex(' . $pattern . ', reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null))) - 1, null))'; + } + + /** + * {@inheritDoc} + */ + public function getConcatExpression() + { + $args = func_get_args(); + + return '(' . implode(' + ', $args) . ')'; + } + + /** + * {@inheritDoc} + */ + public function getListDatabasesSQL() + { + return 'SELECT * FROM sys.databases'; + } + + /** + * {@inheritDoc} + */ + public function getListNamespacesSQL() + { + return "SELECT name FROM sys.schemas WHERE name NOT IN('guest', 'INFORMATION_SCHEMA', 'sys')"; + } + + /** + * {@inheritDoc} + */ + public function getSubstringExpression($value, $from, $length = null) + { + if ($length !== null) { + return 'SUBSTRING(' . $value . ', ' . $from . ', ' . $length . ')'; + } + + return 'SUBSTRING(' . $value . ', ' . $from . ', LEN(' . $value . ') - ' . $from . ' + 1)'; + } + + /** + * {@inheritDoc} + */ + public function getLengthExpression($column) + { + return 'LEN(' . $column . ')'; + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getGuidTypeDeclarationSQL(array $field) + { + return 'UNIQUEIDENTIFIER'; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'NCHAR(' . $length . ')' : 'CHAR(255)') : ($length ? 'NVARCHAR(' . $length . ')' : 'NVARCHAR(255)'); + } + + /** + * {@inheritdoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? 'BINARY(' . ($length ?: 255) . ')' : 'VARBINARY(' . ($length ?: 255) . ')'; + } + + /** + * {@inheritdoc} + */ + public function getBinaryMaxLength() + { + return 8000; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'VARCHAR(MAX)'; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + return ! empty($columnDef['autoincrement']) ? ' IDENTITY' : ''; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'BIT'; + } + + /** + * {@inheritDoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset = null) + { + $where = []; + + if ($offset > 0) { + $where[] = sprintf('doctrine_rownum >= %d', $offset + 1); + } + + if ($limit !== null) { + $where[] = sprintf('doctrine_rownum <= %d', $offset + $limit); + $top = sprintf('TOP %d', $offset + $limit); + } else { + $top = 'TOP 9223372036854775807'; + } + + if (empty($where)) { + return $query; + } + + // We'll find a SELECT or SELECT distinct and prepend TOP n to it + // Even if the TOP n is very large, the use of a CTE will + // allow the SQL Server query planner to optimize it so it doesn't + // actually scan the entire range covered by the TOP clause. + $selectPattern = '/^(\s*SELECT\s+(?:DISTINCT\s+)?)(.*)$/im'; + $replacePattern = sprintf('$1%s $2', $top); + $query = preg_replace($selectPattern, $replacePattern, $query); + + if (stristr($query, 'ORDER BY')) { + // Inner order by is not valid in SQL Server for our purposes + // unless it's in a TOP N subquery. + $query = $this->scrubInnerOrderBy($query); + } + + // Build a new limited query around the original, using a CTE + return sprintf( + 'WITH dctrn_cte AS (%s) ' + . 'SELECT * FROM (' + . 'SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM dctrn_cte' + . ') AS doctrine_tbl ' + . 'WHERE %s ORDER BY doctrine_rownum ASC', + $query, + implode(' AND ', $where) + ); + } + + /** + * Remove ORDER BY clauses in subqueries - they're not supported by SQL Server. + * Caveat: will leave ORDER BY in TOP N subqueries. + * + * @param string $query + * + * @return string + */ + private function scrubInnerOrderBy($query) + { + $count = substr_count(strtoupper($query), 'ORDER BY'); + $offset = 0; + + while ($count-- > 0) { + $orderByPos = stripos($query, ' ORDER BY', $offset); + if ($orderByPos === false) { + break; + } + + $qLen = strlen($query); + $parenCount = 0; + $currentPosition = $orderByPos; + + while ($parenCount >= 0 && $currentPosition < $qLen) { + if ($query[$currentPosition] === '(') { + $parenCount++; + } elseif ($query[$currentPosition] === ')') { + $parenCount--; + } + + $currentPosition++; + } + + if ($this->isOrderByInTopNSubquery($query, $orderByPos)) { + // If the order by clause is in a TOP N subquery, do not remove + // it and continue iteration from the current position. + $offset = $currentPosition; + continue; + } + + if ($currentPosition >= $qLen - 1) { + continue; + } + + $query = substr($query, 0, $orderByPos) . substr($query, $currentPosition - 1); + $offset = $orderByPos; + } + return $query; + } + + /** + * Check an ORDER BY clause to see if it is in a TOP N query or subquery. + * + * @param string $query The query + * @param int $currentPosition Start position of ORDER BY clause + * + * @return bool true if ORDER BY is in a TOP N query, false otherwise + */ + private function isOrderByInTopNSubquery($query, $currentPosition) + { + // Grab query text on the same nesting level as the ORDER BY clause we're examining. + $subQueryBuffer = ''; + $parenCount = 0; + + // If $parenCount goes negative, we've exited the subquery we're examining. + // If $currentPosition goes negative, we've reached the beginning of the query. + while ($parenCount >= 0 && $currentPosition >= 0) { + if ($query[$currentPosition] === '(') { + $parenCount--; + } elseif ($query[$currentPosition] === ')') { + $parenCount++; + } + + // Only yank query text on the same nesting level as the ORDER BY clause. + $subQueryBuffer = ($parenCount === 0 ? $query[$currentPosition] : ' ') . $subQueryBuffer; + + $currentPosition--; + } + + return (bool) preg_match('/SELECT\s+(DISTINCT\s+)?TOP\s/i', $subQueryBuffer); + } + + /** + * {@inheritDoc} + */ + public function supportsLimitOffset() + { + return false; + } + + /** + * {@inheritDoc} + */ + public function convertBooleans($item) + { + if (is_array($item)) { + foreach ($item as $key => $value) { + if (! is_bool($value) && ! is_numeric($item)) { + continue; + } + + $item[$key] = $value ? 1 : 0; + } + } elseif (is_bool($item) || is_numeric($item)) { + $item = $item ? 1 : 0; + } + + return $item; + } + + /** + * {@inheritDoc} + */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'CREATE TABLE'; + } + + /** + * {@inheritDoc} + */ + public function getTemporaryTableName($tableName) + { + return '#' . $tableName; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:s.000'; + } + + /** + * {@inheritDoc} + */ + public function getDateFormatString() + { + return 'Y-m-d H:i:s.000'; + } + + /** + * {@inheritDoc} + */ + public function getTimeFormatString() + { + return 'Y-m-d H:i:s.000'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzFormatString() + { + return $this->getDateTimeFormatString(); + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return 'mssql'; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'bigint' => 'bigint', + 'numeric' => 'decimal', + 'bit' => 'boolean', + 'smallint' => 'smallint', + 'decimal' => 'decimal', + 'smallmoney' => 'integer', + 'int' => 'integer', + 'tinyint' => 'smallint', + 'money' => 'integer', + 'float' => 'float', + 'real' => 'float', + 'double' => 'float', + 'double precision' => 'float', + 'smalldatetime' => 'datetime', + 'datetime' => 'datetime', + 'char' => 'string', + 'varchar' => 'string', + 'text' => 'text', + 'nchar' => 'string', + 'nvarchar' => 'string', + 'ntext' => 'text', + 'binary' => 'binary', + 'varbinary' => 'binary', + 'image' => 'blob', + 'uniqueidentifier' => 'guid', + ]; + } + + /** + * {@inheritDoc} + */ + public function createSavePoint($savepoint) + { + return 'SAVE TRANSACTION ' . $savepoint; + } + + /** + * {@inheritDoc} + */ + public function releaseSavePoint($savepoint) + { + return ''; + } + + /** + * {@inheritDoc} + */ + public function rollbackSavePoint($savepoint) + { + return 'ROLLBACK TRANSACTION ' . $savepoint; + } + + /** + * {@inheritdoc} + */ + public function getForeignKeyReferentialActionSQL($action) + { + // RESTRICT is not supported, therefore falling back to NO ACTION. + if (strtoupper($action) === 'RESTRICT') { + return 'NO ACTION'; + } + + return parent::getForeignKeyReferentialActionSQL($action); + } + + /** + * {@inheritDoc} + */ + public function appendLockHint($fromClause, $lockMode) + { + switch (true) { + case $lockMode === LockMode::NONE: + return $fromClause . ' WITH (NOLOCK)'; + + case $lockMode === LockMode::PESSIMISTIC_READ: + return $fromClause . ' WITH (HOLDLOCK, ROWLOCK)'; + + case $lockMode === LockMode::PESSIMISTIC_WRITE: + return $fromClause . ' WITH (UPDLOCK, ROWLOCK)'; + + default: + return $fromClause; + } + } + + /** + * {@inheritDoc} + */ + public function getForUpdateSQL() + { + return ' '; + } + + /** + * {@inheritDoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\SQLServerKeywords::class; + } + + /** + * {@inheritDoc} + */ + public function quoteSingleIdentifier($str) + { + return '[' . str_replace(']', '][', $str) . ']'; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'VARBINARY(MAX)'; + } + + /** + * {@inheritDoc} + */ + public function getDefaultValueDeclarationSQL($field) + { + if (! isset($field['default'])) { + return empty($field['notnull']) ? ' NULL' : ''; + } + + if (! isset($field['type'])) { + return " DEFAULT '" . $field['default'] . "'"; + } + + $type = $field['type']; + + if ($type instanceof Types\PhpIntegerMappingType) { + return ' DEFAULT ' . $field['default']; + } + + if ($type instanceof Types\PhpDateTimeMappingType && $field['default'] === $this->getCurrentTimestampSQL()) { + return ' DEFAULT ' . $this->getCurrentTimestampSQL(); + } + + if ($type instanceof Types\BooleanType) { + return " DEFAULT '" . $this->convertBooleans($field['default']) . "'"; + } + + return " DEFAULT '" . $field['default'] . "'"; + } + + /** + * {@inheritdoc} + * + * Modifies column declaration order as it differs in Microsoft SQL Server. + */ + public function getColumnDeclarationSQL($name, array $field) + { + if (isset($field['columnDefinition'])) { + $columnDef = $this->getCustomTypeDeclarationSQL($field); + } else { + $collation = isset($field['collation']) && $field['collation'] ? + ' ' . $this->getColumnCollationDeclarationSQL($field['collation']) : ''; + + $notnull = isset($field['notnull']) && $field['notnull'] ? ' NOT NULL' : ''; + + $unique = isset($field['unique']) && $field['unique'] ? + ' ' . $this->getUniqueFieldDeclarationSQL() : ''; + + $check = isset($field['check']) && $field['check'] ? + ' ' . $field['check'] : ''; + + $typeDecl = $field['type']->getSQLDeclaration($field, $this); + $columnDef = $typeDecl . $collation . $notnull . $unique . $check; + } + + return $name . ' ' . $columnDef; + } + + /** + * Returns a unique default constraint name for a table and column. + * + * @param string $table Name of the table to generate the unique default constraint name for. + * @param string $column Name of the column in the table to generate the unique default constraint name for. + * + * @return string + */ + private function generateDefaultConstraintName($table, $column) + { + return 'DF_' . $this->generateIdentifierName($table) . '_' . $this->generateIdentifierName($column); + } + + /** + * Returns a hash value for a given identifier. + * + * @param string $identifier Identifier to generate a hash value for. + * + * @return string + */ + private function generateIdentifierName($identifier) + { + // Always generate name for unquoted identifiers to ensure consistency. + $identifier = new Identifier($identifier); + + return strtoupper(dechex(crc32($identifier->getName()))); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php new file mode 100644 index 000000000..819421d34 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -0,0 +1,1167 @@ +_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + public function prefersIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $field) + { + return 'BOOLEAN'; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $field) + { + return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $field) + { + // SQLite autoincrement is implicit for INTEGER PKs, but not for BIGINT fields. + if (! empty($field['autoincrement'])) { + return $this->getIntegerTypeDeclarationSQL($field); + } + + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getTinyIntTypeDeclarationSql(array $field) + { + // SQLite autoincrement is implicit for INTEGER PKs, but not for TINYINT fields. + if (! empty($field['autoincrement'])) { + return $this->getIntegerTypeDeclarationSQL($field); + } + + return 'TINYINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $field) + { + // SQLite autoincrement is implicit for INTEGER PKs, but not for SMALLINT fields. + if (! empty($field['autoincrement'])) { + return $this->getIntegerTypeDeclarationSQL($field); + } + + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getMediumIntTypeDeclarationSql(array $field) + { + // SQLite autoincrement is implicit for INTEGER PKs, but not for MEDIUMINT fields. + if (! empty($field['autoincrement'])) { + return $this->getIntegerTypeDeclarationSQL($field); + } + + return 'MEDIUMINT' . $this->_getCommonIntegerTypeDeclarationSQL($field); + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATETIME'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $fieldDeclaration) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $fieldDeclaration) + { + return 'TIME'; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $columnDef) + { + // sqlite autoincrement is only possible for the primary key + if (! empty($columnDef['autoincrement'])) { + return ' PRIMARY KEY AUTOINCREMENT'; + } + + return ! empty($columnDef['unsigned']) ? ' UNSIGNED' : ''; + } + + /** + * {@inheritDoc} + */ + public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + return parent::getForeignKeyDeclarationSQL(new ForeignKeyConstraint( + $foreignKey->getQuotedLocalColumns($this), + str_replace('.', '__', $foreignKey->getQuotedForeignTableName($this)), + $foreignKey->getQuotedForeignColumns($this), + $foreignKey->getName(), + $foreignKey->getOptions() + )); + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($name, array $columns, array $options = []) + { + $name = str_replace('.', '__', $name); + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $name => $definition) { + $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($name, $definition); + } + } + + $queryFields .= $this->getNonAutoincrementPrimaryKeyDefinition($columns, $options); + + if (isset($options['foreignKeys'])) { + foreach ($options['foreignKeys'] as $foreignKey) { + $queryFields .= ', ' . $this->getForeignKeyDeclarationSQL($foreignKey); + } + } + + $query = ['CREATE TABLE ' . $name . ' (' . $queryFields . ')']; + + if (isset($options['alter']) && $options['alter'] === true) { + return $query; + } + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $indexDef) { + $query[] = $this->getCreateIndexSQL($indexDef, $name); + } + } + + if (isset($options['unique']) && ! empty($options['unique'])) { + foreach ($options['unique'] as $indexDef) { + $query[] = $this->getCreateIndexSQL($indexDef, $name); + } + } + + return $query; + } + + /** + * Generate a PRIMARY KEY definition if no autoincrement value is used + * + * @param string[] $columns + * @param mixed[] $options + */ + private function getNonAutoincrementPrimaryKeyDefinition(array $columns, array $options) : string + { + if (empty($options['primary'])) { + return ''; + } + + $keyColumns = array_unique(array_values($options['primary'])); + + foreach ($keyColumns as $keyColumn) { + if (isset($columns[$keyColumn]['autoincrement']) && ! empty($columns[$keyColumn]['autoincrement'])) { + return ''; + } + } + + return ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length ? 'VARCHAR(' . $length . ')' : 'TEXT'); + } + + /** + * {@inheritdoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return 'BLOB'; + } + + /** + * {@inheritdoc} + */ + public function getBinaryMaxLength() + { + return 0; + } + + /** + * {@inheritdoc} + */ + public function getBinaryDefaultLength() + { + return 0; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $field) + { + return 'CLOB'; + } + + /** + * {@inheritDoc} + */ + public function getListTableConstraintsSQL($table) + { + $table = str_replace('.', '__', $table); + + return sprintf( + "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = %s AND sql NOT NULL ORDER BY name", + $this->quoteStringLiteral($table) + ); + } + + /** + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $currentDatabase = null) + { + $table = str_replace('.', '__', $table); + + return sprintf('PRAGMA table_info(%s)', $this->quoteStringLiteral($table)); + } + + /** + * {@inheritDoc} + */ + public function getListTableIndexesSQL($table, $currentDatabase = null) + { + $table = str_replace('.', '__', $table); + + return sprintf('PRAGMA index_list(%s)', $this->quoteStringLiteral($table)); + } + + /** + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return "SELECT name FROM sqlite_master WHERE type = 'table' AND name != 'sqlite_sequence' AND name != 'geometry_columns' AND name != 'spatial_ref_sys' " + . 'UNION ALL SELECT name FROM sqlite_temp_master ' + . "WHERE type = 'table' ORDER BY name"; + } + + /** + * {@inheritDoc} + */ + public function getListViewsSQL($database) + { + return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; + } + + /** + * {@inheritDoc} + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * {@inheritDoc} + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * {@inheritDoc} + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + + $query .= ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false ? ' ' : ' NOT ') . 'DEFERRABLE'; + $query .= ' INITIALLY ' . ($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false ? 'DEFERRED' : 'IMMEDIATE'); + + return $query; + } + + /** + * {@inheritDoc} + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsColumnCollation() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsInlineColumnComments() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return 'sqlite'; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + $tableName = str_replace('.', '__', $tableIdentifier->getQuotedName($this)); + + return 'DELETE FROM ' . $tableName; + } + + /** + * User-defined function for Sqlite that is used with PDO::sqliteCreateFunction(). + * + * @param int|float $value + * + * @return float + */ + public static function udfSqrt($value) + { + return sqrt($value); + } + + /** + * User-defined function for Sqlite that implements MOD(a, b). + * + * @param int $a + * @param int $b + * + * @return int + */ + public static function udfMod($a, $b) + { + return $a % $b; + } + + /** + * @param string $str + * @param string $substr + * @param int $offset + * + * @return int + */ + public static function udfLocate($str, $substr, $offset = 0) + { + // SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions. + // So we have to make them compatible if an offset is given. + if ($offset > 0) { + $offset -= 1; + } + + $pos = strpos($str, $substr, $offset); + + if ($pos !== false) { + return $pos + 1; + } + + return 0; + } + + /** + * {@inheritDoc} + */ + public function getForUpdateSql() + { + return ''; + } + + /** + * {@inheritDoc} + */ + public function getInlineColumnCommentSQL($comment) + { + return '--' . str_replace("\n", "\n--", $comment) . "\n"; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'boolean' => 'boolean', + 'tinyint' => 'boolean', + 'smallint' => 'smallint', + 'mediumint' => 'integer', + 'int' => 'integer', + 'integer' => 'integer', + 'serial' => 'integer', + 'bigint' => 'bigint', + 'bigserial' => 'bigint', + 'clob' => 'text', + 'tinytext' => 'text', + 'mediumtext' => 'text', + 'longtext' => 'text', + 'text' => 'text', + 'varchar' => 'string', + 'longvarchar' => 'string', + 'varchar2' => 'string', + 'nvarchar' => 'string', + 'image' => 'string', + 'ntext' => 'string', + 'char' => 'string', + 'date' => 'date', + 'datetime' => 'datetime', + 'timestamp' => 'datetime', + 'time' => 'time', + 'float' => 'float', + 'double' => 'float', + 'double precision' => 'float', + 'real' => 'float', + 'decimal' => 'decimal', + 'numeric' => 'decimal', + 'blob' => 'blob', + ]; + } + + /** + * {@inheritDoc} + */ + protected function getReservedKeywordsClass() + { + return Keywords\SQLiteKeywords::class; + } + + /** + * {@inheritDoc} + */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + if (! $diff->fromTable instanceof Table) { + throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema'); + } + + $sql = []; + foreach ($diff->fromTable->getIndexes() as $index) { + if ($index->isPrimary()) { + continue; + } + + $sql[] = $this->getDropIndexSQL($index, $diff->name); + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) + { + if (! $diff->fromTable instanceof Table) { + throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema'); + } + + $sql = []; + $tableName = $diff->newName ? $diff->getNewName(): $diff->getName($this); + foreach ($this->getIndexesInAlteredTable($diff) as $index) { + if ($index->isPrimary()) { + continue; + } + + $sql[] = $this->getCreateIndexSQL($index, $tableName->getQuotedName($this)); + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + if ($limit === null && $offset > 0) { + return $query . ' LIMIT -1 OFFSET ' . $offset; + } + + return parent::doModifyLimitQuery($query, $limit, $offset); + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $field) + { + return 'BLOB'; + } + + /** + * {@inheritDoc} + */ + public function getTemporaryTableName($tableName) + { + $tableName = str_replace('.', '__', $tableName); + + return $tableName; + } + + /** + * {@inheritDoc} + * + * Sqlite Platform emulates schema by underscoring each dot and generating tables + * into the default database. + * + * This hack is implemented to be able to use SQLite as testdriver when + * using schema supporting databases. + */ + public function canEmulateSchemas() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsForeignKeyConstraints() + { + return false; + } + + /** + * {@inheritDoc} + */ + public function getCreatePrimaryKeySQL(Index $index, $table) + { + throw new DBALException('Sqlite platform does not support alter primary key.'); + } + + /** + * {@inheritdoc} + */ + public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table) + { + throw new DBALException('Sqlite platform does not support alter foreign key.'); + } + + /** + * {@inheritdoc} + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + throw new DBALException('Sqlite platform does not support alter foreign key.'); + } + + /** + * {@inheritDoc} + */ + public function getCreateConstraintSQL(Constraint $constraint, $table) + { + throw new DBALException('Sqlite platform does not support alter constraint.'); + } + + /** + * {@inheritDoc} + */ + public function getCreateTableSQL(Table $table, $createFlags = null) + { + $createFlags = $createFlags ?? self::CREATE_INDEXES | self::CREATE_FOREIGNKEYS; + + return parent::getCreateTableSQL($table, $createFlags); + } + + /** + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + $table = str_replace('.', '__', $table); + + return sprintf('PRAGMA foreign_key_list(%s)', $this->quoteStringLiteral($table)); + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = $this->getSimpleAlterTableSQL($diff); + if ($sql !== false) { + return $sql; + } + + $fromTable = $diff->fromTable; + if (! $fromTable instanceof Table) { + throw new DBALException('Sqlite platform requires for alter table the table diff with reference to original table schema'); + } + + $table = clone $fromTable; + + $columns = []; + $oldColumnNames = []; + $newColumnNames = []; + $columnSql = []; + + foreach ($table->getColumns() as $columnName => $column) { + $columnName = strtolower($columnName); + $columns[$columnName] = $column; + $oldColumnNames[$columnName] = $newColumnNames[$columnName] = $column->getQuotedName($this); + } + + foreach ($diff->removedColumns as $columnName => $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $columnName = strtolower($columnName); + if (! isset($columns[$columnName])) { + continue; + } + + unset( + $columns[$columnName], + $oldColumnNames[$columnName], + $newColumnNames[$columnName] + ); + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = strtolower($oldColumnName); + if (isset($columns[$oldColumnName])) { + unset($columns[$oldColumnName]); + } + + $columns[strtolower($column->getName())] = $column; + + if (! isset($newColumnNames[$oldColumnName])) { + continue; + } + + $newColumnNames[$oldColumnName] = $column->getQuotedName($this); + } + + foreach ($diff->changedColumns as $oldColumnName => $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + if (isset($columns[$oldColumnName])) { + unset($columns[$oldColumnName]); + } + + $columns[strtolower($columnDiff->column->getName())] = $columnDiff->column; + + if (! isset($newColumnNames[$oldColumnName])) { + continue; + } + + $newColumnNames[$oldColumnName] = $columnDiff->column->getQuotedName($this); + } + + foreach ($diff->addedColumns as $columnName => $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columns[strtolower($columnName)] = $column; + } + + $sql = []; + $tableSql = []; + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + $dataTable = new Table('__temp__' . $table->getName()); + + $newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions()); + $newTable->addOption('alter', true); + + $sql = $this->getPreAlterTableIndexForeignKeySQL($diff); + //$sql = array_merge($sql, $this->getCreateTableSQL($dataTable, 0)); + $sql[] = sprintf('CREATE TEMPORARY TABLE %s AS SELECT %s FROM %s', $dataTable->getQuotedName($this), implode(', ', $oldColumnNames), $table->getQuotedName($this)); + $sql[] = $this->getDropTableSQL($fromTable); + + $sql = array_merge($sql, $this->getCreateTableSQL($newTable)); + $sql[] = sprintf('INSERT INTO %s (%s) SELECT %s FROM %s', $newTable->getQuotedName($this), implode(', ', $newColumnNames), implode(', ', $oldColumnNames), $dataTable->getQuotedName($this)); + $sql[] = $this->getDropTableSQL($dataTable); + + if ($diff->newName && $diff->newName !== $diff->name) { + $renamedTable = $diff->getNewName(); + $sql[] = 'ALTER TABLE ' . $newTable->getQuotedName($this) . ' RENAME TO ' . $renamedTable->getQuotedName($this); + } + + $sql = array_merge($sql, $this->getPostAlterTableIndexForeignKeySQL($diff)); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * @return string[]|false + */ + private function getSimpleAlterTableSQL(TableDiff $diff) + { + // Suppress changes on integer type autoincrement columns. + foreach ($diff->changedColumns as $oldColumnName => $columnDiff) { + if (! $columnDiff->fromColumn instanceof Column || + ! $columnDiff->column instanceof Column || + ! $columnDiff->column->getAutoincrement() || + ! $columnDiff->column->getType() instanceof Types\IntegerType + ) { + continue; + } + + if (! $columnDiff->hasChanged('type') && $columnDiff->hasChanged('unsigned')) { + unset($diff->changedColumns[$oldColumnName]); + + continue; + } + + $fromColumnType = $columnDiff->fromColumn->getType(); + + if (! ($fromColumnType instanceof Types\SmallIntType) && ! ($fromColumnType instanceof Types\BigIntType)) { + continue; + } + + unset($diff->changedColumns[$oldColumnName]); + } + + if (! empty($diff->renamedColumns) || ! empty($diff->addedForeignKeys) || ! empty($diff->addedIndexes) + || ! empty($diff->changedColumns) || ! empty($diff->changedForeignKeys) || ! empty($diff->changedIndexes) + || ! empty($diff->removedColumns) || ! empty($diff->removedForeignKeys) || ! empty($diff->removedIndexes) + || ! empty($diff->renamedIndexes) + ) { + return false; + } + + $table = new Table($diff->name); + + $sql = []; + $tableSql = []; + $columnSql = []; + + foreach ($diff->addedColumns as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $field = array_merge(['unique' => null, 'autoincrement' => null, 'default' => null], $column->toArray()); + $type = $field['type']; + switch (true) { + case isset($field['columnDefinition']) || $field['autoincrement'] || $field['unique']: + case $type instanceof Types\DateTimeType && $field['default'] === $this->getCurrentTimestampSQL(): + case $type instanceof Types\DateType && $field['default'] === $this->getCurrentDateSQL(): + case $type instanceof Types\TimeType && $field['default'] === $this->getCurrentTimeSQL(): + return false; + } + + $field['name'] = $column->getQuotedName($this); + if ($type instanceof Types\StringType && $field['length'] === null) { + $field['length'] = 255; + } + + $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ADD COLUMN ' . $this->getColumnDeclarationSQL($field['name'], $field); + } + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + if ($diff->newName !== false) { + $newTable = new Identifier($diff->newName); + $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' RENAME TO ' . $newTable->getQuotedName($this); + } + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * @return string[] + */ + private function getColumnNamesInAlteredTable(TableDiff $diff) + { + $columns = []; + + foreach ($diff->fromTable->getColumns() as $columnName => $column) { + $columns[strtolower($columnName)] = $column->getName(); + } + + foreach ($diff->removedColumns as $columnName => $column) { + $columnName = strtolower($columnName); + if (! isset($columns[$columnName])) { + continue; + } + + unset($columns[$columnName]); + } + + foreach ($diff->renamedColumns as $oldColumnName => $column) { + $columnName = $column->getName(); + $columns[strtolower($oldColumnName)] = $columnName; + $columns[strtolower($columnName)] = $columnName; + } + + foreach ($diff->changedColumns as $oldColumnName => $columnDiff) { + $columnName = $columnDiff->column->getName(); + $columns[strtolower($oldColumnName)] = $columnName; + $columns[strtolower($columnName)] = $columnName; + } + + foreach ($diff->addedColumns as $columnName => $column) { + $columns[strtolower($columnName)] = $columnName; + } + + return $columns; + } + + /** + * @return Index[] + */ + private function getIndexesInAlteredTable(TableDiff $diff) + { + $indexes = $diff->fromTable->getIndexes(); + $columnNames = $this->getColumnNamesInAlteredTable($diff); + + foreach ($indexes as $key => $index) { + foreach ($diff->renamedIndexes as $oldIndexName => $renamedIndex) { + if (strtolower($key) !== strtolower($oldIndexName)) { + continue; + } + + unset($indexes[$key]); + } + + $changed = false; + $indexColumns = []; + foreach ($index->getColumns() as $columnName) { + $normalizedColumnName = strtolower($columnName); + if (! isset($columnNames[$normalizedColumnName])) { + unset($indexes[$key]); + continue 2; + } else { + $indexColumns[] = $columnNames[$normalizedColumnName]; + if ($columnName !== $columnNames[$normalizedColumnName]) { + $changed = true; + } + } + } + + if (! $changed) { + continue; + } + + $indexes[$key] = new Index($index->getName(), $indexColumns, $index->isUnique(), $index->isPrimary(), $index->getFlags()); + } + + foreach ($diff->removedIndexes as $index) { + $indexName = strtolower($index->getName()); + if (! strlen($indexName) || ! isset($indexes[$indexName])) { + continue; + } + + unset($indexes[$indexName]); + } + + foreach (array_merge($diff->changedIndexes, $diff->addedIndexes, $diff->renamedIndexes) as $index) { + $indexName = strtolower($index->getName()); + if (strlen($indexName)) { + $indexes[$indexName] = $index; + } else { + $indexes[] = $index; + } + } + + return $indexes; + } + + /** + * @return ForeignKeyConstraint[] + */ + private function getForeignKeysInAlteredTable(TableDiff $diff) + { + $foreignKeys = $diff->fromTable->getForeignKeys(); + $columnNames = $this->getColumnNamesInAlteredTable($diff); + + foreach ($foreignKeys as $key => $constraint) { + $changed = false; + $localColumns = []; + foreach ($constraint->getLocalColumns() as $columnName) { + $normalizedColumnName = strtolower($columnName); + if (! isset($columnNames[$normalizedColumnName])) { + unset($foreignKeys[$key]); + continue 2; + } else { + $localColumns[] = $columnNames[$normalizedColumnName]; + if ($columnName !== $columnNames[$normalizedColumnName]) { + $changed = true; + } + } + } + + if (! $changed) { + continue; + } + + $foreignKeys[$key] = new ForeignKeyConstraint($localColumns, $constraint->getForeignTableName(), $constraint->getForeignColumns(), $constraint->getName(), $constraint->getOptions()); + } + + foreach ($diff->removedForeignKeys as $constraint) { + $constraintName = strtolower($constraint->getName()); + if (! strlen($constraintName) || ! isset($foreignKeys[$constraintName])) { + continue; + } + + unset($foreignKeys[$constraintName]); + } + + foreach (array_merge($diff->changedForeignKeys, $diff->addedForeignKeys) as $constraint) { + $constraintName = strtolower($constraint->getName()); + if (strlen($constraintName)) { + $foreignKeys[$constraintName] = $constraint; + } else { + $foreignKeys[] = $constraint; + } + } + + return $foreignKeys; + } + + /** + * @return Index[] + */ + private function getPrimaryIndexInAlteredTable(TableDiff $diff) + { + $primaryIndex = []; + + foreach ($this->getIndexesInAlteredTable($diff) as $index) { + if (! $index->isPrimary()) { + continue; + } + + $primaryIndex = [$index->getName() => $index]; + } + + return $primaryIndex; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/TrimMode.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/TrimMode.php new file mode 100644 index 000000000..0a4b6ea8c --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/TrimMode.php @@ -0,0 +1,20 @@ +getParams(); + if (isset($params['portability'])) { + if ($this->getDatabasePlatform()->getName() === 'oracle') { + $params['portability'] &= self::PORTABILITY_ORACLE; + } elseif ($this->getDatabasePlatform()->getName() === 'postgresql') { + $params['portability'] &= self::PORTABILITY_POSTGRESQL; + } elseif ($this->getDatabasePlatform()->getName() === 'sqlite') { + $params['portability'] &= self::PORTABILITY_SQLITE; + } elseif ($this->getDatabasePlatform()->getName() === 'drizzle') { + $params['portability'] &= self::PORTABILITY_DRIZZLE; + } elseif ($this->getDatabasePlatform()->getName() === 'sqlanywhere') { + $params['portability'] &= self::PORTABILITY_SQLANYWHERE; + } elseif ($this->getDatabasePlatform()->getName() === 'db2') { + $params['portability'] &= self::PORTABILITY_DB2; + } elseif ($this->getDatabasePlatform()->getName() === 'mssql') { + $params['portability'] &= self::PORTABILITY_SQLSRV; + } else { + $params['portability'] &= self::PORTABILITY_OTHERVENDORS; + } + $this->portability = $params['portability']; + } + + if (isset($params['fetch_case']) && $this->portability & self::PORTABILITY_FIX_CASE) { + if ($this->_conn instanceof PDOConnection) { + // make use of c-level support for case handling + $this->_conn->setAttribute(PDO::ATTR_CASE, $params['fetch_case']); + } else { + $this->case = $params['fetch_case'] === ColumnCase::LOWER ? CASE_LOWER : CASE_UPPER; + } + } + } + + return $ret; + } + + /** + * @return int + */ + public function getPortability() + { + return $this->portability; + } + + /** + * @return int + */ + public function getFetchCase() + { + return $this->case; + } + + /** + * {@inheritdoc} + */ + public function executeQuery($query, array $params = [], $types = [], ?QueryCacheProfile $qcp = null) + { + $stmt = new Statement(parent::executeQuery($query, $params, $types, $qcp), $this); + $stmt->setFetchMode($this->defaultFetchMode); + + return $stmt; + } + + /** + * {@inheritdoc} + */ + public function prepare($statement) + { + $stmt = new Statement(parent::prepare($statement), $this); + $stmt->setFetchMode($this->defaultFetchMode); + + return $stmt; + } + + /** + * {@inheritdoc} + */ + public function query() + { + $this->connect(); + + $stmt = $this->_conn->query(...func_get_args()); + $stmt = new Statement($stmt, $this); + $stmt->setFetchMode($this->defaultFetchMode); + + return $stmt; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php new file mode 100644 index 000000000..1499ff1bf --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Portability/Statement.php @@ -0,0 +1,233 @@ +Statement and applies portability measures. + * + * @param DriverStatement $stmt + */ + public function __construct($stmt, Connection $conn) + { + $this->stmt = $stmt; + $this->portability = $conn->getPortability(); + $this->case = $conn->getFetchCase(); + } + + /** + * {@inheritdoc} + */ + public function bindParam($column, &$variable, $type = ParameterType::STRING, $length = null) + { + return $this->stmt->bindParam($column, $variable, $type, $length); + } + + /** + * {@inheritdoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + return $this->stmt->bindValue($param, $value, $type); + } + + /** + * {@inheritdoc} + */ + public function closeCursor() + { + return $this->stmt->closeCursor(); + } + + /** + * {@inheritdoc} + */ + public function columnCount() + { + return $this->stmt->columnCount(); + } + + /** + * {@inheritdoc} + */ + public function errorCode() + { + return $this->stmt->errorCode(); + } + + /** + * {@inheritdoc} + */ + public function errorInfo() + { + return $this->stmt->errorInfo(); + } + + /** + * {@inheritdoc} + */ + public function execute($params = null) + { + return $this->stmt->execute($params); + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg1 = null, $arg2 = null) + { + $this->defaultFetchMode = $fetchMode; + + return $this->stmt->setFetchMode($fetchMode, $arg1, $arg2); + } + + /** + * {@inheritdoc} + */ + public function getIterator() + { + return new StatementIterator($this); + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + $fetchMode = $fetchMode ?: $this->defaultFetchMode; + + $row = $this->stmt->fetch($fetchMode); + + $iterateRow = $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM); + $fixCase = $this->case !== null + && ($fetchMode === FetchMode::ASSOCIATIVE || $fetchMode === FetchMode::MIXED) + && ($this->portability & Connection::PORTABILITY_FIX_CASE); + + $row = $this->fixRow($row, $iterateRow, $fixCase); + + return $row; + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + $fetchMode = $fetchMode ?: $this->defaultFetchMode; + + if ($fetchArgument) { + $rows = $this->stmt->fetchAll($fetchMode, $fetchArgument); + } else { + $rows = $this->stmt->fetchAll($fetchMode); + } + + $iterateRow = $this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM); + $fixCase = $this->case !== null + && ($fetchMode === FetchMode::ASSOCIATIVE || $fetchMode === FetchMode::MIXED) + && ($this->portability & Connection::PORTABILITY_FIX_CASE); + + if (! $iterateRow && ! $fixCase) { + return $rows; + } + + if ($fetchMode === FetchMode::COLUMN) { + foreach ($rows as $num => $row) { + $rows[$num] = [$row]; + } + } + + foreach ($rows as $num => $row) { + $rows[$num] = $this->fixRow($row, $iterateRow, $fixCase); + } + + if ($fetchMode === FetchMode::COLUMN) { + foreach ($rows as $num => $row) { + $rows[$num] = $row[0]; + } + } + + return $rows; + } + + /** + * @param mixed $row + * @param int $iterateRow + * @param bool $fixCase + * + * @return mixed + */ + protected function fixRow($row, $iterateRow, $fixCase) + { + if (! $row) { + return $row; + } + + if ($fixCase) { + $row = array_change_key_case($row, $this->case); + } + + if ($iterateRow) { + foreach ($row as $k => $v) { + if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $v === '') { + $row[$k] = null; + } elseif (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($v)) { + $row[$k] = rtrim($v); + } + } + } + + return $row; + } + + /** + * {@inheritdoc} + */ + public function fetchColumn($columnIndex = 0) + { + $value = $this->stmt->fetchColumn($columnIndex); + + if ($this->portability & (Connection::PORTABILITY_EMPTY_TO_NULL|Connection::PORTABILITY_RTRIM)) { + if (($this->portability & Connection::PORTABILITY_EMPTY_TO_NULL) && $value === '') { + $value = null; + } elseif (($this->portability & Connection::PORTABILITY_RTRIM) && is_string($value)) { + $value = rtrim($value); + } + } + + return $value; + } + + /** + * {@inheritdoc} + */ + public function rowCount() + { + return $this->stmt->rowCount(); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php new file mode 100644 index 000000000..443d71bc3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/CompositeExpression.php @@ -0,0 +1,120 @@ +type = $type; + + $this->addMultiple($parts); + } + + /** + * Adds multiple parts to composite expression. + * + * @param self[]|string[] $parts + * + * @return \Doctrine\DBAL\Query\Expression\CompositeExpression + */ + public function addMultiple(array $parts = []) + { + foreach ($parts as $part) { + $this->add($part); + } + + return $this; + } + + /** + * Adds an expression to composite expression. + * + * @param mixed $part + * + * @return \Doctrine\DBAL\Query\Expression\CompositeExpression + */ + public function add($part) + { + if (empty($part)) { + return $this; + } + + if ($part instanceof self && count($part) === 0) { + return $this; + } + + $this->parts[] = $part; + + return $this; + } + + /** + * Retrieves the amount of expressions on composite expression. + * + * @return int + */ + public function count() + { + return count($this->parts); + } + + /** + * Retrieves the string representation of this composite expression. + * + * @return string + */ + public function __toString() + { + if ($this->count() === 1) { + return (string) $this->parts[0]; + } + + return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')'; + } + + /** + * Returns the type of this composite expression (AND/OR). + * + * @return string + */ + public function getType() + { + return $this->type; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php new file mode 100644 index 000000000..91f370aec --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php @@ -0,0 +1,298 @@ +'; + public const LT = '<'; + public const LTE = '<='; + public const GT = '>'; + public const GTE = '>='; + + /** + * The DBAL Connection. + * + * @var Connection + */ + private $connection; + + /** + * Initializes a new ExpressionBuilder. + * + * @param Connection $connection The DBAL Connection. + */ + public function __construct(Connection $connection) + { + $this->connection = $connection; + } + + /** + * Creates a conjunction of the given boolean expressions. + * + * Example: + * + * [php] + * // (u.type = ?) AND (u.role = ?) + * $expr->andX('u.type = ?', 'u.role = ?')); + * + * @param mixed $x Optional clause. Defaults = null, but requires + * at least one defined when converting to string. + * + * @return CompositeExpression + */ + public function andX($x = null) + { + return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args()); + } + + /** + * Creates a disjunction of the given boolean expressions. + * + * Example: + * + * [php] + * // (u.type = ?) OR (u.role = ?) + * $qb->where($qb->expr()->orX('u.type = ?', 'u.role = ?')); + * + * @param mixed $x Optional clause. Defaults = null, but requires + * at least one defined when converting to string. + * + * @return CompositeExpression + */ + public function orX($x = null) + { + return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args()); + } + + /** + * Creates a comparison expression. + * + * @param mixed $x The left expression. + * @param string $operator One of the ExpressionBuilder::* constants. + * @param mixed $y The right expression. + * + * @return string + */ + public function comparison($x, $operator, $y) + { + return $x . ' ' . $operator . ' ' . $y; + } + + /** + * Creates an equality comparison expression with the given arguments. + * + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a = . Example: + * + * [php] + * // u.id = ? + * $expr->eq('u.id', '?'); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function eq($x, $y) + { + return $this->comparison($x, self::EQ, $y); + } + + /** + * Creates a non equality comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a <> . Example: + * + * [php] + * // u.id <> 1 + * $q->where($q->expr()->neq('u.id', '1')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function neq($x, $y) + { + return $this->comparison($x, self::NEQ, $y); + } + + /** + * Creates a lower-than comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a < . Example: + * + * [php] + * // u.id < ? + * $q->where($q->expr()->lt('u.id', '?')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function lt($x, $y) + { + return $this->comparison($x, self::LT, $y); + } + + /** + * Creates a lower-than-equal comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a <= . Example: + * + * [php] + * // u.id <= ? + * $q->where($q->expr()->lte('u.id', '?')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function lte($x, $y) + { + return $this->comparison($x, self::LTE, $y); + } + + /** + * Creates a greater-than comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a > . Example: + * + * [php] + * // u.id > ? + * $q->where($q->expr()->gt('u.id', '?')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function gt($x, $y) + { + return $this->comparison($x, self::GT, $y); + } + + /** + * Creates a greater-than-equal comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a >= . Example: + * + * [php] + * // u.id >= ? + * $q->where($q->expr()->gte('u.id', '?')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function gte($x, $y) + { + return $this->comparison($x, self::GTE, $y); + } + + /** + * Creates an IS NULL expression with the given arguments. + * + * @param string $x The field in string format to be restricted by IS NULL. + * + * @return string + */ + public function isNull($x) + { + return $x . ' IS NULL'; + } + + /** + * Creates an IS NOT NULL expression with the given arguments. + * + * @param string $x The field in string format to be restricted by IS NOT NULL. + * + * @return string + */ + public function isNotNull($x) + { + return $x . ' IS NOT NULL'; + } + + /** + * Creates a LIKE() comparison expression with the given arguments. + * + * @param string $x Field in string format to be inspected by LIKE() comparison. + * @param mixed $y Argument to be used in LIKE() comparison. + * + * @return string + */ + public function like($x, $y/*, ?string $escapeChar = null */) + { + return $this->comparison($x, 'LIKE', $y) . + (func_num_args() >= 3 ? sprintf(' ESCAPE %s', func_get_arg(2)) : ''); + } + + /** + * Creates a NOT LIKE() comparison expression with the given arguments. + * + * @param string $x Field in string format to be inspected by NOT LIKE() comparison. + * @param mixed $y Argument to be used in NOT LIKE() comparison. + * + * @return string + */ + public function notLike($x, $y/*, ?string $escapeChar = null */) + { + return $this->comparison($x, 'NOT LIKE', $y) . + (func_num_args() >= 3 ? sprintf(' ESCAPE %s', func_get_arg(2)) : ''); + } + + /** + * Creates a IN () comparison expression with the given arguments. + * + * @param string $x The field in string format to be inspected by IN() comparison. + * @param string|string[] $y The placeholder or the array of values to be used by IN() comparison. + * + * @return string + */ + public function in($x, $y) + { + return $this->comparison($x, 'IN', '(' . implode(', ', (array) $y) . ')'); + } + + /** + * Creates a NOT IN () comparison expression with the given arguments. + * + * @param string $x The field in string format to be inspected by NOT IN() comparison. + * @param string|string[] $y The placeholder or the array of values to be used by NOT IN() comparison. + * + * @return string + */ + public function notIn($x, $y) + { + return $this->comparison($x, 'NOT IN', '(' . implode(', ', (array) $y) . ')'); + } + + /** + * Quotes a given input parameter. + * + * @param mixed $input The parameter to be quoted. + * @param string|null $type The type of the parameter. + * + * @return string + */ + public function literal($input, $type = null) + { + return $this->connection->quote($input, $type); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php new file mode 100644 index 000000000..12584d960 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryBuilder.php @@ -0,0 +1,1347 @@ + [], + 'from' => [], + 'join' => [], + 'set' => [], + 'where' => null, + 'groupBy' => [], + 'having' => null, + 'orderBy' => [], + 'values' => [], + ]; + + /** + * The complete SQL string for this query. + * + * @var string + */ + private $sql; + + /** + * The query parameters. + * + * @var mixed[] + */ + private $params = []; + + /** + * The parameter type map of this query. + * + * @var int[]|string[] + */ + private $paramTypes = []; + + /** + * The type of query this is. Can be select, update or delete. + * + * @var int + */ + private $type = self::SELECT; + + /** + * The state of the query object. Can be dirty or clean. + * + * @var int + */ + private $state = self::STATE_CLEAN; + + /** + * The index of the first result to retrieve. + * + * @var int + */ + private $firstResult = null; + + /** + * The maximum number of results to retrieve. + * + * @var int + */ + private $maxResults = null; + + /** + * The counter of bound parameters used with {@see bindValue). + * + * @var int + */ + private $boundCounter = 0; + + /** + * Initializes a new QueryBuilder. + * + * @param Connection $connection The DBAL Connection. + */ + public function __construct(Connection $connection) + { + $this->connection = $connection; + } + + /** + * Gets an ExpressionBuilder used for object-oriented construction of query expressions. + * This producer method is intended for convenient inline usage. Example: + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where($qb->expr()->eq('u.id', 1)); + * + * + * For more complex expression construction, consider storing the expression + * builder object in a local variable. + * + * @return ExpressionBuilder + */ + public function expr() + { + return $this->connection->getExpressionBuilder(); + } + + /** + * Gets the type of the currently built query. + * + * @return int + */ + public function getType() + { + return $this->type; + } + + /** + * Gets the associated DBAL Connection for this query builder. + * + * @return Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Gets the state of this query builder instance. + * + * @return int Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN. + */ + public function getState() + { + return $this->state; + } + + /** + * Executes this query using the bound parameters and their types. + * + * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate} + * for insert, update and delete statements. + * + * @return Statement|int + */ + public function execute() + { + if ($this->type === self::SELECT) { + return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes); + } + + return $this->connection->executeUpdate($this->getSQL(), $this->params, $this->paramTypes); + } + + /** + * Gets the complete SQL string formed by the current specifications of this QueryBuilder. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * echo $qb->getSQL(); // SELECT u FROM User u + * + * + * @return string The SQL query string. + */ + public function getSQL() + { + if ($this->sql !== null && $this->state === self::STATE_CLEAN) { + return $this->sql; + } + + switch ($this->type) { + case self::INSERT: + $sql = $this->getSQLForInsert(); + break; + case self::DELETE: + $sql = $this->getSQLForDelete(); + break; + + case self::UPDATE: + $sql = $this->getSQLForUpdate(); + break; + + case self::SELECT: + default: + $sql = $this->getSQLForSelect(); + break; + } + + $this->state = self::STATE_CLEAN; + $this->sql = $sql; + + return $sql; + } + + /** + * Sets a query parameter for the query being constructed. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.id = :user_id') + * ->setParameter(':user_id', 1); + * + * + * @param string|int $key The parameter position or name. + * @param mixed $value The parameter value. + * @param string|int|null $type One of the {@link \Doctrine\DBAL\ParameterType} constants. + * + * @return $this This QueryBuilder instance. + */ + public function setParameter($key, $value, $type = null) + { + if ($type !== null) { + $this->paramTypes[$key] = $type; + } + + $this->params[$key] = $value; + + return $this; + } + + /** + * Sets a collection of query parameters for the query being constructed. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.id = :user_id1 OR u.id = :user_id2') + * ->setParameters(array( + * ':user_id1' => 1, + * ':user_id2' => 2 + * )); + * + * + * @param mixed[] $params The query parameters to set. + * @param int[]|string[] $types The query parameters types to set. + * + * @return $this This QueryBuilder instance. + */ + public function setParameters(array $params, array $types = []) + { + $this->paramTypes = $types; + $this->params = $params; + + return $this; + } + + /** + * Gets all defined query parameters for the query being constructed indexed by parameter index or name. + * + * @return mixed[] The currently defined query parameters indexed by parameter index or name. + */ + public function getParameters() + { + return $this->params; + } + + /** + * Gets a (previously set) query parameter of the query being constructed. + * + * @param mixed $key The key (index or name) of the bound parameter. + * + * @return mixed The value of the bound parameter. + */ + public function getParameter($key) + { + return $this->params[$key] ?? null; + } + + /** + * Gets all defined query parameter types for the query being constructed indexed by parameter index or name. + * + * @return int[]|string[] The currently defined query parameter types indexed by parameter index or name. + */ + public function getParameterTypes() + { + return $this->paramTypes; + } + + /** + * Gets a (previously set) query parameter type of the query being constructed. + * + * @param mixed $key The key (index or name) of the bound parameter type. + * + * @return mixed The value of the bound parameter type. + */ + public function getParameterType($key) + { + return $this->paramTypes[$key] ?? null; + } + + /** + * Sets the position of the first result to retrieve (the "offset"). + * + * @param int $firstResult The first result to return. + * + * @return $this This QueryBuilder instance. + */ + public function setFirstResult($firstResult) + { + $this->state = self::STATE_DIRTY; + $this->firstResult = $firstResult; + + return $this; + } + + /** + * Gets the position of the first result the query object was set to retrieve (the "offset"). + * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder. + * + * @return int The position of the first result. + */ + public function getFirstResult() + { + return $this->firstResult; + } + + /** + * Sets the maximum number of results to retrieve (the "limit"). + * + * @param int $maxResults The maximum number of results to retrieve. + * + * @return $this This QueryBuilder instance. + */ + public function setMaxResults($maxResults) + { + $this->state = self::STATE_DIRTY; + $this->maxResults = $maxResults; + + return $this; + } + + /** + * Gets the maximum number of results the query object was set to retrieve (the "limit"). + * Returns NULL if {@link setMaxResults} was not applied to this query builder. + * + * @return int The maximum number of results. + */ + public function getMaxResults() + { + return $this->maxResults; + } + + /** + * Either appends to or replaces a single, generic query part. + * + * The available parts are: 'select', 'from', 'set', 'where', + * 'groupBy', 'having' and 'orderBy'. + * + * @param string $sqlPartName + * @param string $sqlPart + * @param bool $append + * + * @return $this This QueryBuilder instance. + */ + public function add($sqlPartName, $sqlPart, $append = false) + { + $isArray = is_array($sqlPart); + $isMultiple = is_array($this->sqlParts[$sqlPartName]); + + if ($isMultiple && ! $isArray) { + $sqlPart = [$sqlPart]; + } + + $this->state = self::STATE_DIRTY; + + if ($append) { + if ($sqlPartName === 'orderBy' || $sqlPartName === 'groupBy' || $sqlPartName === 'select' || $sqlPartName === 'set') { + foreach ($sqlPart as $part) { + $this->sqlParts[$sqlPartName][] = $part; + } + } elseif ($isArray && is_array($sqlPart[key($sqlPart)])) { + $key = key($sqlPart); + $this->sqlParts[$sqlPartName][$key][] = $sqlPart[$key]; + } elseif ($isMultiple) { + $this->sqlParts[$sqlPartName][] = $sqlPart; + } else { + $this->sqlParts[$sqlPartName] = $sqlPart; + } + + return $this; + } + + $this->sqlParts[$sqlPartName] = $sqlPart; + + return $this; + } + + /** + * Specifies an item that is to be returned in the query result. + * Replaces any previously specified selections, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id', 'p.id') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id'); + * + * + * @param mixed $select The selection expressions. + * + * @return $this This QueryBuilder instance. + */ + public function select($select = null) + { + $this->type = self::SELECT; + + if (empty($select)) { + return $this; + } + + $selects = is_array($select) ? $select : func_get_args(); + + return $this->add('select', $selects); + } + + /** + * Adds an item that is to be returned in the query result. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id') + * ->addSelect('p.id') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id'); + * + * + * @param mixed $select The selection expression. + * + * @return $this This QueryBuilder instance. + */ + public function addSelect($select = null) + { + $this->type = self::SELECT; + + if (empty($select)) { + return $this; + } + + $selects = is_array($select) ? $select : func_get_args(); + + return $this->add('select', $selects, true); + } + + /** + * Turns the query being built into a bulk delete query that ranges over + * a certain table. + * + * + * $qb = $conn->createQueryBuilder() + * ->delete('users', 'u') + * ->where('u.id = :user_id'); + * ->setParameter(':user_id', 1); + * + * + * @param string $delete The table whose rows are subject to the deletion. + * @param string $alias The table alias used in the constructed query. + * + * @return $this This QueryBuilder instance. + */ + public function delete($delete = null, $alias = null) + { + $this->type = self::DELETE; + + if (! $delete) { + return $this; + } + + return $this->add('from', [ + 'table' => $delete, + 'alias' => $alias, + ]); + } + + /** + * Turns the query being built into a bulk update query that ranges over + * a certain table + * + * + * $qb = $conn->createQueryBuilder() + * ->update('counters', 'c') + * ->set('c.value', 'c.value + 1') + * ->where('c.id = ?'); + * + * + * @param string $update The table whose rows are subject to the update. + * @param string $alias The table alias used in the constructed query. + * + * @return $this This QueryBuilder instance. + */ + public function update($update = null, $alias = null) + { + $this->type = self::UPDATE; + + if (! $update) { + return $this; + } + + return $this->add('from', [ + 'table' => $update, + 'alias' => $alias, + ]); + } + + /** + * Turns the query being built into an insert query that inserts into + * a certain table + * + * + * $qb = $conn->createQueryBuilder() + * ->insert('users') + * ->values( + * array( + * 'name' => '?', + * 'password' => '?' + * ) + * ); + * + * + * @param string $insert The table into which the rows should be inserted. + * + * @return $this This QueryBuilder instance. + */ + public function insert($insert = null) + { + $this->type = self::INSERT; + + if (! $insert) { + return $this; + } + + return $this->add('from', ['table' => $insert]); + } + + /** + * Creates and adds a query root corresponding to the table identified by the + * given alias, forming a cartesian product with any existing query roots. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id') + * ->from('users', 'u') + * + * + * @param string $from The table. + * @param string|null $alias The alias of the table. + * + * @return $this This QueryBuilder instance. + */ + public function from($from, $alias = null) + { + return $this->add('from', [ + 'table' => $from, + 'alias' => $alias, + ], true); + } + + /** + * Creates and adds a join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause. + * @param string $join The table name to join. + * @param string $alias The alias of the join table. + * @param string $condition The condition for the join. + * + * @return $this This QueryBuilder instance. + */ + public function join($fromAlias, $join, $alias, $condition = null) + { + return $this->innerJoin($fromAlias, $join, $alias, $condition); + } + + /** + * Creates and adds a join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause. + * @param string $join The table name to join. + * @param string $alias The alias of the join table. + * @param string $condition The condition for the join. + * + * @return $this This QueryBuilder instance. + */ + public function innerJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', [ + $fromAlias => [ + 'joinType' => 'inner', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition, + ], + ], true); + } + + /** + * Creates and adds a left join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause. + * @param string $join The table name to join. + * @param string $alias The alias of the join table. + * @param string $condition The condition for the join. + * + * @return $this This QueryBuilder instance. + */ + public function leftJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', [ + $fromAlias => [ + 'joinType' => 'left', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition, + ], + ], true); + } + + /** + * Creates and adds a right join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause. + * @param string $join The table name to join. + * @param string $alias The alias of the join table. + * @param string $condition The condition for the join. + * + * @return $this This QueryBuilder instance. + */ + public function rightJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', [ + $fromAlias => [ + 'joinType' => 'right', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition, + ], + ], true); + } + + /** + * Sets a new value for a column in a bulk update query. + * + * + * $qb = $conn->createQueryBuilder() + * ->update('counters', 'c') + * ->set('c.value', 'c.value + 1') + * ->where('c.id = ?'); + * + * + * @param string $key The column to set. + * @param string $value The value, expression, placeholder, etc. + * + * @return $this This QueryBuilder instance. + */ + public function set($key, $value) + { + return $this->add('set', $key . ' = ' . $value, true); + } + + /** + * Specifies one or more restrictions to the query result. + * Replaces any previously specified restrictions, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('c.value') + * ->from('counters', 'c') + * ->where('c.id = ?'); + * + * // You can optionally programatically build and/or expressions + * $qb = $conn->createQueryBuilder(); + * + * $or = $qb->expr()->orx(); + * $or->add($qb->expr()->eq('c.id', 1)); + * $or->add($qb->expr()->eq('c.id', 2)); + * + * $qb->update('counters', 'c') + * ->set('c.value', 'c.value + 1') + * ->where($or); + * + * + * @param mixed $predicates The restriction predicates. + * + * @return $this This QueryBuilder instance. + */ + public function where($predicates) + { + if (! (func_num_args() === 1 && $predicates instanceof CompositeExpression)) { + $predicates = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args()); + } + + return $this->add('where', $predicates); + } + + /** + * Adds one or more restrictions to the query results, forming a logical + * conjunction with any previously specified restrictions. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.username LIKE ?') + * ->andWhere('u.is_active = 1'); + * + * + * @see where() + * + * @param mixed $where The query restrictions. + * + * @return $this This QueryBuilder instance. + */ + public function andWhere($where) + { + $args = func_get_args(); + $where = $this->getQueryPart('where'); + + if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_AND) { + $where->addMultiple($args); + } else { + array_unshift($args, $where); + $where = new CompositeExpression(CompositeExpression::TYPE_AND, $args); + } + + return $this->add('where', $where, true); + } + + /** + * Adds one or more restrictions to the query results, forming a logical + * disjunction with any previously specified restrictions. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->where('u.id = 1') + * ->orWhere('u.id = 2'); + * + * + * @see where() + * + * @param mixed $where The WHERE statement. + * + * @return $this This QueryBuilder instance. + */ + public function orWhere($where) + { + $args = func_get_args(); + $where = $this->getQueryPart('where'); + + if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_OR) { + $where->addMultiple($args); + } else { + array_unshift($args, $where); + $where = new CompositeExpression(CompositeExpression::TYPE_OR, $args); + } + + return $this->add('where', $where, true); + } + + /** + * Specifies a grouping over the results of the query. + * Replaces any previously specified groupings, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->groupBy('u.id'); + * + * + * @param mixed $groupBy The grouping expression. + * + * @return $this This QueryBuilder instance. + */ + public function groupBy($groupBy) + { + if (empty($groupBy)) { + return $this; + } + + $groupBy = is_array($groupBy) ? $groupBy : func_get_args(); + + return $this->add('groupBy', $groupBy, false); + } + + + /** + * Adds a grouping expression to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->groupBy('u.lastLogin'); + * ->addGroupBy('u.createdAt') + * + * + * @param mixed $groupBy The grouping expression. + * + * @return $this This QueryBuilder instance. + */ + public function addGroupBy($groupBy) + { + if (empty($groupBy)) { + return $this; + } + + $groupBy = is_array($groupBy) ? $groupBy : func_get_args(); + + return $this->add('groupBy', $groupBy, true); + } + + /** + * Sets a value for a column in an insert query. + * + * + * $qb = $conn->createQueryBuilder() + * ->insert('users') + * ->values( + * array( + * 'name' => '?' + * ) + * ) + * ->setValue('password', '?'); + * + * + * @param string $column The column into which the value should be inserted. + * @param string $value The value that should be inserted into the column. + * + * @return $this This QueryBuilder instance. + */ + public function setValue($column, $value) + { + $this->sqlParts['values'][$column] = $value; + + return $this; + } + + /** + * Specifies values for an insert query indexed by column names. + * Replaces any previous values, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->insert('users') + * ->values( + * array( + * 'name' => '?', + * 'password' => '?' + * ) + * ); + * + * + * @param mixed[] $values The values to specify for the insert query indexed by column names. + * + * @return $this This QueryBuilder instance. + */ + public function values(array $values) + { + return $this->add('values', $values); + } + + /** + * Specifies a restriction over the groups of the query. + * Replaces any previous having restrictions, if any. + * + * @param mixed $having The restriction over the groups. + * + * @return $this This QueryBuilder instance. + */ + public function having($having) + { + if (! (func_num_args() === 1 && $having instanceof CompositeExpression)) { + $having = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args()); + } + + return $this->add('having', $having); + } + + /** + * Adds a restriction over the groups of the query, forming a logical + * conjunction with any existing having restrictions. + * + * @param mixed $having The restriction to append. + * + * @return $this This QueryBuilder instance. + */ + public function andHaving($having) + { + $args = func_get_args(); + $having = $this->getQueryPart('having'); + + if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_AND) { + $having->addMultiple($args); + } else { + array_unshift($args, $having); + $having = new CompositeExpression(CompositeExpression::TYPE_AND, $args); + } + + return $this->add('having', $having); + } + + /** + * Adds a restriction over the groups of the query, forming a logical + * disjunction with any existing having restrictions. + * + * @param mixed $having The restriction to add. + * + * @return $this This QueryBuilder instance. + */ + public function orHaving($having) + { + $args = func_get_args(); + $having = $this->getQueryPart('having'); + + if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_OR) { + $having->addMultiple($args); + } else { + array_unshift($args, $having); + $having = new CompositeExpression(CompositeExpression::TYPE_OR, $args); + } + + return $this->add('having', $having); + } + + /** + * Specifies an ordering for the query results. + * Replaces any previously specified orderings, if any. + * + * @param string $sort The ordering expression. + * @param string $order The ordering direction. + * + * @return $this This QueryBuilder instance. + */ + public function orderBy($sort, $order = null) + { + return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), false); + } + + /** + * Adds an ordering to the query results. + * + * @param string $sort The ordering expression. + * @param string $order The ordering direction. + * + * @return $this This QueryBuilder instance. + */ + public function addOrderBy($sort, $order = null) + { + return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), true); + } + + /** + * Gets a query part by its name. + * + * @param string $queryPartName + * + * @return mixed + */ + public function getQueryPart($queryPartName) + { + return $this->sqlParts[$queryPartName]; + } + + /** + * Gets all query parts. + * + * @return mixed[] + */ + public function getQueryParts() + { + return $this->sqlParts; + } + + /** + * Resets SQL parts. + * + * @param string[]|null $queryPartNames + * + * @return $this This QueryBuilder instance. + */ + public function resetQueryParts($queryPartNames = null) + { + if ($queryPartNames === null) { + $queryPartNames = array_keys($this->sqlParts); + } + + foreach ($queryPartNames as $queryPartName) { + $this->resetQueryPart($queryPartName); + } + + return $this; + } + + /** + * Resets a single SQL part. + * + * @param string $queryPartName + * + * @return $this This QueryBuilder instance. + */ + public function resetQueryPart($queryPartName) + { + $this->sqlParts[$queryPartName] = is_array($this->sqlParts[$queryPartName]) + ? [] : null; + + $this->state = self::STATE_DIRTY; + + return $this; + } + + /** + * @return string + * + * @throws QueryException + */ + private function getSQLForSelect() + { + $query = 'SELECT ' . implode(', ', $this->sqlParts['select']); + + $query .= ($this->sqlParts['from'] ? ' FROM ' . implode(', ', $this->getFromClauses()) : '') + . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '') + . ($this->sqlParts['groupBy'] ? ' GROUP BY ' . implode(', ', $this->sqlParts['groupBy']) : '') + . ($this->sqlParts['having'] !== null ? ' HAVING ' . ((string) $this->sqlParts['having']) : '') + . ($this->sqlParts['orderBy'] ? ' ORDER BY ' . implode(', ', $this->sqlParts['orderBy']) : ''); + + if ($this->isLimitQuery()) { + return $this->connection->getDatabasePlatform()->modifyLimitQuery( + $query, + $this->maxResults, + $this->firstResult + ); + } + + return $query; + } + + /** + * @return string[] + */ + private function getFromClauses() + { + $fromClauses = []; + $knownAliases = []; + + // Loop through all FROM clauses + foreach ($this->sqlParts['from'] as $from) { + if ($from['alias'] === null) { + $tableSql = $from['table']; + $tableReference = $from['table']; + } else { + $tableSql = $from['table'] . ' ' . $from['alias']; + $tableReference = $from['alias']; + } + + $knownAliases[$tableReference] = true; + + $fromClauses[$tableReference] = $tableSql . $this->getSQLForJoins($tableReference, $knownAliases); + } + + $this->verifyAllAliasesAreKnown($knownAliases); + + return $fromClauses; + } + + /** + * @param string[] $knownAliases + * + * @throws QueryException + */ + private function verifyAllAliasesAreKnown(array $knownAliases) + { + foreach ($this->sqlParts['join'] as $fromAlias => $joins) { + if (! isset($knownAliases[$fromAlias])) { + throw QueryException::unknownAlias($fromAlias, array_keys($knownAliases)); + } + } + } + + /** + * @return bool + */ + private function isLimitQuery() + { + return $this->maxResults !== null || $this->firstResult !== null; + } + + /** + * Converts this instance into an INSERT string in SQL. + * + * @return string + */ + private function getSQLForInsert() + { + return 'INSERT INTO ' . $this->sqlParts['from']['table'] . + ' (' . implode(', ', array_keys($this->sqlParts['values'])) . ')' . + ' VALUES(' . implode(', ', $this->sqlParts['values']) . ')'; + } + + /** + * Converts this instance into an UPDATE string in SQL. + * + * @return string + */ + private function getSQLForUpdate() + { + $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); + return 'UPDATE ' . $table + . ' SET ' . implode(', ', $this->sqlParts['set']) + . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); + } + + /** + * Converts this instance into a DELETE string in SQL. + * + * @return string + */ + private function getSQLForDelete() + { + $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); + return 'DELETE FROM ' . $table . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); + } + + /** + * Gets a string representation of this QueryBuilder which corresponds to + * the final SQL query being constructed. + * + * @return string The string representation of this QueryBuilder. + */ + public function __toString() + { + return $this->getSQL(); + } + + /** + * Creates a new named parameter and bind the value $value to it. + * + * This method provides a shortcut for PDOStatement::bindValue + * when using prepared statements. + * + * The parameter $value specifies the value that you want to bind. If + * $placeholder is not provided bindValue() will automatically create a + * placeholder for you. An automatic placeholder will be of the name + * ':dcValue1', ':dcValue2' etc. + * + * For more information see {@link http://php.net/pdostatement-bindparam} + * + * Example: + * + * $value = 2; + * $q->eq( 'id', $q->bindValue( $value ) ); + * $stmt = $q->executeQuery(); // executed with 'id = 2' + * + * + * @link http://www.zetacomponents.org + * + * @param mixed $value + * @param mixed $type + * @param string $placeHolder The name to bind with. The string must start with a colon ':'. + * + * @return string the placeholder name used. + */ + public function createNamedParameter($value, $type = ParameterType::STRING, $placeHolder = null) + { + if ($placeHolder === null) { + $this->boundCounter++; + $placeHolder = ':dcValue' . $this->boundCounter; + } + $this->setParameter(substr($placeHolder, 1), $value, $type); + + return $placeHolder; + } + + /** + * Creates a new positional parameter and bind the given value to it. + * + * Attention: If you are using positional parameters with the query builder you have + * to be very careful to bind all parameters in the order they appear in the SQL + * statement , otherwise they get bound in the wrong order which can lead to serious + * bugs in your code. + * + * Example: + * + * $qb = $conn->createQueryBuilder(); + * $qb->select('u.*') + * ->from('users', 'u') + * ->where('u.username = ' . $qb->createPositionalParameter('Foo', ParameterType::STRING)) + * ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', ParameterType::STRING)) + * + * + * @param mixed $value + * @param int $type + * + * @return string + */ + public function createPositionalParameter($value, $type = ParameterType::STRING) + { + $this->boundCounter++; + $this->setParameter($this->boundCounter, $value, $type); + + return '?'; + } + + /** + * @param string $fromAlias + * @param string[] $knownAliases + * + * @return string + * + * @throws QueryException + */ + private function getSQLForJoins($fromAlias, array &$knownAliases) + { + $sql = ''; + + if (isset($this->sqlParts['join'][$fromAlias])) { + foreach ($this->sqlParts['join'][$fromAlias] as $join) { + if (array_key_exists($join['joinAlias'], $knownAliases)) { + throw QueryException::nonUniqueAlias($join['joinAlias'], array_keys($knownAliases)); + } + $sql .= ' ' . strtoupper($join['joinType']) + . ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias'] + . ' ON ' . ((string) $join['joinCondition']); + $knownAliases[$join['joinAlias']] = true; + } + + foreach ($this->sqlParts['join'][$fromAlias] as $join) { + $sql .= $this->getSQLForJoins($join['joinAlias'], $knownAliases); + } + } + + return $sql; + } + + /** + * Deep clone of all expression objects in the SQL parts. + * + * @return void + */ + public function __clone() + { + foreach ($this->sqlParts as $part => $elements) { + if (is_array($this->sqlParts[$part])) { + foreach ($this->sqlParts[$part] as $idx => $element) { + if (! is_object($element)) { + continue; + } + + $this->sqlParts[$part][$idx] = clone $element; + } + } elseif (is_object($elements)) { + $this->sqlParts[$part] = clone $elements; + } + } + + foreach ($this->params as $name => $param) { + if (! is_object($param)) { + continue; + } + + $this->params[$name] = clone $param; + } + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php new file mode 100644 index 000000000..3fcb3b480 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/QueryException.php @@ -0,0 +1,35 @@ + integer pair (indexed from zero) for a positional statement + * and a string => int[] pair for a named statement. + * + * @param string $statement + * @param bool $isPositional + * + * @return int[] + */ + public static function getPlaceholderPositions($statement, $isPositional = true) + { + $match = $isPositional ? '?' : ':'; + if (strpos($statement, $match) === false) { + return []; + } + + $token = $isPositional ? self::POSITIONAL_TOKEN : self::NAMED_TOKEN; + $paramMap = []; + + foreach (self::getUnquotedStatementFragments($statement) as $fragment) { + preg_match_all('/' . $token . '/', $fragment[0], $matches, PREG_OFFSET_CAPTURE); + foreach ($matches[0] as $placeholder) { + if ($isPositional) { + $paramMap[] = $placeholder[1] + $fragment[1]; + } else { + $pos = $placeholder[1] + $fragment[1]; + $paramMap[$pos] = substr($placeholder[0], 1, strlen($placeholder[0])); + } + } + } + + return $paramMap; + } + + /** + * For a positional query this method can rewrite the sql statement with regard to array parameters. + * + * @param string $query The SQL query to execute. + * @param mixed[] $params The parameters to bind to the query. + * @param int[]|string[] $types The types the previous parameters are in. + * + * @return mixed[] + * + * @throws SQLParserUtilsException + */ + public static function expandListParameters($query, $params, $types) + { + $isPositional = is_int(key($params)); + $arrayPositions = []; + $bindIndex = -1; + + if ($isPositional) { + ksort($params); + ksort($types); + } + + foreach ($types as $name => $type) { + ++$bindIndex; + + if ($type !== Connection::PARAM_INT_ARRAY && $type !== Connection::PARAM_STR_ARRAY) { + continue; + } + + if ($isPositional) { + $name = $bindIndex; + } + + $arrayPositions[$name] = false; + } + + if (( ! $arrayPositions && $isPositional)) { + return [$query, $params, $types]; + } + + $paramPos = self::getPlaceholderPositions($query, $isPositional); + + if ($isPositional) { + $paramOffset = 0; + $queryOffset = 0; + $params = array_values($params); + $types = array_values($types); + + foreach ($paramPos as $needle => $needlePos) { + if (! isset($arrayPositions[$needle])) { + continue; + } + + $needle += $paramOffset; + $needlePos += $queryOffset; + $count = count($params[$needle]); + + $params = array_merge( + array_slice($params, 0, $needle), + $params[$needle], + array_slice($params, $needle + 1) + ); + + $types = array_merge( + array_slice($types, 0, $needle), + $count ? + // array needles are at {@link \Doctrine\DBAL\ParameterType} constants + // + {@link Doctrine\DBAL\Connection::ARRAY_PARAM_OFFSET} + array_fill(0, $count, $types[$needle] - Connection::ARRAY_PARAM_OFFSET) : + [], + array_slice($types, $needle + 1) + ); + + $expandStr = $count ? implode(', ', array_fill(0, $count, '?')) : 'NULL'; + $query = substr($query, 0, $needlePos) . $expandStr . substr($query, $needlePos + 1); + + $paramOffset += ($count - 1); // Grows larger by number of parameters minus the replaced needle. + $queryOffset += (strlen($expandStr) - 1); + } + + return [$query, $params, $types]; + } + + $queryOffset = 0; + $typesOrd = []; + $paramsOrd = []; + + foreach ($paramPos as $pos => $paramName) { + $paramLen = strlen($paramName) + 1; + $value = static::extractParam($paramName, $params, true); + + if (! isset($arrayPositions[$paramName]) && ! isset($arrayPositions[':' . $paramName])) { + $pos += $queryOffset; + $queryOffset -= ($paramLen - 1); + $paramsOrd[] = $value; + $typesOrd[] = static::extractParam($paramName, $types, false, ParameterType::STRING); + $query = substr($query, 0, $pos) . '?' . substr($query, ($pos + $paramLen)); + + continue; + } + + $count = count($value); + $expandStr = $count > 0 ? implode(', ', array_fill(0, $count, '?')) : 'NULL'; + + foreach ($value as $val) { + $paramsOrd[] = $val; + $typesOrd[] = static::extractParam($paramName, $types, false) - Connection::ARRAY_PARAM_OFFSET; + } + + $pos += $queryOffset; + $queryOffset += (strlen($expandStr) - $paramLen); + $query = substr($query, 0, $pos) . $expandStr . substr($query, ($pos + $paramLen)); + } + + return [$query, $paramsOrd, $typesOrd]; + } + + /** + * Slice the SQL statement around pairs of quotes and + * return string fragments of SQL outside of quoted literals. + * Each fragment is captured as a 2-element array: + * + * 0 => matched fragment string, + * 1 => offset of fragment in $statement + * + * @param string $statement + * + * @return mixed[][] + */ + private static function getUnquotedStatementFragments($statement) + { + $literal = self::ESCAPED_SINGLE_QUOTED_TEXT . '|' . + self::ESCAPED_DOUBLE_QUOTED_TEXT . '|' . + self::ESCAPED_BACKTICK_QUOTED_TEXT . '|' . + self::ESCAPED_BRACKET_QUOTED_TEXT; + $expression = sprintf('/((.+(?i:ARRAY)\\[.+\\])|([^\'"`\\[]+))(?:%s)?/s', $literal); + + preg_match_all($expression, $statement, $fragments, PREG_OFFSET_CAPTURE); + + return $fragments[1]; + } + + /** + * @param string $paramName The name of the parameter (without a colon in front) + * @param mixed $paramsOrTypes A hash of parameters or types + * @param bool $isParam + * @param mixed $defaultValue An optional default value. If omitted, an exception is thrown + * + * @return mixed + * + * @throws SQLParserUtilsException + */ + private static function extractParam($paramName, $paramsOrTypes, $isParam, $defaultValue = null) + { + if (array_key_exists($paramName, $paramsOrTypes)) { + return $paramsOrTypes[$paramName]; + } + + // Hash keys can be prefixed with a colon for compatibility + if (array_key_exists(':' . $paramName, $paramsOrTypes)) { + return $paramsOrTypes[':' . $paramName]; + } + + if ($defaultValue !== null) { + return $defaultValue; + } + + if ($isParam) { + throw SQLParserUtilsException::missingParam($paramName); + } + + throw SQLParserUtilsException::missingType($paramName); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php new file mode 100644 index 000000000..a500ed52d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtilsException.php @@ -0,0 +1,31 @@ + Table($tableName)); if you want to rename the table, you have to make sure + */ +abstract class AbstractAsset +{ + /** @var string */ + protected $_name; + + /** + * Namespace of the asset. If none isset the default namespace is assumed. + * + * @var string|null + */ + protected $_namespace = null; + + /** @var bool */ + protected $_quoted = false; + + /** + * Sets the name of this asset. + * + * @param string $name + * + * @return void + */ + protected function _setName($name) + { + if ($this->isIdentifierQuoted($name)) { + $this->_quoted = true; + $name = $this->trimQuotes($name); + } + if (strpos($name, '.') !== false) { + $parts = explode('.', $name); + $this->_namespace = $parts[0]; + $name = $parts[1]; + } + $this->_name = $name; + } + + /** + * Is this asset in the default namespace? + * + * @param string $defaultNamespaceName + * + * @return bool + */ + public function isInDefaultNamespace($defaultNamespaceName) + { + return $this->_namespace === $defaultNamespaceName || $this->_namespace === null; + } + + /** + * Gets the namespace name of this asset. + * + * If NULL is returned this means the default namespace is used. + * + * @return string|null + */ + public function getNamespaceName() + { + return $this->_namespace; + } + + /** + * The shortest name is stripped of the default namespace. All other + * namespaced elements are returned as full-qualified names. + * + * @param string $defaultNamespaceName + * + * @return string + */ + public function getShortestName($defaultNamespaceName) + { + $shortestName = $this->getName(); + if ($this->_namespace === $defaultNamespaceName) { + $shortestName = $this->_name; + } + + return strtolower($shortestName); + } + + /** + * The normalized name is full-qualified and lowerspaced. Lowerspacing is + * actually wrong, but we have to do it to keep our sanity. If you are + * using database objects that only differentiate in the casing (FOO vs + * Foo) then you will NOT be able to use Doctrine Schema abstraction. + * + * Every non-namespaced element is prefixed with the default namespace + * name which is passed as argument to this method. + * + * @param string $defaultNamespaceName + * + * @return string + */ + public function getFullQualifiedName($defaultNamespaceName) + { + $name = $this->getName(); + if (! $this->_namespace) { + $name = $defaultNamespaceName . '.' . $name; + } + + return strtolower($name); + } + + /** + * Checks if this asset's name is quoted. + * + * @return bool + */ + public function isQuoted() + { + return $this->_quoted; + } + + /** + * Checks if this identifier is quoted. + * + * @param string $identifier + * + * @return bool + */ + protected function isIdentifierQuoted($identifier) + { + return isset($identifier[0]) && ($identifier[0] === '`' || $identifier[0] === '"' || $identifier[0] === '['); + } + + /** + * Trim quotes from the identifier. + * + * @param string $identifier + * + * @return string + */ + protected function trimQuotes($identifier) + { + return str_replace(['`', '"', '[', ']'], '', $identifier); + } + + /** + * Returns the name of this schema asset. + * + * @return string + */ + public function getName() + { + if ($this->_namespace) { + return $this->_namespace . '.' . $this->_name; + } + + return $this->_name; + } + + /** + * Gets the quoted representation of this asset but only if it was defined with one. Otherwise + * return the plain unquoted value as inserted. + * + * @return string + */ + public function getQuotedName(AbstractPlatform $platform) + { + $keywords = $platform->getReservedKeywordsList(); + $parts = explode('.', $this->getName()); + foreach ($parts as $k => $v) { + $parts[$k] = $this->_quoted || $keywords->isKeyword($v) ? $platform->quoteIdentifier($v) : $v; + } + + return implode('.', $parts); + } + + /** + * Generates an identifier from a list of column names obeying a certain string length. + * + * This is especially important for Oracle, since it does not allow identifiers larger than 30 chars, + * however building idents automatically for foreign keys, composite keys or such can easily create + * very long names. + * + * @param string[] $columnNames + * @param string $prefix + * @param int $maxSize + * + * @return string + */ + protected function _generateIdentifierName($columnNames, $prefix = '', $maxSize = 30) + { + $hash = implode('', array_map(static function ($column) { + return dechex(crc32($column)); + }, $columnNames)); + + return strtoupper(substr($prefix . '_' . $hash, 0, $maxSize)); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php new file mode 100644 index 000000000..9b917427f --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php @@ -0,0 +1,1130 @@ +_conn = $conn; + $this->_platform = $platform ?: $this->_conn->getDatabasePlatform(); + } + + /** + * Returns the associated platform. + * + * @return AbstractPlatform + */ + public function getDatabasePlatform() + { + return $this->_platform; + } + + /** + * Tries any method on the schema manager. Normally a method throws an + * exception when your DBMS doesn't support it or if an error occurs. + * This method allows you to try and method on your SchemaManager + * instance and will return false if it does not work or is not supported. + * + * + * $result = $sm->tryMethod('dropView', 'view_name'); + * + * + * @return mixed + */ + public function tryMethod() + { + $args = func_get_args(); + $method = $args[0]; + unset($args[0]); + $args = array_values($args); + + try { + return call_user_func_array([$this, $method], $args); + } catch (Throwable $e) { + return false; + } + } + + /** + * Lists the available databases for this connection. + * + * @return string[] + */ + public function listDatabases() + { + $sql = $this->_platform->getListDatabasesSQL(); + + $databases = $this->_conn->fetchAll($sql); + + return $this->_getPortableDatabasesList($databases); + } + + /** + * Returns a list of all namespaces in the current database. + * + * @return string[] + */ + public function listNamespaceNames() + { + $sql = $this->_platform->getListNamespacesSQL(); + + $namespaces = $this->_conn->fetchAll($sql); + + return $this->getPortableNamespacesList($namespaces); + } + + /** + * Lists the available sequences for this connection. + * + * @param string|null $database + * + * @return Sequence[] + */ + public function listSequences($database = null) + { + if ($database === null) { + $database = $this->_conn->getDatabase(); + } + $sql = $this->_platform->getListSequencesSQL($database); + + $sequences = $this->_conn->fetchAll($sql); + + return $this->filterAssetNames($this->_getPortableSequencesList($sequences)); + } + + /** + * Lists the columns for a given table. + * + * In contrast to other libraries and to the old version of Doctrine, + * this column definition does try to contain the 'primary' field for + * the reason that it is not portable across different RDBMS. Use + * {@see listTableIndexes($tableName)} to retrieve the primary key + * of a table. We're a RDBMS specifies more details these are held + * in the platformDetails array. + * + * @param string $table The name of the table. + * @param string|null $database + * + * @return Column[] + */ + public function listTableColumns($table, $database = null) + { + if (! $database) { + $database = $this->_conn->getDatabase(); + } + + $sql = $this->_platform->getListTableColumnsSQL($table, $database); + + $tableColumns = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableColumnList($table, $database, $tableColumns); + } + + /** + * Lists the indexes for a given table returning an array of Index instances. + * + * Keys of the portable indexes list are all lower-cased. + * + * @param string $table The name of the table. + * + * @return Index[] + */ + public function listTableIndexes($table) + { + $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase()); + + $tableIndexes = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableIndexesList($tableIndexes, $table); + } + + /** + * Returns true if all the given tables exist. + * + * @param string[] $tableNames + * + * @return bool + */ + public function tablesExist($tableNames) + { + $tableNames = array_map('strtolower', (array) $tableNames); + + return count($tableNames) === count(array_intersect($tableNames, array_map('strtolower', $this->listTableNames()))); + } + + /** + * Returns a list of all tables in the current database. + * + * @return string[] + */ + public function listTableNames() + { + $sql = $this->_platform->getListTablesSQL(); + + $tables = $this->_conn->fetchAll($sql); + $tableNames = $this->_getPortableTablesList($tables); + + return $this->filterAssetNames($tableNames); + } + + /** + * Filters asset names if they are configured to return only a subset of all + * the found elements. + * + * @param mixed[] $assetNames + * + * @return mixed[] + */ + protected function filterAssetNames($assetNames) + { + $filter = $this->_conn->getConfiguration()->getSchemaAssetsFilter(); + if (! $filter) { + return $assetNames; + } + + return array_values(array_filter($assetNames, $filter)); + } + + /** + * @deprecated Use Configuration::getSchemaAssetsFilter() instead + * + * @return string|null + */ + protected function getFilterSchemaAssetsExpression() + { + return $this->_conn->getConfiguration()->getFilterSchemaAssetsExpression(); + } + + /** + * Lists the tables for this connection. + * + * @return Table[] + */ + public function listTables() + { + $tableNames = $this->listTableNames(); + + $tables = []; + foreach ($tableNames as $tableName) { + $tables[] = $this->listTableDetails($tableName); + } + + return $tables; + } + + /** + * @param string $tableName + * + * @return Table + */ + public function listTableDetails($tableName) + { + $columns = $this->listTableColumns($tableName); + $foreignKeys = []; + if ($this->_platform->supportsForeignKeyConstraints()) { + $foreignKeys = $this->listTableForeignKeys($tableName); + } + $indexes = $this->listTableIndexes($tableName); + + return new Table($tableName, $columns, $indexes, $foreignKeys, false, []); + } + + /** + * Lists the views this connection has. + * + * @return View[] + */ + public function listViews() + { + $database = $this->_conn->getDatabase(); + $sql = $this->_platform->getListViewsSQL($database); + $views = $this->_conn->fetchAll($sql); + + return $this->_getPortableViewsList($views); + } + + /** + * Lists the foreign keys for the given table. + * + * @param string $table The name of the table. + * @param string|null $database + * + * @return ForeignKeyConstraint[] + */ + public function listTableForeignKeys($table, $database = null) + { + if ($database === null) { + $database = $this->_conn->getDatabase(); + } + $sql = $this->_platform->getListTableForeignKeysSQL($table, $database); + $tableForeignKeys = $this->_conn->fetchAll($sql); + + return $this->_getPortableTableForeignKeysList($tableForeignKeys); + } + + /* drop*() Methods */ + + /** + * Drops a database. + * + * NOTE: You can not drop the database this SchemaManager is currently connected to. + * + * @param string $database The name of the database to drop. + * + * @return void + */ + public function dropDatabase($database) + { + $this->_execSql($this->_platform->getDropDatabaseSQL($database)); + } + + /** + * Drops the given table. + * + * @param string $tableName The name of the table to drop. + * + * @return void + */ + public function dropTable($tableName) + { + $this->_execSql($this->_platform->getDropTableSQL($tableName)); + } + + /** + * Drops the index from the given table. + * + * @param Index|string $index The name of the index. + * @param Table|string $table The name of the table. + * + * @return void + */ + public function dropIndex($index, $table) + { + if ($index instanceof Index) { + $index = $index->getQuotedName($this->_platform); + } + + $this->_execSql($this->_platform->getDropIndexSQL($index, $table)); + } + + /** + * Drops the constraint from the given table. + * + * @param Table|string $table The name of the table. + * + * @return void + */ + public function dropConstraint(Constraint $constraint, $table) + { + $this->_execSql($this->_platform->getDropConstraintSQL($constraint, $table)); + } + + /** + * Drops a foreign key from a table. + * + * @param ForeignKeyConstraint|string $foreignKey The name of the foreign key. + * @param Table|string $table The name of the table with the foreign key. + * + * @return void + */ + public function dropForeignKey($foreignKey, $table) + { + $this->_execSql($this->_platform->getDropForeignKeySQL($foreignKey, $table)); + } + + /** + * Drops a sequence with a given name. + * + * @param string $name The name of the sequence to drop. + * + * @return void + */ + public function dropSequence($name) + { + $this->_execSql($this->_platform->getDropSequenceSQL($name)); + } + + /** + * Drops a view. + * + * @param string $name The name of the view. + * + * @return void + */ + public function dropView($name) + { + $this->_execSql($this->_platform->getDropViewSQL($name)); + } + + /* create*() Methods */ + + /** + * Creates a new database. + * + * @param string $database The name of the database to create. + * + * @return void + */ + public function createDatabase($database) + { + $this->_execSql($this->_platform->getCreateDatabaseSQL($database)); + } + + /** + * Creates a new table. + * + * @return void + */ + public function createTable(Table $table) + { + $createFlags = AbstractPlatform::CREATE_INDEXES|AbstractPlatform::CREATE_FOREIGNKEYS; + $this->_execSql($this->_platform->getCreateTableSQL($table, $createFlags)); + } + + /** + * Creates a new sequence. + * + * @param Sequence $sequence + * + * @return void + * + * @throws ConnectionException If something fails at database level. + */ + public function createSequence($sequence) + { + $this->_execSql($this->_platform->getCreateSequenceSQL($sequence)); + } + + /** + * Creates a constraint on a table. + * + * @param Table|string $table + * + * @return void + */ + public function createConstraint(Constraint $constraint, $table) + { + $this->_execSql($this->_platform->getCreateConstraintSQL($constraint, $table)); + } + + /** + * Creates a new index on a table. + * + * @param Table|string $table The name of the table on which the index is to be created. + * + * @return void + */ + public function createIndex(Index $index, $table) + { + $this->_execSql($this->_platform->getCreateIndexSQL($index, $table)); + } + + /** + * Creates a new foreign key. + * + * @param ForeignKeyConstraint $foreignKey The ForeignKey instance. + * @param Table|string $table The name of the table on which the foreign key is to be created. + * + * @return void + */ + public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + $this->_execSql($this->_platform->getCreateForeignKeySQL($foreignKey, $table)); + } + + /** + * Creates a new view. + * + * @return void + */ + public function createView(View $view) + { + $this->_execSql($this->_platform->getCreateViewSQL($view->getQuotedName($this->_platform), $view->getSql())); + } + + /* dropAndCreate*() Methods */ + + /** + * Drops and creates a constraint. + * + * @see dropConstraint() + * @see createConstraint() + * + * @param Table|string $table + * + * @return void + */ + public function dropAndCreateConstraint(Constraint $constraint, $table) + { + $this->tryMethod('dropConstraint', $constraint, $table); + $this->createConstraint($constraint, $table); + } + + /** + * Drops and creates a new index on a table. + * + * @param Table|string $table The name of the table on which the index is to be created. + * + * @return void + */ + public function dropAndCreateIndex(Index $index, $table) + { + $this->tryMethod('dropIndex', $index->getQuotedName($this->_platform), $table); + $this->createIndex($index, $table); + } + + /** + * Drops and creates a new foreign key. + * + * @param ForeignKeyConstraint $foreignKey An associative array that defines properties of the foreign key to be created. + * @param Table|string $table The name of the table on which the foreign key is to be created. + * + * @return void + */ + public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + $this->tryMethod('dropForeignKey', $foreignKey, $table); + $this->createForeignKey($foreignKey, $table); + } + + /** + * Drops and create a new sequence. + * + * @return void + * + * @throws ConnectionException If something fails at database level. + */ + public function dropAndCreateSequence(Sequence $sequence) + { + $this->tryMethod('dropSequence', $sequence->getQuotedName($this->_platform)); + $this->createSequence($sequence); + } + + /** + * Drops and creates a new table. + * + * @return void + */ + public function dropAndCreateTable(Table $table) + { + $this->tryMethod('dropTable', $table->getQuotedName($this->_platform)); + $this->createTable($table); + } + + /** + * Drops and creates a new database. + * + * @param string $database The name of the database to create. + * + * @return void + */ + public function dropAndCreateDatabase($database) + { + $this->tryMethod('dropDatabase', $database); + $this->createDatabase($database); + } + + /** + * Drops and creates a new view. + * + * @return void + */ + public function dropAndCreateView(View $view) + { + $this->tryMethod('dropView', $view->getQuotedName($this->_platform)); + $this->createView($view); + } + + /* alterTable() Methods */ + + /** + * Alters an existing tables schema. + * + * @return void + */ + public function alterTable(TableDiff $tableDiff) + { + $queries = $this->_platform->getAlterTableSQL($tableDiff); + if (! is_array($queries) || ! count($queries)) { + return; + } + + foreach ($queries as $ddlQuery) { + $this->_execSql($ddlQuery); + } + } + + /** + * Renames a given table to another name. + * + * @param string $name The current name of the table. + * @param string $newName The new name of the table. + * + * @return void + */ + public function renameTable($name, $newName) + { + $tableDiff = new TableDiff($name); + $tableDiff->newName = $newName; + $this->alterTable($tableDiff); + } + + /** + * Methods for filtering return values of list*() methods to convert + * the native DBMS data definition to a portable Doctrine definition + */ + + /** + * @param mixed[] $databases + * + * @return string[] + */ + protected function _getPortableDatabasesList($databases) + { + $list = []; + foreach ($databases as $value) { + $value = $this->_getPortableDatabaseDefinition($value); + + if (! $value) { + continue; + } + + $list[] = $value; + } + + return $list; + } + + /** + * Converts a list of namespace names from the native DBMS data definition to a portable Doctrine definition. + * + * @param mixed[][] $namespaces The list of namespace names in the native DBMS data definition. + * + * @return string[] + */ + protected function getPortableNamespacesList(array $namespaces) + { + $namespacesList = []; + + foreach ($namespaces as $namespace) { + $namespacesList[] = $this->getPortableNamespaceDefinition($namespace); + } + + return $namespacesList; + } + + /** + * @param mixed $database + * + * @return mixed + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database; + } + + /** + * Converts a namespace definition from the native DBMS data definition to a portable Doctrine definition. + * + * @param mixed[] $namespace The native DBMS namespace definition. + * + * @return mixed + */ + protected function getPortableNamespaceDefinition(array $namespace) + { + return $namespace; + } + + /** + * @param mixed[][] $functions + * + * @return mixed[][] + */ + protected function _getPortableFunctionsList($functions) + { + $list = []; + foreach ($functions as $value) { + $value = $this->_getPortableFunctionDefinition($value); + + if (! $value) { + continue; + } + + $list[] = $value; + } + + return $list; + } + + /** + * @param mixed[] $function + * + * @return mixed + */ + protected function _getPortableFunctionDefinition($function) + { + return $function; + } + + /** + * @param mixed[][] $triggers + * + * @return mixed[][] + */ + protected function _getPortableTriggersList($triggers) + { + $list = []; + foreach ($triggers as $value) { + $value = $this->_getPortableTriggerDefinition($value); + + if (! $value) { + continue; + } + + $list[] = $value; + } + + return $list; + } + + /** + * @param mixed[] $trigger + * + * @return mixed + */ + protected function _getPortableTriggerDefinition($trigger) + { + return $trigger; + } + + /** + * @param mixed[][] $sequences + * + * @return Sequence[] + */ + protected function _getPortableSequencesList($sequences) + { + $list = []; + foreach ($sequences as $value) { + $value = $this->_getPortableSequenceDefinition($value); + + if (! $value) { + continue; + } + + $list[] = $value; + } + + return $list; + } + + /** + * @param mixed[] $sequence + * + * @return Sequence + * + * @throws DBALException + */ + protected function _getPortableSequenceDefinition($sequence) + { + throw DBALException::notSupported('Sequences'); + } + + /** + * Independent of the database the keys of the column list result are lowercased. + * + * The name of the created column instance however is kept in its case. + * + * @param string $table The name of the table. + * @param string $database + * @param mixed[][] $tableColumns + * + * @return Column[] + */ + protected function _getPortableTableColumnList($table, $database, $tableColumns) + { + $eventManager = $this->_platform->getEventManager(); + + $list = []; + foreach ($tableColumns as $tableColumn) { + $column = null; + $defaultPrevented = false; + + if ($eventManager !== null && $eventManager->hasListeners(Events::onSchemaColumnDefinition)) { + $eventArgs = new SchemaColumnDefinitionEventArgs($tableColumn, $table, $database, $this->_conn); + $eventManager->dispatchEvent(Events::onSchemaColumnDefinition, $eventArgs); + + $defaultPrevented = $eventArgs->isDefaultPrevented(); + $column = $eventArgs->getColumn(); + } + + if (! $defaultPrevented) { + $column = $this->_getPortableTableColumnDefinition($tableColumn); + } + + if (! $column) { + continue; + } + + $name = strtolower($column->getQuotedName($this->_platform)); + $list[$name] = $column; + } + + return $list; + } + + /** + * Gets Table Column Definition. + * + * @param mixed[] $tableColumn + * + * @return Column + */ + abstract protected function _getPortableTableColumnDefinition($tableColumn); + + /** + * Aggregates and groups the index results according to the required data result. + * + * @param mixed[][] $tableIndexRows + * @param string|null $tableName + * + * @return Index[] + */ + protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null) + { + $result = []; + foreach ($tableIndexRows as $tableIndex) { + $indexName = $keyName = $tableIndex['key_name']; + if ($tableIndex['primary']) { + $keyName = 'primary'; + } + $keyName = strtolower($keyName); + + if (! isset($result[$keyName])) { + $options = [ + 'lengths' => [], + ]; + + if (isset($tableIndex['where'])) { + $options['where'] = $tableIndex['where']; + } + + $result[$keyName] = [ + 'name' => $indexName, + 'columns' => [], + 'unique' => $tableIndex['non_unique'] ? false : true, + 'primary' => $tableIndex['primary'], + 'flags' => $tableIndex['flags'] ?? [], + 'options' => $options, + ]; + } + + $result[$keyName]['columns'][] = $tableIndex['column_name']; + $result[$keyName]['options']['lengths'][] = $tableIndex['length'] ?? null; + } + + $eventManager = $this->_platform->getEventManager(); + + $indexes = []; + foreach ($result as $indexKey => $data) { + $index = null; + $defaultPrevented = false; + + if ($eventManager !== null && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) { + $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn); + $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs); + + $defaultPrevented = $eventArgs->isDefaultPrevented(); + $index = $eventArgs->getIndex(); + } + + if (! $defaultPrevented) { + $index = new Index($data['name'], $data['columns'], $data['unique'], $data['primary'], $data['flags'], $data['options']); + } + + if (! $index) { + continue; + } + + $indexes[$indexKey] = $index; + } + + return $indexes; + } + + /** + * @param mixed[][] $tables + * + * @return string[] + */ + protected function _getPortableTablesList($tables) + { + $list = []; + foreach ($tables as $value) { + $value = $this->_getPortableTableDefinition($value); + + if (! $value) { + continue; + } + + $list[] = $value; + } + + return $list; + } + + /** + * @param mixed $table + * + * @return string + */ + protected function _getPortableTableDefinition($table) + { + return $table; + } + + /** + * @param mixed[][] $users + * + * @return string[][] + */ + protected function _getPortableUsersList($users) + { + $list = []; + foreach ($users as $value) { + $value = $this->_getPortableUserDefinition($value); + + if (! $value) { + continue; + } + + $list[] = $value; + } + + return $list; + } + + /** + * @param mixed[] $user + * + * @return mixed[] + */ + protected function _getPortableUserDefinition($user) + { + return $user; + } + + /** + * @param mixed[][] $views + * + * @return View[] + */ + protected function _getPortableViewsList($views) + { + $list = []; + foreach ($views as $value) { + $view = $this->_getPortableViewDefinition($value); + + if (! $view) { + continue; + } + + $viewName = strtolower($view->getQuotedName($this->_platform)); + $list[$viewName] = $view; + } + + return $list; + } + + /** + * @param mixed[] $view + * + * @return View|false + */ + protected function _getPortableViewDefinition($view) + { + return false; + } + + /** + * @param mixed[][] $tableForeignKeys + * + * @return ForeignKeyConstraint[] + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = []; + foreach ($tableForeignKeys as $value) { + $value = $this->_getPortableTableForeignKeyDefinition($value); + + if (! $value) { + continue; + } + + $list[] = $value; + } + + return $list; + } + + /** + * @param mixed $tableForeignKey + * + * @return ForeignKeyConstraint + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return $tableForeignKey; + } + + /** + * @param string[]|string $sql + * + * @return void + */ + protected function _execSql($sql) + { + foreach ((array) $sql as $query) { + $this->_conn->executeUpdate($query); + } + } + + /** + * Creates a schema instance for the current database. + * + * @return Schema + */ + public function createSchema() + { + $namespaces = []; + + if ($this->_platform->supportsSchemas()) { + $namespaces = $this->listNamespaceNames(); + } + + $sequences = []; + + if ($this->_platform->supportsSequences()) { + $sequences = $this->listSequences(); + } + + $tables = $this->listTables(); + + return new Schema($tables, $sequences, $this->createSchemaConfig(), $namespaces); + } + + /** + * Creates the configuration for this schema. + * + * @return SchemaConfig + */ + public function createSchemaConfig() + { + $schemaConfig = new SchemaConfig(); + $schemaConfig->setMaxIdentifierLength($this->_platform->getMaxIdentifierLength()); + + $searchPaths = $this->getSchemaSearchPaths(); + if (isset($searchPaths[0])) { + $schemaConfig->setName($searchPaths[0]); + } + + $params = $this->_conn->getParams(); + if (! isset($params['defaultTableOptions'])) { + $params['defaultTableOptions'] = []; + } + if (! isset($params['defaultTableOptions']['charset']) && isset($params['charset'])) { + $params['defaultTableOptions']['charset'] = $params['charset']; + } + $schemaConfig->setDefaultTableOptions($params['defaultTableOptions']); + + return $schemaConfig; + } + + /** + * The search path for namespaces in the currently connected database. + * + * The first entry is usually the default namespace in the Schema. All + * further namespaces contain tables/sequences which can also be addressed + * with a short, not full-qualified name. + * + * For databases that don't support subschema/namespaces this method + * returns the name of the currently connected database. + * + * @return string[] + */ + public function getSchemaSearchPaths() + { + return [$this->_conn->getDatabase()]; + } + + /** + * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns + * the type given as default. + * + * @param string $comment + * @param string $currentType + * + * @return string + */ + public function extractDoctrineTypeFromComment($comment, $currentType) + { + if (preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match)) { + $currentType = $match[1]; + } + + return $currentType; + } + + /** + * @param string $comment + * @param string $type + * + * @return string + */ + public function removeDoctrineTypeFromComment($comment, $type) + { + return str_replace('(DC2Type:' . $type . ')', '', $comment); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php new file mode 100644 index 000000000..aef471e06 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php @@ -0,0 +1,451 @@ +_setName($columnName); + $this->setType($type); + $this->setOptions($options); + } + + /** + * @param mixed[] $options + * + * @return Column + */ + public function setOptions(array $options) + { + foreach ($options as $name => $value) { + $method = 'set' . $name; + if (! method_exists($this, $method)) { + // next major: throw an exception + @trigger_error(sprintf( + 'The "%s" column option is not supported,' . + ' setting it is deprecated and will cause an error in Doctrine 3.0', + $name + ), E_USER_DEPRECATED); + + continue; + } + $this->$method($value); + } + + return $this; + } + + /** + * @return Column + */ + public function setType(Type $type) + { + $this->_type = $type; + + return $this; + } + + /** + * @param int|null $length + * + * @return Column + */ + public function setLength($length) + { + if ($length !== null) { + $this->_length = (int) $length; + } else { + $this->_length = null; + } + + return $this; + } + + /** + * @param int $precision + * + * @return Column + */ + public function setPrecision($precision) + { + if (! is_numeric($precision)) { + $precision = 10; // defaults to 10 when no valid precision is given. + } + + $this->_precision = (int) $precision; + + return $this; + } + + /** + * @param int $scale + * + * @return Column + */ + public function setScale($scale) + { + if (! is_numeric($scale)) { + $scale = 0; + } + + $this->_scale = (int) $scale; + + return $this; + } + + /** + * @param bool $unsigned + * + * @return Column + */ + public function setUnsigned($unsigned) + { + $this->_unsigned = (bool) $unsigned; + + return $this; + } + + /** + * @param bool $fixed + * + * @return Column + */ + public function setFixed($fixed) + { + $this->_fixed = (bool) $fixed; + + return $this; + } + + /** + * @param bool $notnull + * + * @return Column + */ + public function setNotnull($notnull) + { + $this->_notnull = (bool) $notnull; + + return $this; + } + + /** + * @param mixed $default + * + * @return Column + */ + public function setDefault($default) + { + $this->_default = $default; + + return $this; + } + + /** + * @param mixed[] $platformOptions + * + * @return Column + */ + public function setPlatformOptions(array $platformOptions) + { + $this->_platformOptions = $platformOptions; + + return $this; + } + + /** + * @param string $name + * @param mixed $value + * + * @return Column + */ + public function setPlatformOption($name, $value) + { + $this->_platformOptions[$name] = $value; + + return $this; + } + + /** + * @param string $value + * + * @return Column + */ + public function setColumnDefinition($value) + { + $this->_columnDefinition = $value; + + return $this; + } + + /** + * @return Type + */ + public function getType() + { + return $this->_type; + } + + /** + * @return int|null + */ + public function getLength() + { + return $this->_length; + } + + /** + * @return int + */ + public function getPrecision() + { + return $this->_precision; + } + + /** + * @return int + */ + public function getScale() + { + return $this->_scale; + } + + /** + * @return bool + */ + public function getUnsigned() + { + return $this->_unsigned; + } + + /** + * @return bool + */ + public function getFixed() + { + return $this->_fixed; + } + + /** + * @return bool + */ + public function getNotnull() + { + return $this->_notnull; + } + + /** + * @return string|null + */ + public function getDefault() + { + return $this->_default; + } + + /** + * @return mixed[] + */ + public function getPlatformOptions() + { + return $this->_platformOptions; + } + + /** + * @param string $name + * + * @return bool + */ + public function hasPlatformOption($name) + { + return isset($this->_platformOptions[$name]); + } + + /** + * @param string $name + * + * @return mixed + */ + public function getPlatformOption($name) + { + return $this->_platformOptions[$name]; + } + + /** + * @return string|null + */ + public function getColumnDefinition() + { + return $this->_columnDefinition; + } + + /** + * @return bool + */ + public function getAutoincrement() + { + return $this->_autoincrement; + } + + /** + * @param bool $flag + * + * @return Column + */ + public function setAutoincrement($flag) + { + $this->_autoincrement = $flag; + + return $this; + } + + /** + * @param string $comment + * + * @return Column + */ + public function setComment($comment) + { + $this->_comment = $comment; + + return $this; + } + + /** + * @return string|null + */ + public function getComment() + { + return $this->_comment; + } + + /** + * @param string $name + * @param mixed $value + * + * @return Column + */ + public function setCustomSchemaOption($name, $value) + { + $this->_customSchemaOptions[$name] = $value; + + return $this; + } + + /** + * @param string $name + * + * @return bool + */ + public function hasCustomSchemaOption($name) + { + return isset($this->_customSchemaOptions[$name]); + } + + /** + * @param string $name + * + * @return mixed + */ + public function getCustomSchemaOption($name) + { + return $this->_customSchemaOptions[$name]; + } + + /** + * @param mixed[] $customSchemaOptions + * + * @return Column + */ + public function setCustomSchemaOptions(array $customSchemaOptions) + { + $this->_customSchemaOptions = $customSchemaOptions; + + return $this; + } + + /** + * @return mixed[] + */ + public function getCustomSchemaOptions() + { + return $this->_customSchemaOptions; + } + + /** + * @return mixed[] + */ + public function toArray() + { + return array_merge([ + 'name' => $this->_name, + 'type' => $this->_type, + 'default' => $this->_default, + 'notnull' => $this->_notnull, + 'length' => $this->_length, + 'precision' => $this->_precision, + 'scale' => $this->_scale, + 'fixed' => $this->_fixed, + 'unsigned' => $this->_unsigned, + 'autoincrement' => $this->_autoincrement, + 'columnDefinition' => $this->_columnDefinition, + 'comment' => $this->_comment, + ], $this->_platformOptions, $this->_customSchemaOptions); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php new file mode 100644 index 000000000..cb6459210 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ColumnDiff.php @@ -0,0 +1,55 @@ +oldColumnName = $oldColumnName; + $this->column = $column; + $this->changedProperties = $changedProperties; + $this->fromColumn = $fromColumn; + } + + /** + * @param string $propertyName + * + * @return bool + */ + public function hasChanged($propertyName) + { + return in_array($propertyName, $this->changedProperties); + } + + /** + * @return Identifier + */ + public function getOldColumnName() + { + $quote = $this->fromColumn && $this->fromColumn->isQuoted(); + + return new Identifier($this->oldColumnName, $quote); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php new file mode 100644 index 000000000..1d8a7275d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php @@ -0,0 +1,524 @@ +compare($fromSchema, $toSchema); + } + + /** + * Returns a SchemaDiff object containing the differences between the schemas $fromSchema and $toSchema. + * + * The returned differences are returned in such a way that they contain the + * operations to change the schema stored in $fromSchema to the schema that is + * stored in $toSchema. + * + * @return SchemaDiff + */ + public function compare(Schema $fromSchema, Schema $toSchema) + { + $diff = new SchemaDiff(); + $diff->fromSchema = $fromSchema; + + $foreignKeysToTable = []; + + foreach ($toSchema->getNamespaces() as $namespace) { + if ($fromSchema->hasNamespace($namespace)) { + continue; + } + + $diff->newNamespaces[$namespace] = $namespace; + } + + foreach ($fromSchema->getNamespaces() as $namespace) { + if ($toSchema->hasNamespace($namespace)) { + continue; + } + + $diff->removedNamespaces[$namespace] = $namespace; + } + + foreach ($toSchema->getTables() as $table) { + $tableName = $table->getShortestName($toSchema->getName()); + if (! $fromSchema->hasTable($tableName)) { + $diff->newTables[$tableName] = $toSchema->getTable($tableName); + } else { + $tableDifferences = $this->diffTable($fromSchema->getTable($tableName), $toSchema->getTable($tableName)); + if ($tableDifferences !== false) { + $diff->changedTables[$tableName] = $tableDifferences; + } + } + } + + /* Check if there are tables removed */ + foreach ($fromSchema->getTables() as $table) { + $tableName = $table->getShortestName($fromSchema->getName()); + + $table = $fromSchema->getTable($tableName); + if (! $toSchema->hasTable($tableName)) { + $diff->removedTables[$tableName] = $table; + } + + // also remember all foreign keys that point to a specific table + foreach ($table->getForeignKeys() as $foreignKey) { + $foreignTable = strtolower($foreignKey->getForeignTableName()); + if (! isset($foreignKeysToTable[$foreignTable])) { + $foreignKeysToTable[$foreignTable] = []; + } + $foreignKeysToTable[$foreignTable][] = $foreignKey; + } + } + + foreach ($diff->removedTables as $tableName => $table) { + if (! isset($foreignKeysToTable[$tableName])) { + continue; + } + + $diff->orphanedForeignKeys = array_merge($diff->orphanedForeignKeys, $foreignKeysToTable[$tableName]); + + // deleting duplicated foreign keys present on both on the orphanedForeignKey + // and the removedForeignKeys from changedTables + foreach ($foreignKeysToTable[$tableName] as $foreignKey) { + // strtolower the table name to make if compatible with getShortestName + $localTableName = strtolower($foreignKey->getLocalTableName()); + if (! isset($diff->changedTables[$localTableName])) { + continue; + } + + foreach ($diff->changedTables[$localTableName]->removedForeignKeys as $key => $removedForeignKey) { + // We check if the key is from the removed table if not we skip. + if ($tableName !== strtolower($removedForeignKey->getForeignTableName())) { + continue; + } + unset($diff->changedTables[$localTableName]->removedForeignKeys[$key]); + } + } + } + + foreach ($toSchema->getSequences() as $sequence) { + $sequenceName = $sequence->getShortestName($toSchema->getName()); + if (! $fromSchema->hasSequence($sequenceName)) { + if (! $this->isAutoIncrementSequenceInSchema($fromSchema, $sequence)) { + $diff->newSequences[] = $sequence; + } + } else { + if ($this->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) { + $diff->changedSequences[] = $toSchema->getSequence($sequenceName); + } + } + } + + foreach ($fromSchema->getSequences() as $sequence) { + if ($this->isAutoIncrementSequenceInSchema($toSchema, $sequence)) { + continue; + } + + $sequenceName = $sequence->getShortestName($fromSchema->getName()); + + if ($toSchema->hasSequence($sequenceName)) { + continue; + } + + $diff->removedSequences[] = $sequence; + } + + return $diff; + } + + /** + * @param Schema $schema + * @param Sequence $sequence + * + * @return bool + */ + private function isAutoIncrementSequenceInSchema($schema, $sequence) + { + foreach ($schema->getTables() as $table) { + if ($sequence->isAutoIncrementsFor($table)) { + return true; + } + } + + return false; + } + + /** + * @return bool + */ + public function diffSequence(Sequence $sequence1, Sequence $sequence2) + { + if ($sequence1->getAllocationSize() !== $sequence2->getAllocationSize()) { + return true; + } + + return $sequence1->getInitialValue() !== $sequence2->getInitialValue(); + } + + /** + * Returns the difference between the tables $table1 and $table2. + * + * If there are no differences this method returns the boolean false. + * + * @return TableDiff|false + */ + public function diffTable(Table $table1, Table $table2) + { + $changes = 0; + $tableDifferences = new TableDiff($table1->getName()); + $tableDifferences->fromTable = $table1; + + $table1Columns = $table1->getColumns(); + $table2Columns = $table2->getColumns(); + + /* See if all the fields in table 1 exist in table 2 */ + foreach ($table2Columns as $columnName => $column) { + if ($table1->hasColumn($columnName)) { + continue; + } + + $tableDifferences->addedColumns[$columnName] = $column; + $changes++; + } + /* See if there are any removed fields in table 2 */ + foreach ($table1Columns as $columnName => $column) { + // See if column is removed in table 2. + if (! $table2->hasColumn($columnName)) { + $tableDifferences->removedColumns[$columnName] = $column; + $changes++; + continue; + } + + // See if column has changed properties in table 2. + $changedProperties = $this->diffColumn($column, $table2->getColumn($columnName)); + + if (empty($changedProperties)) { + continue; + } + + $columnDiff = new ColumnDiff($column->getName(), $table2->getColumn($columnName), $changedProperties); + $columnDiff->fromColumn = $column; + $tableDifferences->changedColumns[$column->getName()] = $columnDiff; + $changes++; + } + + $this->detectColumnRenamings($tableDifferences); + + $table1Indexes = $table1->getIndexes(); + $table2Indexes = $table2->getIndexes(); + + /* See if all the indexes in table 1 exist in table 2 */ + foreach ($table2Indexes as $indexName => $index) { + if (($index->isPrimary() && $table1->hasPrimaryKey()) || $table1->hasIndex($indexName)) { + continue; + } + + $tableDifferences->addedIndexes[$indexName] = $index; + $changes++; + } + /* See if there are any removed indexes in table 2 */ + foreach ($table1Indexes as $indexName => $index) { + // See if index is removed in table 2. + if (($index->isPrimary() && ! $table2->hasPrimaryKey()) || + ! $index->isPrimary() && ! $table2->hasIndex($indexName) + ) { + $tableDifferences->removedIndexes[$indexName] = $index; + $changes++; + continue; + } + + // See if index has changed in table 2. + $table2Index = $index->isPrimary() ? $table2->getPrimaryKey() : $table2->getIndex($indexName); + + if (! $this->diffIndex($index, $table2Index)) { + continue; + } + + $tableDifferences->changedIndexes[$indexName] = $table2Index; + $changes++; + } + + $this->detectIndexRenamings($tableDifferences); + + $fromFkeys = $table1->getForeignKeys(); + $toFkeys = $table2->getForeignKeys(); + + foreach ($fromFkeys as $key1 => $constraint1) { + foreach ($toFkeys as $key2 => $constraint2) { + if ($this->diffForeignKey($constraint1, $constraint2) === false) { + unset($fromFkeys[$key1], $toFkeys[$key2]); + } else { + if (strtolower($constraint1->getName()) === strtolower($constraint2->getName())) { + $tableDifferences->changedForeignKeys[] = $constraint2; + $changes++; + unset($fromFkeys[$key1], $toFkeys[$key2]); + } + } + } + } + + foreach ($fromFkeys as $constraint1) { + $tableDifferences->removedForeignKeys[] = $constraint1; + $changes++; + } + + foreach ($toFkeys as $constraint2) { + $tableDifferences->addedForeignKeys[] = $constraint2; + $changes++; + } + + return $changes ? $tableDifferences : false; + } + + /** + * Try to find columns that only changed their name, rename operations maybe cheaper than add/drop + * however ambiguities between different possibilities should not lead to renaming at all. + * + * @return void + */ + private function detectColumnRenamings(TableDiff $tableDifferences) + { + $renameCandidates = []; + foreach ($tableDifferences->addedColumns as $addedColumnName => $addedColumn) { + foreach ($tableDifferences->removedColumns as $removedColumn) { + if (count($this->diffColumn($addedColumn, $removedColumn)) !== 0) { + continue; + } + + $renameCandidates[$addedColumn->getName()][] = [$removedColumn, $addedColumn, $addedColumnName]; + } + } + + foreach ($renameCandidates as $candidateColumns) { + if (count($candidateColumns) !== 1) { + continue; + } + + [$removedColumn, $addedColumn] = $candidateColumns[0]; + $removedColumnName = strtolower($removedColumn->getName()); + $addedColumnName = strtolower($addedColumn->getName()); + + if (isset($tableDifferences->renamedColumns[$removedColumnName])) { + continue; + } + + $tableDifferences->renamedColumns[$removedColumnName] = $addedColumn; + unset( + $tableDifferences->addedColumns[$addedColumnName], + $tableDifferences->removedColumns[$removedColumnName] + ); + } + } + + /** + * Try to find indexes that only changed their name, rename operations maybe cheaper than add/drop + * however ambiguities between different possibilities should not lead to renaming at all. + * + * @return void + */ + private function detectIndexRenamings(TableDiff $tableDifferences) + { + $renameCandidates = []; + + // Gather possible rename candidates by comparing each added and removed index based on semantics. + foreach ($tableDifferences->addedIndexes as $addedIndexName => $addedIndex) { + foreach ($tableDifferences->removedIndexes as $removedIndex) { + if ($this->diffIndex($addedIndex, $removedIndex)) { + continue; + } + + $renameCandidates[$addedIndex->getName()][] = [$removedIndex, $addedIndex, $addedIndexName]; + } + } + + foreach ($renameCandidates as $candidateIndexes) { + // If the current rename candidate contains exactly one semantically equal index, + // we can safely rename it. + // Otherwise it is unclear if a rename action is really intended, + // therefore we let those ambiguous indexes be added/dropped. + if (count($candidateIndexes) !== 1) { + continue; + } + + [$removedIndex, $addedIndex] = $candidateIndexes[0]; + + $removedIndexName = strtolower($removedIndex->getName()); + $addedIndexName = strtolower($addedIndex->getName()); + + if (isset($tableDifferences->renamedIndexes[$removedIndexName])) { + continue; + } + + $tableDifferences->renamedIndexes[$removedIndexName] = $addedIndex; + unset( + $tableDifferences->addedIndexes[$addedIndexName], + $tableDifferences->removedIndexes[$removedIndexName] + ); + } + } + + /** + * @return bool + */ + public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2) + { + if (array_map('strtolower', $key1->getUnquotedLocalColumns()) !== array_map('strtolower', $key2->getUnquotedLocalColumns())) { + return true; + } + + if (array_map('strtolower', $key1->getUnquotedForeignColumns()) !== array_map('strtolower', $key2->getUnquotedForeignColumns())) { + return true; + } + + if ($key1->getUnqualifiedForeignTableName() !== $key2->getUnqualifiedForeignTableName()) { + return true; + } + + if ($key1->onUpdate() !== $key2->onUpdate()) { + return true; + } + + return $key1->onDelete() !== $key2->onDelete(); + } + + /** + * Returns the difference between the fields $field1 and $field2. + * + * If there are differences this method returns $field2, otherwise the + * boolean false. + * + * @return string[] + */ + public function diffColumn(Column $column1, Column $column2) + { + $properties1 = $column1->toArray(); + $properties2 = $column2->toArray(); + + $changedProperties = []; + + foreach (['type', 'notnull', 'unsigned', 'autoincrement'] as $property) { + if ($properties1[$property] === $properties2[$property]) { + continue; + } + + $changedProperties[] = $property; + } + + // This is a very nasty hack to make comparator work with the legacy json_array type, which should be killed in v3 + if ($this->isALegacyJsonComparison($properties1['type'], $properties2['type'])) { + array_shift($changedProperties); + + $changedProperties[] = 'comment'; + } + + // Null values need to be checked additionally as they tell whether to create or drop a default value. + // null != 0, null != false, null != '' etc. This affects platform's table alteration SQL generation. + if (($properties1['default'] === null) !== ($properties2['default'] === null) + || $properties1['default'] != $properties2['default']) { + $changedProperties[] = 'default'; + } + + if (($properties1['type'] instanceof Types\StringType && ! $properties1['type'] instanceof Types\GuidType) || + $properties1['type'] instanceof Types\BinaryType + ) { + // check if value of length is set at all, default value assumed otherwise. + $length1 = $properties1['length'] ?: 255; + $length2 = $properties2['length'] ?: 255; + if ($length1 !== $length2) { + $changedProperties[] = 'length'; + } + + if ($properties1['fixed'] !== $properties2['fixed']) { + $changedProperties[] = 'fixed'; + } + } elseif ($properties1['type'] instanceof Types\DecimalType) { + if (($properties1['precision'] ?: 10) !== ($properties2['precision'] ?: 10)) { + $changedProperties[] = 'precision'; + } + if ($properties1['scale'] !== $properties2['scale']) { + $changedProperties[] = 'scale'; + } + } + + // A null value and an empty string are actually equal for a comment so they should not trigger a change. + if ($properties1['comment'] !== $properties2['comment'] && + ! ($properties1['comment'] === null && $properties2['comment'] === '') && + ! ($properties2['comment'] === null && $properties1['comment'] === '') + ) { + $changedProperties[] = 'comment'; + } + + $customOptions1 = $column1->getCustomSchemaOptions(); + $customOptions2 = $column2->getCustomSchemaOptions(); + + foreach (array_merge(array_keys($customOptions1), array_keys($customOptions2)) as $key) { + if (! array_key_exists($key, $properties1) || ! array_key_exists($key, $properties2)) { + $changedProperties[] = $key; + } elseif ($properties1[$key] !== $properties2[$key]) { + $changedProperties[] = $key; + } + } + + $platformOptions1 = $column1->getPlatformOptions(); + $platformOptions2 = $column2->getPlatformOptions(); + + foreach (array_keys(array_intersect_key($platformOptions1, $platformOptions2)) as $key) { + if ($properties1[$key] === $properties2[$key]) { + continue; + } + + $changedProperties[] = $key; + } + + return array_unique($changedProperties); + } + + /** + * TODO: kill with fire on v3.0 + * + * @deprecated + */ + private function isALegacyJsonComparison(Types\Type $one, Types\Type $other) : bool + { + if (! $one instanceof Types\JsonType || ! $other instanceof Types\JsonType) { + return false; + } + + return ( ! $one instanceof Types\JsonArrayType && $other instanceof Types\JsonArrayType) + || ( ! $other instanceof Types\JsonArrayType && $one instanceof Types\JsonArrayType); + } + + /** + * Finds the difference between the indexes $index1 and $index2. + * + * Compares $index1 with $index2 and returns $index2 if there are any + * differences or false in case there are no differences. + * + * @return bool + */ + public function diffIndex(Index $index1, Index $index2) + { + return ! ($index1->isFullfilledBy($index2) && $index2->isFullfilledBy($index1)); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php new file mode 100644 index 000000000..65e239ec1 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php @@ -0,0 +1,43 @@ +_platform->getListTablesSQL(); + $sql .= ' AND CREATOR = UPPER(' . $this->_conn->quote($this->_conn->getUsername()) . ')'; + + $tables = $this->_conn->fetchAll($sql); + + return $this->filterAssetNames($this->_getPortableTablesList($tables)); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + $length = null; + $fixed = null; + $unsigned = false; + $scale = false; + $precision = false; + + $default = null; + + if ($tableColumn['default'] !== null && $tableColumn['default'] !== 'NULL') { + $default = trim($tableColumn['default'], "'"); + } + + $type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']); + + if (isset($tableColumn['comment'])) { + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + } + + switch (strtolower($tableColumn['typename'])) { + case 'varchar': + $length = $tableColumn['length']; + $fixed = false; + break; + case 'character': + $length = $tableColumn['length']; + $fixed = true; + break; + case 'clob': + $length = $tableColumn['length']; + break; + case 'decimal': + case 'double': + case 'real': + $scale = $tableColumn['scale']; + $precision = $tableColumn['length']; + break; + } + + $options = [ + 'length' => $length, + 'unsigned' => (bool) $unsigned, + 'fixed' => (bool) $fixed, + 'default' => $default, + 'autoincrement' => (bool) $tableColumn['autoincrement'], + 'notnull' => (bool) ($tableColumn['nulls'] === 'N'), + 'scale' => null, + 'precision' => null, + 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' + ? $tableColumn['comment'] + : null, + 'platformOptions' => [], + ]; + + if ($scale !== null && $precision !== null) { + $options['scale'] = $scale; + $options['precision'] = $precision; + } + + return new Column($tableColumn['colname'], Type::getType($type), $options); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTablesList($tables) + { + $tableNames = []; + foreach ($tables as $tableRow) { + $tableRow = array_change_key_case($tableRow, CASE_LOWER); + $tableNames[] = $tableRow['name']; + } + + return $tableNames; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null) + { + foreach ($tableIndexRows as &$tableIndexRow) { + $tableIndexRow = array_change_key_case($tableIndexRow, CASE_LOWER); + $tableIndexRow['primary'] = (bool) $tableIndexRow['primary']; + } + + return parent::_getPortableTableIndexesList($tableIndexRows, $tableName); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return new ForeignKeyConstraint( + $tableForeignKey['local_columns'], + $tableForeignKey['foreign_table'], + $tableForeignKey['foreign_columns'], + $tableForeignKey['name'], + $tableForeignKey['options'] + ); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $foreignKeys = []; + + foreach ($tableForeignKeys as $tableForeignKey) { + $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER); + + if (! isset($foreignKeys[$tableForeignKey['index_name']])) { + $foreignKeys[$tableForeignKey['index_name']] = [ + 'local_columns' => [$tableForeignKey['local_column']], + 'foreign_table' => $tableForeignKey['foreign_table'], + 'foreign_columns' => [$tableForeignKey['foreign_column']], + 'name' => $tableForeignKey['index_name'], + 'options' => [ + 'onUpdate' => $tableForeignKey['on_update'], + 'onDelete' => $tableForeignKey['on_delete'], + ], + ]; + } else { + $foreignKeys[$tableForeignKey['index_name']]['local_columns'][] = $tableForeignKey['local_column']; + $foreignKeys[$tableForeignKey['index_name']]['foreign_columns'][] = $tableForeignKey['foreign_column']; + } + } + + return parent::_getPortableTableForeignKeysList($foreignKeys); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableForeignKeyRuleDef($def) + { + if ($def === 'C') { + return 'CASCADE'; + } elseif ($def === 'N') { + return 'SET NULL'; + } + + return null; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableViewDefinition($view) + { + $view = array_change_key_case($view, CASE_LOWER); + // sadly this still segfaults on PDO_IBM, see http://pecl.php.net/bugs/bug.php?id=17199 + //$view['text'] = (is_resource($view['text']) ? stream_get_contents($view['text']) : $view['text']); + if (! is_resource($view['text'])) { + $pos = strpos($view['text'], ' AS '); + $sql = substr($view['text'], $pos+4); + } else { + $sql = ''; + } + + return new View($view['name'], $sql); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/DrizzleSchemaManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/DrizzleSchemaManager.php new file mode 100644 index 000000000..c334db279 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/DrizzleSchemaManager.php @@ -0,0 +1,103 @@ +_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['COLUMN_COMMENT'], $type); + $tableColumn['COLUMN_COMMENT'] = $this->removeDoctrineTypeFromComment($tableColumn['COLUMN_COMMENT'], $type); + + $options = [ + 'notnull' => ! (bool) $tableColumn['IS_NULLABLE'], + 'length' => (int) $tableColumn['CHARACTER_MAXIMUM_LENGTH'], + 'default' => $tableColumn['COLUMN_DEFAULT'] ?? null, + 'autoincrement' => (bool) $tableColumn['IS_AUTO_INCREMENT'], + 'scale' => (int) $tableColumn['NUMERIC_SCALE'], + 'precision' => (int) $tableColumn['NUMERIC_PRECISION'], + 'comment' => isset($tableColumn['COLUMN_COMMENT']) && $tableColumn['COLUMN_COMMENT'] !== '' + ? $tableColumn['COLUMN_COMMENT'] + : null, + ]; + + $column = new Column($tableColumn['COLUMN_NAME'], Type::getType($type), $options); + + if (! empty($tableColumn['COLLATION_NAME'])) { + $column->setPlatformOption('collation', $tableColumn['COLLATION_NAME']); + } + + return $column; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['SCHEMA_NAME']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableDefinition($table) + { + return $table['TABLE_NAME']; + } + + /** + * {@inheritdoc} + */ + public function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + $columns = []; + foreach (explode(',', $tableForeignKey['CONSTRAINT_COLUMNS']) as $value) { + $columns[] = trim($value, ' `'); + } + + $refColumns = []; + foreach (explode(',', $tableForeignKey['REFERENCED_TABLE_COLUMNS']) as $value) { + $refColumns[] = trim($value, ' `'); + } + + return new ForeignKeyConstraint( + $columns, + $tableForeignKey['REFERENCED_TABLE_NAME'], + $refColumns, + $tableForeignKey['CONSTRAINT_NAME'], + [ + 'onUpdate' => $tableForeignKey['UPDATE_RULE'], + 'onDelete' => $tableForeignKey['DELETE_RULE'], + ] + ); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + $indexes = []; + foreach ($tableIndexes as $k) { + $k['primary'] = (bool) $k['primary']; + $indexes[] = $k; + } + + return parent::_getPortableTableIndexesList($indexes, $tableName); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php new file mode 100644 index 000000000..31850d7f2 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php @@ -0,0 +1,377 @@ + Identifier) + * + * @var Identifier[] + */ + protected $_localColumnNames; + + /** + * Table or asset identifier instance of the referenced table name the foreign key constraint is associated with. + * + * @var Table|Identifier + */ + protected $_foreignTableName; + + /** + * Asset identifier instances of the referenced table column names the foreign key constraint is associated with. + * array($columnName => Identifier) + * + * @var Identifier[] + */ + protected $_foreignColumnNames; + + /** + * Options associated with the foreign key constraint. + * + * @var mixed[] + */ + protected $_options; + + /** + * Initializes the foreign key constraint. + * + * @param string[] $localColumnNames Names of the referencing table columns. + * @param Table|string $foreignTableName Referenced table. + * @param string[] $foreignColumnNames Names of the referenced table columns. + * @param string|null $name Name of the foreign key constraint. + * @param mixed[] $options Options associated with the foreign key constraint. + */ + public function __construct(array $localColumnNames, $foreignTableName, array $foreignColumnNames, $name = null, array $options = []) + { + $this->_setName($name); + $identifierConstructorCallback = static function ($column) { + return new Identifier($column); + }; + $this->_localColumnNames = $localColumnNames + ? array_combine($localColumnNames, array_map($identifierConstructorCallback, $localColumnNames)) + : []; + + if ($foreignTableName instanceof Table) { + $this->_foreignTableName = $foreignTableName; + } else { + $this->_foreignTableName = new Identifier($foreignTableName); + } + + $this->_foreignColumnNames = $foreignColumnNames + ? array_combine($foreignColumnNames, array_map($identifierConstructorCallback, $foreignColumnNames)) + : []; + $this->_options = $options; + } + + /** + * Returns the name of the referencing table + * the foreign key constraint is associated with. + * + * @return string + */ + public function getLocalTableName() + { + return $this->_localTable->getName(); + } + + /** + * Sets the Table instance of the referencing table + * the foreign key constraint is associated with. + * + * @param Table $table Instance of the referencing table. + * + * @return void + */ + public function setLocalTable(Table $table) + { + $this->_localTable = $table; + } + + /** + * @return Table + */ + public function getLocalTable() + { + return $this->_localTable; + } + + /** + * Returns the names of the referencing table columns + * the foreign key constraint is associated with. + * + * @return string[] + */ + public function getLocalColumns() + { + return array_keys($this->_localColumnNames); + } + + /** + * Returns the quoted representation of the referencing table column names + * the foreign key constraint is associated with. + * + * But only if they were defined with one or the referencing table column name + * is a keyword reserved by the platform. + * Otherwise the plain unquoted value as inserted is returned. + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return string[] + */ + public function getQuotedLocalColumns(AbstractPlatform $platform) + { + $columns = []; + + foreach ($this->_localColumnNames as $column) { + $columns[] = $column->getQuotedName($platform); + } + + return $columns; + } + + /** + * Returns unquoted representation of local table column names for comparison with other FK + * + * @return string[] + */ + public function getUnquotedLocalColumns() + { + return array_map([$this, 'trimQuotes'], $this->getLocalColumns()); + } + + /** + * Returns unquoted representation of foreign table column names for comparison with other FK + * + * @return string[] + */ + public function getUnquotedForeignColumns() + { + return array_map([$this, 'trimQuotes'], $this->getForeignColumns()); + } + + /** + * {@inheritdoc} + * + * @see getLocalColumns + */ + public function getColumns() + { + return $this->getLocalColumns(); + } + + /** + * Returns the quoted representation of the referencing table column names + * the foreign key constraint is associated with. + * + * But only if they were defined with one or the referencing table column name + * is a keyword reserved by the platform. + * Otherwise the plain unquoted value as inserted is returned. + * + * @see getQuotedLocalColumns + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return string[] + */ + public function getQuotedColumns(AbstractPlatform $platform) + { + return $this->getQuotedLocalColumns($platform); + } + + /** + * Returns the name of the referenced table + * the foreign key constraint is associated with. + * + * @return string + */ + public function getForeignTableName() + { + return $this->_foreignTableName->getName(); + } + + /** + * Returns the non-schema qualified foreign table name. + * + * @return string + */ + public function getUnqualifiedForeignTableName() + { + $parts = explode('.', $this->_foreignTableName->getName()); + + return strtolower(end($parts)); + } + + /** + * Returns the quoted representation of the referenced table name + * the foreign key constraint is associated with. + * + * But only if it was defined with one or the referenced table name + * is a keyword reserved by the platform. + * Otherwise the plain unquoted value as inserted is returned. + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return string + */ + public function getQuotedForeignTableName(AbstractPlatform $platform) + { + return $this->_foreignTableName->getQuotedName($platform); + } + + /** + * Returns the names of the referenced table columns + * the foreign key constraint is associated with. + * + * @return string[] + */ + public function getForeignColumns() + { + return array_keys($this->_foreignColumnNames); + } + + /** + * Returns the quoted representation of the referenced table column names + * the foreign key constraint is associated with. + * + * But only if they were defined with one or the referenced table column name + * is a keyword reserved by the platform. + * Otherwise the plain unquoted value as inserted is returned. + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return string[] + */ + public function getQuotedForeignColumns(AbstractPlatform $platform) + { + $columns = []; + + foreach ($this->_foreignColumnNames as $column) { + $columns[] = $column->getQuotedName($platform); + } + + return $columns; + } + + /** + * Returns whether or not a given option + * is associated with the foreign key constraint. + * + * @param string $name Name of the option to check. + * + * @return bool + */ + public function hasOption($name) + { + return isset($this->_options[$name]); + } + + /** + * Returns an option associated with the foreign key constraint. + * + * @param string $name Name of the option the foreign key constraint is associated with. + * + * @return mixed + */ + public function getOption($name) + { + return $this->_options[$name]; + } + + /** + * Returns the options associated with the foreign key constraint. + * + * @return mixed[] + */ + public function getOptions() + { + return $this->_options; + } + + /** + * Returns the referential action for UPDATE operations + * on the referenced table the foreign key constraint is associated with. + * + * @return string|null + */ + public function onUpdate() + { + return $this->onEvent('onUpdate'); + } + + /** + * Returns the referential action for DELETE operations + * on the referenced table the foreign key constraint is associated with. + * + * @return string|null + */ + public function onDelete() + { + return $this->onEvent('onDelete'); + } + + /** + * Returns the referential action for a given database operation + * on the referenced table the foreign key constraint is associated with. + * + * @param string $event Name of the database operation/event to return the referential action for. + * + * @return string|null + */ + private function onEvent($event) + { + if (isset($this->_options[$event])) { + $onEvent = strtoupper($this->_options[$event]); + + if (! in_array($onEvent, ['NO ACTION', 'RESTRICT'])) { + return $onEvent; + } + } + + return false; + } + + /** + * Checks whether this foreign key constraint intersects the given index columns. + * + * Returns `true` if at least one of this foreign key's local columns + * matches one of the given index's columns, `false` otherwise. + * + * @param Index $index The index to be checked against. + * + * @return bool + */ + public function intersectsIndexColumns(Index $index) + { + foreach ($index->getColumns() as $indexColumn) { + foreach ($this->_localColumnNames as $localColumn) { + if (strtolower($indexColumn) === strtolower($localColumn->getName())) { + return true; + } + } + } + + return false; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Identifier.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Identifier.php new file mode 100644 index 000000000..f34465e9e --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Identifier.php @@ -0,0 +1,27 @@ +_setName($identifier); + + if (! $quote || $this->_quoted) { + return; + } + + $this->_setName('"' . $this->getName() . '"'); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php new file mode 100644 index 000000000..91ffd4724 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php @@ -0,0 +1,357 @@ + Identifier) + * + * @var Identifier[] + */ + protected $_columns = []; + + /** @var bool */ + protected $_isUnique = false; + + /** @var bool */ + protected $_isPrimary = false; + + /** + * Platform specific flags for indexes. + * array($flagName => true) + * + * @var true[] + */ + protected $_flags = []; + + /** + * Platform specific options + * + * @todo $_flags should eventually be refactored into options + * @var mixed[] + */ + private $options = []; + + /** + * @param string $indexName + * @param string[] $columns + * @param bool $isUnique + * @param bool $isPrimary + * @param string[] $flags + * @param mixed[] $options + */ + public function __construct($indexName, array $columns, $isUnique = false, $isPrimary = false, array $flags = [], array $options = []) + { + $isUnique = $isUnique || $isPrimary; + + $this->_setName($indexName); + $this->_isUnique = $isUnique; + $this->_isPrimary = $isPrimary; + $this->options = $options; + + foreach ($columns as $column) { + $this->_addColumn($column); + } + foreach ($flags as $flag) { + $this->addFlag($flag); + } + } + + /** + * @param string $column + * + * @return void + * + * @throws InvalidArgumentException + */ + protected function _addColumn($column) + { + if (! is_string($column)) { + throw new InvalidArgumentException('Expecting a string as Index Column'); + } + + $this->_columns[$column] = new Identifier($column); + } + + /** + * {@inheritdoc} + */ + public function getColumns() + { + return array_keys($this->_columns); + } + + /** + * {@inheritdoc} + */ + public function getQuotedColumns(AbstractPlatform $platform) + { + $subParts = $platform->supportsColumnLengthIndexes() && $this->hasOption('lengths') + ? $this->getOption('lengths') : []; + + $columns = []; + + foreach ($this->_columns as $column) { + $length = array_shift($subParts); + + $quotedColumn = $column->getQuotedName($platform); + + if ($length !== null) { + $quotedColumn .= '(' . $length . ')'; + } + + $columns[] = $quotedColumn; + } + + return $columns; + } + + /** + * @return string[] + */ + public function getUnquotedColumns() + { + return array_map([$this, 'trimQuotes'], $this->getColumns()); + } + + /** + * Is the index neither unique nor primary key? + * + * @return bool + */ + public function isSimpleIndex() + { + return ! $this->_isPrimary && ! $this->_isUnique; + } + + /** + * @return bool + */ + public function isUnique() + { + return $this->_isUnique; + } + + /** + * @return bool + */ + public function isPrimary() + { + return $this->_isPrimary; + } + + /** + * @param string $columnName + * @param int $pos + * + * @return bool + */ + public function hasColumnAtPosition($columnName, $pos = 0) + { + $columnName = $this->trimQuotes(strtolower($columnName)); + $indexColumns = array_map('strtolower', $this->getUnquotedColumns()); + + return array_search($columnName, $indexColumns) === $pos; + } + + /** + * Checks if this index exactly spans the given column names in the correct order. + * + * @param string[] $columnNames + * + * @return bool + */ + public function spansColumns(array $columnNames) + { + $columns = $this->getColumns(); + $numberOfColumns = count($columns); + $sameColumns = true; + + for ($i = 0; $i < $numberOfColumns; $i++) { + if (isset($columnNames[$i]) && $this->trimQuotes(strtolower($columns[$i])) === $this->trimQuotes(strtolower($columnNames[$i]))) { + continue; + } + + $sameColumns = false; + } + + return $sameColumns; + } + + /** + * Checks if the other index already fulfills all the indexing and constraint needs of the current one. + * + * @return bool + */ + public function isFullfilledBy(Index $other) + { + // allow the other index to be equally large only. It being larger is an option + // but it creates a problem with scenarios of the kind PRIMARY KEY(foo,bar) UNIQUE(foo) + if (count($other->getColumns()) !== count($this->getColumns())) { + return false; + } + + // Check if columns are the same, and even in the same order + $sameColumns = $this->spansColumns($other->getColumns()); + + if ($sameColumns) { + if (! $this->samePartialIndex($other)) { + return false; + } + + if (! $this->hasSameColumnLengths($other)) { + return false; + } + + if (! $this->isUnique() && ! $this->isPrimary()) { + // this is a special case: If the current key is neither primary or unique, any unique or + // primary key will always have the same effect for the index and there cannot be any constraint + // overlaps. This means a primary or unique index can always fulfill the requirements of just an + // index that has no constraints. + return true; + } + + if ($other->isPrimary() !== $this->isPrimary()) { + return false; + } + + return $other->isUnique() === $this->isUnique(); + } + + return false; + } + + /** + * Detects if the other index is a non-unique, non primary index that can be overwritten by this one. + * + * @return bool + */ + public function overrules(Index $other) + { + if ($other->isPrimary()) { + return false; + } elseif ($this->isSimpleIndex() && $other->isUnique()) { + return false; + } + + return $this->spansColumns($other->getColumns()) && ($this->isPrimary() || $this->isUnique()) && $this->samePartialIndex($other); + } + + /** + * Returns platform specific flags for indexes. + * + * @return string[] + */ + public function getFlags() + { + return array_keys($this->_flags); + } + + /** + * Adds Flag for an index that translates to platform specific handling. + * + * @param string $flag + * + * @return Index + * + * @example $index->addFlag('CLUSTERED') + */ + public function addFlag($flag) + { + $this->_flags[strtolower($flag)] = true; + + return $this; + } + + /** + * Does this index have a specific flag? + * + * @param string $flag + * + * @return bool + */ + public function hasFlag($flag) + { + return isset($this->_flags[strtolower($flag)]); + } + + /** + * Removes a flag. + * + * @param string $flag + * + * @return void + */ + public function removeFlag($flag) + { + unset($this->_flags[strtolower($flag)]); + } + + /** + * @param string $name + * + * @return bool + */ + public function hasOption($name) + { + return isset($this->options[strtolower($name)]); + } + + /** + * @param string $name + * + * @return mixed + */ + public function getOption($name) + { + return $this->options[strtolower($name)]; + } + + /** + * @return mixed[] + */ + public function getOptions() + { + return $this->options; + } + + /** + * Return whether the two indexes have the same partial index + * + * @return bool + */ + private function samePartialIndex(Index $other) + { + if ($this->hasOption('where') && $other->hasOption('where') && $this->getOption('where') === $other->getOption('where')) { + return true; + } + + return ! $this->hasOption('where') && ! $other->hasOption('where'); + } + + /** + * Returns whether the index has the same column lengths as the other + */ + private function hasSameColumnLengths(self $other) : bool + { + $filter = static function (?int $length) : bool { + return $length !== null; + }; + + return array_filter($this->options['lengths'] ?? [], $filter) + === array_filter($other->options['lengths'] ?? [], $filter); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php new file mode 100644 index 000000000..7bcd5533e --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php @@ -0,0 +1,331 @@ + $user['User'], + 'password' => $user['Password'], + ]; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + foreach ($tableIndexes as $k => $v) { + $v = array_change_key_case($v, CASE_LOWER); + if ($v['key_name'] === 'PRIMARY') { + $v['primary'] = true; + } else { + $v['primary'] = false; + } + if (strpos($v['index_type'], 'FULLTEXT') !== false) { + $v['flags'] = ['FULLTEXT']; + } elseif (strpos($v['index_type'], 'SPATIAL') !== false) { + $v['flags'] = ['SPATIAL']; + } + $v['length'] = $v['sub_part'] ?? null; + + $tableIndexes[$k] = $v; + } + + return parent::_getPortableTableIndexesList($tableIndexes, $tableName); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableSequenceDefinition($sequence) + { + return end($sequence); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['Database']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + $dbType = strtolower($tableColumn['type']); + $dbType = strtok($dbType, '(), '); + $length = $tableColumn['length'] ?? strtok('(), '); + + $fixed = null; + + if (! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $scale = null; + $precision = null; + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + + // In cases where not connected to a database DESCRIBE $table does not return 'Comment' + if (isset($tableColumn['comment'])) { + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + } + + switch ($dbType) { + case 'char': + case 'binary': + $fixed = true; + break; + case 'float': + case 'double': + case 'real': + case 'numeric': + case 'decimal': + if (preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['type'], $match)) { + $precision = $match[1]; + $scale = $match[2]; + $length = null; + } + break; + case 'tinytext': + $length = MySqlPlatform::LENGTH_LIMIT_TINYTEXT; + break; + case 'text': + $length = MySqlPlatform::LENGTH_LIMIT_TEXT; + break; + case 'mediumtext': + $length = MySqlPlatform::LENGTH_LIMIT_MEDIUMTEXT; + break; + case 'tinyblob': + $length = MySqlPlatform::LENGTH_LIMIT_TINYBLOB; + break; + case 'blob': + $length = MySqlPlatform::LENGTH_LIMIT_BLOB; + break; + case 'mediumblob': + $length = MySqlPlatform::LENGTH_LIMIT_MEDIUMBLOB; + break; + case 'tinyint': + case 'smallint': + case 'mediumint': + case 'int': + case 'integer': + case 'bigint': + case 'year': + $length = null; + break; + } + + if ($this->_platform instanceof MariaDb1027Platform) { + $columnDefault = $this->getMariaDb1027ColumnDefault($this->_platform, $tableColumn['default']); + } else { + $columnDefault = $tableColumn['default']; + } + + $options = [ + 'length' => $length !== null ? (int) $length : null, + 'unsigned' => strpos($tableColumn['type'], 'unsigned') !== false, + 'fixed' => (bool) $fixed, + 'default' => $columnDefault, + 'notnull' => $tableColumn['null'] !== 'YES', + 'scale' => null, + 'precision' => null, + 'autoincrement' => strpos($tableColumn['extra'], 'auto_increment') !== false, + 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' + ? $tableColumn['comment'] + : null, + ]; + + if ($scale !== null && $precision !== null) { + $options['scale'] = (int) $scale; + $options['precision'] = (int) $precision; + } + + $column = new Column($tableColumn['field'], Type::getType($type), $options); + + if (isset($tableColumn['collation'])) { + $column->setPlatformOption('collation', $tableColumn['collation']); + } + + return $column; + } + + /** + * Return Doctrine/Mysql-compatible column default values for MariaDB 10.2.7+ servers. + * + * - Since MariaDb 10.2.7 column defaults stored in information_schema are now quoted + * to distinguish them from expressions (see MDEV-10134). + * - CURRENT_TIMESTAMP, CURRENT_TIME, CURRENT_DATE are stored in information_schema + * as current_timestamp(), currdate(), currtime() + * - Quoted 'NULL' is not enforced by Maria, it is technically possible to have + * null in some circumstances (see https://jira.mariadb.org/browse/MDEV-14053) + * - \' is always stored as '' in information_schema (normalized) + * + * @link https://mariadb.com/kb/en/library/information-schema-columns-table/ + * @link https://jira.mariadb.org/browse/MDEV-13132 + * + * @param string|null $columnDefault default value as stored in information_schema for MariaDB >= 10.2.7 + */ + private function getMariaDb1027ColumnDefault(MariaDb1027Platform $platform, ?string $columnDefault) : ?string + { + if ($columnDefault === 'NULL' || $columnDefault === null) { + return null; + } + if ($columnDefault[0] === "'") { + return stripslashes( + str_replace( + "''", + "'", + preg_replace('/^\'(.*)\'$/', '$1', $columnDefault) + ) + ); + } + switch ($columnDefault) { + case 'current_timestamp()': + return $platform->getCurrentTimestampSQL(); + case 'curdate()': + return $platform->getCurrentDateSQL(); + case 'curtime()': + return $platform->getCurrentTimeSQL(); + } + return $columnDefault; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = []; + foreach ($tableForeignKeys as $value) { + $value = array_change_key_case($value, CASE_LOWER); + if (! isset($list[$value['constraint_name']])) { + if (! isset($value['delete_rule']) || $value['delete_rule'] === 'RESTRICT') { + $value['delete_rule'] = null; + } + if (! isset($value['update_rule']) || $value['update_rule'] === 'RESTRICT') { + $value['update_rule'] = null; + } + + $list[$value['constraint_name']] = [ + 'name' => $value['constraint_name'], + 'local' => [], + 'foreign' => [], + 'foreignTable' => $value['referenced_table_name'], + 'onDelete' => $value['delete_rule'], + 'onUpdate' => $value['update_rule'], + ]; + } + $list[$value['constraint_name']]['local'][] = $value['column_name']; + $list[$value['constraint_name']]['foreign'][] = $value['referenced_column_name']; + } + + $result = []; + foreach ($list as $constraint) { + $result[] = new ForeignKeyConstraint( + array_values($constraint['local']), + $constraint['foreignTable'], + array_values($constraint['foreign']), + $constraint['name'], + [ + 'onDelete' => $constraint['onDelete'], + 'onUpdate' => $constraint['onUpdate'], + ] + ); + } + + return $result; + } + + public function listTableDetails($tableName) + { + $table = parent::listTableDetails($tableName); + + /** @var MySqlPlatform $platform */ + $platform = $this->_platform; + $sql = $platform->getListTableMetadataSQL($tableName); + + $tableOptions = $this->_conn->fetchAssoc($sql); + + $table->addOption('engine', $tableOptions['ENGINE']); + if ($tableOptions['TABLE_COLLATION'] !== null) { + $table->addOption('collation', $tableOptions['TABLE_COLLATION']); + } + if ($tableOptions['AUTO_INCREMENT'] !== null) { + $table->addOption('autoincrement', $tableOptions['AUTO_INCREMENT']); + } + $table->addOption('comment', $tableOptions['TABLE_COMMENT']); + $table->addOption('create_options', $this->parseCreateOptions($tableOptions['CREATE_OPTIONS'])); + + return $table; + } + + /** + * @return string[]|true[] + */ + private function parseCreateOptions(?string $string) : array + { + $options = []; + + if ($string === null || $string === '') { + return $options; + } + + foreach (explode(' ', $string) as $pair) { + $parts = explode('=', $pair, 2); + + $options[$parts[0]] = $parts[1] ?? true; + } + + return $options; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php new file mode 100644 index 000000000..250ec2a26 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php @@ -0,0 +1,383 @@ +getPrevious(); + + if (! $exception instanceof DriverException) { + throw $exception; + } + + // If we have a error code 1940 (ORA-01940), the drop database operation failed + // because of active connections on the database. + // To force dropping the database, we first have to close all active connections + // on that database and issue the drop database operation again. + if ($exception->getErrorCode() !== 1940) { + throw $exception; + } + + $this->killUserSessions($database); + + parent::dropDatabase($database); + } + } + + /** + * {@inheritdoc} + */ + protected function _getPortableViewDefinition($view) + { + $view = array_change_key_case($view, CASE_LOWER); + + return new View($this->getQuotedIdentifierName($view['view_name']), $view['text']); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableUserDefinition($user) + { + $user = array_change_key_case($user, CASE_LOWER); + + return [ + 'user' => $user['username'], + ]; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableDefinition($table) + { + $table = array_change_key_case($table, CASE_LOWER); + + return $this->getQuotedIdentifierName($table['table_name']); + } + + /** + * {@inheritdoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + $indexBuffer = []; + foreach ($tableIndexes as $tableIndex) { + $tableIndex = array_change_key_case($tableIndex, CASE_LOWER); + + $keyName = strtolower($tableIndex['name']); + $buffer = []; + + if (strtolower($tableIndex['is_primary']) === 'p') { + $keyName = 'primary'; + $buffer['primary'] = true; + $buffer['non_unique'] = false; + } else { + $buffer['primary'] = false; + $buffer['non_unique'] = ! $tableIndex['is_unique']; + } + $buffer['key_name'] = $keyName; + $buffer['column_name'] = $this->getQuotedIdentifierName($tableIndex['column_name']); + $indexBuffer[] = $buffer; + } + + return parent::_getPortableTableIndexesList($indexBuffer, $tableName); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + $dbType = strtolower($tableColumn['data_type']); + if (strpos($dbType, 'timestamp(') === 0) { + if (strpos($dbType, 'with time zone')) { + $dbType = 'timestamptz'; + } else { + $dbType = 'timestamp'; + } + } + + $unsigned = $fixed = $precision = $scale = $length = null; + + if (! isset($tableColumn['column_name'])) { + $tableColumn['column_name'] = ''; + } + + // Default values returned from database sometimes have trailing spaces. + $tableColumn['data_default'] = trim($tableColumn['data_default']); + + if ($tableColumn['data_default'] === '' || $tableColumn['data_default'] === 'NULL') { + $tableColumn['data_default'] = null; + } + + if ($tableColumn['data_default'] !== null) { + // Default values returned from database are enclosed in single quotes. + $tableColumn['data_default'] = trim($tableColumn['data_default'], "'"); + } + + if ($tableColumn['data_precision'] !== null) { + $precision = (int) $tableColumn['data_precision']; + } + + if ($tableColumn['data_scale'] !== null) { + $scale = (int) $tableColumn['data_scale']; + } + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comments'], $type); + $tableColumn['comments'] = $this->removeDoctrineTypeFromComment($tableColumn['comments'], $type); + + switch ($dbType) { + case 'number': + if ($precision === 20 && $scale === 0) { + $type = 'bigint'; + } elseif ($precision === 5 && $scale === 0) { + $type = 'smallint'; + } elseif ($precision === 1 && $scale === 0) { + $type = 'boolean'; + } elseif ($scale > 0) { + $type = 'decimal'; + } + + break; + case 'varchar': + case 'varchar2': + case 'nvarchar2': + $length = $tableColumn['char_length']; + $fixed = false; + break; + case 'char': + case 'nchar': + $length = $tableColumn['char_length']; + $fixed = true; + break; + } + + $options = [ + 'notnull' => (bool) ($tableColumn['nullable'] === 'N'), + 'fixed' => (bool) $fixed, + 'unsigned' => (bool) $unsigned, + 'default' => $tableColumn['data_default'], + 'length' => $length, + 'precision' => $precision, + 'scale' => $scale, + 'comment' => isset($tableColumn['comments']) && $tableColumn['comments'] !== '' + ? $tableColumn['comments'] + : null, + ]; + + return new Column($this->getQuotedIdentifierName($tableColumn['column_name']), Type::getType($type), $options); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = []; + foreach ($tableForeignKeys as $value) { + $value = array_change_key_case($value, CASE_LOWER); + if (! isset($list[$value['constraint_name']])) { + if ($value['delete_rule'] === 'NO ACTION') { + $value['delete_rule'] = null; + } + + $list[$value['constraint_name']] = [ + 'name' => $this->getQuotedIdentifierName($value['constraint_name']), + 'local' => [], + 'foreign' => [], + 'foreignTable' => $value['references_table'], + 'onDelete' => $value['delete_rule'], + ]; + } + + $localColumn = $this->getQuotedIdentifierName($value['local_column']); + $foreignColumn = $this->getQuotedIdentifierName($value['foreign_column']); + + $list[$value['constraint_name']]['local'][$value['position']] = $localColumn; + $list[$value['constraint_name']]['foreign'][$value['position']] = $foreignColumn; + } + + $result = []; + foreach ($list as $constraint) { + $result[] = new ForeignKeyConstraint( + array_values($constraint['local']), + $this->getQuotedIdentifierName($constraint['foreignTable']), + array_values($constraint['foreign']), + $this->getQuotedIdentifierName($constraint['name']), + ['onDelete' => $constraint['onDelete']] + ); + } + + return $result; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableSequenceDefinition($sequence) + { + $sequence = array_change_key_case($sequence, CASE_LOWER); + + return new Sequence( + $this->getQuotedIdentifierName($sequence['sequence_name']), + (int) $sequence['increment_by'], + (int) $sequence['min_value'] + ); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableFunctionDefinition($function) + { + $function = array_change_key_case($function, CASE_LOWER); + + return $function['name']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + $database = array_change_key_case($database, CASE_LOWER); + + return $database['username']; + } + + /** + * {@inheritdoc} + */ + public function createDatabase($database = null) + { + if ($database === null) { + $database = $this->_conn->getDatabase(); + } + + $params = $this->_conn->getParams(); + $username = $database; + $password = $params['password']; + + $query = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password; + $this->_conn->executeUpdate($query); + + $query = 'GRANT DBA TO ' . $username; + $this->_conn->executeUpdate($query); + } + + /** + * @param string $table + * + * @return bool + */ + public function dropAutoincrement($table) + { + assert($this->_platform instanceof OraclePlatform); + + $sql = $this->_platform->getDropAutoincrementSql($table); + foreach ($sql as $query) { + $this->_conn->executeUpdate($query); + } + + return true; + } + + /** + * {@inheritdoc} + */ + public function dropTable($name) + { + $this->tryMethod('dropAutoincrement', $name); + + parent::dropTable($name); + } + + /** + * Returns the quoted representation of the given identifier name. + * + * Quotes non-uppercase identifiers explicitly to preserve case + * and thus make references to the particular identifier work. + * + * @param string $identifier The identifier to quote. + * + * @return string The quoted identifier. + */ + private function getQuotedIdentifierName($identifier) + { + if (preg_match('/[a-z]/', $identifier)) { + return $this->_platform->quoteIdentifier($identifier); + } + + return $identifier; + } + + /** + * Kills sessions connected with the given user. + * + * This is useful to force DROP USER operations which could fail because of active user sessions. + * + * @param string $user The name of the user to kill sessions for. + * + * @return void + */ + private function killUserSessions($user) + { + $sql = <<_conn->fetchAll($sql, [strtoupper($user)]); + + foreach ($activeUserSessions as $activeUserSession) { + $activeUserSession = array_change_key_case($activeUserSession, CASE_LOWER); + + $this->_execSql( + sprintf( + "ALTER SYSTEM KILL SESSION '%s, %s' IMMEDIATE", + $activeUserSession['sid'], + $activeUserSession['serial#'] + ) + ); + } + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php new file mode 100644 index 000000000..168e74ea8 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/PostgreSqlSchemaManager.php @@ -0,0 +1,481 @@ +_conn->executeQuery("SELECT nspname FROM pg_namespace WHERE nspname !~ '^pg_.*' AND nspname != 'information_schema'"); + + return $statement->fetchAll(FetchMode::COLUMN); + } + + /** + * Returns an array of schema search paths. + * + * This is a PostgreSQL only function. + * + * @return string[] + */ + public function getSchemaSearchPaths() + { + $params = $this->_conn->getParams(); + $schema = explode(',', $this->_conn->fetchColumn('SHOW search_path')); + + if (isset($params['user'])) { + $schema = str_replace('"$user"', $params['user'], $schema); + } + + return array_map('trim', $schema); + } + + /** + * Gets names of all existing schemas in the current users search path. + * + * This is a PostgreSQL only function. + * + * @return string[] + */ + public function getExistingSchemaSearchPaths() + { + if ($this->existingSchemaPaths === null) { + $this->determineExistingSchemaSearchPaths(); + } + + return $this->existingSchemaPaths; + } + + /** + * Sets or resets the order of the existing schemas in the current search path of the user. + * + * This is a PostgreSQL only function. + * + * @return void + */ + public function determineExistingSchemaSearchPaths() + { + $names = $this->getSchemaNames(); + $paths = $this->getSchemaSearchPaths(); + + $this->existingSchemaPaths = array_filter($paths, static function ($v) use ($names) { + return in_array($v, $names); + }); + } + + /** + * {@inheritdoc} + */ + public function dropDatabase($database) + { + try { + parent::dropDatabase($database); + } catch (DriverException $exception) { + // If we have a SQLSTATE 55006, the drop database operation failed + // because of active connections on the database. + // To force dropping the database, we first have to close all active connections + // on that database and issue the drop database operation again. + if ($exception->getSQLState() !== '55006') { + throw $exception; + } + + assert($this->_platform instanceof PostgreSqlPlatform); + + $this->_execSql( + [ + $this->_platform->getDisallowDatabaseConnectionsSQL($database), + $this->_platform->getCloseActiveDatabaseConnectionsSQL($database), + ] + ); + + parent::dropDatabase($database); + } + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + $onUpdate = null; + $onDelete = null; + $localColumns = null; + $foreignColumns = null; + $foreignTable = null; + + if (preg_match('(ON UPDATE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) { + $onUpdate = $match[1]; + } + if (preg_match('(ON DELETE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', $tableForeignKey['condef'], $match)) { + $onDelete = $match[1]; + } + + if (preg_match('/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)/', $tableForeignKey['condef'], $values)) { + // PostgreSQL returns identifiers that are keywords with quotes, we need them later, don't get + // the idea to trim them here. + $localColumns = array_map('trim', explode(',', $values[1])); + $foreignColumns = array_map('trim', explode(',', $values[3])); + $foreignTable = $values[2]; + } + + return new ForeignKeyConstraint( + $localColumns, + $foreignTable, + $foreignColumns, + $tableForeignKey['conname'], + ['onUpdate' => $onUpdate, 'onDelete' => $onDelete] + ); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTriggerDefinition($trigger) + { + return $trigger['trigger_name']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableViewDefinition($view) + { + return new View($view['schemaname'] . '.' . $view['viewname'], $view['definition']); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableUserDefinition($user) + { + return [ + 'user' => $user['usename'], + 'password' => $user['passwd'], + ]; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableDefinition($table) + { + $schemas = $this->getExistingSchemaSearchPaths(); + $firstSchema = array_shift($schemas); + + if ($table['schema_name'] === $firstSchema) { + return $table['table_name']; + } + + return $table['schema_name'] . '.' . $table['table_name']; + } + + /** + * {@inheritdoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + $buffer = []; + foreach ($tableIndexes as $row) { + $colNumbers = array_map('intval', explode(' ', $row['indkey'])); + $columnNameSql = sprintf( + 'SELECT attnum, attname FROM pg_attribute WHERE attrelid=%d AND attnum IN (%s) ORDER BY attnum ASC', + $row['indrelid'], + implode(' ,', $colNumbers) + ); + + $stmt = $this->_conn->executeQuery($columnNameSql); + $indexColumns = $stmt->fetchAll(); + + // required for getting the order of the columns right. + foreach ($colNumbers as $colNum) { + foreach ($indexColumns as $colRow) { + if ($colNum !== $colRow['attnum']) { + continue; + } + + $buffer[] = [ + 'key_name' => $row['relname'], + 'column_name' => trim($colRow['attname']), + 'non_unique' => ! $row['indisunique'], + 'primary' => $row['indisprimary'], + 'where' => $row['where'], + ]; + } + } + } + + return parent::_getPortableTableIndexesList($buffer, $tableName); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['datname']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableSequencesList($sequences) + { + $sequenceDefinitions = []; + + foreach ($sequences as $sequence) { + if ($sequence['schemaname'] !== 'public') { + $sequenceName = $sequence['schemaname'] . '.' . $sequence['relname']; + } else { + $sequenceName = $sequence['relname']; + } + + $sequenceDefinitions[$sequenceName] = $sequence; + } + + $list = []; + + foreach ($this->filterAssetNames(array_keys($sequenceDefinitions)) as $sequenceName) { + $list[] = $this->_getPortableSequenceDefinition($sequenceDefinitions[$sequenceName]); + } + + return $list; + } + + /** + * {@inheritdoc} + */ + protected function getPortableNamespaceDefinition(array $namespace) + { + return $namespace['nspname']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableSequenceDefinition($sequence) + { + if ($sequence['schemaname'] !== 'public') { + $sequenceName = $sequence['schemaname'] . '.' . $sequence['relname']; + } else { + $sequenceName = $sequence['relname']; + } + + if (! isset($sequence['increment_by'], $sequence['min_value'])) { + /** @var string[] $data */ + $data = $this->_conn->fetchAssoc('SELECT min_value, increment_by FROM ' . $this->_platform->quoteIdentifier($sequenceName)); + + $sequence += $data; + } + + return new Sequence($sequenceName, (int) $sequence['increment_by'], (int) $sequence['min_value']); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + if (strtolower($tableColumn['type']) === 'varchar' || strtolower($tableColumn['type']) === 'bpchar') { + // get length from varchar definition + $length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $tableColumn['complete_type']); + $tableColumn['length'] = $length; + } + + $matches = []; + + $autoincrement = false; + if (preg_match("/^nextval\('(.*)'(::.*)?\)$/", $tableColumn['default'], $matches)) { + $tableColumn['sequence'] = $matches[1]; + $tableColumn['default'] = null; + $autoincrement = true; + } + + if (preg_match("/^['(](.*)[')]::.*$/", $tableColumn['default'], $matches)) { + $tableColumn['default'] = $matches[1]; + } + + if (stripos($tableColumn['default'], 'NULL') === 0) { + $tableColumn['default'] = null; + } + + $length = $tableColumn['length'] ?? null; + if ($length === '-1' && isset($tableColumn['atttypmod'])) { + $length = $tableColumn['atttypmod'] - 4; + } + if ((int) $length <= 0) { + $length = null; + } + $fixed = null; + + if (! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $precision = null; + $scale = null; + $jsonb = null; + + $dbType = strtolower($tableColumn['type']); + if (strlen($tableColumn['domain_type']) && ! $this->_platform->hasDoctrineTypeMappingFor($tableColumn['type'])) { + $dbType = strtolower($tableColumn['domain_type']); + $tableColumn['complete_type'] = $tableColumn['domain_complete_type']; + } + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + + switch ($dbType) { + case 'smallint': + case 'int2': + $tableColumn['default'] = $this->fixVersion94NegativeNumericDefaultValue($tableColumn['default']); + $length = null; + break; + case 'int': + case 'int4': + case 'integer': + $tableColumn['default'] = $this->fixVersion94NegativeNumericDefaultValue($tableColumn['default']); + $length = null; + break; + case 'bigint': + case 'int8': + $tableColumn['default'] = $this->fixVersion94NegativeNumericDefaultValue($tableColumn['default']); + $length = null; + break; + case 'bool': + case 'boolean': + if ($tableColumn['default'] === 'true') { + $tableColumn['default'] = true; + } + + if ($tableColumn['default'] === 'false') { + $tableColumn['default'] = false; + } + + $length = null; + break; + case 'text': + $fixed = false; + break; + case 'varchar': + case 'interval': + case '_varchar': + $fixed = false; + break; + case 'char': + case 'bpchar': + $fixed = true; + break; + case 'float': + case 'float4': + case 'float8': + case 'double': + case 'double precision': + case 'real': + case 'decimal': + case 'money': + case 'numeric': + $tableColumn['default'] = $this->fixVersion94NegativeNumericDefaultValue($tableColumn['default']); + + if (preg_match('([A-Za-z]+\(([0-9]+)\,([0-9]+)\))', $tableColumn['complete_type'], $match)) { + $precision = $match[1]; + $scale = $match[2]; + $length = null; + } + break; + case 'year': + $length = null; + break; + + // PostgreSQL 9.4+ only + case 'jsonb': + $jsonb = true; + break; + } + + if ($tableColumn['default'] && preg_match("('([^']+)'::)", $tableColumn['default'], $match)) { + $tableColumn['default'] = $match[1]; + } + + $options = [ + 'length' => $length, + 'notnull' => (bool) $tableColumn['isnotnull'], + 'default' => $tableColumn['default'], + 'precision' => $precision, + 'scale' => $scale, + 'fixed' => $fixed, + 'unsigned' => false, + 'autoincrement' => $autoincrement, + 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' + ? $tableColumn['comment'] + : null, + ]; + + $column = new Column($tableColumn['field'], Type::getType($type), $options); + + if (isset($tableColumn['collation']) && ! empty($tableColumn['collation'])) { + $column->setPlatformOption('collation', $tableColumn['collation']); + } + + if (in_array($column->getType()->getName(), [Type::JSON_ARRAY, Type::JSON], true)) { + $column->setPlatformOption('jsonb', $jsonb); + } + + return $column; + } + + /** + * PostgreSQL 9.4 puts parentheses around negative numeric default values that need to be stripped eventually. + * + * @param mixed $defaultValue + * + * @return mixed + */ + private function fixVersion94NegativeNumericDefaultValue($defaultValue) + { + if (strpos($defaultValue, '(') === 0) { + return trim($defaultValue, '()'); + } + + return $defaultValue; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLAnywhereSchemaManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLAnywhereSchemaManager.php new file mode 100644 index 000000000..62d5fa88e --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLAnywhereSchemaManager.php @@ -0,0 +1,230 @@ +startDatabase($database); + } + + /** + * {@inheritdoc} + * + * Tries stopping a database before dropping + * as SQL Anywhere needs a database to be stopped + * before it can be dropped. + * + * @see stopDatabase + */ + public function dropDatabase($database) + { + $this->tryMethod('stopDatabase', $database); + parent::dropDatabase($database); + } + + /** + * Starts a database. + * + * @param string $database The name of the database to start. + */ + public function startDatabase($database) + { + assert($this->_platform instanceof SQLAnywherePlatform); + $this->_execSql($this->_platform->getStartDatabaseSQL($database)); + } + + /** + * Stops a database. + * + * @param string $database The name of the database to stop. + */ + public function stopDatabase($database) + { + assert($this->_platform instanceof SQLAnywherePlatform); + $this->_execSql($this->_platform->getStopDatabaseSQL($database)); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['name']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableSequenceDefinition($sequence) + { + return new Sequence($sequence['sequence_name'], $sequence['increment_by'], $sequence['start_with']); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $type = $this->_platform->getDoctrineTypeMapping($tableColumn['type']); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + $precision = null; + $scale = null; + $fixed = false; + $default = null; + + if ($tableColumn['default'] !== null) { + // Strip quotes from default value. + $default = preg_replace(["/^'(.*)'$/", "/''/"], ['$1', "'"], $tableColumn['default']); + + if ($default === 'autoincrement') { + $default = null; + } + } + + switch ($tableColumn['type']) { + case 'binary': + case 'char': + case 'nchar': + $fixed = true; + } + + switch ($type) { + case 'decimal': + case 'float': + $precision = $tableColumn['length']; + $scale = $tableColumn['scale']; + } + + return new Column( + $tableColumn['column_name'], + Type::getType($type), + [ + 'length' => $type === 'string' ? $tableColumn['length'] : null, + 'precision' => $precision, + 'scale' => $scale, + 'unsigned' => (bool) $tableColumn['unsigned'], + 'fixed' => $fixed, + 'notnull' => (bool) $tableColumn['notnull'], + 'default' => $default, + 'autoincrement' => (bool) $tableColumn['autoincrement'], + 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' + ? $tableColumn['comment'] + : null, + ] + ); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableDefinition($table) + { + return $table['table_name']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return new ForeignKeyConstraint( + $tableForeignKey['local_columns'], + $tableForeignKey['foreign_table'], + $tableForeignKey['foreign_columns'], + $tableForeignKey['name'], + $tableForeignKey['options'] + ); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $foreignKeys = []; + + foreach ($tableForeignKeys as $tableForeignKey) { + if (! isset($foreignKeys[$tableForeignKey['index_name']])) { + $foreignKeys[$tableForeignKey['index_name']] = [ + 'local_columns' => [$tableForeignKey['local_column']], + 'foreign_table' => $tableForeignKey['foreign_table'], + 'foreign_columns' => [$tableForeignKey['foreign_column']], + 'name' => $tableForeignKey['index_name'], + 'options' => [ + 'notnull' => $tableForeignKey['notnull'], + 'match' => $tableForeignKey['match'], + 'onUpdate' => $tableForeignKey['on_update'], + 'onDelete' => $tableForeignKey['on_delete'], + 'check_on_commit' => $tableForeignKey['check_on_commit'], + 'clustered' => $tableForeignKey['clustered'], + 'for_olap_workload' => $tableForeignKey['for_olap_workload'], + ], + ]; + } else { + $foreignKeys[$tableForeignKey['index_name']]['local_columns'][] = $tableForeignKey['local_column']; + $foreignKeys[$tableForeignKey['index_name']]['foreign_columns'][] = $tableForeignKey['foreign_column']; + } + } + + return parent::_getPortableTableForeignKeysList($foreignKeys); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null) + { + foreach ($tableIndexRows as &$tableIndex) { + $tableIndex['primary'] = (bool) $tableIndex['primary']; + $tableIndex['flags'] = []; + + if ($tableIndex['clustered']) { + $tableIndex['flags'][] = 'clustered'; + } + + if ($tableIndex['with_nulls_not_distinct']) { + $tableIndex['flags'][] = 'with_nulls_not_distinct'; + } + + if (! $tableIndex['for_olap_workload']) { + continue; + } + + $tableIndex['flags'][] = 'for_olap_workload'; + } + + return parent::_getPortableTableIndexesList($tableIndexRows, $tableName); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableViewDefinition($view) + { + return new View( + $view['table_name'], + preg_replace('/^.*\s+as\s+SELECT(.*)/i', 'SELECT$1', $view['view_def']) + ); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php new file mode 100644 index 000000000..6cd82b2ff --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SQLServerSchemaManager.php @@ -0,0 +1,310 @@ +getPrevious(); + + if (! $exception instanceof DriverException) { + throw $exception; + } + + // If we have a error code 3702, the drop database operation failed + // because of active connections on the database. + // To force dropping the database, we first have to close all active connections + // on that database and issue the drop database operation again. + if ($exception->getErrorCode() !== 3702) { + throw $exception; + } + + $this->closeActiveDatabaseConnections($database); + + parent::dropDatabase($database); + } + } + + /** + * {@inheritdoc} + */ + protected function _getPortableSequenceDefinition($sequence) + { + return new Sequence($sequence['name'], (int) $sequence['increment'], (int) $sequence['start_value']); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $dbType = strtok($tableColumn['type'], '(), '); + $fixed = null; + $length = (int) $tableColumn['length']; + $default = $tableColumn['default']; + + if (! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + if ($default !== null) { + while ($default !== ($default2 = preg_replace('/^\((.*)\)$/', '$1', $default))) { + $default = trim($default2, "'"); + + if ($default !== 'getdate()') { + continue; + } + + $default = $this->_platform->getCurrentTimestampSQL(); + } + } + + switch ($dbType) { + case 'nchar': + case 'nvarchar': + case 'ntext': + // Unicode data requires 2 bytes per character + $length /= 2; + break; + case 'varchar': + // TEXT type is returned as VARCHAR(MAX) with a length of -1 + if ($length === -1) { + $dbType = 'text'; + } + break; + } + + if ($dbType === 'char' || $dbType === 'nchar' || $dbType === 'binary') { + $fixed = true; + } + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + + $options = [ + 'length' => $length === 0 || ! in_array($type, ['text', 'string']) ? null : $length, + 'unsigned' => false, + 'fixed' => (bool) $fixed, + 'default' => $default !== 'NULL' ? $default : null, + 'notnull' => (bool) $tableColumn['notnull'], + 'scale' => $tableColumn['scale'], + 'precision' => $tableColumn['precision'], + 'autoincrement' => (bool) $tableColumn['autoincrement'], + 'comment' => $tableColumn['comment'] !== '' ? $tableColumn['comment'] : null, + ]; + + $column = new Column($tableColumn['name'], Type::getType($type), $options); + + if (isset($tableColumn['collation']) && $tableColumn['collation'] !== 'NULL') { + $column->setPlatformOption('collation', $tableColumn['collation']); + } + + return $column; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $foreignKeys = []; + + foreach ($tableForeignKeys as $tableForeignKey) { + if (! isset($foreignKeys[$tableForeignKey['ForeignKey']])) { + $foreignKeys[$tableForeignKey['ForeignKey']] = [ + 'local_columns' => [$tableForeignKey['ColumnName']], + 'foreign_table' => $tableForeignKey['ReferenceTableName'], + 'foreign_columns' => [$tableForeignKey['ReferenceColumnName']], + 'name' => $tableForeignKey['ForeignKey'], + 'options' => [ + 'onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']), + 'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc']), + ], + ]; + } else { + $foreignKeys[$tableForeignKey['ForeignKey']]['local_columns'][] = $tableForeignKey['ColumnName']; + $foreignKeys[$tableForeignKey['ForeignKey']]['foreign_columns'][] = $tableForeignKey['ReferenceColumnName']; + } + } + + return parent::_getPortableTableForeignKeysList($foreignKeys); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableIndexesList($tableIndexRows, $tableName = null) + { + foreach ($tableIndexRows as &$tableIndex) { + $tableIndex['non_unique'] = (bool) $tableIndex['non_unique']; + $tableIndex['primary'] = (bool) $tableIndex['primary']; + $tableIndex['flags'] = $tableIndex['flags'] ? [$tableIndex['flags']] : null; + } + + return parent::_getPortableTableIndexesList($tableIndexRows, $tableName); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return new ForeignKeyConstraint( + $tableForeignKey['local_columns'], + $tableForeignKey['foreign_table'], + $tableForeignKey['foreign_columns'], + $tableForeignKey['name'], + $tableForeignKey['options'] + ); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableDefinition($table) + { + if (isset($table['schema_name']) && $table['schema_name'] !== 'dbo') { + return $table['schema_name'] . '.' . $table['name']; + } + + return $table['name']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['name']; + } + + /** + * {@inheritdoc} + */ + protected function getPortableNamespaceDefinition(array $namespace) + { + return $namespace['name']; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableViewDefinition($view) + { + // @todo + return new View($view['name'], null); + } + + /** + * {@inheritdoc} + */ + public function listTableIndexes($table) + { + $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase()); + + try { + $tableIndexes = $this->_conn->fetchAll($sql); + } catch (PDOException $e) { + if ($e->getCode() === 'IMSSP') { + return []; + } + + throw $e; + } catch (DBALException $e) { + if (strpos($e->getMessage(), 'SQLSTATE [01000, 15472]') === 0) { + return []; + } + + throw $e; + } + + return $this->_getPortableTableIndexesList($tableIndexes, $table); + } + + /** + * {@inheritdoc} + */ + public function alterTable(TableDiff $tableDiff) + { + if (count($tableDiff->removedColumns) > 0) { + foreach ($tableDiff->removedColumns as $col) { + $columnConstraintSql = $this->getColumnConstraintSQL($tableDiff->name, $col->getName()); + foreach ($this->_conn->fetchAll($columnConstraintSql) as $constraint) { + $this->_conn->exec( + sprintf( + 'ALTER TABLE %s DROP CONSTRAINT %s', + $tableDiff->name, + $constraint['Name'] + ) + ); + } + } + } + + parent::alterTable($tableDiff); + } + + /** + * Returns the SQL to retrieve the constraints for a given column. + * + * @param string $table + * @param string $column + * + * @return string + */ + private function getColumnConstraintSQL($table, $column) + { + return "SELECT SysObjects.[Name] + FROM SysObjects INNER JOIN (SELECT [Name],[ID] FROM SysObjects WHERE XType = 'U') AS Tab + ON Tab.[ID] = Sysobjects.[Parent_Obj] + INNER JOIN sys.default_constraints DefCons ON DefCons.[object_id] = Sysobjects.[ID] + INNER JOIN SysColumns Col ON Col.[ColID] = DefCons.[parent_column_id] AND Col.[ID] = Tab.[ID] + WHERE Col.[Name] = " . $this->_conn->quote($column) . ' AND Tab.[Name] = ' . $this->_conn->quote($table) . ' + ORDER BY Col.[Name]'; + } + + /** + * Closes currently active connections on the given database. + * + * This is useful to force DROP DATABASE operations which could fail because of active connections. + * + * @param string $database The name of the database to close currently active connections for. + * + * @return void + */ + private function closeActiveDatabaseConnections($database) + { + $database = new Identifier($database); + + $this->_execSql( + sprintf( + 'ALTER DATABASE %s SET SINGLE_USER WITH ROLLBACK IMMEDIATE', + $database->getQuotedName($this->_platform) + ) + ); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php new file mode 100644 index 000000000..7b75f4fb7 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Schema.php @@ -0,0 +1,471 @@ +_schemaConfig = $schemaConfig; + $this->_setName($schemaConfig->getName() ?: 'public'); + + foreach ($namespaces as $namespace) { + $this->createNamespace($namespace); + } + + foreach ($tables as $table) { + $this->_addTable($table); + } + + foreach ($sequences as $sequence) { + $this->_addSequence($sequence); + } + } + + /** + * @return bool + */ + public function hasExplicitForeignKeyIndexes() + { + return $this->_schemaConfig->hasExplicitForeignKeyIndexes(); + } + + /** + * @return void + * + * @throws SchemaException + */ + protected function _addTable(Table $table) + { + $namespaceName = $table->getNamespaceName(); + $tableName = $table->getFullQualifiedName($this->getName()); + + if (isset($this->_tables[$tableName])) { + throw SchemaException::tableAlreadyExists($tableName); + } + + if (! $table->isInDefaultNamespace($this->getName()) && ! $this->hasNamespace($namespaceName)) { + $this->createNamespace($namespaceName); + } + + $this->_tables[$tableName] = $table; + $table->setSchemaConfig($this->_schemaConfig); + } + + /** + * @return void + * + * @throws SchemaException + */ + protected function _addSequence(Sequence $sequence) + { + $namespaceName = $sequence->getNamespaceName(); + $seqName = $sequence->getFullQualifiedName($this->getName()); + + if (isset($this->_sequences[$seqName])) { + throw SchemaException::sequenceAlreadyExists($seqName); + } + + if (! $sequence->isInDefaultNamespace($this->getName()) && ! $this->hasNamespace($namespaceName)) { + $this->createNamespace($namespaceName); + } + + $this->_sequences[$seqName] = $sequence; + } + + /** + * Returns the namespaces of this schema. + * + * @return string[] A list of namespace names. + */ + public function getNamespaces() + { + return $this->namespaces; + } + + /** + * Gets all tables of this schema. + * + * @return Table[] + */ + public function getTables() + { + return $this->_tables; + } + + /** + * @param string $tableName + * + * @return Table + * + * @throws SchemaException + */ + public function getTable($tableName) + { + $tableName = $this->getFullQualifiedAssetName($tableName); + if (! isset($this->_tables[$tableName])) { + throw SchemaException::tableDoesNotExist($tableName); + } + + return $this->_tables[$tableName]; + } + + /** + * @param string $name + * + * @return string + */ + private function getFullQualifiedAssetName($name) + { + $name = $this->getUnquotedAssetName($name); + + if (strpos($name, '.') === false) { + $name = $this->getName() . '.' . $name; + } + + return strtolower($name); + } + + /** + * Returns the unquoted representation of a given asset name. + * + * @param string $assetName Quoted or unquoted representation of an asset name. + * + * @return string + */ + private function getUnquotedAssetName($assetName) + { + if ($this->isIdentifierQuoted($assetName)) { + return $this->trimQuotes($assetName); + } + + return $assetName; + } + + /** + * Does this schema have a namespace with the given name? + * + * @param string $namespaceName + * + * @return bool + */ + public function hasNamespace($namespaceName) + { + $namespaceName = strtolower($this->getUnquotedAssetName($namespaceName)); + + return isset($this->namespaces[$namespaceName]); + } + + /** + * Does this schema have a table with the given name? + * + * @param string $tableName + * + * @return bool + */ + public function hasTable($tableName) + { + $tableName = $this->getFullQualifiedAssetName($tableName); + + return isset($this->_tables[$tableName]); + } + + /** + * Gets all table names, prefixed with a schema name, even the default one if present. + * + * @return string[] + */ + public function getTableNames() + { + return array_keys($this->_tables); + } + + /** + * @param string $sequenceName + * + * @return bool + */ + public function hasSequence($sequenceName) + { + $sequenceName = $this->getFullQualifiedAssetName($sequenceName); + + return isset($this->_sequences[$sequenceName]); + } + + /** + * @param string $sequenceName + * + * @return Sequence + * + * @throws SchemaException + */ + public function getSequence($sequenceName) + { + $sequenceName = $this->getFullQualifiedAssetName($sequenceName); + if (! $this->hasSequence($sequenceName)) { + throw SchemaException::sequenceDoesNotExist($sequenceName); + } + + return $this->_sequences[$sequenceName]; + } + + /** + * @return Sequence[] + */ + public function getSequences() + { + return $this->_sequences; + } + + /** + * Creates a new namespace. + * + * @param string $namespaceName The name of the namespace to create. + * + * @return \Doctrine\DBAL\Schema\Schema This schema instance. + * + * @throws SchemaException + */ + public function createNamespace($namespaceName) + { + $unquotedNamespaceName = strtolower($this->getUnquotedAssetName($namespaceName)); + + if (isset($this->namespaces[$unquotedNamespaceName])) { + throw SchemaException::namespaceAlreadyExists($unquotedNamespaceName); + } + + $this->namespaces[$unquotedNamespaceName] = $namespaceName; + + return $this; + } + + /** + * Creates a new table. + * + * @param string $tableName + * + * @return Table + */ + public function createTable($tableName) + { + $table = new Table($tableName); + $this->_addTable($table); + + foreach ($this->_schemaConfig->getDefaultTableOptions() as $name => $value) { + $table->addOption($name, $value); + } + + return $table; + } + + /** + * Renames a table. + * + * @param string $oldTableName + * @param string $newTableName + * + * @return \Doctrine\DBAL\Schema\Schema + */ + public function renameTable($oldTableName, $newTableName) + { + $table = $this->getTable($oldTableName); + $table->_setName($newTableName); + + $this->dropTable($oldTableName); + $this->_addTable($table); + + return $this; + } + + /** + * Drops a table from the schema. + * + * @param string $tableName + * + * @return \Doctrine\DBAL\Schema\Schema + */ + public function dropTable($tableName) + { + $tableName = $this->getFullQualifiedAssetName($tableName); + $this->getTable($tableName); + unset($this->_tables[$tableName]); + + return $this; + } + + /** + * Creates a new sequence. + * + * @param string $sequenceName + * @param int $allocationSize + * @param int $initialValue + * + * @return Sequence + */ + public function createSequence($sequenceName, $allocationSize = 1, $initialValue = 1) + { + $seq = new Sequence($sequenceName, $allocationSize, $initialValue); + $this->_addSequence($seq); + + return $seq; + } + + /** + * @param string $sequenceName + * + * @return \Doctrine\DBAL\Schema\Schema + */ + public function dropSequence($sequenceName) + { + $sequenceName = $this->getFullQualifiedAssetName($sequenceName); + unset($this->_sequences[$sequenceName]); + + return $this; + } + + /** + * Returns an array of necessary SQL queries to create the schema on the given platform. + * + * @return string[] + */ + public function toSql(AbstractPlatform $platform) + { + $sqlCollector = new CreateSchemaSqlCollector($platform); + $this->visit($sqlCollector); + + return $sqlCollector->getQueries(); + } + + /** + * Return an array of necessary SQL queries to drop the schema on the given platform. + * + * @return string[] + */ + public function toDropSql(AbstractPlatform $platform) + { + $dropSqlCollector = new DropSchemaSqlCollector($platform); + $this->visit($dropSqlCollector); + + return $dropSqlCollector->getQueries(); + } + + /** + * @return string[] + */ + public function getMigrateToSql(Schema $toSchema, AbstractPlatform $platform) + { + $comparator = new Comparator(); + $schemaDiff = $comparator->compare($this, $toSchema); + + return $schemaDiff->toSql($platform); + } + + /** + * @return string[] + */ + public function getMigrateFromSql(Schema $fromSchema, AbstractPlatform $platform) + { + $comparator = new Comparator(); + $schemaDiff = $comparator->compare($fromSchema, $this); + + return $schemaDiff->toSql($platform); + } + + /** + * @return void + */ + public function visit(Visitor $visitor) + { + $visitor->acceptSchema($this); + + if ($visitor instanceof NamespaceVisitor) { + foreach ($this->namespaces as $namespace) { + $visitor->acceptNamespace($namespace); + } + } + + foreach ($this->_tables as $table) { + $table->visit($visitor); + } + + foreach ($this->_sequences as $sequence) { + $sequence->visit($visitor); + } + } + + /** + * Cloning a Schema triggers a deep clone of all related assets. + * + * @return void + */ + public function __clone() + { + foreach ($this->_tables as $k => $table) { + $this->_tables[$k] = clone $table; + } + foreach ($this->_sequences as $k => $sequence) { + $this->_sequences[$k] = clone $sequence; + } + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaConfig.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaConfig.php new file mode 100644 index 000000000..b8c3502f7 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaConfig.php @@ -0,0 +1,100 @@ +hasExplicitForeignKeyIndexes; + } + + /** + * @param bool $flag + * + * @return void + */ + public function setExplicitForeignKeyIndexes($flag) + { + $this->hasExplicitForeignKeyIndexes = (bool) $flag; + } + + /** + * @param int $length + * + * @return void + */ + public function setMaxIdentifierLength($length) + { + $this->maxIdentifierLength = (int) $length; + } + + /** + * @return int + */ + public function getMaxIdentifierLength() + { + return $this->maxIdentifierLength; + } + + /** + * Gets the default namespace of schema objects. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Sets the default namespace name of schema objects. + * + * @param string $name The value to set. + * + * @return void + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Gets the default options that are passed to Table instances created with + * Schema#createTable(). + * + * @return mixed[] + */ + public function getDefaultTableOptions() + { + return $this->defaultTableOptions; + } + + /** + * @param mixed[] $defaultTableOptions + * + * @return void + */ + public function setDefaultTableOptions(array $defaultTableOptions) + { + $this->defaultTableOptions = $defaultTableOptions; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php new file mode 100644 index 000000000..0f2e25fb3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaDiff.php @@ -0,0 +1,168 @@ +newTables = $newTables; + $this->changedTables = $changedTables; + $this->removedTables = $removedTables; + $this->fromSchema = $fromSchema; + } + + /** + * The to save sql mode ensures that the following things don't happen: + * + * 1. Tables are deleted + * 2. Sequences are deleted + * 3. Foreign Keys which reference tables that would otherwise be deleted. + * + * This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all. + * + * @return string[] + */ + public function toSaveSql(AbstractPlatform $platform) + { + return $this->_toSql($platform, true); + } + + /** + * @return string[] + */ + public function toSql(AbstractPlatform $platform) + { + return $this->_toSql($platform, false); + } + + /** + * @param bool $saveMode + * + * @return string[] + */ + protected function _toSql(AbstractPlatform $platform, $saveMode = false) + { + $sql = []; + + if ($platform->supportsSchemas()) { + foreach ($this->newNamespaces as $newNamespace) { + $sql[] = $platform->getCreateSchemaSQL($newNamespace); + } + } + + if ($platform->supportsForeignKeyConstraints() && $saveMode === false) { + foreach ($this->orphanedForeignKeys as $orphanedForeignKey) { + $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTable()); + } + } + + if ($platform->supportsSequences() === true) { + foreach ($this->changedSequences as $sequence) { + $sql[] = $platform->getAlterSequenceSQL($sequence); + } + + if ($saveMode === false) { + foreach ($this->removedSequences as $sequence) { + $sql[] = $platform->getDropSequenceSQL($sequence); + } + } + + foreach ($this->newSequences as $sequence) { + $sql[] = $platform->getCreateSequenceSQL($sequence); + } + } + + $foreignKeySql = []; + foreach ($this->newTables as $table) { + $sql = array_merge( + $sql, + $platform->getCreateTableSQL($table, AbstractPlatform::CREATE_INDEXES) + ); + + if (! $platform->supportsForeignKeyConstraints()) { + continue; + } + + foreach ($table->getForeignKeys() as $foreignKey) { + $foreignKeySql[] = $platform->getCreateForeignKeySQL($foreignKey, $table); + } + } + $sql = array_merge($sql, $foreignKeySql); + + if ($saveMode === false) { + foreach ($this->removedTables as $table) { + $sql[] = $platform->getDropTableSQL($table); + } + } + + foreach ($this->changedTables as $tableDiff) { + $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff)); + } + + return $sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php new file mode 100644 index 000000000..213d21847 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SchemaException.php @@ -0,0 +1,183 @@ +getName() . ' requires a named foreign key, ' . + 'but the given foreign key from (' . implode(', ', $foreignKey->getColumns()) . ') onto foreign table ' . + "'" . $foreignKey->getForeignTableName() . "' (" . implode(', ', $foreignKey->getForeignColumns()) . ') is currently ' . + 'unnamed.' + ); + } + + /** + * @param string $changeName + * + * @return \Doctrine\DBAL\Schema\SchemaException + */ + public static function alterTableChangeNotSupported($changeName) + { + return new self( + sprintf("Alter table change not supported, given '%s'", $changeName) + ); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php new file mode 100644 index 000000000..24cf4aae0 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Sequence.php @@ -0,0 +1,138 @@ +_setName($name); + $this->setAllocationSize($allocationSize); + $this->setInitialValue($initialValue); + $this->cache = $cache; + } + + /** + * @return int + */ + public function getAllocationSize() + { + return $this->allocationSize; + } + + /** + * @return int + */ + public function getInitialValue() + { + return $this->initialValue; + } + + /** + * @return int|null + */ + public function getCache() + { + return $this->cache; + } + + /** + * @param int $allocationSize + * + * @return \Doctrine\DBAL\Schema\Sequence + */ + public function setAllocationSize($allocationSize) + { + $this->allocationSize = is_numeric($allocationSize) ? (int) $allocationSize : 1; + + return $this; + } + + /** + * @param int $initialValue + * + * @return \Doctrine\DBAL\Schema\Sequence + */ + public function setInitialValue($initialValue) + { + $this->initialValue = is_numeric($initialValue) ? (int) $initialValue : 1; + + return $this; + } + + /** + * @param int $cache + * + * @return \Doctrine\DBAL\Schema\Sequence + */ + public function setCache($cache) + { + $this->cache = $cache; + + return $this; + } + + /** + * Checks if this sequence is an autoincrement sequence for a given table. + * + * This is used inside the comparator to not report sequences as missing, + * when the "from" schema implicitly creates the sequences. + * + * @return bool + */ + public function isAutoIncrementsFor(Table $table) + { + if (! $table->hasPrimaryKey()) { + return false; + } + + $pkColumns = $table->getPrimaryKey()->getColumns(); + + if (count($pkColumns) !== 1) { + return false; + } + + $column = $table->getColumn($pkColumns[0]); + + if (! $column->getAutoincrement()) { + return false; + } + + $sequenceName = $this->getShortestName($table->getNamespaceName()); + $tableName = $table->getShortestName($table->getNamespaceName()); + $tableSequenceName = sprintf('%s_%s_seq', $tableName, $column->getShortestName($table->getNamespaceName())); + + return $tableSequenceName === $sequenceName; + } + + /** + * @return void + */ + public function visit(Visitor $visitor) + { + $visitor->acceptSequence($this); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php new file mode 100644 index 000000000..744acedab --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/SqliteSchemaManager.php @@ -0,0 +1,501 @@ +_conn->getParams(); + $driver = $params['driver']; + $options = [ + 'driver' => $driver, + 'path' => $database, + ]; + $conn = DriverManager::getConnection($options); + $conn->connect(); + $conn->close(); + } + + /** + * {@inheritdoc} + */ + public function renameTable($name, $newName) + { + $tableDiff = new TableDiff($name); + $tableDiff->fromTable = $this->listTableDetails($name); + $tableDiff->newName = $newName; + $this->alterTable($tableDiff); + } + + /** + * {@inheritdoc} + */ + public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); + $tableDiff->addedForeignKeys[] = $foreignKey; + + $this->alterTable($tableDiff); + } + + /** + * {@inheritdoc} + */ + public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); + $tableDiff->changedForeignKeys[] = $foreignKey; + + $this->alterTable($tableDiff); + } + + /** + * {@inheritdoc} + */ + public function dropForeignKey($foreignKey, $table) + { + $tableDiff = $this->getTableDiffForAlterForeignKey($foreignKey, $table); + $tableDiff->removedForeignKeys[] = $foreignKey; + + $this->alterTable($tableDiff); + } + + /** + * {@inheritdoc} + */ + public function listTableForeignKeys($table, $database = null) + { + if ($database === null) { + $database = $this->_conn->getDatabase(); + } + $sql = $this->_platform->getListTableForeignKeysSQL($table, $database); + $tableForeignKeys = $this->_conn->fetchAll($sql); + + if (! empty($tableForeignKeys)) { + $createSql = $this->getCreateTableSQL($table); + + if ($createSql !== null && preg_match_all( + '# + (?:CONSTRAINT\s+([^\s]+)\s+)? + (?:FOREIGN\s+KEY[^\)]+\)\s*)? + REFERENCES\s+[^\s]+\s+(?:\([^\)]+\))? + (?: + [^,]*? + (NOT\s+DEFERRABLE|DEFERRABLE) + (?:\s+INITIALLY\s+(DEFERRED|IMMEDIATE))? + )?#isx', + $createSql, + $match + )) { + $names = array_reverse($match[1]); + $deferrable = array_reverse($match[2]); + $deferred = array_reverse($match[3]); + } else { + $names = $deferrable = $deferred = []; + } + + foreach ($tableForeignKeys as $key => $value) { + $id = $value['id']; + $tableForeignKeys[$key]['constraint_name'] = isset($names[$id]) && $names[$id] !== '' ? $names[$id] : $id; + $tableForeignKeys[$key]['deferrable'] = isset($deferrable[$id]) && strtolower($deferrable[$id]) === 'deferrable'; + $tableForeignKeys[$key]['deferred'] = isset($deferred[$id]) && strtolower($deferred[$id]) === 'deferred'; + } + } + + return $this->_getPortableTableForeignKeysList($tableForeignKeys); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableDefinition($table) + { + return $table['name']; + } + + /** + * {@inheritdoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + $indexBuffer = []; + + // fetch primary + $stmt = $this->_conn->executeQuery(sprintf( + 'PRAGMA TABLE_INFO (%s)', + $this->_conn->quote($tableName) + )); + $indexArray = $stmt->fetchAll(FetchMode::ASSOCIATIVE); + + usort($indexArray, static function ($a, $b) { + if ($a['pk'] === $b['pk']) { + return $a['cid'] - $b['cid']; + } + + return $a['pk'] - $b['pk']; + }); + foreach ($indexArray as $indexColumnRow) { + if ($indexColumnRow['pk'] === '0') { + continue; + } + + $indexBuffer[] = [ + 'key_name' => 'primary', + 'primary' => true, + 'non_unique' => false, + 'column_name' => $indexColumnRow['name'], + ]; + } + + // fetch regular indexes + foreach ($tableIndexes as $tableIndex) { + // Ignore indexes with reserved names, e.g. autoindexes + if (strpos($tableIndex['name'], 'sqlite_') === 0) { + continue; + } + + $keyName = $tableIndex['name']; + $idx = []; + $idx['key_name'] = $keyName; + $idx['primary'] = false; + $idx['non_unique'] = $tableIndex['unique']?false:true; + + $stmt = $this->_conn->executeQuery(sprintf( + 'PRAGMA INDEX_INFO (%s)', + $this->_conn->quote($keyName) + )); + $indexArray = $stmt->fetchAll(FetchMode::ASSOCIATIVE); + + foreach ($indexArray as $indexColumnRow) { + $idx['column_name'] = $indexColumnRow['name']; + $indexBuffer[] = $idx; + } + } + + return parent::_getPortableTableIndexesList($indexBuffer, $tableName); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableIndexDefinition($tableIndex) + { + return [ + 'name' => $tableIndex['name'], + 'unique' => (bool) $tableIndex['unique'], + ]; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableColumnList($table, $database, $tableColumns) + { + $list = parent::_getPortableTableColumnList($table, $database, $tableColumns); + + // find column with autoincrement + $autoincrementColumn = null; + $autoincrementCount = 0; + + foreach ($tableColumns as $tableColumn) { + if ($tableColumn['pk'] === '0') { + continue; + } + + $autoincrementCount++; + if ($autoincrementColumn !== null || strtolower($tableColumn['type']) !== 'integer') { + continue; + } + + $autoincrementColumn = $tableColumn['name']; + } + + if ($autoincrementCount === 1 && $autoincrementColumn !== null) { + foreach ($list as $column) { + if ($autoincrementColumn !== $column->getName()) { + continue; + } + + $column->setAutoincrement(true); + } + } + + // inspect column collation and comments + $createSql = $this->getCreateTableSQL($table) ?? ''; + + foreach ($list as $columnName => $column) { + $type = $column->getType(); + + if ($type instanceof StringType || $type instanceof TextType) { + $column->setPlatformOption('collation', $this->parseColumnCollationFromSQL($columnName, $createSql) ?: 'BINARY'); + } + + $comment = $this->parseColumnCommentFromSQL($columnName, $createSql); + + if ($comment === null) { + continue; + } + + $type = $this->extractDoctrineTypeFromComment($comment, null); + + if ($type !== null) { + $column->setType(Type::getType($type)); + + $comment = $this->removeDoctrineTypeFromComment($comment, $type); + } + + $column->setComment($comment); + } + + return $list; + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $parts = explode('(', $tableColumn['type']); + $tableColumn['type'] = trim($parts[0]); + if (isset($parts[1])) { + $length = trim($parts[1], ')'); + $tableColumn['length'] = $length; + } + + $dbType = strtolower($tableColumn['type']); + $length = $tableColumn['length'] ?? null; + $unsigned = false; + + if (strpos($dbType, ' unsigned') !== false) { + $dbType = str_replace(' unsigned', '', $dbType); + $unsigned = true; + } + + $fixed = false; + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $default = $tableColumn['dflt_value']; + if ($default === 'NULL') { + $default = null; + } + if ($default !== null) { + // SQLite returns strings wrapped in single quotes, so we need to strip them + $default = preg_replace("/^'(.*)'$/", '\1', $default); + } + $notnull = (bool) $tableColumn['notnull']; + + if (! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $precision = null; + $scale = null; + + switch ($dbType) { + case 'char': + $fixed = true; + break; + case 'float': + case 'double': + case 'real': + case 'decimal': + case 'numeric': + if (isset($tableColumn['length'])) { + if (strpos($tableColumn['length'], ',') === false) { + $tableColumn['length'] .= ',0'; + } + [$precision, $scale] = array_map('trim', explode(',', $tableColumn['length'])); + } + $length = null; + break; + } + + $options = [ + 'length' => $length, + 'unsigned' => (bool) $unsigned, + 'fixed' => $fixed, + 'notnull' => $notnull, + 'default' => $default, + 'precision' => $precision, + 'scale' => $scale, + 'autoincrement' => false, + ]; + + return new Column($tableColumn['name'], Type::getType($type), $options); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableViewDefinition($view) + { + return new View($view['name'], $view['sql']); + } + + /** + * {@inheritdoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = []; + foreach ($tableForeignKeys as $value) { + $value = array_change_key_case($value, CASE_LOWER); + $name = $value['constraint_name']; + if (! isset($list[$name])) { + if (! isset($value['on_delete']) || $value['on_delete'] === 'RESTRICT') { + $value['on_delete'] = null; + } + if (! isset($value['on_update']) || $value['on_update'] === 'RESTRICT') { + $value['on_update'] = null; + } + + $list[$name] = [ + 'name' => $name, + 'local' => [], + 'foreign' => [], + 'foreignTable' => $value['table'], + 'onDelete' => $value['on_delete'], + 'onUpdate' => $value['on_update'], + 'deferrable' => $value['deferrable'], + 'deferred'=> $value['deferred'], + ]; + } + $list[$name]['local'][] = $value['from']; + $list[$name]['foreign'][] = $value['to']; + } + + $result = []; + foreach ($list as $constraint) { + $result[] = new ForeignKeyConstraint( + array_values($constraint['local']), + $constraint['foreignTable'], + array_values($constraint['foreign']), + $constraint['name'], + [ + 'onDelete' => $constraint['onDelete'], + 'onUpdate' => $constraint['onUpdate'], + 'deferrable' => $constraint['deferrable'], + 'deferred'=> $constraint['deferred'], + ] + ); + } + + return $result; + } + + /** + * @param Table|string $table + * + * @return TableDiff + * + * @throws DBALException + */ + private function getTableDiffForAlterForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + if (! $table instanceof Table) { + $tableDetails = $this->tryMethod('listTableDetails', $table); + if ($table === false) { + throw new DBALException(sprintf('Sqlite schema manager requires to modify foreign keys table definition "%s".', $table)); + } + + $table = $tableDetails; + } + + $tableDiff = new TableDiff($table->getName()); + $tableDiff->fromTable = $table; + + return $tableDiff; + } + + private function parseColumnCollationFromSQL(string $column, string $sql) : ?string + { + $pattern = '{(?:\W' . preg_quote($column) . '\W|\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) + . '\W)[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}is'; + + if (preg_match($pattern, $sql, $match) !== 1) { + return null; + } + + return $match[1]; + } + + private function parseColumnCommentFromSQL(string $column, string $sql) : ?string + { + $pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) . '\W|\W' . preg_quote($column) + . '\W)(?:\(.*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i'; + + if (preg_match($pattern, $sql, $match) !== 1) { + return null; + } + + $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); + + return $comment === '' ? null : $comment; + } + + private function getCreateTableSQL(string $table) : ?string + { + return $this->_conn->fetchColumn( + <<<'SQL' +SELECT sql + FROM ( + SELECT * + FROM sqlite_master + UNION ALL + SELECT * + FROM sqlite_temp_master + ) +WHERE type = 'table' +AND name = ? +SQL + , + [$table] + ) ?: null; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/AbstractSchemaSynchronizer.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/AbstractSchemaSynchronizer.php new file mode 100644 index 000000000..b597b8db9 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/AbstractSchemaSynchronizer.php @@ -0,0 +1,43 @@ +conn = $conn; + } + + /** + * @param string[] $sql + */ + protected function processSqlSafely(array $sql) + { + foreach ($sql as $s) { + try { + $this->conn->exec($s); + } catch (Throwable $e) { + } + } + } + + /** + * @param string[] $sql + */ + protected function processSql(array $sql) + { + foreach ($sql as $s) { + $this->conn->exec($s); + } + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SchemaSynchronizer.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SchemaSynchronizer.php new file mode 100644 index 000000000..3e7beea75 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Synchronizer/SchemaSynchronizer.php @@ -0,0 +1,72 @@ +platform = $conn->getDatabasePlatform(); + } + + /** + * {@inheritdoc} + */ + public function getCreateSchema(Schema $createSchema) + { + return $createSchema->toSql($this->platform); + } + + + /** + * {@inheritdoc} + */ + public function getUpdateSchema(Schema $toSchema, $noDrops = false) + { + $comparator = new Comparator(); + $sm = $this->conn->getSchemaManager(); + + $fromSchema = $sm->createSchema(); + $schemaDiff = $comparator->compare($fromSchema, $toSchema); + + if ($noDrops) { + return $schemaDiff->toSaveSql($this->platform); + } + + return $schemaDiff->toSql($this->platform); + } + + /** + * {@inheritdoc} + */ + public function getDropSchema(Schema $dropSchema) + { + $visitor = new DropSchemaSqlCollector($this->platform); + $sm = $this->conn->getSchemaManager(); + + $fullSchema = $sm->createSchema(); + + foreach ($fullSchema->getTables() as $table) { + if ($dropSchema->hasTable($table->getName())) { + $visitor->acceptTable($table); + } + + foreach ($table->getForeignKeys() as $foreignKey) { + if (! $dropSchema->hasTable($table->getName())) { + continue; + } + + if (! $dropSchema->hasTable($foreignKey->getForeignTableName())) { + continue; + } + + $visitor->acceptForeignKey($table, $foreignKey); + } + } + + if (! $this->platform->supportsSequences()) { + return $visitor->getQueries(); + } + + foreach ($dropSchema->getSequences() as $sequence) { + $visitor->acceptSequence($sequence); + } + + foreach ($dropSchema->getTables() as $table) { + if (! $table->hasPrimaryKey()) { + continue; + } + + $columns = $table->getPrimaryKey()->getColumns(); + if (count($columns) > 1) { + continue; + } + + $checkSequence = $table->getName() . '_' . $columns[0] . '_seq'; + if (! $fullSchema->hasSequence($checkSequence)) { + continue; + } + + $visitor->acceptSequence($fullSchema->getSequence($checkSequence)); + } + + return $visitor->getQueries(); + } + + /** + * {@inheritdoc} + */ + public function getDropAllSchema() + { + $sm = $this->conn->getSchemaManager(); + $visitor = new DropSchemaSqlCollector($this->platform); + + $schema = $sm->createSchema(); + $schema->visit($visitor); + + return $visitor->getQueries(); + } + + /** + * {@inheritdoc} + */ + public function createSchema(Schema $createSchema) + { + $this->processSql($this->getCreateSchema($createSchema)); + } + + /** + * {@inheritdoc} + */ + public function updateSchema(Schema $toSchema, $noDrops = false) + { + $this->processSql($this->getUpdateSchema($toSchema, $noDrops)); + } + + /** + * {@inheritdoc} + */ + public function dropSchema(Schema $dropSchema) + { + $this->processSqlSafely($this->getDropSchema($dropSchema)); + } + + /** + * {@inheritdoc} + */ + public function dropAllSchema() + { + $this->processSql($this->getDropAllSchema()); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php new file mode 100644 index 000000000..191294d6d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php @@ -0,0 +1,834 @@ +_setName($tableName); + + foreach ($columns as $column) { + $this->_addColumn($column); + } + + foreach ($indexes as $idx) { + $this->_addIndex($idx); + } + + foreach ($fkConstraints as $constraint) { + $this->_addForeignKeyConstraint($constraint); + } + + $this->_options = $options; + } + + /** + * @return void + */ + public function setSchemaConfig(SchemaConfig $schemaConfig) + { + $this->_schemaConfig = $schemaConfig; + } + + /** + * @return int + */ + protected function _getMaxIdentifierLength() + { + if ($this->_schemaConfig instanceof SchemaConfig) { + return $this->_schemaConfig->getMaxIdentifierLength(); + } + + return 63; + } + + /** + * Sets the Primary Key. + * + * @param string[] $columnNames + * @param string|bool $indexName + * + * @return self + */ + public function setPrimaryKey(array $columnNames, $indexName = false) + { + $this->_addIndex($this->_createIndex($columnNames, $indexName ?: 'primary', true, true)); + + foreach ($columnNames as $columnName) { + $column = $this->getColumn($columnName); + $column->setNotnull(true); + } + + return $this; + } + + /** + * @param string[] $columnNames + * @param string|null $indexName + * @param string[] $flags + * @param mixed[] $options + * + * @return self + */ + public function addIndex(array $columnNames, $indexName = null, array $flags = [], array $options = []) + { + if ($indexName === null) { + $indexName = $this->_generateIdentifierName( + array_merge([$this->getName()], $columnNames), + 'idx', + $this->_getMaxIdentifierLength() + ); + } + + return $this->_addIndex($this->_createIndex($columnNames, $indexName, false, false, $flags, $options)); + } + + /** + * Drops the primary key from this table. + * + * @return void + */ + public function dropPrimaryKey() + { + $this->dropIndex($this->_primaryKeyName); + $this->_primaryKeyName = false; + } + + /** + * Drops an index from this table. + * + * @param string $indexName The index name. + * + * @return void + * + * @throws SchemaException If the index does not exist. + */ + public function dropIndex($indexName) + { + $indexName = $this->normalizeIdentifier($indexName); + if (! $this->hasIndex($indexName)) { + throw SchemaException::indexDoesNotExist($indexName, $this->_name); + } + unset($this->_indexes[$indexName]); + } + + /** + * @param string[] $columnNames + * @param string|null $indexName + * @param mixed[] $options + * + * @return self + */ + public function addUniqueIndex(array $columnNames, $indexName = null, array $options = []) + { + if ($indexName === null) { + $indexName = $this->_generateIdentifierName( + array_merge([$this->getName()], $columnNames), + 'uniq', + $this->_getMaxIdentifierLength() + ); + } + + return $this->_addIndex($this->_createIndex($columnNames, $indexName, true, false, [], $options)); + } + + /** + * Renames an index. + * + * @param string $oldIndexName The name of the index to rename from. + * @param string|null $newIndexName The name of the index to rename to. + * If null is given, the index name will be auto-generated. + * + * @return self This table instance. + * + * @throws SchemaException If no index exists for the given current name + * or if an index with the given new name already exists on this table. + */ + public function renameIndex($oldIndexName, $newIndexName = null) + { + $oldIndexName = $this->normalizeIdentifier($oldIndexName); + $normalizedNewIndexName = $this->normalizeIdentifier($newIndexName); + + if ($oldIndexName === $normalizedNewIndexName) { + return $this; + } + + if (! $this->hasIndex($oldIndexName)) { + throw SchemaException::indexDoesNotExist($oldIndexName, $this->_name); + } + + if ($this->hasIndex($normalizedNewIndexName)) { + throw SchemaException::indexAlreadyExists($normalizedNewIndexName, $this->_name); + } + + $oldIndex = $this->_indexes[$oldIndexName]; + + if ($oldIndex->isPrimary()) { + $this->dropPrimaryKey(); + + return $this->setPrimaryKey($oldIndex->getColumns(), $newIndexName); + } + + unset($this->_indexes[$oldIndexName]); + + if ($oldIndex->isUnique()) { + return $this->addUniqueIndex($oldIndex->getColumns(), $newIndexName, $oldIndex->getOptions()); + } + + return $this->addIndex($oldIndex->getColumns(), $newIndexName, $oldIndex->getFlags(), $oldIndex->getOptions()); + } + + /** + * Checks if an index begins in the order of the given columns. + * + * @param string[] $columnNames + * + * @return bool + */ + public function columnsAreIndexed(array $columnNames) + { + foreach ($this->getIndexes() as $index) { + /** @var $index Index */ + if ($index->spansColumns($columnNames)) { + return true; + } + } + + return false; + } + + /** + * @param string[] $columnNames + * @param string $indexName + * @param bool $isUnique + * @param bool $isPrimary + * @param string[] $flags + * @param mixed[] $options + * + * @return Index + * + * @throws SchemaException + */ + private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary, array $flags = [], array $options = []) + { + if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) { + throw SchemaException::indexNameInvalid($indexName); + } + + foreach ($columnNames as $columnName) { + if (! $this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + } + + return new Index($indexName, $columnNames, $isUnique, $isPrimary, $flags, $options); + } + + /** + * @param string $columnName + * @param string $typeName + * @param mixed[] $options + * + * @return Column + */ + public function addColumn($columnName, $typeName, array $options = []) + { + $column = new Column($columnName, Type::getType($typeName), $options); + + $this->_addColumn($column); + + return $column; + } + + /** + * Renames a Column. + * + * @deprecated + * + * @param string $oldColumnName + * @param string $newColumnName + * + * @throws DBALException + */ + public function renameColumn($oldColumnName, $newColumnName) + { + throw new DBALException('Table#renameColumn() was removed, because it drops and recreates ' . + 'the column instead. There is no fix available, because a schema diff cannot reliably detect if a ' . + 'column was renamed or one column was created and another one dropped.'); + } + + /** + * Change Column Details. + * + * @param string $columnName + * @param mixed[] $options + * + * @return self + */ + public function changeColumn($columnName, array $options) + { + $column = $this->getColumn($columnName); + $column->setOptions($options); + + return $this; + } + + /** + * Drops a Column from the Table. + * + * @param string $columnName + * + * @return self + */ + public function dropColumn($columnName) + { + $columnName = $this->normalizeIdentifier($columnName); + unset($this->_columns[$columnName]); + + return $this; + } + + /** + * Adds a foreign key constraint. + * + * Name is inferred from the local columns. + * + * @param Table|string $foreignTable Table schema instance or table name + * @param string[] $localColumnNames + * @param string[] $foreignColumnNames + * @param mixed[] $options + * @param string|null $constraintName + * + * @return self + */ + public function addForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options = [], $constraintName = null) + { + $constraintName = $constraintName ?: $this->_generateIdentifierName(array_merge((array) $this->getName(), $localColumnNames), 'fk', $this->_getMaxIdentifierLength()); + + return $this->addNamedForeignKeyConstraint($constraintName, $foreignTable, $localColumnNames, $foreignColumnNames, $options); + } + + /** + * Adds a foreign key constraint. + * + * Name is to be generated by the database itself. + * + * @deprecated Use {@link addForeignKeyConstraint} + * + * @param Table|string $foreignTable Table schema instance or table name + * @param string[] $localColumnNames + * @param string[] $foreignColumnNames + * @param mixed[] $options + * + * @return self + */ + public function addUnnamedForeignKeyConstraint($foreignTable, array $localColumnNames, array $foreignColumnNames, array $options = []) + { + return $this->addForeignKeyConstraint($foreignTable, $localColumnNames, $foreignColumnNames, $options); + } + + /** + * Adds a foreign key constraint with a given name. + * + * @deprecated Use {@link addForeignKeyConstraint} + * + * @param string $name + * @param Table|string $foreignTable Table schema instance or table name + * @param string[] $localColumnNames + * @param string[] $foreignColumnNames + * @param mixed[] $options + * + * @return self + * + * @throws SchemaException + */ + public function addNamedForeignKeyConstraint($name, $foreignTable, array $localColumnNames, array $foreignColumnNames, array $options = []) + { + if ($foreignTable instanceof Table) { + foreach ($foreignColumnNames as $columnName) { + if (! $foreignTable->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $foreignTable->getName()); + } + } + } + + foreach ($localColumnNames as $columnName) { + if (! $this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + } + + $constraint = new ForeignKeyConstraint( + $localColumnNames, + $foreignTable, + $foreignColumnNames, + $name, + $options + ); + $this->_addForeignKeyConstraint($constraint); + + return $this; + } + + /** + * @param string $name + * @param string $value + * + * @return self + */ + public function addOption($name, $value) + { + $this->_options[$name] = $value; + + return $this; + } + + /** + * @return void + * + * @throws SchemaException + */ + protected function _addColumn(Column $column) + { + $columnName = $column->getName(); + $columnName = $this->normalizeIdentifier($columnName); + + if (isset($this->_columns[$columnName])) { + throw SchemaException::columnAlreadyExists($this->getName(), $columnName); + } + + $this->_columns[$columnName] = $column; + } + + /** + * Adds an index to the table. + * + * @return self + * + * @throws SchemaException + */ + protected function _addIndex(Index $indexCandidate) + { + $indexName = $indexCandidate->getName(); + $indexName = $this->normalizeIdentifier($indexName); + $replacedImplicitIndexes = []; + + foreach ($this->implicitIndexes as $name => $implicitIndex) { + if (! $implicitIndex->isFullfilledBy($indexCandidate) || ! isset($this->_indexes[$name])) { + continue; + } + + $replacedImplicitIndexes[] = $name; + } + + if ((isset($this->_indexes[$indexName]) && ! in_array($indexName, $replacedImplicitIndexes, true)) || + ($this->_primaryKeyName !== false && $indexCandidate->isPrimary()) + ) { + throw SchemaException::indexAlreadyExists($indexName, $this->_name); + } + + foreach ($replacedImplicitIndexes as $name) { + unset($this->_indexes[$name], $this->implicitIndexes[$name]); + } + + if ($indexCandidate->isPrimary()) { + $this->_primaryKeyName = $indexName; + } + + $this->_indexes[$indexName] = $indexCandidate; + + return $this; + } + + /** + * @return void + */ + protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint) + { + $constraint->setLocalTable($this); + + if (strlen($constraint->getName())) { + $name = $constraint->getName(); + } else { + $name = $this->_generateIdentifierName( + array_merge((array) $this->getName(), $constraint->getLocalColumns()), + 'fk', + $this->_getMaxIdentifierLength() + ); + } + $name = $this->normalizeIdentifier($name); + + $this->_fkConstraints[$name] = $constraint; + + // add an explicit index on the foreign key columns. If there is already an index that fulfils this requirements drop the request. + // In the case of __construct calling this method during hydration from schema-details all the explicitly added indexes + // lead to duplicates. This creates computation overhead in this case, however no duplicate indexes are ever added (based on columns). + $indexName = $this->_generateIdentifierName( + array_merge([$this->getName()], $constraint->getColumns()), + 'idx', + $this->_getMaxIdentifierLength() + ); + $indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, false, false); + + foreach ($this->_indexes as $existingIndex) { + if ($indexCandidate->isFullfilledBy($existingIndex)) { + return; + } + } + + $this->_addIndex($indexCandidate); + $this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate; + } + + /** + * Returns whether this table has a foreign key constraint with the given name. + * + * @param string $constraintName + * + * @return bool + */ + public function hasForeignKey($constraintName) + { + $constraintName = $this->normalizeIdentifier($constraintName); + + return isset($this->_fkConstraints[$constraintName]); + } + + /** + * Returns the foreign key constraint with the given name. + * + * @param string $constraintName The constraint name. + * + * @return ForeignKeyConstraint + * + * @throws SchemaException If the foreign key does not exist. + */ + public function getForeignKey($constraintName) + { + $constraintName = $this->normalizeIdentifier($constraintName); + if (! $this->hasForeignKey($constraintName)) { + throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name); + } + + return $this->_fkConstraints[$constraintName]; + } + + /** + * Removes the foreign key constraint with the given name. + * + * @param string $constraintName The constraint name. + * + * @return void + * + * @throws SchemaException + */ + public function removeForeignKey($constraintName) + { + $constraintName = $this->normalizeIdentifier($constraintName); + if (! $this->hasForeignKey($constraintName)) { + throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name); + } + + unset($this->_fkConstraints[$constraintName]); + } + + /** + * Returns ordered list of columns (primary keys are first, then foreign keys, then the rest) + * + * @return Column[] + */ + public function getColumns() + { + $primaryKeyColumns = []; + if ($this->hasPrimaryKey()) { + $primaryKeyColumns = $this->filterColumns($this->getPrimaryKey()->getColumns()); + } + + return array_merge($primaryKeyColumns, $this->getForeignKeyColumns(), $this->_columns); + } + + /** + * Returns foreign key columns + * + * @return Column[] + */ + private function getForeignKeyColumns() + { + $foreignKeyColumns = []; + foreach ($this->getForeignKeys() as $foreignKey) { + $foreignKeyColumns = array_merge($foreignKeyColumns, $foreignKey->getColumns()); + } + return $this->filterColumns($foreignKeyColumns); + } + + /** + * Returns only columns that have specified names + * + * @param string[] $columnNames + * + * @return Column[] + */ + private function filterColumns(array $columnNames) + { + return array_filter($this->_columns, static function ($columnName) use ($columnNames) { + return in_array($columnName, $columnNames, true); + }, ARRAY_FILTER_USE_KEY); + } + + /** + * Returns whether this table has a Column with the given name. + * + * @param string $columnName The column name. + * + * @return bool + */ + public function hasColumn($columnName) + { + $columnName = $this->normalizeIdentifier($columnName); + + return isset($this->_columns[$columnName]); + } + + /** + * Returns the Column with the given name. + * + * @param string $columnName The column name. + * + * @return Column + * + * @throws SchemaException If the column does not exist. + */ + public function getColumn($columnName) + { + $columnName = $this->normalizeIdentifier($columnName); + if (! $this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + + return $this->_columns[$columnName]; + } + + /** + * Returns the primary key. + * + * @return Index|null The primary key, or null if this Table has no primary key. + */ + public function getPrimaryKey() + { + if (! $this->hasPrimaryKey()) { + return null; + } + + return $this->getIndex($this->_primaryKeyName); + } + + /** + * Returns the primary key columns. + * + * @return string[] + * + * @throws DBALException + */ + public function getPrimaryKeyColumns() + { + if (! $this->hasPrimaryKey()) { + throw new DBALException('Table ' . $this->getName() . ' has no primary key.'); + } + return $this->getPrimaryKey()->getColumns(); + } + + /** + * Returns whether this table has a primary key. + * + * @return bool + */ + public function hasPrimaryKey() + { + return $this->_primaryKeyName && $this->hasIndex($this->_primaryKeyName); + } + + /** + * Returns whether this table has an Index with the given name. + * + * @param string $indexName The index name. + * + * @return bool + */ + public function hasIndex($indexName) + { + $indexName = $this->normalizeIdentifier($indexName); + + return isset($this->_indexes[$indexName]); + } + + /** + * Returns the Index with the given name. + * + * @param string $indexName The index name. + * + * @return Index + * + * @throws SchemaException If the index does not exist. + */ + public function getIndex($indexName) + { + $indexName = $this->normalizeIdentifier($indexName); + if (! $this->hasIndex($indexName)) { + throw SchemaException::indexDoesNotExist($indexName, $this->_name); + } + + return $this->_indexes[$indexName]; + } + + /** + * @return Index[] + */ + public function getIndexes() + { + return $this->_indexes; + } + + /** + * Returns the foreign key constraints. + * + * @return ForeignKeyConstraint[] + */ + public function getForeignKeys() + { + return $this->_fkConstraints; + } + + /** + * @param string $name + * + * @return bool + */ + public function hasOption($name) + { + return isset($this->_options[$name]); + } + + /** + * @param string $name + * + * @return mixed + */ + public function getOption($name) + { + return $this->_options[$name]; + } + + /** + * @return mixed[] + */ + public function getOptions() + { + return $this->_options; + } + + /** + * @return void + */ + public function visit(Visitor $visitor) + { + $visitor->acceptTable($this); + + foreach ($this->getColumns() as $column) { + $visitor->acceptColumn($this, $column); + } + + foreach ($this->getIndexes() as $index) { + $visitor->acceptIndex($this, $index); + } + + foreach ($this->getForeignKeys() as $constraint) { + $visitor->acceptForeignKey($this, $constraint); + } + } + + /** + * Clone of a Table triggers a deep clone of all affected assets. + * + * @return void + */ + public function __clone() + { + foreach ($this->_columns as $k => $column) { + $this->_columns[$k] = clone $column; + } + foreach ($this->_indexes as $k => $index) { + $this->_indexes[$k] = clone $index; + } + foreach ($this->_fkConstraints as $k => $fk) { + $this->_fkConstraints[$k] = clone $fk; + $this->_fkConstraints[$k]->setLocalTable($this); + } + } + + /** + * Normalizes a given identifier. + * + * Trims quotes and lowercases the given identifier. + * + * @param string $identifier The identifier to normalize. + * + * @return string The normalized identifier. + */ + private function normalizeIdentifier($identifier) + { + return $this->trimQuotes(strtolower($identifier)); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php new file mode 100644 index 000000000..457e1b6a9 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php @@ -0,0 +1,148 @@ +name = $tableName; + $this->addedColumns = $addedColumns; + $this->changedColumns = $changedColumns; + $this->removedColumns = $removedColumns; + $this->addedIndexes = $addedIndexes; + $this->changedIndexes = $changedIndexes; + $this->removedIndexes = $removedIndexes; + $this->fromTable = $fromTable; + } + + /** + * @param AbstractPlatform $platform The platform to use for retrieving this table diff's name. + * + * @return Identifier + */ + public function getName(AbstractPlatform $platform) + { + return new Identifier( + $this->fromTable instanceof Table ? $this->fromTable->getQuotedName($platform) : $this->name + ); + } + + /** + * @return Identifier|string|bool + */ + public function getNewName() + { + return $this->newName ? new Identifier($this->newName) : $this->newName; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/View.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/View.php new file mode 100644 index 000000000..ac8d6cb5c --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/View.php @@ -0,0 +1,30 @@ +_setName($name); + $this->sql = $sql; + } + + /** + * @return string + */ + public function getSql() + { + return $this->sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/AbstractVisitor.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/AbstractVisitor.php new file mode 100644 index 000000000..471690442 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/AbstractVisitor.php @@ -0,0 +1,47 @@ +platform = $platform; + } + + /** + * {@inheritdoc} + */ + public function acceptNamespace($namespaceName) + { + if (! $this->platform->supportsSchemas()) { + return; + } + + $this->createNamespaceQueries[] = $this->platform->getCreateSchemaSQL($namespaceName); + } + + /** + * {@inheritdoc} + */ + public function acceptTable(Table $table) + { + $this->createTableQueries = array_merge($this->createTableQueries, (array) $this->platform->getCreateTableSQL($table)); + } + + /** + * {@inheritdoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + if (! $this->platform->supportsForeignKeyConstraints()) { + return; + } + + $this->createFkConstraintQueries[] = $this->platform->getCreateForeignKeySQL($fkConstraint, $localTable); + } + + /** + * {@inheritdoc} + */ + public function acceptSequence(Sequence $sequence) + { + $this->createSequenceQueries[] = $this->platform->getCreateSequenceSQL($sequence); + } + + /** + * @return void + */ + public function resetQueries() + { + $this->createNamespaceQueries = []; + $this->createTableQueries = []; + $this->createSequenceQueries = []; + $this->createFkConstraintQueries = []; + } + + /** + * Gets all queries collected so far. + * + * @return string[] + */ + public function getQueries() + { + return array_merge( + $this->createNamespaceQueries, + $this->createTableQueries, + $this->createSequenceQueries, + $this->createFkConstraintQueries + ); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php new file mode 100644 index 000000000..44f5ea80a --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/DropSchemaSqlCollector.php @@ -0,0 +1,96 @@ +platform = $platform; + $this->clearQueries(); + } + + /** + * {@inheritdoc} + */ + public function acceptTable(Table $table) + { + $this->tables->attach($table); + } + + /** + * {@inheritdoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + if (strlen($fkConstraint->getName()) === 0) { + throw SchemaException::namedForeignKeyRequired($localTable, $fkConstraint); + } + + $this->constraints->attach($fkConstraint, $localTable); + } + + /** + * {@inheritdoc} + */ + public function acceptSequence(Sequence $sequence) + { + $this->sequences->attach($sequence); + } + + /** + * @return void + */ + public function clearQueries() + { + $this->constraints = new SplObjectStorage(); + $this->sequences = new SplObjectStorage(); + $this->tables = new SplObjectStorage(); + } + + /** + * @return string[] + */ + public function getQueries() + { + $sql = []; + + foreach ($this->constraints as $fkConstraint) { + $localTable = $this->constraints[$fkConstraint]; + $sql[] = $this->platform->getDropForeignKeySQL($fkConstraint, $localTable); + } + + foreach ($this->sequences as $sequence) { + $sql[] = $this->platform->getDropSequenceSQL($sequence); + } + + foreach ($this->tables as $table) { + $sql[] = $this->platform->getDropTableSQL($table); + } + + return $sql; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php new file mode 100644 index 000000000..889f96112 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/Graphviz.php @@ -0,0 +1,159 @@ +output .= $this->createNodeRelation( + $fkConstraint->getLocalTableName() . ':col' . current($fkConstraint->getLocalColumns()) . ':se', + $fkConstraint->getForeignTableName() . ':col' . current($fkConstraint->getForeignColumns()) . ':se', + [ + 'dir' => 'back', + 'arrowtail' => 'dot', + 'arrowhead' => 'normal', + ] + ); + } + + /** + * {@inheritdoc} + */ + public function acceptSchema(Schema $schema) + { + $this->output = 'digraph "' . sha1(mt_rand()) . '" {' . "\n"; + $this->output .= 'splines = true;' . "\n"; + $this->output .= 'overlap = false;' . "\n"; + $this->output .= 'outputorder=edgesfirst;' . "\n"; + $this->output .= 'mindist = 0.6;' . "\n"; + $this->output .= 'sep = .2;' . "\n"; + } + + /** + * {@inheritdoc} + */ + public function acceptTable(Table $table) + { + $this->output .= $this->createNode( + $table->getName(), + [ + 'label' => $this->createTableLabel($table), + 'shape' => 'plaintext', + ] + ); + } + + /** + * @return string + */ + private function createTableLabel(Table $table) + { + // Start the table + $label = '<'; + + // The title + $label .= ''; + + // The attributes block + foreach ($table->getColumns() as $column) { + $columnLabel = $column->getName(); + + $label .= ''; + $label .= ''; + $label .= ''; + } + + // End the table + $label .= '
' . $table->getName() . '
'; + $label .= '' . $columnLabel . ''; + $label .= '' . strtolower($column->getType()) . ''; + if ($table->hasPrimaryKey() && in_array($column->getName(), $table->getPrimaryKey()->getColumns())) { + $label .= "\xe2\x9c\xb7"; + } + $label .= '
>'; + + return $label; + } + + /** + * @param string $name + * @param string[] $options + * + * @return string + */ + private function createNode($name, $options) + { + $node = $name . ' ['; + foreach ($options as $key => $value) { + $node .= $key . '=' . $value . ' '; + } + $node .= "]\n"; + + return $node; + } + + /** + * @param string $node1 + * @param string $node2 + * @param string[] $options + * + * @return string + */ + private function createNodeRelation($node1, $node2, $options) + { + $relation = $node1 . ' -> ' . $node2 . ' ['; + foreach ($options as $key => $value) { + $relation .= $key . '=' . $value . ' '; + } + $relation .= "]\n"; + + return $relation; + } + + /** + * Get Graphviz Output + * + * @return string + */ + public function getOutput() + { + return $this->output . '}'; + } + + /** + * Writes dot language output to a file. This should usually be a *.dot file. + * + * You have to convert the output into a viewable format. For example use "neato" on linux systems + * and execute: + * + * neato -Tpng -o er.png er.dot + * + * @param string $filename + * + * @return void + */ + public function write($filename) + { + file_put_contents($filename, $this->getOutput()); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/NamespaceVisitor.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/NamespaceVisitor.php new file mode 100644 index 000000000..186fe1b42 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/NamespaceVisitor.php @@ -0,0 +1,16 @@ +schema = $schema; + } + + /** + * {@inheritdoc} + */ + public function acceptTable(Table $table) + { + if ($table->isInDefaultNamespace($this->schema->getName())) { + return; + } + + $this->schema->dropTable($table->getName()); + } + + /** + * {@inheritdoc} + */ + public function acceptSequence(Sequence $sequence) + { + if ($sequence->isInDefaultNamespace($this->schema->getName())) { + return; + } + + $this->schema->dropSequence($sequence->getName()); + } + + /** + * {@inheritdoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + // The table may already be deleted in a previous + // RemoveNamespacedAssets#acceptTable call. Removing Foreign keys that + // point to nowhere. + if (! $this->schema->hasTable($fkConstraint->getForeignTableName())) { + $localTable->removeForeignKey($fkConstraint->getName()); + return; + } + + $foreignTable = $this->schema->getTable($fkConstraint->getForeignTableName()); + if ($foreignTable->isInDefaultNamespace($this->schema->getName())) { + return; + } + + $localTable->removeForeignKey($fkConstraint->getName()); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/SchemaDiffVisitor.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/SchemaDiffVisitor.php new file mode 100644 index 000000000..5ec843d9b --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Visitor/SchemaDiffVisitor.php @@ -0,0 +1,39 @@ + "client" to the ShardChooser interface. + * - An exception is thrown if trying to switch shards during an open + * transaction. + * + * Instantiation through the DriverManager looks like: + * + * @example + * + * $conn = DriverManager::getConnection(array( + * 'wrapperClass' => 'Doctrine\DBAL\Sharding\PoolingShardConnection', + * 'driver' => 'pdo_mysql', + * 'global' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''), + * 'shards' => array( + * array('id' => 1, 'user' => 'slave1', 'password', 'host' => '', 'dbname' => ''), + * array('id' => 2, 'user' => 'slave2', 'password', 'host' => '', 'dbname' => ''), + * ), + * 'shardChoser' => 'Doctrine\DBAL\Sharding\ShardChoser\MultiTenantShardChoser', + * )); + * $shardManager = $conn->getShardManager(); + * $shardManager->selectGlobal(); + * $shardManager->selectShard($value); + */ +class PoolingShardConnection extends Connection +{ + /** @var DriverConnection[] */ + private $activeConnections = []; + + /** @var int|null */ + private $activeShardId; + + /** @var mixed[] */ + private $connectionParameters = []; + + /** + * {@inheritDoc} + * + * @throws InvalidArgumentException + */ + public function __construct(array $params, Driver $driver, ?Configuration $config = null, ?EventManager $eventManager = null) + { + if (! isset($params['global'], $params['shards'])) { + throw new InvalidArgumentException("Connection Parameters require 'global' and 'shards' configurations."); + } + + if (! isset($params['shardChoser'])) { + throw new InvalidArgumentException("Missing Shard Choser configuration 'shardChoser'"); + } + + if (is_string($params['shardChoser'])) { + $params['shardChoser'] = new $params['shardChoser'](); + } + + if (! ($params['shardChoser'] instanceof ShardChoser)) { + throw new InvalidArgumentException("The 'shardChoser' configuration is not a valid instance of Doctrine\DBAL\Sharding\ShardChoser\ShardChoser"); + } + + $this->connectionParameters[0] = array_merge($params, $params['global']); + + foreach ($params['shards'] as $shard) { + if (! isset($shard['id'])) { + throw new InvalidArgumentException("Missing 'id' for one configured shard. Please specify a unique shard-id."); + } + + if (! is_numeric($shard['id']) || $shard['id'] < 1) { + throw new InvalidArgumentException('Shard Id has to be a non-negative number.'); + } + + if (isset($this->connectionParameters[$shard['id']])) { + throw new InvalidArgumentException('Shard ' . $shard['id'] . ' is duplicated in the configuration.'); + } + + $this->connectionParameters[$shard['id']] = array_merge($params, $shard); + } + + parent::__construct($params, $driver, $config, $eventManager); + } + + /** + * Get active shard id. + * + * @return int + */ + public function getActiveShardId() + { + return $this->activeShardId; + } + + /** + * {@inheritdoc} + */ + public function getParams() + { + return $this->activeShardId ? $this->connectionParameters[$this->activeShardId] : $this->connectionParameters[0]; + } + + /** + * {@inheritdoc} + */ + public function getHost() + { + $params = $this->getParams(); + + return $params['host'] ?? parent::getHost(); + } + + /** + * {@inheritdoc} + */ + public function getPort() + { + $params = $this->getParams(); + + return $params['port'] ?? parent::getPort(); + } + + /** + * {@inheritdoc} + */ + public function getUsername() + { + $params = $this->getParams(); + + return $params['user'] ?? parent::getUsername(); + } + + /** + * {@inheritdoc} + */ + public function getPassword() + { + $params = $this->getParams(); + + return $params['password'] ?? parent::getPassword(); + } + + /** + * Connects to a given shard. + * + * @param mixed $shardId + * + * @return bool + * + * @throws ShardingException + */ + public function connect($shardId = null) + { + if ($shardId === null && $this->_conn) { + return false; + } + + if ($shardId !== null && $shardId === $this->activeShardId) { + return false; + } + + if ($this->getTransactionNestingLevel() > 0) { + throw new ShardingException('Cannot switch shard when transaction is active.'); + } + + $this->activeShardId = (int) $shardId; + + if (isset($this->activeConnections[$this->activeShardId])) { + $this->_conn = $this->activeConnections[$this->activeShardId]; + + return false; + } + + $this->_conn = $this->activeConnections[$this->activeShardId] = $this->connectTo($this->activeShardId); + + if ($this->_eventManager->hasListeners(Events::postConnect)) { + $eventArgs = new ConnectionEventArgs($this); + $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs); + } + + return true; + } + + /** + * Connects to a specific connection. + * + * @param string $shardId + * + * @return \Doctrine\DBAL\Driver\Connection + */ + protected function connectTo($shardId) + { + $params = $this->getParams(); + + $driverOptions = $params['driverOptions'] ?? []; + + $connectionParams = $this->connectionParameters[$shardId]; + + $user = $connectionParams['user'] ?? null; + $password = $connectionParams['password'] ?? null; + + return $this->_driver->connect($connectionParams, $user, $password, $driverOptions); + } + + /** + * @param string|null $shardId + * + * @return bool + */ + public function isConnected($shardId = null) + { + if ($shardId === null) { + return $this->_conn !== null; + } + + return isset($this->activeConnections[$shardId]); + } + + /** + * @return void + */ + public function close() + { + $this->_conn = null; + $this->activeConnections = []; + $this->activeShardId = null; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardManager.php new file mode 100644 index 000000000..5edc56b87 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/PoolingShardManager.php @@ -0,0 +1,101 @@ +getParams(); + $this->conn = $conn; + $this->choser = $params['shardChoser']; + } + + /** + * {@inheritDoc} + */ + public function selectGlobal() + { + $this->conn->connect(0); + $this->currentDistributionValue = null; + } + + /** + * {@inheritDoc} + */ + public function selectShard($distributionValue) + { + $shardId = $this->choser->pickShard($distributionValue, $this->conn); + $this->conn->connect($shardId); + $this->currentDistributionValue = $distributionValue; + } + + /** + * {@inheritDoc} + */ + public function getCurrentDistributionValue() + { + return $this->currentDistributionValue; + } + + /** + * {@inheritDoc} + */ + public function getShards() + { + $params = $this->conn->getParams(); + $shards = []; + + foreach ($params['shards'] as $shard) { + $shards[] = ['id' => $shard['id']]; + } + + return $shards; + } + + /** + * {@inheritDoc} + * + * @throws RuntimeException + */ + public function queryAll($sql, array $params, array $types) + { + $shards = $this->getShards(); + if (! $shards) { + throw new RuntimeException('No shards found.'); + } + + $result = []; + $oldDistribution = $this->getCurrentDistributionValue(); + + foreach ($shards as $shard) { + $this->conn->connect($shard['id']); + foreach ($this->conn->fetchAll($sql, $params, $types) as $row) { + $result[] = $row; + } + } + + if ($oldDistribution === null) { + $this->selectGlobal(); + } else { + $this->selectShard($oldDistribution); + } + + return $result; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureFederationsSynchronizer.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureFederationsSynchronizer.php new file mode 100644 index 000000000..32d642365 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureFederationsSynchronizer.php @@ -0,0 +1,270 @@ +shardManager = $shardManager; + $this->synchronizer = $sync ?: new SingleDatabaseSynchronizer($conn); + } + + /** + * {@inheritdoc} + */ + public function getCreateSchema(Schema $createSchema) + { + $sql = []; + + [$global, $federation] = $this->partitionSchema($createSchema); + + $globalSql = $this->synchronizer->getCreateSchema($global); + if ($globalSql) { + $sql[] = "-- Create Root Federation\n" . + 'USE FEDERATION ROOT WITH RESET;'; + $sql = array_merge($sql, $globalSql); + } + + $federationSql = $this->synchronizer->getCreateSchema($federation); + + if ($federationSql) { + $defaultValue = $this->getFederationTypeDefaultValue(); + + $sql[] = $this->getCreateFederationStatement(); + $sql[] = 'USE FEDERATION ' . $this->shardManager->getFederationName() . ' (' . $this->shardManager->getDistributionKey() . ' = ' . $defaultValue . ') WITH RESET, FILTERING = OFF;'; + $sql = array_merge($sql, $federationSql); + } + + return $sql; + } + + /** + * {@inheritdoc} + */ + public function getUpdateSchema(Schema $toSchema, $noDrops = false) + { + return $this->work($toSchema, static function ($synchronizer, $schema) use ($noDrops) { + return $synchronizer->getUpdateSchema($schema, $noDrops); + }); + } + + /** + * {@inheritdoc} + */ + public function getDropSchema(Schema $dropSchema) + { + return $this->work($dropSchema, static function ($synchronizer, $schema) { + return $synchronizer->getDropSchema($schema); + }); + } + + /** + * {@inheritdoc} + */ + public function createSchema(Schema $createSchema) + { + $this->processSql($this->getCreateSchema($createSchema)); + } + + /** + * {@inheritdoc} + */ + public function updateSchema(Schema $toSchema, $noDrops = false) + { + $this->processSql($this->getUpdateSchema($toSchema, $noDrops)); + } + + /** + * {@inheritdoc} + */ + public function dropSchema(Schema $dropSchema) + { + $this->processSqlSafely($this->getDropSchema($dropSchema)); + } + + /** + * {@inheritdoc} + */ + public function getDropAllSchema() + { + $this->shardManager->selectGlobal(); + $globalSql = $this->synchronizer->getDropAllSchema(); + + if ($globalSql) { + $sql[] = "-- Work on Root Federation\nUSE FEDERATION ROOT WITH RESET;"; + $sql = array_merge($sql, $globalSql); + } + + $shards = $this->shardManager->getShards(); + foreach ($shards as $shard) { + $this->shardManager->selectShard($shard['rangeLow']); + + $federationSql = $this->synchronizer->getDropAllSchema(); + if (! $federationSql) { + continue; + } + + $sql[] = '-- Work on Federation ID ' . $shard['id'] . "\n" . + 'USE FEDERATION ' . $this->shardManager->getFederationName() . ' (' . $this->shardManager->getDistributionKey() . ' = ' . $shard['rangeLow'] . ') WITH RESET, FILTERING = OFF;'; + $sql = array_merge($sql, $federationSql); + } + + $sql[] = 'USE FEDERATION ROOT WITH RESET;'; + $sql[] = 'DROP FEDERATION ' . $this->shardManager->getFederationName(); + + return $sql; + } + + /** + * {@inheritdoc} + */ + public function dropAllSchema() + { + $this->processSqlSafely($this->getDropAllSchema()); + } + + /** + * @return Schema[] + */ + private function partitionSchema(Schema $schema) + { + return [ + $this->extractSchemaFederation($schema, false), + $this->extractSchemaFederation($schema, true), + ]; + } + + /** + * @param bool $isFederation + * + * @return Schema + * + * @throws RuntimeException + */ + private function extractSchemaFederation(Schema $schema, $isFederation) + { + $partitionedSchema = clone $schema; + + foreach ($partitionedSchema->getTables() as $table) { + if ($isFederation) { + $table->addOption(self::FEDERATION_DISTRIBUTION_NAME, $this->shardManager->getDistributionKey()); + } + + if ($table->hasOption(self::FEDERATION_TABLE_FEDERATED) !== $isFederation) { + $partitionedSchema->dropTable($table->getName()); + } else { + foreach ($table->getForeignKeys() as $fk) { + $foreignTable = $schema->getTable($fk->getForeignTableName()); + if ($foreignTable->hasOption(self::FEDERATION_TABLE_FEDERATED) !== $isFederation) { + throw new RuntimeException('Cannot have foreign key between global/federation.'); + } + } + } + } + + return $partitionedSchema; + } + + /** + * Work on the Global/Federation based on currently existing shards and + * perform the given operation on the underlying schema synchronizer given + * the different partitioned schema instances. + * + * @return string[] + */ + private function work(Schema $schema, Closure $operation) + { + [$global, $federation] = $this->partitionSchema($schema); + $sql = []; + + $this->shardManager->selectGlobal(); + $globalSql = $operation($this->synchronizer, $global); + + if ($globalSql) { + $sql[] = "-- Work on Root Federation\nUSE FEDERATION ROOT WITH RESET;"; + $sql = array_merge($sql, $globalSql); + } + + $shards = $this->shardManager->getShards(); + + foreach ($shards as $shard) { + $this->shardManager->selectShard($shard['rangeLow']); + + $federationSql = $operation($this->synchronizer, $federation); + if (! $federationSql) { + continue; + } + + $sql[] = '-- Work on Federation ID ' . $shard['id'] . "\n" . + 'USE FEDERATION ' . $this->shardManager->getFederationName() . ' (' . $this->shardManager->getDistributionKey() . ' = ' . $shard['rangeLow'] . ') WITH RESET, FILTERING = OFF;'; + $sql = array_merge($sql, $federationSql); + } + + return $sql; + } + + /** + * @return string + */ + private function getFederationTypeDefaultValue() + { + $federationType = Type::getType($this->shardManager->getDistributionType()); + + switch ($federationType->getName()) { + case Type::GUID: + $defaultValue = '00000000-0000-0000-0000-000000000000'; + break; + case Type::INTEGER: + case Type::SMALLINT: + case Type::BIGINT: + $defaultValue = '0'; + break; + default: + $defaultValue = ''; + break; + } + + return $defaultValue; + } + + /** + * @return string + */ + private function getCreateFederationStatement() + { + $federationType = Type::getType($this->shardManager->getDistributionType()); + $federationTypeSql = $federationType->getSQLDeclaration([], $this->conn->getDatabasePlatform()); + + return "--Create Federation\n" . + 'CREATE FEDERATION ' . $this->shardManager->getFederationName() . ' (' . $this->shardManager->getDistributionKey() . ' ' . $federationTypeSql . ' RANGE)'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php new file mode 100644 index 000000000..7c5dfe5c4 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/SQLAzureShardManager.php @@ -0,0 +1,214 @@ +conn = $conn; + $params = $conn->getParams(); + + if (! isset($params['sharding']['federationName'])) { + throw ShardingException::missingDefaultFederationName(); + } + + if (! isset($params['sharding']['distributionKey'])) { + throw ShardingException::missingDefaultDistributionKey(); + } + + if (! isset($params['sharding']['distributionType'])) { + throw ShardingException::missingDistributionType(); + } + + $this->federationName = $params['sharding']['federationName']; + $this->distributionKey = $params['sharding']['distributionKey']; + $this->distributionType = $params['sharding']['distributionType']; + $this->filteringEnabled = (bool) ($params['sharding']['filteringEnabled'] ?? false); + } + + /** + * Gets the name of the federation. + * + * @return string + */ + public function getFederationName() + { + return $this->federationName; + } + + /** + * Gets the distribution key. + * + * @return string + */ + public function getDistributionKey() + { + return $this->distributionKey; + } + + /** + * Gets the Doctrine Type name used for the distribution. + * + * @return string + */ + public function getDistributionType() + { + return $this->distributionType; + } + + /** + * Sets Enabled/Disable filtering on the fly. + * + * @param bool $flag + * + * @return void + */ + public function setFilteringEnabled($flag) + { + $this->filteringEnabled = (bool) $flag; + } + + /** + * {@inheritDoc} + */ + public function selectGlobal() + { + if ($this->conn->isTransactionActive()) { + throw ShardingException::activeTransaction(); + } + + $sql = 'USE FEDERATION ROOT WITH RESET'; + $this->conn->exec($sql); + $this->currentDistributionValue = null; + } + + /** + * {@inheritDoc} + */ + public function selectShard($distributionValue) + { + if ($this->conn->isTransactionActive()) { + throw ShardingException::activeTransaction(); + } + + if ($distributionValue === null || is_bool($distributionValue) || ! is_scalar($distributionValue)) { + throw ShardingException::noShardDistributionValue(); + } + + $platform = $this->conn->getDatabasePlatform(); + $sql = sprintf( + 'USE FEDERATION %s (%s = %s) WITH RESET, FILTERING = %s;', + $platform->quoteIdentifier($this->federationName), + $platform->quoteIdentifier($this->distributionKey), + $this->conn->quote($distributionValue), + ($this->filteringEnabled ? 'ON' : 'OFF') + ); + + $this->conn->exec($sql); + $this->currentDistributionValue = $distributionValue; + } + + /** + * {@inheritDoc} + */ + public function getCurrentDistributionValue() + { + return $this->currentDistributionValue; + } + + /** + * {@inheritDoc} + */ + public function getShards() + { + $sql = 'SELECT member_id as id, + distribution_name as distribution_key, + CAST(range_low AS CHAR) AS rangeLow, + CAST(range_high AS CHAR) AS rangeHigh + FROM sys.federation_member_distributions d + INNER JOIN sys.federations f ON f.federation_id = d.federation_id + WHERE f.name = ' . $this->conn->quote($this->federationName); + + return $this->conn->fetchAll($sql); + } + + /** + * {@inheritDoc} + */ + public function queryAll($sql, array $params = [], array $types = []) + { + $shards = $this->getShards(); + if (! $shards) { + throw new RuntimeException('No shards found for ' . $this->federationName); + } + + $result = []; + $oldDistribution = $this->getCurrentDistributionValue(); + + foreach ($shards as $shard) { + $this->selectShard($shard['rangeLow']); + foreach ($this->conn->fetchAll($sql, $params, $types) as $row) { + $result[] = $row; + } + } + + if ($oldDistribution === null) { + $this->selectGlobal(); + } else { + $this->selectShard($oldDistribution); + } + + return $result; + } + + /** + * Splits Federation at a given distribution value. + * + * @param mixed $splitDistributionValue + * + * @return void + */ + public function splitFederation($splitDistributionValue) + { + $type = Type::getType($this->distributionType); + + $sql = 'ALTER FEDERATION ' . $this->getFederationName() . ' ' . + 'SPLIT AT (' . $this->getDistributionKey() . ' = ' . + $this->conn->quote($splitDistributionValue, $type->getBindingType()) . ')'; + $this->conn->exec($sql); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/Schema/MultiTenantVisitor.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/Schema/MultiTenantVisitor.php new file mode 100644 index 000000000..a83b401c2 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/SQLAzure/Schema/MultiTenantVisitor.php @@ -0,0 +1,148 @@ +excludedTables = $excludedTables; + $this->tenantColumnName = $tenantColumnName; + $this->distributionName = $distributionName ?: $tenantColumnName; + } + + /** + * {@inheritdoc} + */ + public function acceptTable(Table $table) + { + if (in_array($table->getName(), $this->excludedTables)) { + return; + } + + $table->addColumn($this->tenantColumnName, $this->tenantColumnType, [ + 'default' => "federation_filtering_value('" . $this->distributionName . "')", + ]); + + $clusteredIndex = $this->getClusteredIndex($table); + + $indexColumns = $clusteredIndex->getColumns(); + $indexColumns[] = $this->tenantColumnName; + + if ($clusteredIndex->isPrimary()) { + $table->dropPrimaryKey(); + $table->setPrimaryKey($indexColumns); + } else { + $table->dropIndex($clusteredIndex->getName()); + $table->addIndex($indexColumns, $clusteredIndex->getName()); + $table->getIndex($clusteredIndex->getName())->addFlag('clustered'); + } + } + + /** + * @param Table $table + * + * @return Index + * + * @throws RuntimeException + */ + private function getClusteredIndex($table) + { + foreach ($table->getIndexes() as $index) { + if ($index->isPrimary() && ! $index->hasFlag('nonclustered')) { + return $index; + } + + if ($index->hasFlag('clustered')) { + return $index; + } + } + throw new RuntimeException('No clustered index found on table ' . $table->getName()); + } + + /** + * {@inheritdoc} + */ + public function acceptSchema(Schema $schema) + { + } + + /** + * {@inheritdoc} + */ + public function acceptColumn(Table $table, Column $column) + { + } + + /** + * {@inheritdoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + } + + /** + * {@inheritdoc} + */ + public function acceptIndex(Table $table, Index $index) + { + } + + /** + * {@inheritdoc} + */ + public function acceptSequence(Sequence $sequence) + { + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/ShardChoser/MultiTenantShardChoser.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/ShardChoser/MultiTenantShardChoser.php new file mode 100644 index 000000000..584e8155a --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Sharding/ShardChoser/MultiTenantShardChoser.php @@ -0,0 +1,20 @@ +Statement for the given SQL and Connection. + * + * @param string $sql The SQL of the statement. + * @param Connection $conn The connection on which the statement should be executed. + */ + public function __construct($sql, Connection $conn) + { + $this->sql = $sql; + $this->stmt = $conn->getWrappedConnection()->prepare($sql); + $this->conn = $conn; + $this->platform = $conn->getDatabasePlatform(); + } + + /** + * Binds a parameter value to the statement. + * + * The value can optionally be bound with a PDO binding type or a DBAL mapping type. + * If bound with a DBAL mapping type, the binding type is derived from the mapping + * type and the value undergoes the conversion routines of the mapping type before + * being bound. + * + * @param string|int $name The name or position of the parameter. + * @param mixed $value The value of the parameter. + * @param mixed $type Either a PDO binding type or a DBAL mapping type name or instance. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function bindValue($name, $value, $type = ParameterType::STRING) + { + $this->params[$name] = $value; + $this->types[$name] = $type; + if ($type !== null) { + if (is_string($type)) { + $type = Type::getType($type); + } + if ($type instanceof Type) { + $value = $type->convertToDatabaseValue($value, $this->platform); + $bindingType = $type->getBindingType(); + } else { + $bindingType = $type; + } + + return $this->stmt->bindValue($name, $value, $bindingType); + } + + return $this->stmt->bindValue($name, $value); + } + + /** + * Binds a parameter to a value by reference. + * + * Binding a parameter by reference does not support DBAL mapping types. + * + * @param string|int $name The name or position of the parameter. + * @param mixed $var The reference to the variable to bind. + * @param int $type The PDO binding type. + * @param int|null $length Must be specified when using an OUT bind + * so that PHP allocates enough memory to hold the returned value. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function bindParam($name, &$var, $type = ParameterType::STRING, $length = null) + { + $this->params[$name] = $var; + $this->types[$name] = $type; + + return $this->stmt->bindParam($name, $var, $type, $length); + } + + /** + * Executes the statement with the currently bound parameters. + * + * @param mixed[]|null $params + * + * @return bool TRUE on success, FALSE on failure. + * + * @throws DBALException + */ + public function execute($params = null) + { + if (is_array($params)) { + $this->params = $params; + } + + $logger = $this->conn->getConfiguration()->getSQLLogger(); + if ($logger) { + $logger->startQuery($this->sql, $this->params, $this->types); + } + + try { + $stmt = $this->stmt->execute($params); + } catch (Throwable $ex) { + if ($logger) { + $logger->stopQuery(); + } + throw DBALException::driverExceptionDuringQuery( + $this->conn->getDriver(), + $ex, + $this->sql, + $this->conn->resolveParams($this->params, $this->types) + ); + } + + if ($logger) { + $logger->stopQuery(); + } + $this->params = []; + $this->types = []; + + return $stmt; + } + + /** + * Closes the cursor, freeing the database resources used by this statement. + * + * @return bool TRUE on success, FALSE on failure. + */ + public function closeCursor() + { + return $this->stmt->closeCursor(); + } + + /** + * Returns the number of columns in the result set. + * + * @return int + */ + public function columnCount() + { + return $this->stmt->columnCount(); + } + + /** + * Fetches the SQLSTATE associated with the last operation on the statement. + * + * @return string|int|bool + */ + public function errorCode() + { + return $this->stmt->errorCode(); + } + + /** + * {@inheritDoc} + */ + public function errorInfo() + { + return $this->stmt->errorInfo(); + } + + /** + * {@inheritdoc} + */ + public function setFetchMode($fetchMode, $arg2 = null, $arg3 = null) + { + if ($arg2 === null) { + return $this->stmt->setFetchMode($fetchMode); + } elseif ($arg3 === null) { + return $this->stmt->setFetchMode($fetchMode, $arg2); + } + + return $this->stmt->setFetchMode($fetchMode, $arg2, $arg3); + } + + /** + * Required by interface IteratorAggregate. + * + * {@inheritdoc} + */ + public function getIterator() + { + return $this->stmt; + } + + /** + * {@inheritdoc} + */ + public function fetch($fetchMode = null, $cursorOrientation = PDO::FETCH_ORI_NEXT, $cursorOffset = 0) + { + return $this->stmt->fetch($fetchMode); + } + + /** + * {@inheritdoc} + */ + public function fetchAll($fetchMode = null, $fetchArgument = null, $ctorArgs = null) + { + if ($fetchArgument) { + return $this->stmt->fetchAll($fetchMode, $fetchArgument); + } + + return $this->stmt->fetchAll($fetchMode); + } + + /** + * {@inheritDoc} + */ + public function fetchColumn($columnIndex = 0) + { + return $this->stmt->fetchColumn($columnIndex); + } + + /** + * Returns the number of rows affected by the last execution of this statement. + * + * @return int The number of affected rows. + */ + public function rowCount() + { + return $this->stmt->rowCount(); + } + + /** + * Gets the wrapped driver statement. + * + * @return \Doctrine\DBAL\Driver\Statement + */ + public function getWrappedStatement() + { + return $this->stmt; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php new file mode 100644 index 000000000..0e8156637 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ImportCommand.php @@ -0,0 +1,129 @@ +setName('dbal:import') + ->setDescription('Import SQL file(s) directly to Database.') + ->setDefinition([new InputArgument( + 'file', + InputArgument::REQUIRED | InputArgument::IS_ARRAY, + 'File path(s) of SQL to be executed.' + ), + ]) + ->setHelp(<<getHelper('db')->getConnection(); + + $fileNames = $input->getArgument('file'); + + if ($fileNames === null) { + return null; + } + + foreach ((array) $fileNames as $fileName) { + $filePath = realpath($fileName); + + // Phar compatibility. + if ($filePath === false) { + $filePath = $fileName; + } + + if (! file_exists($filePath)) { + throw new InvalidArgumentException( + sprintf("SQL file '%s' does not exist.", $filePath) + ); + } elseif (! is_readable($filePath)) { + throw new InvalidArgumentException( + sprintf("SQL file '%s' does not have read permissions.", $filePath) + ); + } + + $output->write(sprintf("Processing file '%s'... ", $filePath)); + $sql = file_get_contents($filePath); + + if ($conn instanceof PDOConnection) { + // PDO Drivers + try { + $lines = 0; + + $stmt = $conn->prepare($sql); + assert($stmt instanceof PDOStatement); + + $stmt->execute(); + + do { + // Required due to "MySQL has gone away!" issue + $stmt->fetch(); + $stmt->closeCursor(); + + $lines++; + } while ($stmt->nextRowset()); + + $output->write(sprintf('%d statements executed!', $lines) . PHP_EOL); + } catch (PDOException $e) { + $output->write('error!' . PHP_EOL); + + throw new RuntimeException($e->getMessage(), $e->getCode(), $e); + } + } else { + // Non-PDO Drivers (ie. OCI8 driver) + $stmt = $conn->prepare($sql); + $rs = $stmt->execute(); + + if (! $rs) { + $error = $stmt->errorInfo(); + + $output->write('error!' . PHP_EOL); + + throw new RuntimeException($error[2], $error[0]); + } + + $output->writeln('OK!' . PHP_EOL); + + $stmt->closeCursor(); + } + } + + return null; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php new file mode 100644 index 000000000..2e0c48a81 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/ReservedWordsCommand.php @@ -0,0 +1,181 @@ + MySQLKeywords::class, + 'mysql57' => MySQL57Keywords::class, + 'mysql80' => MySQL80Keywords::class, + 'sqlserver' => SQLServerKeywords::class, + 'sqlserver2005' => SQLServer2005Keywords::class, + 'sqlserver2008' => SQLServer2008Keywords::class, + 'sqlserver2012' => SQLServer2012Keywords::class, + 'sqlite' => SQLiteKeywords::class, + 'pgsql' => PostgreSQLKeywords::class, + 'pgsql91' => PostgreSQL91Keywords::class, + 'pgsql92' => PostgreSQL92Keywords::class, + 'oracle' => OracleKeywords::class, + 'db2' => DB2Keywords::class, + 'sqlanywhere' => SQLAnywhereKeywords::class, + 'sqlanywhere11' => SQLAnywhere11Keywords::class, + 'sqlanywhere12' => SQLAnywhere12Keywords::class, + 'sqlanywhere16' => SQLAnywhere16Keywords::class, + ]; + + /** + * If you want to add or replace a keywords list use this command. + * + * @param string $name + * @param string $class + * + * @return void + */ + public function setKeywordListClass($name, $class) + { + $this->keywordListClasses[$name] = $class; + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('dbal:reserved-words') + ->setDescription('Checks if the current database contains identifiers that are reserved.') + ->setDefinition([new InputOption( + 'list', + 'l', + InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, + 'Keyword-List name.' + ), + ]) + ->setHelp(<<%command.full_name% + +If you want to check against specific dialects you can +pass them to the command: + + %command.full_name% -l mysql -l pgsql + +The following keyword lists are currently shipped with Doctrine: + + * mysql + * mysql57 + * mysql80 + * pgsql + * pgsql92 + * sqlite + * oracle + * sqlserver + * sqlserver2005 + * sqlserver2008 + * sqlserver2012 + * sqlanywhere + * sqlanywhere11 + * sqlanywhere12 + * sqlanywhere16 + * db2 (Not checked by default) +EOT + ); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + /** @var Connection $conn */ + $conn = $this->getHelper('db')->getConnection(); + + $keywordLists = (array) $input->getOption('list'); + if (! $keywordLists) { + $keywordLists = [ + 'mysql', + 'mysql57', + 'mysql80', + 'pgsql', + 'pgsql92', + 'sqlite', + 'oracle', + 'sqlserver', + 'sqlserver2005', + 'sqlserver2008', + 'sqlserver2012', + 'sqlanywhere', + 'sqlanywhere11', + 'sqlanywhere12', + 'sqlanywhere16', + ]; + } + + $keywords = []; + foreach ($keywordLists as $keywordList) { + if (! isset($this->keywordListClasses[$keywordList])) { + throw new InvalidArgumentException( + "There exists no keyword list with name '" . $keywordList . "'. " . + 'Known lists: ' . implode(', ', array_keys($this->keywordListClasses)) + ); + } + $class = $this->keywordListClasses[$keywordList]; + $keywords[] = new $class(); + } + + $output->write('Checking keyword violations for ' . implode(', ', $keywordLists) . '...', true); + + $schema = $conn->getSchemaManager()->createSchema(); + $visitor = new ReservedKeywordsValidator($keywords); + $schema->visit($visitor); + + $violations = $visitor->getViolations(); + if (count($violations) !== 0) { + $output->write('There are ' . count($violations) . ' reserved keyword violations in your database schema:', true); + foreach ($violations as $violation) { + $output->write(' - ' . $violation, true); + } + + return 1; + } + + $output->write('No reserved keywords violations have been found!', true); + + return 0; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php new file mode 100644 index 000000000..8361219ad --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/Command/RunSqlCommand.php @@ -0,0 +1,68 @@ +setName('dbal:run-sql') + ->setDescription('Executes arbitrary SQL directly from the command line.') + ->setDefinition([ + new InputArgument('sql', InputArgument::REQUIRED, 'The SQL statement to execute.'), + new InputOption('depth', null, InputOption::VALUE_REQUIRED, 'Dumping depth of result set.', 7), + new InputOption('force-fetch', null, InputOption::VALUE_NONE, 'Forces fetching the result.'), + ]) + ->setHelp(<<getHelper('db')->getConnection(); + + $sql = $input->getArgument('sql'); + + if ($sql === null) { + throw new RuntimeException("Argument 'SQL' is required in order to execute this command correctly."); + } + + $depth = $input->getOption('depth'); + + if (! is_numeric($depth)) { + throw new LogicException("Option 'depth' must contains an integer value"); + } + + if (stripos($sql, 'select') === 0 || $input->getOption('force-fetch')) { + $resultSet = $conn->fetchAll($sql); + } else { + $resultSet = $conn->executeUpdate($sql); + } + + $output->write(Dumper::dump($resultSet, (int) $depth)); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php new file mode 100644 index 000000000..520a9af80 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Console/ConsoleRunner.php @@ -0,0 +1,86 @@ + new ConnectionHelper($connection), + ]); + } + + /** + * Runs console with the given helperset. + * + * @param Command[] $commands + * + * @return void + */ + public static function run(HelperSet $helperSet, $commands = []) + { + $cli = new Application('Doctrine Command Line Interface', Version::VERSION); + + $cli->setCatchExceptions(true); + $cli->setHelperSet($helperSet); + + self::addCommands($cli); + + $cli->addCommands($commands); + $cli->run(); + } + + /** + * @return void + */ + public static function addCommands(Application $cli) + { + $cli->addCommands([ + new RunSqlCommand(), + new ImportCommand(), + new ReservedWordsCommand(), + ]); + } + + /** + * Prints the instructions to create a configuration file + */ + public static function printCliConfigTemplate() + { + echo <<<'HELP' +You are missing a "cli-config.php" or "config/cli-config.php" file in your +project, which is required to get the Doctrine-DBAL Console working. You can use the +following sample as a template: + +_connection = $connection; + } + + /** + * Retrieves the Doctrine database Connection. + * + * @return Connection + */ + public function getConnection() + { + return $this->_connection; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'connection'; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Dumper.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Dumper.php new file mode 100644 index 000000000..d5086adee --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Tools/Dumper.php @@ -0,0 +1,176 @@ +toArray(); + } + + if ($maxDepth === 0) { + return is_object($var) ? get_class($var) + : (is_array($var) ? 'Array(' . count($var) . ')' : $var); + } + + if (is_array($var)) { + $return = []; + + foreach ($var as $k => $v) { + $return[$k] = self::export($v, $maxDepth - 1); + } + + return $return; + } + + if (! $isObj) { + return $var; + } + + $return = new stdClass(); + if ($var instanceof DateTimeInterface) { + $return->__CLASS__ = get_class($var); + $return->date = $var->format('c'); + $return->timezone = $var->getTimezone()->getName(); + + return $return; + } + + $return->__CLASS__ = self::getClass($var); + + if ($var instanceof Proxy) { + $return->__IS_PROXY__ = true; + $return->__PROXY_INITIALIZED__ = $var->__isInitialized(); + } + + if ($var instanceof ArrayObject || $var instanceof ArrayIterator) { + $return->__STORAGE__ = self::export($var->getArrayCopy(), $maxDepth - 1); + } + + return self::fillReturnWithClassAttributes($var, $return, $maxDepth); + } + + /** + * Fill the $return variable with class attributes + * Based on obj2array function from {@see https://secure.php.net/manual/en/function.get-object-vars.php#47075} + * + * @param object $var + * + * @return mixed + */ + private static function fillReturnWithClassAttributes($var, stdClass $return, int $maxDepth) + { + $clone = (array) $var; + + foreach (array_keys($clone) as $key) { + $aux = explode("\0", $key); + $name = end($aux); + if ($aux[0] === '') { + $name .= ':' . ($aux[1] === '*' ? 'protected' : $aux[1] . ':private'); + } + $return->$name = self::export($clone[$key], $maxDepth - 1); + } + + return $return; + } + + /** + * @param object $object + */ + private static function getClass($object) : string + { + $class = get_class($object); + + if (! class_exists(Proxy::class)) { + return $class; + } + + $pos = strrpos($class, '\\' . Proxy::MARKER . '\\'); + + if ($pos === false) { + return $class; + } + + return substr($class, $pos + Proxy::MARKER_LENGTH + 2); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/TransactionIsolationLevel.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/TransactionIsolationLevel.php new file mode 100644 index 000000000..4e35639fb --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/TransactionIsolationLevel.php @@ -0,0 +1,32 @@ +getClobTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + // @todo 3.0 - $value === null check to save real NULL in database + return serialize($value); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $value = is_resource($value) ? stream_get_contents($value) : $value; + + set_error_handler(function (int $code, string $message) : void { + throw ConversionException::conversionFailedUnserialization($this->getName(), $message); + }); + + try { + return unserialize($value); + } finally { + restore_error_handler(); + } + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::TARRAY; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php new file mode 100644 index 000000000..1d320d624 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php @@ -0,0 +1,44 @@ +getBigIntTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function getBindingType() + { + return ParameterType::STRING; + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value === null ? null : (string) $value; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php new file mode 100644 index 000000000..14362e840 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php @@ -0,0 +1,64 @@ +getBinaryTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + if (is_string($value)) { + $fp = fopen('php://temp', 'rb+'); + fwrite($fp, $value); + fseek($fp, 0); + $value = $fp; + } + + if (! is_resource($value)) { + throw ConversionException::conversionFailed($value, self::BINARY); + } + + return $value; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::BINARY; + } + + /** + * {@inheritdoc} + */ + public function getBindingType() + { + return ParameterType::BINARY; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php new file mode 100644 index 000000000..c309f0f06 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php @@ -0,0 +1,64 @@ +getBlobTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + if (is_string($value)) { + $fp = fopen('php://temp', 'rb+'); + fwrite($fp, $value); + fseek($fp, 0); + $value = $fp; + } + + if (! is_resource($value)) { + throw ConversionException::conversionFailed($value, self::BLOB); + } + + return $value; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::BLOB; + } + + /** + * {@inheritdoc} + */ + public function getBindingType() + { + return ParameterType::LARGE_OBJECT; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php new file mode 100644 index 000000000..976f00e1f --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php @@ -0,0 +1,52 @@ +getBooleanTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return $platform->convertBooleansToDatabaseValue($value); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $platform->convertFromBoolean($value); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::BOOLEAN; + } + + /** + * {@inheritdoc} + */ + public function getBindingType() + { + return ParameterType::BOOLEAN; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php new file mode 100644 index 000000000..b9f8a82e7 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ConversionException.php @@ -0,0 +1,109 @@ + 32 ? substr($value, 0, 20) . '...' : $value; + + return new self('Could not convert database value "' . $value . '" to Doctrine Type ' . $toType); + } + + /** + * Thrown when a Database to Doctrine Type Conversion fails and we can make a statement + * about the expected format. + * + * @param string $value + * @param string $toType + * @param string $expectedFormat + * + * @return \Doctrine\DBAL\Types\ConversionException + */ + public static function conversionFailedFormat($value, $toType, $expectedFormat, ?Throwable $previous = null) + { + $value = strlen($value) > 32 ? substr($value, 0, 20) . '...' : $value; + + return new self( + 'Could not convert database value "' . $value . '" to Doctrine Type ' . + $toType . '. Expected format: ' . $expectedFormat, + 0, + $previous + ); + } + + /** + * Thrown when the PHP value passed to the converter was not of the expected type. + * + * @param mixed $value + * @param string $toType + * @param string[] $possibleTypes + * + * @return \Doctrine\DBAL\Types\ConversionException + */ + public static function conversionFailedInvalidType($value, $toType, array $possibleTypes) + { + $actualType = is_object($value) ? get_class($value) : gettype($value); + + if (is_scalar($value)) { + return new self(sprintf( + "Could not convert PHP value '%s' of type '%s' to type '%s'. Expected one of the following types: %s", + $value, + $actualType, + $toType, + implode(', ', $possibleTypes) + )); + } + + return new self(sprintf( + "Could not convert PHP value of type '%s' to type '%s'. Expected one of the following types: %s", + $actualType, + $toType, + implode(', ', $possibleTypes) + )); + } + + public static function conversionFailedSerialization($value, $format, $error) + { + $actualType = is_object($value) ? get_class($value) : gettype($value); + + return new self(sprintf( + "Could not convert PHP type '%s' to '%s', as an '%s' error was triggered by the serialization", + $actualType, + $format, + $error + )); + } + + public static function conversionFailedUnserialization(string $format, string $error) : self + { + return new self(sprintf( + "Could not convert database value to '%s' as an error was triggered by the unserialization: '%s'", + $format, + $error + )); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateImmutableType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateImmutableType.php new file mode 100644 index 000000000..196fc88c7 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateImmutableType.php @@ -0,0 +1,70 @@ +format($platform->getDateFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class] + ); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = DateTimeImmutable::createFromFormat('!' . $platform->getDateFormatString(), $value); + + if (! $dateTime) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateFormatString() + ); + } + + return $dateTime; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateIntervalType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateIntervalType.php new file mode 100644 index 000000000..30e61c9ea --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateIntervalType.php @@ -0,0 +1,87 @@ +getVarcharTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + if ($value instanceof DateInterval) { + return $value->format(self::FORMAT); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateInterval']); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateInterval) { + return $value; + } + + $negative = false; + + if (isset($value[0]) && ($value[0] === '+' || $value[0] === '-')) { + $negative = $value[0] === '-'; + $value = substr($value, 1); + } + + try { + $interval = new DateInterval($value); + + if ($negative) { + $interval->invert = 1; + } + + return $interval; + } catch (Throwable $exception) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), self::FORMAT, $exception); + } + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeImmutableType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeImmutableType.php new file mode 100644 index 000000000..fdda50faa --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeImmutableType.php @@ -0,0 +1,75 @@ +format($platform->getDateTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class] + ); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = DateTimeImmutable::createFromFormat($platform->getDateTimeFormatString(), $value); + + if (! $dateTime) { + $dateTime = date_create_immutable($value); + } + + if (! $dateTime) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateTimeFormatString() + ); + } + + return $dateTime; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php new file mode 100644 index 000000000..962d9d38d --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php @@ -0,0 +1,68 @@ +getDateTimeTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return $value; + } + + if ($value instanceof DateTimeInterface) { + return $value->format($platform->getDateTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTime']); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeInterface) { + return $value; + } + + $val = DateTime::createFromFormat($platform->getDateTimeFormatString(), $value); + + if (! $val) { + $val = date_create($value); + } + + if (! $val) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeFormatString()); + } + + return $val; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzImmutableType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzImmutableType.php new file mode 100644 index 000000000..253c02e00 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzImmutableType.php @@ -0,0 +1,70 @@ +format($platform->getDateTimeTzFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class] + ); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = DateTimeImmutable::createFromFormat($platform->getDateTimeTzFormatString(), $value); + + if (! $dateTime) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateTimeTzFormatString() + ); + } + + return $dateTime; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php new file mode 100644 index 000000000..0b78720ec --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php @@ -0,0 +1,75 @@ +getDateTimeTzTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return $value; + } + + if ($value instanceof DateTimeInterface) { + return $value->format($platform->getDateTimeTzFormatString()); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTime']); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeInterface) { + return $value; + } + + $val = DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value); + if (! $val) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateTimeTzFormatString()); + } + + return $val; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php new file mode 100644 index 000000000..b5ad5356f --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php @@ -0,0 +1,62 @@ +getDateTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return $value; + } + + if ($value instanceof DateTimeInterface) { + return $value->format($platform->getDateFormatString()); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTime']); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeInterface) { + return $value; + } + + $val = DateTime::createFromFormat('!' . $platform->getDateFormatString(), $value); + if (! $val) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getDateFormatString()); + } + + return $val; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php new file mode 100644 index 000000000..318cb2476 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php @@ -0,0 +1,35 @@ +getDecimalTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php new file mode 100644 index 000000000..3ad9aa737 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php @@ -0,0 +1,32 @@ +getFloatDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value === null ? null : (float) $value; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php new file mode 100644 index 000000000..a9ab21537 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php @@ -0,0 +1,35 @@ +getGuidTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::GUID; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return ! $platform->hasNativeGuidType(); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php new file mode 100644 index 000000000..f04f3c7e0 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php @@ -0,0 +1,44 @@ +getIntegerTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value === null ? null : (int) $value; + } + + /** + * {@inheritdoc} + */ + public function getBindingType() + { + return ParameterType::INTEGER; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php new file mode 100644 index 000000000..beae80387 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php @@ -0,0 +1,46 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $encoded = json_encode($value); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw ConversionException::conversionFailedSerialization($value, 'json', json_last_error_msg()); + } + + return $encoded; + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value === '') { + return null; + } + + if (is_resource($value)) { + $value = stream_get_contents($value); + } + + $val = json_decode($value, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw ConversionException::conversionFailed($value, $this->getName()); + } + + return $val; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::JSON; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return ! $platform->hasNativeJsonType(); + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php new file mode 100644 index 000000000..081ec483b --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php @@ -0,0 +1,71 @@ +getClobTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return serialize($value); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $value = is_resource($value) ? stream_get_contents($value) : $value; + + set_error_handler(function (int $code, string $message) : void { + throw ConversionException::conversionFailedUnserialization($this->getName(), $message); + }); + + try { + return unserialize($value); + } finally { + restore_error_handler(); + } + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::OBJECT; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/PhpDateTimeMappingType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/PhpDateTimeMappingType.php new file mode 100644 index 000000000..456585053 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/PhpDateTimeMappingType.php @@ -0,0 +1,12 @@ +getClobTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if (! $value) { + return null; + } + + return implode(',', $value); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return []; + } + + $value = is_resource($value) ? stream_get_contents($value) : $value; + + return explode(',', $value); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::SIMPLE_ARRAY; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php new file mode 100644 index 000000000..bca8a533f --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php @@ -0,0 +1,44 @@ +getSmallIntTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value === null ? null : (int) $value; + } + + /** + * {@inheritdoc} + */ + public function getBindingType() + { + return ParameterType::INTEGER; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php new file mode 100644 index 000000000..879359a13 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php @@ -0,0 +1,35 @@ +getVarcharTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function getDefaultLength(AbstractPlatform $platform) + { + return $platform->getVarcharDefaultLength(); + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::STRING; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php new file mode 100644 index 000000000..635d4f7de --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php @@ -0,0 +1,37 @@ +getClobTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return is_resource($value) ? stream_get_contents($value) : $value; + } + + /** + * {@inheritdoc} + */ + public function getName() + { + return Type::TEXT; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php new file mode 100644 index 000000000..8cb870fb3 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeImmutableType.php @@ -0,0 +1,70 @@ +format($platform->getTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class] + ); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = DateTimeImmutable::createFromFormat('!' . $platform->getTimeFormatString(), $value); + + if (! $dateTime) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getTimeFormatString() + ); + } + + return $dateTime; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php new file mode 100644 index 000000000..c9895294e --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php @@ -0,0 +1,62 @@ +getTimeTypeDeclarationSQL($fieldDeclaration); + } + + /** + * {@inheritdoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return $value; + } + + if ($value instanceof DateTimeInterface) { + return $value->format($platform->getTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', 'DateTime']); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeInterface) { + return $value; + } + + $val = DateTime::createFromFormat('!' . $platform->getTimeFormatString(), $value); + if (! $val) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getTimeFormatString()); + } + + return $val; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php new file mode 100644 index 000000000..ec1ab6813 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php @@ -0,0 +1,325 @@ + ArrayType::class, + self::SIMPLE_ARRAY => SimpleArrayType::class, + self::JSON_ARRAY => JsonArrayType::class, + self::JSON => JsonType::class, + self::OBJECT => ObjectType::class, + self::BOOLEAN => BooleanType::class, + self::INTEGER => IntegerType::class, + self::SMALLINT => SmallIntType::class, + self::BIGINT => BigIntType::class, + self::STRING => StringType::class, + self::TEXT => TextType::class, + self::DATETIME => DateTimeType::class, + self::DATETIME_IMMUTABLE => DateTimeImmutableType::class, + self::DATETIMETZ => DateTimeTzType::class, + self::DATETIMETZ_IMMUTABLE => DateTimeTzImmutableType::class, + self::DATE => DateType::class, + self::DATE_IMMUTABLE => DateImmutableType::class, + self::TIME => TimeType::class, + self::TIME_IMMUTABLE => TimeImmutableType::class, + self::DECIMAL => DecimalType::class, + self::FLOAT => FloatType::class, + self::BINARY => BinaryType::class, + self::BLOB => BlobType::class, + self::GUID => GuidType::class, + self::DATEINTERVAL => DateIntervalType::class, + ]; + + /** + * Prevents instantiation and forces use of the factory method. + */ + final private function __construct() + { + } + + /** + * Converts a value from its PHP representation to its database representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * + * @return mixed The database representation of the value. + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return $value; + } + + /** + * Converts a value from its database representation to its PHP representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * + * @return mixed The PHP representation of the value. + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value; + } + + /** + * Gets the default length of this type. + * + * @deprecated Rely on information provided by the platform instead. + * + * @return int|null + */ + public function getDefaultLength(AbstractPlatform $platform) + { + return null; + } + + /** + * Gets the SQL declaration snippet for a field of this type. + * + * @param mixed[] $fieldDeclaration The field declaration. + * @param AbstractPlatform $platform The currently used database platform. + * + * @return string + */ + abstract public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform); + + /** + * Gets the name of this type. + * + * @return string + * + * @todo Needed? + */ + abstract public function getName(); + + /** + * Factory method to create type instances. + * Type instances are implemented as flyweights. + * + * @param string $name The name of the type (as returned by getName()). + * + * @return \Doctrine\DBAL\Types\Type + * + * @throws DBALException + */ + public static function getType($name) + { + if (! isset(self::$_typeObjects[$name])) { + if (! isset(self::$_typesMap[$name])) { + throw DBALException::unknownColumnType($name); + } + self::$_typeObjects[$name] = new self::$_typesMap[$name](); + } + + return self::$_typeObjects[$name]; + } + + /** + * Adds a custom type to the type map. + * + * @param string $name The name of the type. This should correspond to what getName() returns. + * @param string $className The class name of the custom type. + * + * @return void + * + * @throws DBALException + */ + public static function addType($name, $className) + { + if (isset(self::$_typesMap[$name])) { + throw DBALException::typeExists($name); + } + + self::$_typesMap[$name] = $className; + } + + /** + * Checks if exists support for a type. + * + * @param string $name The name of the type. + * + * @return bool TRUE if type is supported; FALSE otherwise. + */ + public static function hasType($name) + { + return isset(self::$_typesMap[$name]); + } + + /** + * Overrides an already defined type to use a different implementation. + * + * @param string $name + * @param string $className + * + * @return void + * + * @throws DBALException + */ + public static function overrideType($name, $className) + { + if (! isset(self::$_typesMap[$name])) { + throw DBALException::typeNotFound($name); + } + + if (isset(self::$_typeObjects[$name])) { + unset(self::$_typeObjects[$name]); + } + + self::$_typesMap[$name] = $className; + } + + /** + * Gets the (preferred) binding type for values of this type that + * can be used when binding parameters to prepared statements. + * + * This method should return one of the {@link \Doctrine\DBAL\ParameterType} constants. + * + * @return int + */ + public function getBindingType() + { + return ParameterType::STRING; + } + + /** + * Gets the types array map which holds all registered types and the corresponding + * type class + * + * @return string[] + */ + public static function getTypesMap() + { + return self::$_typesMap; + } + + /** + * @deprecated Relying on string representation is discouraged and will be removed in DBAL 3.0. + * + * @return string + */ + public function __toString() + { + $e = explode('\\', static::class); + + return str_replace('Type', '', end($e)); + } + + /** + * Does working with this column require SQL conversion functions? + * + * This is a metadata function that is required for example in the ORM. + * Usage of {@link convertToDatabaseValueSQL} and + * {@link convertToPHPValueSQL} works for any type and mostly + * does nothing. This method can additionally be used for optimization purposes. + * + * @return bool + */ + public function canRequireSQLConversion() + { + return false; + } + + /** + * Modifies the SQL expression (identifier, parameter) to convert to a database value. + * + * @param string $sqlExpr + * + * @return string + */ + public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) + { + return $sqlExpr; + } + + /** + * Modifies the SQL expression (identifier, parameter) to convert to a PHP value. + * + * @param string $sqlExpr + * @param AbstractPlatform $platform + * + * @return string + */ + public function convertToPHPValueSQL($sqlExpr, $platform) + { + return $sqlExpr; + } + + /** + * Gets an array of database types that map to this Doctrine type. + * + * @return string[] + */ + public function getMappedDatabaseTypes(AbstractPlatform $platform) + { + return []; + } + + /** + * If this Doctrine Type maps to an already mapped database type, + * reverse schema engineering can't tell them apart. You need to mark + * one of those types as commented, which will have Doctrine use an SQL + * comment to typehint the actual Doctrine Type. + * + * @return bool + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return false; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeImmutableType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeImmutableType.php new file mode 100644 index 000000000..6636f53a5 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeImmutableType.php @@ -0,0 +1,67 @@ +format($platform->getDateTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class] + ); + } + + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = date_create_immutable($value); + + if (! $dateTime) { + throw ConversionException::conversionFailed($value, $this->getName()); + } + + return $dateTime; + } + + /** + * {@inheritdoc} + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + return true; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php new file mode 100644 index 000000000..1d9dbd3a6 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/VarDateTimeType.php @@ -0,0 +1,34 @@ + 0 it is necessary to use this type. + */ +class VarDateTimeType extends DateTimeType +{ + /** + * {@inheritdoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTime) { + return $value; + } + + $val = date_create($value); + if (! $val) { + throw ConversionException::conversionFailed($value, $this->getName()); + } + + return $val; + } +} diff --git a/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Version.php b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Version.php new file mode 100644 index 000000000..c6e44a045 --- /dev/null +++ b/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Version.php @@ -0,0 +1,33 @@ += MAJOR).new.exists' # New issues of major or higher severity + - 'project.metric_change("scrutinizer.test_coverage", < 0)' # Code Coverage decreased from previous inspection diff --git a/app/vendor/doctrine/event-manager/LICENSE b/app/vendor/doctrine/event-manager/LICENSE new file mode 100644 index 000000000..8c38cc1bc --- /dev/null +++ b/app/vendor/doctrine/event-manager/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006-2015 Doctrine Project + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/vendor/doctrine/event-manager/README.md b/app/vendor/doctrine/event-manager/README.md new file mode 100644 index 000000000..3aee6b6f0 --- /dev/null +++ b/app/vendor/doctrine/event-manager/README.md @@ -0,0 +1,13 @@ +# Doctrine Event Manager + +[![Build Status](https://travis-ci.org/doctrine/event-manager.svg)](https://travis-ci.org/doctrine/event-manager) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/event-manager/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/event-manager/?branch=master) +[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/event-manager/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/event-manager/?branch=master) + +The Doctrine Event Manager is a library that provides a simple event system. + +## More resources: + +* [Website](https://www.doctrine-project.org/) +* [Documentation](https://www.doctrine-project.org/projects/doctrine-event-manager/en/latest/) +* [Downloads](https://github.com/doctrine/event-manager/releases) diff --git a/app/vendor/doctrine/event-manager/composer.json b/app/vendor/doctrine/event-manager/composer.json new file mode 100644 index 000000000..b86855453 --- /dev/null +++ b/app/vendor/doctrine/event-manager/composer.json @@ -0,0 +1,41 @@ +{ + "name": "doctrine/event-manager", + "type": "library", + "description": "Doctrine Event Manager component", + "keywords": ["eventmanager", "eventdispatcher", "event"], + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "license": "MIT", + "authors": [ + {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, + {"name": "Roman Borschel", "email": "roman@code-factory.org"}, + {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, + {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, + {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}, + {"name": "Marco Pivetta", "email": "ocramius@gmail.com"} + ], + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0", + "doctrine/coding-standard": "^4.0" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "autoload-dev": { + "psr-4": { + "Doctrine\\Tests\\": "tests/Doctrine/Tests" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/app/vendor/doctrine/event-manager/docs/en/index.rst b/app/vendor/doctrine/event-manager/docs/en/index.rst new file mode 100644 index 000000000..4872d3347 --- /dev/null +++ b/app/vendor/doctrine/event-manager/docs/en/index.rst @@ -0,0 +1,22 @@ +Event Manager Documentation +=========================== + +The Doctrine Event Manager documentation is a reference guide to everything you need +to know about the project. + +Getting Help +------------ + +If this documentation is not helping to answer questions you have about the +Doctrine DBAL, don't panic. You can get help from different sources: + +- Gitter chat room `#doctrine/event-manager `_ +- On `Stack Overflow `_ +- The `Doctrine Mailing List `_ +- Report a bug on `GitHub `_. + +Getting Started +--------------- + +The best way to get started is with the :doc:`Introduction ` section +in the documentation. Use the sidebar to browse other documentation for the Doctrine Event Manager. diff --git a/app/vendor/doctrine/event-manager/docs/en/reference/index.rst b/app/vendor/doctrine/event-manager/docs/en/reference/index.rst new file mode 100644 index 000000000..2b092859c --- /dev/null +++ b/app/vendor/doctrine/event-manager/docs/en/reference/index.rst @@ -0,0 +1,133 @@ +Introduction +============ + +The Doctrine Event Manager is a simple event system used by the various Doctrine projects. It was originally built +for the DBAL and ORM but over time other projects adopted it and now it is available as a standalone library. + +Installation +============ + +The library can easily be installed with composer. + +.. code-block:: sh + + $ composer require doctrine/event-manager + +Setup +===== + +The event system is controlled by the ``Doctrine\Common\EventManager`` class. + +.. code-block:: php + + use Doctrine\Common\EventManager; + + $eventManager = new EventManager(); + +Listeners +========= + +Now you are ready to listen for events. Here is an example of a custom event listener named ``TestEvent``. + +.. code-block:: php + + use Doctrine\Common\EventArgs; + use Doctrine\Common\EventManager; + + final class TestEvent + { + public const preFoo = 'preFoo'; + public const postFoo = 'postFoo'; + + /** @var EventManager */ + private $eventManager; + + /** @var bool */ + public $preFooInvoked = false; + + /** @var bool */ + public $postFooInvoked = false; + + public function __construct(EventManager $eventManager) + { + $eventManager->addEventListener([self::preFoo, self::postFoo], $this); + } + + public function preFoo(EventArgs $eventArgs) : void + { + $this->preFooInvoked = true; + } + + public function postFoo(EventArgs $eventArgs) : void + { + $this->postFooInvoked = true; + } + } + + // Create a new instance + $testEvent = new TestEvent($eventManager); + +Dispatching Events +================== + +Now you can dispatch events with the ``dispatchEvent()`` method. + +.. code-block:: php + + $eventManager->dispatchEvent(TestEvent::preFoo); + $eventManager->dispatchEvent(TestEvent::postFoo); + +Removing Event Listeners +======================== + +You can easily remove a listener with the ``removeEventListener()`` method. + +.. code-block:: php + + $eventManager->removeEventListener([TestEvent::preFoo, TestEvent::postFoo], $testEvent); + +Event Subscribers +================= + +The Doctrine event system also has a simple concept of event subscribers. We can define a simple ``TestEventSubscriber`` class which implements the ``Doctrine\Common\EventSubscriber`` interface with a ``getSubscribedEvents()`` method which returns an array of events it should be subscribed to. + +.. code-block:: php + + use Doctrine\Common\EventSubscriber; + + final class TestEventSubscriber implements EventSubscriber + { + /** @var bool */ + public $preFooInvoked = false; + + public function preFoo() : void + { + $this->preFooInvoked = true; + } + + public function getSubscribedEvents() : array + { + return [TestEvent::preFoo]; + } + } + + $eventSubscriber = new TestEventSubscriber(); + $eventManager->addEventSubscriber($eventSubscriber); + +.. note:: + + The array returned by the ``getSubscribedEvents()`` method is a simple array with the values being the event names. The subscriber must have a method that is named exactly like the event. + +Now when you dispatch an event, any event subscribers will be notified of that event. + +.. code-block:: php + + $eventManager->dispatchEvent(TestEvent::preFoo); + +Now you can check the ``preFooInvoked`` property to see if the event subscriber was notified of the event: + +.. code-block:: php + + if ($eventSubscriber->preFooInvoked) { + // the preFoo method was invoked + } diff --git a/app/vendor/doctrine/event-manager/docs/en/sidebar.rst b/app/vendor/doctrine/event-manager/docs/en/sidebar.rst new file mode 100644 index 000000000..0672d8d3e --- /dev/null +++ b/app/vendor/doctrine/event-manager/docs/en/sidebar.rst @@ -0,0 +1,4 @@ +.. toctree:: + :depth: 3 + + reference/index diff --git a/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php b/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php new file mode 100644 index 000000000..12e6256db --- /dev/null +++ b/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventArgs.php @@ -0,0 +1,46 @@ + => + * + * @var object[][] + */ + private $_listeners = []; + + /** + * Dispatches an event to all registered listeners. + * + * @param string $eventName The name of the event to dispatch. The name of the event is + * the name of the method that is invoked on listeners. + * @param EventArgs|null $eventArgs The event arguments to pass to the event handlers/listeners. + * If not supplied, the single empty EventArgs instance is used. + * + * @return void + */ + public function dispatchEvent($eventName, ?EventArgs $eventArgs = null) + { + if (! isset($this->_listeners[$eventName])) { + return; + } + + $eventArgs = $eventArgs ?? EventArgs::getEmptyInstance(); + + foreach ($this->_listeners[$eventName] as $listener) { + $listener->$eventName($eventArgs); + } + } + + /** + * Gets the listeners of a specific event or all listeners. + * + * @param string|null $event The name of the event. + * + * @return object[]|object[][] The event listeners for the specified event, or all event listeners. + */ + public function getListeners($event = null) + { + return $event ? $this->_listeners[$event] : $this->_listeners; + } + + /** + * Checks whether an event has any registered listeners. + * + * @param string $event + * + * @return bool TRUE if the specified event has any listeners, FALSE otherwise. + */ + public function hasListeners($event) + { + return ! empty($this->_listeners[$event]); + } + + /** + * Adds an event listener that listens on the specified events. + * + * @param string|string[] $events The event(s) to listen on. + * @param object $listener The listener object. + * + * @return void + */ + public function addEventListener($events, $listener) + { + // Picks the hash code related to that listener + $hash = spl_object_hash($listener); + + foreach ((array) $events as $event) { + // Overrides listener if a previous one was associated already + // Prevents duplicate listeners on same event (same instance only) + $this->_listeners[$event][$hash] = $listener; + } + } + + /** + * Removes an event listener from the specified events. + * + * @param string|string[] $events + * @param object $listener + * + * @return void + */ + public function removeEventListener($events, $listener) + { + // Picks the hash code related to that listener + $hash = spl_object_hash($listener); + + foreach ((array) $events as $event) { + unset($this->_listeners[$event][$hash]); + } + } + + /** + * Adds an EventSubscriber. The subscriber is asked for all the events it is + * interested in and added as a listener for these events. + * + * @param EventSubscriber $subscriber The subscriber. + * + * @return void + */ + public function addEventSubscriber(EventSubscriber $subscriber) + { + $this->addEventListener($subscriber->getSubscribedEvents(), $subscriber); + } + + /** + * Removes an EventSubscriber. The subscriber is asked for all the events it is + * interested in and removed as a listener for these events. + * + * @param EventSubscriber $subscriber The subscriber. + * + * @return void + */ + public function removeEventSubscriber(EventSubscriber $subscriber) + { + $this->removeEventListener($subscriber->getSubscribedEvents(), $subscriber); + } +} diff --git a/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventSubscriber.php b/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventSubscriber.php new file mode 100644 index 000000000..7d5e2ea3f --- /dev/null +++ b/app/vendor/doctrine/event-manager/lib/Doctrine/Common/EventSubscriber.php @@ -0,0 +1,21 @@ +=5.3.2" + "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "3.7.*", - "jakub-onderka/php-parallel-lint": "0.*", + "phpunit/phpunit": "~4.3", + "jakub-onderka/php-parallel-lint": "1.0", "jakub-onderka/php-var-dump-check": "0.*", "squizlabs/php_codesniffer": "1.*", "jakub-onderka/php-code-style": "1.0" } -} \ No newline at end of file +} diff --git a/app/vendor/jakub-onderka/php-console-color/phpunit.xml b/app/vendor/jakub-onderka/php-console-color/phpunit.xml index 74011d9df..f1105cc4e 100644 --- a/app/vendor/jakub-onderka/php-console-color/phpunit.xml +++ b/app/vendor/jakub-onderka/php-console-color/phpunit.xml @@ -1,8 +1,9 @@ - + - tests/* + tests @@ -12,4 +13,4 @@ vendor - \ No newline at end of file + diff --git a/app/vendor/jakub-onderka/php-console-color/src/JakubOnderka/PhpConsoleColor/ConsoleColor.php b/app/vendor/jakub-onderka/php-console-color/src/ConsoleColor.php similarity index 90% rename from app/vendor/jakub-onderka/php-console-color/src/JakubOnderka/PhpConsoleColor/ConsoleColor.php rename to app/vendor/jakub-onderka/php-console-color/src/ConsoleColor.php index c367a7655..90fd12528 100644 --- a/app/vendor/jakub-onderka/php-console-color/src/JakubOnderka/PhpConsoleColor/ConsoleColor.php +++ b/app/vendor/jakub-onderka/php-console-color/src/ConsoleColor.php @@ -201,10 +201,15 @@ public function removeTheme($name) public function isSupported() { if (DIRECTORY_SEPARATOR === '\\') { - return getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON'; + if (function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT)) { + return true; + } elseif (getenv('ANSICON') !== false || getenv('ConEmuANSI') === 'ON') { + return true; + } + return false; + } else { + return function_exists('posix_isatty') && @posix_isatty(STDOUT); } - - return function_exists('posix_isatty') && @posix_isatty(STDOUT); } /** @@ -212,7 +217,11 @@ public function isSupported() */ public function are256ColorsSupported() { - return DIRECTORY_SEPARATOR === '/' && strpos(getenv('TERM'), '256color') !== false; + if (DIRECTORY_SEPARATOR === '\\') { + return function_exists('sapi_windows_vt100_support') && @sapi_windows_vt100_support(STDOUT); + } else { + return strpos(getenv('TERM'), '256color') !== false; + } } /** @@ -225,8 +234,7 @@ public function getPossibleStyles() /** * @param string $name - * @return string - * @throws InvalidStyleException + * @return string[] */ private function themeSequence($name) { @@ -240,7 +248,6 @@ private function themeSequence($name) /** * @param string $style * @return string - * @throws InvalidStyleException */ private function styleSequence($style) { @@ -277,4 +284,4 @@ private function escSequence($value) { return "\033[{$value}m"; } -} \ No newline at end of file +} diff --git a/app/vendor/jakub-onderka/php-console-color/src/JakubOnderka/PhpConsoleColor/InvalidStyleException.php b/app/vendor/jakub-onderka/php-console-color/src/InvalidStyleException.php similarity index 100% rename from app/vendor/jakub-onderka/php-console-color/src/JakubOnderka/PhpConsoleColor/InvalidStyleException.php rename to app/vendor/jakub-onderka/php-console-color/src/InvalidStyleException.php diff --git a/app/vendor/jakub-onderka/php-console-color/tests/JakubOnderka/PhpConsoleColor/ConsoleColorTest.php b/app/vendor/jakub-onderka/php-console-color/tests/ConsoleColorTest.php similarity index 100% rename from app/vendor/jakub-onderka/php-console-color/tests/JakubOnderka/PhpConsoleColor/ConsoleColorTest.php rename to app/vendor/jakub-onderka/php-console-color/tests/ConsoleColorTest.php diff --git a/app/vendor/jakub-onderka/php-console-color/tests/bootstrap.php b/app/vendor/jakub-onderka/php-console-color/tests/bootstrap.php deleted file mode 100644 index 7500417ed..000000000 --- a/app/vendor/jakub-onderka/php-console-color/tests/bootstrap.php +++ /dev/null @@ -1,2 +0,0 @@ - "VALUE" // ] ``` +### Context variables + +test_context.env +```bash +TEST_1 = $EXTERNAL +TEST_2 = VALUE +``` + +example_context.php +```php + 'external')); +$arr = $env->getContent(); + +// example 2 -- statically +$arr = Parser::parse(file_get_contents('test_context.env'), array('EXTERNAL' => 'external')); + +var_dump($arr); +// [ +// "TEST_1" => "external" +// "TEST_2" => "VALUE" +// ] +``` ### Syntax diff --git a/app/vendor/m1/env/src/Parser.php b/app/vendor/m1/env/src/Parser.php index 7dfd3d57e..dbd2f4d4a 100644 --- a/app/vendor/m1/env/src/Parser.php +++ b/app/vendor/m1/env/src/Parser.php @@ -69,12 +69,13 @@ class Parser /** * The parser constructor * - * @param string $content The + * @param string $content The content to parse + * @param array $context Variables context */ - public function __construct($content) + public function __construct($content, array $context = array()) { $this->key_parser = new KeyParser($this); - $this->value_parser = new ValueParser($this); + $this->value_parser = new ValueParser($this, $context); $this->string_helper = new StringHelper(); $this->doParse($content); @@ -84,12 +85,13 @@ public function __construct($content) * Parses the .env and returns the contents statically * * @param string $content The content to parse + * @param array $context Variables context * * @return array The .env contents */ - public static function parse($content) + public static function parse($content, array $context = array()) { - $parser = new Parser($content); + $parser = new Parser($content, $context); return $parser->getContent(); } @@ -101,7 +103,7 @@ public static function parse($content) * * @return array The .env contents */ - private function doParse($content) + protected function doParse($content) { $raw_lines = array_filter($this->makeLines($content), 'strlen'); @@ -185,7 +187,7 @@ private function parseLine($raw_line) private function parseExport($raw_line) { $line = trim($raw_line); - + if ($this->string_helper->startsWith("export", $line)) { $export_line = explode("export", $raw_line, 2); @@ -232,8 +234,11 @@ private function parseKeyValue($raw_line) * * @return array The .env contents */ - public function getContent() + public function getContent($keyName = null) { + if (!is_null($keyName)) { + return (array_key_exists($keyName, $this->lines)) ? $this->lines[$keyName] : null; + } return $this->lines; } } diff --git a/app/vendor/m1/env/src/Parser/ValueParser.php b/app/vendor/m1/env/src/Parser/ValueParser.php index ee0727874..aff9511a1 100644 --- a/app/vendor/m1/env/src/Parser/ValueParser.php +++ b/app/vendor/m1/env/src/Parser/ValueParser.php @@ -78,12 +78,13 @@ class ValueParser extends AbstractParser * {@inheritdoc} * * @param \M1\Env\Parser $parser The parent parser + * @param array $context Variables context */ - public function __construct($parser) + public function __construct($parser, array $context = array()) { parent::__construct($parser); - $this->variable_parser = new VariableParser($parser); + $this->variable_parser = new VariableParser($parser, $context); } /** diff --git a/app/vendor/m1/env/src/Parser/VariableParser.php b/app/vendor/m1/env/src/Parser/VariableParser.php index 7102385e2..7cdaf6b4f 100644 --- a/app/vendor/m1/env/src/Parser/VariableParser.php +++ b/app/vendor/m1/env/src/Parser/VariableParser.php @@ -49,6 +49,26 @@ class VariableParser extends AbstractParser */ const SYMBOL_DEFAULT_VALUE = '-'; + /** + * Variables context + * + * @var array + */ + private $context; + + /** + * {@inheritdoc} + * + * @param \M1\Env\Parser $parser The parent parser + * @param array $context Variables context + */ + public function __construct($parser, array $context = array()) + { + parent::__construct($parser); + + $this->context = $context; + } + /** * Parses a .env variable * @@ -93,20 +113,26 @@ private function fetchVariableMatches($value) /** * Parses a .env variable * - * @param string $value The value to parse + * @param string $value The value to parse * @param string $variable_name The variable name to get - * @param array $matches The matches of the variables - * @param bool $quoted_string Is the value in a quoted string + * @param array $matches The matches of the variables + * @param bool $quoted_string Is the value in a quoted string * * @return string The parsed value + * @throws \M1\Env\Exception\ParseException If the variable can not be found */ private function fetchVariable($value, $variable_name, $matches, $quoted_string) { if ($this->hasParameterExpansion($variable_name)) { $replacement = $this->fetchParameterExpansion($variable_name); + } elseif ($this->hasVariable($variable_name)) { + $replacement = $this->getVariable($variable_name); } else { - $this->checkVariableExists($value, $variable_name); - $replacement = $this->parser->lines[$variable_name]; + throw new ParseException( + sprintf('Variable has not been defined: %s', $variable_name), + $value, + $this->parser->line_num + ); } if ($this->parser->string_helper->isBoolInString($replacement, $quoted_string, count($matches[0]))) { @@ -148,11 +174,13 @@ private function fetchParameterExpansion($variable_name) list($parameter_symbol, $empty_flag) = $this->fetchParameterExpansionSymbol($variable_name, $parameter_type); list($variable, $default) = $this->splitVariableDefault($variable_name, $parameter_symbol); + $value = $this->getVariable($variable); + return $this->parseVariableParameter( $variable, $default, - $this->checkVariableExists($variable, $variable, true), - $empty_flag && empty($this->parser->lines[$variable]), + $this->hasVariable($variable), + $empty_flag && empty($value), $parameter_type ); } @@ -236,7 +264,7 @@ private function splitVariableDefault($variable_name, $parameter_symbol) private function parseVariableParameter($variable, $default, $exists, $empty, $type) { if ($exists && !$empty) { - return $this->parser->lines[$variable]; + return $this->getVariable($variable); } return $this->assignVariableParameterDefault($variable, $default, $empty, $type); @@ -266,29 +294,41 @@ private function assignVariableParameterDefault($variable, $default, $empty, $ty /** * Checks to see if a variable exists * - * @param string $value The value to throw an error with if doesn't exist - * @param string $variable The variable name to get - * @param bool $variable_check Are you checking to only see if a variable exists and not to throw an exception + * @param string $variable The variable name to get * - * @throws \M1\Env\Exception\ParseException If the variable can not be found and `$variable_check` is false + * @return bool + */ + private function hasVariable($variable) + { + if (array_key_exists($variable, $this->parser->lines)) { + return true; + } + + if (array_key_exists($variable, $this->context)) { + return true; + } + + return false; + } + + /** + * Get variable value + * + * @param string $variable * - * @return bool Does the variable exist + * @return mixed */ - private function checkVariableExists($value, $variable, $variable_check = false) + private function getVariable($variable) { - if (!array_key_exists($variable, $this->parser->lines)) { - if ($variable_check) { - return false; - } + if (array_key_exists($variable, $this->parser->lines)) { + return $this->parser->lines[$variable]; + } - throw new ParseException( - sprintf('Variable has not been defined: %s', $variable), - $value, - $this->parser->line_num - ); + if (array_key_exists($variable, $this->context)) { + return $this->context[$variable]; } - return true; + return null; } /** diff --git a/app/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.json b/app/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.json index ce6cb4577..a4361a9f5 100644 --- a/app/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.json +++ b/app/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.json @@ -1 +1 @@ -{"version":"2.8.30","headerMatch":{"HTTP_ACCEPT":{"matches":["application\/x-obml2d","application\/vnd.rim.html","text\/vnd.wap.wml","application\/vnd.wap.xhtml+xml"]},"HTTP_X_WAP_PROFILE":null,"HTTP_X_WAP_CLIENTID":null,"HTTP_WAP_CONNECTION":null,"HTTP_PROFILE":null,"HTTP_X_OPERAMINI_PHONE_UA":null,"HTTP_X_NOKIA_GATEWAY_ID":null,"HTTP_X_ORANGE_ID":null,"HTTP_X_VODAFONE_3GPDPCONTEXT":null,"HTTP_X_HUAWEI_USERID":null,"HTTP_UA_OS":null,"HTTP_X_MOBILE_GATEWAY":null,"HTTP_X_ATT_DEVICEID":null,"HTTP_UA_CPU":{"matches":["ARM"]}},"uaHttpHeaders":["HTTP_USER_AGENT","HTTP_X_OPERAMINI_PHONE_UA","HTTP_X_DEVICE_USER_AGENT","HTTP_X_ORIGINAL_USER_AGENT","HTTP_X_SKYFIRE_PHONE","HTTP_X_BOLT_PHONE_UA","HTTP_DEVICE_STOCK_UA","HTTP_X_UCBROWSER_DEVICE_UA"],"uaMatch":{"phones":{"iPhone":"\\biPhone\\b|\\biPod\\b","BlackBerry":"BlackBerry|\\bBB10\\b|rim[0-9]+","HTC":"HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel","Nexus":"Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6","Dell":"Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b","Motorola":"Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092","Samsung":"\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F","LG":"\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323)","Sony":"SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533","Asus":"Asus.*Galaxy|PadFone.*Mobile","NokiaLumia":"Lumia [0-9]{3,4}","Micromax":"Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b","Palm":"PalmSource|Palm","Vertu":"Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature","Pantech":"PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790","Fly":"IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250","Wiko":"KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM","iMobile":"i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)","SimValley":"\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b","Wolfgang":"AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q","Alcatel":"Alcatel","Nintendo":"Nintendo 3DS","Amoi":"Amoi","INQ":"INQ","GenericPhone":"Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser"},"tablets":{"iPad":"iPad|iPad.*Mobile","NexusTablet":"Android.*Nexus[\\s]+(7|9|10)","SamsungTablet":"SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y","Kindle":"Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk\/[0-9.]+ like Chrome\/[0-9.]+ (?!Mobile)","SurfaceTablet":"Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)","HPTablet":"HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10","AsusTablet":"^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b","BlackBerryTablet":"PlayBook|RIM Tablet","HTCtablet":"HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410","MotorolaTablet":"xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617","NookTablet":"Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2","AcerTablet":"Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30","ToshibaTablet":"Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO","LGTablet":"\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b","FujitsuTablet":"Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b","PrestigioTablet":"PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002","LenovoTablet":"Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304F|TB-8703F","DellTablet":"Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7","YarvikTablet":"Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b","MedionTablet":"Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB","ArnovaTablet":"97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2","IntensoTablet":"INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004","IRUTablet":"M702pro","MegafonTablet":"MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b","EbodaTablet":"E-Boda (Supreme|Impresspeed|Izzycomm|Essential)","AllViewTablet":"Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)","ArchosTablet":"\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b","AinolTablet":"NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark","NokiaLumiaTablet":"Lumia 2520","SonyTablet":"Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP612|SOT31","PhilipsTablet":"\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b","CubeTablet":"Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT","CobyTablet":"MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010","MIDTablet":"M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10","MSITablet":"MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b","SMiTTablet":"Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)","RockChipTablet":"Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A","FlyTablet":"IQ310|Fly Vision","bqTablet":"Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))|Maxwell.*Lite|Maxwell.*Plus","HuaweiTablet":"MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L","NecTablet":"\\bN-06D|\\bN-08D","PantechTablet":"Pantech.*P4100","BronchoTablet":"Broncho.*(N701|N708|N802|a710)","VersusTablet":"TOUCHPAD.*[78910]|\\bTOUCHTAB\\b","ZyncTablet":"z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900","PositivoTablet":"TB07STA|TB10STA|TB07FTA|TB10FTA","NabiTablet":"Android.*\\bNabi","KoboTablet":"Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build","DanewTablet":"DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b","TexetTablet":"NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE","PlaystationTablet":"Playstation.*(Portable|Vita)","TrekstorTablet":"ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab","PyleAudioTablet":"\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b","AdvanTablet":"Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ","DanyTechTablet":"Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1","GalapadTablet":"Android.*\\bG1\\b","MicromaxTablet":"Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b","KarbonnTablet":"Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b","AllFineTablet":"Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide","PROSCANTablet":"\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b","YONESTablet":"BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026","ChangJiaTablet":"TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503","GUTablet":"TX-A1301|TX-M9002|Q702|kf026","PointOfViewTablet":"TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10","OvermaxTablet":"OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027","HCLTablet":"HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync","DPSTablet":"DPS Dream 9|DPS Dual 7","VistureTablet":"V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10","CrestaTablet":"CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989","MediatekTablet":"\\bMT8125|MT8389|MT8135|MT8377\\b","ConcordeTablet":"Concorde([ ]+)?Tab|ConCorde ReadMan","GoCleverTablet":"GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042","ModecomTablet":"FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003","VoninoTablet":"\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b","ECSTablet":"V07OT2|TM105A|S10OT1|TR10CS1","StorexTablet":"eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab","VodafoneTablet":"SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497","EssentielBTablet":"Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2","RossMoorTablet":"RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711","iMobileTablet":"i-mobile i-note","TolinoTablet":"tolino tab [0-9.]+|tolino shine","AudioSonicTablet":"\\bC-22Q|T7-QC|T-17B|T-17P\\b","AMPETablet":"Android.* A78 ","SkkTablet":"Android.* (SKYPAD|PHOENIX|CYCLOPS)","TecnoTablet":"TECNO P9","JXDTablet":"Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b","iJoyTablet":"Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)","FX2Tablet":"FX2 PAD7|FX2 PAD10","XoroTablet":"KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151","ViewsonicTablet":"ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a","VerizonTablet":"QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1","OdysTablet":"LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10","CaptivaTablet":"CAPTIVA PAD","IconbitTablet":"NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S","TeclastTablet":"T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi","OndaTablet":"\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+","JaytechTablet":"TPC-PA762","BlaupunktTablet":"Endeavour 800NG|Endeavour 1010","DigmaTablet":"\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b","EvolioTablet":"ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b","LavaTablet":"QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b","AocTablet":"MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712","MpmanTablet":"MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010","CelkonTablet":"CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b","WolderTablet":"miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b","MiTablet":"\\bMI PAD\\b|\\bHM NOTE 1W\\b","NibiruTablet":"Nibiru M1|Nibiru Jupiter One","NexoTablet":"NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI","LeaderTablet":"TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100","UbislateTablet":"UbiSlate[\\s]?7C","PocketBookTablet":"Pocketbook","KocasoTablet":"\\b(TB-1207)\\b","HisenseTablet":"\\b(F5281|E2371)\\b","Hudl":"Hudl HT7S3|Hudl 2","TelstraTablet":"T-Hub2","GenericTablet":"Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b"},"browsers":{"Chrome":"\\bCrMo\\b|CriOS|Android.*Chrome\/[.0-9]* (Mobile)?","Dolfin":"\\bDolfin\\b","Opera":"Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR\/[0-9.]+|Coast\/[0-9.]+","Skyfire":"Skyfire","Edge":"Mobile Safari\/[.0-9]* Edge","IE":"IEMobile|MSIEMobile","Firefox":"fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS","Bolt":"bolt","TeaShark":"teashark","Blazer":"Blazer","Safari":"Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari","UCBrowser":"UC.*Browser|UCWEB","baiduboxapp":"baiduboxapp","baidubrowser":"baidubrowser","DiigoBrowser":"DiigoBrowser","Puffin":"Puffin","Mercury":"\\bMercury\\b","ObigoBrowser":"Obigo","NetFront":"NF-Browser","GenericBrowser":"NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger","PaleMoon":"Android.*PaleMoon|Mobile.*PaleMoon"},"os":{"AndroidOS":"Android","BlackBerryOS":"blackberry|\\bBB10\\b|rim tablet os","PalmOS":"PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino","SymbianOS":"Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b","WindowsMobileOS":"Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;","WindowsPhoneOS":"Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;","iOS":"\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia","MeeGoOS":"MeeGo","MaemoOS":"Maemo","JavaOS":"J2ME\/|\\bMIDP\\b|\\bCLDC\\b","webOS":"webOS|hpwOS","badaOS":"\\bBada\\b","BREWOS":"BREW"},"utilities":{"Bot":"Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom","MobileBot":"Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker\/M1A1-R2D2","DesktopMode":"WPDesktop","TV":"SonyDTV|HbbTV","WebKit":"(webkit)[ \/]([\\w.]+)","Console":"\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\\b","Watch":"SM-V700"}}} \ No newline at end of file +{"version":"2.8.33","headerMatch":{"HTTP_ACCEPT":{"matches":["application\/x-obml2d","application\/vnd.rim.html","text\/vnd.wap.wml","application\/vnd.wap.xhtml+xml"]},"HTTP_X_WAP_PROFILE":null,"HTTP_X_WAP_CLIENTID":null,"HTTP_WAP_CONNECTION":null,"HTTP_PROFILE":null,"HTTP_X_OPERAMINI_PHONE_UA":null,"HTTP_X_NOKIA_GATEWAY_ID":null,"HTTP_X_ORANGE_ID":null,"HTTP_X_VODAFONE_3GPDPCONTEXT":null,"HTTP_X_HUAWEI_USERID":null,"HTTP_UA_OS":null,"HTTP_X_MOBILE_GATEWAY":null,"HTTP_X_ATT_DEVICEID":null,"HTTP_UA_CPU":{"matches":["ARM"]}},"uaHttpHeaders":["HTTP_USER_AGENT","HTTP_X_OPERAMINI_PHONE_UA","HTTP_X_DEVICE_USER_AGENT","HTTP_X_ORIGINAL_USER_AGENT","HTTP_X_SKYFIRE_PHONE","HTTP_X_BOLT_PHONE_UA","HTTP_DEVICE_STOCK_UA","HTTP_X_UCBROWSER_DEVICE_UA"],"uaMatch":{"phones":{"iPhone":"\\biPhone\\b|\\biPod\\b","BlackBerry":"BlackBerry|\\bBB10\\b|rim[0-9]+","HTC":"HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\\bEVO\\b|T-Mobile G1|Z520m|Android [0-9.]+; Pixel","Nexus":"Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6","Dell":"Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\\b001DL\\b|\\b101DL\\b|\\bGS01\\b","Motorola":"Motorola|DROIDX|DROID BIONIC|\\bDroid\\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\\bMoto E\\b|XT1068|XT1092|XT1052","Samsung":"\\bSamsung\\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F","LG":"\\bLG\\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)","Sony":"SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533","Asus":"Asus.*Galaxy|PadFone.*Mobile","NokiaLumia":"Lumia [0-9]{3,4}","Micromax":"Micromax.*\\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\\b","Palm":"PalmSource|Palm","Vertu":"Vertu|Vertu.*Ltd|Vertu.*Ascent|Vertu.*Ayxta|Vertu.*Constellation(F|Quest)?|Vertu.*Monika|Vertu.*Signature","Pantech":"PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790","Fly":"IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250","Wiko":"KITE 4G|HIGHWAY|GETAWAY|STAIRWAY|DARKSIDE|DARKFULL|DARKNIGHT|DARKMOON|SLIDE|WAX 4G|RAINBOW|BLOOM|SUNSET|GOA(?!nna)|LENNY|BARRY|IGGY|OZZY|CINK FIVE|CINK PEAX|CINK PEAX 2|CINK SLIM|CINK SLIM 2|CINK +|CINK KING|CINK PEAX|CINK SLIM|SUBLIM","iMobile":"i-mobile (IQ|i-STYLE|idea|ZAA|Hitz)","SimValley":"\\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\\b","Wolfgang":"AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q","Alcatel":"Alcatel","Nintendo":"Nintendo (3DS|Switch)","Amoi":"Amoi","INQ":"INQ","GenericPhone":"Tapatalk|PDA;|SAGEM|\\bmmp\\b|pocket|\\bpsp\\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\\bwap\\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser"},"tablets":{"iPad":"iPad|iPad.*Mobile","NexusTablet":"Android.*Nexus[\\s]+(7|9|10)","GoogleTablet":"Android.*Pixel C","SamsungTablet":"SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835","Kindle":"Kindle|Silk.*Accelerated|Android.*\\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\\b|Android.*Silk\/[0-9.]+ like Chrome\/[0-9.]+ (?!Mobile)","SurfaceTablet":"Windows NT [0-9.]+; ARM;.*(Tablet|ARMBJS)","HPTablet":"HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10","AsusTablet":"^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\\bK00F\\b|\\bK00C\\b|\\bK00E\\b|\\bK00L\\b|TX201LA|ME176C|ME102A|\\bM80TA\\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\\bME70C\\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\\bP027\\b|\\bP024\\b|\\bP00C\\b","BlackBerryTablet":"PlayBook|RIM Tablet","HTCtablet":"HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410","MotorolaTablet":"xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617","NookTablet":"Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2","AcerTablet":"Android.*; \\b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810|A1-811|A1-830)\\b|W3-810|\\bA3-A10\\b|\\bA3-A11\\b|\\bA3-A20\\b|\\bA3-A30","ToshibaTablet":"Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO","LGTablet":"\\bL-06C|LG-V909|LG-V900|LG-V700|LG-V510|LG-V500|LG-V410|LG-V400|LG-VK810\\b","FujitsuTablet":"Android.*\\b(F-01D|F-02F|F-05E|F-10D|M532|Q572)\\b","PrestigioTablet":"PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002","LenovoTablet":"Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304F|TB-X304L|TB-8703F|Tab2A7-10F|TB2-X30L","DellTablet":"Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7","YarvikTablet":"Android.*\\b(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468|TAB07-100|TAB07-101|TAB07-150|TAB07-151|TAB07-152|TAB07-200|TAB07-201-3G|TAB07-210|TAB07-211|TAB07-212|TAB07-214|TAB07-220|TAB07-400|TAB07-485|TAB08-150|TAB08-200|TAB08-201-3G|TAB08-201-30|TAB09-100|TAB09-211|TAB09-410|TAB10-150|TAB10-201|TAB10-211|TAB10-400|TAB10-410|TAB13-201|TAB274EUK|TAB275EUK|TAB374EUK|TAB462EUK|TAB474EUK|TAB9-200)\\b","MedionTablet":"Android.*\\bOYO\\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB","ArnovaTablet":"97G4|AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT|AN9G2","IntensoTablet":"INM8002KP|INM1010FP|INM805ND|Intenso Tab|TAB1004","IRUTablet":"M702pro","MegafonTablet":"MegaFon V9|\\bZTE V9\\b|Android.*\\bMT7A\\b","EbodaTablet":"E-Boda (Supreme|Impresspeed|Izzycomm|Essential)","AllViewTablet":"Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)","ArchosTablet":"\\b(101G9|80G9|A101IT)\\b|Qilive 97R|Archos5|\\bARCHOS (70|79|80|90|97|101|FAMILYPAD|)(b|c|)(G10| Cobalt| TITANIUM(HD|)| Xenon| Neon|XSK| 2| XS 2| PLATINUM| CARBON|GAMEPAD)\\b","AinolTablet":"NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark","NokiaLumiaTablet":"Lumia 2520","SonyTablet":"Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712","PhilipsTablet":"\\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\\b","CubeTablet":"Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT","CobyTablet":"MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010","MIDTablet":"M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733|MID4X10","MSITablet":"MSI \\b(Primo 73K|Primo 73L|Primo 81L|Primo 77|Primo 93|Primo 75|Primo 76|Primo 73|Primo 81|Primo 91|Primo 90|Enjoy 71|Enjoy 7|Enjoy 10)\\b","SMiTTablet":"Android.*(\\bMID\\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)","RockChipTablet":"Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A","FlyTablet":"IQ310|Fly Vision","bqTablet":"Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))|Maxwell.*Lite|Maxwell.*Plus","HuaweiTablet":"MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09","NecTablet":"\\bN-06D|\\bN-08D","PantechTablet":"Pantech.*P4100","BronchoTablet":"Broncho.*(N701|N708|N802|a710)","VersusTablet":"TOUCHPAD.*[78910]|\\bTOUCHTAB\\b","ZyncTablet":"z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900","PositivoTablet":"TB07STA|TB10STA|TB07FTA|TB10FTA","NabiTablet":"Android.*\\bNabi","KoboTablet":"Kobo Touch|\\bK080\\b|\\bVox\\b Build|\\bArc\\b Build","DanewTablet":"DSlide.*\\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\\b","TexetTablet":"NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE","PlaystationTablet":"Playstation.*(Portable|Vita)","TrekstorTablet":"ST10416-1|VT10416-1|ST70408-1|ST702xx-1|ST702xx-2|ST80208|ST97216|ST70104-2|VT10416-2|ST10216-2A|SurfTab","PyleAudioTablet":"\\b(PTBL10CEU|PTBL10C|PTBL72BC|PTBL72BCEU|PTBL7CEU|PTBL7C|PTBL92BC|PTBL92BCEU|PTBL9CEU|PTBL9CUK|PTBL9C)\\b","AdvanTablet":"Android.* \\b(E3A|T3X|T5C|T5B|T3E|T3C|T3B|T1J|T1F|T2A|T1H|T1i|E1C|T1-E|T5-A|T4|E1-B|T2Ci|T1-B|T1-D|O1-A|E1-A|T1-A|T3A|T4i)\\b ","DanyTechTablet":"Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1","GalapadTablet":"Android.*\\bG1\\b(?!\\))","MicromaxTablet":"Funbook|Micromax.*\\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\\b","KarbonnTablet":"Android.*\\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\\b","AllFineTablet":"Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide","PROSCANTablet":"\\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\\b","YONESTablet":"BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026","ChangJiaTablet":"TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503","GUTablet":"TX-A1301|TX-M9002|Q702|kf026","PointOfViewTablet":"TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10","OvermaxTablet":"OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)|Qualcore 1027","HCLTablet":"HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync","DPSTablet":"DPS Dream 9|DPS Dual 7","VistureTablet":"V97 HD|i75 3G|Visture V4( HD)?|Visture V5( HD)?|Visture V10","CrestaTablet":"CTP(-)?810|CTP(-)?818|CTP(-)?828|CTP(-)?838|CTP(-)?888|CTP(-)?978|CTP(-)?980|CTP(-)?987|CTP(-)?988|CTP(-)?989","MediatekTablet":"\\bMT8125|MT8389|MT8135|MT8377\\b","ConcordeTablet":"Concorde([ ]+)?Tab|ConCorde ReadMan","GoCleverTablet":"GOCLEVER TAB|A7GOCLEVER|M1042|M7841|M742|R1042BK|R1041|TAB A975|TAB A7842|TAB A741|TAB A741L|TAB M723G|TAB M721|TAB A1021|TAB I921|TAB R721|TAB I720|TAB T76|TAB R70|TAB R76.2|TAB R106|TAB R83.2|TAB M813G|TAB I721|GCTA722|TAB I70|TAB I71|TAB S73|TAB R73|TAB R74|TAB R93|TAB R75|TAB R76.1|TAB A73|TAB A93|TAB A93.2|TAB T72|TAB R83|TAB R974|TAB R973|TAB A101|TAB A103|TAB A104|TAB A104.2|R105BK|M713G|A972BK|TAB A971|TAB R974.2|TAB R104|TAB R83.3|TAB A1042","ModecomTablet":"FreeTAB 9000|FreeTAB 7.4|FreeTAB 7004|FreeTAB 7800|FreeTAB 2096|FreeTAB 7.5|FreeTAB 1014|FreeTAB 1001 |FreeTAB 8001|FreeTAB 9706|FreeTAB 9702|FreeTAB 7003|FreeTAB 7002|FreeTAB 1002|FreeTAB 7801|FreeTAB 1331|FreeTAB 1004|FreeTAB 8002|FreeTAB 8014|FreeTAB 9704|FreeTAB 1003","VoninoTablet":"\\b(Argus[ _]?S|Diamond[ _]?79HD|Emerald[ _]?78E|Luna[ _]?70C|Onyx[ _]?S|Onyx[ _]?Z|Orin[ _]?HD|Orin[ _]?S|Otis[ _]?S|SpeedStar[ _]?S|Magnet[ _]?M9|Primus[ _]?94[ _]?3G|Primus[ _]?94HD|Primus[ _]?QS|Android.*\\bQ8\\b|Sirius[ _]?EVO[ _]?QS|Sirius[ _]?QS|Spirit[ _]?S)\\b","ECSTablet":"V07OT2|TM105A|S10OT1|TR10CS1","StorexTablet":"eZee[_']?(Tab|Go)[0-9]+|TabLC7|Looney Tunes Tab","VodafoneTablet":"SmartTab([ ]+)?[0-9]+|SmartTabII10|SmartTabII7|VF-1497","EssentielBTablet":"Smart[ ']?TAB[ ]+?[0-9]+|Family[ ']?TAB2","RossMoorTablet":"RM-790|RM-997|RMD-878G|RMD-974R|RMT-705A|RMT-701|RME-601|RMT-501|RMT-711","iMobileTablet":"i-mobile i-note","TolinoTablet":"tolino tab [0-9.]+|tolino shine","AudioSonicTablet":"\\bC-22Q|T7-QC|T-17B|T-17P\\b","AMPETablet":"Android.* A78 ","SkkTablet":"Android.* (SKYPAD|PHOENIX|CYCLOPS)","TecnoTablet":"TECNO P9|TECNO DP8D","JXDTablet":"Android.* \\b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\\b","iJoyTablet":"Tablet (Spirit 7|Essentia|Galatea|Fusion|Onix 7|Landa|Titan|Scooby|Deox|Stella|Themis|Argon|Unique 7|Sygnus|Hexen|Finity 7|Cream|Cream X2|Jade|Neon 7|Neron 7|Kandy|Scape|Saphyr 7|Rebel|Biox|Rebel|Rebel 8GB|Myst|Draco 7|Myst|Tab7-004|Myst|Tadeo Jones|Tablet Boing|Arrow|Draco Dual Cam|Aurix|Mint|Amity|Revolution|Finity 9|Neon 9|T9w|Amity 4GB Dual Cam|Stone 4GB|Stone 8GB|Andromeda|Silken|X2|Andromeda II|Halley|Flame|Saphyr 9,7|Touch 8|Planet|Triton|Unique 10|Hexen 10|Memphis 4GB|Memphis 8GB|Onix 10)","FX2Tablet":"FX2 PAD7|FX2 PAD10","XoroTablet":"KidsPAD 701|PAD[ ]?712|PAD[ ]?714|PAD[ ]?716|PAD[ ]?717|PAD[ ]?718|PAD[ ]?720|PAD[ ]?721|PAD[ ]?722|PAD[ ]?790|PAD[ ]?792|PAD[ ]?900|PAD[ ]?9715D|PAD[ ]?9716DR|PAD[ ]?9718DR|PAD[ ]?9719QR|PAD[ ]?9720QR|TelePAD1030|Telepad1032|TelePAD730|TelePAD731|TelePAD732|TelePAD735Q|TelePAD830|TelePAD9730|TelePAD795|MegaPAD 1331|MegaPAD 1851|MegaPAD 2151","ViewsonicTablet":"ViewPad 10pi|ViewPad 10e|ViewPad 10s|ViewPad E72|ViewPad7|ViewPad E100|ViewPad 7e|ViewSonic VB733|VB100a","VerizonTablet":"QTAQZ3|QTAIR7|QTAQTZ3|QTASUN1|QTASUN2|QTAXIA1","OdysTablet":"LOOX|XENO10|ODYS[ -](Space|EVO|Xpress|NOON)|\\bXELIO\\b|Xelio10Pro|XELIO7PHONETAB|XELIO10EXTREME|XELIOPT2|NEO_QUAD10","CaptivaTablet":"CAPTIVA PAD","IconbitTablet":"NetTAB|NT-3702|NT-3702S|NT-3702S|NT-3603P|NT-3603P|NT-0704S|NT-0704S|NT-3805C|NT-3805C|NT-0806C|NT-0806C|NT-0909T|NT-0909T|NT-0907S|NT-0907S|NT-0902S|NT-0902S","TeclastTablet":"T98 4G|\\bP80\\b|\\bX90HD\\b|X98 Air|X98 Air 3G|\\bX89\\b|P80 3G|\\bX80h\\b|P98 Air|\\bX89HD\\b|P98 3G|\\bP90HD\\b|P89 3G|X98 3G|\\bP70h\\b|P79HD 3G|G18d 3G|\\bP79HD\\b|\\bP89s\\b|\\bA88\\b|\\bP10HD\\b|\\bP19HD\\b|G18 3G|\\bP78HD\\b|\\bA78\\b|\\bP75\\b|G17s 3G|G17h 3G|\\bP85t\\b|\\bP90\\b|\\bP11\\b|\\bP98t\\b|\\bP98HD\\b|\\bG18d\\b|\\bP85s\\b|\\bP11HD\\b|\\bP88s\\b|\\bA80HD\\b|\\bA80se\\b|\\bA10h\\b|\\bP89\\b|\\bP78s\\b|\\bG18\\b|\\bP85\\b|\\bA70h\\b|\\bA70\\b|\\bG17\\b|\\bP18\\b|\\bA80s\\b|\\bA11s\\b|\\bP88HD\\b|\\bA80h\\b|\\bP76s\\b|\\bP76h\\b|\\bP98\\b|\\bA10HD\\b|\\bP78\\b|\\bP88\\b|\\bA11\\b|\\bA10t\\b|\\bP76a\\b|\\bP76t\\b|\\bP76e\\b|\\bP85HD\\b|\\bP85a\\b|\\bP86\\b|\\bP75HD\\b|\\bP76v\\b|\\bA12\\b|\\bP75a\\b|\\bA15\\b|\\bP76Ti\\b|\\bP81HD\\b|\\bA10\\b|\\bT760VE\\b|\\bT720HD\\b|\\bP76\\b|\\bP73\\b|\\bP71\\b|\\bP72\\b|\\bT720SE\\b|\\bC520Ti\\b|\\bT760\\b|\\bT720VE\\b|T720-3GE|T720-WiFi","OndaTablet":"\\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\\b[\\s]+|V10 \\b4G\\b","JaytechTablet":"TPC-PA762","BlaupunktTablet":"Endeavour 800NG|Endeavour 1010","DigmaTablet":"\\b(iDx10|iDx9|iDx8|iDx7|iDxD7|iDxD8|iDsQ8|iDsQ7|iDsQ8|iDsD10|iDnD7|3TS804H|iDsQ11|iDj7|iDs10)\\b","EvolioTablet":"ARIA_Mini_wifi|Aria[ _]Mini|Evolio X10|Evolio X7|Evolio X8|\\bEvotab\\b|\\bNeura\\b","LavaTablet":"QPAD E704|\\bIvoryS\\b|E-TAB IVORY|\\bE-TAB\\b","AocTablet":"MW0811|MW0812|MW0922|MTK8382|MW1031|MW0831|MW0821|MW0931|MW0712","MpmanTablet":"MP11 OCTA|MP10 OCTA|MPQC1114|MPQC1004|MPQC994|MPQC974|MPQC973|MPQC804|MPQC784|MPQC780|\\bMPG7\\b|MPDCG75|MPDCG71|MPDC1006|MP101DC|MPDC9000|MPDC905|MPDC706HD|MPDC706|MPDC705|MPDC110|MPDC100|MPDC99|MPDC97|MPDC88|MPDC8|MPDC77|MP709|MID701|MID711|MID170|MPDC703|MPQC1010","CelkonTablet":"CT695|CT888|CT[\\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\\bCT-1\\b","WolderTablet":"miTab \\b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\\b","MediacomTablet":"M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA","MiTablet":"\\bMI PAD\\b|\\bHM NOTE 1W\\b","NibiruTablet":"Nibiru M1|Nibiru Jupiter One","NexoTablet":"NEXO NOVA|NEXO 10|NEXO AVIO|NEXO FREE|NEXO GO|NEXO EVO|NEXO 3G|NEXO SMART|NEXO KIDDO|NEXO MOBI","LeaderTablet":"TBLT10Q|TBLT10I|TBL-10WDKB|TBL-10WDKBO2013|TBL-W230V2|TBL-W450|TBL-W500|SV572|TBLT7I|TBA-AC7-8G|TBLT79|TBL-8W16|TBL-10W32|TBL-10WKB|TBL-W100","UbislateTablet":"UbiSlate[\\s]?7C","PocketBookTablet":"Pocketbook","KocasoTablet":"\\b(TB-1207)\\b","HisenseTablet":"\\b(F5281|E2371)\\b","Hudl":"Hudl HT7S3|Hudl 2","TelstraTablet":"T-Hub2","GenericTablet":"Android.*\\b97D\\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\\bA7EB\\b|CatNova8|A1_07|CT704|CT1002|\\bM721\\b|rk30sdk|\\bEVOTAB\\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\\bM6pro\\b|CT1020W|arc 10HD|\\bTP750\\b|\\bQTAQZ3\\b|WVT101|TM1088|KT107"},"browsers":{"Chrome":"\\bCrMo\\b|CriOS|Android.*Chrome\/[.0-9]* (Mobile)?","Dolfin":"\\bDolfin\\b","Opera":"Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR\/[0-9.]+$|Coast\/[0-9.]+","Skyfire":"Skyfire","Edge":"Mobile Safari\/[.0-9]* Edge","IE":"IEMobile|MSIEMobile","Firefox":"fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile|FxiOS","Bolt":"bolt","TeaShark":"teashark","Blazer":"Blazer","Safari":"Version.*Mobile.*Safari|Safari.*Mobile|MobileSafari","WeChat":"\\bMicroMessenger\\b","UCBrowser":"UC.*Browser|UCWEB","baiduboxapp":"baiduboxapp","baidubrowser":"baidubrowser","DiigoBrowser":"DiigoBrowser","Puffin":"Puffin","Mercury":"\\bMercury\\b","ObigoBrowser":"Obigo","NetFront":"NF-Browser","GenericBrowser":"NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger","PaleMoon":"Android.*PaleMoon|Mobile.*PaleMoon"},"os":{"AndroidOS":"Android","BlackBerryOS":"blackberry|\\bBB10\\b|rim tablet os","PalmOS":"PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino","SymbianOS":"Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\\bS60\\b","WindowsMobileOS":"Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;","WindowsPhoneOS":"Windows Phone 10.0|Windows Phone 8.1|Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7|Windows NT 6.[23]; ARM;","iOS":"\\biPhone.*Mobile|\\biPod|\\biPad|AppleCoreMedia","MeeGoOS":"MeeGo","MaemoOS":"Maemo","JavaOS":"J2ME\/|\\bMIDP\\b|\\bCLDC\\b","webOS":"webOS|hpwOS","badaOS":"\\bBada\\b","BREWOS":"BREW"},"utilities":{"Bot":"Googlebot|facebookexternalhit|AdsBot-Google|Google Keyword Suggestion|Facebot|YandexBot|YandexMobileBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|Exabot|MJ12bot|YandexImages|TurnitinBot|Pingdom","MobileBot":"Googlebot-Mobile|AdsBot-Google-Mobile|YahooSeeker\/M1A1-R2D2","DesktopMode":"WPDesktop","TV":"SonyDTV|HbbTV","WebKit":"(webkit)[ \/]([\\w.]+)","Console":"\\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\\b","Watch":"SM-V700"}}} \ No newline at end of file diff --git a/app/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.php b/app/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.php index 6ccf39b7f..c65b3812f 100644 --- a/app/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.php +++ b/app/vendor/mobiledetect/mobiledetectlib/Mobile_Detect.php @@ -1,30 +1,25 @@ - * Nick Ilyin - * - * Original author: Victor Stanciu - * - * @license Code and contributions have 'MIT License' - * More details: https://github.com/serbanghita/Mobile-Detect/blob/master/LICENSE.txt + * Homepage: http://mobiledetect.net + * GitHub: https://github.com/serbanghita/Mobile-Detect + * README: https://github.com/serbanghita/Mobile-Detect/blob/master/README.md + * CONTRIBUTING: https://github.com/serbanghita/Mobile-Detect/blob/master/docs/CONTRIBUTING.md + * KNOWN LIMITATIONS: https://github.com/serbanghita/Mobile-Detect/blob/master/docs/KNOWN_LIMITATIONS.md + * EXAMPLES: https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples * - * @link Homepage: http://mobiledetect.net - * GitHub Repo: https://github.com/serbanghita/Mobile-Detect - * Google Code: http://code.google.com/p/php-mobile-detect/ - * README: https://github.com/serbanghita/Mobile-Detect/blob/master/README.md - * HOWTO: https://github.com/serbanghita/Mobile-Detect/wiki/Code-examples + * @license https://github.com/serbanghita/Mobile-Detect/blob/master/LICENSE.txt MIT License + * @author Serban Ghita + * @author Nick Ilyin + * Original author: Victor Stanciu * - * @version 2.8.30 + * @version 2.8.33 */ - class Mobile_Detect { /** @@ -66,7 +61,7 @@ class Mobile_Detect /** * Stores the version number of the current release. */ - const VERSION = '2.8.30'; + const VERSION = '2.8.33'; /** * A type for the version() method indicating a string return value. @@ -112,6 +107,7 @@ class Mobile_Detect /** * The matches extracted from the regex expression. * This is good for debug. + * * @var string */ protected $matchesArray = null; @@ -173,9 +169,9 @@ class Mobile_Detect 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile|Nexus 4|Nexus 5|Nexus 6', // @todo: Is 'Dell Streak' a tablet or a phone? ;) 'Dell' => 'Dell[;]? (Streak|Aero|Venue|Venue Pro|Flash|Smoke|Mini 3iX)|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b', - 'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\bMoto E\b|XT1068|XT1092', - 'Samsung' => '\bSamsung\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F', - 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323)', + 'Motorola' => 'Motorola|DROIDX|DROID BIONIC|\bDroid\b.*Build|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925|XT1021|\bMoto E\b|XT1068|XT1092|XT1052', + 'Samsung' => '\bSamsung\b|SM-G950F|SM-G955F|SM-G9250|GT-19300|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535|SM-N900A|SGH-I317|SGH-T999L|GT-S5360B|GT-I8262|GT-S6802|GT-S6312|GT-S6310|GT-S5312|GT-S5310|GT-I9105|GT-I8510|GT-S6790N|SM-G7105|SM-N9005|GT-S5301|GT-I9295|GT-I9195|SM-C101|GT-S7392|GT-S7560|GT-B7610|GT-I5510|GT-S7582|GT-S7530E|GT-I8750|SM-G9006V|SM-G9008V|SM-G9009D|SM-G900A|SM-G900D|SM-G900F|SM-G900H|SM-G900I|SM-G900J|SM-G900K|SM-G900L|SM-G900M|SM-G900P|SM-G900R4|SM-G900S|SM-G900T|SM-G900V|SM-G900W8|SHV-E160K|SCH-P709|SCH-P729|SM-T2558|GT-I9205|SM-G9350|SM-J120F|SM-G920F|SM-G920V|SM-G930F|SM-N910C|SM-A310F|GT-I9190|SM-J500FN|SM-G903F|SM-J330F', + 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS740|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999|E612|D955|D802|MS323|M257)', 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i|C5303|C6902|C6903|C6906|C6943|D2533', 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile', 'NokiaLumia' => 'Lumia [0-9]{3,4}', @@ -200,7 +196,7 @@ class Mobile_Detect // http://www.wolfgangmobile.com/ 'Wolfgang' => 'AT-B24D|AT-AS50HD|AT-AS40W|AT-AS55HD|AT-AS45q2|AT-B26D|AT-AS50Q', 'Alcatel' => 'Alcatel', - 'Nintendo' => 'Nintendo 3DS', + 'Nintendo' => 'Nintendo (3DS|Switch)', // http://en.wikipedia.org/wiki/Amoi 'Amoi' => 'Amoi', // http://en.wikipedia.org/wiki/INQ @@ -219,8 +215,11 @@ class Mobile_Detect 'iPad' => 'iPad|iPad.*Mobile', // Removed |^.*Android.*Nexus(?!(?:Mobile).)*$ // @see #442 + // @todo Merge NexusTablet into GoogleTablet. 'NexusTablet' => 'Android.*Nexus[\s]+(7|9|10)', - 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y', // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone. + // https://en.wikipedia.org/wiki/Pixel_C + 'GoogleTablet' => 'Android.*Pixel C', + 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5105|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-P5200|GT-P5210|GT-P5210X|SM-T311|SM-T310|SM-T310X|SM-T210|SM-T210R|SM-T211|SM-P600|SM-P601|SM-P605|SM-P900|SM-P901|SM-T217|SM-T217A|SM-T217S|SM-P6000|SM-T3100|SGH-I467|XE500|SM-T110|GT-P5220|GT-I9200X|GT-N5110X|GT-N5120|SM-P905|SM-T111|SM-T2105|SM-T315|SM-T320|SM-T320X|SM-T321|SM-T520|SM-T525|SM-T530NU|SM-T230NU|SM-T330NU|SM-T900|XE500T1C|SM-P605V|SM-P905V|SM-T337V|SM-T537V|SM-T707V|SM-T807V|SM-P600X|SM-P900X|SM-T210X|SM-T230|SM-T230X|SM-T325|GT-P7503|SM-T531|SM-T330|SM-T530|SM-T705|SM-T705C|SM-T535|SM-T331|SM-T800|SM-T700|SM-T537|SM-T807|SM-P907A|SM-T337A|SM-T537A|SM-T707A|SM-T807A|SM-T237|SM-T807P|SM-P607T|SM-T217T|SM-T337T|SM-T807T|SM-T116NQ|SM-T116BU|SM-P550|SM-T350|SM-T550|SM-T9000|SM-P9000|SM-T705Y|SM-T805|GT-P3113|SM-T710|SM-T810|SM-T815|SM-T360|SM-T533|SM-T113|SM-T335|SM-T715|SM-T560|SM-T670|SM-T677|SM-T377|SM-T567|SM-T357T|SM-T555|SM-T561|SM-T713|SM-T719|SM-T813|SM-T819|SM-T580|SM-T355Y?|SM-T280|SM-T817A|SM-T820|SM-W700|SM-P580|SM-T587|SM-P350|SM-P555M|SM-P355M|SM-T113NU|SM-T815Y|SM-T585|SM-T285|SM-T825|SM-W708|SM-T835', // SCH-P709|SCH-P729|SM-T2558|GT-I9205 - Samsung Mega - treat them like a regular phone. // http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFOT|KFTT|KFJWI|KFJWA|KFOTE|KFSOWI|KFTHWI|KFTHWA|KFAPWI|KFAPWA|WFJWAE|KFSAWA|KFSAWI|KFASWI|KFARWI|KFFOWI|KFGIWI|KFMEWI)\b|Android.*Silk/[0-9.]+ like Chrome/[0-9.]+ (?!Mobile)', // Only the Surface tablets with Windows RT are considered mobile. @@ -230,7 +229,7 @@ class Mobile_Detect 'HPTablet' => 'HP Slate (7|8|10)|HP ElitePad 900|hp-tablet|EliteBook.*Touch|HP 8|Slate 21|HP SlateBook 10', // Watch out for PadFone, see #132. // http://www.asus.com/de/Tablets_Mobile/Memo_Pad_Products/ - 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|\bK00C\b|\bK00E\b|\bK00L\b|TX201LA|ME176C|ME102A|\bM80TA\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\bME70C\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\bP027\b', + 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME302C|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101|\bK00F\b|\bK00C\b|\bK00E\b|\bK00L\b|TX201LA|ME176C|ME102A|\bM80TA\b|ME372CL|ME560CG|ME372CG|ME302KL| K010 | K011 | K017 | K01E |ME572C|ME103K|ME170C|ME171C|\bME70C\b|ME581C|ME581CL|ME8510C|ME181C|P01Y|PO1MA|P01Z|\bP027\b|\bP024\b|\bP00C\b', 'BlackBerryTablet' => 'PlayBook|RIM Tablet', 'HTCtablet' => 'HTC_Flyer_P512|HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200|PG09410', 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617', @@ -252,7 +251,7 @@ class Mobile_Detect // Prestigio Tablets http://www.prestigio.com/support 'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280C3G|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D|PMP5297C|PMP5297C_QUAD|PMP812E|PMP812E3G|PMP812F|PMP810E|PMP880TD|PMT3017|PMT3037|PMT3047|PMT3057|PMT7008|PMT5887|PMT5001|PMT5002', // http://support.lenovo.com/en_GB/downloads/default.page?# - 'LenovoTablet' => 'Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304F|TB-8703F', + 'LenovoTablet' => 'Lenovo TAB|Idea(Tab|Pad)( A1|A10| K1|)|ThinkPad([ ]+)?Tablet|YT3-850M|YT3-X90L|YT3-X90F|YT3-X90X|Lenovo.*(S2109|S2110|S5000|S6000|K3011|A3000|A3500|A1000|A2107|A2109|A1107|A5500|A7600|B6000|B8000|B8080)(-|)(FL|F|HV|H|)|TB-X103F|TB-X304F|TB-X304L|TB-8703F|Tab2A7-10F|TB2-X30L', // http://www.dell.com/support/home/us/en/04/Products/tab_mob/tablets 'DellTablet' => 'Venue 11|Venue 8|Venue 7|Dell Streak 10|Dell Streak 7', // http://www.yarvik.com/en/matrix/tablets/ @@ -278,7 +277,7 @@ class Mobile_Detect // @todo: inspect http://esupport.sony.com/US/p/select-system.pl?DIRECTOR=DRIVER // Readers http://www.atsuhiro-me.net/ebook/sony-reader/sony-reader-web-browser // http://www.sony.jp/support/tablet/ - 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP612|SOT31', + 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT13|SGPT114|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT131|SGPT132|SGPT133|SGPT211|SGPT212|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201|SGP351|SGP341|SGP511|SGP512|SGP521|SGP541|SGP551|SGP621|SGP641|SGP612|SOT31|SGP771|SGP611|SGP612|SGP712', // http://www.support.philips.com/support/catalog/worldproducts.jsp?userLanguage=en&userCountry=cn&categoryid=3G_LTE_TABLET_SU_CN_CARE&title=3G%20tablets%20/%20LTE%20range&_dyncharset=UTF-8 'PhilipsTablet' => '\b(PI2010|PI3000|PI3100|PI3105|PI3110|PI3205|PI3210|PI3900|PI4010|PI7000|PI7100)\b', // db + http://www.cube-tablet.com/buy-products.html @@ -305,7 +304,7 @@ class Mobile_Detect 'bqTablet' => 'Android.*(bq)?.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant|Aquaris ([E|M]10|M8))|Maxwell.*Lite|Maxwell.*Plus', // http://www.huaweidevice.com/worldwide/productFamily.do?method=index&directoryId=5011&treeId=3290 // http://www.huaweidevice.com/worldwide/downloadCenter.do?method=index&directoryId=3372&treeId=0&tb=1&type=software (including legacy tablets) - 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L', + 'HuaweiTablet' => 'MediaPad|MediaPad 7 Youth|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim|M2-A01L|BAH-L09|BAH-W09', // Nec or Medias Tab 'NecTablet' => '\bN-06D|\bN-08D', // Pantech Tablets: http://www.pantechusa.com/phones/ @@ -337,7 +336,7 @@ class Mobile_Detect // http://www.danytech.com/category/tablet-pc 'DanyTechTablet' => 'Genius Tab G3|Genius Tab S2|Genius Tab Q3|Genius Tab G4|Genius Tab Q4|Genius Tab G-II|Genius TAB GII|Genius TAB GIII|Genius Tab S1', // http://www.galapad.net/product.html - 'GalapadTablet' => 'Android.*\bG1\b', + 'GalapadTablet' => 'Android.*\bG1\b(?!\))', // http://www.micromaxinfo.com/tablet/funbook 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b', // http://www.karbonnmobiles.com/products_tablet.php @@ -405,7 +404,7 @@ class Mobile_Detect // Skk Mobile - http://skkmobile.com.ph/product_tablets.php 'SkkTablet' => 'Android.* (SKYPAD|PHOENIX|CYCLOPS)', // Tecno Mobile (only tablet) - http://www.tecno-mobile.com/index.php/product?filterby=smart&list_order=all&page=1 - 'TecnoTablet' => 'TECNO P9', + 'TecnoTablet' => 'TECNO P9|TECNO DP8D', // JXD (consoles & tablets) - http://jxd.hk/products.asp?selectclassid=009008&clsid=3 'JXDTablet' => 'Android.* \b(F3000|A3300|JXD5000|JXD3000|JXD2000|JXD300B|JXD300|S5800|S7800|S602b|S5110b|S7300|S5300|S602|S603|S5100|S5110|S601|S7100a|P3000F|P3000s|P101|P200s|P1000m|P200m|P9100|P1000s|S6600b|S908|P1000|P300|S18|S6600|S9100)\b', // i-Joy tablets - http://www.i-joy.es/en/cat/products/tablets/ @@ -428,7 +427,7 @@ class Mobile_Detect // http://www.teclast.com/topic.php?channelID=70&topicID=140&pid=63 'TeclastTablet' => 'T98 4G|\bP80\b|\bX90HD\b|X98 Air|X98 Air 3G|\bX89\b|P80 3G|\bX80h\b|P98 Air|\bX89HD\b|P98 3G|\bP90HD\b|P89 3G|X98 3G|\bP70h\b|P79HD 3G|G18d 3G|\bP79HD\b|\bP89s\b|\bA88\b|\bP10HD\b|\bP19HD\b|G18 3G|\bP78HD\b|\bA78\b|\bP75\b|G17s 3G|G17h 3G|\bP85t\b|\bP90\b|\bP11\b|\bP98t\b|\bP98HD\b|\bG18d\b|\bP85s\b|\bP11HD\b|\bP88s\b|\bA80HD\b|\bA80se\b|\bA10h\b|\bP89\b|\bP78s\b|\bG18\b|\bP85\b|\bA70h\b|\bA70\b|\bG17\b|\bP18\b|\bA80s\b|\bA11s\b|\bP88HD\b|\bA80h\b|\bP76s\b|\bP76h\b|\bP98\b|\bA10HD\b|\bP78\b|\bP88\b|\bA11\b|\bA10t\b|\bP76a\b|\bP76t\b|\bP76e\b|\bP85HD\b|\bP85a\b|\bP86\b|\bP75HD\b|\bP76v\b|\bA12\b|\bP75a\b|\bA15\b|\bP76Ti\b|\bP81HD\b|\bA10\b|\bT760VE\b|\bT720HD\b|\bP76\b|\bP73\b|\bP71\b|\bP72\b|\bT720SE\b|\bC520Ti\b|\bT760\b|\bT720VE\b|T720-3GE|T720-WiFi', // Onda - http://www.onda-tablet.com/buy-android-onda.html?dir=desc&limit=all&order=price - 'OndaTablet' => '\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\b[\s]+', + 'OndaTablet' => '\b(V975i|Vi30|VX530|V701|Vi60|V701s|Vi50|V801s|V719|Vx610w|VX610W|V819i|Vi10|VX580W|Vi10|V711s|V813|V811|V820w|V820|Vi20|V711|VI30W|V712|V891w|V972|V819w|V820w|Vi60|V820w|V711|V813s|V801|V819|V975s|V801|V819|V819|V818|V811|V712|V975m|V101w|V961w|V812|V818|V971|V971s|V919|V989|V116w|V102w|V973|Vi40)\b[\s]+|V10 \b4G\b', 'JaytechTablet' => 'TPC-PA762', 'BlaupunktTablet' => 'Endeavour 800NG|Endeavour 1010', // http://www.digma.ru/support/download/ @@ -448,6 +447,7 @@ class Mobile_Detect 'CelkonTablet' => 'CT695|CT888|CT[\s]?910|CT7 Tab|CT9 Tab|CT3 Tab|CT2 Tab|CT1 Tab|C820|C720|\bCT-1\b', // http://www.wolderelectronics.com/productos/manuales-y-guias-rapidas/categoria-2-miTab 'WolderTablet' => 'miTab \b(DIAMOND|SPACE|BROOKLYN|NEO|FLY|MANHATTAN|FUNK|EVOLUTION|SKY|GOCAR|IRON|GENIUS|POP|MINT|EPSILON|BROADWAY|JUMP|HOP|LEGEND|NEW AGE|LINE|ADVANCE|FEEL|FOLLOW|LIKE|LINK|LIVE|THINK|FREEDOM|CHICAGO|CLEVELAND|BALTIMORE-GH|IOWA|BOSTON|SEATTLE|PHOENIX|DALLAS|IN 101|MasterChef)\b', + 'MediacomTablet' => 'M-MPI10C3G|M-SP10EG|M-SP10EGP|M-SP10HXAH|M-SP7HXAH|M-SP10HXBH|M-SP8HXAH|M-SP8MXA', // http://www.mi.com/en 'MiTablet' => '\bMI PAD\b|\bHM NOTE 1W\b', // http://www.nbru.cn/index.html @@ -470,7 +470,7 @@ class Mobile_Detect 'Hudl' => 'Hudl HT7S3|Hudl 2', // http://www.telstra.com.au/home-phone/thub-2/ 'TelstraTablet' => 'T-Hub2', - 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\bM6pro\b|CT1020W|arc 10HD|\bTP750\b|\bQTAQZ3\b' + 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|M758A|ET904|ALUMIUM10|Smartfren Tab|Endeavour 1010|Tablet-PC-4|Tagi Tab|\bM6pro\b|CT1020W|arc 10HD|\bTP750\b|\bQTAQZ3\b|WVT101|TM1088|KT107' ); /** @@ -519,7 +519,7 @@ class Mobile_Detect // @reference: https://developers.google.com/chrome/mobile/docs/user-agent 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?', 'Dolfin' => '\bDolfin\b', - 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+', + 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+$|Coast/[0-9.]+', 'Skyfire' => 'Skyfire', 'Edge' => 'Mobile Safari/[.0-9]* Edge', 'IE' => 'IEMobile|MSIEMobile', // |Trident/[.0-9]+ @@ -532,6 +532,7 @@ class Mobile_Detect // http://en.wikipedia.org/wiki/Midori_(web_browser) //'Midori' => 'midori', //'Tizen' => 'Tizen', + 'WeChat' => '\bMicroMessenger\b', 'UCBrowser' => 'UC.*Browser|UCWEB', 'baiduboxapp' => 'baiduboxapp', 'baidubrowser' => 'baidubrowser', @@ -568,7 +569,7 @@ class Mobile_Detect 'TV' => 'SonyDTV|HbbTV', // experimental 'WebKit' => '(webkit)[ /]([\w.]+)', // @todo: Include JXD consoles. - 'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|PLAYSTATION|Xbox)\b', + 'Console' => '\b(Nintendo|Nintendo WiiU|Nintendo 3DS|Nintendo Switch|PLAYSTATION|Xbox)\b', 'Watch' => 'SM-V700', ); diff --git a/app/vendor/mobiledetect/mobiledetectlib/README.md b/app/vendor/mobiledetect/mobiledetectlib/README.md index 91b9e59f7..310d9f366 100644 --- a/app/vendor/mobiledetect/mobiledetectlib/README.md +++ b/app/vendor/mobiledetect/mobiledetectlib/README.md @@ -1,6 +1,6 @@ ![Mobile Detect](http://demo.mobiledetect.net/logo-github.png) -> Motto: "Every business should have a mobile detection script to detect mobile readers." +> Motto: "Every business should have a detection script to detect mobile readers." [![Build Status](https://travis-ci.org/serbanghita/Mobile-Detect.svg?branch=devel)](https://travis-ci.org/serbanghita/Mobile-Detect) [![Latest Stable Version](https://poser.pugx.org/mobiledetect/mobiledetectlib/v/stable.svg)](https://packagist.org/packages/mobiledetect/mobiledetectlib) @@ -14,29 +14,30 @@ Mobile Detect is a lightweight PHP class for detecting mobile devices (including tablets). It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment. +*Why* + Your website's _content strategy_ is important! You need a complete toolkit to deliver an experience that is _optimized_, _fast_ and _relevant_ to your users. Mobile Detect class is a [server-side detection](http://www.w3.org/TR/mwabp/#bp-devcap-detection) tool that can help you with your RWD strategy, it is not a replacement for CSS3 media queries or other forms of client-side feature detection. -We're committed to make Mobile_Detect the best open-source mobile detection resource and this is why before -each release we're running [unit tests](./tests), we also research and update the detection rules on **daily** -and **weekly** basis. +*How* -See also [the history](./docs/HISTORY.md) of the project. +We're committed to make Mobile_Detect the best open-source mobile detection resource and this is why before +each release we're running [unit tests](./tests) and research and update the detection rules on **monthly** basis. -#### Announcements +*Who* -For `2.x` branch we are only integrating new regexes and User-Agents for our tests. -On `2.x` releases we are focusing on **new tablets only**. All the pull requests about TVs, bots or optimizations will -be closed and analyzed after `3.0.0-beta` is released. +See [the history](./docs/HISTORY.md) of the project. -Still working on `3.0.0` branch to provide you with device detection! -We're really excited on this one! -We would like to speed this up, but life and family gets in the way ;) +#### Announcements -Many thanks **JetBrains** team for providing licenses for [PHPStorm](https://www.jetbrains.com/phpstorm/) and +* **JetBrains** is sponsoring the project by providing licenses for [PHPStorm](https://www.jetbrains.com/phpstorm/) and [DataGrip](https://www.jetbrains.com/datagrip/). +* **Mobile_Detect `2.x.x`** is only integrating new regexes, User-Agents and tests. We are focusing on **new tablets only**. +The rest of the PRs about TVs, bots or optimizations will be closed and analyzed after `3.0.0-beta` is released. +* **Mobile_Detect `3.x.x`** is experimental and WIP. + #### Install @@ -77,9 +78,9 @@ or include the dependency in the `composer.json` file: *Donate* -|Pledgie|Paypal| -|-------|------| -|[Donate :+1:](https://pledgie.com/campaigns/21856)|[Donate :beer:](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=mobiledetectlib%40gmail%2ecom&lc=US&item_name=Mobile%20Detect¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted)| +|Paypal| +|------| +|[Donate :+1:](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=mobiledetectlib%40gmail%2ecom&lc=US&item_name=Mobile%20Detect¤cy_code=USD&bn=PP%2dDonationsBF%3abtn_donate_SM%2egif%3aNonHosted)| I'm currently paying for hosting and spend a lot of my family time to maintain the project and planning the future releases. @@ -139,6 +140,16 @@ Mobile attributes include type of device, Operating System, Browser, etc. Exampl .is-tablet, .is-ios, .is-not-ios, .is-androidos, .is-chromebrowser. Made by [wescleveland56](https://github.com/wescleveland56). +* [Adaptive Content](https://wordpress.org/plugins/addfunc-adaptive-content/) for WordPress provides the most +intuitive set of shortcodes for including/excluding content on mobile devices, tablets desktops and other +more specific device parameters. This lightweight plugin lets content writers and theme authors choose when +WordPress should or shouldn’t show any give content item using shortcodes and quicktags or theme elements using functions. +Made by [AddFunc](https://profiles.wordpress.org/addfunc). + +* [AddFunc Mobile Detect](https://wordpress.org/plugins/addfunc-mobile-detect/) for WordPress redirects +mobile traffic to your mobile website and, basically, gives you loads of control over your mobile redirects. +Made by [AddFunc](https://profiles.wordpress.org/addfunc). + **Drupal** * [Drupal Mobile Switch](https://www.drupal.org/project/mobile_switch) - The Mobile Switch Drupal module provides a @@ -282,9 +293,13 @@ Made by [quentin389](https://github.com/quentin389). * [LJ Mobile Detect](https://github.com/lewisjenkins/craft-lj-mobiledetect) is a simple implementation of Mobile Detect for Craft CMS. Made by [Lewis Jenkins](https://github.com/lewisjenkins). +* [Detect Craft](https://github.com/mmikkel/Detect-Craft) is a Craft CMS wrapper for the Mobile_Detect library. Made by [Mikkel Rummelhoff](https://github.com/mmikkel). + * [Grav Plugin Mobile Detect](https://github.com/dimitrilongo/grav-plugin-mobile-detect/) is a simple implementation of Mobile Detect for Grav CMS. Made by [Dimitri Longo](https://github.com/dimitrilongo). +* [Mobile_Detect module for UliCMS](https://github.com/derUli/ulicms-Mobile_Detect). +Made by [derUli](https://github.com/derUli). **Perl** @@ -318,3 +333,12 @@ Made by [Frédéric Robinet](https://github.com/robinef). * [mobile-detect](https://github.com/validide/mobile-detect) is a .Net partial port written in C#. Made by [Valentin Dide](https://github.com/validide). + +**ColdFusion** + +* [MobileDetect](https://github.com/GiancarloGomez/ColdFusion-MobileDetect) is a CFC port of the +Mobile_Detect PHP Library. Made by [Giancarlo Gomez](https://github.com/GiancarloGomez). + +**Experiments** :bulb: + +* [Mobile Detect Fast](https://bitbucket.org/lanaguani/mobile-detect-fast/) (See: [#474](https://github.com/serbanghita/Mobile-Detect/issues/474)) is a class to increase the performance of Mobile Detect lib. Made by [LanaGuani](https://github.com/lanaguanifw). diff --git a/app/vendor/mobiledetect/mobiledetectlib/composer.json b/app/vendor/mobiledetect/mobiledetectlib/composer.json index 671738768..25cd99a37 100644 --- a/app/vendor/mobiledetect/mobiledetectlib/composer.json +++ b/app/vendor/mobiledetect/mobiledetectlib/composer.json @@ -24,5 +24,8 @@ "psr-0": { "Detection": "namespaced/" } + }, + "archive": { + "exclude": ["docs", "examples", "export"] } } diff --git a/app/vendor/mobiledetect/mobiledetectlib/docs/KNOWN_LIMITATIONS.md b/app/vendor/mobiledetect/mobiledetectlib/docs/KNOWN_LIMITATIONS.md index df31cfe68..8b5d461fe 100644 --- a/app/vendor/mobiledetect/mobiledetectlib/docs/KNOWN_LIMITATIONS.md +++ b/app/vendor/mobiledetect/mobiledetectlib/docs/KNOWN_LIMITATIONS.md @@ -1,10 +1,11 @@ **Known limitations** -* User-Agent and HTTP headers sniffing is overall a non reliable method of detecting a mobile device. +* Mobile Detect script was designed to detect `mobile` devices. Implicitly other devices are considered to be `desktop`. +* User-Agent and HTTP headers sniffing is a non reliable method of detecting a mobile device. * If the mobile browser is set on `Desktop mode`, the Mobile Detect script has no way of knowing that the device is `mobile`. -* There are hundreds of devices launched every month, we cannot keep a 100% up to date detection rate. * Some touchscreen devices (eg. Microsoft Surface) are tough to detect as mobile since they can be used in a laptop mode. * Detecting the device brand (eg. Apple, Samsung, HTC) is not 100% reliable. -* We don't monitor the quality of the 3rd party tools based on Mobile Detect script. We cannot guarantee that they are using -the class properly or if they provide the latest version. +* We don't monitor the quality of the 3rd party tools based on Mobile Detect script. +We cannot guarantee that they are using the class properly or if they provide the latest version. * Version `2.x` is made to be PHP 5.3 compatible because of the backward compatibility changes of PHP. +* There are hundreds of devices launched every month, we cannot keep a 100% up to date detection rate. \ No newline at end of file diff --git a/app/vendor/mobiledetect/mobiledetectlib/phpcs.xml b/app/vendor/mobiledetect/mobiledetectlib/phpcs.xml new file mode 100644 index 000000000..3c6666490 --- /dev/null +++ b/app/vendor/mobiledetect/mobiledetectlib/phpcs.xml @@ -0,0 +1,20 @@ + + + The PSR-2 coding standard extended. + + + + + + + + + + error + + + + + + + \ No newline at end of file diff --git a/app/vendor/mobiledetect/mobiledetectlib/ruleset.xml b/app/vendor/mobiledetect/mobiledetectlib/ruleset.xml deleted file mode 100644 index 21462efd9..000000000 --- a/app/vendor/mobiledetect/mobiledetectlib/ruleset.xml +++ /dev/null @@ -1,187 +0,0 @@ - - - The PSR-2 coding standard. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/vendor/nikic/php-parser/.travis.yml b/app/vendor/nikic/php-parser/.travis.yml index 9cd00253e..989d7a049 100644 --- a/app/vendor/nikic/php-parser/.travis.yml +++ b/app/vendor/nikic/php-parser/.travis.yml @@ -7,14 +7,13 @@ cache: - $HOME/.composer/cache php: - - 5.5 - - 5.6 - 7.0 + - 7.1 + - 7.2 - nightly - - hhvm install: - - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then composer require satooshi/php-coveralls '~1.0'; fi + - if [ $TRAVIS_PHP_VERSION = '7.0' ]; then composer require satooshi/php-coveralls '~1.0'; fi - composer install --prefer-dist matrix: @@ -23,9 +22,8 @@ matrix: fast_finish: true script: - - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then vendor/bin/phpunit --coverage-clover build/logs/clover.xml; else vendor/bin/phpunit; fi - - if [ $TRAVIS_PHP_VERSION = '7.0' ]; then test_old/run-php-src.sh; fi + - if [ $TRAVIS_PHP_VERSION = '7.0' ]; then vendor/bin/phpunit --coverage-clover build/logs/clover.xml; else vendor/bin/phpunit; fi + - if [ $TRAVIS_PHP_VERSION = '7.1' ]; then test_old/run-php-src.sh; fi after_success: - if [ $TRAVIS_PHP_VERSION = '5.6' ]; then php vendor/bin/coveralls; fi - + - if [ $TRAVIS_PHP_VERSION = '7.0' ]; then php vendor/bin/coveralls; fi diff --git a/app/vendor/nikic/php-parser/CHANGELOG.md b/app/vendor/nikic/php-parser/CHANGELOG.md index dcec1ff38..70d85e557 100644 --- a/app/vendor/nikic/php-parser/CHANGELOG.md +++ b/app/vendor/nikic/php-parser/CHANGELOG.md @@ -1,8 +1,185 @@ -Version 3.1.5-dev +Version 4.0.5-dev ----------------- Nothing yet. +Version 4.0.4 (2018-09-18) +-------------------------- + +### Added + +* The following methods have been added to `BuilderFactory`: + * `useTrait()` (fluent builder) + * `traitUseAdaptation()` (fluent builder) + * `useFunction()` (fluent builder) + * `useConst()` (fluent builder) + * `var()` + * `propertyFetch()` + +### Deprecated + +* `Builder\Param::setTypeHint()` has been deprecated in favor of the newly introduced + `Builder\Param::setType()`. + +Version 4.0.3 (2018-07-15) +-------------------------- + +### Fixed + +* Fixed possible undefined offset notice in formatting-preserving printer. (#513) + +### Added + +* Improved error recovery inside arrays. +* Preserve trailing comment inside classes. **Note:** This change is possibly BC breaking if your + code validates that classes can only contain certain statement types. After this change, classes + can also contain Nop statements, while this was not previously possible. (#509) + +Version 4.0.2 (2018-06-03) +-------------------------- + +### Added + +* Improved error recovery inside classes. +* Support error recovery for `foreach` without `as`. +* Support error recovery for parameters without variable (`function (Type ) {}`). +* Support error recovery for functions without body (`function ($foo)`). + +Version 4.0.1 (2018-03-25) +-------------------------- + +### Added + +* [PHP 7.3] Added support for trailing commas in function calls. +* [PHP 7.3] Added support for by-reference array destructuring. +* Added checks to node traverser to prevent replacing a statement with an expression or vice versa. + This should prevent common mistakes in the implementation of node visitors. +* Added the following methods to `BuilderFactory`, to simplify creation of expressions: + * `funcCall()` + * `methodCall()` + * `staticCall()` + * `new()` + * `constFetch()` + * `classConstFetch()` + +Version 4.0.0 (2018-02-28) +-------------------------- + +* No significant code changes since the beta 1 release. + +Version 4.0.0-beta1 (2018-01-27) +-------------------------------- + +### Fixed + +* In formatting-preserving pretty printer: Fixed indentation when inserting into lists. (#466) + +### Added + +* In formatting-preserving pretty printer: Improved formatting of elements inserted into multi-line + arrays. + +### Removed + +* The `Autoloader` class has been removed. It is now required to use the Composer autoloader. + +Version 4.0.0-alpha3 (2017-12-26) +--------------------------------- + +### Fixed + +* In the formatting-preserving pretty printer: + * Fixed comment indentation. + * Fixed handling of inline HTML in the fallback case. + * Fixed insertion into list nodes that require creation of a code block. + +### Added + +* Added support for inserting at the start of list nodes in formatting-preserving pretty printer. + +Version 4.0.0-alpha2 (2017-11-10) +--------------------------------- + +### Added + +* In the formatting-preserving pretty printer: + * Added support for changing modifiers. + * Added support for anonymous classes. + * Added support for removing from list nodes. + * Improved support for changing comments. +* Added start token offsets to comments. + +Version 4.0.0-alpha1 (2017-10-18) +--------------------------------- + +### Added + +* Added experimental support for format-preserving pretty-printing. In this mode formatting will be + preserved for parts of the code which have not been modified. +* Added `replaceNodes` option to `NameResolver`, defaulting to true. If this option is disabled, + resolved names will be added as `resolvedName` attributes, instead of replacing the original + names. +* Added `NodeFinder` class, which can be used to find nodes based on a callback or class name. This + is a utility to avoid custom node visitor implementations for simple search operations. +* Added `ClassMethod::isMagic()` method. +* Added `BuilderFactory` methods: `val()` method for creating an AST for a simple value, `concat()` + for creating concatenation trees, `args()` for preparing function arguments. +* Added `NameContext` class, which encapsulates the `NameResolver` logic independently of the actual + AST traversal. This facilitates use in other context, such as class names in doc comments. + Additionally it provides an API for getting the shortest representation of a name. +* Added `Node::setAttributes()` method. +* Added `JsonDecoder`. This allows conversion JSON back into an AST. +* Added `Name` methods `toLowerString()` and `isSpecialClassName()`. +* Added `Identifier` and `VarLikeIdentifier` nodes, which are used in place of simple strings in + many places. +* Added `getComments()`, `getStartLine()`, `getEndLine()`, `getStartTokenPos()`, `getEndTokenPos()`, + `getStartFilePos()` and `getEndFilePos()` methods to `Node`. These provide a more obvious access + point for the already existing attributes of the same name. +* Added `ConstExprEvaluator` to evaluate constant expressions to PHP values. +* Added `Expr\BinaryOp::getOperatorSigil()`, returning `+` for `Expr\BinaryOp\Plus`, etc. + +### Changed + +* Many subnodes that previously held simple strings now use `Identifier` (or `VarLikeIdentifier`) + nodes. Please see the UPGRADE-4.0 file for an exhaustive list of affected nodes and some notes on + possible impact. +* Expression statements (`expr;`) are now represented using a `Stmt\Expression` node. Previously + these statements were directly represented as their constituent expression. +* The `name` subnode of `Param` has been renamed to `var` and now contains a `Variable` rather than + a plain string. +* The `name` subnode of `StaticVar` has been renamed to `var` and now contains a `Variable` rather + than a plain string. +* The `var` subnode of `ClosureUse` now contains a `Variable` rather than a plain string. +* The `var` subnode of `Catch` now contains a `Variable` rather than a plain string. +* The `alias` subnode of `UseUse` is now `null` if no explicit alias is given. As such, + `use Foo\Bar` and `use Foo\Bar as Bar` are now represented differently. The `getAlias()` method + can be used to get the effective alias, even if it is not explicitly given. + +### Removed + +* Support for running on PHP 5 and HHVM has been removed. You can however still parse code of old + PHP versions (such as PHP 5.2), while running on PHP 7. +* Removed `type` subnode on `Class`, `ClassMethod` and `Property` nodes. Use `flags` instead. +* The `ClassConst::isStatic()` method has been removed. Constants cannot have a static modifier. +* The `NodeTraverser` no longer accepts `false` as a return value from a `leaveNode()` method. + `NodeTraverser::REMOVE_NODE` should be returned instead. +* The `Node::setLine()` method has been removed. If you really need to, you can use `setAttribute()` + instead. +* The misspelled `Class_::VISIBILITY_MODIFER_MASK` constant has been dropped in favor of + `Class_::VISIBILITY_MODIFIER_MASK`. +* The XML serializer has been removed. As such, the classes `Serializer\XML`, and + `Unserializer\XML`, as well as the interfaces `Serializer` and `Unserializer` no longer exist. +* The `BuilderAbstract` class has been removed. It's functionality is moved into `BuilderHelpers`. + However, this is an internal class and should not be used directly. + +Version 3.1.5 (2018-02-28) +-------------------------- + +### Fixed + +* Fixed duplicate comment assignment in switch statements. (#469) +* Improve compatibility with PHP-Scoper. (#477) + Version 3.1.4 (2018-01-25) -------------------------- @@ -47,7 +224,7 @@ Version 3.1.0 (2017-07-28) * [PHP 7.2] Added support for trailing comma in group use statements. * [PHP 7.2] Added support for `object` type. This means `object` types will now be represented as a builtin type (a simple `"object"` string), rather than a class `Name`. - + ### Fixed * Floating-point numbers are now printed correctly if the LC_NUMERIC locale uses a comma as decimal @@ -167,7 +344,7 @@ This release primarily improves our support for error recovery. `NameResolver::__construct()`. * The `NameResolver` now adds a `namespacedName` attribute on name nodes that cannot be statically resolved (unqualified unaliased function or constant names in namespaces). - + ### Fixed * Fixed attribute assignment for `GroupUse` prefix and variables in interpolated strings. @@ -257,7 +434,7 @@ Additionally the following changes were made: takes an array of subnodes. Unlike classes/interfaces, traits can only have a `stmts` subnode. * The `NodeDumper` now prints class/method/property/constant modifiers, as well as the include and use type in a textual representation, instead of only showing the number. -* All methods on `PrettyPrinter\Standard` are now protected. Previoulsy most of them were public. +* All methods on `PrettyPrinter\Standard` are now protected. Previously most of them were public. ### Removed @@ -295,7 +472,7 @@ Version 2.1.0 (2016-04-19) * Added `kind` attribute to `Expr\Exit` to distinguish between `exit` and `die`. * Added `kind` attribute to `Scalar\LNumber` to distinguish between decimal, binary, octal and hexadecimal numbers. -* Added `kind` attribtue to `Expr\Array` to distinguish between `array()` and `[]`. +* Added `kind` attribute to `Expr\Array` to distinguish between `array()` and `[]`. * Added `kind` attribute to `Scalar\String` and `Scalar\Encapsed` to distinguish between single-quoted, double-quoted, heredoc and nowdoc string. * Added `docLabel` attribute to `Scalar\String` and `Scalar\Encapsed`, if it is a heredoc or @@ -411,4 +588,4 @@ A more detailed description of backwards incompatible changes can be found in th **This changelog only includes changes from the 2.0 series. For older changes see the [1.x series changelog](https://github.com/nikic/PHP-Parser/blob/1.x/CHANGELOG.md) and the -[0.9 series changelog](https://github.com/nikic/PHP-Parser/blob/0.9/CHANGELOG.md).** \ No newline at end of file +[0.9 series changelog](https://github.com/nikic/PHP-Parser/blob/0.9/CHANGELOG.md).** diff --git a/app/vendor/nikic/php-parser/README.md b/app/vendor/nikic/php-parser/README.md index 2f62754ce..5fea5c906 100644 --- a/app/vendor/nikic/php-parser/README.md +++ b/app/vendor/nikic/php-parser/README.md @@ -3,97 +3,223 @@ PHP Parser [![Build Status](https://travis-ci.org/nikic/PHP-Parser.svg?branch=master)](https://travis-ci.org/nikic/PHP-Parser) [![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master) -This is a PHP 5.2 to PHP 7.1 parser written in PHP. Its purpose is to simplify static code analysis and +This is a PHP 5.2 to PHP 7.2 parser written in PHP. Its purpose is to simplify static code analysis and manipulation. -[**Documentation for version 3.x**][doc_master] (stable; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.1). +[**Documentation for version 4.x**][doc_master] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 7.2). -[Documentation for version 2.x][doc_2_x] (stable; for running on PHP >= 5.4; for parsing PHP 5.2 to PHP 7.0). +[Documentation for version 3.x][doc_3_x] (unsupported; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2). -[Documentation for version 1.x][doc_1_x] (unsupported; for running on PHP >= 5.3; for parsing PHP 5.2 to PHP 5.6). +Features +-------- -In a Nutshell -------------- +The main features provided by this library are: + + * Parsing PHP 5 and PHP 7 code into an abstract syntax tree (AST). + * Invalid code can be parsed into a partial AST. + * The AST contains accurate location information. + * Dumping the AST in human-readable form. + * Converting an AST back to PHP code. + * Experimental: Formatting can be preserved for partially changed ASTs. + * Infrastructure to traverse and modify ASTs. + * Resolution of namespaced names. + * Evaluation of constant expressions. + * Builders to simplify AST construction for code generation. + * Converting an AST into JSON and back. + +Quick Start +----------- + +Install the library using [composer](https://getcomposer.org): + + php composer.phar require nikic/php-parser -The parser turns PHP source code into an abstract syntax tree. For example, if you pass the following code into the -parser: +Parse some PHP code into an AST and dump the result in human-readable form: ```php create(ParserFactory::PREFER_PHP7); +try { + $ast = $parser->parse($code); +} catch (Error $error) { + echo "Parse error: {$error->getMessage()}\n"; + return; +} + +$dumper = new NodeDumper; +echo $dumper->dump($ast) . "\n"; ``` -You'll get a syntax tree looking roughly like this: +This dumps an AST looking something like this: -```php +``` array( - 0: Stmt_Echo( - exprs: array( - 0: Scalar_String( - value: Hi - ) - 1: Scalar_String( - value: World - ) - ) - ) - 1: Expr_FuncCall( - name: Name( - parts: array( - 0: hello - 1: world - ) + 0: Stmt_Function( + byRef: false + name: Identifier( + name: test ) - args: array( - 0: Arg( - value: Scalar_String( - value: foo - ) + params: array( + 0: Param( + type: null byRef: false + variadic: false + var: Expr_Variable( + name: foo + ) + default: null ) - 1: Arg( - value: Expr_Concat( - left: Scalar_String( - value: bar + ) + returnType: null + stmts: array( + 0: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: var_dump + ) ) - right: Scalar_String( - value: baz + args: array( + 0: Arg( + value: Expr_Variable( + name: foo + ) + byRef: false + unpack: false + ) ) ) + ) + ) + ) +) +``` + +Let's traverse the AST and perform some kind of modification. For example, drop all function bodies: + +```php +use PhpParser\Node; +use PhpParser\Node\Stmt\Function_; +use PhpParser\NodeTraverser; +use PhpParser\NodeVisitorAbstract; + +$traverser = new NodeTraverser(); +$traverser->addVisitor(new class extends NodeVisitorAbstract { + public function enterNode(Node $node) { + if ($node instanceof Function_) { + // Clean out the function body + $node->stmts = []; + } + } +}); + +$ast = $traverser->traverse($ast); +echo $dumper->dump($ast) . "\n"; +``` + +This gives us an AST where the `Function_::$stmts` are empty: + +``` +array( + 0: Stmt_Function( + byRef: false + name: Identifier( + name: test + ) + params: array( + 0: Param( + type: null byRef: false + variadic: false + var: Expr_Variable( + name: foo + ) + default: null ) ) + returnType: null + stmts: array( + ) ) ) ``` -You can then work with this syntax tree, for example to statically analyze the code (e.g. to find -programming errors or security issues). +Finally, we can convert the new AST back to PHP code: -Additionally, you can convert a syntax tree back to PHP code. This allows you to do code preprocessing -(like automatedly porting code to older PHP versions). +```php +use PhpParser\PrettyPrinter; -Installation ------------- +$prettyPrinter = new PrettyPrinter\Standard; +echo $prettyPrinter->prettyPrintFile($ast); +``` -The preferred installation method is [composer](https://getcomposer.org): +This gives us our original code, minus the `var_dump()` call inside the function: - php composer.phar require nikic/php-parser +```php +nl`. + +### Removed functionality + +* Removed `type` subnode on `Class_`, `ClassMethod` and `Property` nodes. Use `flags` instead. +* The `ClassConst::isStatic()` method has been removed. Constants cannot have a static modifier. +* The `NodeTraverser` no longer accepts `false` as a return value from a `leaveNode()` method. + `NodeTraverser::REMOVE_NODE` should be returned instead. +* The `Node::setLine()` method has been removed. If you really need to, you can use `setAttribute()` + instead. +* The misspelled `Class_::VISIBILITY_MODIFER_MASK` constant has been dropped in favor of + `Class_::VISIBILITY_MODIFIER_MASK`. +* The XML serializer has been removed. As such, the classes `Serializer\XML`, and + `Unserializer\XML`, as well as the interfaces `Serializer` and `Unserializer` no longer exist. +* The `BuilderAbstract` class has been removed. It's functionality is moved into `BuilderHelpers`. + However, this is an internal class and should not be used directly. +* The `Autoloader` class has been removed in favor of relying on the Composer autoloader. diff --git a/app/vendor/nikic/php-parser/bin/php-parse b/app/vendor/nikic/php-parser/bin/php-parse index 1760e758d..5dd01ba17 100755 --- a/app/vendor/nikic/php-parser/bin/php-parse +++ b/app/vendor/nikic/php-parser/bin/php-parse @@ -26,9 +26,9 @@ if (empty($files)) { showHelp("Must specify at least one file."); } -$lexer = new PhpParser\Lexer\Emulative(array('usedAttributes' => array( +$lexer = new PhpParser\Lexer\Emulative(['usedAttributes' => [ 'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments' -))); +]]); $parser = (new PhpParser\ParserFactory)->create( PhpParser\ParserFactory::PREFER_PHP7, $lexer @@ -38,7 +38,6 @@ $dumper = new PhpParser\NodeDumper([ 'dumpPositions' => $attributes['with-positions'], ]); $prettyPrinter = new PhpParser\PrettyPrinter\Standard; -$serializer = new PhpParser\Serializer\XML; $traverser = new PhpParser\NodeTraverser(); $traverser->addVisitor(new PhpParser\NodeVisitor\NameResolver); @@ -82,9 +81,9 @@ foreach ($files as $file) { } elseif ('pretty-print' === $operation) { echo "==> Pretty print:\n"; echo $prettyPrinter->prettyPrintFile($stmts), "\n"; - } elseif ('serialize-xml' === $operation) { - echo "==> Serialized XML:\n"; - echo $serializer->serialize($stmts), "\n"; + } elseif ('json-dump' === $operation) { + echo "==> JSON dump:\n"; + echo json_encode($stmts, JSON_PRETTY_PRINT), "\n"; } elseif ('var-dump' === $operation) { echo "==> var_dump():\n"; var_dump($stmts); @@ -116,7 +115,7 @@ Operations is a list of the following options (--dump by default): -d, --dump Dump nodes using NodeDumper -p, --pretty-print Pretty print file using PrettyPrinter\Standard - --serialize-xml Serialize nodes using Serializer\XML + -j, --json-dump Print json_encode() result --var-dump var_dump() nodes (for exact structure) -N, --resolve-names Resolve names using NodeVisitor\NameResolver -c, --with-column-info Show column-numbers for errors (if available) @@ -135,13 +134,13 @@ OUTPUT } function parseArgs($args) { - $operations = array(); - $files = array(); - $attributes = array( + $operations = []; + $files = []; + $attributes = [ 'with-column-info' => false, 'with-positions' => false, 'with-recovery' => false, - ); + ]; array_shift($args); $parseOptions = true; @@ -160,8 +159,9 @@ function parseArgs($args) { case '-p': $operations[] = 'pretty-print'; break; - case '--serialize-xml': - $operations[] = 'serialize-xml'; + case '--json-dump': + case '-j': + $operations[] = 'json-dump'; break; case '--var-dump': $operations[] = 'var-dump'; @@ -198,5 +198,5 @@ function parseArgs($args) { } } - return array($operations, $files, $attributes); + return [$operations, $files, $attributes]; } diff --git a/app/vendor/nikic/php-parser/composer.json b/app/vendor/nikic/php-parser/composer.json index 66df90a8f..7ae425ff7 100644 --- a/app/vendor/nikic/php-parser/composer.json +++ b/app/vendor/nikic/php-parser/composer.json @@ -10,11 +10,11 @@ } ], "require": { - "php": ">=5.5", + "php": ">=7.0", "ext-tokenizer": "*" }, "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" + "phpunit/phpunit": "^6.5 || ^7.0" }, "autoload": { "psr-4": { @@ -24,7 +24,7 @@ "bin": ["bin/php-parse"], "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } } } diff --git a/app/vendor/nikic/php-parser/doc/0_Introduction.markdown b/app/vendor/nikic/php-parser/doc/0_Introduction.markdown index ca1ceb2ec..240f7fdea 100644 --- a/app/vendor/nikic/php-parser/doc/0_Introduction.markdown +++ b/app/vendor/nikic/php-parser/doc/0_Introduction.markdown @@ -1,7 +1,7 @@ Introduction ============ -This project is a PHP 5.2 to PHP 7.1 parser **written in PHP itself**. +This project is a PHP 5.2 to PHP 7.2 parser **written in PHP itself**. What is this for? ----------------- @@ -14,7 +14,7 @@ There are other ways of processing source code. One that PHP supports natively i token stream generated by [`token_get_all`][2]. The token stream is much more low level than the AST and thus has different applications: It allows to also analyze the exact formatting of a file. On the other hand the token stream is much harder to deal with for more complex analysis. -For example an AST abstracts away the fact that in PHP variables can be written as `$foo`, but also +For example, an AST abstracts away the fact that, in PHP, variables can be written as `$foo`, but also as `$$bar`, `${'foobar'}` or even `${!${''}=barfoo()}`. You don't have to worry about recognizing all the different syntaxes from a stream of tokens. @@ -26,17 +26,17 @@ programmatic PHP code analysis are incidentally PHP developers, not C developers What can it parse? ------------------ -The parser supports parsing PHP 5.2-5.6 and PHP 7. +The parser supports parsing PHP 5.2-7.2. As the parser is based on the tokens returned by `token_get_all` (which is only able to lex the PHP version it runs on), additionally a wrapper for emulating tokens from newer versions is provided. -This allows to parse PHP 7.1 source code running on PHP 5.5, for example. This emulation is somewhat +This allows to parse PHP 7.2 source code running on PHP 5.5, for example. This emulation is somewhat hacky and not perfect, but it should work well on any sane code. What output does it produce? ---------------------------- -The parser produces an [Abstract Syntax Tree][1] (AST) also known as a node tree. How this looks like +The parser produces an [Abstract Syntax Tree][1] (AST) also known as a node tree. How this looks can best be seen in an example. The program `create(ParserFactory::PREFER_PHP7); try { @@ -66,27 +74,68 @@ try { A parser instance can be reused to parse multiple files. -Node tree ---------- +Node dumping +------------ + +To dump the abstact syntax tree in human readable form, a `NodeDumper` can be used: + +```php +dump($stmts), "\n"; +``` -If you use the above code with `$code = " PhpParser\Node\Stmt\Function_` + * `Stmt_Expression -> PhpParser\Node\Stmt\Expression` + +The additional `_` at the end of the first class name is necessary, because `Function` is a +reserved keyword. Many node class names in this library have a trailing `_` to avoid clashing with +a keyword. + +As PHP is a large language there are approximately 140 different nodes. In order to make working with them easier they are grouped into three categories: * `PhpParser\Node\Stmt`s are statement nodes, i.e. language constructs that do not return @@ -113,8 +182,9 @@ with them easier they are grouped into three categories: * There are some nodes not in either of these groups, for example names (`PhpParser\Node\Name`) and call arguments (`PhpParser\Node\Arg`). -Some node class names have a trailing `_`. This is used whenever the class name would otherwise clash -with a PHP keyword. +The `Node\Stmt\Expression` node is somewhat confusing in that it contains both the terms "statement" +and "expression". This node distinguishes `expr`, which is a `Node\Expr`, from `expr;`, which is +an "expression statement" represented by `Node\Stmt\Expression` and containing `expr` as a sub-node. Every node has a (possibly zero) number of subnodes. You can access subnodes by writing `$node->subNodeName`. The `Stmt\Echo_` node has only one subnode `exprs`. So in order to access it @@ -173,7 +243,7 @@ try { The above code will output: - parse()`, then changed and then again converted to code using `PhpParser\PrettyPrinter\Standard->prettyPrint()`. @@ -184,6 +254,8 @@ single expression using `prettyPrintExpr()`. The `prettyPrintFile()` method can be used to print an entire file. This will include the opening ` Read more: [Pretty printing documentation](component/Pretty_printing.markdown) + Node traversation ----------------- @@ -278,10 +350,12 @@ be `array(A, X, Y, Z, C)`. Instead of manually implementing the `NodeVisitor` interface you can also extend the `NodeVisitorAbstract` class, which will define empty default implementations for all the above methods. +> Read more: [Walking the AST](component/Walking_the_AST.markdown) + The NameResolver node visitor ----------------------------- -One visitor is already bundled with the package: `PhpParser\NodeVisitor\NameResolver`. This visitor +One visitor that is already bundled with the package is `PhpParser\NodeVisitor\NameResolver`. This visitor helps you work with namespaced code by trying to resolve most names to fully qualified ones. For example, consider the following code: @@ -292,7 +366,7 @@ For example, consider the following code: In order to know that `B\C` really is `A\C` you would need to track aliases and namespaces yourself. The `NameResolver` takes care of that and resolves names as far as possible. -After running it most names will be fully qualified. The only names that will stay unqualified are +After running it, most names will be fully qualified. The only names that will stay unqualified are unqualified function and constant names. These are resolved at runtime and thus the visitor can't know which function they are referring to. In most cases this is a non-issue as the global functions are meant. @@ -300,6 +374,8 @@ are meant. Also the `NameResolver` adds a `namespacedName` subnode to class, function and constant declarations that contains the namespaced name instead of only the shortname that is available via `name`. +> Read more: [Name resolution documentation](component/Name_resolution.markdown) + Example: Converting namespaced code to pseudo namespaces -------------------------------------------------------- @@ -333,7 +409,7 @@ $files = new \RegexIterator($files, '/\.php$/'); foreach ($files as $file) { try { // read the file that should be converted - $code = file_get_contents($file); + $code = file_get_contents($file->getPathName()); // parse $stmts = $parser->parse($code); @@ -365,7 +441,7 @@ class NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { - return new Node\Name($node->toString('_')); + return new Node\Name(str_replace('\\', '_', $node->toString())); } } } @@ -373,7 +449,7 @@ class NamespaceConverter extends \PhpParser\NodeVisitorAbstract The above code profits from the fact that the `NameResolver` already resolved all names as far as possible, so we don't need to do that. We only need to create a string with the name parts separated -by underscores instead of backslashes. This is what `$node->toString('_')` does. (If you want to +by underscores instead of backslashes. This is what `str_replace('\\', '_', $node->toString())` does. (If you want to create a name with backslashes either write `$node->toString()` or `(string) $node`.) Then we create a new name from the string and return it. Returning a new node replaces the old node. @@ -389,14 +465,14 @@ class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { - return new Node\Name($node->toString('_')); + return new Node\Name(str_replace('\\', '_', $node->toString())); } elseif ($node instanceof Stmt\Class_ || $node instanceof Stmt\Interface_ || $node instanceof Stmt\Function_) { - $node->name = $node->namespacedName->toString('_'); + $node->name = str_replace('\\', '_', $node->namespacedName->toString()); } elseif ($node instanceof Stmt\Const_) { foreach ($node->consts as $const) { - $const->name = $const->namespacedName->toString('_'); + $const->name = str_replace('\\', '_', $const->namespacedName->toString()); } } } @@ -410,26 +486,27 @@ The last thing we need to do is remove the `namespace` and `use` statements: ```php use PhpParser\Node; use PhpParser\Node\Stmt; +use PhpParser\NodeTraverser; class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract { public function leaveNode(Node $node) { if ($node instanceof Node\Name) { - return new Node\Name($node->toString('_')); + return new Node\Name(str_replace('\\', '_', $node->toString())); } elseif ($node instanceof Stmt\Class_ || $node instanceof Stmt\Interface_ || $node instanceof Stmt\Function_) { - $node->name = $node->namespacedName->toString('_'); + $node->name = str_replace('\\', '_', $node->namespacedName->toString(); } elseif ($node instanceof Stmt\Const_) { foreach ($node->consts as $const) { - $const->name = $const->namespacedName->toString('_'); + $const->name = str_replace('\\', '_', $const->namespacedName->toString()); } } elseif ($node instanceof Stmt\Namespace_) { // returning an array merges is into the parent array return $node->stmts; } elseif ($node instanceof Stmt\Use_) { - // returning false removed the node altogether - return false; + // remove use nodes altogether + return NodeTraverser::REMOVE_NODE; } } } diff --git a/app/vendor/nikic/php-parser/doc/3_Other_node_tree_representations.markdown b/app/vendor/nikic/php-parser/doc/3_Other_node_tree_representations.markdown deleted file mode 100644 index 0830f399c..000000000 --- a/app/vendor/nikic/php-parser/doc/3_Other_node_tree_representations.markdown +++ /dev/null @@ -1,330 +0,0 @@ -Other node tree representations -=============================== - -It is possible to convert the AST into several textual representations, which serve different uses. - -Simple serialization --------------------- - -It is possible to serialize the node tree using `serialize()` and also unserialize it using -`unserialize()`. The output is not human readable and not easily processable from anything -but PHP, but it is compact and generates quickly. The main application thus is in caching. - -Human readable dumping ----------------------- - -Furthermore it is possible to dump nodes into a human readable format using the `dump` method of -`PhpParser\NodeDumper`. This can be used for debugging. - -```php -$code = <<<'CODE' -create(PhpParser\ParserFactory::PREFER_PHP7); -$nodeDumper = new PhpParser\NodeDumper; - -try { - $stmts = $parser->parse($code); - - echo $nodeDumper->dump($stmts), "\n"; -} catch (PhpParser\Error $e) { - echo 'Parse Error: ', $e->getMessage(); -} -``` - -The above script will have an output looking roughly like this: - -``` -array( - 0: Stmt_Function( - byRef: false - params: array( - 0: Param( - name: msg - default: null - type: null - byRef: false - ) - ) - stmts: array( - 0: Stmt_Echo( - exprs: array( - 0: Expr_Variable( - name: msg - ) - 1: Scalar_String( - value: - - ) - ) - ) - ) - name: printLine - ) - 1: Expr_FuncCall( - name: Name( - parts: array( - 0: printLine - ) - ) - args: array( - 0: Arg( - value: Scalar_String( - value: Hello World!!! - ) - byRef: false - ) - ) - ) -) -``` - -JSON encoding -------------- - -Nodes (and comments) implement the `JsonSerializable` interface. As such, it is possible to JSON -encode the AST directly using `json_encode()`: - -```php -$code = <<<'CODE' -create(PhpParser\ParserFactory::PREFER_PHP7); -$nodeDumper = new PhpParser\NodeDumper; - -try { - $stmts = $parser->parse($code); - - echo json_encode($stmts, JSON_PRETTY_PRINT), "\n"; -} catch (PhpParser\Error $e) { - echo 'Parse Error: ', $e->getMessage(); -} -``` - -This will result in the following output (which includes attributes): - -```json -[ - { - "nodeType": "Stmt_Function", - "byRef": false, - "name": "printLine", - "params": [ - { - "nodeType": "Param", - "type": null, - "byRef": false, - "variadic": false, - "name": "msg", - "default": null, - "attributes": { - "startLine": 3, - "endLine": 3 - } - } - ], - "returnType": null, - "stmts": [ - { - "nodeType": "Stmt_Echo", - "exprs": [ - { - "nodeType": "Expr_Variable", - "name": "msg", - "attributes": { - "startLine": 4, - "endLine": 4 - } - }, - { - "nodeType": "Scalar_String", - "value": "\n", - "attributes": { - "startLine": 4, - "endLine": 4, - "kind": 2 - } - } - ], - "attributes": { - "startLine": 4, - "endLine": 4 - } - } - ], - "attributes": { - "startLine": 3, - "endLine": 5 - } - }, - { - "nodeType": "Expr_FuncCall", - "name": { - "nodeType": "Name", - "parts": [ - "printLine" - ], - "attributes": { - "startLine": 7, - "endLine": 7 - } - }, - "args": [ - { - "nodeType": "Arg", - "value": { - "nodeType": "Scalar_String", - "value": "Hello World!!!", - "attributes": { - "startLine": 7, - "endLine": 7, - "kind": 1 - } - }, - "byRef": false, - "unpack": false, - "attributes": { - "startLine": 7, - "endLine": 7 - } - } - ], - "attributes": { - "startLine": 7, - "endLine": 7 - } - } -] -``` - -There is currently no mechanism to convert JSON back into a node tree. Furthermore, not all ASTs -can be JSON encoded. In particular, JSON only supports UTF-8 strings. - -Serialization to XML --------------------- - -It is also possible to serialize the node tree to XML using `PhpParser\Serializer\XML->serialize()` -and to unserialize it using `PhpParser\Unserializer\XML->unserialize()`. This is useful for -interfacing with other languages and applications or for doing transformation using XSLT. - -```php -create(PhpParser\ParserFactory::PREFER_PHP7); -$serializer = new PhpParser\Serializer\XML; - -try { - $stmts = $parser->parse($code); - - echo $serializer->serialize($stmts); -} catch (PhpParser\Error $e) { - echo 'Parse Error: ', $e->getMessage(); -} -``` - -Produces: - -```xml - - - - - - - - - - - - msg - - - - - - - - - - - - - - - - - - - - - msg - - - - - - - - - - - - - - - printLine - - - - - - - - printLine - - - - - - - - - - - Hello World!!! - - - - - - - - - - - - -``` \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/doc/4_Code_generation.markdown b/app/vendor/nikic/php-parser/doc/4_Code_generation.markdown deleted file mode 100644 index 2c0aa0ede..000000000 --- a/app/vendor/nikic/php-parser/doc/4_Code_generation.markdown +++ /dev/null @@ -1,84 +0,0 @@ -Code generation -=============== - -It is also possible to generate code using the parser, by first creating an Abstract Syntax Tree and then using the -pretty printer to convert it to PHP code. To simplify code generation, the project comes with builders which allow -creating node trees using a fluid interface, instead of instantiating all nodes manually. Builders are available for -the following syntactic elements: - - * namespaces and use statements - * classes, interfaces and traits - * methods, functions and parameters - * properties - -Here is an example: - -```php -use PhpParser\BuilderFactory; -use PhpParser\PrettyPrinter; -use PhpParser\Node; - -$factory = new BuilderFactory; -$node = $factory->namespace('Name\Space') - ->addStmt($factory->use('Some\Other\Thingy')->as('SomeOtherClass')) - ->addStmt($factory->class('SomeClass') - ->extend('SomeOtherClass') - ->implement('A\Few', '\Interfaces') - ->makeAbstract() // ->makeFinal() - - ->addStmt($factory->method('someMethod') - ->makePublic() - ->makeAbstract() // ->makeFinal() - ->setReturnType('bool') - ->addParam($factory->param('someParam')->setTypeHint('SomeClass')) - ->setDocComment('/** - * This method does something. - * - * @param SomeClass And takes a parameter - */') - ) - - ->addStmt($factory->method('anotherMethod') - ->makeProtected() // ->makePublic() [default], ->makePrivate() - ->addParam($factory->param('someParam')->setDefault('test')) - // it is possible to add manually created nodes - ->addStmt(new Node\Expr\Print_(new Node\Expr\Variable('someParam'))) - ) - - // properties will be correctly reordered above the methods - ->addStmt($factory->property('someProperty')->makeProtected()) - ->addStmt($factory->property('anotherProperty')->makePrivate()->setDefault(array(1, 2, 3))) - ) - - ->getNode() -; - -$stmts = array($node); -$prettyPrinter = new PrettyPrinter\Standard(); -echo $prettyPrinter->prettyPrintFile($stmts); -``` - -This will produce the following output with the standard pretty printer: - -```php -namespace('Name\Space') + ->addStmt($factory->use('Some\Other\Thingy')->as('SomeClass')) + ->addStmt($factory->useFunction('strlen')) + ->addStmt($factory->useConst('PHP_VERSION')) + ->addStmt($factory->class('SomeOtherClass') + ->extend('SomeClass') + ->implement('A\Few', '\Interfaces') + ->makeAbstract() // ->makeFinal() + + ->addStmt($factory->useTrait('FirstTrait')) + + ->addStmt($factory->useTrait('SecondTrait', 'ThirdTrait') + ->and('AnotherTrait') + ->with($factory->traitUseAdaptation('foo')->as('bar')) + ->with($factory->traitUseAdaptation('AnotherTrait', 'baz')->as('test')) + ->with($factory->traitUseAdaptation('AnotherTrait', 'func')->insteadof('SecondTrait'))) + + ->addStmt($factory->method('someMethod') + ->makePublic() + ->makeAbstract() // ->makeFinal() + ->setReturnType('bool') // ->makeReturnByRef() + ->addParam($factory->param('someParam')->setTypeHint('SomeClass')) + ->setDocComment('/** + * This method does something. + * + * @param SomeClass And takes a parameter + */') + ) + + ->addStmt($factory->method('anotherMethod') + ->makeProtected() // ->makePublic() [default], ->makePrivate() + ->addParam($factory->param('someParam')->setDefault('test')) + // it is possible to add manually created nodes + ->addStmt(new Node\Expr\Print_(new Node\Expr\Variable('someParam'))) + ) + + // properties will be correctly reordered above the methods + ->addStmt($factory->property('someProperty')->makeProtected()) + ->addStmt($factory->property('anotherProperty')->makePrivate()->setDefault(array(1, 2, 3))) + ) + + ->getNode() +; + +$stmts = array($node); +$prettyPrinter = new PrettyPrinter\Standard(); +echo $prettyPrinter->prettyPrintFile($stmts); +``` + +This will produce the following output with the standard pretty printer: + +```php +evaluateSilently($someExpr); +} catch (ConstExprEvaluationException $e) { + // Either the expression contains unsupported expression types, + // or an error occurred during evaluation +} +``` + +Error handling +-------------- + +The constant evaluator provides two methods, `evaluateDirectly()` and `evaluateSilently()`, which +differ in error behavior. `evaluateDirectly()` will evaluate the expression as PHP would, including +any generated warnings or Errors. `evaluateSilently()` will instead convert warnings and Errors into +a `ConstExprEvaluationException`. For example: + +```php +evaluateDirectly($expr)); // float(INF) +// Warning: Division by zero + +try { + $evaluator->evaluateSilently($expr); +} catch (ConstExprEvaluationException $e) { + var_dump($e->getPrevious()->getMessage()); // Division by zero +} +``` + +For the purposes of static analysis, you will likely want to use `evaluateSilently()` and leave +erroring expressions unevaluated. + +Unsupported expressions and evaluator fallback +---------------------------------------------- + +The constant expression evaluator supports all expression types that are permitted in constant +expressions, apart from the following: + + * `Scalar\MagicConst\*` + * `Expr\ConstFetch` (only null/false/true are handled) + * `Expr\ClassConstFetch` + +Handling these expression types requires non-local information, such as which global constants are +defined. By default, the evaluator will throw a `ConstExprEvaluationException` when it encounters +an unsupported expression type. + +It is possible to override this behavior and support resolution for these expression types by +specifying an evaluation fallback function: + +```php +getType()} cannot be evaluated"); +}); + +try { + $evalutator->evaluateSilently($someExpr); +} catch (ConstExprEvaluationException $e) { + // Handle exception +} +``` + +Implementers are advised to ensure that evaluation of indirect constant references cannot lead to +infinite recursion. For example, the following code could lead to infinite recursion if constant +lookup is implemented naively. + +```php +hasColumnInfo()`, as the precise +Before using column information, its availability needs to be checked with `$e->hasColumnInfo()`, as the precise location of an error cannot always be determined. The methods for retrieving column information also have to be passed the source code of the parsed file. An example for printing an error: diff --git a/app/vendor/nikic/php-parser/doc/component/FAQ.markdown b/app/vendor/nikic/php-parser/doc/component/FAQ.markdown new file mode 100644 index 000000000..b8bf834b6 --- /dev/null +++ b/app/vendor/nikic/php-parser/doc/component/FAQ.markdown @@ -0,0 +1,68 @@ +Frequently Asked Questions +========================== + + * [How can the parent of a node be obtained?](#how-can-the-parent-of-a-node-be-obtained) + * [How can the next/previous sibling of a node be obtained?](#how-can-the-nextprevious-sibling-of-a-node-be-obtained) + +How can the parent of a node be obtained? +----- + +The AST does not store parent nodes by default. However, it is easy to add a custom parent node +attribute using a custom node visitor: + +```php +use PhpParser\Node; +use PhpParser\NodeVisitorAbstract; + +class ParentConnector extends NodeVisitorAbstract { + private $stack; + public function beforeTraverse(array $nodes) { + $this->stack = []; + } + public function enterNode(Node $node) { + if (!empty($this->stack)) { + $node->setAttribute('parent', $this->stack[count($this->stack)-1]); + } + $this->stack[] = $node; + } + public function leaveNode(Node $node) { + array_pop($this->stack); + } +} +``` + +After running this visitor, the parent node can be obtained through `$node->getAttribute('parent')`. + +How can the next/previous sibling of a node be obtained? +----- + +Again, siblings are not stored by default, but the visitor from the previous entry can be easily +extended to store the previous / next node with a common parent as well: + +```php +use PhpParser\Node; +use PhpParser\NodeVisitorAbstract; + +class NodeConnector extends NodeVisitorAbstract { + private $stack; + private $prev; + public function beforeTraverse(array $nodes) { + $this->stack = []; + $this->prev = null; + } + public function enterNode(Node $node) { + if (!empty($this->stack)) { + $node->setAttribute('parent', $this->stack[count($this->stack)-1]); + } + if ($this->prev && $this->prev->getAttribute('parent') == $node->getAttribute('parent')) { + $node->setAttribute('prev', $this->prev); + $this->prev->setAttribute('next', $node); + } + $this->stack[] = $node; + } + public function leaveNode(Node $node) { + $this->prev = $node; + array_pop($this->stack); + } +} +``` diff --git a/app/vendor/nikic/php-parser/doc/component/JSON_representation.markdown b/app/vendor/nikic/php-parser/doc/component/JSON_representation.markdown new file mode 100644 index 000000000..a4d393356 --- /dev/null +++ b/app/vendor/nikic/php-parser/doc/component/JSON_representation.markdown @@ -0,0 +1,131 @@ +JSON representation +=================== + +Nodes (and comments) implement the `JsonSerializable` interface. As such, it is possible to JSON +encode the AST directly using `json_encode()`: + +```php +create(ParserFactory::PREFER_PHP7); + +try { + $stmts = $parser->parse($code); + + echo json_encode($stmts, JSON_PRETTY_PRINT), "\n"; +} catch (PhpParser\Error $e) { + echo 'Parse Error: ', $e->getMessage(); +} +``` + +This will result in the following output (which includes attributes): + +```json +[ + { + "nodeType": "Stmt_Function", + "byRef": false, + "name": { + "nodeType": "Identifier", + "name": "printLine", + "attributes": { + "startLine": 4, + "endLine": 4 + } + }, + "params": [ + { + "nodeType": "Param", + "type": null, + "byRef": false, + "variadic": false, + "var": { + "nodeType": "Expr_Variable", + "name": "msg", + "attributes": { + "startLine": 4, + "endLine": 4 + } + }, + "default": null, + "attributes": { + "startLine": 4, + "endLine": 4 + } + } + ], + "returnType": null, + "stmts": [ + { + "nodeType": "Stmt_Echo", + "exprs": [ + { + "nodeType": "Expr_Variable", + "name": "msg", + "attributes": { + "startLine": 5, + "endLine": 5 + } + }, + { + "nodeType": "Scalar_String", + "value": "\n", + "attributes": { + "startLine": 5, + "endLine": 5, + "kind": 2 + } + } + ], + "attributes": { + "startLine": 5, + "endLine": 5 + } + } + ], + "attributes": { + "startLine": 4, + "comments": [ + { + "nodeType": "Comment_Doc", + "text": "\/** @param string $msg *\/", + "line": 3, + "filePos": 9, + "tokenPos": 2 + } + ], + "endLine": 6 + } + } +] +``` + +The JSON representation may be converted back into an AST using the `JsonDecoder`: + +```php +decode($json); +``` + +Note that not all ASTs can be represented using JSON. In particular: + + * JSON only supports UTF-8 strings. + * JSON does not support non-finite floating-point numbers. This can occur if the original source + code contains non-representable floating-pointing literals such as `1e1000`. + +If the node tree is not representable in JSON, the initial `json_encode()` call will fail. + +From the command line, a JSON dump can be obtained using `vendor/bin/php-parse -j file.php`. \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/doc/component/Lexer.markdown b/app/vendor/nikic/php-parser/doc/component/Lexer.markdown index b22942dd1..be26e381e 100644 --- a/app/vendor/nikic/php-parser/doc/component/Lexer.markdown +++ b/app/vendor/nikic/php-parser/doc/component/Lexer.markdown @@ -27,18 +27,23 @@ The attributes used in this example match the default behavior of the lexer. The * `comments`: Array of `PhpParser\Comment` or `PhpParser\Comment\Doc` instances, representing all comments that occurred between the previous non-discarded token and the current one. Use of this attribute is required for the - `$node->getDocComment()` method to work. The attribute is also needed if you wish the pretty printer to retain - comments present in the original code. + `$node->getComments()` and `$node->getDocComment()` methods to work. The attribute is also needed if you wish the pretty + printer to retain comments present in the original code. * `startLine`: Line in which the node starts. This attribute is required for the `$node->getLine()` to work. It is also required if syntax errors should contain line number information. - * `endLine`: Line in which the node ends. - * `startTokenPos`: Offset into the token array of the first token in the node. - * `endTokenPos`: Offset into the token array of the last token in the node. - * `startFilePos`: Offset into the code string of the first character that is part of the node. - * `endFilePos`: Offset into the code string of the last character that is part of the node. + * `endLine`: Line in which the node ends. Required for `$node->getEndLine()`. + * `startTokenPos`: Offset into the token array of the first token in the node. Required for `$node->getStartTokenPos()`. + * `endTokenPos`: Offset into the token array of the last token in the node. Required for `$node->getEndTokenPos()`. + * `startFilePos`: Offset into the code string of the first character that is part of the node. Required for `$node->getStartFilePos()`. + * `endFilePos`: Offset into the code string of the last character that is part of the node. Required for `$node->getEndFilePos()`. ### Using token positions +> **Note:** The example in this section is outdated in that this information is directly available in the AST: While +> `$property->isPublic()` does not distinguish between `public` and `var`, directly checking `$property->flags` for +> the `$property->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0` allows making this distinction without resorting to +> tokens. However the general idea behind the example still applies in other cases. + The token offset information is useful if you wish to examine the exact formatting used for a node. For example the AST does not distinguish whether a property was declared using `public` or using `var`, but you can retrieve this information based on the token position: @@ -72,7 +77,7 @@ $lexer = new PhpParser\Lexer(array( 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos' ) )); -$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::PREFER_PHP7, $lexer); +$parser = (new PhpParser\ParserFactory)->create(PhpParser\ParserFactory::ONLY_PHP7, $lexer); $visitor = new MyNodeVisitor(); $traverser = new PhpParser\NodeTraverser(); @@ -95,14 +100,16 @@ Lexer extension A lexer has to define the following public interface: - void startLexing(string $code, ErrorHandler $errorHandler = null); - array getTokens(); - string handleHaltCompiler(); - int getNextToken(string &$value = null, array &$startAttributes = null, array &$endAttributes = null); +```php +function startLexing(string $code, ErrorHandler $errorHandler = null): void; +function getTokens(): array; +function handleHaltCompiler(): string; +function getNextToken(string &$value = null, array &$startAttributes = null, array &$endAttributes = null): int; +``` -The `startLexing()` method is invoked with the source code that is to be lexed (including the opening tag) whenever the -`parse()` method of the parser is called. It can be used to reset state or preprocess the source code or tokens. The -passes `ErrorHandler` should be used to report lexing errors. +The `startLexing()` method is invoked whenever the `parse()` method of the parser is called and is passed the source +code that is to be lexed (including the opening tag). It can be used to reset state or preprocess the source code or tokens. The +passed `ErrorHandler` should be used to report lexing errors. The `getTokens()` method returns the current token array, in the usual `token_get_all()` format. This method is not used by the parser (which uses `getNextToken()`), but is useful in combination with the token position attributes. diff --git a/app/vendor/nikic/php-parser/doc/component/Name_resolution.markdown b/app/vendor/nikic/php-parser/doc/component/Name_resolution.markdown new file mode 100644 index 000000000..2a7eb603a --- /dev/null +++ b/app/vendor/nikic/php-parser/doc/component/Name_resolution.markdown @@ -0,0 +1,87 @@ +Name resolution +=============== + +Since the introduction of namespaces in PHP 5.3, literal names in PHP code are subject to a +relatively complex name resolution process, which is based on the current namespace, the current +import table state, as well the type of the referenced symbol. PHP-Parser implements name +resolution and related functionality, both as reusable logic (NameContext), as well as a node +visitor (NameResolver) based on it. + +The NameResolver visitor +------------------------ + +The `NameResolver` visitor can (and for nearly all uses of the AST, is) be applied to resolve names +to their fully-qualified form, to the degree that this is possible. + +```php +$nameResolver = new PhpParser\NodeVisitor\NameResolver; +$nodeTraverser = new PhpParser\NodeTraverser; +$nodeTraverser->addVisitor($nameResolver); + +// Resolve names +$stmts = $nodeTraverser->traverse($stmts); +``` + +In the default configuration, the name resolver will perform three actions: + + * Declarations of functions, classes, interfaces, traits and global constants will have a + `namespacedName` property added, which contains the function/class/etc name including the + namespace prefix. For historic reasons this is a **property** rather than an attribute. + * Names will be replaced by fully qualified resolved names, which are instances of + `Node\Name\FullyQualified`. + * Unqualified function and constant names inside a namespace cannot be statically resolved. Inside + a namespace `Foo`, a call to `strlen()` may either refer to the namespaced `\Foo\strlen()`, or + the global `\strlen()`. Because PHP-Parser does not have the necessary context to decide this, + such names are left unresolved. Additionally a `namespacedName` **attribute** is added to the + name node. + +The name resolver accepts an option array as the second argument, with the following default values: + +```php +$nameResolver = new PhpParser\NodeVisitor\NameResolver(null, [ + 'preserveOriginalNames' => false, + 'replaceNodes' => true, +]); +``` + +If the `preserveOriginalNames` option is enabled, then the resolved (fully qualified) name will have +an `originalName` attribute, which contains the unresolved name. + +If the `replaceNodes` option is disabled, then names will no longer be resolved in-place. Instead a +`resolvedName` attribute will be added to each name, which contains the resolved (fully qualified) +name. Once again, if an unqualified function or constant name cannot be resolved, then the +`resolvedName` attribute will not be present, and instead a `namespacedName` attribute is added. + +The `replaceNodes` attribute is useful if you wish to perform modifications on the AST, as you +probably do not wish the resoluting code to have fully resolved names as a side-effect. + +The NameContext +--------------- + +The actual name resolution logic is implemented in the `NameContext` class, which has the following +public API: + +```php +class NameContext { + public function __construct(ErrorHandler $errorHandler); + public function startNamespace(Name $namespace = null); + public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []); + + public function getNamespace(); + public function getResolvedName(Name $name, int $type); + public function getResolvedClassName(Name $name) : Name; + public function getPossibleNames(string $name, int $type) : array; + public function getShortName(string $name, int $type) : Name; +} +``` + +The `$type` parameters accept on of the `Stmt\Use_::TYPE_*` constants, which represent the three +basic symbol types in PHP (functions, constants and everything else). + +Next to name resolution, the `NameContext` also supports the reverse operation of finding a short +representation of a name given the current name resolution environment. + +The name context is intended to be used for name resolution operations outside the AST itself, such +as class names inside doc comments. A visitor running in parallel with the name resolver can access +the name context using `$nameResolver->getNameContext()`. Alternatively a visitor can use an +independent context and explicitly feed `Namespace` and `Use` nodes to it. \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/doc/component/Performance.markdown b/app/vendor/nikic/php-parser/doc/component/Performance.markdown new file mode 100644 index 000000000..4281ce8cb --- /dev/null +++ b/app/vendor/nikic/php-parser/doc/component/Performance.markdown @@ -0,0 +1,65 @@ +Performance +=========== + +Parsing is computationally expensive task, to which the PHP language is not very well suited. +Nonetheless, there are a few things you can do to improve the performance of this library, which are +described in the following. + +Xdebug +------ + +Running PHP with XDebug adds a lot of overhead, especially for code that performs many method calls. +Just by loading XDebug (without enabling profiling or other more intrusive XDebug features), you +can expect that code using PHP-Parser will be approximately *five times slower*. + +As such, you should make sure that XDebug is not loaded when using this library. Note that setting +the `xdebug.default_enable=0` ini option does *not* disable XDebug. The *only* way to disable +XDebug is to not load the extension in the first place. + +If you are building a command-line utility for use by developers (who often have XDebug enabled), +you may want to consider automatically restarting PHP with XDebug unloaded. The +[composer/xdebug-handler](https://github.com/composer/xdebug-handler) package can be used to do +this. + +If you do run with XDebug, you may need to increase the `xdebug.max_nesting_level` option to a +higher level, such as 3000. While the parser itself is recursion free, most other code working on +the AST uses recursion and will generate an error if the value of this option is too low. + +Assertions +---------- + +Assertions should be disabled in a production context by setting `zend.assertions=-1` (or +`zend.assertions=0` if set at runtime). The library currently doesn't make heavy use of assertions, +but they are used in an increasing number of places. + +Object reuse +------------ + +Many objects in this project are designed for reuse. For example, one `Parser` object can be used to +parse multiple files. + +When possible, objects should be reused rather than being newly instantiated for every use. Some +objects have expensive initialization procedures, which will be unnecessarily repeated if the object +is not reused. (Currently two objects with particularly expensive setup are lexers and pretty +printers, though the details might change between versions of this library.) + +Garbage collection +------------------ + +A limitation in PHP's cyclic garbage collector may lead to major performance degradation when the +active working set exceeds 10000 objects (or arrays). Especially when parsing very large files this +limit is significantly exceeded and PHP will spend the majority of time performing unnecessary +garbage collection attempts. + +Without GC, parsing time is roughly linear in the input size. With GC, this degenerates to quadratic +runtime for large files. While the specifics may differ, as a rough guideline you may expect a 2.5x +GC overhead for 500KB files and a 5x overhead for 1MB files. + +Because this a limitation in PHP's implementation, there is no easy way to work around this. If +possible, you should avoid parsing very large files, as they will impact overall execution time +disproportionally (and are usually generated anyway). + +Of course, you can also try to (temporarily) disable GC. By design the AST generated by PHP-Parser +is cycle-free, so the AST itself will never cause leaks with GC disabled. However, other code +(including for example the parser object itself) may hold cycles, so disabling of GC should be +approached with care. \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/doc/component/Pretty_printing.markdown b/app/vendor/nikic/php-parser/doc/component/Pretty_printing.markdown new file mode 100644 index 000000000..d6198e315 --- /dev/null +++ b/app/vendor/nikic/php-parser/doc/component/Pretty_printing.markdown @@ -0,0 +1,96 @@ +Pretty printing +=============== + +Pretty printing is the process of converting a syntax tree back to PHP code. In its basic mode of +operation the pretty printer provided by this library will print the AST using a certain predefined +code style and will discard (nearly) all formatting of the original code. Because programmers tend +to be rather picky about their code formatting, this mode of operation is not very suitable for +refactoring code, but can be used for automatically generated code, which is usually only read for +debugging purposes. + +Basic usage +----------- + +```php +$stmts = $parser->parse($code); + +// MODIFY $stmts here + +$prettyPrinter = new PhpParser\PrettyPrinter\Standard; +$newCode = $prettyPrinter->prettyPrintFile($stmts); +``` + +The pretty printer has three basic printing methods: `prettyPrint()`, `prettyPrintFile()` and +`prettyPrintExpr()`. The one that is most commonly useful is `prettyPrintFile()`, which takes an +array of statements and produces a full PHP file, including opening ` **Note:** This functionality is **experimental** and not yet complete. + +For automated code refactoring, migration and similar, you will usually only want to modify a small +portion of the code and leave the remainder alone. The basic pretty printer is not suitable for +this, because it will also reformat parts of the code which have not been modified. + +Since PHP-Parser 4.0, an experimental formatting-preserving pretty-printing mode is available, which +attempts to preserve the formatting of code (those AST nodes that have not changed) and only reformat +code which has been modified or newly inserted. + +Use of the formatting-preservation functionality requires some additional preparatory steps: + +```php +use PhpParser\{Lexer, NodeTraverser, NodeVisitor, Parser, PrettyPrinter}; + +$lexer = new Lexer\Emulative([ + 'usedAttributes' => [ + 'comments', + 'startLine', 'endLine', + 'startTokenPos', 'endTokenPos', + ], +]); +$parser = new Parser\Php7($lexer); + +$traverser = new NodeTraverser(); +$traverser->addVisitor(new NodeVisitor\CloningVisitor()); + +$printer = new PrettyPrinter\Standard(); + +$oldStmts = $parser->parse($code); +$oldTokens = $lexer->getTokens(); + +$newStmts = $traverser->traverse($oldStmts); + +// MODIFY $newStmts HERE + +$newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); +``` + +If you make use of the name resolution functionality, you will likely want to disable the +`replaceNodes` option. This will add resolved names as attributes, instead of directlying modifying +the AST and causing spurious changes to the pretty printed code. For more information, see the +[name resolution documentation](Name_resolution.markdown). + +This functionality is experimental and not yet fully implemented. It should not provide incorrect +code, but it may sometimes reformat more code than necessary. Open issues are tracked in +[issue #344](https://github.com/nikic/PHP-Parser/issues/344). If you encounter problems while using +this functionality, please open an issue, so we know what to prioritize. diff --git a/app/vendor/nikic/php-parser/doc/component/Walking_the_AST.markdown b/app/vendor/nikic/php-parser/doc/component/Walking_the_AST.markdown new file mode 100644 index 000000000..fd979d5a7 --- /dev/null +++ b/app/vendor/nikic/php-parser/doc/component/Walking_the_AST.markdown @@ -0,0 +1,335 @@ +Walking the AST +=============== + +The most common way to work with the AST is by using a node traverser and one or more node visitors. +As a basic example, the following code changes all literal integers in the AST into strings (e.g., +`42` becomes `'42'`.) + +```php +use PhpParser\{Node, NodeTraverser, NodeVisitorAbstract}; + +$traverser = new NodeTraverser; +$traverser->addVisitor(new class extends NodeVisitorAbstract { + public function leaveNode(Node $node) { + if ($node instanceof Node\Scalar\LNumber) { + return new Node\Scalar\String_((string) $node->value); + } + } +}); + +$stmts = ...; +$modifiedStmts = $traverser->traverse($stmts); +``` + +Node visitors +------------- + +Each node visitor implements an interface with following four methods: + +```php +interface NodeVisitor { + public function beforeTraverse(array $nodes); + public function enterNode(Node $node); + public function leaveNode(Node $node); + public function afterTraverse(array $nodes); +} +``` + +The `beforeTraverse()` and `afterTraverse()` methods are called before and after the traversal +respectively, and are passed the entire AST. They can be used to perform any necessary state +setup or cleanup. + +The `enterNode()` method is called when a node is first encountered, before its children are +processed ("preorder"). The `leaveNode()` method is called after all children have been visited +("postorder"). + +For example, if we have the following excerpt of an AST + +``` +Expr_FuncCall( + name: Name( + parts: array( + 0: printLine + ) + ) + args: array( + 0: Arg( + value: Scalar_String( + value: Hello World!!! + ) + byRef: false + unpack: false + ) + ) +) +``` + +then the enter/leave methods will be called in the following order: + +``` +enterNode(Expr_FuncCall) +enterNode(Name) +leaveNode(Name) +enterNode(Arg) +enterNode(Scalar_String) +leaveNode(Scalar_String) +leaveNode(Arg) +leaveNode(Expr_FuncCall) +``` + +A common pattern is that `enterNode` is used to collect some information and then `leaveNode` +performs modifications based on that. At the time when `leaveNode` is called, all the code inside +the node will have already been visited and necessary information collected. + +As you usually do not want to implement all four methods, it is recommended that you extend +`NodeVisitorAbstract` instead of implementing the interface directly. The abstract class provides +empty default implementations. + +Modifying the AST +----------------- + +There are a number of ways in which the AST can be modified from inside a node visitor. The first +and simplest is to simply change AST properties inside the visitor: + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Scalar\LNumber) { + // increment all integer literals + $node->value++; + } +} +``` + +The second is to replace a node entirely by returning a new node: + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Expr\BinaryOp\BooleanAnd) { + // Convert all $a && $b expressions into !($a && $b) + return new Node\Expr\BooleanNot($node); + } +} +``` + +Doing this is supported both inside enterNode and leaveNode. However, you have to be mindful about +where you perform the replacement: If a node is replaced in enterNode, then the recursive traversal +will also consider the children of the new node. If you aren't careful, this can lead to infinite +recursion. For example, let's take the previous code sample and use enterNode instead: + +```php +public function enterNode(Node $node) { + if ($node instanceof Node\Expr\BinaryOp\BooleanAnd) { + // Convert all $a && $b expressions into !($a && $b) + return new Node\Expr\BooleanNot($node); + } +} +``` + +Now `$a && $b` will be replaced by `!($a && $b)`. Then the traverser will go into the first (and +only) child of `!($a && $b)`, which is `$a && $b`. The transformation applies again and we end up +with `!!($a && $b)`. This will continue until PHP hits the memory limit. + +Finally, two special replacement types are supported only by leaveNode. The first is removal of a +node: + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Stmt\Return_) { + // Remove all return statements + return NodeTraverser::REMOVE_NODE; + } +} +``` + +Node removal only works if the parent structure is an array. This means that usually it only makes +sense to remove nodes of type `Node\Stmt`, as they always occur inside statement lists (and a few +more node types like `Arg` or `Expr\ArrayItem`, which are also always part of lists). + +On the other hand, removing a `Node\Expr` does not make sense: If you have `$a * $b`, there is no +meaningful way in which the `$a` part could be removed. If you want to remove an expression, you +generally want to remove it together with a surrounding expression statement: + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Stmt\Expression + && $node->expr instanceof Node\Expr\FuncCall + && $node->expr->name instanceof Node\Name + && $node->expr->name->toString() === 'var_dump' + ) { + return NodeTraverser::REMOVE_NODE; + } +} +``` + +This example will remove all calls to `var_dump()` which occur as expression statements. This means +that `var_dump($a);` will be removed, but `if (var_dump($a))` will not be removed (and there is no +obvious way in which it can be removed). + +Next to removing nodes, it is also possible to replace one node with multiple nodes. Again, this +only works inside leaveNode and only if the parent structure is an array. + +```php +public function leaveNode(Node $node) { + if ($node instanceof Node\Stmt\Return_ && $node->expr !== null) { + // Convert "return foo();" into "$retval = foo(); return $retval;" + $var = new Node\Expr\Variable('retval'); + return [ + new Node\Stmt\Expression(new Node\Expr\Assign($var, $node->expr)), + new Node\Stmt\Return_($var), + ]; + } +} +``` + +Short-circuiting traversal +-------------------------- + +An AST can easily contain thousands of nodes, and traversing over all of them may be slow, +especially if you have more than one visitor. In some cases, it is possible to avoid a full +traversal. + +If you are looking for all class declarations in a file (and assuming you're not interested in +anonymous classes), you know that once you've seen a class declaration, there is no point in also +checking all it's child nodes, because PHP does not allow nesting classes. In this case, you can +instruct the traverser to not recurse into the class node: + +``` +private $classes = []; +public function enterNode(Node $node) { + if ($node instanceof Node\Stmt\Class_) { + $this->classes[] = $node; + return NodeTraverser::DONT_TRAVERSE_CHILDREN; + } +} +``` + +Of course, this option is only available in enterNode, because it's already too late by the time +leaveNode is reached. + +If you are only looking for one specific node, it is also possible to abort the traversal entirely +after finding it. For example, if you are looking for the node of a class with a certain name (and +discounting exotic cases like conditionally defining a class two times), you can stop traversal +once you found it: + +``` +private $class = null; +public function enterNode(Node $node) { + if ($node instanceof Node\Stmt\Class_ && + $node->namespaceName->toString() === 'Foo\Bar\Baz' + ) { + $this->class = $node; + return NodeTraverser::STOP_TRAVERSAL; + } +} +``` + +This works both in enterNode and leaveNode. Note that this particular case can also be more easily +handled using a NodeFinder, which will be introduced below. + +Multiple visitors +----------------- + +A single traverser can be used with multiple visitors: + +```php +$traverser = new NodeTraverser; +$traverser->addVisitor($visitorA); +$traverser->addVisitor($visitorB); +$stmts = $traverser->traverser($stmts); +``` + +It is important to understand that if a traverser is run with multiple visitors, the visitors will +be interleaved. Given the following AST excerpt + +``` +Stmt_Return( + expr: Expr_Variable( + name: foobar + ) +) +``` + +the following method calls will be performed: + +``` +$visitorA->enterNode(Stmt_Return) +$visitorB->enterNode(Stmt_Return) +$visitorA->enterNode(Expr_Variable) +$visitorB->enterNode(Expr_Variable) +$visitorA->leaveNode(Expr_Variable) +$visitorB->leaveNode(Expr_Variable) +$visitorA->leaveNode(Stmt_Return) +$visitorB->leaveNode(Stmt_Return) +``` + +That is, when visiting a node, enterNode and leaveNode will always be called for all visitors. +Running multiple visitors in parallel improves performance, as the AST only has to be traversed +once. However, it is not always possible to write visitors in a way that allows interleaved +execution. In this case, you can always fall back to performing multiple traversals: + +```php +$traverserA = new NodeTraverser; +$traverserA->addVisitor($visitorA); +$traverserB = new NodeTraverser; +$traverserB->addVisitor($visitorB); +$stmts = $traverserA->traverser($stmts); +$stmts = $traverserB->traverser($stmts); +``` + +When using multiple visitors, it is important to understand how they interact with the various +special enterNode/leaveNode return values: + + * If *any* visitor returns `DONT_TRAVERSE_CHILDREN`, the children will be skipped for *all* + visitors. + * If *any* visitor returns `STOP_TRAVERSAL`, traversal is stopped for *all* visitors. + * If a visitor returns a replacement node, subsequent visitors will be passed the replacement node, + not the original one. + * If a visitor returns `REMOVE_NODE`, subsequent visitors will not see this node. + * If a visitor returns an array of replacement nodes, subsequent visitors will see neither the node + that was replaced, nor the replacement nodes. + +Simple node finding +------------------- + +While the node visitor mechanism is very flexible, creating a node visitor can be overly cumbersome +for minor tasks. For this reason a `NodeFinder` is provided, which can find AST nodes that either +satisfy a certain callback, or which are instanced of a certain node type. A couple of examples are +shown in the following: + +```php +use PhpParser\{Node, NodeFinder}; + +$nodeFinder = new NodeFinder; + +// Find all class nodes. +$classes = $nodeFinder->findInstanceOf($stmts, Node\Stmt\Class_::class); + +// Find all classes that extend another class +$extendingClasses = $nodeFinder->findInstanceOf($stmts, function(Node $node) { + return $node instanceof Node\Stmt\Class_ + && $node->extends !== null; +}); + +// Find first class occuring in the AST. Returns null if no class exists. +$class = $nodeFinder->findFirstInstanceOf($stmts, Node\Stmt\Class_::class); + +// Find first class that has name $name +$class = $nodeFinder->findFirst($stmts, function(Node $node) use ($name) { + return $node instanceof Node\Stmt\Class_ + && $node->resolvedName->toString() === $name; +}); +``` + +Internally, the `NodeFinder` also uses a node traverser. It only simplifies the interface for a +common use case. + +Parent and sibling references +----------------------------- + +The node visitor mechanism is somewhat rigid, in that it prescribes an order in which nodes should +be accessed: From parents to children. However, it can often be convenient to operate in the +reverse direction: When working on a node, you might want to check if the parent node satisfies a +certain property. + +PHP-Parser does not add parent (or sibling) references to nodes by itself, but you can easily +emulate this with a visitor. See the [FAQ](FAQ.markdown) for more information. \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/grammar/README.md b/app/vendor/nikic/php-parser/grammar/README.md index 3f1698a68..90988cf44 100644 --- a/app/vendor/nikic/php-parser/grammar/README.md +++ b/app/vendor/nikic/php-parser/grammar/README.md @@ -11,7 +11,7 @@ What do all those files mean? .phpy pseudo language ===================== -The `.y` file is a normal grammer in `kmyacc` (`yacc`) style, with some transformations +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 diff --git a/app/vendor/nikic/php-parser/grammar/parser.template b/app/vendor/nikic/php-parser/grammar/parser.template index fff893ff4..6166607c9 100644 --- a/app/vendor/nikic/php-parser/grammar/parser.template +++ b/app/vendor/nikic/php-parser/grammar/parser.template @@ -2,8 +2,8 @@ $meta # #semval($) $this->semValue #semval($,%t) $this->semValue -#semval(%n) $this->stackPos-(%l-%n) -#semval(%n,%t) $this->stackPos-(%l-%n) +#semval(%n) $stackPos-(%l-%n) +#semval(%n,%t) $stackPos-(%l-%n) namespace PhpParser\Parser; @@ -32,8 +32,8 @@ class #(-p) extends \PhpParser\ParserAbstract protected $defaultAction = #(YYDEFAULT); protected $unexpectedTokenRule = #(YYUNEXPECTED); - protected $YY2TBLSTATE = #(YY2TBLSTATE); - protected $YYNLSTATES = #(YYNLSTATES); + protected $YY2TBLSTATE = #(YY2TBLSTATE); + protected $numNonLeafStates = #(YYNLSTATES); protected $symbolToName = array( #listvar terminals @@ -88,16 +88,19 @@ class #(-p) extends \PhpParser\ParserAbstract #production-strings; ); #endif -#reduce - protected function reduceRule%n() { - %b - } + protected function initReduceCallbacks() { + $this->reduceCallbacks = [ +#reduce + %n => function ($stackPos) { + %b + }, #noact - - protected function reduceRule%n() { - $this->semValue = $this->semStack[$this->stackPos]; - } + %n => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, #endreduce + ]; + } } #tailcode; diff --git a/app/vendor/nikic/php-parser/grammar/php5.y b/app/vendor/nikic/php-parser/grammar/php5.y index 458804636..486d836c8 100644 --- a/app/vendor/nikic/php-parser/grammar/php5.y +++ b/app/vendor/nikic/php-parser/grammar/php5.y @@ -16,7 +16,7 @@ top_statement_list_ex: top_statement_list: top_statement_list_ex - { makeNop($nop, $this->lookaheadStartAttributes); + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); if ($nop !== null) { $1[] = $nop; } $$ = $1; } ; @@ -35,9 +35,17 @@ semi_reserved: | 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 { $$ = $1; } - | semi_reserved { $$ = $1; } + T_STRING { $$ = Node\Identifier[$1]; } +; + +reserved_non_modifiers_identifier: + reserved_non_modifiers { $$ = Node\Identifier[$1]; } ; namespace_name_parts: @@ -49,6 +57,10 @@ namespace_name: namespace_name_parts { $$ = Name[$1]; } ; +plain_variable: + T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +; + top_statement: statement { $$ = $1; } | function_declaration_statement { $$ = $1; } @@ -109,7 +121,7 @@ inline_use_declarations: unprefixed_use_declaration: namespace_name { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } - | namespace_name T_AS T_STRING + | namespace_name T_AS identifier { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } ; @@ -129,7 +141,7 @@ constant_declaration_list: ; constant_declaration: - T_STRING '=' static_scalar { $$ = Node\Const_[$1, $3]; } + identifier '=' static_scalar { $$ = Node\Const_[$1, $3]; } ; class_const_list: @@ -138,7 +150,7 @@ class_const_list: ; class_const: - identifier '=' static_scalar { $$ = Node\Const_[$1, $3]; } + identifier_ex '=' static_scalar { $$ = Node\Const_[$1, $3]; } ; inner_statement_list_ex: @@ -148,7 +160,7 @@ inner_statement_list_ex: inner_statement_list: inner_statement_list_ex - { makeNop($nop, $this->lookaheadStartAttributes); + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); if ($nop !== null) { $1[] = $nop; } $$ = $1; } ; @@ -166,7 +178,7 @@ non_empty_statement: if ($2) { $$ = $2; prependLeadingComments($$); } else { - makeNop($$, $this->startAttributeStack[#1]); + makeNop($$, $this->startAttributeStack[#1], $this->endAttributes); if (null === $$) { $$ = array(); } } } @@ -185,12 +197,12 @@ non_empty_statement: | T_CONTINUE expr ';' { $$ = Stmt\Continue_[$2]; } | T_RETURN ';' { $$ = Stmt\Return_[null]; } | T_RETURN expr ';' { $$ = Stmt\Return_[$2]; } - | yield_expr ';' { $$ = $1; } | 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]; } - | expr ';' { $$ = $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]]; } @@ -200,16 +212,16 @@ non_empty_statement: | T_TRY '{' inner_statement_list '}' catches optional_finally { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } | T_THROW expr ';' { $$ = Stmt\Throw_[$2]; } - | T_GOTO T_STRING ';' { $$ = Stmt\Goto_[$2]; } - | T_STRING ':' { $$ = Stmt\Label[$1]; } - | expr error { $$ = $1; } + | 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]); + { makeNop($$, $this->startAttributeStack[#1], $this->endAttributes); if ($$ === null) $$ = array(); /* means: no statement */ } ; @@ -219,8 +231,8 @@ catches: ; catch: - T_CATCH '(' name T_VARIABLE ')' '{' inner_statement_list '}' - { $$ = Stmt\Catch_[array($3), parseVar($4), $7]; } + T_CATCH '(' name plain_variable ')' '{' inner_statement_list '}' + { $$ = Stmt\Catch_[array($3), $4, $7]; } ; optional_finally: @@ -244,18 +256,18 @@ optional_ellipsis: ; function_declaration_statement: - T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' + T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; } ; class_declaration_statement: - class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}' + 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 T_STRING interface_extends_list '{' class_statement_list '}' + | T_INTERFACE identifier interface_extends_list '{' class_statement_list '}' { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; $this->checkInterface($$, #2); } - | T_TRAIT T_STRING '{' class_statement_list '}' + | T_TRAIT identifier '{' class_statement_list '}' { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } ; @@ -307,7 +319,7 @@ declare_list: ; declare_list_element: - T_STRING '=' static_scalar { $$ = Stmt\DeclareDeclare[$1, $3]; } + identifier '=' static_scalar { $$ = Stmt\DeclareDeclare[$1, $3]; } ; switch_case_list: @@ -323,8 +335,8 @@ case_list: ; case: - T_CASE expr case_separator inner_statement_list { $$ = Stmt\Case_[$2, $4]; } - | T_DEFAULT case_separator inner_statement_list { $$ = Stmt\Case_[null, $3]; } + 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: @@ -382,16 +394,16 @@ non_empty_parameter_list: ; parameter: - optional_param_type optional_ref optional_ellipsis T_VARIABLE - { $$ = Node\Param[parseVar($4), null, $1, $2, $3]; $this->checkParam($$); } - | optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' static_scalar - { $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; $this->checkParam($$); } + optional_param_type optional_ref optional_ellipsis plain_variable + { $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); } + | optional_param_type optional_ref optional_ellipsis plain_variable '=' static_scalar + { $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); } ; type: name { $$ = $1; } - | T_ARRAY { $$ = 'array'; } - | T_CALLABLE { $$ = 'callable'; } + | T_ARRAY { $$ = Node\Identifier['array']; } + | T_CALLABLE { $$ = Node\Identifier['callable']; } ; optional_param_type: @@ -427,7 +439,7 @@ global_var_list: ; global_var: - T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } + plain_variable { $$ = $1; } | '$' variable { $$ = Expr\Variable[$2]; } | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } ; @@ -438,20 +450,26 @@ static_var_list: ; static_var: - T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; } - | T_VARIABLE '=' static_scalar { $$ = Stmt\StaticVar[parseVar($1), $3]; } + plain_variable { $$ = Stmt\StaticVar[$1, null]; } + | plain_variable '=' static_scalar { $$ = Stmt\StaticVar[$1, $3]; } ; -class_statement_list: - class_statement_list class_statement { push($1, $2); } +class_statement_list_ex: + class_statement_list_ex class_statement { if ($2 !== null) { push($1, $2); } } | /* empty */ { init(); } ; +class_statement_list: + class_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + class_statement: variable_modifiers property_declaration_list ';' { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); } | T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$2, 0]; } - | method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body + | 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]; } @@ -470,22 +488,22 @@ trait_adaptation_list: 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 ';' + | 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 T_STRING ';' + | trait_method_reference T_AS identifier ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } - | trait_method_reference T_AS reserved_non_modifiers ';' + | 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 { $$ = array($1, $3); } + name T_PAAMAYIM_NEKUDOTAYIM identifier_ex { $$ = array($1, $3); } ; trait_method_reference: trait_method_reference_fully_qualified { $$ = $1; } - | identifier { $$ = array(null, $1); } + | identifier_ex { $$ = array(null, $1); } ; method_body: @@ -522,9 +540,13 @@ property_declaration_list: | property_declaration_list ',' property_declaration { push($1, $3); } ; +property_decl_name: + T_VARIABLE { $$ = Node\VarLikeIdentifier[parseVar($1)]; } +; + property_declaration: - T_VARIABLE { $$ = Stmt\PropertyProperty[parseVar($1), null]; } - | T_VARIABLE '=' static_scalar { $$ = Stmt\PropertyProperty[parseVar($1), $3]; } + property_decl_name { $$ = Stmt\PropertyProperty[$1, null]; } + | property_decl_name '=' static_scalar { $$ = Stmt\PropertyProperty[$1, $3]; } ; expr_list: @@ -665,6 +687,7 @@ 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]; } @@ -683,30 +706,17 @@ lexical_var_list: ; lexical_var: - optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; } + optional_ref plain_variable { $$ = Expr\ClosureUse[$2, $1]; } ; function_call: name argument_list { $$ = Expr\FuncCall[$1, $2]; } - | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier argument_list + | 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 { - if ($1 instanceof Node\Expr\StaticPropertyFetch) { - $$ = Expr\StaticCall[$1->class, Expr\Variable[$1->name], $2]; - } elseif ($1 instanceof Node\Expr\ArrayDimFetch) { - $tmp = $1; - while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { - $tmp = $tmp->var; - } - - $$ = Expr\StaticCall[$tmp->var->class, $1, $2]; - $tmp->var = Expr\Variable[$tmp->var->name]; - } else { - throw new \Exception; - } - } + | 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]; } @@ -790,7 +800,7 @@ common_scalar: static_scalar: common_scalar { $$ = $1; } - | class_name T_PAAMAYIM_NEKUDOTAYIM identifier { $$ = Expr\ClassConstFetch[$1, $3]; } + | 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]; } @@ -835,7 +845,7 @@ static_operation: constant: name { $$ = Expr\ConstFetch[$1]; } - | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_ex { $$ = Expr\ClassConstFetch[$1, $3]; } ; @@ -914,9 +924,14 @@ static_property: | 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 T_VARIABLE - { $$ = Expr\StaticPropertyFetch[$1, parseVar($3)]; } + 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]; } @@ -926,7 +941,7 @@ static_property_with_arrays: reference_variable: reference_variable '[' dim_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | reference_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } - | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } + | plain_variable { $$ = $1; } | '$' '{' expr '}' { $$ = Expr\Variable[$3]; } ; @@ -936,7 +951,7 @@ dim_offset: ; object_property: - T_STRING { $$ = $1; } + identifier { $$ = $1; } | '{' expr '}' { $$ = $2; } | variable_without_objects { $$ = $1; } | error { $$ = Expr\Error[]; $this->errorState = 2; } @@ -985,25 +1000,25 @@ encaps_string_part: T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } ; -encaps_base_var: - T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +encaps_str_varname: + T_STRING_VARNAME { $$ = Expr\Variable[$1]; } ; encaps_var: - encaps_base_var { $$ = $1; } - | encaps_base_var '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } - | encaps_base_var T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[$1, $3]; } + 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 T_STRING_VARNAME '[' expr ']' '}' - { $$ = Expr\ArrayDimFetch[Expr\Variable[$2], $4]; } + | 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_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } + | plain_variable { $$ = $1; } ; %% diff --git a/app/vendor/nikic/php-parser/grammar/php7.y b/app/vendor/nikic/php-parser/grammar/php7.y index b941c4964..ba203284b 100644 --- a/app/vendor/nikic/php-parser/grammar/php7.y +++ b/app/vendor/nikic/php-parser/grammar/php7.y @@ -16,7 +16,7 @@ top_statement_list_ex: top_statement_list: top_statement_list_ex - { makeNop($nop, $this->lookaheadStartAttributes); + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); if ($nop !== null) { $1[] = $nop; } $$ = $1; } ; @@ -35,9 +35,17 @@ semi_reserved: | 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 { $$ = $1; } - | semi_reserved { $$ = $1; } + T_STRING { $$ = Node\Identifier[$1]; } +; + +reserved_non_modifiers_identifier: + reserved_non_modifiers { $$ = Node\Identifier[$1]; } ; namespace_name_parts: @@ -49,6 +57,10 @@ namespace_name: namespace_name_parts { $$ = Name[$1]; } ; +plain_variable: + T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +; + semi: ';' { /* nothing */ } | error { /* nothing */ } @@ -136,7 +148,7 @@ non_empty_inline_use_declarations: unprefixed_use_declaration: namespace_name { $$ = Stmt\UseUse[$1, null, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #1); } - | namespace_name T_AS T_STRING + | namespace_name T_AS identifier { $$ = Stmt\UseUse[$1, $3, Stmt\Use_::TYPE_UNKNOWN]; $this->checkUseUse($$, #3); } ; @@ -161,7 +173,7 @@ non_empty_constant_declaration_list: ; constant_declaration: - T_STRING '=' expr { $$ = Node\Const_[$1, $3]; } + identifier '=' expr { $$ = Node\Const_[$1, $3]; } ; class_const_list: @@ -174,7 +186,7 @@ non_empty_class_const_list: ; class_const: - identifier '=' expr { $$ = Node\Const_[$1, $3]; } + identifier_ex '=' expr { $$ = Node\Const_[$1, $3]; } ; inner_statement_list_ex: @@ -184,7 +196,7 @@ inner_statement_list_ex: inner_statement_list: inner_statement_list_ex - { makeNop($nop, $this->lookaheadStartAttributes); + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); if ($nop !== null) { $1[] = $nop; } $$ = $1; } ; @@ -202,7 +214,7 @@ non_empty_statement: if ($2) { $$ = $2; prependLeadingComments($$); } else { - makeNop($$, $this->startAttributeStack[#1]); + makeNop($$, $this->startAttributeStack[#1], $this->endAttributes); if (null === $$) { $$ = array(); } } } @@ -222,25 +234,27 @@ non_empty_statement: | T_STATIC static_var_list semi { $$ = Stmt\Static_[$2]; } | T_ECHO expr_list semi { $$ = Stmt\Echo_[$2]; } | T_INLINE_HTML { $$ = Stmt\InlineHTML[$1]; } - | expr semi { $$ = $1; } + | expr semi { $$ = Stmt\Expression[$1]; } | T_UNSET '(' variables_list ')' semi { $$ = Stmt\Unset_[$3]; } | T_FOREACH '(' expr T_AS foreach_variable ')' foreach_statement { $$ = Stmt\Foreach_[$3, $5[0], ['keyVar' => null, 'byRef' => $5[1], 'stmts' => $7]]; } | T_FOREACH '(' expr T_AS variable T_DOUBLE_ARROW foreach_variable ')' foreach_statement { $$ = Stmt\Foreach_[$3, $7[0], ['keyVar' => $5, 'byRef' => $7[1], 'stmts' => $9]]; } + | T_FOREACH '(' expr error ')' foreach_statement + { $$ = Stmt\Foreach_[$3, new Expr\Error(stackAttributes(#4)), ['stmts' => $6]]; } | T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt\Declare_[$3, $5]; } | T_TRY '{' inner_statement_list '}' catches optional_finally { $$ = Stmt\TryCatch[$3, $5, $6]; $this->checkTryCatch($$); } | T_THROW expr semi { $$ = Stmt\Throw_[$2]; } - | T_GOTO T_STRING semi { $$ = Stmt\Goto_[$2]; } - | T_STRING ':' { $$ = Stmt\Label[$1]; } + | T_GOTO identifier semi { $$ = Stmt\Goto_[$2]; } + | identifier ':' { $$ = Stmt\Label[$1]; } | error { $$ = array(); /* means: no statement */ } ; statement: non_empty_statement { $$ = $1; } | ';' - { makeNop($$, $this->startAttributeStack[#1]); + { makeNop($$, $this->startAttributeStack[#1], $this->endAttributes); if ($$ === null) $$ = array(); /* means: no statement */ } ; @@ -255,8 +269,8 @@ name_union: ; catch: - T_CATCH '(' name_union T_VARIABLE ')' '{' inner_statement_list '}' - { $$ = Stmt\Catch_[$3, parseVar($4), $7]; } + T_CATCH '(' name_union plain_variable ')' '{' inner_statement_list '}' + { $$ = Stmt\Catch_[$3, $4, $7]; } ; optional_finally: @@ -265,7 +279,7 @@ optional_finally: ; variables_list: - non_empty_variables_list no_comma { $$ = $1; } + non_empty_variables_list optional_comma { $$ = $1; } ; non_empty_variables_list: @@ -283,19 +297,24 @@ optional_ellipsis: | T_ELLIPSIS { $$ = true; } ; +block_or_error: + '{' inner_statement_list '}' { $$ = $2; } + | error { $$ = []; } +; + function_declaration_statement: - T_FUNCTION optional_ref T_STRING '(' parameter_list ')' optional_return_type '{' inner_statement_list '}' - { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $9]]; } + T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type block_or_error + { $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $8]]; } ; class_declaration_statement: - class_entry_type T_STRING extends_from implements_list '{' class_statement_list '}' + 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 T_STRING interface_extends_list '{' class_statement_list '}' + | T_INTERFACE identifier interface_extends_list '{' class_statement_list '}' { $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]]; $this->checkInterface($$, #2); } - | T_TRAIT T_STRING '{' class_statement_list '}' + | T_TRAIT identifier '{' class_statement_list '}' { $$ = Stmt\Trait_[$2, ['stmts' => $4]]; } ; @@ -355,7 +374,7 @@ non_empty_declare_list: ; declare_list_element: - T_STRING '=' expr { $$ = Stmt\DeclareDeclare[$1, $3]; } + identifier '=' expr { $$ = Stmt\DeclareDeclare[$1, $3]; } ; switch_case_list: @@ -371,8 +390,8 @@ case_list: ; case: - T_CASE expr case_separator inner_statement_list { $$ = Stmt\Case_[$2, $4]; } - | T_DEFAULT case_separator inner_statement_list { $$ = Stmt\Case_[null, $3]; } + 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: @@ -431,10 +450,12 @@ non_empty_parameter_list: ; parameter: - optional_param_type optional_ref optional_ellipsis T_VARIABLE - { $$ = Node\Param[parseVar($4), null, $1, $2, $3]; $this->checkParam($$); } - | optional_param_type optional_ref optional_ellipsis T_VARIABLE '=' expr - { $$ = Node\Param[parseVar($4), $6, $1, $2, $3]; $this->checkParam($$); } + optional_param_type optional_ref optional_ellipsis plain_variable + { $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); } + | optional_param_type optional_ref optional_ellipsis plain_variable '=' expr + { $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); } + | optional_param_type optional_ref optional_ellipsis error + { $$ = Node\Param[Expr\Error[], null, $1, $2, $3]; } ; type_expr: @@ -444,8 +465,8 @@ type_expr: type: name { $$ = $this->handleBuiltinTypes($1); } - | T_ARRAY { $$ = 'array'; } - | T_CALLABLE { $$ = 'callable'; } + | T_ARRAY { $$ = Node\Identifier['array']; } + | T_CALLABLE { $$ = Node\Identifier['callable']; } ; optional_param_type: @@ -460,7 +481,7 @@ optional_return_type: argument_list: '(' ')' { $$ = array(); } - | '(' non_empty_argument_list no_comma ')' { $$ = $2; } + | '(' non_empty_argument_list optional_comma ')' { $$ = $2; } ; non_empty_argument_list: @@ -497,24 +518,31 @@ non_empty_static_var_list: ; static_var: - T_VARIABLE { $$ = Stmt\StaticVar[parseVar($1), null]; } - | T_VARIABLE '=' expr { $$ = Stmt\StaticVar[parseVar($1), $3]; } + plain_variable { $$ = Stmt\StaticVar[$1, null]; } + | plain_variable '=' expr { $$ = Stmt\StaticVar[$1, $3]; } ; -class_statement_list: - class_statement_list class_statement { push($1, $2); } +class_statement_list_ex: + class_statement_list_ex class_statement { if ($2 !== null) { push($1, $2); } } | /* empty */ { init(); } ; +class_statement_list: + class_statement_list_ex + { makeNop($nop, $this->lookaheadStartAttributes, $this->endAttributes); + if ($nop !== null) { $1[] = $nop; } $$ = $1; } +; + class_statement: variable_modifiers property_declaration_list ';' { $$ = Stmt\Property[$1, $2]; $this->checkProperty($$, #1); } | method_modifiers T_CONST class_const_list ';' { $$ = Stmt\ClassConst[$3, $1]; $this->checkClassConst($$, #1); } - | method_modifiers T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type method_body + | method_modifiers T_FUNCTION optional_ref identifier_ex '(' parameter_list ')' optional_return_type method_body { $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]]; $this->checkClassMethod($$, #1); } | T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; } + | error { $$ = null; /* will be skipped */ } ; trait_adaptations: @@ -530,27 +558,27 @@ trait_adaptation_list: 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 ';' + | 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 T_STRING ';' + | trait_method_reference T_AS identifier ';' { $$ = Stmt\TraitUseAdaptation\Alias[$1[0], $1[1], null, $3]; } - | trait_method_reference T_AS reserved_non_modifiers ';' + | 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 { $$ = array($1, $3); } + name T_PAAMAYIM_NEKUDOTAYIM identifier_ex { $$ = array($1, $3); } ; trait_method_reference: trait_method_reference_fully_qualified { $$ = $1; } - | identifier { $$ = array(null, $1); } + | identifier_ex { $$ = array(null, $1); } ; method_body: ';' /* abstract method */ { $$ = null; } - | '{' inner_statement_list '}' { $$ = $2; } + | block_or_error { $$ = $1; } ; variable_modifiers: @@ -587,9 +615,13 @@ non_empty_property_declaration_list: { push($1, $3); } ; +property_decl_name: + T_VARIABLE { $$ = Node\VarLikeIdentifier[parseVar($1)]; } +; + property_declaration: - T_VARIABLE { $$ = Stmt\PropertyProperty[parseVar($1), null]; } - | T_VARIABLE '=' expr { $$ = Stmt\PropertyProperty[parseVar($1), $3]; } + property_decl_name { $$ = Stmt\PropertyProperty[$1, null]; } + | property_decl_name '=' expr { $$ = Stmt\PropertyProperty[$1, $3]; } ; expr_list: @@ -692,17 +724,18 @@ expr: | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr\Yield_[$4, $2]; } | T_YIELD_FROM expr { $$ = Expr\YieldFrom[$2]; } | T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type - '{' inner_statement_list '}' - { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $9]]; } + block_or_error + { $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $8]]; } | T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type - '{' inner_statement_list '}' - { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $10]]; } + block_or_error + { $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9]]; } ; anonymous_class: T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}' { $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2); $this->checkClass($$[0], -1); } +; new_expr: T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } @@ -725,7 +758,7 @@ non_empty_lexical_var_list: ; lexical_var: - optional_ref T_VARIABLE { $$ = Expr\ClosureUse[parseVar($2), $1]; } + optional_ref plain_variable { $$ = Expr\ClosureUse[$2, $1]; } ; function_call: @@ -776,7 +809,7 @@ ctor_arguments: constant: name { $$ = Expr\ConstFetch[$1]; } - | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier + | class_name_or_var T_PAAMAYIM_NEKUDOTAYIM identifier_ex { $$ = Expr\ClassConstFetch[$1, $3]; } /* We interpret and isolated FOO:: as an unfinished class constant fetch. It could also be an unfinished static property fetch or unfinished scoped call. */ @@ -867,8 +900,13 @@ simple_variable: | '$' error { $$ = Expr\Error[]; $this->errorState = 2; } ; +static_member_prop_name: + simple_variable + { $var = $1; $$ = \is_string($var) ? Node\VarLikeIdentifier[$var] : $var; } +; + static_member: - class_name_or_var T_PAAMAYIM_NEKUDOTAYIM simple_variable + class_name_or_var T_PAAMAYIM_NEKUDOTAYIM static_member_prop_name { $$ = Expr\StaticPropertyFetch[$1, $3]; } ; @@ -877,18 +915,20 @@ new_variable: | new_variable '[' optional_expr ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } | new_variable '{' expr '}' { $$ = Expr\ArrayDimFetch[$1, $3]; } | new_variable T_OBJECT_OPERATOR property_name { $$ = Expr\PropertyFetch[$1, $3]; } - | class_name T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$1, $3]; } - | new_variable T_PAAMAYIM_NEKUDOTAYIM simple_variable { $$ = Expr\StaticPropertyFetch[$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 { $$ = $1; } + identifier_ex { $$ = $1; } | '{' expr '}' { $$ = $2; } | simple_variable { $$ = Expr\Variable[$1]; } ; property_name: - T_STRING { $$ = $1; } + identifier { $$ = $1; } | '{' expr '}' { $$ = $2; } | simple_variable { $$ = Expr\Variable[$1]; } | error { $$ = Expr\Error[]; $this->errorState = 2; } @@ -905,19 +945,26 @@ list_expr_elements: list_expr_element: variable { $$ = Expr\ArrayItem[$1, null, false]; } + | '&' variable { $$ = Expr\ArrayItem[$2, null, true]; } | list_expr { $$ = Expr\ArrayItem[$1, null, false]; } | expr T_DOUBLE_ARROW variable { $$ = Expr\ArrayItem[$3, $1, false]; } + | expr T_DOUBLE_ARROW '&' variable { $$ = Expr\ArrayItem[$4, $1, true]; } | expr T_DOUBLE_ARROW list_expr { $$ = Expr\ArrayItem[$3, $1, false]; } | /* empty */ { $$ = null; } ; array_pair_list: inner_array_pair_list - { $$ = $1; $end = count($$)-1; if ($$[$end] === null) unset($$[$end]); } + { $$ = $1; $end = count($$)-1; if ($$[$end] === null) array_pop($$); } +; + +comma_or_error: + ',' + | error ; inner_array_pair_list: - inner_array_pair_list ',' array_pair { push($1, $3); } + inner_array_pair_list comma_or_error array_pair { push($1, $3); } | array_pair { init($1); } ; @@ -940,18 +987,18 @@ encaps_string_part: T_ENCAPSED_AND_WHITESPACE { $$ = Scalar\EncapsedStringPart[$1]; } ; -encaps_base_var: - T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } +encaps_str_varname: + T_STRING_VARNAME { $$ = Expr\Variable[$1]; } ; encaps_var: - encaps_base_var { $$ = $1; } - | encaps_base_var '[' encaps_var_offset ']' { $$ = Expr\ArrayDimFetch[$1, $3]; } - | encaps_base_var T_OBJECT_OPERATOR T_STRING { $$ = Expr\PropertyFetch[$1, $3]; } + 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 T_STRING_VARNAME '[' expr ']' '}' - { $$ = Expr\ArrayDimFetch[Expr\Variable[$2], $4]; } + | T_DOLLAR_OPEN_CURLY_BRACES encaps_str_varname '[' expr ']' '}' + { $$ = Expr\ArrayDimFetch[$2, $4]; } | T_CURLY_OPEN variable '}' { $$ = $2; } ; @@ -959,7 +1006,7 @@ encaps_var_offset: T_STRING { $$ = Scalar\String_[$1]; } | T_NUM_STRING { $$ = $this->parseNumString($1, attributes()); } | '-' T_NUM_STRING { $$ = $this->parseNumString('-' . $2, attributes()); } - | T_VARIABLE { $$ = Expr\Variable[parseVar($1)]; } + | plain_variable { $$ = $1; } ; %% diff --git a/app/vendor/nikic/php-parser/grammar/rebuildParsers.php b/app/vendor/nikic/php-parser/grammar/rebuildParsers.php index 340b0eacd..3be5edb64 100644 --- a/app/vendor/nikic/php-parser/grammar/rebuildParsers.php +++ b/app/vendor/nikic/php-parser/grammar/rebuildParsers.php @@ -176,11 +176,11 @@ function($matches) { } if ('makeNop' == $name) { - assertArgs(2, $args, $name); + assertArgs(3, $args, $name); return '$startAttributes = ' . $args[1] . ';' . ' if (isset($startAttributes[\'comments\']))' - . ' { ' . $args[0] . ' = new Stmt\Nop([\'comments\' => $startAttributes[\'comments\']]); }' + . ' { ' . $args[0] . ' = new Stmt\Nop($startAttributes + ' . $args[2] . '); }' . ' else { ' . $args[0] . ' = null; }'; } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Autoloader.php b/app/vendor/nikic/php-parser/lib/PhpParser/Autoloader.php deleted file mode 100644 index 809a06ed8..000000000 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Autoloader.php +++ /dev/null @@ -1,40 +0,0 @@ -name = $name; } @@ -36,7 +37,7 @@ public function __construct($name) { * @return $this The builder instance (for fluid interface) */ public function extend($class) { - $this->extends = $this->normalizeName($class); + $this->extends = BuilderHelpers::normalizeName($class); return $this; } @@ -48,9 +49,9 @@ public function extend($class) { * * @return $this The builder instance (for fluid interface) */ - public function implement() { - foreach (func_get_args() as $interface) { - $this->implements[] = $this->normalizeName($interface); + public function implement(...$interfaces) { + foreach ($interfaces as $interface) { + $this->implements[] = BuilderHelpers::normalizeName($interface); } return $this; @@ -62,7 +63,7 @@ public function implement() { * @return $this The builder instance (for fluid interface) */ public function makeAbstract() { - $this->setModifier(Stmt\Class_::MODIFIER_ABSTRACT); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT); return $this; } @@ -73,7 +74,7 @@ public function makeAbstract() { * @return $this The builder instance (for fluid interface) */ public function makeFinal() { - $this->setModifier(Stmt\Class_::MODIFIER_FINAL); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL); return $this; } @@ -86,21 +87,21 @@ public function makeFinal() { * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { - $stmt = $this->normalizeNode($stmt); - - $targets = array( - 'Stmt_TraitUse' => &$this->uses, - 'Stmt_ClassConst' => &$this->constants, - 'Stmt_Property' => &$this->properties, - 'Stmt_ClassMethod' => &$this->methods, - ); - - $type = $stmt->getType(); - if (!isset($targets[$type])) { - throw new \LogicException(sprintf('Unexpected node of type "%s"', $type)); + $stmt = BuilderHelpers::normalizeNode($stmt); + + $targets = [ + Stmt\TraitUse::class => &$this->uses, + Stmt\ClassConst::class => &$this->constants, + Stmt\Property::class => &$this->properties, + Stmt\ClassMethod::class => &$this->methods, + ]; + + $class = \get_class($stmt); + if (!isset($targets[$class])) { + throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType())); } - $targets[$type][] = $stmt; + $targets[$class][] = $stmt; return $this; } @@ -110,12 +111,12 @@ public function addStmt($stmt) { * * @return Stmt\Class_ The built class node */ - public function getNode() { - return new Stmt\Class_($this->name, array( + public function getNode() : PhpParser\Node { + return new Stmt\Class_($this->name, [ 'flags' => $this->flags, 'extends' => $this->extends, 'implements' => $this->implements, 'stmts' => array_merge($this->uses, $this->constants, $this->properties, $this->methods), - ), $this->attributes); + ], $this->attributes); } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php index 30a1937f9..830949928 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Declaration.php @@ -1,12 +1,13 @@ -attributes['comments'] = array( - $this->normalizeDocComment($docComment) - ); + $this->attributes['comments'] = [ + BuilderHelpers::normalizeDocComment($docComment) + ]; return $this; } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php index 28a2ea618..8e7db399d 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/FunctionLike.php @@ -1,14 +1,14 @@ -normalizeNode($param); + $param = BuilderHelpers::normalizeNode($param); if (!$param instanceof Node\Param) { throw new \LogicException(sprintf('Expected parameter node, got "%s"', $param->getType())); @@ -61,14 +61,13 @@ public function addParams(array $params) { /** * Sets the return type for PHP 7. * - * @param string|Node\Name|Node\NullableType $type One of array, callable, string, int, float, bool, iterable, - * or a class/interface name. + * @param string|Node\Name|Node\NullableType $type One of array, callable, string, int, float, + * bool, iterable, or a class/interface name. * * @return $this The builder instance (for fluid interface) */ - public function setReturnType($type) - { - $this->returnType = $this->normalizeType($type); + public function setReturnType($type) { + $this->returnType = BuilderHelpers::normalizeType($type); return $this; } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php index 228bdfaa2..56eda2a81 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Function_.php @@ -1,22 +1,23 @@ -name = $name; } @@ -28,7 +29,7 @@ public function __construct($name) { * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { - $this->stmts[] = $this->normalizeNode($stmt); + $this->stmts[] = BuilderHelpers::normalizeStmt($stmt); return $this; } @@ -38,12 +39,12 @@ public function addStmt($stmt) { * * @return Stmt\Function_ The built function node */ - public function getNode() { - return new Stmt\Function_($this->name, array( + public function getNode() : Node { + return new Stmt\Function_($this->name, [ 'byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, - ), $this->attributes); + ], $this->attributes); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php index 8ebb292a5..87e5b93ee 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Interface_.php @@ -1,24 +1,25 @@ -name = $name; } @@ -29,9 +30,9 @@ public function __construct($name) { * * @return $this The builder instance (for fluid interface) */ - public function extend() { - foreach (func_get_args() as $interface) { - $this->extends[] = $this->normalizeName($interface); + public function extend(...$interfaces) { + foreach ($interfaces as $interface) { + $this->extends[] = BuilderHelpers::normalizeName($interface); } return $this; @@ -45,22 +46,16 @@ public function extend() { * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { - $stmt = $this->normalizeNode($stmt); + $stmt = BuilderHelpers::normalizeNode($stmt); - $type = $stmt->getType(); - switch ($type) { - case 'Stmt_ClassConst': - $this->constants[] = $stmt; - break; - - case 'Stmt_ClassMethod': - // we erase all statements in the body of an interface method - $stmt->stmts = null; - $this->methods[] = $stmt; - break; - - default: - throw new \LogicException(sprintf('Unexpected node of type "%s"', $type)); + if ($stmt instanceof Stmt\ClassConst) { + $this->constants[] = $stmt; + } elseif ($stmt instanceof Stmt\ClassMethod) { + // we erase all statements in the body of an interface method + $stmt->stmts = null; + $this->methods[] = $stmt; + } else { + throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType())); } return $this; @@ -71,10 +66,10 @@ public function addStmt($stmt) { * * @return Stmt\Interface_ The built interface node */ - public function getNode() { - return new Stmt\Interface_($this->name, array( + public function getNode() : PhpParser\Node { + return new Stmt\Interface_($this->name, [ 'extends' => $this->extends, 'stmts' => array_merge($this->constants, $this->methods), - ), $this->attributes); + ], $this->attributes); } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php index 1ed75eeda..a3e867659 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Method.php @@ -1,8 +1,9 @@ -name = $name; } @@ -29,7 +30,7 @@ public function __construct($name) { * @return $this The builder instance (for fluid interface) */ public function makePublic() { - $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC); return $this; } @@ -40,7 +41,7 @@ public function makePublic() { * @return $this The builder instance (for fluid interface) */ public function makeProtected() { - $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED); return $this; } @@ -51,7 +52,7 @@ public function makeProtected() { * @return $this The builder instance (for fluid interface) */ public function makePrivate() { - $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE); return $this; } @@ -62,7 +63,7 @@ public function makePrivate() { * @return $this The builder instance (for fluid interface) */ public function makeStatic() { - $this->setModifier(Stmt\Class_::MODIFIER_STATIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC); return $this; } @@ -77,7 +78,7 @@ public function makeAbstract() { throw new \LogicException('Cannot make method with statements abstract'); } - $this->setModifier(Stmt\Class_::MODIFIER_ABSTRACT); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_ABSTRACT); $this->stmts = null; // abstract methods don't have statements return $this; @@ -89,7 +90,7 @@ public function makeAbstract() { * @return $this The builder instance (for fluid interface) */ public function makeFinal() { - $this->setModifier(Stmt\Class_::MODIFIER_FINAL); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_FINAL); return $this; } @@ -106,7 +107,7 @@ public function addStmt($stmt) { throw new \LogicException('Cannot add statements to an abstract method'); } - $this->stmts[] = $this->normalizeNode($stmt); + $this->stmts[] = BuilderHelpers::normalizeStmt($stmt); return $this; } @@ -116,13 +117,13 @@ public function addStmt($stmt) { * * @return Stmt\ClassMethod The built method node */ - public function getNode() { - return new Stmt\ClassMethod($this->name, array( + public function getNode() : Node { + return new Stmt\ClassMethod($this->name, [ 'flags' => $this->flags, 'byRef' => $this->returnByRef, 'params' => $this->params, 'returnType' => $this->returnType, 'stmts' => $this->stmts, - ), $this->attributes); + ], $this->attributes); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php index fe636c4ff..b9ccab3ec 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Namespace_.php @@ -1,15 +1,16 @@ -name = null !== $name ? $this->normalizeName($name) : null; + $this->name = null !== $name ? BuilderHelpers::normalizeName($name) : null; } /** @@ -28,7 +29,7 @@ public function __construct($name) { * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { - $this->stmts[] = $this->normalizeNode($stmt); + $this->stmts[] = BuilderHelpers::normalizeStmt($stmt); return $this; } @@ -38,7 +39,7 @@ public function addStmt($stmt) { * * @return Node The built node */ - public function getNode() { + public function getNode() : Node { return new Stmt\Namespace_($this->name, $this->stmts, $this->attributes); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php index c029e748b..184813a65 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Param.php @@ -1,11 +1,12 @@ -name = $name; } @@ -35,27 +36,40 @@ public function __construct($name) { * @return $this The builder instance (for fluid interface) */ public function setDefault($value) { - $this->default = $this->normalizeValue($value); + $this->default = BuilderHelpers::normalizeValue($value); return $this; } /** - * Sets type hint for the parameter. + * Sets type for the parameter. * - * @param string|Node\Name|Node\NullableType $type Type hint to use + * @param string|Node\Name|Node\NullableType $type Parameter type * * @return $this The builder instance (for fluid interface) */ - public function setTypeHint($type) { - $this->type = $this->normalizeType($type); - if ($this->type === 'void') { + public function setType($type) { + $this->type = BuilderHelpers::normalizeType($type); + if ($this->type == 'void') { throw new \LogicException('Parameter type cannot be void'); } return $this; } + /** + * Sets type for the parameter. + * + * @param string|Node\Name|Node\NullableType $type Parameter type + * + * @return $this The builder instance (for fluid interface) + * + * @deprecated Use setType() instead + */ + public function setTypeHint($type) { + return $this->setType($type); + } + /** * Make the parameter accept the value by reference. * @@ -83,9 +97,10 @@ public function makeVariadic() { * * @return Node\Param The built parameter node */ - public function getNode() { + public function getNode() : Node { return new Node\Param( - $this->name, $this->default, $this->type, $this->byRef, $this->variadic + new Node\Expr\Variable($this->name), + $this->default, $this->type, $this->byRef, $this->variadic ); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php index 053c851b9..439bd09c6 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Property.php @@ -1,24 +1,25 @@ -name = $name; } @@ -28,7 +29,7 @@ public function __construct($name) { * @return $this The builder instance (for fluid interface) */ public function makePublic() { - $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PUBLIC); return $this; } @@ -39,7 +40,7 @@ public function makePublic() { * @return $this The builder instance (for fluid interface) */ public function makeProtected() { - $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PROTECTED); return $this; } @@ -50,7 +51,7 @@ public function makeProtected() { * @return $this The builder instance (for fluid interface) */ public function makePrivate() { - $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_PRIVATE); return $this; } @@ -61,7 +62,7 @@ public function makePrivate() { * @return $this The builder instance (for fluid interface) */ public function makeStatic() { - $this->setModifier(Stmt\Class_::MODIFIER_STATIC); + $this->flags = BuilderHelpers::addModifier($this->flags, Stmt\Class_::MODIFIER_STATIC); return $this; } @@ -74,7 +75,7 @@ public function makeStatic() { * @return $this The builder instance (for fluid interface) */ public function setDefault($value) { - $this->default = $this->normalizeValue($value); + $this->default = BuilderHelpers::normalizeValue($value); return $this; } @@ -87,9 +88,9 @@ public function setDefault($value) { * @return $this The builder instance (for fluid interface) */ public function setDocComment($docComment) { - $this->attributes = array( - 'comments' => array($this->normalizeDocComment($docComment)) - ); + $this->attributes = [ + 'comments' => [BuilderHelpers::normalizeDocComment($docComment)] + ]; return $this; } @@ -99,13 +100,13 @@ public function setDocComment($docComment) { * * @return Stmt\Property The built property node */ - public function getNode() { + public function getNode() : PhpParser\Node { return new Stmt\Property( $this->flags !== 0 ? $this->flags : Stmt\Class_::MODIFIER_PUBLIC, - array( + [ new Stmt\PropertyProperty($this->name, $this->default) - ), + ], $this->attributes ); } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php new file mode 100644 index 000000000..311e8cd7b --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUse.php @@ -0,0 +1,64 @@ +and($trait); + } + } + + /** + * Adds used trait. + * + * @param Node\Name|string $trait Trait name + * + * @return $this The builder instance (for fluid interface) + */ + public function and($trait) { + $this->traits[] = BuilderHelpers::normalizeName($trait); + return $this; + } + + /** + * Adds trait adaptation. + * + * @param Stmt\TraitUseAdaptation|Builder\TraitUseAdaptation $adaptation Trait adaptation + * + * @return $this The builder instance (for fluid interface) + */ + public function with($adaptation) { + $adaptation = BuilderHelpers::normalizeNode($adaptation); + + if (!$adaptation instanceof Stmt\TraitUseAdaptation) { + throw new \LogicException('Adaptation must have type TraitUseAdaptation'); + } + + $this->adaptations[] = $adaptation; + return $this; + } + + /** + * Returns the built node. + * + * @return Node The built node + */ + public function getNode() : Node { + return new Stmt\TraitUse($this->traits, $this->adaptations); + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php new file mode 100644 index 000000000..eb6c0b622 --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/TraitUseAdaptation.php @@ -0,0 +1,148 @@ +type = self::TYPE_UNDEFINED; + + $this->trait = is_null($trait)? null: BuilderHelpers::normalizeName($trait); + $this->method = BuilderHelpers::normalizeIdentifier($method); + } + + /** + * Sets alias of method. + * + * @param Node\Identifier|string $alias Alias for adaptated method + * + * @return $this The builder instance (for fluid interface) + */ + public function as($alias) { + if ($this->type === self::TYPE_UNDEFINED) { + $this->type = self::TYPE_ALIAS; + } + + if ($this->type !== self::TYPE_ALIAS) { + throw new \LogicException('Cannot set alias for not alias adaptation buider'); + } + + $this->alias = $alias; + return $this; + } + + /** + * Sets adaptated method public. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePublic() { + $this->setModifier(Stmt\Class_::MODIFIER_PUBLIC); + return $this; + } + + /** + * Sets adaptated method protected. + * + * @return $this The builder instance (for fluid interface) + */ + public function makeProtected() { + $this->setModifier(Stmt\Class_::MODIFIER_PROTECTED); + return $this; + } + + /** + * Sets adaptated method private. + * + * @return $this The builder instance (for fluid interface) + */ + public function makePrivate() { + $this->setModifier(Stmt\Class_::MODIFIER_PRIVATE); + return $this; + } + + /** + * Adds overwritten traits. + * + * @param Node\Name|string ...$traits Traits for overwrite + * + * @return $this The builder instance (for fluid interface) + */ + public function insteadof(...$traits) { + if ($this->type === self::TYPE_UNDEFINED) { + if (is_null($this->trait)) { + throw new \LogicException('Precedence adaptation must have trait'); + } + + $this->type = self::TYPE_PRECEDENCE; + } + + if ($this->type !== self::TYPE_PRECEDENCE) { + throw new \LogicException('Cannot add overwritten traits for not precedence adaptation buider'); + } + + foreach ($traits as $trait) { + $this->insteadof[] = BuilderHelpers::normalizeName($trait); + } + + return $this; + } + + protected function setModifier(int $modifier) { + if ($this->type === self::TYPE_UNDEFINED) { + $this->type = self::TYPE_ALIAS; + } + + if ($this->type !== self::TYPE_ALIAS) { + throw new \LogicException('Cannot set access modifier for not alias adaptation buider'); + } + + if (is_null($this->modifier)) { + $this->modifier = $modifier; + } else { + throw new \LogicException('Multiple access type modifiers are not allowed'); + } + } + + /** + * Returns the built node. + * + * @return Node The built node + */ + public function getNode() : Node { + switch ($this->type) { + case self::TYPE_ALIAS: + return new Stmt\TraitUseAdaptation\Alias($this->trait, $this->method, $this->modifier, $this->alias); + case self::TYPE_PRECEDENCE: + return new Stmt\TraitUseAdaptation\Precedence($this->trait, $this->method, $this->insteadof); + default: + throw new \LogicException('Type of adaptation is not defined'); + } + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php index 7b004fa96..a836d40c6 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Trait_.php @@ -1,23 +1,24 @@ -name = $name; } @@ -29,13 +30,13 @@ public function __construct($name) { * @return $this The builder instance (for fluid interface) */ public function addStmt($stmt) { - $stmt = $this->normalizeNode($stmt); + $stmt = BuilderHelpers::normalizeNode($stmt); if ($stmt instanceof Stmt\Property) { $this->properties[] = $stmt; - } else if ($stmt instanceof Stmt\ClassMethod) { + } elseif ($stmt instanceof Stmt\ClassMethod) { $this->methods[] = $stmt; - } else if ($stmt instanceof Stmt\TraitUse) { + } elseif ($stmt instanceof Stmt\TraitUse) { $this->uses[] = $stmt; } else { throw new \LogicException(sprintf('Unexpected node of type "%s"', $stmt->getType())); @@ -49,11 +50,11 @@ public function addStmt($stmt) { * * @return Stmt\Trait_ The built interface node */ - public function getNode() { + public function getNode() : PhpParser\Node { return new Stmt\Trait_( - $this->name, array( + $this->name, [ 'stmts' => array_merge($this->uses, $this->properties, $this->methods) - ), $this->attributes + ], $this->attributes ); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php index f6d3a856f..2026a1726 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Builder/Use_.php @@ -1,15 +1,14 @@ -name = $this->normalizeName($name); + public function __construct($name, int $type) { + $this->name = BuilderHelpers::normalizeName($name); $this->type = $type; } @@ -32,27 +31,19 @@ public function __construct($name, $type) { * * @return $this The builder instance (for fluid interface) */ - protected function as_($alias) { + public function as(string $alias) { $this->alias = $alias; return $this; } - public function __call($name, $args) { - if (method_exists($this, $name . '_')) { - return call_user_func_array(array($this, $name . '_'), $args); - } - - throw new \LogicException(sprintf('Method "%s" does not exist', $name)); - } /** * Returns the built node. * * @return Node The built node */ - public function getNode() { - $alias = null !== $this->alias ? $this->alias : $this->name->getLast(); - return new Stmt\Use_(array( - new Stmt\UseUse($this->name, $alias) - ), $this->type); + public function getNode() : Node { + return new Stmt\Use_([ + new Stmt\UseUse($this->name, $this->alias) + ], $this->type); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/BuilderAbstract.php b/app/vendor/nikic/php-parser/lib/PhpParser/BuilderAbstract.php deleted file mode 100644 index e353963e6..000000000 --- a/app/vendor/nikic/php-parser/lib/PhpParser/BuilderAbstract.php +++ /dev/null @@ -1,175 +0,0 @@ -getNode(); - } elseif ($node instanceof Node) { - return $node; - } - - throw new \LogicException('Expected node or builder object'); - } - - /** - * Normalizes a name: Converts plain string names to PhpParser\Node\Name. - * - * @param Name|string $name The name to normalize - * - * @return Name The normalized name - */ - protected function normalizeName($name) { - if ($name instanceof Name) { - return $name; - } elseif (is_string($name)) { - if (!$name) { - throw new \LogicException('Name cannot be empty'); - } - - if ($name[0] == '\\') { - return new Name\FullyQualified(substr($name, 1)); - } elseif (0 === strpos($name, 'namespace\\')) { - return new Name\Relative(substr($name, strlen('namespace\\'))); - } else { - return new Name($name); - } - } - - throw new \LogicException('Name must be a string or an instance of PhpParser\Node\Name'); - } - - /** - * Normalizes a type: Converts plain-text type names into proper AST representation. - * - * In particular, builtin types are left as strings, custom types become Names and nullables - * are wrapped in NullableType nodes. - * - * @param Name|string|NullableType $type The type to normalize - * - * @return Name|string|NullableType The normalized type - */ - protected function normalizeType($type) { - if (!is_string($type)) { - if (!$type instanceof Name && !$type instanceof NullableType) { - throw new \LogicException( - 'Type must be a string, or an instance of Name or NullableType'); - } - return $type; - } - - $nullable = false; - if (strlen($type) > 0 && $type[0] === '?') { - $nullable = true; - $type = substr($type, 1); - } - - $builtinTypes = array( - 'array', 'callable', 'string', 'int', 'float', 'bool', 'iterable', 'void', 'object' - ); - - $lowerType = strtolower($type); - if (in_array($lowerType, $builtinTypes)) { - $type = $lowerType; - } else { - $type = $this->normalizeName($type); - } - - if ($nullable && $type === 'void') { - throw new \LogicException('void type cannot be nullable'); - } - - return $nullable ? new Node\NullableType($type) : $type; - } - - /** - * Normalizes a value: Converts nulls, booleans, integers, - * floats, strings and arrays into their respective nodes - * - * @param mixed $value The value to normalize - * - * @return Expr The normalized value - */ - protected function normalizeValue($value) { - if ($value instanceof Node) { - return $value; - } elseif (is_null($value)) { - return new Expr\ConstFetch( - new Name('null') - ); - } elseif (is_bool($value)) { - return new Expr\ConstFetch( - new Name($value ? 'true' : 'false') - ); - } elseif (is_int($value)) { - return new Scalar\LNumber($value); - } elseif (is_float($value)) { - return new Scalar\DNumber($value); - } elseif (is_string($value)) { - return new Scalar\String_($value); - } elseif (is_array($value)) { - $items = array(); - $lastKey = -1; - foreach ($value as $itemKey => $itemValue) { - // for consecutive, numeric keys don't generate keys - if (null !== $lastKey && ++$lastKey === $itemKey) { - $items[] = new Expr\ArrayItem( - $this->normalizeValue($itemValue) - ); - } else { - $lastKey = null; - $items[] = new Expr\ArrayItem( - $this->normalizeValue($itemValue), - $this->normalizeValue($itemKey) - ); - } - } - - return new Expr\Array_($items); - } else { - throw new \LogicException('Invalid value'); - } - } - - /** - * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc. - * - * @param Comment\Doc|string $docComment The doc comment to normalize - * - * @return Comment\Doc The normalized doc comment - */ - protected function normalizeDocComment($docComment) { - if ($docComment instanceof Comment\Doc) { - return $docComment; - } else if (is_string($docComment)) { - return new Comment\Doc($docComment); - } else { - throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc'); - } - } - - /** - * Sets a modifier in the $this->type property. - * - * @param int $modifier Modifier to set - */ - protected function setModifier($modifier) { - Stmt\Class_::verifyModifier($this->flags, $modifier); - $this->flags |= $modifier; - } -} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php b/app/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php index 42c7f612c..77d282e01 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/BuilderFactory.php @@ -1,21 +1,16 @@ -args($args) + ); + } + + /** + * Creates a method call node. + * + * @param Expr $var Variable the method is called on + * @param string|Identifier|Expr $name Method name + * @param array $args Method arguments + * + * @return Expr\MethodCall + */ + public function methodCall(Expr $var, $name, array $args = []) : Expr\MethodCall { + return new Expr\MethodCall( + $var, + BuilderHelpers::normalizeIdentifierOrExpr($name), + $this->args($args) + ); + } + + /** + * Creates a static method call node. + * + * @param string|Name|Expr $class Class name + * @param string|Identifier|Expr $name Method name + * @param array $args Method arguments + * + * @return Expr\StaticCall + */ + public function staticCall($class, $name, array $args = []) : Expr\StaticCall { + return new Expr\StaticCall( + BuilderHelpers::normalizeNameOrExpr($class), + BuilderHelpers::normalizeIdentifierOrExpr($name), + $this->args($args) + ); + } + + /** + * Creates an object creation node. + * + * @param string|Name|Expr $class Class name + * @param array $args Constructor arguments + * + * @return Expr\New_ + */ + public function new($class, array $args = []) : Expr\New_ { + return new Expr\New_( + BuilderHelpers::normalizeNameOrExpr($class), + $this->args($args) + ); + } + + /** + * Creates a constant fetch node. + * + * @param string|Name $name Constant name + * + * @return Expr\ConstFetch + */ + public function constFetch($name) : Expr\ConstFetch { + return new Expr\ConstFetch(BuilderHelpers::normalizeName($name)); + } + + /** + * Creates a property fetch node. + * + * @param Expr $var Variable holding object + * @param string|Identifier|Expr $name Property name + * + * @return Expr\PropertyFetch + */ + public function propertyFetch(Expr $var, $name) : Expr\PropertyFetch { + return new Expr\PropertyFetch($var, BuilderHelpers::normalizeIdentifierOrExpr($name)); + } + + /** + * Creates a class constant fetch node. + * + * @param string|Name|Expr $class Class name + * @param string|Identifier $name Constant name + * + * @return Expr\ClassConstFetch + */ + public function classConstFetch($class, $name): Expr\ClassConstFetch { + return new Expr\ClassConstFetch( + BuilderHelpers::normalizeNameOrExpr($class), + BuilderHelpers::normalizeIdentifier($name) + ); + } + + /** + * Creates nested Concat nodes from a list of expressions. + * + * @param Expr|string ...$exprs Expressions or literal strings + * + * @return Concat + */ + public function concat(...$exprs) : Concat { + $numExprs = count($exprs); + if ($numExprs < 2) { + throw new \LogicException('Expected at least two expressions'); + } + + $lastConcat = $this->normalizeStringExpr($exprs[0]); + for ($i = 1; $i < $numExprs; $i++) { + $lastConcat = new Concat($lastConcat, $this->normalizeStringExpr($exprs[$i])); + } + return $lastConcat; + } + + /** + * @param string|Expr $expr + * @return Expr + */ + private function normalizeStringExpr($expr) : Expr { + if ($expr instanceof Expr) { + return $expr; + } + + if (\is_string($expr)) { + return new String_($expr); } - throw new \LogicException(sprintf('Method "%s" does not exist', $name)); + throw new \LogicException('Expected string or Expr'); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php b/app/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php new file mode 100644 index 000000000..790e8877e --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/BuilderHelpers.php @@ -0,0 +1,277 @@ +getNode(); + } elseif ($node instanceof Node) { + return $node; + } + + throw new \LogicException('Expected node or builder object'); + } + + /** + * Normalizes a node to a statement. + * + * Expressions are wrapped in a Stmt\Expression node. + * + * @param Node|Builder $node The node to normalize + * + * @return Stmt The normalized statement node + */ + public static function normalizeStmt($node) : Stmt { + $node = self::normalizeNode($node); + if ($node instanceof Stmt) { + return $node; + } + + if ($node instanceof Expr) { + return new Stmt\Expression($node); + } + + throw new \LogicException('Expected statement or expression node'); + } + + /** + * Normalizes strings to Identifier. + * + * @param string|Identifier $name The identifier to normalize + * + * @return Identifier The normalized identifier + */ + public static function normalizeIdentifier($name) : Identifier { + if ($name instanceof Identifier) { + return $name; + } + + if (\is_string($name)) { + return new Identifier($name); + } + + throw new \LogicException('Expected string or instance of Node\Identifier'); + } + + /** + * Normalizes strings to Identifier, also allowing expressions. + * + * @param string|Identifier|Expr $name The identifier to normalize + * + * @return Identifier|Expr The normalized identifier or expression + */ + public static function normalizeIdentifierOrExpr($name) { + if ($name instanceof Identifier || $name instanceof Expr) { + return $name; + } + + if (\is_string($name)) { + return new Identifier($name); + } + + throw new \LogicException('Expected string or instance of Node\Identifier or Node\Expr'); + } + + /** + * Normalizes a name: Converts string names to Name nodes. + * + * @param Name|string $name The name to normalize + * + * @return Name The normalized name + */ + public static function normalizeName($name) : Name { + return self::normalizeNameCommon($name, false); + } + + /** + * Normalizes a name: Converts string names to Name nodes, while also allowing expressions. + * + * @param Expr|Name|string $name The name to normalize + * + * @return Name|Expr The normalized name or expression + */ + public static function normalizeNameOrExpr($name) { + return self::normalizeNameCommon($name, true); + } + + /** + * Normalizes a name: Converts string names to Name nodes, optionally allowing expressions. + * + * @param Expr|Name|string $name The name to normalize + * @param bool $allowExpr Whether to also allow expressions + * + * @return Name|Expr The normalized name, or expression (if allowed) + */ + private static function normalizeNameCommon($name, bool $allowExpr) { + if ($name instanceof Name) { + return $name; + } elseif (is_string($name)) { + if (!$name) { + throw new \LogicException('Name cannot be empty'); + } + + if ($name[0] === '\\') { + return new Name\FullyQualified(substr($name, 1)); + } elseif (0 === strpos($name, 'namespace\\')) { + return new Name\Relative(substr($name, strlen('namespace\\'))); + } else { + return new Name($name); + } + } + + if ($allowExpr) { + if ($name instanceof Expr) { + return $name; + } + throw new \LogicException( + 'Name must be a string or an instance of Node\Name or Node\Expr' + ); + } else { + throw new \LogicException('Name must be a string or an instance of Node\Name'); + } + } + + /** + * Normalizes a type: Converts plain-text type names into proper AST representation. + * + * In particular, builtin types become Identifiers, custom types become Names and nullables + * are wrapped in NullableType nodes. + * + * @param string|Name|Identifier|NullableType $type The type to normalize + * + * @return Name|Identifier|NullableType The normalized type + */ + public static function normalizeType($type) { + if (!is_string($type)) { + if (!$type instanceof Name && !$type instanceof Identifier + && !$type instanceof NullableType) { + throw new \LogicException( + 'Type must be a string, or an instance of Name, Identifier or NullableType'); + } + return $type; + } + + $nullable = false; + if (strlen($type) > 0 && $type[0] === '?') { + $nullable = true; + $type = substr($type, 1); + } + + $builtinTypes = [ + 'array', 'callable', 'string', 'int', 'float', 'bool', 'iterable', 'void', 'object' + ]; + + $lowerType = strtolower($type); + if (in_array($lowerType, $builtinTypes)) { + $type = new Identifier($lowerType); + } else { + $type = self::normalizeName($type); + } + + if ($nullable && (string) $type === 'void') { + throw new \LogicException('void type cannot be nullable'); + } + + return $nullable ? new Node\NullableType($type) : $type; + } + + /** + * Normalizes a value: Converts nulls, booleans, integers, + * floats, strings and arrays into their respective nodes + * + * @param Node\Expr|bool|null|int|float|string|array $value The value to normalize + * + * @return Expr The normalized value + */ + public static function normalizeValue($value) : Expr { + if ($value instanceof Node\Expr) { + return $value; + } elseif (is_null($value)) { + return new Expr\ConstFetch( + new Name('null') + ); + } elseif (is_bool($value)) { + return new Expr\ConstFetch( + new Name($value ? 'true' : 'false') + ); + } elseif (is_int($value)) { + return new Scalar\LNumber($value); + } elseif (is_float($value)) { + return new Scalar\DNumber($value); + } elseif (is_string($value)) { + return new Scalar\String_($value); + } elseif (is_array($value)) { + $items = []; + $lastKey = -1; + foreach ($value as $itemKey => $itemValue) { + // for consecutive, numeric keys don't generate keys + if (null !== $lastKey && ++$lastKey === $itemKey) { + $items[] = new Expr\ArrayItem( + self::normalizeValue($itemValue) + ); + } else { + $lastKey = null; + $items[] = new Expr\ArrayItem( + self::normalizeValue($itemValue), + self::normalizeValue($itemKey) + ); + } + } + + return new Expr\Array_($items); + } else { + throw new \LogicException('Invalid value'); + } + } + + /** + * Normalizes a doc comment: Converts plain strings to PhpParser\Comment\Doc. + * + * @param Comment\Doc|string $docComment The doc comment to normalize + * + * @return Comment\Doc The normalized doc comment + */ + public static function normalizeDocComment($docComment) : Comment\Doc { + if ($docComment instanceof Comment\Doc) { + return $docComment; + } elseif (is_string($docComment)) { + return new Comment\Doc($docComment); + } else { + throw new \LogicException('Doc comment must be a string or an instance of PhpParser\Comment\Doc'); + } + } + + /** + * Adds a modifier and returns new modifier bitmask. + * + * @param int $modifiers Existing modifiers + * @param int $modifier Modifier to set + * + * @return int New modifiers + */ + public static function addModifier(int $modifiers, int $modifier) : int { + Stmt\Class_::verifyModifier($modifiers, $modifier); + return $modifiers | $modifier; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Comment.php b/app/vendor/nikic/php-parser/lib/PhpParser/Comment.php index 4034cfa6b..5da842095 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Comment.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Comment.php @@ -1,4 +1,4 @@ -text = $text; $this->line = $startLine; $this->filePos = $startFilePos; + $this->tokenPos = $startTokenPos; } /** @@ -26,7 +31,7 @@ public function __construct($text, $startLine = -1, $startFilePos = -1) { * * @return string The comment text (including comment delimiters like /*) */ - public function getText() { + public function getText() : string { return $this->text; } @@ -35,7 +40,7 @@ public function getText() { * * @return int Line number */ - public function getLine() { + public function getLine() : int { return $this->line; } @@ -44,16 +49,25 @@ public function getLine() { * * @return int File offset */ - public function getFilePos() { + public function getFilePos() : int { return $this->filePos; } + /** + * Gets the token offset the comment started on. + * + * @return int Token offset + */ + public function getTokenPos() : int { + return $this->tokenPos; + } + /** * Gets the comment text. * * @return string The comment text (including comment delimiters like /*) */ - public function __toString() { + public function __toString() : string { return $this->text; } @@ -114,9 +128,17 @@ public function getReformattedText() { return $text; } - private function getShortestWhitespacePrefixLen($str) { + /** + * Get length of shortest whitespace prefix (at the start of a line). + * + * If there is a line with no prefix whitespace, 0 is a valid return value. + * + * @param string $str String to check + * @return int Length in characters. Tabs count as single characters. + */ + private function getShortestWhitespacePrefixLen(string $str) : int { $lines = explode("\n", $str); - $shortestPrefixLen = INF; + $shortestPrefixLen = \INF; foreach ($lines as $line) { preg_match('(^\s*)', $line, $matches); $prefixLen = strlen($matches[0]); @@ -127,7 +149,11 @@ private function getShortestWhitespacePrefixLen($str) { return $shortestPrefixLen; } - public function jsonSerialize() { + /** + * @return array + * @psalm-return array{nodeType:string, text:mixed, line:mixed, filePos:mixed} + */ + public function jsonSerialize() : array { // Technically not a node, but we make it look like one anyway $type = $this instanceof Comment\Doc ? 'Comment_Doc' : 'Comment'; return [ @@ -135,6 +161,7 @@ public function jsonSerialize() { 'text' => $this->text, 'line' => $this->line, 'filePos' => $this->filePos, + 'tokenPos' => $this->tokenPos, ]; } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php b/app/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php index 24fc6c9ec..a9db6128f 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Comment/Doc.php @@ -1,7 +1,7 @@ -fallbackEvaluator = $fallbackEvaluator ?? function(Expr $expr) { + throw new ConstExprEvaluationException( + "Expression of type {$expr->getType()} cannot be evaluated" + ); + }; + } + + /** + * Silently evaluates a constant expression into a PHP value. + * + * Thrown Errors, warnings or notices will be converted into a ConstExprEvaluationException. + * The original source of the exception is available through getPrevious(). + * + * If some part of the expression cannot be evaluated, the fallback evaluator passed to the + * constructor will be invoked. By default, if no fallback is provided, an exception of type + * ConstExprEvaluationException is thrown. + * + * See class doc comment for caveats and limitations. + * + * @param Expr $expr Constant expression to evaluate + * @return mixed Result of evaluation + * + * @throws ConstExprEvaluationException if the expression cannot be evaluated or an error occurred + */ + public function evaluateSilently(Expr $expr) { + set_error_handler(function($num, $str, $file, $line) { + throw new \ErrorException($str, 0, $num, $file, $line); + }); + + try { + return $this->evaluate($expr); + } catch (\Throwable $e) { + if (!$e instanceof ConstExprEvaluationException) { + $e = new ConstExprEvaluationException( + "An error occurred during constant expression evaluation", 0, $e); + } + throw $e; + } finally { + restore_error_handler(); + } + } + + /** + * Directly evaluates a constant expression into a PHP value. + * + * May generate Error exceptions, warnings or notices. Use evaluateSilently() to convert these + * into a ConstExprEvaluationException. + * + * If some part of the expression cannot be evaluated, the fallback evaluator passed to the + * constructor will be invoked. By default, if no fallback is provided, an exception of type + * ConstExprEvaluationException is thrown. + * + * See class doc comment for caveats and limitations. + * + * @param Expr $expr Constant expression to evaluate + * @return mixed Result of evaluation + * + * @throws ConstExprEvaluationException if the expression cannot be evaluated + */ + public function evaluateDirectly(Expr $expr) { + return $this->evaluate($expr); + } + + private function evaluate(Expr $expr) { + if ($expr instanceof Scalar\LNumber + || $expr instanceof Scalar\DNumber + || $expr instanceof Scalar\String_ + ) { + return $expr->value; + } + + if ($expr instanceof Expr\Array_) { + return $this->evaluateArray($expr); + } + + // Unary operators + if ($expr instanceof Expr\UnaryPlus) { + return +$this->evaluate($expr->expr); + } + if ($expr instanceof Expr\UnaryMinus) { + return -$this->evaluate($expr->expr); + } + if ($expr instanceof Expr\BooleanNot) { + return !$this->evaluate($expr->expr); + } + if ($expr instanceof Expr\BitwiseNot) { + return ~$this->evaluate($expr->expr); + } + + if ($expr instanceof Expr\BinaryOp) { + return $this->evaluateBinaryOp($expr); + } + + if ($expr instanceof Expr\Ternary) { + return $this->evaluateTernary($expr); + } + + if ($expr instanceof Expr\ArrayDimFetch && null !== $expr->dim) { + return $this->evaluate($expr->var)[$this->evaluate($expr->dim)]; + } + + if ($expr instanceof Expr\ConstFetch) { + return $this->evaluateConstFetch($expr); + } + + return ($this->fallbackEvaluator)($expr); + } + + private function evaluateArray(Expr\Array_ $expr) { + $array = []; + foreach ($expr->items as $item) { + if (null !== $item->key) { + $array[$this->evaluate($item->key)] = $this->evaluate($item->value); + } else { + $array[] = $this->evaluate($item->value); + } + } + return $array; + } + + private function evaluateTernary(Expr\Ternary $expr) { + if (null === $expr->if) { + return $this->evaluate($expr->cond) ?: $this->evaluate($expr->else); + } + + return $this->evaluate($expr->cond) + ? $this->evaluate($expr->if) + : $this->evaluate($expr->else); + } + + private function evaluateBinaryOp(Expr\BinaryOp $expr) { + if ($expr instanceof Expr\BinaryOp\Coalesce + && $expr->left instanceof Expr\ArrayDimFetch + ) { + // This needs to be special cased to respect BP_VAR_IS fetch semantics + return $this->evaluate($expr->left->var)[$this->evaluate($expr->left->dim)] + ?? $this->evaluate($expr->right); + } + + // The evaluate() calls are repeated in each branch, because some of the operators are + // short-circuiting and evaluating the RHS in advance may be illegal in that case + $l = $expr->left; + $r = $expr->right; + switch ($expr->getOperatorSigil()) { + case '&': return $this->evaluate($l) & $this->evaluate($r); + case '|': return $this->evaluate($l) | $this->evaluate($r); + case '^': return $this->evaluate($l) ^ $this->evaluate($r); + case '&&': return $this->evaluate($l) && $this->evaluate($r); + case '||': return $this->evaluate($l) || $this->evaluate($r); + case '??': return $this->evaluate($l) ?? $this->evaluate($r); + case '.': return $this->evaluate($l) . $this->evaluate($r); + case '/': return $this->evaluate($l) / $this->evaluate($r); + case '==': return $this->evaluate($l) == $this->evaluate($r); + case '>': return $this->evaluate($l) > $this->evaluate($r); + case '>=': return $this->evaluate($l) >= $this->evaluate($r); + case '===': return $this->evaluate($l) === $this->evaluate($r); + case 'and': return $this->evaluate($l) and $this->evaluate($r); + case 'or': return $this->evaluate($l) or $this->evaluate($r); + case 'xor': return $this->evaluate($l) xor $this->evaluate($r); + case '-': return $this->evaluate($l) - $this->evaluate($r); + case '%': return $this->evaluate($l) % $this->evaluate($r); + case '*': return $this->evaluate($l) * $this->evaluate($r); + case '!=': return $this->evaluate($l) != $this->evaluate($r); + case '!==': return $this->evaluate($l) !== $this->evaluate($r); + case '+': return $this->evaluate($l) + $this->evaluate($r); + case '**': return $this->evaluate($l) ** $this->evaluate($r); + case '<<': return $this->evaluate($l) << $this->evaluate($r); + case '>>': return $this->evaluate($l) >> $this->evaluate($r); + case '<': return $this->evaluate($l) < $this->evaluate($r); + case '<=': return $this->evaluate($l) <= $this->evaluate($r); + case '<=>': return $this->evaluate($l) <=> $this->evaluate($r); + } + + throw new \Exception('Should not happen'); + } + + private function evaluateConstFetch(Expr\ConstFetch $expr) { + $name = $expr->name->toLowerString(); + switch ($name) { + case 'null': return null; + case 'false': return false; + case 'true': return true; + } + + return ($this->fallbackEvaluator)($expr); + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Error.php b/app/vendor/nikic/php-parser/lib/PhpParser/Error.php index 4a23294fe..d1fb959d1 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Error.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Error.php @@ -1,4 +1,4 @@ -rawMessage = (string) $message; + public function __construct(string $message, $attributes = []) { + $this->rawMessage = $message; if (is_array($attributes)) { $this->attributes = $attributes; } else { - $this->attributes = array('startLine' => $attributes); + $this->attributes = ['startLine' => $attributes]; } $this->updateMessage(); } @@ -29,7 +29,7 @@ public function __construct($message, $attributes = array()) { * * @return string Error message */ - public function getRawMessage() { + public function getRawMessage() : string { return $this->rawMessage; } @@ -38,8 +38,8 @@ public function getRawMessage() { * * @return int Error start line */ - public function getStartLine() { - return isset($this->attributes['startLine']) ? $this->attributes['startLine'] : -1; + public function getStartLine() : int { + return $this->attributes['startLine'] ?? -1; } /** @@ -47,22 +47,21 @@ public function getStartLine() { * * @return int Error end line */ - public function getEndLine() { - return isset($this->attributes['endLine']) ? $this->attributes['endLine'] : -1; + public function getEndLine() : int { + return $this->attributes['endLine'] ?? -1; } - /** * Gets the attributes of the node/token the error occurred at. * * @return array */ - public function getAttributes() { + public function getAttributes() : array { return $this->attributes; } /** - * Sets the attributes of the node/token the error occured at. + * Sets the attributes of the node/token the error occurred at. * * @param array $attributes */ @@ -76,8 +75,8 @@ public function setAttributes(array $attributes) { * * @param string $message Error message */ - public function setRawMessage($message) { - $this->rawMessage = (string) $message; + public function setRawMessage(string $message) { + $this->rawMessage = $message; $this->updateMessage(); } @@ -86,8 +85,8 @@ public function setRawMessage($message) { * * @param int $line Error start line */ - public function setStartLine($line) { - $this->attributes['startLine'] = (int) $line; + public function setStartLine(int $line) { + $this->attributes['startLine'] = $line; $this->updateMessage(); } @@ -98,8 +97,8 @@ public function setStartLine($line) { * * @return bool */ - public function hasColumnInfo() { - return isset($this->attributes['startFilePos']) && isset($this->attributes['endFilePos']); + public function hasColumnInfo() : bool { + return isset($this->attributes['startFilePos'], $this->attributes['endFilePos']); } /** @@ -108,7 +107,7 @@ public function hasColumnInfo() { * @param string $code Source code of the file * @return int */ - public function getStartColumn($code) { + public function getStartColumn(string $code) : int { if (!$this->hasColumnInfo()) { throw new \RuntimeException('Error does not have column information'); } @@ -122,7 +121,7 @@ public function getStartColumn($code) { * @param string $code Source code of the file * @return int */ - public function getEndColumn($code) { + public function getEndColumn(string $code) : int { if (!$this->hasColumnInfo()) { throw new \RuntimeException('Error does not have column information'); } @@ -130,7 +129,14 @@ public function getEndColumn($code) { return $this->toColumn($code, $this->attributes['endFilePos']); } - public function getMessageWithColumnInfo($code) { + /** + * Formats message including line and column information. + * + * @param string $code Source code associated with the error, for calculation of the columns + * + * @return string Formatted message + */ + public function getMessageWithColumnInfo(string $code) : string { return sprintf( '%s from %d:%d to %d:%d', $this->getRawMessage(), $this->getStartLine(), $this->getStartColumn($code), @@ -138,7 +144,15 @@ public function getMessageWithColumnInfo($code) { ); } - private function toColumn($code, $pos) { + /** + * Converts a file offset into a column. + * + * @param string $code Source code that $pos indexes into + * @param int $pos 0-based position in $code + * + * @return int 1-based column (relative to start of line) + */ + private function toColumn(string $code, int $pos) : int { if ($pos > strlen($code)) { throw new \RuntimeException('Invalid position information'); } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php b/app/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php index fa2c2f8ce..d620e7453 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler.php @@ -1,4 +1,4 @@ -errors; } @@ -33,7 +33,7 @@ public function getErrors() { * * @return bool */ - public function hasErrors() { + public function hasErrors() : bool { return !empty($this->errors); } @@ -43,4 +43,4 @@ public function hasErrors() { public function clearErrors() { $this->errors = []; } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php b/app/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php index c5a76dd0c..aeee989b1 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/ErrorHandler/Throwing.php @@ -1,4 +1,4 @@ -type = $type; + $this->old = $old; + $this->new = $new; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php b/app/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php new file mode 100644 index 000000000..7f218c74f --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Internal/Differ.php @@ -0,0 +1,164 @@ +isEqual = $isEqual; + } + + /** + * Calculate diff (edit script) from $old to $new. + * + * @param array $old Original array + * @param array $new New array + * + * @return DiffElem[] Diff (edit script) + */ + public function diff(array $old, array $new) { + list($trace, $x, $y) = $this->calculateTrace($old, $new); + return $this->extractDiff($trace, $x, $y, $old, $new); + } + + /** + * Calculate diff, including "replace" operations. + * + * If a sequence of remove operations is followed by the same number of add operations, these + * will be coalesced into replace operations. + * + * @param array $old Original array + * @param array $new New array + * + * @return DiffElem[] Diff (edit script), including replace operations + */ + public function diffWithReplacements(array $old, array $new) { + return $this->coalesceReplacements($this->diff($old, $new)); + } + + private function calculateTrace(array $a, array $b) { + $n = \count($a); + $m = \count($b); + $max = $n + $m; + $v = [1 => 0]; + $trace = []; + for ($d = 0; $d <= $max; $d++) { + $trace[] = $v; + for ($k = -$d; $k <= $d; $k += 2) { + if ($k === -$d || ($k !== $d && $v[$k-1] < $v[$k+1])) { + $x = $v[$k+1]; + } else { + $x = $v[$k-1] + 1; + } + + $y = $x - $k; + while ($x < $n && $y < $m && ($this->isEqual)($a[$x], $b[$y])) { + $x++; + $y++; + } + + $v[$k] = $x; + if ($x >= $n && $y >= $m) { + return [$trace, $x, $y]; + } + } + } + throw new \Exception('Should not happen'); + } + + private function extractDiff(array $trace, int $x, int $y, array $a, array $b) { + $result = []; + for ($d = \count($trace) - 1; $d >= 0; $d--) { + $v = $trace[$d]; + $k = $x - $y; + + if ($k === -$d || ($k !== $d && $v[$k-1] < $v[$k+1])) { + $prevK = $k + 1; + } else { + $prevK = $k - 1; + } + + $prevX = $v[$prevK]; + $prevY = $prevX - $prevK; + + while ($x > $prevX && $y > $prevY) { + $result[] = new DiffElem(DiffElem::TYPE_KEEP, $a[$x-1], $b[$y-1]); + $x--; + $y--; + } + + if ($d === 0) { + break; + } + + while ($x > $prevX) { + $result[] = new DiffElem(DiffElem::TYPE_REMOVE, $a[$x-1], null); + $x--; + } + + while ($y > $prevY) { + $result[] = new DiffElem(DiffElem::TYPE_ADD, null, $b[$y-1]); + $y--; + } + } + return array_reverse($result); + } + + /** + * Coalesce equal-length sequences of remove+add into a replace operation. + * + * @param DiffElem[] $diff + * @return DiffElem[] + */ + private function coalesceReplacements(array $diff) { + $newDiff = []; + $c = \count($diff); + for ($i = 0; $i < $c; $i++) { + $diffType = $diff[$i]->type; + if ($diffType !== DiffElem::TYPE_REMOVE) { + $newDiff[] = $diff[$i]; + continue; + } + + $j = $i; + while ($j < $c && $diff[$j]->type === DiffElem::TYPE_REMOVE) { + $j++; + } + + $k = $j; + while ($k < $c && $diff[$k]->type === DiffElem::TYPE_ADD) { + $k++; + } + + if ($j - $i === $k - $j) { + $len = $j - $i; + for ($n = 0; $n < $len; $n++) { + $newDiff[] = new DiffElem( + DiffElem::TYPE_REPLACE, $diff[$i + $n]->old, $diff[$j + $n]->new + ); + } + } else { + for (; $i < $k; $i++) { + $newDiff[] = $diff[$i]; + } + } + $i = $k - 1; + } + return $newDiff; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php b/app/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php new file mode 100644 index 000000000..dcacbfb62 --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php @@ -0,0 +1,56 @@ +args = $args; + $this->extends = $extends; + $this->implements = $implements; + $this->stmts = $stmts; + } + + public static function fromNewNode(Expr\New_ $newNode) { + $class = $newNode->class; + assert($class instanceof Node\Stmt\Class_); + assert($class->name === null); + return new self( + $newNode->args, $class->extends, $class->implements, + $class->stmts, $newNode->getAttributes() + ); + } + + public function getType() : string { + return 'Expr_PrintableNewAnonClass'; + } + + public function getSubNodeNames() : array { + return ['args', 'extends', 'implements', 'stmts']; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php b/app/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php new file mode 100644 index 000000000..cf9e00abf --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Internal/TokenStream.php @@ -0,0 +1,256 @@ +tokens = $tokens; + $this->indentMap = $this->calcIndentMap(); + } + + /** + * Whether the given position is immediately surrounded by parenthesis. + * + * @param int $startPos Start position + * @param int $endPos End position + * + * @return bool + */ + public function haveParens(int $startPos, int $endPos) : bool { + return $this->haveTokenImmediativelyBefore($startPos, '(') + && $this->haveTokenImmediatelyAfter($endPos, ')'); + } + + /** + * Whether the given position is immediately surrounded by braces. + * + * @param int $startPos Start position + * @param int $endPos End position + * + * @return bool + */ + public function haveBraces(int $startPos, int $endPos) : bool { + return $this->haveTokenImmediativelyBefore($startPos, '{') + && $this->haveTokenImmediatelyAfter($endPos, '}'); + } + + /** + * Check whether the position is directly preceded by a certain token type. + * + * During this check whitespace and comments are skipped. + * + * @param int $pos Position before which the token should occur + * @param int|string $expectedTokenType Token to check for + * + * @return bool Whether the expected token was found + */ + public function haveTokenImmediativelyBefore(int $pos, $expectedTokenType) : bool { + $tokens = $this->tokens; + $pos--; + for (; $pos >= 0; $pos--) { + $tokenType = $tokens[$pos][0]; + if ($tokenType === $expectedTokenType) { + return true; + } + if ($tokenType !== \T_WHITESPACE + && $tokenType !== \T_COMMENT && $tokenType !== \T_DOC_COMMENT) { + break; + } + } + return false; + } + + /** + * Check whether the position is directly followed by a certain token type. + * + * During this check whitespace and comments are skipped. + * + * @param int $pos Position after which the token should occur + * @param int|string $expectedTokenType Token to check for + * + * @return bool Whether the expected token was found + */ + public function haveTokenImmediatelyAfter(int $pos, $expectedTokenType) : bool { + $tokens = $this->tokens; + $pos++; + for (; $pos < \count($tokens); $pos++) { + $tokenType = $tokens[$pos][0]; + if ($tokenType === $expectedTokenType) { + return true; + } + if ($tokenType !== \T_WHITESPACE + && $tokenType !== \T_COMMENT && $tokenType !== \T_DOC_COMMENT) { + break; + } + } + return false; + } + + public function skipLeft(int $pos, $skipTokenType) { + $tokens = $this->tokens; + + $pos = $this->skipLeftWhitespace($pos); + if ($skipTokenType === \T_WHITESPACE) { + return $pos; + } + + if ($tokens[$pos][0] !== $skipTokenType) { + // Shouldn't happen. The skip token MUST be there + throw new \Exception('Encountered unexpected token'); + } + $pos--; + + return $this->skipLeftWhitespace($pos); + } + + public function skipRight(int $pos, $skipTokenType) { + $tokens = $this->tokens; + + $pos = $this->skipRightWhitespace($pos); + if ($skipTokenType === \T_WHITESPACE) { + return $pos; + } + + if ($tokens[$pos][0] !== $skipTokenType) { + // Shouldn't happen. The skip token MUST be there + throw new \Exception('Encountered unexpected token'); + } + $pos++; + + return $this->skipRightWhitespace($pos); + } + + /** + * Return first non-whitespace token position smaller or equal to passed position. + * + * @param int $pos Token position + * @return int Non-whitespace token position + */ + public function skipLeftWhitespace(int $pos) { + $tokens = $this->tokens; + for (; $pos >= 0; $pos--) { + $type = $tokens[$pos][0]; + if ($type !== \T_WHITESPACE && $type !== \T_COMMENT && $type !== \T_DOC_COMMENT) { + break; + } + } + return $pos; + } + + /** + * Return first non-whitespace position greater or equal to passed position. + * + * @param int $pos Token position + * @return int Non-whitespace token position + */ + public function skipRightWhitespace(int $pos) { + $tokens = $this->tokens; + for ($count = \count($tokens); $pos < $count; $pos++) { + $type = $tokens[$pos][0]; + if ($type !== \T_WHITESPACE && $type !== \T_COMMENT && $type !== \T_DOC_COMMENT) { + break; + } + } + return $pos; + } + + public function findRight($pos, $findTokenType) { + $tokens = $this->tokens; + for ($count = \count($tokens); $pos < $count; $pos++) { + $type = $tokens[$pos][0]; + if ($type === $findTokenType) { + return $pos; + } + } + return -1; + } + + /** + * Get indentation before token position. + * + * @param int $pos Token position + * + * @return int Indentation depth (in spaces) + */ + public function getIndentationBefore(int $pos) : int { + return $this->indentMap[$pos]; + } + + /** + * Get the code corresponding to a token offset range, optionally adjusted for indentation. + * + * @param int $from Token start position (inclusive) + * @param int $to Token end position (exclusive) + * @param int $indent By how much the code should be indented (can be negative as well) + * + * @return string Code corresponding to token range, adjusted for indentation + */ + public function getTokenCode(int $from, int $to, int $indent) : string { + $tokens = $this->tokens; + $result = ''; + for ($pos = $from; $pos < $to; $pos++) { + $token = $tokens[$pos]; + if (\is_array($token)) { + $type = $token[0]; + $content = $token[1]; + if ($type === \T_CONSTANT_ENCAPSED_STRING || $type === \T_ENCAPSED_AND_WHITESPACE) { + $result .= $content; + } else { + // TODO Handle non-space indentation + if ($indent < 0) { + $result .= str_replace("\n" . str_repeat(" ", -$indent), "\n", $content); + } elseif ($indent > 0) { + $result .= str_replace("\n", "\n" . str_repeat(" ", $indent), $content); + } else { + $result .= $content; + } + } + } else { + $result .= $token; + } + } + return $result; + } + + /** + * Precalculate the indentation at every token position. + * + * @return int[] Token position to indentation map + */ + private function calcIndentMap() { + $indentMap = []; + $indent = 0; + foreach ($this->tokens as $token) { + $indentMap[] = $indent; + + if ($token[0] === \T_WHITESPACE) { + $content = $token[1]; + $newlinePos = \strrpos($content, "\n"); + if (false !== $newlinePos) { + $indent = \strlen($content) - $newlinePos - 1; + } + } + } + + // Add a sentinel for one past end of the file + $indentMap[] = $indent; + + return $indentMap; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php b/app/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php new file mode 100644 index 000000000..25d1c6abe --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/JsonDecoder.php @@ -0,0 +1,101 @@ +decodeRecursive($value); + } + + private function decodeRecursive($value) { + if (\is_array($value)) { + if (isset($value['nodeType'])) { + if ($value['nodeType'] === 'Comment' || $value['nodeType'] === 'Comment_Doc') { + return $this->decodeComment($value); + } + return $this->decodeNode($value); + } + return $this->decodeArray($value); + } + return $value; + } + + private function decodeArray(array $array) : array { + $decodedArray = []; + foreach ($array as $key => $value) { + $decodedArray[$key] = $this->decodeRecursive($value); + } + return $decodedArray; + } + + private function decodeNode(array $value) : Node { + $nodeType = $value['nodeType']; + if (!\is_string($nodeType)) { + throw new \RuntimeException('Node type must be a string'); + } + + $reflectionClass = $this->reflectionClassFromNodeType($nodeType); + /** @var Node $node */ + $node = $reflectionClass->newInstanceWithoutConstructor(); + + if (isset($value['attributes'])) { + if (!\is_array($value['attributes'])) { + throw new \RuntimeException('Attributes must be an array'); + } + + $node->setAttributes($this->decodeArray($value['attributes'])); + } + + foreach ($value as $name => $subNode) { + if ($name === 'nodeType' || $name === 'attributes') { + continue; + } + + $node->$name = $this->decodeRecursive($subNode); + } + + return $node; + } + + private function decodeComment(array $value) : Comment { + $className = $value['nodeType'] === 'Comment' ? Comment::class : Comment\Doc::class; + if (!isset($value['text'])) { + throw new \RuntimeException('Comment must have text'); + } + + return new $className( + $value['text'], $value['line'] ?? -1, $value['filePos'] ?? -1, $value['tokenPos'] ?? -1 + ); + } + + private function reflectionClassFromNodeType(string $nodeType) : \ReflectionClass { + if (!isset($this->reflectionClassCache[$nodeType])) { + $className = $this->classNameFromNodeType($nodeType); + $this->reflectionClassCache[$nodeType] = new \ReflectionClass($className); + } + return $this->reflectionClassCache[$nodeType]; + } + + private function classNameFromNodeType(string $nodeType) : string { + $className = 'PhpParser\\Node\\' . strtr($nodeType, '_', '\\'); + if (class_exists($className)) { + return $className; + } + + $className .= '_'; + if (class_exists($className)) { + return $className; + } + + throw new \RuntimeException("Unknown node type \"$nodeType\""); + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Lexer.php b/app/vendor/nikic/php-parser/lib/PhpParser/Lexer.php index 75d3f35a3..125c3b806 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Lexer.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Lexer.php @@ -1,4 +1,4 @@ -tokenMap = $this->createTokenMap(); // map of tokens to drop while lexing (the map is only used for isset lookup, // that's why the value is simply set to 1; the value is never actually used.) $this->dropTokens = array_fill_keys( - array(T_WHITESPACE, T_OPEN_TAG, T_COMMENT, T_DOC_COMMENT), 1 + [\T_WHITESPACE, \T_OPEN_TAG, \T_COMMENT, \T_DOC_COMMENT], 1 ); // the usedAttributes member is a map of the used attribute names to a dummy // value (here "true") - $options += array( - 'usedAttributes' => array('comments', 'startLine', 'endLine'), - ); + $options += [ + 'usedAttributes' => ['comments', 'startLine', 'endLine'], + ]; $this->usedAttributes = array_fill_keys($options['usedAttributes'], true); } @@ -55,7 +55,7 @@ public function __construct(array $options = array()) { * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to * ErrorHandler\Throwing */ - public function startLexing($code, ErrorHandler $errorHandler = null) { + public function startLexing(string $code, ErrorHandler $errorHandler = null) { if (null === $errorHandler) { $errorHandler = new ErrorHandler\Throwing(); } @@ -71,7 +71,7 @@ public function startLexing($code, ErrorHandler $errorHandler = null) { $scream = ini_set('xdebug.scream', '0'); - $this->resetErrors(); + error_clear_last(); $this->tokens = @token_get_all($code); $this->handleErrors($errorHandler); @@ -80,17 +80,6 @@ public function startLexing($code, ErrorHandler $errorHandler = null) { } } - protected function resetErrors() { - if (function_exists('error_clear_last')) { - error_clear_last(); - } else { - // set error_get_last() to defined state by forcing an undefined variable error - set_error_handler(function() { return false; }, 0); - @$undefinedVariable; - restore_error_handler(); - } - } - private function handleInvalidCharacterRange($start, $end, $line, ErrorHandler $errorHandler) { for ($i = $start; $i < $end; $i++) { $chr = $this->code[$i]; @@ -117,22 +106,30 @@ private function handleInvalidCharacterRange($start, $end, $line, ErrorHandler $ } } - private function isUnterminatedComment($token) { - return ($token[0] === T_COMMENT || $token[0] === T_DOC_COMMENT) + /** + * Check whether comment token is unterminated. + * + * @return bool + */ + private function isUnterminatedComment($token) : bool { + return ($token[0] === \T_COMMENT || $token[0] === \T_DOC_COMMENT) && substr($token[1], 0, 2) === '/*' && substr($token[1], -2) !== '*/'; } - private function errorMayHaveOccurred() { + /** + * Check whether an error *may* have occurred during tokenization. + * + * @return bool + */ + private function errorMayHaveOccurred() : bool { if (defined('HHVM_VERSION')) { // In HHVM token_get_all() does not throw warnings, so we need to conservatively // assume that an error occurred return true; } - $error = error_get_last(); - return null !== $error - && false === strpos($error['message'], 'Undefined variable'); + return null !== error_get_last(); } protected function handleErrors(ErrorHandler $errorHandler) { @@ -147,7 +144,7 @@ protected function handleErrors(ErrorHandler $errorHandler) { $filePos = 0; $line = 1; - foreach ($this->tokens as $i => $token) { + foreach ($this->tokens as $token) { $tokenValue = \is_string($token) ? $token : $token[1]; $tokenLen = \strlen($tokenValue); @@ -156,7 +153,7 @@ protected function handleErrors(ErrorHandler $errorHandler) { $nextFilePos = strpos($this->code, $tokenValue, $filePos); $this->handleInvalidCharacterRange( $filePos, $nextFilePos, $line, $errorHandler); - $filePos = $nextFilePos; + $filePos = (int) $nextFilePos; } $filePos += $tokenLen; @@ -176,7 +173,7 @@ protected function handleErrors(ErrorHandler $errorHandler) { // Emulate the PHP behavior $isDocComment = isset($comment[3]) && $comment[3] === '*'; - $this->tokens[] = [$isDocComment ? T_DOC_COMMENT : T_COMMENT, $comment, $line]; + $this->tokens[] = [$isDocComment ? \T_DOC_COMMENT : \T_COMMENT, $comment, $line]; } else { // Invalid characters at the end of the input $this->handleInvalidCharacterRange( @@ -221,9 +218,9 @@ protected function handleErrors(ErrorHandler $errorHandler) { * * @return int Token id */ - public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { - $startAttributes = array(); - $endAttributes = array(); + public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) : int { + $startAttributes = []; + $endAttributes = []; while (1) { if (isset($this->tokens[++$this->pos])) { @@ -256,20 +253,20 @@ public function getNextToken(&$value = null, &$startAttributes = null, &$endAttr } elseif (!isset($this->dropTokens[$token[0]])) { $value = $token[1]; $id = $this->tokenMap[$token[0]]; - if (T_CLOSE_TAG === $token[0]) { + if (\T_CLOSE_TAG === $token[0]) { $this->prevCloseTagHasNewline = false !== strpos($token[1], "\n"); - } else if (T_INLINE_HTML === $token[0]) { + } elseif (\T_INLINE_HTML === $token[0]) { $startAttributes['hasLeadingNewline'] = $this->prevCloseTagHasNewline; } $this->line += substr_count($value, "\n"); $this->filePos += \strlen($value); } else { - if (T_COMMENT === $token[0] || T_DOC_COMMENT === $token[0]) { + if (\T_COMMENT === $token[0] || \T_DOC_COMMENT === $token[0]) { if (isset($this->usedAttributes['comments'])) { - $comment = T_DOC_COMMENT === $token[0] - ? new Comment\Doc($token[1], $this->line, $this->filePos) - : new Comment($token[1], $this->line, $this->filePos); + $comment = \T_DOC_COMMENT === $token[0] + ? new Comment\Doc($token[1], $this->line, $this->filePos, $this->pos) + : new Comment($token[1], $this->line, $this->filePos, $this->pos); $startAttributes['comments'][] = $comment; } } @@ -305,7 +302,7 @@ public function getNextToken(&$value = null, &$startAttributes = null, &$endAttr * * @return array Array of tokens in token_get_all() format */ - public function getTokens() { + public function getTokens() : array { return $this->tokens; } @@ -314,7 +311,7 @@ public function getTokens() { * * @return string Remaining text */ - public function handleHaltCompiler() { + public function handleHaltCompiler() : string { // text after T_HALT_COMPILER, still including (); $textAfter = substr($this->code, $this->filePos); @@ -329,7 +326,7 @@ public function handleHaltCompiler() { $this->pos = count($this->tokens); // return with (); removed - return (string) substr($textAfter, strlen($matches[0])); // (string) converts false to '' + return substr($textAfter, strlen($matches[0])); } /** @@ -341,26 +338,26 @@ public function handleHaltCompiler() { * * @return array The token map */ - protected function createTokenMap() { - $tokenMap = array(); + protected function createTokenMap() : array { + $tokenMap = []; // 256 is the minimum possible token number, as everything below // it is an ASCII value for ($i = 256; $i < 1000; ++$i) { - if (T_DOUBLE_COLON === $i) { + if (\T_DOUBLE_COLON === $i) { // T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM $tokenMap[$i] = Tokens::T_PAAMAYIM_NEKUDOTAYIM; - } elseif(T_OPEN_TAG_WITH_ECHO === $i) { + } elseif(\T_OPEN_TAG_WITH_ECHO === $i) { // T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO $tokenMap[$i] = Tokens::T_ECHO; - } elseif(T_CLOSE_TAG === $i) { + } elseif(\T_CLOSE_TAG === $i) { // T_CLOSE_TAG is equivalent to ';' $tokenMap[$i] = ord(';'); } elseif ('UNKNOWN' !== $name = token_name($i)) { if ('T_HASHBANG' === $name) { // HHVM uses a special token for #! hashbang lines $tokenMap[$i] = Tokens::T_INLINE_HTML; - } else if (defined($name = Tokens::class . '::' . $name)) { + } elseif (defined($name = Tokens::class . '::' . $name)) { // Other tokens can be mapped directly $tokenMap[$i] = constant($name); } @@ -369,11 +366,11 @@ protected function createTokenMap() { // HHVM uses a special token for numbers that overflow to double if (defined('T_ONUMBER')) { - $tokenMap[T_ONUMBER] = Tokens::T_DNUMBER; + $tokenMap[\T_ONUMBER] = Tokens::T_DNUMBER; } // HHVM also has a separate token for the __COMPILER_HALT_OFFSET__ constant if (defined('T_COMPILER_HALT_OFFSET')) { - $tokenMap[T_COMPILER_HALT_OFFSET] = Tokens::T_STRING; + $tokenMap[\T_COMPILER_HALT_OFFSET] = Tokens::T_STRING; } return $tokenMap; diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php b/app/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php index 739a328ab..647aaa34c 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php @@ -1,174 +1,8 @@ -newKeywords = array(); - foreach ($newKeywordsPerVersion as $version => $newKeywords) { - if (version_compare(PHP_VERSION, $version, '>=')) { - break; - } - - $this->newKeywords += $newKeywords; - } - - if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) { - return; - } - $this->tokenMap[self::T_COALESCE] = Tokens::T_COALESCE; - $this->tokenMap[self::T_SPACESHIP] = Tokens::T_SPACESHIP; - $this->tokenMap[self::T_YIELD_FROM] = Tokens::T_YIELD_FROM; - - if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) { - return; - } - $this->tokenMap[self::T_ELLIPSIS] = Tokens::T_ELLIPSIS; - $this->tokenMap[self::T_POW] = Tokens::T_POW; - $this->tokenMap[self::T_POW_EQUAL] = Tokens::T_POW_EQUAL; - } - - public function startLexing($code, ErrorHandler $errorHandler = null) { - $this->inObjectAccess = false; - - parent::startLexing($code, $errorHandler); - if ($this->requiresEmulation($code)) { - $this->emulateTokens(); - } - } - - /* - * Checks if the code is potentially using features that require emulation. - */ - protected function requiresEmulation($code) { - if (version_compare(PHP_VERSION, self::PHP_7_0, '>=')) { - return false; - } - - if (preg_match('(\?\?|<=>|yield[ \n\r\t]+from)', $code)) { - return true; - } - - if (version_compare(PHP_VERSION, self::PHP_5_6, '>=')) { - return false; - } - - return preg_match('(\.\.\.|(?tokens); $i < $c; ++$i) { - $replace = null; - if (isset($this->tokens[$i + 1])) { - if ($this->tokens[$i] === '?' && $this->tokens[$i + 1] === '?') { - array_splice($this->tokens, $i, 2, array( - array(self::T_COALESCE, '??', $line) - )); - $c--; - continue; - } - if ($this->tokens[$i][0] === T_IS_SMALLER_OR_EQUAL - && $this->tokens[$i + 1] === '>' - ) { - array_splice($this->tokens, $i, 2, array( - array(self::T_SPACESHIP, '<=>', $line) - )); - $c--; - continue; - } - if ($this->tokens[$i] === '*' && $this->tokens[$i + 1] === '*') { - array_splice($this->tokens, $i, 2, array( - array(self::T_POW, '**', $line) - )); - $c--; - continue; - } - if ($this->tokens[$i] === '*' && $this->tokens[$i + 1][0] === T_MUL_EQUAL) { - array_splice($this->tokens, $i, 2, array( - array(self::T_POW_EQUAL, '**=', $line) - )); - $c--; - continue; - } - } - - if (isset($this->tokens[$i + 2])) { - if ($this->tokens[$i][0] === T_YIELD && $this->tokens[$i + 1][0] === T_WHITESPACE - && $this->tokens[$i + 2][0] === T_STRING - && !strcasecmp($this->tokens[$i + 2][1], 'from') - ) { - array_splice($this->tokens, $i, 3, array( - array( - self::T_YIELD_FROM, - $this->tokens[$i][1] . $this->tokens[$i + 1][1] . $this->tokens[$i + 2][1], - $line - ) - )); - $c -= 2; - $line += substr_count($this->tokens[$i][1], "\n"); - continue; - } - if ($this->tokens[$i] === '.' && $this->tokens[$i + 1] === '.' - && $this->tokens[$i + 2] === '.' - ) { - array_splice($this->tokens, $i, 3, array( - array(self::T_ELLIPSIS, '...', $line) - )); - $c -= 2; - continue; - } - } - - if (\is_array($this->tokens[$i])) { - $line += substr_count($this->tokens[$i][1], "\n"); - } - } - } - - public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { - $token = parent::getNextToken($value, $startAttributes, $endAttributes); - - // replace new keywords by their respective tokens. This is not done - // if we currently are in an object access (e.g. in $obj->namespace - // "namespace" stays a T_STRING tokens and isn't converted to T_NAMESPACE) - if (Tokens::T_STRING === $token && !$this->inObjectAccess) { - if (isset($this->newKeywords[strtolower($value)])) { - return $this->newKeywords[strtolower($value)]; - } - } else { - // keep track of whether we currently are in an object access (after ->) - $this->inObjectAccess = Tokens::T_OBJECT_OPERATOR === $token; - } - - return $token; - } + /* No features requiring emulation have been added in PHP > 7.0 */ } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NameContext.php b/app/vendor/nikic/php-parser/lib/PhpParser/NameContext.php new file mode 100644 index 000000000..777a4afde --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NameContext.php @@ -0,0 +1,285 @@ + [aliasName => originalName]] */ + protected $aliases = []; + + /** @var Name[][] Same as $aliases but preserving original case */ + protected $origAliases = []; + + /** @var ErrorHandler Error handler */ + protected $errorHandler; + + /** + * Create a name context. + * + * @param ErrorHandler $errorHandler Error handling used to report errors + */ + public function __construct(ErrorHandler $errorHandler) { + $this->errorHandler = $errorHandler; + } + + /** + * Start a new namespace. + * + * This also resets the alias table. + * + * @param Name|null $namespace Null is the global namespace + */ + public function startNamespace(Name $namespace = null) { + $this->namespace = $namespace; + $this->origAliases = $this->aliases = [ + Stmt\Use_::TYPE_NORMAL => [], + Stmt\Use_::TYPE_FUNCTION => [], + Stmt\Use_::TYPE_CONSTANT => [], + ]; + } + + /** + * Add an alias / import. + * + * @param Name $name Original name + * @param string $aliasName Aliased name + * @param int $type One of Stmt\Use_::TYPE_* + * @param array $errorAttrs Attributes to use to report an error + */ + public function addAlias(Name $name, string $aliasName, int $type, array $errorAttrs = []) { + // Constant names are case sensitive, everything else case insensitive + if ($type === Stmt\Use_::TYPE_CONSTANT) { + $aliasLookupName = $aliasName; + } else { + $aliasLookupName = strtolower($aliasName); + } + + if (isset($this->aliases[$type][$aliasLookupName])) { + $typeStringMap = [ + Stmt\Use_::TYPE_NORMAL => '', + Stmt\Use_::TYPE_FUNCTION => 'function ', + Stmt\Use_::TYPE_CONSTANT => 'const ', + ]; + + $this->errorHandler->handleError(new Error( + sprintf( + 'Cannot use %s%s as %s because the name is already in use', + $typeStringMap[$type], $name, $aliasName + ), + $errorAttrs + )); + return; + } + + $this->aliases[$type][$aliasLookupName] = $name; + $this->origAliases[$type][$aliasName] = $name; + } + + /** + * Get current namespace. + * + * @return null|Name Namespace (or null if global namespace) + */ + public function getNamespace() { + return $this->namespace; + } + + /** + * Get resolved name. + * + * @param Name $name Name to resolve + * @param int $type One of Stmt\Use_::TYPE_{FUNCTION|CONSTANT} + * + * @return null|Name Resolved name, or null if static resolution is not possible + */ + public function getResolvedName(Name $name, int $type) { + // don't resolve special class names + if ($type === Stmt\Use_::TYPE_NORMAL && $name->isSpecialClassName()) { + if (!$name->isUnqualified()) { + $this->errorHandler->handleError(new Error( + sprintf("'\\%s' is an invalid class name", $name->toString()), + $name->getAttributes() + )); + } + return $name; + } + + // fully qualified names are already resolved + if ($name->isFullyQualified()) { + return $name; + } + + // Try to resolve aliases + if (null !== $resolvedName = $this->resolveAlias($name, $type)) { + return $resolvedName; + } + + if ($type !== Stmt\Use_::TYPE_NORMAL && $name->isUnqualified()) { + if (null === $this->namespace) { + // outside of a namespace unaliased unqualified is same as fully qualified + return new FullyQualified($name, $name->getAttributes()); + } + + // Cannot resolve statically + return null; + } + + // if no alias exists prepend current namespace + return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); + } + + /** + * Get resolved class name. + * + * @param Name $name Class ame to resolve + * + * @return Name Resolved name + */ + public function getResolvedClassName(Name $name) : Name { + return $this->getResolvedName($name, Stmt\Use_::TYPE_NORMAL); + } + + /** + * Get possible ways of writing a fully qualified name (e.g., by making use of aliases). + * + * @param string $name Fully-qualified name (without leading namespace separator) + * @param int $type One of Stmt\Use_::TYPE_* + * + * @return Name[] Possible representations of the name + */ + public function getPossibleNames(string $name, int $type) : array { + $lcName = strtolower($name); + + if ($type === Stmt\Use_::TYPE_NORMAL) { + // self, parent and static must always be unqualified + if ($lcName === "self" || $lcName === "parent" || $lcName === "static") { + return [new Name($name)]; + } + } + + // Collect possible ways to write this name, starting with the fully-qualified name + $possibleNames = [new FullyQualified($name)]; + + if (null !== $nsRelativeName = $this->getNamespaceRelativeName($name, $lcName, $type)) { + // Make sure there is no alias that makes the normally namespace-relative name + // into something else + if (null === $this->resolveAlias($nsRelativeName, $type)) { + $possibleNames[] = $nsRelativeName; + } + } + + // Check for relevant namespace use statements + foreach ($this->origAliases[Stmt\Use_::TYPE_NORMAL] as $alias => $orig) { + $lcOrig = $orig->toLowerString(); + if (0 === strpos($lcName, $lcOrig . '\\')) { + $possibleNames[] = new Name($alias . substr($name, strlen($lcOrig))); + } + } + + // Check for relevant type-specific use statements + foreach ($this->origAliases[$type] as $alias => $orig) { + if ($type === Stmt\Use_::TYPE_CONSTANT) { + // Constants are are complicated-sensitive + $normalizedOrig = $this->normalizeConstName($orig->toString()); + if ($normalizedOrig === $this->normalizeConstName($name)) { + $possibleNames[] = new Name($alias); + } + } else { + // Everything else is case-insensitive + if ($orig->toLowerString() === $lcName) { + $possibleNames[] = new Name($alias); + } + } + } + + return $possibleNames; + } + + /** + * Get shortest representation of this fully-qualified name. + * + * @param string $name Fully-qualified name (without leading namespace separator) + * @param int $type One of Stmt\Use_::TYPE_* + * + * @return Name Shortest representation + */ + public function getShortName(string $name, int $type) : Name { + $possibleNames = $this->getPossibleNames($name, $type); + + // Find shortest name + $shortestName = null; + $shortestLength = \INF; + foreach ($possibleNames as $possibleName) { + $length = strlen($possibleName->toCodeString()); + if ($length < $shortestLength) { + $shortestName = $possibleName; + $shortestLength = $length; + } + } + + return $shortestName; + } + + private function resolveAlias(Name $name, $type) { + $firstPart = $name->getFirst(); + + if ($name->isQualified()) { + // resolve aliases for qualified names, always against class alias table + $checkName = strtolower($firstPart); + if (isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName])) { + $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$checkName]; + return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); + } + } elseif ($name->isUnqualified()) { + // constant aliases are case-sensitive, function aliases case-insensitive + $checkName = $type === Stmt\Use_::TYPE_CONSTANT ? $firstPart : strtolower($firstPart); + if (isset($this->aliases[$type][$checkName])) { + // resolve unqualified aliases + return new FullyQualified($this->aliases[$type][$checkName], $name->getAttributes()); + } + } + + // No applicable aliases + return null; + } + + private function getNamespaceRelativeName(string $name, string $lcName, int $type) { + if (null === $this->namespace) { + return new Name($name); + } + + if ($type === Stmt\Use_::TYPE_CONSTANT) { + // The constants true/false/null always resolve to the global symbols, even inside a + // namespace, so they may be used without qualification + if ($lcName === "true" || $lcName === "false" || $lcName === "null") { + return new Name($name); + } + } + + $namespacePrefix = strtolower($this->namespace . '\\'); + if (0 === strpos($lcName, $namespacePrefix)) { + return new Name(substr($name, strlen($namespacePrefix))); + } + + return null; + } + + private function normalizeConstName(string $name) { + $nsSep = strrpos($name, '\\'); + if (false === $nsSep) { + return $name; + } + + // Constants have case-insensitive namespace and case-sensitive short-name + $ns = substr($name, 0, $nsSep); + $shortName = substr($name, $nsSep + 1); + return strtolower($ns) . '\\' . $shortName; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node.php index 6925fd726..7f04c3432 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node.php @@ -1,4 +1,4 @@ -value = $value; $this->byRef = $byRef; $this->unpack = $unpack; } - public function getSubNodeNames() { - return array('value', 'byRef', 'unpack'); + public function getSubNodeNames() : array { + return ['value', 'byRef', 'unpack']; + } + + public function getType() : string { + return 'Arg'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php index 26322d49e..76a220f4d 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Const_.php @@ -1,12 +1,15 @@ -name = $name; + $this->name = \is_string($name) ? new Identifier($name) : $name; $this->value = $value; } - public function getSubNodeNames() { - return array('name', 'value'); + public function getSubNodeNames() : array { + return ['name', 'value']; + } + + public function getType() : string { + return 'Const'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php index 2dae5bfcd..6cf4df223 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr.php @@ -1,4 +1,4 @@ -var = $var; $this->dim = $dim; } - public function getSubNodeNames() { - return array('var', 'dim'); + public function getSubNodeNames() : array { + return ['var', 'dim']; + } + + public function getType() : string { + return 'Expr_ArrayDimFetch'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php index de73ef467..bf9c7fdef 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php @@ -1,4 +1,4 @@ -key = $key; $this->value = $value; $this->byRef = $byRef; } - public function getSubNodeNames() { - return array('key', 'value', 'byRef'); + public function getSubNodeNames() : array { + return ['key', 'value', 'byRef']; + } + + public function getType() : string { + return 'Expr_ArrayItem'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php index 9151f27d8..061c52e38 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Array_.php @@ -1,4 +1,4 @@ -items = $items; } - public function getSubNodeNames() { - return array('items'); + public function getSubNodeNames() : array { + return ['items']; + } + + public function getType() : string { + return 'Expr_Array'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php index 1f280ff0c..1306c88f2 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Assign.php @@ -1,4 +1,4 @@ -var = $var; $this->expr = $expr; } - public function getSubNodeNames() { - return array('var', 'expr'); + public function getSubNodeNames() : array { + return ['var', 'expr']; + } + + public function getType() : string { + return 'Expr_Assign'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php index 83540a072..e5bdbf58f 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp.php @@ -1,4 +1,4 @@ -var = $var; $this->expr = $expr; } - public function getSubNodeNames() { - return array('var', 'expr'); + public function getSubNodeNames() : array { + return ['var', 'expr']; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php index 9e3ed8226..420284cdc 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/AssignOp/BitwiseAnd.php @@ -1,4 +1,4 @@ -var = $var; $this->expr = $expr; } - public function getSubNodeNames() { - return array('var', 'expr'); + public function getSubNodeNames() : array { + return ['var', 'expr']; + } + + public function getType() : string { + return 'Expr_AssignRef'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php index 6f87e2350..466b01a22 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp.php @@ -1,4 +1,4 @@ -left = $left; $this->right = $right; } - public function getSubNodeNames() { - return array('left', 'right'); + public function getSubNodeNames() : array { + return ['left', 'right']; } + + /** + * Get the operator sigil for this binary operation. + * + * In the case there are multiple possible sigils for an operator, this method does not + * necessarily return the one used in the parsed code. + * + * @return string + */ + abstract public function getOperatorSigil() : string; } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php index bd6c5c1fb..d907393bf 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/BitwiseAnd.php @@ -1,4 +1,4 @@ -'; + } + + public function getType() : string { + return 'Expr_BinaryOp_Greater'; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php index 9bd93a152..d677502cf 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/GreaterOrEqual.php @@ -1,4 +1,4 @@ -='; + } + + public function getType() : string { + return 'Expr_BinaryOp_GreaterOrEqual'; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php index 9562680e7..3d96285c6 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Identical.php @@ -1,4 +1,4 @@ ->'; + } + + public function getType() : string { + return 'Expr_BinaryOp_ShiftRight'; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php index ba2c28b8b..3cb8e7e0d 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BinaryOp/Smaller.php @@ -1,4 +1,4 @@ -'; + } + + public function getType() : string { + return 'Expr_BinaryOp_Spaceship'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php index 1d9226410..f96fdddc7 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BitwiseNot.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_BitwiseNot'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php index 8f543b822..1ae74b165 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/BooleanNot.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_BooleanNot'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php index bf850dc52..8fd0285e5 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php index 08b3a384c..57cc473b6 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Cast/Array_.php @@ -1,4 +1,4 @@ -class = $class; - $this->name = $name; + $this->name = \is_string($name) ? new Identifier($name) : $name; } - public function getSubNodeNames() { - return array('class', 'name'); + public function getSubNodeNames() : array { + return ['class', 'name']; + } + + public function getType() : string { + return 'Expr_ClassConstFetch'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php index 198ec4d89..9f6931a69 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Clone_.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Clone'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php index 5d3765508..261b4440b 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Closure.php @@ -1,4 +1,4 @@ - array(): Statements * @param array $attributes Additional attributes */ - public function __construct(array $subNodes = array(), array $attributes = array()) { + public function __construct(array $subNodes = [], array $attributes = []) { parent::__construct($attributes); - $this->static = isset($subNodes['static']) ? $subNodes['static'] : false; - $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; - $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); - $this->uses = isset($subNodes['uses']) ? $subNodes['uses'] : array(); - $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; - $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + $this->static = $subNodes['static'] ?? false; + $this->byRef = $subNodes['byRef'] ?? false; + $this->params = $subNodes['params'] ?? []; + $this->uses = $subNodes['uses'] ?? []; + $returnType = $subNodes['returnType'] ?? null; + $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->stmts = $subNodes['stmts'] ?? []; } - public function getSubNodeNames() { - return array('static', 'byRef', 'params', 'uses', 'returnType', 'stmts'); + public function getSubNodeNames() : array { + return ['static', 'byRef', 'params', 'uses', 'returnType', 'stmts']; } - public function returnsByRef() { + public function returnsByRef() : bool { return $this->byRef; } - public function getParams() { + public function getParams() : array { return $this->params; } @@ -59,7 +60,12 @@ public function getReturnType() { return $this->returnType; } - public function getStmts() { + /** @return Node\Stmt[] */ + public function getStmts() : array { return $this->stmts; } + + public function getType() : string { + return 'Expr_Closure'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php index f4d02023e..4c5516846 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ClosureUse.php @@ -1,4 +1,4 @@ -var = $var; $this->byRef = $byRef; } - public function getSubNodeNames() { - return array('var', 'byRef'); + public function getSubNodeNames() : array { + return ['var', 'byRef']; + } + + public function getType() : string { + return 'Expr_ClosureUse'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php index 98e51d527..875ddf3c3 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ConstFetch.php @@ -1,4 +1,4 @@ -name = $name; } - public function getSubNodeNames() { - return array('name'); + public function getSubNodeNames() : array { + return ['name']; + } + + public function getType() : string { + return 'Expr_ConstFetch'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php index 0c0509efb..2e0c43b0e 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Empty_.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Empty'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php index 5ab8fd445..90f6cbbcd 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Error.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_ErrorSuppress'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php index eadffd008..d421595a9 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Eval_.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Eval'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php index b0b94cf7b..58134811e 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Exit'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php index 60d00507d..79457670c 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/FuncCall.php @@ -1,4 +1,4 @@ -name = $name; $this->args = $args; } - public function getSubNodeNames() { - return array('name', 'args'); + public function getSubNodeNames() : array { + return ['name', 'args']; + } + + public function getType() : string { + return 'Expr_FuncCall'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php index b27f3af18..aa6e55d18 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Include_.php @@ -1,4 +1,4 @@ -expr = $expr; $this->type = $type; } - public function getSubNodeNames() { - return array('expr', 'type'); + public function getSubNodeNames() : array { + return ['expr', 'type']; + } + + public function getType() : string { + return 'Expr_Include'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php index 69573d865..5b73d027f 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Instanceof_.php @@ -1,4 +1,4 @@ -expr = $expr; $this->class = $class; } - public function getSubNodeNames() { - return array('expr', 'class'); + public function getSubNodeNames() : array { + return ['expr', 'class']; + } + + public function getType() : string { + return 'Expr_Instanceof'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php index 4ec1d025a..5e192cfea 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Isset_.php @@ -1,4 +1,4 @@ -vars = $vars; } - public function getSubNodeNames() { - return array('vars'); + public function getSubNodeNames() : array { + return ['vars']; + } + + public function getType() : string { + return 'Expr_Isset'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php index 30f3dc165..cc156e3a6 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/List_.php @@ -1,4 +1,4 @@ -items = $items; } - public function getSubNodeNames() { - return array('items'); + public function getSubNodeNames() : array { + return ['items']; + } + + public function getType() : string { + return 'Expr_List'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php index a6cdd07c1..e0fe32710 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/MethodCall.php @@ -1,15 +1,16 @@ -var = $var; - $this->name = $name; + $this->name = \is_string($name) ? new Identifier($name) : $name; $this->args = $args; } - public function getSubNodeNames() { - return array('var', 'name', 'args'); + public function getSubNodeNames() : array { + return ['var', 'name', 'args']; + } + + public function getType() : string { + return 'Expr_MethodCall'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php index a8c87794d..f43800827 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/New_.php @@ -1,4 +1,4 @@ -class = $class; $this->args = $args; } - public function getSubNodeNames() { - return array('class', 'args'); + public function getSubNodeNames() : array { + return ['class', 'args']; + } + + public function getType() : string { + return 'Expr_New'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php index 06ce5470e..c3f21a2c3 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostDec.php @@ -1,4 +1,4 @@ -var = $var; } - public function getSubNodeNames() { - return array('var'); + public function getSubNodeNames() : array { + return ['var']; + } + + public function getType() : string { + return 'Expr_PostDec'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php index 54865ba12..e8b07d806 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PostInc.php @@ -1,4 +1,4 @@ -var = $var; } - public function getSubNodeNames() { - return array('var'); + public function getSubNodeNames() : array { + return ['var']; + } + + public function getType() : string { + return 'Expr_PostInc'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php index db30f5102..d31b2580e 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreDec.php @@ -1,4 +1,4 @@ -var = $var; } - public function getSubNodeNames() { - return array('var'); + public function getSubNodeNames() : array { + return ['var']; + } + + public function getType() : string { + return 'Expr_PreDec'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php index 06356028c..68be695b8 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PreInc.php @@ -1,4 +1,4 @@ -var = $var; } - public function getSubNodeNames() { - return array('var'); + public function getSubNodeNames() : array { + return ['var']; + } + + public function getType() : string { + return 'Expr_PreInc'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php index 0666ab84d..9d514e650 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Print_.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_Print'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php index adcf21ce1..90efef3d8 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/PropertyFetch.php @@ -1,30 +1,35 @@ -var = $var; - $this->name = $name; + $this->name = \is_string($name) ? new Identifier($name) : $name; } - public function getSubNodeNames() { - return array('var', 'name'); + public function getSubNodeNames() : array { + return ['var', 'name']; + } + + public function getType() : string { + return 'Expr_PropertyFetch'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php index 9516a32f4..59708d66a 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/ShellExec.php @@ -1,4 +1,4 @@ -parts = $parts; } - public function getSubNodeNames() { - return array('parts'); + public function getSubNodeNames() : array { + return ['parts']; + } + + public function getType() : string { + return 'Expr_ShellExec'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php index 5118f34a7..5dc2d3161 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticCall.php @@ -1,15 +1,16 @@ -class = $class; - $this->name = $name; + $this->name = \is_string($name) ? new Identifier($name) : $name; $this->args = $args; } - public function getSubNodeNames() { - return array('class', 'name', 'args'); + public function getSubNodeNames() : array { + return ['class', 'name', 'args']; + } + + public function getType() : string { + return 'Expr_StaticCall'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php index 477a69ddb..809b66620 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/StaticPropertyFetch.php @@ -1,31 +1,36 @@ -class = $class; - $this->name = $name; + $this->name = \is_string($name) ? new VarLikeIdentifier($name) : $name; } - public function getSubNodeNames() { - return array('class', 'name'); + public function getSubNodeNames() : array { + return ['class', 'name']; + } + + public function getType() : string { + return 'Expr_StaticPropertyFetch'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php index 57301390f..cb36145e2 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Ternary.php @@ -1,4 +1,4 @@ -cond = $cond; $this->if = $if; $this->else = $else; } - public function getSubNodeNames() { - return array('cond', 'if', 'else'); + public function getSubNodeNames() : array { + return ['cond', 'if', 'else']; + } + + public function getType() : string { + return 'Expr_Ternary'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php index 94635d638..90be0e05e 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryMinus.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_UnaryMinus'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php index 651412003..1a5bc6324 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/UnaryPlus.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_UnaryPlus'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php index 3ae3ecd9b..b100f2140 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Variable.php @@ -1,4 +1,4 @@ -name = $name; } - public function getSubNodeNames() { - return array('name'); + public function getSubNodeNames() : array { + return ['name']; + } + + public function getType() : string { + return 'Expr_Variable'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php index 993c82c20..ab3a27542 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/YieldFrom.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Expr_YieldFrom'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php index f3ca88e05..a28a701a5 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php @@ -1,4 +1,4 @@ -key = $key; $this->value = $value; } - public function getSubNodeNames() { - return array('key', 'value'); + public function getSubNodeNames() : array { + return ['key', 'value']; + } + + public function getType() : string { + return 'Expr_Yield'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php index 82569450c..d574e0208 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/FunctionLike.php @@ -1,4 +1,4 @@ - true, + 'parent' => true, + 'static' => true, + ]; + + /** + * Constructs an identifier node. + * + * @param string $name Identifier as string + * @param array $attributes Additional attributes + */ + public function __construct(string $name, array $attributes = []) { + parent::__construct($attributes); + $this->name = $name; + } + + public function getSubNodeNames() : array { + return ['name']; + } + + /** + * Get identifier as string. + * + * @return string Identifier as string. + */ + public function toString() : string { + return $this->name; + } + + /** + * Get lowercased identifier as string. + * + * @return string Lowercased identifier as string + */ + public function toLowerString() : string { + return strtolower($this->name); + } + + /** + * Checks whether the identifier is a special class name (self, parent or static). + * + * @return bool Whether identifier is a special class name + */ + public function isSpecialClassName() : bool { + return isset(self::$specialClassNames[strtolower($this->name)]); + } + + /** + * Get identifier as string. + * + * @return string Identifier as string + */ + public function __toString() : string { + return $this->name; + } + + public function getType() : string { + return 'Identifier'; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php index 7b8c8e232..5d923d02a 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name.php @@ -1,4 +1,4 @@ - true, + 'parent' => true, + 'static' => true, + ]; + /** * Constructs a name node. * - * @param string|array|self $name Name as string, part array or Name instance (copy ctor) - * @param array $attributes Additional attributes + * @param string|string[]|self $name Name as string, part array or Name instance (copy ctor) + * @param array $attributes Additional attributes */ - public function __construct($name, array $attributes = array()) { + public function __construct($name, array $attributes = []) { parent::__construct($attributes); $this->parts = self::prepareName($name); } - public function getSubNodeNames() { - return array('parts'); + public function getSubNodeNames() : array { + return ['parts']; } /** @@ -31,7 +37,7 @@ public function getSubNodeNames() { * * @return string First part of the name */ - public function getFirst() { + public function getFirst() : string { return $this->parts[0]; } @@ -40,7 +46,7 @@ public function getFirst() { * * @return string Last part of the name */ - public function getLast() { + public function getLast() : string { return $this->parts[count($this->parts) - 1]; } @@ -49,8 +55,8 @@ public function getLast() { * * @return bool Whether the name is unqualified */ - public function isUnqualified() { - return 1 == count($this->parts); + public function isUnqualified() : bool { + return 1 === count($this->parts); } /** @@ -58,7 +64,7 @@ public function isUnqualified() { * * @return bool Whether the name is qualified */ - public function isQualified() { + public function isQualified() : bool { return 1 < count($this->parts); } @@ -67,7 +73,7 @@ public function isQualified() { * * @return bool Whether the name is fully qualified */ - public function isFullyQualified() { + public function isFullyQualified() : bool { return false; } @@ -76,27 +82,57 @@ public function isFullyQualified() { * * @return bool Whether the name is relative */ - public function isRelative() { + public function isRelative() : bool { return false; } /** - * Returns a string representation of the name by imploding the namespace parts with the - * namespace separator. + * Returns a string representation of the name itself, without taking taking the name type into + * account (e.g., not including a leading backslash for fully qualified names). * * @return string String representation */ - public function toString() { + public function toString() : string { return implode('\\', $this->parts); } + /** + * Returns a string representation of the name as it would occur in code (e.g., including + * leading backslash for fully qualified names. + * + * @return string String representation + */ + public function toCodeString() : string { + return $this->toString(); + } + + /** + * Returns lowercased string representation of the name, without taking the name type into + * account (e.g., no leading backslash for fully qualified names). + * + * @return string Lowercased string representation + */ + public function toLowerString() : string { + return strtolower(implode('\\', $this->parts)); + } + + /** + * Checks whether the identifier is a special class name (self, parent or static). + * + * @return bool Whether identifier is a special class name + */ + public function isSpecialClassName() : bool { + return count($this->parts) === 1 + && isset(self::$specialClassNames[strtolower($this->parts[0])]); + } + /** * Returns a string representation of the name by imploding the namespace parts with the * namespace separator. * * @return string String representation */ - public function __toString() { + public function __toString() : string { return implode('\\', $this->parts); } @@ -116,7 +152,7 @@ public function __toString() { * * @return static|null Sliced name */ - public function slice($offset, $length = null) { + public function slice(int $offset, int $length = null) { $numParts = count($this->parts); $realOffset = $offset < 0 ? $offset + $numParts : $offset; @@ -152,9 +188,9 @@ public function slice($offset, $length = null) { * Name::concat($namespace, $shortName) * where $namespace is a Name node or null will work as expected. * - * @param string|array|self|null $name1 The first name - * @param string|array|self|null $name2 The second name - * @param array $attributes Attributes to assign to concatenated name + * @param string|string[]|self|null $name1 The first name + * @param string|string[]|self|null $name2 The second name + * @param array $attributes Attributes to assign to concatenated name * * @return static|null Concatenated name */ @@ -163,7 +199,7 @@ public static function concat($name1, $name2, array $attributes = []) { return null; } elseif (null === $name1) { return new static(self::prepareName($name2), $attributes); - } else if (null === $name2) { + } elseif (null === $name2) { return new static(self::prepareName($name1), $attributes); } else { return new static( @@ -176,14 +212,22 @@ public static function concat($name1, $name2, array $attributes = []) { * Prepares a (string, array or Name node) name for use in name changing methods by converting * it to an array. * - * @param string|array|self $name Name to prepare + * @param string|string[]|self $name Name to prepare * - * @return array Prepared name + * @return string[] Prepared name */ - private static function prepareName($name) { + private static function prepareName($name) : array { if (\is_string($name)) { + if ('' === $name) { + throw new \InvalidArgumentException('Name cannot be empty'); + } + return explode('\\', $name); } elseif (\is_array($name)) { + if (empty($name)) { + throw new \InvalidArgumentException('Name cannot be empty'); + } + return $name; } elseif ($name instanceof self) { return $name->parts; @@ -193,4 +237,8 @@ private static function prepareName($name) { 'Expected string, array of parts or Name instance' ); } + + public function getType() : string { + return 'Name'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php index 97cc1113d..1df93a56b 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name/FullyQualified.php @@ -1,4 +1,4 @@ -toString(); + } + + public function getType() : string { + return 'Name_FullyQualified'; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php index 25676ce69..57bf7af2b 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Name/Relative.php @@ -1,4 +1,4 @@ -toString(); + } + + public function getType() : string { + return 'Name_Relative'; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php index d887b321a..3679269e9 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/NullableType.php @@ -1,4 +1,4 @@ -type = $type; + $this->type = \is_string($type) ? new Identifier($type) : $type; } - public function getSubNodeNames() { - return array('type'); + public function getSubNodeNames() : array { + return ['type']; + } + + public function getType() : string { + return 'NullableType'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php index b35ee4ef0..0b53f67cc 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Param.php @@ -1,4 +1,4 @@ -type = $type; + $this->type = \is_string($type) ? new Identifier($type) : $type; $this->byRef = $byRef; $this->variadic = $variadic; - $this->name = $name; + $this->var = $var; $this->default = $default; } - public function getSubNodeNames() { - return array('type', 'byRef', 'variadic', 'name', 'default'); + public function getSubNodeNames() : array { + return ['type', 'byRef', 'variadic', 'var', 'default']; + } + + public function getType() : string { + return 'Param'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php index 01177532c..8117909b6 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar.php @@ -1,7 +1,7 @@ -value = $value; } - public function getSubNodeNames() { - return array('value'); + public function getSubNodeNames() : array { + return ['value']; } /** @@ -33,7 +33,7 @@ public function getSubNodeNames() { * * @return float The parsed number */ - public static function parse($str) { + public static function parse(string $str) : float { // if string contains any of .eE just cast it to float if (false !== strpbrk($str, '.eE')) { return (float) $str; @@ -61,4 +61,8 @@ public static function parse($str) { // dec return (float) $str; } + + public function getType() : string { + return 'Scalar_DNumber'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php index 4f9b433c2..0541a31e2 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/Encapsed.php @@ -1,4 +1,4 @@ -parts = $parts; } - public function getSubNodeNames() { - return array('parts'); + public function getSubNodeNames() : array { + return ['parts']; + } + + public function getType() : string { + return 'Scalar_Encapsed'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php index 50cb1afe6..89048e215 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/EncapsedStringPart.php @@ -1,4 +1,4 @@ -value = $value; } - public function getSubNodeNames() { - return array('value'); + public function getSubNodeNames() : array { + return ['value']; + } + + public function getType() : string { + return 'Scalar_EncapsedStringPart'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php index 3559b982c..7b9ec5e95 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/LNumber.php @@ -1,4 +1,4 @@ -value = $value; } - public function getSubNodeNames() { - return array('value'); + public function getSubNodeNames() : array { + return ['value']; } /** @@ -40,7 +40,7 @@ public function getSubNodeNames() { * * @return LNumber The constructed LNumber, including kind attribute */ - public static function fromString($str, array $attributes = array(), $allowInvalidOctal = false) { + public static function fromString(string $str, array $attributes = [], bool $allowInvalidOctal = false) : LNumber { if ('0' !== $str[0] || '0' === $str) { $attributes['kind'] = LNumber::KIND_DEC; return new LNumber((int) $str, $attributes); @@ -64,4 +64,8 @@ public static function fromString($str, array $attributes = array(), $allowInval $attributes['kind'] = LNumber::KIND_OCT; return new LNumber(intval($str, 8), $attributes); } + + public function getType() : string { + return 'Scalar_LNumber'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php index a50d68f3d..841f4f8be 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Scalar/MagicConst.php @@ -1,4 +1,4 @@ - '\\', '$' => '$', 'n' => "\n", @@ -25,7 +25,7 @@ class String_ extends Scalar 'f' => "\f", 'v' => "\v", 'e' => "\x1B", - ); + ]; /** * Constructs a string scalar node. @@ -33,13 +33,13 @@ class String_ extends Scalar * @param string $value Value of the string * @param array $attributes Additional attributes */ - public function __construct($value, array $attributes = array()) { + public function __construct(string $value, array $attributes = []) { parent::__construct($attributes); $this->value = $value; } - public function getSubNodeNames() { - return array('value'); + public function getSubNodeNames() : array { + return ['value']; } /** @@ -52,7 +52,7 @@ public function getSubNodeNames() { * * @return string The parsed string */ - public static function parse($str, $parseUnicodeEscape = true) { + public static function parse(string $str, bool $parseUnicodeEscape = true) : string { $bLength = 0; if ('b' === $str[0] || 'B' === $str[0]) { $bLength = 1; @@ -60,8 +60,8 @@ public static function parse($str, $parseUnicodeEscape = true) { if ('\'' === $str[$bLength]) { return str_replace( - array('\\\\', '\\\''), - array( '\\', '\''), + ['\\\\', '\\\''], + ['\\', '\''], substr($str, $bLength + 1, -1) ); } else { @@ -82,7 +82,7 @@ public static function parse($str, $parseUnicodeEscape = true) { * * @return string String with escape sequences parsed */ - public static function parseEscapeSequences($str, $quote, $parseUnicodeEscape = true) { + public static function parseEscapeSequences(string $str, $quote, bool $parseUnicodeEscape = true) : string { if (null !== $quote) { $str = str_replace('\\' . $quote, $quote, $str); } @@ -111,7 +111,14 @@ function($matches) { ); } - private static function codePointToUtf8($num) { + /** + * Converts a Unicode code point to its UTF-8 encoded representation. + * + * @param int $num Code point + * + * @return string UTF-8 representation of code point + */ + private static function codePointToUtf8(int $num) : string { if ($num <= 0x7F) { return chr($num); } @@ -139,7 +146,7 @@ private static function codePointToUtf8($num) { * * @return string Parsed string */ - public static function parseDocString($startToken, $str, $parseUnicodeEscape = true) { + public static function parseDocString(string $startToken, string $str, bool $parseUnicodeEscape = true) : string { // strip last newline (thanks tokenizer for sticking it into the string!) $str = preg_replace('~(\r\n|\n|\r)\z~', '', $str); @@ -150,4 +157,8 @@ public static function parseDocString($startToken, $str, $parseUnicodeEscape = t return self::parseEscapeSequences($str, null, $parseUnicodeEscape); } + + public function getType() : string { + return 'Scalar_String'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php index baa2f3e16..69d33e579 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt.php @@ -1,4 +1,4 @@ -num = $num; } - public function getSubNodeNames() { - return array('num'); + public function getSubNodeNames() : array { + return ['num']; + } + + public function getType() : string { + return 'Stmt_Break'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php index 03f892c7c..30528509b 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Case_.php @@ -1,4 +1,4 @@ -cond = $cond; $this->stmts = $stmts; } - public function getSubNodeNames() { - return array('cond', 'stmts'); + public function getSubNodeNames() : array { + return ['cond', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Case'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php index 58337ad9b..49cecf39d 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php @@ -1,34 +1,41 @@ -types = $types; $this->var = $var; $this->stmts = $stmts; } - public function getSubNodeNames() { - return array('types', 'var', 'stmts'); + public function getSubNodeNames() : array { + return ['types', 'var', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Catch'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php index 0d41094ff..ff2f40d2c 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassConst.php @@ -1,4 +1,4 @@ -flags = $flags; $this->consts = $consts; } - public function getSubNodeNames() { - return array('flags', 'consts'); + public function getSubNodeNames() : array { + return ['flags', 'consts']; } - public function isPublic() { + /** + * Whether constant is explicitly or implicitly public. + * + * @return bool + */ + public function isPublic() : bool { return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; } - public function isProtected() { + /** + * Whether constant is protected. + * + * @return bool + */ + public function isProtected() : bool { return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); } - public function isPrivate() { + /** + * Whether constant is private. + * + * @return bool + */ + public function isPrivate() : bool { return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); } - - public function isStatic() { - return (bool) ($this->flags & Class_::MODIFIER_STATIC); + + public function getType() : string { + return 'Stmt_ClassConst'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php index f90533553..31cd66ac9 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassLike.php @@ -1,13 +1,17 @@ -stmts as $stmt) { if ($stmt instanceof ClassMethod) { $methods[] = $stmt; @@ -32,10 +36,10 @@ public function getMethods() { * * @return ClassMethod|null Method node or null if the method does not exist */ - public function getMethod($name) { + public function getMethod(string $name) { $lowerName = strtolower($name); foreach ($this->stmts as $stmt) { - if ($stmt instanceof ClassMethod && $lowerName === strtolower($stmt->name)) { + if ($stmt instanceof ClassMethod && $lowerName === $stmt->name->toLowerString()) { return $stmt; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php index de05390ad..550b54ba2 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ClassMethod.php @@ -1,4 +1,4 @@ - true, + '__destruct' => true, + '__call' => true, + '__callstatic' => true, + '__get' => true, + '__set' => true, + '__isset' => true, + '__unset' => true, + '__sleep' => true, + '__wakeup' => true, + '__tostring' => true, + '__set_state' => true, + '__clone' => true, + '__invoke' => true, + '__debuginfo' => true, + ]; /** * Constructs a class method node. * - * @param string $name Name - * @param array $subNodes Array of the following optional subnodes: - * 'flags => MODIFIER_PUBLIC: Flags - * 'byRef' => false : Whether to return by reference - * 'params' => array() : Parameters - * 'returnType' => null : Return type - * 'stmts' => array() : Statements - * @param array $attributes Additional attributes + * @param string|Node\Identifier $name Name + * @param array $subNodes Array of the following optional subnodes: + * 'flags => MODIFIER_PUBLIC: Flags + * 'byRef' => false : Whether to return by reference + * 'params' => array() : Parameters + * 'returnType' => null : Return type + * 'stmts' => array() : Statements + * @param array $attributes Additional attributes */ - public function __construct($name, array $subNodes = array(), array $attributes = array()) { + public function __construct($name, array $subNodes = [], array $attributes = []) { parent::__construct($attributes); - $this->flags = isset($subNodes['flags']) ? $subNodes['flags'] - : (isset($subNodes['type']) ? $subNodes['type'] : 0); - $this->type = $this->flags; - $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; - $this->name = $name; - $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); - $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; - $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : array(); + $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0; + $this->byRef = $subNodes['byRef'] ?? false; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->params = $subNodes['params'] ?? []; + $returnType = $subNodes['returnType'] ?? null; + $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : []; } - public function getSubNodeNames() { - return array('flags', 'byRef', 'name', 'params', 'returnType', 'stmts'); + public function getSubNodeNames() : array { + return ['flags', 'byRef', 'name', 'params', 'returnType', 'stmts']; } - public function returnsByRef() { + public function returnsByRef() : bool { return $this->byRef; } - public function getParams() { + public function getParams() : array { return $this->params; } @@ -67,28 +81,71 @@ public function getStmts() { return $this->stmts; } - public function isPublic() { + /** + * Whether the method is explicitly or implicitly public. + * + * @return bool + */ + public function isPublic() : bool { return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; } - public function isProtected() { + /** + * Whether the method is protected. + * + * @return bool + */ + public function isProtected() : bool { return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); } - public function isPrivate() { + /** + * Whether the method is private. + * + * @return bool + */ + public function isPrivate() : bool { return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); } - public function isAbstract() { + /** + * Whether the method is abstract. + * + * @return bool + */ + public function isAbstract() : bool { return (bool) ($this->flags & Class_::MODIFIER_ABSTRACT); } - public function isFinal() { + /** + * Whether the method is final. + * + * @return bool + */ + public function isFinal() : bool { return (bool) ($this->flags & Class_::MODIFIER_FINAL); } - public function isStatic() { + /** + * Whether the method is static. + * + * @return bool + */ + public function isStatic() : bool { return (bool) ($this->flags & Class_::MODIFIER_STATIC); } + + /** + * Whether the method is magic. + * + * @return bool + */ + public function isMagic() : bool { + return isset(self::$magicNames[$this->name->toLowerString()]); + } + + public function getType() : string { + return 'Stmt_ClassMethod'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php index 0a65e3740..78bd19570 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Class_.php @@ -1,4 +1,4 @@ - true, - 'parent' => true, - 'static' => true, - ); - /** * Constructs a class node. * - * @param string|null $name Name + * @param string|Node\Identifier|null $name Name * @param array $subNodes Array of the following optional subnodes: * 'flags' => 0 : Flags * 'extends' => null : Name of extended class @@ -45,30 +34,43 @@ class Class_ extends ClassLike * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ - public function __construct($name, array $subNodes = array(), array $attributes = array()) { + public function __construct($name, array $subNodes = [], array $attributes = []) { parent::__construct($attributes); - $this->flags = isset($subNodes['flags']) ? $subNodes['flags'] - : (isset($subNodes['type']) ? $subNodes['type'] : 0); - $this->type = $this->flags; - $this->name = $name; - $this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : null; - $this->implements = isset($subNodes['implements']) ? $subNodes['implements'] : array(); - $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + $this->flags = $subNodes['flags'] ?? $subNodes['type'] ?? 0; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->extends = $subNodes['extends'] ?? null; + $this->implements = $subNodes['implements'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; } - public function getSubNodeNames() { - return array('flags', 'name', 'extends', 'implements', 'stmts'); + public function getSubNodeNames() : array { + return ['flags', 'name', 'extends', 'implements', 'stmts']; } - public function isAbstract() { + /** + * Whether the class is explicitly abstract. + * + * @return bool + */ + public function isAbstract() : bool { return (bool) ($this->flags & self::MODIFIER_ABSTRACT); } - public function isFinal() { + /** + * Whether the class is final. + * + * @return bool + */ + public function isFinal() : bool { return (bool) ($this->flags & self::MODIFIER_FINAL); } - public function isAnonymous() { + /** + * Whether the class is anonymous. + * + * @return bool + */ + public function isAnonymous() : bool { return null === $this->name; } @@ -96,4 +98,8 @@ public static function verifyModifier($a, $b) { throw new Error('Cannot use the final modifier on an abstract class member'); } } + + public function getType() : string { + return 'Stmt_Class'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php index 8b2eecd51..c1786bedd 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Const_.php @@ -1,4 +1,4 @@ -consts = $consts; } - public function getSubNodeNames() { - return array('consts'); + public function getSubNodeNames() : array { + return ['consts']; + } + + public function getType() : string { + return 'Stmt_Const'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php index f78e19a2a..7e143ac96 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php @@ -1,4 +1,4 @@ -num = $num; } - public function getSubNodeNames() { - return array('num'); + public function getSubNodeNames() : array { + return ['num']; + } + + public function getType() : string { + return 'Stmt_Continue'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php index 829dbaf25..40bec3030 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/DeclareDeclare.php @@ -1,4 +1,4 @@ -value pair node. * - * @param string $key Key - * @param Node\Expr $value Value - * @param array $attributes Additional attributes + * @param string|Node\Identifier $key Key + * @param Node\Expr $value Value + * @param array $attributes Additional attributes */ - public function __construct($key, Node\Expr $value, array $attributes = array()) { + public function __construct($key, Node\Expr $value, array $attributes = []) { parent::__construct($attributes); - $this->key = $key; + $this->key = \is_string($key) ? new Node\Identifier($key) : $key; $this->value = $value; } - public function getSubNodeNames() { - return array('key', 'value'); + public function getSubNodeNames() : array { + return ['key', 'value']; + } + + public function getType() : string { + return 'Stmt_DeclareDeclare'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php index 32739f35f..305e07d5a 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php @@ -1,4 +1,4 @@ -declares = $declares; $this->stmts = $stmts; } - public function getSubNodeNames() { - return array('declares', 'stmts'); + public function getSubNodeNames() : array { + return ['declares', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Declare'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php index dd4c6c843..778c73983 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Do_.php @@ -1,4 +1,4 @@ -cond = $cond; $this->stmts = $stmts; } - public function getSubNodeNames() { - return array('cond', 'stmts'); + public function getSubNodeNames() : array { + return ['stmts', 'cond']; + } + + public function getType() : string { + return 'Stmt_Do'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php index 11e107072..9c35c6165 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Echo_.php @@ -1,4 +1,4 @@ -exprs = $exprs; } - public function getSubNodeNames() { - return array('exprs'); + public function getSubNodeNames() : array { + return ['exprs']; + } + + public function getType() : string { + return 'Stmt_Echo'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php index 608878f65..f518d512e 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/ElseIf_.php @@ -1,4 +1,4 @@ -cond = $cond; $this->stmts = $stmts; } - public function getSubNodeNames() { - return array('cond', 'stmts'); + public function getSubNodeNames() : array { + return ['cond', 'stmts']; + } + + public function getType() : string { + return 'Stmt_ElseIf'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php index c91a1484f..c7015c69d 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Else_.php @@ -1,4 +1,4 @@ -stmts = $stmts; } - public function getSubNodeNames() { - return array('stmts'); + public function getSubNodeNames() : array { + return ['stmts']; + } + + public function getType() : string { + return 'Stmt_Else'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php new file mode 100644 index 000000000..1e2aa394d --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Expression.php @@ -0,0 +1,33 @@ +expr = $expr; + } + + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Stmt_Expression'; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php index 0e3eabbe1..0498f5bf8 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Finally_.php @@ -1,4 +1,4 @@ -stmts = $stmts; } - public function getSubNodeNames() { - return array('stmts'); + public function getSubNodeNames() : array { + return ['stmts']; + } + + public function getType() : string { + return 'Stmt_Finally'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php index 2ca88a332..3e208914d 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/For_.php @@ -1,4 +1,4 @@ - array(): Statements * @param array $attributes Additional attributes */ - public function __construct(array $subNodes = array(), array $attributes = array()) { + public function __construct(array $subNodes = [], array $attributes = []) { parent::__construct($attributes); - $this->init = isset($subNodes['init']) ? $subNodes['init'] : array(); - $this->cond = isset($subNodes['cond']) ? $subNodes['cond'] : array(); - $this->loop = isset($subNodes['loop']) ? $subNodes['loop'] : array(); - $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + $this->init = $subNodes['init'] ?? []; + $this->cond = $subNodes['cond'] ?? []; + $this->loop = $subNodes['loop'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; } - public function getSubNodeNames() { - return array('init', 'cond', 'loop', 'stmts'); + public function getSubNodeNames() : array { + return ['init', 'cond', 'loop', 'stmts']; + } + + public function getType() : string { + return 'Stmt_For'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php index d2c643205..9c8e88f8f 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Foreach_.php @@ -1,4 +1,4 @@ - array(): Statements * @param array $attributes Additional attributes */ - public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = array(), array $attributes = array()) { + public function __construct(Node\Expr $expr, Node\Expr $valueVar, array $subNodes = [], array $attributes = []) { parent::__construct($attributes); $this->expr = $expr; - $this->keyVar = isset($subNodes['keyVar']) ? $subNodes['keyVar'] : null; - $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; + $this->keyVar = $subNodes['keyVar'] ?? null; + $this->byRef = $subNodes['byRef'] ?? false; $this->valueVar = $valueVar; - $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + $this->stmts = $subNodes['stmts'] ?? []; } - public function getSubNodeNames() { - return array('expr', 'keyVar', 'byRef', 'valueVar', 'stmts'); + public function getSubNodeNames() : array { + return ['expr', 'keyVar', 'byRef', 'valueVar', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Foreach'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php index 4c1f48d84..a0bd2570c 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Function_.php @@ -1,27 +1,30 @@ - false : Whether to return by reference * 'params' => array(): Parameters @@ -29,24 +32,25 @@ class Function_ extends Node\Stmt implements FunctionLike * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ - public function __construct($name, array $subNodes = array(), array $attributes = array()) { + public function __construct($name, array $subNodes = [], array $attributes = []) { parent::__construct($attributes); - $this->byRef = isset($subNodes['byRef']) ? $subNodes['byRef'] : false; - $this->name = $name; - $this->params = isset($subNodes['params']) ? $subNodes['params'] : array(); - $this->returnType = isset($subNodes['returnType']) ? $subNodes['returnType'] : null; - $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + $this->byRef = $subNodes['byRef'] ?? false; + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->params = $subNodes['params'] ?? []; + $returnType = $subNodes['returnType'] ?? null; + $this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType; + $this->stmts = $subNodes['stmts'] ?? []; } - public function getSubNodeNames() { - return array('byRef', 'name', 'params', 'returnType', 'stmts'); + public function getSubNodeNames() : array { + return ['byRef', 'name', 'params', 'returnType', 'stmts']; } - public function returnsByRef() { + public function returnsByRef() : bool { return $this->byRef; } - public function getParams() { + public function getParams() : array { return $this->params; } @@ -54,7 +58,12 @@ public function getReturnType() { return $this->returnType; } - public function getStmts() { + /** @return Node\Stmt[] */ + public function getStmts() : array { return $this->stmts; } + + public function getType() : string { + return 'Stmt_Function'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php index 29fbc488e..8e6164879 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Global_.php @@ -1,4 +1,4 @@ -vars = $vars; } - public function getSubNodeNames() { - return array('vars'); + public function getSubNodeNames() : array { + return ['vars']; + } + + public function getType() : string { + return 'Stmt_Global'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php index b087fe02b..35052b8a6 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Goto_.php @@ -1,26 +1,31 @@ -name = $name; + $this->name = \is_string($name) ? new Identifier($name) : $name; } - public function getSubNodeNames() { - return array('name'); + public function getSubNodeNames() : array { + return ['name']; + } + + public function getType() : string { + return 'Stmt_Goto'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php index 30837dd6b..e0d7e604c 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/GroupUse.php @@ -1,4 +1,4 @@ -type = $type; $this->prefix = $prefix; $this->uses = $uses; } - public function getSubNodeNames() { - return array('type', 'prefix', 'uses'); + public function getSubNodeNames() : array { + return ['type', 'prefix', 'uses']; + } + + public function getType() : string { + return 'Stmt_GroupUse'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php index c33ec9f1d..c86d71e14 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/HaltCompiler.php @@ -1,4 +1,4 @@ -remaining = $remaining; } - public function getSubNodeNames() { - return array('remaining'); + public function getSubNodeNames() : array { + return ['remaining']; + } + + public function getType() : string { + return 'Stmt_HaltCompiler'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php index 98bda356f..87cd313b4 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/If_.php @@ -1,4 +1,4 @@ - null : Else clause * @param array $attributes Additional attributes */ - public function __construct(Node\Expr $cond, array $subNodes = array(), array $attributes = array()) { + public function __construct(Node\Expr $cond, array $subNodes = [], array $attributes = []) { parent::__construct($attributes); $this->cond = $cond; - $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); - $this->elseifs = isset($subNodes['elseifs']) ? $subNodes['elseifs'] : array(); - $this->else = isset($subNodes['else']) ? $subNodes['else'] : null; + $this->stmts = $subNodes['stmts'] ?? []; + $this->elseifs = $subNodes['elseifs'] ?? []; + $this->else = $subNodes['else'] ?? null; } - public function getSubNodeNames() { - return array('cond', 'stmts', 'elseifs', 'else'); + public function getSubNodeNames() : array { + return ['cond', 'stmts', 'elseifs', 'else']; + } + + public function getType() : string { + return 'Stmt_If'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php index accebe61e..1dec989fd 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/InlineHTML.php @@ -1,4 +1,4 @@ -value = $value; } - public function getSubNodeNames() { - return array('value'); + public function getSubNodeNames() : array { + return ['value']; + } + + public function getType() : string { + return 'Stmt_InlineHTML'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php index efb5891fc..39049aae7 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Interface_.php @@ -1,4 +1,4 @@ - array(): Name of extended interfaces * 'stmts' => array(): Statements * @param array $attributes Additional attributes */ - public function __construct($name, array $subNodes = array(), array $attributes = array()) { + public function __construct($name, array $subNodes = [], array $attributes = []) { parent::__construct($attributes); - $this->name = $name; - $this->extends = isset($subNodes['extends']) ? $subNodes['extends'] : array(); - $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->extends = $subNodes['extends'] ?? []; + $this->stmts = $subNodes['stmts'] ?? []; } - public function getSubNodeNames() { - return array('name', 'extends', 'stmts'); + public function getSubNodeNames() : array { + return ['name', 'extends', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Interface'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php index edd0ee9a5..332043ba5 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Label.php @@ -1,26 +1,31 @@ -name = $name; + $this->name = \is_string($name) ? new Identifier($name) : $name; } - public function getSubNodeNames() { - return array('name'); + public function getSubNodeNames() : array { + return ['name']; + } + + public function getType() : string { + return 'Stmt_Label'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php index 444855c39..f113998d6 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php @@ -1,4 +1,4 @@ -name = $name; $this->stmts = $stmts; } - public function getSubNodeNames() { - return array('name', 'stmts'); + public function getSubNodeNames() : array { + return ['name', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Namespace'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php index 270dd0995..f86f8df7d 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Nop.php @@ -1,4 +1,4 @@ -flags = $flags; - $this->type = $flags; $this->props = $props; } - public function getSubNodeNames() { - return array('flags', 'props'); + public function getSubNodeNames() : array { + return ['flags', 'props']; } - public function isPublic() { + /** + * Whether the property is explicitly or implicitly public. + * + * @return bool + */ + public function isPublic() : bool { return ($this->flags & Class_::MODIFIER_PUBLIC) !== 0 || ($this->flags & Class_::VISIBILITY_MODIFIER_MASK) === 0; } - public function isProtected() { + /** + * Whether the property is protected. + * + * @return bool + */ + public function isProtected() : bool { return (bool) ($this->flags & Class_::MODIFIER_PROTECTED); } - public function isPrivate() { + /** + * Whether the property is private. + * + * @return bool + */ + public function isPrivate() : bool { return (bool) ($this->flags & Class_::MODIFIER_PRIVATE); } - public function isStatic() { + /** + * Whether the property is static. + * + * @return bool + */ + public function isStatic() : bool { return (bool) ($this->flags & Class_::MODIFIER_STATIC); } + + public function getType() : string { + return 'Stmt_Property'; + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php index b2d29dc77..45e26faaf 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php @@ -1,4 +1,4 @@ -name = $name; + $this->name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name; $this->default = $default; } - public function getSubNodeNames() { - return array('name', 'default'); + public function getSubNodeNames() : array { + return ['name', 'default']; + } + + public function getType() : string { + return 'Stmt_PropertyProperty'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php index b64284114..346f9bd88 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Stmt_Return'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php index 4bc5dd25c..7fbb7de15 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php @@ -1,30 +1,37 @@ -name = $name; + $this->var = $var; $this->default = $default; } - public function getSubNodeNames() { - return array('name', 'default'); + public function getSubNodeNames() : array { + return ['var', 'default']; + } + + public function getType() : string { + return 'Stmt_StaticVar'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php index 37cc0b36f..e408f51f3 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Static_.php @@ -1,4 +1,4 @@ -vars = $vars; } - public function getSubNodeNames() { - return array('vars'); + public function getSubNodeNames() : array { + return ['vars']; + } + + public function getType() : string { + return 'Stmt_Static'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php index 72d667b1e..ff2ba0d96 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Switch_.php @@ -1,4 +1,4 @@ -cond = $cond; $this->cases = $cases; } - public function getSubNodeNames() { - return array('cond', 'cases'); + public function getSubNodeNames() : array { + return ['cond', 'cases']; + } + + public function getType() : string { + return 'Stmt_Switch'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php index f8ff6aa38..21709bf75 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Throw_.php @@ -1,4 +1,4 @@ -expr = $expr; } - public function getSubNodeNames() { - return array('expr'); + public function getSubNodeNames() : array { + return ['expr']; + } + + public function getType() : string { + return 'Stmt_Throw'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php index a29874bea..43c66b8d7 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUse.php @@ -1,10 +1,9 @@ -traits = $traits; $this->adaptations = $adaptations; } - public function getSubNodeNames() { - return array('traits', 'adaptations'); + public function getSubNodeNames() : array { + return ['traits', 'adaptations']; + } + + public function getType() : string { + return 'Stmt_TraitUse'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php index c6038c8ca..8bdd2c041 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation.php @@ -1,4 +1,4 @@ -trait = $trait; - $this->method = $method; + $this->method = \is_string($method) ? new Node\Identifier($method) : $method; $this->newModifier = $newModifier; - $this->newName = $newName; + $this->newName = \is_string($newName) ? new Node\Identifier($newName) : $newName; } - public function getSubNodeNames() { - return array('trait', 'method', 'newModifier', 'newName'); + public function getSubNodeNames() : array { + return ['trait', 'method', 'newModifier', 'newName']; + } + + public function getType() : string { + return 'Stmt_TraitUseAdaptation_Alias'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php index 1f6bc1f98..2ec6bff2a 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TraitUseAdaptation/Precedence.php @@ -1,4 +1,4 @@ -trait = $trait; - $this->method = $method; + $this->method = \is_string($method) ? new Node\Identifier($method) : $method; $this->insteadof = $insteadof; } - public function getSubNodeNames() { - return array('trait', 'method', 'insteadof'); + public function getSubNodeNames() : array { + return ['trait', 'method', 'insteadof']; + } + + public function getType() : string { + return 'Stmt_TraitUseAdaptation_Precedence'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php index eed5844ae..83980a762 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Trait_.php @@ -1,4 +1,4 @@ - array(): Statements * @param array $attributes Additional attributes */ - public function __construct($name, array $subNodes = array(), array $attributes = array()) { + public function __construct($name, array $subNodes = [], array $attributes = []) { parent::__construct($attributes); - $this->name = $name; - $this->stmts = isset($subNodes['stmts']) ? $subNodes['stmts'] : array(); + $this->name = \is_string($name) ? new Node\Identifier($name) : $name; + $this->stmts = $subNodes['stmts'] ?? []; } - public function getSubNodeNames() { - return array('name', 'stmts'); + public function getSubNodeNames() : array { + return ['name', 'stmts']; + } + + public function getType() : string { + return 'Stmt_Trait'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php index 0ff36cc77..7661ecb7a 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php @@ -1,4 +1,4 @@ -stmts = $stmts; $this->catches = $catches; $this->finally = $finally; } - public function getSubNodeNames() { - return array('stmts', 'catches', 'finally'); + public function getSubNodeNames() : array { + return ['stmts', 'catches', 'finally']; + } + + public function getType() : string { + return 'Stmt_TryCatch'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php index 0f00fe941..8bd2d7d68 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Unset_.php @@ -1,4 +1,4 @@ -vars = $vars; } - public function getSubNodeNames() { - return array('vars'); + public function getSubNodeNames() : array { + return ['vars']; + } + + public function getType() : string { + return 'Stmt_Unset'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php index 2de8432d7..fe588d2c9 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/UseUse.php @@ -1,8 +1,9 @@ -getLast(); - } - + public function __construct(Node\Name $name, $alias = null, int $type = Use_::TYPE_UNKNOWN, array $attributes = []) { parent::__construct($attributes); $this->type = $type; $this->name = $name; - $this->alias = $alias; + $this->alias = \is_string($alias) ? new Identifier($alias) : $alias; } - public function getSubNodeNames() { - return array('type', 'name', 'alias'); + public function getSubNodeNames() : array { + return ['type', 'name', 'alias']; + } + + /** + * Get alias. If not explicitly given this is the last component of the used name. + * + * @return Identifier + */ + public function getAlias() : Identifier { + if (null !== $this->alias) { + return $this->alias; + } + + return new Identifier($this->name->getLast()); + } + + public function getType() : string { + return 'Stmt_UseUse'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php index 6c89ebb1b..dafc1090f 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/Use_.php @@ -1,4 +1,4 @@ -type = $type; $this->uses = $uses; } - public function getSubNodeNames() { - return array('type', 'uses'); + public function getSubNodeNames() : array { + return ['type', 'uses']; + } + + public function getType() : string { + return 'Stmt_Use'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php index afad1b259..671207b8f 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/Stmt/While_.php @@ -1,4 +1,4 @@ -cond = $cond; $this->stmts = $stmts; } - public function getSubNodeNames() { - return array('cond', 'stmts'); + public function getSubNodeNames() : array { + return ['cond', 'stmts']; + } + + public function getType() : string { + return 'Stmt_While'; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php b/app/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php new file mode 100644 index 000000000..a30807a6d --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Node/VarLikeIdentifier.php @@ -0,0 +1,17 @@ +attributes = $attributes; } /** - * Gets the type of the node. + * Gets line the node started in (alias of getStartLine). * - * @return string Type of the node + * @return int Start line (or -1 if not available) */ - public function getType() { - $className = rtrim(get_class($this), '_'); - return strtr( - substr( - $className, - strpos($className, 'PhpParser\Node') + 15 - ), - '\\', - '_' - ); + public function getLine() : int { + return $this->attributes['startLine'] ?? -1; } /** * Gets line the node started in. * - * @return int Line + * Requires the 'startLine' attribute to be enabled in the lexer (enabled by default). + * + * @return int Start line (or -1 if not available) + */ + public function getStartLine() : int { + return $this->attributes['startLine'] ?? -1; + } + + /** + * Gets the line the node ended in. + * + * Requires the 'endLine' attribute to be enabled in the lexer (enabled by default). + * + * @return int End line (or -1 if not available) + */ + public function getEndLine() : int { + return $this->attributes['endLine'] ?? -1; + } + + /** + * Gets the token offset of the first token that is part of this node. + * + * The offset is an index into the array returned by Lexer::getTokens(). + * + * Requires the 'startTokenPos' attribute to be enabled in the lexer (DISABLED by default). + * + * @return int Token start position (or -1 if not available) */ - public function getLine() { - return $this->getAttribute('startLine', -1); + public function getStartTokenPos() : int { + return $this->attributes['startTokenPos'] ?? -1; } /** - * Sets line the node started in. + * Gets the token offset of the last token that is part of this node. * - * @param int $line Line + * The offset is an index into the array returned by Lexer::getTokens(). * - * @deprecated + * Requires the 'endTokenPos' attribute to be enabled in the lexer (DISABLED by default). + * + * @return int Token end position (or -1 if not available) */ - public function setLine($line) { - $this->setAttribute('startLine', (int) $line); + public function getEndTokenPos() : int { + return $this->attributes['endTokenPos'] ?? -1; + } + + /** + * Gets the file offset of the first character that is part of this node. + * + * Requires the 'startFilePos' attribute to be enabled in the lexer (DISABLED by default). + * + * @return int File start position (or -1 if not available) + */ + public function getStartFilePos() : int { + return $this->attributes['startFilePos'] ?? -1; + } + + /** + * Gets the file offset of the last character that is part of this node. + * + * Requires the 'endFilePos' attribute to be enabled in the lexer (DISABLED by default). + * + * @return int File end position (or -1 if not available) + */ + public function getEndFilePos() : int { + return $this->attributes['endFilePos'] ?? -1; + } + + /** + * Gets all comments directly preceding this node. + * + * The comments are also available through the "comments" attribute. + * + * @return Comment[] + */ + public function getComments() : array { + return $this->attributes['comments'] ?? []; } /** @@ -60,7 +115,7 @@ public function setLine($line) { * @return null|Comment\Doc Doc comment object or null */ public function getDocComment() { - $comments = $this->getAttribute('comments'); + $comments = $this->getComments(); if (!$comments) { return null; } @@ -81,7 +136,7 @@ public function getDocComment() { * @param Comment\Doc $docComment Doc comment to set */ public function setDocComment(Comment\Doc $docComment) { - $comments = $this->getAttribute('comments', []); + $comments = $this->getComments(); $numComments = count($comments); if ($numComments > 0 && $comments[$numComments - 1] instanceof Comment\Doc) { @@ -95,15 +150,15 @@ public function setDocComment(Comment\Doc $docComment) { $this->setAttribute('comments', $comments); } - public function setAttribute($key, $value) { + public function setAttribute(string $key, $value) { $this->attributes[$key] = $value; } - public function hasAttribute($key) { + public function hasAttribute(string $key) : bool { return array_key_exists($key, $this->attributes); } - public function &getAttribute($key, $default = null) { + public function getAttribute(string $key, $default = null) { if (!array_key_exists($key, $this->attributes)) { return $default; } else { @@ -111,11 +166,18 @@ public function &getAttribute($key, $default = null) { } } - public function getAttributes() { + public function getAttributes() : array { return $this->attributes; } - public function jsonSerialize() { + public function setAttributes(array $attributes) { + $this->attributes = $attributes; + } + + /** + * @return array + */ + public function jsonSerialize() : array { return ['nodeType' => $this->getType()] + get_object_vars($this); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php b/app/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php index 9946eb853..197ebc144 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NodeDumper.php @@ -1,4 +1,4 @@ -code = $code; return $this->dumpRecursive($node); } @@ -65,9 +65,9 @@ protected function dumpRecursive($node) { } elseif (is_scalar($value)) { if ('flags' === $key || 'newModifier' === $key) { $r .= $this->dumpFlags($value); - } else if ('type' === $key && $node instanceof Include_) { + } elseif ('type' === $key && $node instanceof Include_) { $r .= $this->dumpIncludeType($value); - } else if ('type' === $key + } elseif ('type' === $key && ($node instanceof Use_ || $node instanceof UseUse || $node instanceof GroupUse)) { $r .= $this->dumpUseType($value); } else { @@ -78,7 +78,7 @@ protected function dumpRecursive($node) { } } - if ($this->dumpComments && $comments = $node->getAttribute('comments')) { + if ($this->dumpComments && $comments = $node->getComments()) { $r .= "\n comments: " . str_replace("\n", "\n ", $this->dumpRecursive($comments)); } } elseif (is_array($node)) { @@ -141,7 +141,7 @@ protected function dumpIncludeType($type) { Include_::TYPE_INCLUDE => 'TYPE_INCLUDE', Include_::TYPE_INCLUDE_ONCE => 'TYPE_INCLUDE_ONCE', Include_::TYPE_REQUIRE => 'TYPE_REQUIRE', - Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQURE_ONCE', + Include_::TYPE_REQUIRE_ONCE => 'TYPE_REQUIRE_ONCE', ]; if (!isset($map[$type])) { @@ -164,18 +164,25 @@ protected function dumpUseType($type) { return $map[$type] . ' (' . $type . ')'; } + /** + * Dump node position, if possible. + * + * @param Node $node Node for which to dump position + * + * @return string|null Dump of position, or null if position information not available + */ protected function dumpPosition(Node $node) { if (!$node->hasAttribute('startLine') || !$node->hasAttribute('endLine')) { return null; } - $start = $node->getAttribute('startLine'); - $end = $node->getAttribute('endLine'); + $start = $node->getStartLine(); + $end = $node->getEndLine(); if ($node->hasAttribute('startFilePos') && $node->hasAttribute('endFilePos') && null !== $this->code ) { - $start .= ':' . $this->toColumn($this->code, $node->getAttribute('startFilePos')); - $end .= ':' . $this->toColumn($this->code, $node->getAttribute('endFilePos')); + $start .= ':' . $this->toColumn($this->code, $node->getStartFilePos()); + $end .= ':' . $this->toColumn($this->code, $node->getEndFilePos()); } return "[$start - $end]"; } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php b/app/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php new file mode 100644 index 000000000..2e7cfdad4 --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NodeFinder.php @@ -0,0 +1,81 @@ +addVisitor($visitor); + $traverser->traverse($nodes); + + return $visitor->getFoundNodes(); + } + + /** + * Find all nodes that are instances of a certain class. + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param string $class Class name + * + * @return Node[] Found nodes (all instances of $class) + */ + public function findInstanceOf($nodes, string $class) : array { + return $this->find($nodes, function ($node) use ($class) { + return $node instanceof $class; + }); + } + + /** + * Find first node satisfying a filter callback. + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param callable $filter Filter callback: function(Node $node) : bool + * + * @return null|Node Found node (or null if none found) + */ + public function findFirst($nodes, callable $filter) { + if (!is_array($nodes)) { + $nodes = [$nodes]; + } + + $visitor = new FirstFindingVisitor($filter); + + $traverser = new NodeTraverser; + $traverser->addVisitor($visitor); + $traverser->traverse($nodes); + + return $visitor->getFoundNode(); + } + + /** + * Find first node that is an instance of a certain class. + * + * @param Node|Node[] $nodes Single node or array of nodes to search in + * @param string $class Class name + * + * @return null|Node Found node, which is an instance of $class (or null if none found) + */ + public function findFirstInstanceOf($nodes, string $class) { + return $this->findFirst($nodes, function ($node) use ($class) { + return $node instanceof $class; + }); + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php b/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php index cce43d926..f9ef079d4 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php @@ -1,4 +1,4 @@ -visitors = array(); + // for BC } /** @@ -73,7 +70,7 @@ public function removeVisitor(NodeVisitor $visitor) { * * @return Node[] Traversed array of nodes */ - public function traverse(array $nodes) { + public function traverse(array $nodes) : array { $this->stopTraversal = false; foreach ($this->visitors as $visitor) { @@ -93,11 +90,18 @@ public function traverse(array $nodes) { return $nodes; } - protected function traverseNode(Node $node) { + /** + * Recursively traverse a node. + * + * @param Node $node Node to traverse. + * + * @return Node Result of traversal (may be original node or new one) + */ + protected function traverseNode(Node $node) : Node { foreach ($node->getSubNodeNames() as $name) { $subNode =& $node->$name; - if (is_array($subNode)) { + if (\is_array($subNode)) { $subNode = $this->traverseArray($subNode); if ($this->stopTraversal) { break; @@ -106,13 +110,20 @@ protected function traverseNode(Node $node) { $traverseChildren = true; foreach ($this->visitors as $visitor) { $return = $visitor->enterNode($subNode); - if (self::DONT_TRAVERSE_CHILDREN === $return) { - $traverseChildren = false; - } else if (self::STOP_TRAVERSAL === $return) { - $this->stopTraversal = true; - break 2; - } else if (null !== $return) { - $subNode = $return; + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($subNode, $return); + $subNode = $return; + } elseif (self::DONT_TRAVERSE_CHILDREN === $return) { + $traverseChildren = false; + } elseif (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } else { + throw new \LogicException( + 'enterNode() returned invalid value of type ' . gettype($return) + ); + } } } @@ -125,17 +136,23 @@ protected function traverseNode(Node $node) { foreach ($this->visitors as $visitor) { $return = $visitor->leaveNode($subNode); - if (self::STOP_TRAVERSAL === $return) { - $this->stopTraversal = true; - break 2; - } else if (null !== $return) { - if (is_array($return)) { + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($subNode, $return); + $subNode = $return; + } elseif (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (\is_array($return)) { throw new \LogicException( 'leaveNode() may only return an array ' . 'if the parent structure is an array' ); + } else { + throw new \LogicException( + 'leaveNode() returned invalid value of type ' . gettype($return) + ); } - $subNode = $return; } } } @@ -144,26 +161,35 @@ protected function traverseNode(Node $node) { return $node; } - protected function traverseArray(array $nodes) { - $doNodes = array(); + /** + * Recursively traverse array (usually of nodes). + * + * @param array $nodes Array to traverse + * + * @return array Result of traversal (may be original array or changed one) + */ + protected function traverseArray(array $nodes) : array { + $doNodes = []; foreach ($nodes as $i => &$node) { - if (is_array($node)) { - $node = $this->traverseArray($node); - if ($this->stopTraversal) { - break; - } - } elseif ($node instanceof Node) { + if ($node instanceof Node) { $traverseChildren = true; foreach ($this->visitors as $visitor) { $return = $visitor->enterNode($node); - if (self::DONT_TRAVERSE_CHILDREN === $return) { - $traverseChildren = false; - } else if (self::STOP_TRAVERSAL === $return) { - $this->stopTraversal = true; - break 2; - } else if (null !== $return) { - $node = $return; + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($node, $return); + $node = $return; + } elseif (self::DONT_TRAVERSE_CHILDREN === $return) { + $traverseChildren = false; + } elseif (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } else { + throw new \LogicException( + 'enterNode() returned invalid value of type ' . gettype($return) + ); + } } } @@ -176,20 +202,33 @@ protected function traverseArray(array $nodes) { foreach ($this->visitors as $visitor) { $return = $visitor->leaveNode($node); - - if (self::REMOVE_NODE === $return) { - $doNodes[] = array($i, array()); - break; - } else if (self::STOP_TRAVERSAL === $return) { - $this->stopTraversal = true; - break 2; - } elseif (is_array($return)) { - $doNodes[] = array($i, $return); - break; - } elseif (null !== $return) { - $node = $return; + if (null !== $return) { + if ($return instanceof Node) { + $this->ensureReplacementReasonable($node, $return); + $node = $return; + } elseif (\is_array($return)) { + $doNodes[] = [$i, $return]; + break; + } elseif (self::REMOVE_NODE === $return) { + $doNodes[] = [$i, []]; + break; + } elseif (self::STOP_TRAVERSAL === $return) { + $this->stopTraversal = true; + break 2; + } elseif (false === $return) { + throw new \LogicException( + 'bool(false) return from leaveNode() no longer supported. ' . + 'Return NodeTraverser::REMOVE_NODE instead' + ); + } else { + throw new \LogicException( + 'leaveNode() returned invalid value of type ' . gettype($return) + ); + } } } + } elseif (\is_array($node)) { + throw new \LogicException('Invalid node structure: Contains nested arrays'); } } @@ -201,4 +240,21 @@ protected function traverseArray(array $nodes) { return $nodes; } + + private function ensureReplacementReasonable($old, $new) { + if ($old instanceof Node\Stmt && $new instanceof Node\Expr) { + throw new \LogicException( + "Trying to replace statement ({$old->getType()}) " . + "with expression ({$new->getType()}). Are you missing a " . + "Stmt_Expression wrapper?" + ); + } + + if ($old instanceof Node\Expr && $new instanceof Node\Stmt) { + throw new \LogicException( + "Trying to replace expression ({$old->getType()}) " . + "with statement ({$new->getType()})" + ); + } + } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php b/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php index 0f88e4671..77ff3d27f 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverserInterface.php @@ -1,4 +1,4 @@ -setAttribute('origNode', $origNode); + return $node; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php b/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php new file mode 100644 index 000000000..9531edbce --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FindingVisitor.php @@ -0,0 +1,48 @@ +filterCallback = $filterCallback; + } + + /** + * Get found nodes satisfying the filter callback. + * + * Nodes are returned in pre-order. + * + * @return Node[] Found nodes + */ + public function getFoundNodes() : array { + return $this->foundNodes; + } + + public function beforeTraverse(array $nodes) { + $this->foundNodes = []; + + return null; + } + + public function enterNode(Node $node) { + $filterCallback = $this->filterCallback; + if ($filterCallback($node)) { + $this->foundNodes[] = $node; + } + + return null; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php b/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php new file mode 100644 index 000000000..596a7d7fd --- /dev/null +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/FirstFindingVisitor.php @@ -0,0 +1,50 @@ +filterCallback = $filterCallback; + } + + /** + * Get found node satisfying the filter callback. + * + * Returns null if no node satisfies the filter callback. + * + * @return null|Node Found node (or null if not found) + */ + public function getFoundNode() { + return $this->foundNode; + } + + public function beforeTraverse(array $nodes) { + $this->foundNode = null; + + return null; + } + + public function enterNode(Node $node) { + $filterCallback = $this->filterCallback; + if ($filterCallback($node)) { + $this->foundNode = $node; + return NodeTraverser::STOP_TRAVERSAL; + } + + return null; + } +} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php b/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php index d56812bcc..44d01e107 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php @@ -1,9 +1,10 @@ - [aliasName => originalName]] */ - protected $aliases; - - /** @var ErrorHandler Error handler */ - protected $errorHandler; + /** @var NameContext Naming context */ + protected $nameContext; /** @var bool Whether to preserve original names */ protected $preserveOriginalNames; + /** @var bool Whether to replace resolved nodes in place, or to add resolvedNode attributes */ + protected $replaceNodes; + /** * Constructs a name resolution visitor. * - * Options: If "preserveOriginalNames" is enabled, an "originalName" attribute will be added to - * all name nodes that underwent resolution. + * Options: + * * preserveOriginalNames (default false): An "originalName" attribute will be added to + * all name nodes that underwent resolution. + * * replaceNodes (default true): Resolved names are replaced in-place. Otherwise, a + * resolvedName attribute is added. (Names that cannot be statically resolved receive a + * namespacedName attribute, as usual.) * * @param ErrorHandler|null $errorHandler Error handler * @param array $options Options */ public function __construct(ErrorHandler $errorHandler = null, array $options = []) { - $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing; - $this->preserveOriginalNames = !empty($options['preserveOriginalNames']); + $this->nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing); + $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? false; + $this->replaceNodes = $options['replaceNodes'] ?? true; + } + + /** + * Get name resolution context. + * + * @return NameContext + */ + public function getNameContext() : NameContext { + return $this->nameContext; } public function beforeTraverse(array $nodes) { - $this->resetState(); + $this->nameContext->startNamespace(); + return null; } public function enterNode(Node $node) { if ($node instanceof Stmt\Namespace_) { - $this->resetState($node->name); + $this->nameContext->startNamespace($node->name); } elseif ($node instanceof Stmt\Use_) { foreach ($node->uses as $use) { $this->addAlias($use, $node->type, null); @@ -100,10 +113,10 @@ public function enterNode(Node $node) { } } elseif ($node instanceof Expr\FuncCall) { if ($node->name instanceof Name) { - $node->name = $this->resolveOtherName($node->name, Stmt\Use_::TYPE_FUNCTION); + $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_FUNCTION); } } elseif ($node instanceof Expr\ConstFetch) { - $node->name = $this->resolveOtherName($node->name, Stmt\Use_::TYPE_CONSTANT); + $node->name = $this->resolveName($node->name, Stmt\Use_::TYPE_CONSTANT); } elseif ($node instanceof Stmt\TraitUse) { foreach ($node->traits as &$trait) { $trait = $this->resolveClassName($trait); @@ -121,48 +134,19 @@ public function enterNode(Node $node) { } } } - } - protected function resetState(Name $namespace = null) { - $this->namespace = $namespace; - $this->aliases = array( - Stmt\Use_::TYPE_NORMAL => array(), - Stmt\Use_::TYPE_FUNCTION => array(), - Stmt\Use_::TYPE_CONSTANT => array(), - ); + return null; } - protected function addAlias(Stmt\UseUse $use, $type, Name $prefix = null) { + private function addAlias(Stmt\UseUse $use, $type, Name $prefix = null) { // Add prefix for group uses $name = $prefix ? Name::concat($prefix, $use->name) : $use->name; // Type is determined either by individual element or whole use declaration $type |= $use->type; - // Constant names are case sensitive, everything else case insensitive - if ($type === Stmt\Use_::TYPE_CONSTANT) { - $aliasName = $use->alias; - } else { - $aliasName = strtolower($use->alias); - } - - if (isset($this->aliases[$type][$aliasName])) { - $typeStringMap = array( - Stmt\Use_::TYPE_NORMAL => '', - Stmt\Use_::TYPE_FUNCTION => 'function ', - Stmt\Use_::TYPE_CONSTANT => 'const ', - ); - - $this->errorHandler->handleError(new Error( - sprintf( - 'Cannot use %s%s as %s because the name is already in use', - $typeStringMap[$type], $name, $use->alias - ), - $use->getAttributes() - )); - return; - } - - $this->aliases[$type][$aliasName] = $name; + $this->nameContext->addAlias( + $name, (string) $use->getAlias(), $type, $use->getAttributes() + ); } /** @param Stmt\Function_|Stmt\ClassMethod|Expr\Closure $node */ @@ -184,42 +168,26 @@ private function resolveType($node) { return $node; } - protected function resolveClassName(Name $name) { - if ($this->preserveOriginalNames) { - // Save the original name - $originalName = $name; - $name = clone $originalName; - $name->setAttribute('originalName', $originalName); - } - - // don't resolve special class names - if (in_array(strtolower($name->toString()), array('self', 'parent', 'static'))) { - if (!$name->isUnqualified()) { - $this->errorHandler->handleError(new Error( - sprintf("'\\%s' is an invalid class name", $name->toString()), - $name->getAttributes() - )); + /** + * Resolve name, according to name resolver options. + * + * @param Name $name Function or constant name to resolve + * @param int $type One of Stmt\Use_::TYPE_* + * + * @return Name Resolved name, or original name with attribute + */ + protected function resolveName(Name $name, int $type) : Name { + if (!$this->replaceNodes) { + $resolvedName = $this->nameContext->getResolvedName($name, $type); + if (null !== $resolvedName) { + $name->setAttribute('resolvedName', $resolvedName); + } else { + $name->setAttribute('namespacedName', FullyQualified::concat( + $this->nameContext->getNamespace(), $name, $name->getAttributes())); } return $name; } - // fully qualified names are already resolved - if ($name->isFullyQualified()) { - return $name; - } - - $aliasName = strtolower($name->getFirst()); - if (!$name->isRelative() && isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName])) { - // resolve aliases (for non-relative names) - $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName]; - return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); - } - - // if no alias exists prepend current namespace - return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); - } - - protected function resolveOtherName(Name $name, $type) { if ($this->preserveOriginalNames) { // Save the original name $originalName = $name; @@ -227,46 +195,24 @@ protected function resolveOtherName(Name $name, $type) { $name->setAttribute('originalName', $originalName); } - // fully qualified names are already resolved - if ($name->isFullyQualified()) { - return $name; - } - - // resolve aliases for qualified names - $aliasName = strtolower($name->getFirst()); - if ($name->isQualified() && isset($this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName])) { - $alias = $this->aliases[Stmt\Use_::TYPE_NORMAL][$aliasName]; - return FullyQualified::concat($alias, $name->slice(1), $name->getAttributes()); + $resolvedName = $this->nameContext->getResolvedName($name, $type); + if (null !== $resolvedName) { + return $resolvedName; } - if ($name->isUnqualified()) { - if ($type === Stmt\Use_::TYPE_CONSTANT) { - // constant aliases are case-sensitive, function aliases case-insensitive - $aliasName = $name->getFirst(); - } - - if (isset($this->aliases[$type][$aliasName])) { - // resolve unqualified aliases - return new FullyQualified($this->aliases[$type][$aliasName], $name->getAttributes()); - } - - if (null === $this->namespace) { - // outside of a namespace unaliased unqualified is same as fully qualified - return new FullyQualified($name, $name->getAttributes()); - } - - // unqualified names inside a namespace cannot be resolved at compile-time - // add the namespaced version of the name as an attribute - $name->setAttribute('namespacedName', - FullyQualified::concat($this->namespace, $name, $name->getAttributes())); - return $name; - } + // unqualified names inside a namespace cannot be resolved at compile-time + // add the namespaced version of the name as an attribute + $name->setAttribute('namespacedName', FullyQualified::concat( + $this->nameContext->getNamespace(), $name, $name->getAttributes())); + return $name; + } - // if no alias exists prepend current namespace - return FullyQualified::concat($this->namespace, $name, $name->getAttributes()); + protected function resolveClassName(Name $name) { + return $this->resolveName($name, Stmt\Use_::TYPE_NORMAL); } protected function addNamespacedName(Node $node) { - $node->namespacedName = Name::concat($this->namespace, $node->name); + $node->namespacedName = Name::concat( + $this->nameContext->getNamespace(), (string) $node->name); } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php b/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php index 3e1743a74..d378d6709 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/NodeVisitorAbstract.php @@ -1,4 +1,4 @@ -parsers = $parsers; } - public function parse($code, ErrorHandler $errorHandler = null) { + public function parse(string $code, ErrorHandler $errorHandler = null) { if (null === $errorHandler) { $errorHandler = new ErrorHandler\Throwing; } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php b/app/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php index 52ca59cfa..b5ebb3273 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Parser/Php5.php @@ -18,16 +18,16 @@ class Php5 extends \PhpParser\ParserAbstract { protected $tokenToSymbolMapSize = 392; - protected $actionTableSize = 1020; - protected $gotoTableSize = 591; + protected $actionTableSize = 1072; + protected $gotoTableSize = 644; protected $invalidSymbol = 157; protected $errorSymbol = 1; protected $defaultAction = -32766; protected $unexpectedTokenRule = 32767; - protected $YY2TBLSTATE = 405; - protected $YYNLSTATES = 667; + protected $YY2TBLSTATE = 403; + protected $numNonLeafStates = 672; protected $symbolToName = array( "EOF", @@ -233,287 +233,300 @@ class Php5 extends \PhpParser\ParserAbstract ); protected $action = array( - 672, 673, 674, 675, 676,-32766, 677, 678, 679, 715, - 716, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 0, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236,-32766,-32766,-32766,-32766,-32766,-32766,-32766, - -32766,-32767,-32767,-32767,-32767, 441, 237, 238,-32766,-32766, - -32766,-32766, 680,-32766, 1036,-32766,-32766,-32766,-32766,-32766, - -32766,-32767,-32767,-32767,-32767,-32767, 681, 682, 683, 684, - 685, 686, 687, 909, 329, 747,-32766,-32766,-32766,-32766, - -32766, 282, 688, 689, 690, 691, 692, 693, 694, 695, - 696, 697, 698, 718, 719, 720, 721, 722, 710, 711, - 712, 713, 714, 699, 700, 701, 702, 703, 704, 705, - 741, 742, 743, 744, 745, 746, 706, 707, 708, 709, - 739, 730, 728, 729, 725, 726, 1178, 717, 723, 724, - 731, 732, 734, 733, 735, 736, 52, 53, 420, 54, - 55, 727, 738, 737, 23, 56, 57, 284, 58,-32766, - -32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, 7,-32767, - -32767,-32767,-32767, 50, 325,-32766, 585, 945, 946, 947, - 944, 943, 942, 937, 1213, 27, 1215, 1214, 763, 764, - 821, 59, 60,-32766,-32766,-32766, 809, 61, 1172, 62, - 291, 292, 63, 64, 65, 66, 67, 68, 69, 70, - 334, 24, 299, 71, 413,-32766,-32766,-32766, 1185, 1087, - 1088, 749, 633, 1178, 213, 214, 215, 464,-32766,-32766, - -32766, 822, 407, 1099, 311,-32766, 1186,-32766,-32766,-32766, - -32766,-32766,-32766, 1036, 200, -269, 428,-32766,-32766,-32766, - -32766,-32766,-32766,-32766,-32766, 120, 491, 945, 946, 947, - 944, 943, 942, 306, 473, 474, 293, 623, 125,-32766, - 893, 894, 339, 477, 478,-32766, 1093, 1094, 1095, 1096, - 1090, 1091, 307, 492,-32766, 440, 425, 492, 1097, 1092, - 425, 121, -220, 869, 1182, 39, 280, 334, 321, 900, - 322, 421, -122, -122, -122, -4, 822, 463, 99, 100, - 101, 811, 301, 119, 38, 19, 422, -122, 465, -122, - 466, -122, 467, -122, 102, 423, -122, -122, -122, 28, - 29, 468, 424, 624, 30, 469, 425, 812, 72, 297, - 923, 349, 350, 470, 471,-32766,-32766,-32766, 419, 472, - 1036, 447, 793, 840, 475, 476,-32767,-32767,-32767,-32767, - 94, 95, 96, 97, 98,-32766, 126,-32766,-32766,-32766, - -32766, 1137, 213, 214, 215, 295, 421, 239, 824, 638, - -122, 1036, 463, 893, 894, 1205, 811, 1036, 1204, 38, - 19, 422, 200, 465, 356, 466, 492, 467, 127, 425, - 423, 213, 214, 215, 28, 29, 468, 424, 414, 30, - 469, 1036, 870, 72, 320, 822, 349, 350, 470, 471, - 34, 200, 214, 215, 472, 460, 762, 755, 840, 475, - 476, 213, 214, 215, 295, -216, 76, 77, 78, 46, - 298, 200, 412, 653, 338, 438, 31, 294, 333, 8, - 348, 200, 241, 824, 638, -4, 32, 332, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 1210, 301, 204, 822, 421, 805, 124,-32766,-32766, - -32766, 463, 899, 1054, 102, 811, 18, 206, 38, 19, - 422, 518, 465, 1172, 466, 546, 467, 47,-32766, 423, - -32766,-32766, 647, 28, 29, 468, 822, 801, 30, 469, - 415, 116, 72, 803, 49, 349, 350,-32766,-32766,-32766, - -32766,-32766,-32766, 472, 477, 808, 234, 235, 236, 213, - 214, 215, 1036, 215, 644, 1138, 124,-32766,-32766,-32766, - -32766,-32766, 237, 238, 421, 231, 232, 233, 1099, 200, - 463, 200, 824, 638, 811, 439, 918, 38, 19, 422, - 1036, 465, 242, 466, 749, 467, 1178, 339, 423, 96, - 97, 98, 28, 29, 468, 822, 421, 30, 469, 117, - 919, 72, 463, 283, 349, 350, 811, 244, 1036, 38, - 19, 422, 472, 465, 243, 466, 118, 467, 377, 1064, - 423, 1036, 207, 642, 28, 29, 468, 822, 129, 30, - 469, 296, 576, 72,-32766,-32766, 349, 350, 123, 205, - 492, 824, 638, 425, 472, 115,-32766,-32766,-32766, 434, - 492, 200, 640, 425, 820, 641,-32766,-32766, 429,-32766, - 334, 237, 238, 454, 591, 421,-32766, 130, 357, 449, - 20, 463, 128, 856, 638, 811, 763, 764, 38, 19, - 422, 313, 465, 646, 466, 650, 467, 599, 600, 423, - 833, 301, 605, 28, 29, 468, 822, 421, 30, 469, - 756, 643, 72, 463, 299, 349, 350, 811, 922, 666, - 38, 19, 422, 472, 465, 102, 466, 51, 467, 934, - 656, 423, 512, 433, 48, 28, 29, 468, 41, 42, - 30, 469, 43, 44, 72, 45, 435, 349, 350, 1057, - 750, 1208, 824, 638, 776, 472, 749, 33, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 534, 533, 517, 513, 524, 437, 421, 602, 516, 622, - 612, 619, 463, 582, 824, 638, 811, 595,-32766, 38, - 19, 422, 632, 465, 579, 466, 240, 467, 975, 977, - 423, 609, 1144, 279, 28, 29, 468, 12, -80, 30, - 469, 537, 432, 72, 208, 209, 349, 350, 458, 1098, - 210, 596, 211, 328, 472, 326, 11, 842, 323, 393, - 4, 385, 408, 303, 202, 1034, 0, 0, 324, 208, - 209, 841, 1087, 1088, 0, 210,-32766, 211, -497, -498, - 1089, 312, 310, 824, 638, 477, 0, 0, 0, 202, - 0, -398, 0, 0, 9, 0, 0, 1087, 1088, 3, - -497,-32766, -406, 370, -407, 1089, 835, 639, 0, 384, - 372, 409, 526, 434, 0, 0, 864, 857, 863, 872, - 0, 813, 798, 819, 807, 761, 661, 565, 760, 1093, - 1094, 1095, 1096, 1090, 1091, 383, 37, 36, 759, 926, - 810, 1097, 1092, 854, 852, 302, 806, 929, 212, 818, - -32766, 930, 565, 928, 1093, 1094, 1095, 1096, 1090, 1091, - 383, 927, 796, 804, 660, 802, 1097, 1092, 649, 651, - 75, 0, 652, 212, 654,-32766, 655, 658, 663, 664, - 665, 405, 122, 330, 331, 406, 0, 1211, 757, 758, - 839, 838, 766, 453, 1209, 1179, 1177, 1163, 1175, 1078, - 911, 1183, 1173, 829, 836, 1038, 1039, 827, 935, 1212, - 765, 837, 794, 662, 1050, 768, 767, 861, 862, 0, - 304, 290, 289, 25, 26, 281, 203, 74, 305, 336, - 411, 417, 35, 73,-32766, 40, 22, 0, 1015, 569, - -217, 1016, 1103, 1080, 901, 1040, 1044, 1041, 629, 559, - 461, 457, 455, 450, 378, 16, 15, 14, -216, 0, - 0, -416, 0, 1045, 603, 1157, 1104, 1207, 1077, 1174, - 1158, 1162, 1176, 1063, 1048, 1049, 1046, 1047, 0, 1143 + 677, 678, 679, 680, 681, 279, 682, 683, 684, 720, + 721, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 0, 227, 228, 229, 230, 231, 232, 233, 234, 235, + 236, 237, 238,-32766,-32766,-32766,-32766,-32766,-32766,-32766, + -32766,-32767,-32767,-32767,-32767, 206, 239, 240,-32766,-32766, + -32766,-32766, 685,-32766, 123,-32766,-32766,-32766,-32766,-32766, + -32766,-32767,-32767,-32767,-32767,-32767, 686, 687, 688, 689, + 690, 691, 692, 350, 30, 752, 954, 955, 956, 953, + 952, 951, 693, 694, 695, 696, 697, 698, 699, 700, + 701, 702, 703, 723, 724, 725, 726, 727, 715, 716, + 717, 718, 719, 704, 705, 706, 707, 708, 709, 710, + 746, 747, 748, 749, 750, 751, 711, 712, 713, 714, + 744, 735, 733, 734, 730, 731, 1046, 722, 728, 729, + 736, 737, 739, 738, 740, 741, 54, 55, 422, 56, + 57, 732, 743, 742, -219, 58, 59, 413, 60,-32766, + -32766,-32766,-32766,-32766,-32766,-32766,-32766,-32766, 1046,-32767, + -32767,-32767,-32767,-32767,-32767,-32767,-32767, 96, 97, 98, + 99, 100,-32766,-32766,-32766,-32766,-32766, 1224, 52, 829, + 1225, 61, 62,-32766,-32766,-32766, 294, 63, 590, 64, + 290, 291, 65, 66, 67, 68, 69, 70, 71, 72, + 1046, 26, 298, 73, 414,-32766,-32766,-32766, 877, 1097, + 1098, 756, 754, 759, 815, 771, 772, 471,-32766,-32766, + -32766, 830, 421, 294, 548,-32766, 1182,-32766,-32766,-32766, + -32766,-32766,-32766, 215, 216, 217, 434, 420,-32766, 306, + -32766,-32766,-32766,-32766,-32766, 1109, 495, 954, 955, 956, + 953, 952, 951, 202, 479, 480, 215, 216, 217, 407, + 122, 241, 813, 481, 482, 1046, 1103, 1104, 1105, 1106, + 1100, 1101, 309, 901, 902, 328, 202, 496, 1107, 1102, + 430,-32766, 215, 216, 217, 41, 496, 332, 320, 430, + 321, 423, -125, -125, -125, -4, 830, 470, 126, 417, + 336, 818, 202, 907, 40, 21, 424, -125, 472, -125, + 473, -125, 474, -125,-32766, 425, 215, 216, 217, 31, + 32, 426, 427, 10, 33, 475, 820, 878, 74, 216, + 217, 348, 349, 476, 477, 126, 202, 243, 418, 478, + 1046, 444, 801, 848, 428, 429, 281, 756, 202, 759, + 35, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116,-32766,-32766,-32766, 423, 1064, 832, 643, + -125, 830, 470, 215, 216, 217, 818, 1148, 927, 40, + 21, 424, 1074, 472, 628, 473,-32766, 474,-32766, 419, + 425, 985, 987, 202, 31, 32, 426, 427, 405, 33, + 475, 811, 1046, 74, 319, 1046, 348, 349, 476, 477, + -32766,-32766,-32766, 496, 478, 25, 430, 763, 848, 428, + 429, 435, 48, 332, 415, 295, 901, 902, 282, 1147, + -32766, 297,-32766,-32766,-32766,-32766, 1182, 347, 333, 496, + 770, 423, 430, 832, 643, -4, 830, 470, -223, 331, + 629, 818,-32766, 430, 40, 21, 424, 932, 472, 308, + 473, 445, 474, -502, 928, 425, -203, -203, -203, 31, + 32, 426, 427, 296, 33, 475, 809, 759, 74, 816, + 1215, 348, 349, 476, 477,-32766,-32766,-32766, 1046, 478, + 335, 1197, 801, 848, 428, 429, 236, 237, 238, 217, + 49,-32766,-32766,-32766, 118,-32766, 127,-32766,-32766,-32766, + 336, 292, 239, 240, 1046, 1196, 423, 202, 832, 643, + -203,-32766, 470,-32766,-32766, 481, 818, 208, 131, 40, + 21, 424, 581, 472, 20, 473, 36, 474, 29, 293, + 425, -204, -204, -204, 31, 32, 426, 427, 51, 33, + 475, 447, 121, 74, 202, 830, 348, 349, 476, 477, + 908,-32766,-32766,-32766, 478, 244, 522, 801, 848, 428, + 429, 101, 102, 103, 9, 300, 78, 79, 80, 246, + 324,-32766, 119, 646, 233, 234, 235, 104, 77, 946, + 130, 754, 332, 832, 643, -204, 34, 245, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, -254, 300, 1109, 830, 423, 98, 99, 100, 496, + 120, 470, 430, 1046, 104, 818,-32766,-32766, 40, 21, + 424, 117, 472, 828, 473, 440, 474, 207, 645, 425, + 125, 209, 647, 31, 32, 426, 830, 841, 33, 475, + -32766,-32766, 74, 128, 657, 348, 349, 332, 239, 240, + 459, 597, 654, 478, 312, 454, 22, 132, 358, 771, + 772, 604, 605, -82, 660, 300, 943, 663, 931, 671, + 764, 649,-32766, 104, 423, 756, 757, 53, 612, 959, + 470, 43, 832, 643, 818, 44, 45, 40, 21, 424, + 298, 472, -273, 473, 46, 474, 50, 47, 425, 129, + 759, 754, 31, 32, 426, 830, 423, 33, 475, 637, + 528, 74, 470,-32766, 348, 349, 818, 624, 850, 40, + 21, 424, 478, 472, 443, 473, 584, 474, 849, 616, + 425, -80, 1108, 655, 31, 32, 426, 830, 11, 33, + 475, 446, 278, 74, 438, 601, 348, 349, 587, 602, + 283, 832, 643, 464, 478, 325, 1154, 0, 0, 327, + 0, 0, 0, 0, 0, 651, 0, 0, 0, 322, + 0, 0, 0, 323, 0, 423, 0, 0, 307, 0, + 0, 470, 305, 832, 643, 818, -503, -502, 40, 21, + 424, 481, 472, 0, 473, -403, 474, 14, 5, 425, + 0, 0, 6, 31, 32, 426, 830, 423, 33, 475, + 357, -411, 74, 470, 12, 348, 349, 818, -412, 440, + 40, 21, 424, 478, 472, 382, 473, 409, 474, 408, + 383, 425, 391, 371, 530, 31, 32, 426, 843, 329, + 33, 475, 666, 810, 74, 39, 38, 348, 349, 880, + 821, 769, 832, 643, 819, 478, 937, 806, 667, 768, + 827, 936, 939, 812, 767, 814, 826, 872, 804, 938, + 865, 862, 817, 860, 935, 871, 423, 77, 644, 648, + 650, 652, 470, 653, 864, 643, 818, 656, 658, 40, + 21, 424, 659, 472, 661, 473, 242, 474, 662, 330, + 425, 403, 404, 124, 31, 32, 426, 845, 773, 33, + 475, 776, 775, 74, 210, 211, 348, 349, 870, 668, + 212, 802, 213, 1221, 478, 458, 1220, 1190, 1188, 1173, + 1186, 1088, 919, 1194, 204, 1184, 869, 944, 835, 210, + 211, 1049, 1097, 1098, 844, 212,-32766, 213, 1048, 837, + 1099, 1060, 774, 832, 643, 42, 1222, 846, 765, 204, + 847, 766, 1223, 1044, 37, 28, 412, 1097, 1098, 406, + 337,-32766, 75, 76, 304, 1099, 303, 302, 301, 27, + 24, 289, 288, 280,-32766, 205, 0, 1025, 573, 1026, + 1050, -220, 1090, -219, 16, 1113, 909, 569, 1054, 1103, + 1104, 1105, 1106, 1100, 1101, 381, 1051, 634, 563, 468, + 463, 1107, 1102, 462, 455, 376, 18, 17, 214, 0, + -32766, 608, 569, -421, 1103, 1104, 1105, 1106, 1100, 1101, + 381, 1168, 1167, 1114, 1218, 1087, 1107, 1102, 1185, 1057, + 1172, 1187, 1073, 214, 1058,-32766, 1059, 0, 1056, 1055, + 0, 1153 ); protected $actionCheck = array( - 2, 3, 4, 5, 6, 8, 8, 9, 10, 11, + 2, 3, 4, 5, 6, 13, 8, 9, 10, 11, 12, 31, 32, 33, 34, 35, 36, 37, 38, 39, 0, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 8, 9, 10, 31, 32, 33, 34, 35, 36, 37, 38, 39, 7, 66, 67, 31, 32, - 33, 34, 54, 28, 12, 30, 31, 32, 33, 34, + 33, 34, 54, 28, 7, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 68, 69, 70, 71, - 72, 73, 74, 79, 7, 77, 31, 32, 33, 34, - 35, 7, 84, 85, 86, 87, 88, 89, 90, 91, + 72, 73, 74, 7, 7, 77, 112, 113, 114, 115, + 116, 117, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 79, 129, 130, 131, + 122, 123, 124, 125, 126, 127, 12, 129, 130, 131, 132, 133, 134, 135, 136, 137, 2, 3, 4, 5, - 6, 143, 144, 145, 7, 11, 12, 153, 14, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 103, 41, - 42, 43, 44, 67, 109, 79, 82, 112, 113, 114, - 115, 116, 117, 118, 77, 7, 79, 80, 102, 103, - 1, 47, 48, 8, 9, 10, 148, 53, 79, 55, + 6, 143, 144, 145, 152, 11, 12, 7, 14, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 12, 41, + 42, 43, 44, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 31, 32, 33, 34, 35, 77, 67, 1, + 80, 47, 48, 8, 9, 10, 35, 53, 82, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 153, 67, 68, 69, 70, 8, 9, 10, 1, 75, - 76, 77, 77, 79, 8, 9, 10, 83, 8, 9, - 10, 1, 146, 139, 128, 28, 152, 30, 31, 32, - 33, 34, 35, 12, 28, 79, 102, 151, 28, 153, - 30, 31, 32, 33, 34, 149, 112, 112, 113, 114, - 115, 116, 117, 7, 120, 121, 35, 77, 149, 103, - 130, 131, 153, 129, 130, 109, 132, 133, 134, 135, - 136, 137, 138, 143, 118, 7, 146, 143, 144, 145, - 146, 7, 152, 29, 77, 151, 13, 153, 154, 152, - 156, 71, 72, 73, 74, 0, 1, 77, 50, 51, - 52, 81, 54, 13, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 66, 95, 96, 97, 98, 99, - 100, 101, 102, 143, 104, 105, 146, 148, 108, 7, - 150, 111, 112, 113, 114, 8, 9, 10, 7, 119, - 12, 7, 122, 123, 124, 125, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 28, 149, 30, 31, 32, - 33, 155, 8, 9, 10, 35, 71, 13, 148, 149, - 150, 12, 77, 130, 131, 79, 81, 12, 82, 84, - 85, 86, 28, 88, 7, 90, 143, 92, 67, 146, - 95, 8, 9, 10, 99, 100, 101, 102, 103, 104, - 105, 12, 148, 108, 109, 1, 111, 112, 113, 114, - 13, 28, 9, 10, 119, 7, 148, 122, 123, 124, - 125, 8, 9, 10, 35, 152, 8, 9, 10, 67, - 35, 28, 7, 29, 67, 29, 140, 141, 143, 7, - 7, 28, 29, 148, 149, 150, 28, 7, 30, 31, + 12, 67, 68, 69, 70, 8, 9, 10, 29, 75, + 76, 77, 77, 79, 148, 102, 103, 83, 8, 9, + 10, 1, 7, 35, 78, 28, 79, 30, 31, 32, + 33, 34, 35, 8, 9, 10, 102, 7, 28, 128, + 30, 31, 32, 33, 34, 139, 112, 112, 113, 114, + 115, 116, 117, 28, 120, 121, 8, 9, 10, 146, + 149, 13, 148, 129, 130, 12, 132, 133, 134, 135, + 136, 137, 138, 130, 131, 7, 28, 143, 144, 145, + 146, 8, 8, 9, 10, 151, 143, 153, 154, 146, + 156, 71, 72, 73, 74, 0, 1, 77, 147, 7, + 153, 81, 28, 152, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 79, 95, 8, 9, 10, 99, + 100, 101, 102, 7, 104, 105, 148, 148, 108, 9, + 10, 111, 112, 113, 114, 147, 28, 29, 7, 119, + 12, 29, 122, 123, 124, 125, 7, 77, 28, 79, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 31, 32, 33, 71, 152, 148, 149, + 150, 1, 77, 8, 9, 10, 81, 152, 148, 84, + 85, 86, 112, 88, 77, 90, 151, 92, 153, 7, + 95, 56, 57, 28, 99, 100, 101, 102, 103, 104, + 105, 148, 12, 108, 109, 12, 111, 112, 113, 114, + 8, 9, 10, 143, 119, 7, 146, 122, 123, 124, + 125, 151, 67, 153, 123, 35, 130, 131, 35, 155, + 28, 35, 30, 31, 32, 33, 79, 7, 143, 143, + 148, 71, 146, 148, 149, 150, 1, 77, 152, 7, + 143, 81, 151, 146, 84, 85, 86, 150, 88, 7, + 90, 149, 92, 128, 148, 95, 96, 97, 98, 99, + 100, 101, 102, 7, 104, 105, 148, 79, 108, 148, + 82, 111, 112, 113, 114, 8, 9, 10, 12, 119, + 67, 152, 122, 123, 124, 125, 50, 51, 52, 10, + 67, 8, 9, 10, 149, 28, 149, 30, 31, 32, + 153, 35, 66, 67, 12, 1, 71, 28, 148, 149, + 150, 28, 77, 30, 31, 129, 81, 15, 149, 84, + 85, 86, 153, 88, 152, 90, 13, 92, 140, 141, + 95, 96, 97, 98, 99, 100, 101, 102, 67, 104, + 105, 128, 13, 108, 28, 1, 111, 112, 113, 114, + 152, 8, 9, 10, 119, 15, 82, 122, 123, 124, + 125, 50, 51, 52, 103, 54, 8, 9, 10, 15, + 109, 28, 149, 29, 47, 48, 49, 66, 149, 118, + 29, 77, 153, 148, 149, 150, 28, 15, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 150, 54, 7, 1, 71, 148, 147, 8, 9, - 10, 77, 152, 152, 66, 81, 152, 15, 84, 85, - 86, 82, 88, 79, 90, 128, 92, 67, 28, 95, - 30, 31, 29, 99, 100, 101, 1, 148, 104, 105, - 123, 149, 108, 148, 67, 111, 112, 8, 9, 10, - 31, 32, 33, 119, 129, 148, 50, 51, 52, 8, - 9, 10, 12, 10, 29, 152, 147, 28, 151, 30, - 31, 32, 66, 67, 71, 47, 48, 49, 139, 28, - 77, 28, 148, 149, 81, 149, 148, 84, 85, 86, - 12, 88, 15, 90, 77, 92, 79, 153, 95, 47, - 48, 49, 99, 100, 101, 1, 71, 104, 105, 149, - 148, 108, 77, 35, 111, 112, 81, 15, 12, 84, - 85, 86, 119, 88, 15, 90, 149, 92, 78, 112, - 95, 12, 15, 29, 99, 100, 101, 1, 149, 104, - 105, 35, 153, 108, 31, 32, 111, 112, 29, 15, - 143, 148, 149, 146, 119, 15, 8, 9, 10, 146, - 143, 28, 149, 146, 29, 29, 8, 9, 151, 31, - 153, 66, 67, 72, 73, 71, 28, 97, 98, 72, - 73, 77, 29, 148, 149, 81, 102, 103, 84, 85, - 86, 29, 88, 29, 90, 29, 92, 106, 107, 95, - 35, 54, 74, 99, 100, 101, 1, 71, 104, 105, - 148, 149, 108, 77, 68, 111, 112, 81, 148, 149, - 84, 85, 86, 119, 88, 66, 90, 67, 92, 148, - 149, 95, 77, 77, 67, 99, 100, 101, 67, 67, - 104, 105, 67, 67, 108, 67, 77, 111, 112, 79, - 77, 77, 148, 149, 77, 119, 77, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 77, 77, 77, 77, 82, 86, 71, 79, 79, 79, - 79, 91, 77, 96, 148, 149, 81, 96, 82, 84, - 85, 86, 89, 88, 87, 90, 29, 92, 56, 57, - 95, 93, 139, 94, 99, 100, 101, 94, 94, 104, - 105, 94, 102, 108, 47, 48, 111, 112, 102, 139, - 53, 109, 55, 126, 119, 110, 142, 123, 126, 146, - 142, 146, 146, 151, 67, 154, -1, -1, 127, 47, - 48, 123, 75, 76, -1, 53, 79, 55, 128, 128, - 83, 128, 128, 148, 149, 129, -1, -1, -1, 67, - -1, 142, -1, -1, 142, -1, -1, 75, 76, 142, - 128, 79, 142, 142, 142, 83, 147, 149, -1, 146, - 146, 146, 146, 146, -1, -1, 148, 148, 148, 148, - -1, 148, 148, 148, 148, 148, 148, 130, 148, 132, - 133, 134, 135, 136, 137, 138, 148, 148, 148, 148, - 148, 144, 145, 148, 148, 151, 148, 148, 151, 148, - 153, 148, 130, 148, 132, 133, 134, 135, 136, 137, - 138, 148, 148, 148, 148, 148, 144, 145, 149, 149, - 149, -1, 149, 151, 149, 153, 149, 149, 149, 149, - 149, 149, 149, 149, 149, 149, -1, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 150, -1, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, -1, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, 152, -1, - -1, 154, -1, 155, 155, 155, 155, 155, 155, 155, - 155, 155, 155, 155, 155, 155, 155, 155, -1, 156 + 52, 150, 54, 139, 1, 71, 47, 48, 49, 143, + 149, 77, 146, 12, 66, 81, 8, 9, 84, 85, + 86, 15, 88, 29, 90, 146, 92, 15, 149, 95, + 29, 15, 29, 99, 100, 101, 1, 35, 104, 105, + 31, 32, 108, 149, 29, 111, 112, 153, 66, 67, + 72, 73, 29, 119, 29, 72, 73, 97, 98, 102, + 103, 106, 107, 29, 29, 54, 148, 149, 148, 149, + 148, 149, 31, 66, 71, 77, 77, 67, 74, 79, + 77, 67, 148, 149, 81, 67, 67, 84, 85, 86, + 68, 88, 79, 90, 67, 92, 67, 67, 95, 67, + 79, 77, 99, 100, 101, 1, 71, 104, 105, 89, + 82, 108, 77, 82, 111, 112, 81, 91, 123, 84, + 85, 86, 119, 88, 86, 90, 87, 92, 123, 93, + 95, 94, 139, 29, 99, 100, 101, 1, 94, 104, + 105, 94, 94, 108, 102, 96, 111, 112, 96, 109, + 153, 148, 149, 102, 119, 110, 139, -1, -1, 126, + -1, -1, -1, -1, -1, 29, -1, -1, -1, 126, + -1, -1, -1, 127, -1, 71, -1, -1, 128, -1, + -1, 77, 128, 148, 149, 81, 128, 128, 84, 85, + 86, 129, 88, -1, 90, 142, 92, 142, 142, 95, + -1, -1, 142, 99, 100, 101, 1, 71, 104, 105, + 142, 142, 108, 77, 142, 111, 112, 81, 142, 146, + 84, 85, 86, 119, 88, 146, 90, 146, 92, 146, + 146, 95, 146, 146, 146, 99, 100, 101, 147, 149, + 104, 105, 148, 148, 108, 148, 148, 111, 112, 148, + 148, 148, 148, 149, 148, 119, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 148, 148, 148, 148, + 148, 148, 148, 148, 148, 148, 71, 149, 149, 149, + 149, 149, 77, 149, 148, 149, 81, 149, 149, 84, + 85, 86, 149, 88, 149, 90, 29, 92, 149, 149, + 95, 149, 149, 149, 99, 100, 101, 150, 150, 104, + 105, 150, 150, 108, 47, 48, 111, 112, 150, 150, + 53, 150, 55, 150, 119, 150, 150, 150, 150, 150, + 150, 150, 150, 150, 67, 150, 150, 150, 150, 47, + 48, 150, 75, 76, 150, 53, 79, 55, 150, 150, + 83, 150, 150, 148, 149, 151, 150, 150, 150, 67, + 150, 150, 150, 154, 151, 151, 151, 75, 76, 151, + 151, 79, 151, 151, 151, 83, 151, 151, 151, 151, + 151, 151, 151, 151, 151, 151, -1, 152, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 130, 152, 132, + 133, 134, 135, 136, 137, 138, 152, 152, 152, 152, + 152, 144, 145, 152, 152, 152, 152, 152, 151, -1, + 153, 155, 130, 154, 132, 133, 134, 135, 136, 137, + 138, 155, 155, 155, 155, 155, 144, 145, 155, 155, + 155, 155, 155, 151, 155, 153, 155, -1, 155, 155, + -1, 156 ); protected $actionBase = array( - 0, 220, 295, 109, 109, 180, 745, -2, -2, -2, - -2, -2, 135, 574, 473, 404, 473, 606, 505, 675, - 675, 675, 330, 389, 221, 221, 831, 221, 359, 365, - 328, 520, 589, 548, 576, 42, 42, 42, 42, 134, - 134, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 254, 179, 290, 397, 757, 755, 738, 741, 833, - 679, 829, 784, 785, 623, 786, 787, 788, 789, 790, - 783, 791, 849, 792, 418, 418, 418, 418, 418, 418, - 418, 418, 418, 418, 418, -3, 354, 383, 413, 206, - 628, 521, 521, 521, 521, 521, 521, 521, 175, 175, + 0, 220, 295, 445, 370, 357, 357, 307, 728, -2, + -2, 135, -2, -2, -2, 623, 724, 655, 724, 554, + 756, 825, 825, 825, 151, 188, 476, 476, 860, 146, + 476, 328, 253, 114, 621, 393, 390, 502, 502, 502, + 502, 134, 134, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 502, 502, 502, 502, 502, 502, 502, + 502, 502, 502, 179, 178, 539, 523, 715, 735, 737, + 738, 858, 668, 857, 796, 797, 561, 798, 799, 800, + 801, 802, 795, 803, 886, 805, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 273, 248, 225, + 308, 274, 628, 365, 365, 365, 365, 365, 365, 365, 175, 175, 175, 175, 175, 175, 175, 175, 175, 175, - 175, 175, 175, 175, 175, 403, 618, 618, 618, 523, - 737, 603, 762, 762, 762, 762, 762, 762, 762, 762, - 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, - 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, - 762, 762, 762, 762, 762, 762, 762, 762, 762, 762, - 762, 762, 762, 762, 762, 470, -20, -20, 509, 608, - 327, 583, 210, 489, 197, 25, 25, 25, 25, 25, - 17, 45, 5, 5, 5, 5, 712, 305, 305, 305, - 305, 118, 118, 118, 118, 780, 781, 801, 804, 395, - 395, 696, 696, 616, 773, 522, 522, 498, 498, 487, - 487, 487, 487, 487, 487, 487, 487, 487, 487, 387, - 156, 823, 130, 130, 130, 130, 243, 409, 633, 863, - 207, 207, 207, 243, 248, 248, 248, 476, 476, 476, - 76, 662, 296, 86, 86, 86, 86, 296, 86, 86, - 554, 554, 554, 483, 761, 676, 477, 430, 97, 459, - 657, 807, 661, 808, 540, 702, 96, 656, 705, -6, - 680, 577, 571, 561, 689, 406, -6, 254, 551, 447, - 617, 732, 663, 268, 730, 377, 38, 367, 532, 362, - 414, 334, 774, 720, 827, 826, 74, 321, 691, 617, - 617, 617, 137, 84, 775, 772, 362, 273, 575, 575, - 575, 575, 806, 776, 575, 575, 575, 575, 805, 800, - 432, 408, 782, 331, 731, 649, 649, 649, 649, 649, - 649, 635, 649, 813, 666, 825, 825, 664, 668, 635, - 824, 824, 824, 824, 635, 649, 825, 825, 635, 616, - 825, 168, 635, 672, 649, 667, 667, 824, 756, 718, - 666, 669, 681, 825, 825, 825, 681, 664, 635, 824, - 682, 699, 466, 825, 824, 632, 632, 682, 635, 632, - 668, 632, 20, 605, 641, 821, 822, 820, 625, 698, - 688, 674, 811, 810, 816, 665, 626, 814, 812, 706, - 717, 716, 639, 610, 642, 645, 646, 648, 697, 637, - 694, 680, 707, 629, 629, 629, 690, 658, 690, 629, - 629, 629, 629, 629, 629, 629, 629, 848, 700, 701, - 693, 659, 715, 604, 704, 687, 472, 768, 650, 706, - 706, 802, 835, 842, 847, 651, 643, 734, 837, 690, - 862, 729, 274, 587, 652, 803, 703, 647, 655, 690, - 809, 690, 769, 690, 834, 799, 644, 706, 779, 629, - 832, 861, 860, 859, 858, 857, 856, 855, 854, 630, - 853, 714, 677, 841, 246, 815, 689, 692, 653, 713, - 67, 852, 778, 690, 690, 770, 761, 690, 771, 711, - 728, 845, 710, 840, 851, 650, 839, 690, 686, 850, - 67, 634, 598, 828, 678, 708, 819, 671, 830, 818, - 759, 547, 579, 777, 636, 754, 844, 843, 846, 709, - 760, 763, 572, 660, 640, 670, 793, 765, 817, 735, - 794, 795, 836, 684, 707, 654, 685, 683, 673, 767, - 796, 838, 736, 739, 743, 797, 753, 798, 0, 0, + 175, 175, 175, 175, 175, 175, 175, 320, 553, 553, + 553, 489, 887, 526, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 912, 912, 912, + 912, 912, 912, 912, 912, 912, 912, 493, -20, -20, + 477, 661, 402, 629, 210, 332, 197, 25, 25, 25, + 25, 25, 17, 141, 5, 5, 5, 5, 335, 122, + 122, 122, 122, 118, 118, 118, 118, 471, 396, 396, + 682, 682, 642, 774, 579, 579, 537, 537, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 301, 633, + 853, 296, 296, 296, 296, 514, 514, 514, 143, 484, + 637, 915, 143, 521, 521, 521, 446, 446, 446, 113, + 648, 398, 235, 235, 235, 235, 398, 235, 235, 577, + 577, 577, 439, 499, 651, 100, 379, 486, 433, 672, + 806, 669, 788, 540, 696, 111, 703, 701, 617, 662, + 617, 603, 598, 575, 673, 312, 847, 147, 179, 538, + 481, 631, 744, 292, 736, 66, 331, 423, 542, 355, + 382, 710, 731, 856, 855, 339, 678, 631, 631, 631, + 408, 106, 770, 772, 355, -8, 602, 602, 602, 602, + 782, 773, 602, 602, 602, 602, 781, 778, 316, 230, + 822, 215, 746, 618, 618, 644, 644, 618, 618, 618, + 618, 620, 622, 618, 834, 849, 849, 644, 641, 644, + 620, 622, 824, 824, 824, 824, 644, 622, 644, 644, + 618, 644, 849, 849, 622, 642, 849, 67, 622, 663, + 618, 653, 653, 824, 714, 730, 644, 644, 666, 849, + 849, 849, 666, 622, 824, 660, 711, 38, 849, 824, + 645, 641, 645, 660, 622, 645, 641, 641, 645, 20, + 654, 634, 833, 841, 838, 749, 625, 615, 851, 850, + 842, 852, 848, 614, 708, 723, 726, 626, 638, 639, + 647, 650, 676, 649, 674, 662, 693, 627, 627, 627, + 679, 680, 679, 627, 627, 627, 627, 627, 627, 627, + 627, 914, 689, 688, 670, 658, 732, 632, 707, 667, + 512, 750, 613, 708, 708, 791, 874, 883, 889, 829, + 619, 847, 876, 679, 904, 718, 47, 636, 846, 789, + 699, 704, 679, 845, 679, 751, 679, 866, 793, 652, + 832, 708, 831, 627, 864, 913, 911, 909, 907, 906, + 905, 896, 903, 630, 900, 729, 659, 882, 452, 854, + 673, 692, 706, 722, 830, 268, 899, 828, 679, 679, + 752, 748, 679, 754, 721, 717, 862, 747, 881, 898, + 613, 878, 679, 671, 827, 897, 268, 643, 624, 859, + 656, 739, 835, 863, 839, 758, 550, 582, 826, 777, + 821, 635, 740, 885, 884, 861, 742, 759, 564, 763, + 646, 819, 765, 843, 743, 818, 814, 875, 657, 693, + 675, 665, 664, 640, 769, 811, 877, 745, 741, 734, + 808, 733, 807, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 134, 134, - -2, -2, -2, -2, 0, 0, 0, 0, 0, -2, + 0, 0, 0, 134, 134, 134, 134, -2, -2, -2, + -2, 0, 0, -2, 0, 0, 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 0, 0, 134, 134, + 134, 134, 134, 0, 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, @@ -522,265 +535,277 @@ class Php5 extends \PhpParser\ParserAbstract 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 134, 134, 134, 418, 418, - 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 418, -20, -20, -20, -20, 418, -20, -20, - -20, -20, -20, -20, -20, 418, 418, 418, 418, 418, - 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, -20, 418, 418, 418, -20, 487, -20, 487, - 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, - 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, - 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, - 487, 487, 487, 487, 487, 487, 487, 487, 487, 487, - 487, 487, 418, 0, 0, 418, -20, 418, -20, 418, - -20, 418, 418, 418, 418, 418, 418, -20, -20, -20, - -20, -20, -20, 0, 248, 248, 248, 248, -20, -20, - -20, -20, 55, 55, 55, 55, 487, 487, 487, 487, - 487, 487, 248, 248, 476, 476, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 487, 55, 487, 649, - 649, 649, 649, 649, 296, 296, 296, 47, 47, 47, - 649, 0, 0, 0, 0, 0, 0, 649, 296, 0, - 487, 487, 487, 487, 0, 487, 487, 649, 649, 649, - 649, 47, 296, 649, 825, 0, 47, 550, 550, 550, - 550, 67, 362, 0, 649, 649, 0, 669, 0, 0, - 0, 825, 0, 0, 0, 0, 0, 629, 274, 734, - 0, 433, 0, 0, 0, 0, 0, 0, 0, 643, - 433, 322, 322, 0, 0, 630, 629, 629, 629, 0, - 0, 643, 643, 0, 0, 0, 0, 0, 0, 440, - 643, 0, 0, 0, 0, 440, 425, 0, 0, 425, - 0, 67 + 134, 134, 134, 134, 134, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 568, + -20, -20, -20, -20, 568, -20, -20, -20, -20, -20, + -20, -20, 568, 568, 568, 568, 568, 568, 568, 568, + 568, 568, 568, 568, 568, 568, 568, 568, 568, -20, + 568, 568, 568, -20, 270, -20, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 568, + 0, 0, 568, -20, 568, -20, 568, -20, 568, 568, + 568, 568, 568, 568, -20, -20, -20, -20, -20, -20, + 0, 521, 521, 521, 521, -20, -20, -20, -20, -36, + 270, 270, 270, 270, 270, 270, 521, 521, 446, 446, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 270, -36, 270, 618, 618, 618, 618, 641, 641, 641, + 618, 398, 398, 398, 618, 0, 0, 0, 0, 0, + 0, 618, 398, 0, 270, 270, 270, 270, 0, 270, + 270, 618, 618, 618, 641, 618, 398, 641, 641, 618, + 849, 580, 580, 580, 580, 268, 355, 0, 618, 618, + 641, 641, 641, 0, 0, 0, 849, 0, 644, 0, + 0, 0, 0, 627, 47, 0, 430, 0, 0, 0, + 0, 0, 0, 619, 430, 466, 466, 0, 630, 627, + 627, 627, 0, 0, 619, 619, 0, 0, 0, 0, + 0, 0, 442, 619, 0, 0, 0, 0, 442, 140, + 0, 0, 140, 0, 268 ); protected $actionDefault = array( 3,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767, 525, 525,32767, 481,32767,32767, - 32767,32767,32767,32767,32767, 287, 287, 287,32767,32767, - 32767, 513, 513, 513, 513, 513, 513, 513, 513, 513, - 513, 513,32767,32767,32767,32767,32767, 369,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 531, 531,32767,32767, + 486,32767,32767,32767,32767,32767,32767, 292, 292, 292, + 32767,32767,32767, 519, 519, 519, 519, 519, 519, 519, + 519, 519, 519, 519,32767,32767,32767,32767,32767, 374, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767, 375, 530,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767, 350, 351, 353, 354, 286, 514, - 237, 376, 529, 285, 239, 314, 485,32767,32767,32767, - 316, 116, 248, 193, 484, 119, 284, 224, 368, 370, - 315, 291, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 290, 441, 347, 346, 345, 443, - 32767, 442, 478, 478, 481,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 380, 536,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 355, 356, 358, 359, + 291, 520, 240, 381, 535, 290, 242, 319, 490,32767, + 32767,32767, 321, 119, 251, 196, 489, 122, 289, 227, + 373, 375, 320, 296, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 295, 446, 352, 351, + 350, 448,32767, 447, 483, 483, 486,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767, 312, 469, 468, 313, 439, - 317, 440, 319, 444, 318, 335, 336, 333, 334, 337, - 446, 445, 462, 463, 460, 461, 289, 338, 339, 340, - 341, 464, 465, 466, 467, 271, 271, 271, 271,32767, - 32767, 524, 524,32767,32767, 326, 327, 453, 454,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 272,32767, 228, 228, 228, 228, 228,32767,32767,32767, - 32767,32767,32767,32767, 321, 322, 320, 448, 449, 447, - 32767, 415,32767,32767,32767,32767,32767, 417,32767,32767, - 32767,32767,32767,32767,32767,32767,32767, 486,32767,32767, - 32767,32767,32767,32767,32767, 499, 404,32767,32767,32767, - 397, 212, 214, 161, 472,32767,32767,32767,32767, 504, - 331,32767,32767,32767,32767,32767,32767, 539,32767, 499, - 32767,32767,32767,32767,32767,32767,32767,32767, 344, 323, - 324, 325,32767,32767,32767,32767, 503, 497, 456, 457, - 458, 459,32767,32767, 450, 451, 452, 455,32767,32767, + 32767,32767,32767,32767,32767,32767,32767, 317, 474, 473, + 318, 444, 322, 445, 324, 449, 323, 340, 341, 338, + 339, 342, 451, 450, 467, 468, 465, 466, 294, 343, + 344, 345, 346, 469, 470, 471, 472, 275,32767,32767, + 530, 530,32767,32767, 331, 332, 458, 459,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 276, + 32767, 231, 231, 231, 231,32767,32767,32767, 231,32767, + 32767,32767,32767, 326, 327, 325, 453, 454, 452,32767, + 420,32767,32767,32767,32767,32767, 422,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 491,32767, + 32767,32767,32767,32767, 504, 409,32767,32767,32767, 402, + 32767, 215, 217, 164, 477,32767,32767,32767,32767,32767, + 509, 336,32767,32767,32767,32767,32767, 545,32767, 504, + 32767,32767,32767,32767,32767,32767, 349, 328, 329, 330, + 32767,32767,32767,32767, 508, 502, 461, 462, 463, 464, + 32767,32767, 455, 456, 457, 460,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767, 165,32767, 412,32767, 418, 418,32767,32767, 165, - 32767,32767,32767,32767, 165,32767, 502, 501, 165,32767, - 398, 480, 165, 178,32767, 176, 176,32767, 198, 198, - 32767,32767, 180, 473, 492,32767, 180,32767, 165,32767, - 386, 167, 480,32767,32767, 230, 230, 386, 165, 230, - 32767, 230,32767, 82, 422,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767,32767, 399, - 32767,32767,32767,32767, 365, 366, 475, 488,32767, 489, - 32767, 397,32767, 329, 330, 332, 309,32767, 311, 355, - 356, 357, 358, 359, 360, 361, 363,32767, 402,32767, - 405,32767,32767,32767, 84, 108, 247,32767, 537, 84, - 400,32767,32767, 294, 537,32767,32767,32767,32767, 532, - 32767,32767, 288,32767,32767,32767, 84,32767, 84, 243, - 32767, 163,32767, 522,32767, 497,32767, 401,32767, 328, - 32767,32767,32767,32767,32767,32767,32767,32767,32767, 498, - 32767,32767,32767,32767, 219,32767, 435,32767, 84,32767, - 179,32767,32767, 292, 238,32767,32767, 531,32767,32767, - 32767,32767,32767,32767,32767,32767,32767, 164,32767,32767, - 181,32767,32767, 497,32767,32767,32767,32767,32767,32767, - 32767,32767, 283,32767,32767,32767,32767,32767, 497,32767, - 32767,32767, 223,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767, 82, 60,32767, 265,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767, 121, 121, - 3, 121, 121, 3, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 206, 250, 209, - 198, 198, 158, 250, 250, 250, 257 + 32767,32767, 168,32767, 417, 423, 423,32767,32767,32767, + 32767, 168,32767,32767,32767,32767,32767, 168,32767,32767, + 32767,32767, 507, 506, 168,32767, 403, 485, 168, 181, + 32767, 179, 179,32767, 201, 201,32767,32767, 183, 478, + 497,32767, 183, 168,32767, 391, 170, 485,32767,32767, + 233,32767, 233, 391, 168, 233,32767,32767, 233,32767, + 84, 427,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 404,32767,32767,32767, 370, 371, + 480, 493,32767, 494,32767, 402,32767, 334, 335, 337, + 314,32767, 316, 360, 361, 362, 363, 364, 365, 366, + 368,32767, 407,32767, 410,32767,32767,32767, 86, 111, + 250,32767, 543, 86, 405,32767,32767, 299, 543,32767, + 32767,32767,32767, 538,32767,32767, 293,32767,32767,32767, + 86, 86, 246,32767, 166,32767, 528,32767, 544,32767, + 502, 406,32767, 333,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 503,32767,32767,32767,32767, 222,32767, + 440,32767, 86,32767,32767, 182,32767,32767, 297, 241, + 32767,32767, 537,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 167,32767,32767,32767, 184,32767,32767, 502, + 32767,32767,32767,32767,32767,32767,32767, 288,32767,32767, + 32767,32767,32767,32767,32767, 502,32767,32767, 226,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 84, 60, + 32767, 269,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767, 124, 124, 3, 124, 124, 253, 3, + 253, 124, 253, 253, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 209, 212, 201, 201, 161, 124, + 124, 261 ); protected $goto = array( - 160, 160, 134, 134, 139, 134, 135, 136, 137, 142, - 144, 181, 162, 158, 158, 158, 158, 139, 139, 159, - 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, - 154, 155, 156, 157, 178, 133, 179, 493, 494, 360, - 495, 499, 500, 501, 502, 503, 504, 505, 506, 962, - 138, 140, 141, 143, 165, 170, 180, 196, 245, 248, - 250, 252, 254, 255, 256, 257, 258, 259, 267, 268, - 269, 270, 285, 286, 314, 315, 316, 379, 380, 381, - 549, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 145, 146, 147, 161, 148, 163, - 149, 197, 164, 150, 151, 152, 198, 153, 131, 625, - 567, 754, 567, 567, 567, 567, 567, 567, 567, 567, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, - 567, 567, 567, 567, 567, 567, 567, 567, 567, 567, - 567, 567, 567, 567, 567, 1100, 753, 1100, 1100, 1100, - 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, - 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, - 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, - 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, - 523, 784, 497, 497, 497, 497, 497, 497, 6, 508, - 634, 508, 497, 497, 497, 497, 497, 497, 497, 497, - 497, 497, 509, 550, 509, 580, 606, 522, 885, 885, - 1190, 1190, 815, 849, 849, 849, 849, 168, 844, 850, - 522, 522, 171, 172, 173, 388, 389, 390, 391, 167, - 195, 199, 201, 249, 251, 253, 260, 261, 262, 263, - 264, 265, 271, 272, 273, 274, 287, 288, 317, 318, - 319, 394, 395, 396, 397, 169, 174, 246, 247, 175, - 176, 177, 387, 608, 543, 543, 573, 539, 583, 586, - 631, 855, 541, 541, 496, 498, 529, 545, 574, 577, - 587, 593, 341, 1169, 566, 1169, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 566, - 566, 566, 566, 566, 566, 566, 566, 566, 566, 514, - 443, 445, 933, 636, 327, 309, 1101, 618, 931, 519, - 519, 519, 519, 777, 551, 552, 553, 554, 555, 556, - 557, 558, 560, 589, 903, 611, 538, 519, 617, 548, - 358, 544, 572, 430, 430, 430, 430, 430, 430, 1194, - 777, 777, 361, 430, 430, 430, 430, 430, 430, 430, - 430, 430, 430, 1065, 1161, 1065, 892, 892, 892, 892, - 892, 1168, 598, 1168, 590, 344, 404, 892, 369, 369, - 369, 1058, 1184, 1184, 1184, 1076, 1075, 1065, 1065, 1065, - 1065, 1149, 1065, 1065, 519, 519, 536, 568, 519, 519, - 615, 519, 369, 510, 960, 510, 1167, 386, 770, 770, - 778, 778, 778, 780, 520, 769, 276, 277, 278, 535, - 607, 659, 562, 547, 594, 868, 882, 613, 867, 616, - 878, 620, 621, 628, 630, 635, 637, 1081, 375, 1201, - 1201, 1187, 1009, 889, 1019, 17, 13, 355, 790, 752, - 1200, 1200, 898, 1061, 1062, 362, 941, 1058, 1201, 527, - 871, 561, 851, 540, 657, 347, 511, 880, 875, 1200, - 1059, 1160, 1059, 21, 398, 373, 773, 1203, 604, 451, - 1060, 771, 907, 342, 343, 368, 645, 402, 446, 10, - 1056, 1051, 912, 781, 578, 1146, 859, 459, 949, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 162, 162, 136, 136, 141, 144, 136, 137, 138, 139, + 146, 183, 164, 160, 160, 160, 160, 141, 141, 161, + 161, 161, 161, 161, 161, 161, 161, 161, 161, 161, + 156, 157, 158, 159, 180, 135, 181, 497, 498, 361, + 499, 503, 504, 505, 506, 507, 508, 509, 510, 972, + 140, 142, 143, 145, 167, 172, 182, 198, 247, 250, + 252, 254, 256, 257, 258, 259, 260, 261, 269, 270, + 271, 272, 284, 285, 313, 314, 315, 377, 378, 379, + 553, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 147, 148, 149, 163, 150, 165, + 151, 199, 166, 152, 153, 154, 200, 155, 133, 630, + 571, 792, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 571, 571, 571, 571, 571, + 571, 571, 571, 571, 571, 1110, 762, 1110, 1110, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, 1110, + 501, 501, 501, 501, 501, 501, 512, 638, 512, 761, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 513, 755, 513, 893, 893, 1201, 1201, 527, 585, 613, + 857, 857, 857, 857, 170, 852, 858, 1086, 1085, 173, + 174, 175, 386, 387, 388, 389, 169, 197, 201, 203, + 251, 253, 255, 262, 263, 264, 265, 266, 267, 273, + 274, 275, 276, 286, 287, 316, 317, 318, 392, 393, + 394, 395, 171, 176, 248, 249, 177, 178, 179, 385, + 615, 546, 546, 578, 542, 1212, 1212, 823, 340, 544, + 544, 500, 502, 533, 550, 579, 582, 592, 599, 619, + 863, 1212, 622, 911, 570, 359, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 570, + 570, 570, 570, 570, 570, 570, 570, 570, 570, 555, + 556, 557, 558, 559, 560, 561, 562, 564, 595, 518, + 554, 326, 311, 594, 526, 609, 610, 949, 552, 523, + 523, 523, 577, 523, 588, 591, 636, 526, 526, 547, + 436, 436, 436, 436, 436, 436, 541, 523, 1205, 950, + 436, 436, 436, 436, 436, 436, 436, 436, 436, 436, + 1075, 362, 1075, 900, 900, 900, 900, 596, 343, 402, + 900, 514, 1159, 514, 900, 1179, 603, 1179, 3, 4, + 367, 367, 367, 614, 1075, 1075, 1075, 1075, 785, 1075, + 1075, 367, 367, 1178, 1198, 1178, 1171, 367, 374, 467, + 1195, 1195, 1195, 523, 523, 367, 1226, 540, 572, 523, + 523, 1019, 1068, 523, 897, 785, 785, 906, 346, 917, + 520, 917, 396, 368, 781, 372, 915, 1177, 970, 779, + 524, 539, 669, 665, 566, 400, 1061, 920, 600, 760, + 551, 890, 620, 621, 886, 625, 626, 633, 635, 640, + 642, 789, 879, 861, 859, 861, 664, 1091, 515, 888, + 883, 1193, 1193, 1193, 867, 1029, 19, 15, 355, 341, + 342, 958, 778, 778, 356, 1066, 786, 786, 786, 788, + 452, 531, 777, 1156, 465, 543, 565, 583, 0, 520, + 1071, 1072, 0, 0, 1068, 0, 0, 23, 1211, 1211, + 456, 0, 611, 369, 369, 369, 0, 1069, 1170, 1069, + 0, 13, 538, 0, 1211, 0, 1070, 449, 451, 942, + 641, 0, 1214, 0, 1111, 623, 940, 0, 0, 0, + 369, 0, 618, 0, 384, 0, 0, 1067, 627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 517, 537, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 517, 0, 537, 0, 0, 0, 0, + 0, 532, 516, 0, 521, 439, 0, 441, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 528 + 0, 0, 784, 1219 ); protected $gotoCheck = array( - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 53, - 63, 12, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 119, 11, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 94, 25, 110, 110, 110, 110, 110, 110, 91, 63, - 5, 63, 110, 110, 110, 110, 110, 110, 110, 110, - 110, 110, 110, 40, 110, 36, 36, 40, 71, 71, - 71, 71, 46, 63, 63, 63, 63, 23, 63, 63, - 40, 40, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 47, 47, 47, 47, 47, 47, 56, 56, - 56, 29, 47, 47, 47, 47, 47, 47, 47, 47, - 47, 47, 66, 111, 53, 111, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 8, - 7, 7, 7, 7, 118, 118, 7, 7, 7, 8, - 8, 8, 8, 19, 103, 103, 103, 103, 103, 103, - 103, 103, 103, 103, 78, 57, 8, 8, 57, 2, - 57, 102, 2, 53, 53, 53, 53, 53, 53, 132, - 19, 19, 43, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 76, 53, 53, 53, 53, 53, - 53, 112, 120, 112, 64, 64, 64, 53, 116, 116, - 116, 76, 112, 112, 112, 117, 117, 53, 53, 53, - 53, 124, 53, 53, 8, 8, 8, 8, 8, 8, - 53, 8, 116, 115, 94, 115, 112, 116, 19, 19, - 19, 19, 19, 19, 8, 19, 61, 61, 61, 28, - 45, 28, 28, 8, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 30, 44, 134, - 134, 130, 95, 73, 30, 30, 30, 30, 10, 10, - 133, 133, 75, 76, 76, 54, 91, 76, 134, 54, - 10, 30, 10, 54, 10, 14, 10, 10, 10, 133, - 76, 76, 76, 30, 18, 13, 21, 133, 30, 54, - 76, 20, 79, 66, 66, 9, 68, 17, 59, 54, - 108, 106, 80, 22, 60, 123, 65, 101, 93, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 56, + 66, 28, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 124, 15, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, + 115, 115, 115, 115, 115, 115, 66, 8, 66, 14, + 115, 115, 115, 115, 115, 115, 115, 115, 115, 115, + 115, 5, 115, 74, 74, 74, 74, 99, 39, 39, + 66, 66, 66, 66, 26, 66, 66, 122, 122, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 50, + 50, 50, 50, 50, 50, 140, 140, 49, 69, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 60, + 32, 140, 60, 81, 56, 60, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 108, + 108, 108, 108, 108, 108, 108, 108, 108, 108, 10, + 46, 123, 123, 64, 46, 64, 64, 95, 2, 10, + 10, 10, 2, 10, 59, 59, 59, 46, 46, 107, + 56, 56, 56, 56, 56, 56, 10, 10, 138, 95, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 45, 56, 56, 56, 56, 56, 67, 67, 67, + 56, 120, 129, 120, 56, 116, 125, 116, 29, 29, + 12, 12, 12, 48, 56, 56, 56, 56, 22, 56, + 56, 12, 12, 117, 136, 117, 79, 12, 47, 56, + 117, 117, 117, 10, 10, 12, 12, 10, 10, 10, + 10, 100, 79, 10, 76, 22, 22, 78, 17, 12, + 12, 12, 21, 11, 24, 16, 82, 117, 99, 23, + 10, 31, 71, 31, 31, 20, 111, 83, 31, 13, + 10, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 25, 13, 13, 13, 13, 13, 33, 13, 13, + 13, 8, 8, 8, 68, 33, 33, 33, 33, 69, + 69, 97, 22, 22, 57, 113, 22, 22, 22, 22, + 62, 57, 22, 128, 106, 57, 33, 63, -1, 12, + 79, 79, -1, -1, 79, -1, -1, 33, 139, 139, + 57, -1, 33, 121, 121, 121, -1, 79, 79, 79, + -1, 57, 8, -1, 139, -1, 79, 7, 7, 7, + 7, -1, 139, -1, 7, 7, 7, -1, -1, -1, + 121, -1, 12, -1, 121, -1, -1, 12, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8, 8, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8, -1, 8, -1, -1, -1, -1, + -1, 99, 8, -1, 8, 8, -1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 94 + -1, -1, 8, 8 ); protected $gotoBase = array( - 0, 0, -261, 0, 0, 198, 0, 347, 29, 192, - 487, 154, 109, 168, 185, 0, 0, 121, 183, 43, - 173, 184, 93, 37, 0, 193, 0, 0, -180, 273, - 64, 0, 0, 0, 0, 0, 189, 0, 0, -22, - 201, 0, 0, 354, 188, 180, 216, 3, 0, 0, - 0, 0, 0, 104, 71, 0, -15, -81, 0, 92, - 88, -207, 0, -90, 90, 89, -137, 0, 169, 0, - 0, -51, 0, 177, 0, 179, 67, 0, 351, 166, - 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 196, 0, 78, 161, 181, 0, 0, 0, 0, - 0, 80, 356, 322, 0, 0, 115, 0, 111, 0, - -77, 4, 112, 0, 0, 144, 108, 114, 33, -45, - 209, 0, 0, 83, 227, 0, 0, 0, 0, 0, - 199, 0, 362, 182, 171, 0, 0 + 0, 0, -277, 0, 0, 210, 0, 552, 196, 0, + 40, 130, 111, 477, 207, 154, 119, 139, 0, 0, + 71, 132, 109, 122, 133, 74, 32, 0, 101, -251, + 0, -173, 280, 83, 0, 0, 0, 0, 0, 190, + 0, 0, -24, 0, 0, 361, 336, 149, 144, 269, + 1, 0, 0, 0, 0, 0, 102, 87, 0, 72, + -163, 0, 78, 75, -287, 0, -92, 84, 85, -157, + 0, 114, 0, 0, -55, 0, 146, 0, 145, 98, + 0, 278, 116, 59, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 90, 0, 91, 0, 186, + 151, 0, 0, 0, 0, 0, 61, 352, 305, 0, + 0, 60, 0, 94, 0, -78, 117, 135, 0, 0, + 113, 238, -69, 41, -47, 211, 0, 0, 66, 206, + 0, 0, 0, 0, 0, 0, 153, 0, 358, 228, + -25, 0, 0 ); protected $gotoDefault = array( - -32768, 462, 668, 2, 669, 740, 748, 601, 479, 515, - 853, 791, 792, 364, 410, 480, 363, 399, 392, 779, - 772, 774, 782, 166, 400, 785, 1, 787, 521, 823, - 1010, 351, 795, 352, 592, 797, 531, 799, 800, 132, - 481, 365, 366, 532, 374, 581, 814, 266, 371, 816, - 353, 817, 826, 354, 614, 597, 563, 610, 482, 442, - 575, 275, 542, 1073, 570, 858, 340, 866, 648, 874, - 877, 483, 564, 888, 448, 896, 1086, 382, 902, 908, - 913, 916, 418, 401, 588, 920, 921, 5, 925, 626, - 627, 940, 300, 948, 961, 416, 1029, 1031, 484, 485, - 525, 456, 507, 530, 486, 1052, 436, 403, 1055, 487, - 488, 426, 427, 1070, 346, 1154, 345, 444, 308, 1141, - 584, 1105, 452, 1193, 1150, 337, 489, 490, 359, 376, - 1188, 431, 1195, 1202, 335, 367, 571 + -32768, 469, 673, 2, 674, 745, 753, 606, 483, 639, + 484, 519, 1189, 798, 799, 800, 364, 410, 485, 363, + 397, 390, 787, 780, 782, 790, 168, 398, 793, 1, + 795, 525, 831, 1020, 351, 803, 352, 598, 805, 535, + 807, 808, 134, 365, 366, 536, 486, 373, 586, 822, + 268, 370, 824, 353, 825, 834, 354, 466, 461, 567, + 617, 431, 448, 580, 574, 545, 1083, 575, 866, 339, + 874, 670, 882, 885, 487, 568, 896, 453, 904, 1096, + 380, 910, 916, 921, 277, 924, 411, 399, 593, 929, + 930, 7, 934, 631, 632, 8, 299, 957, 607, 971, + 416, 1039, 1041, 488, 489, 529, 460, 511, 534, 490, + 1062, 442, 401, 1065, 491, 492, 432, 433, 1080, 345, + 1164, 344, 450, 310, 1151, 589, 1115, 457, 1204, 1160, + 338, 493, 494, 360, 1183, 375, 1199, 437, 1206, 1213, + 334, 549, 576 ); protected $ruleToNonTerminal = array( @@ -792,53 +817,54 @@ class Php5 extends \PhpParser\ParserAbstract 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 8, 8, 9, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 14, 14, 15, 15, - 15, 15, 17, 17, 13, 13, 18, 18, 19, 19, - 20, 20, 21, 21, 16, 16, 22, 24, 24, 25, - 26, 26, 28, 27, 27, 27, 27, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 10, 10, 50, 50, - 52, 51, 51, 44, 44, 54, 54, 55, 55, 11, - 12, 12, 12, 58, 58, 58, 59, 59, 62, 62, - 60, 60, 64, 64, 37, 37, 46, 46, 49, 49, - 49, 48, 48, 65, 38, 38, 38, 38, 66, 66, - 67, 67, 68, 68, 35, 35, 31, 31, 69, 33, - 33, 70, 32, 32, 34, 34, 45, 45, 45, 56, - 56, 72, 72, 73, 73, 75, 75, 75, 74, 74, - 57, 57, 76, 76, 76, 77, 77, 78, 78, 78, - 41, 41, 79, 79, 79, 42, 42, 80, 80, 61, - 61, 81, 81, 81, 81, 86, 86, 87, 87, 88, - 88, 88, 88, 88, 89, 90, 90, 85, 85, 82, - 82, 84, 84, 92, 92, 91, 91, 91, 91, 91, - 91, 83, 83, 93, 93, 43, 43, 36, 36, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 30, 30, 40, 40, 98, 98, 99, - 99, 99, 99, 105, 94, 94, 101, 101, 107, 107, - 108, 109, 109, 109, 109, 109, 109, 63, 63, 53, - 53, 53, 95, 95, 113, 113, 110, 110, 114, 114, - 114, 114, 96, 96, 96, 100, 100, 100, 106, 106, - 119, 119, 119, 119, 119, 119, 119, 119, 119, 119, - 119, 119, 119, 23, 23, 23, 23, 23, 23, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 121, 121, 121, 121, 121, 121, 121, 121, - 121, 121, 104, 104, 97, 97, 97, 97, 120, 120, - 123, 123, 122, 122, 124, 124, 47, 47, 47, 47, - 126, 126, 125, 125, 125, 125, 125, 127, 127, 112, - 112, 115, 115, 111, 111, 128, 128, 128, 128, 116, - 116, 116, 116, 103, 103, 117, 117, 117, 117, 71, - 129, 129, 130, 130, 130, 102, 102, 131, 131, 132, - 132, 132, 132, 118, 118, 118, 118, 134, 135, 133, - 133, 133, 133, 133, 133, 133, 136, 136, 136 + 7, 7, 8, 9, 10, 10, 11, 12, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 17, + 17, 18, 18, 18, 18, 20, 20, 16, 16, 21, + 21, 22, 22, 23, 23, 24, 24, 19, 19, 25, + 27, 27, 28, 29, 29, 31, 30, 30, 30, 30, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 13, + 13, 53, 53, 55, 54, 54, 47, 47, 57, 57, + 58, 58, 14, 15, 15, 15, 61, 61, 61, 62, + 62, 65, 65, 63, 63, 67, 67, 40, 40, 49, + 49, 52, 52, 52, 51, 51, 68, 41, 41, 41, + 41, 69, 69, 70, 70, 71, 71, 38, 38, 34, + 34, 72, 36, 36, 73, 35, 35, 37, 37, 48, + 48, 48, 59, 59, 75, 75, 76, 76, 78, 78, + 78, 77, 77, 60, 60, 79, 79, 79, 80, 80, + 81, 81, 81, 43, 43, 82, 82, 82, 44, 44, + 83, 83, 84, 84, 64, 85, 85, 85, 85, 90, + 90, 91, 91, 92, 92, 92, 92, 92, 93, 94, + 94, 89, 89, 86, 86, 88, 88, 96, 96, 95, + 95, 95, 95, 95, 95, 87, 87, 98, 97, 97, + 45, 45, 39, 39, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, + 42, 42, 42, 42, 42, 42, 42, 42, 33, 33, + 46, 46, 103, 103, 104, 104, 104, 104, 110, 99, + 99, 106, 106, 112, 112, 113, 114, 114, 114, 114, + 114, 114, 66, 66, 56, 56, 56, 100, 100, 118, + 118, 115, 115, 119, 119, 119, 119, 101, 101, 101, + 105, 105, 105, 111, 111, 124, 124, 124, 124, 124, + 124, 124, 124, 124, 124, 124, 124, 124, 26, 26, + 26, 26, 26, 26, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, + 126, 126, 126, 126, 126, 126, 126, 109, 109, 102, + 102, 102, 102, 125, 125, 128, 128, 127, 127, 129, + 129, 50, 50, 50, 50, 131, 131, 130, 130, 130, + 130, 130, 132, 132, 117, 117, 120, 120, 116, 116, + 134, 133, 133, 133, 133, 121, 121, 121, 121, 108, + 108, 122, 122, 122, 122, 74, 135, 135, 136, 136, + 136, 107, 107, 137, 137, 138, 138, 138, 138, 123, + 123, 123, 123, 140, 141, 139, 139, 139, 139, 139, + 139, 139, 142, 142, 142 ); protected $ruleToLength = array( @@ -850,2292 +876,1754 @@ class Php5 extends \PhpParser\ParserAbstract 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 1, 1, 3, - 5, 4, 3, 4, 2, 3, 1, 1, 7, 8, - 6, 7, 3, 1, 3, 1, 3, 1, 1, 3, - 1, 2, 1, 2, 3, 1, 3, 3, 1, 3, - 2, 0, 1, 1, 1, 1, 1, 3, 5, 8, - 3, 5, 9, 3, 2, 3, 2, 3, 2, 3, - 2, 3, 3, 3, 1, 2, 5, 7, 9, 5, - 6, 3, 3, 2, 2, 1, 1, 1, 0, 2, - 8, 0, 4, 1, 3, 0, 1, 0, 1, 10, - 7, 6, 5, 1, 2, 2, 0, 2, 0, 2, - 0, 2, 1, 3, 1, 4, 1, 4, 1, 1, - 4, 1, 3, 3, 3, 4, 4, 5, 0, 2, - 4, 3, 1, 1, 1, 4, 0, 2, 3, 0, - 2, 4, 0, 2, 0, 3, 1, 2, 1, 1, - 0, 1, 3, 4, 6, 1, 1, 1, 0, 1, - 0, 2, 2, 3, 3, 1, 3, 1, 2, 2, - 3, 1, 1, 2, 4, 3, 1, 1, 3, 2, - 0, 3, 3, 9, 3, 1, 3, 0, 2, 4, - 5, 4, 4, 4, 3, 1, 1, 1, 3, 1, - 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, - 1, 1, 3, 1, 3, 3, 1, 0, 1, 1, - 3, 3, 4, 4, 1, 2, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, - 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, - 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 1, 3, 5, 4, 3, 4, 4, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 1, 1, 1, 3, 2, 1, - 2, 10, 11, 3, 3, 2, 4, 4, 3, 4, - 4, 4, 4, 7, 3, 2, 0, 4, 1, 3, - 2, 2, 4, 6, 2, 2, 4, 1, 1, 1, - 2, 3, 1, 1, 1, 1, 1, 1, 3, 3, - 4, 4, 0, 2, 1, 0, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 3, 2, 1, 3, 1, 4, 3, 1, 3, + 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, + 1, 1, 3, 5, 4, 3, 4, 2, 3, 1, + 1, 7, 8, 6, 7, 3, 1, 3, 1, 3, + 1, 1, 3, 1, 2, 1, 2, 3, 1, 3, + 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, + 3, 5, 8, 3, 5, 9, 3, 2, 3, 2, + 3, 2, 3, 3, 3, 3, 1, 2, 2, 5, + 7, 9, 5, 6, 3, 3, 2, 2, 1, 1, + 1, 0, 2, 8, 0, 4, 1, 3, 0, 1, + 0, 1, 10, 7, 6, 5, 1, 2, 2, 0, + 2, 0, 2, 0, 2, 1, 3, 1, 4, 1, + 4, 1, 1, 4, 1, 3, 3, 3, 4, 4, + 5, 0, 2, 4, 3, 1, 1, 1, 4, 0, + 2, 3, 0, 2, 4, 0, 2, 0, 3, 1, + 2, 1, 1, 0, 1, 3, 4, 6, 1, 1, + 1, 0, 1, 0, 2, 2, 3, 3, 1, 3, + 1, 2, 2, 3, 1, 1, 2, 4, 3, 1, + 1, 3, 2, 0, 1, 3, 3, 9, 3, 1, + 3, 0, 2, 4, 5, 4, 4, 4, 3, 1, + 1, 1, 3, 1, 1, 0, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, + 3, 1, 0, 1, 1, 3, 3, 4, 4, 1, + 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, - 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, - 4, 3, 1, 3, 1, 1, 3, 3, 0, 2, - 0, 1, 3, 1, 3, 1, 1, 1, 1, 1, - 6, 4, 3, 4, 2, 4, 4, 1, 3, 1, - 2, 1, 1, 4, 1, 3, 6, 4, 4, 4, - 4, 1, 4, 0, 1, 1, 3, 1, 1, 4, - 3, 1, 1, 1, 0, 0, 2, 3, 1, 3, - 1, 4, 2, 2, 2, 1, 2, 1, 1, 1, - 4, 3, 3, 3, 6, 3, 1, 1, 1 + 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, + 5, 4, 3, 4, 4, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 3, 2, 1, 2, 10, 11, 3, 3, + 2, 4, 4, 3, 4, 4, 4, 4, 7, 3, + 2, 0, 4, 1, 3, 2, 2, 4, 6, 2, + 2, 4, 1, 1, 1, 2, 3, 1, 1, 1, + 1, 1, 1, 3, 3, 4, 4, 0, 2, 1, + 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 2, 1, 3, + 1, 4, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 5, 4, 4, 3, 1, 3, 1, + 1, 3, 3, 0, 2, 0, 1, 3, 1, 3, + 1, 1, 1, 1, 1, 6, 4, 3, 4, 2, + 4, 4, 1, 3, 1, 2, 1, 1, 4, 1, + 1, 3, 6, 4, 4, 4, 4, 1, 4, 0, + 1, 1, 3, 1, 1, 4, 3, 1, 1, 1, + 0, 0, 2, 3, 1, 3, 1, 4, 2, 2, + 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, + 6, 3, 1, 1, 1 ); - protected function reduceRule0() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule1() { - $this->semValue = $this->handleNamespaces($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule2() { - if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; - } - - protected function reduceRule3() { - $this->semValue = array(); - } - - protected function reduceRule4() { - $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; - if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule5() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule6() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule7() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule8() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule9() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule10() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule11() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule12() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule13() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule14() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule15() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule16() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule17() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule18() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule19() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule20() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule21() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule22() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule23() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule24() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule25() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule26() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule27() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule28() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule29() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule30() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule31() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule32() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule33() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule34() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule35() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule36() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule37() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule38() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule39() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule40() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule41() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule42() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule43() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule44() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule45() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule46() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule47() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule48() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule49() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule50() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule51() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule52() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule53() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule54() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule55() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule56() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule57() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule58() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule59() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule60() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule61() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule62() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule63() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule64() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule65() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule66() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule67() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule68() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule69() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule70() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule71() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule72() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule73() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule74() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule75() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule76() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule77() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule78() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule79() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule80() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule81() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule82() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule83() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule84() { - $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule85() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule86() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule87() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule88() { - $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule89() { - $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(3-2)], null, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + protected function initReduceCallbacks() { + $this->reduceCallbacks = [ + 0 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 1 => function ($stackPos) { + $this->semValue = $this->handleNamespaces($this->semStack[$stackPos-(1-1)]); + }, + 2 => function ($stackPos) { + if (is_array($this->semStack[$stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); } else { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }; + }, + 3 => function ($stackPos) { + $this->semValue = array(); + }, + 4 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 5 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 6 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 7 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 8 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 9 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 10 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 11 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 12 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 13 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 14 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 15 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 16 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 17 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 18 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 19 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 20 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 21 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 22 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 23 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 24 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 25 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 26 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 27 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 28 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 29 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 30 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 31 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 32 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 33 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 34 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 35 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 36 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 37 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 38 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 39 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 40 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 41 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 42 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 43 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 44 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 45 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 46 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 47 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 48 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 49 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 50 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 51 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 52 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 53 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 54 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 55 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 56 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 57 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 58 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 59 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 60 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 61 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 62 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 63 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 64 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 65 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 66 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 67 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 68 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 69 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 70 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 71 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 72 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 73 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 74 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 75 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 76 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 77 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 78 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 79 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 80 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 81 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 82 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 83 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 84 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 85 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 86 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 87 => function ($stackPos) { + $this->semValue = new Expr\Variable(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 88 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 89 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 90 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 91 => function ($stackPos) { + $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 92 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos-(3-2)], null, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); $this->checkNamespace($this->semValue); - } - - protected function reduceRule90() { - $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(5-2)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + }, + 93 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos-(5-2)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); - } - - protected function reduceRule91() { - $this->semValue = new Stmt\Namespace_(null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + }, + 94 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); - } - - protected function reduceRule92() { - $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule93() { - $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule94() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule95() { - $this->semValue = new Stmt\Const_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule96() { - $this->semValue = Stmt\Use_::TYPE_FUNCTION; - } - - protected function reduceRule97() { - $this->semValue = Stmt\Use_::TYPE_CONSTANT; - } - - protected function reduceRule98() { - $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], $this->semStack[$this->stackPos-(7-2)], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - } - - protected function reduceRule99() { - $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(8-4)], $this->startAttributeStack[$this->stackPos-(8-4)] + $this->endAttributeStack[$this->stackPos-(8-4)]), $this->semStack[$this->stackPos-(8-7)], $this->semStack[$this->stackPos-(8-2)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); - } - - protected function reduceRule100() { - $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-2)] + $this->endAttributeStack[$this->stackPos-(6-2)]), $this->semStack[$this->stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - } - - protected function reduceRule101() { - $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - } - - protected function reduceRule102() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule103() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule104() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule105() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule106() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule107() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule108() { - $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(1-1)); - } - - protected function reduceRule109() { - $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(3-3)); - } + }, + 95 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 96 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 97 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 98 => function ($stackPos) { + $this->semValue = new Stmt\Const_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 99 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_FUNCTION; + }, + 100 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_CONSTANT; + }, + 101 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(7-3)], $this->startAttributeStack[$stackPos-(7-3)] + $this->endAttributeStack[$stackPos-(7-3)]), $this->semStack[$stackPos-(7-6)], $this->semStack[$stackPos-(7-2)], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 102 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(8-4)], $this->startAttributeStack[$stackPos-(8-4)] + $this->endAttributeStack[$stackPos-(8-4)]), $this->semStack[$stackPos-(8-7)], $this->semStack[$stackPos-(8-2)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 103 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(6-2)], $this->startAttributeStack[$stackPos-(6-2)] + $this->endAttributeStack[$stackPos-(6-2)]), $this->semStack[$stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 104 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(7-3)], $this->startAttributeStack[$stackPos-(7-3)] + $this->endAttributeStack[$stackPos-(7-3)]), $this->semStack[$stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 105 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 106 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 107 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 108 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 109 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 110 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 111 => function ($stackPos) { + $this->semValue = new Stmt\UseUse($this->semStack[$stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $stackPos-(1-1)); + }, + 112 => function ($stackPos) { + $this->semValue = new Stmt\UseUse($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $stackPos-(3-3)); + }, + 113 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 114 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 115 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; + }, + 116 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; $this->semValue->type = $this->semStack[$stackPos-(2-1)]; + }, + 117 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 118 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 119 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 120 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 121 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 122 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 123 => function ($stackPos) { + if (is_array($this->semStack[$stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); } else { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }; + }, + 124 => function ($stackPos) { + $this->semValue = array(); + }, + 125 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 126 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 127 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 128 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 129 => function ($stackPos) { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 130 => function ($stackPos) { + + if ($this->semStack[$stackPos-(3-2)]) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; $attrs = $this->startAttributeStack[$stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; + } else { + $startAttributes = $this->startAttributeStack[$stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $this->semValue = null; }; + if (null === $this->semValue) { $this->semValue = array(); } + } - protected function reduceRule110() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule111() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule112() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; - } - - protected function reduceRule113() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; $this->semValue->type = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule114() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule115() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule116() { - $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule117() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule118() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule119() { - $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule120() { - if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; - } - - protected function reduceRule121() { - $this->semValue = array(); - } - - protected function reduceRule122() { - $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; - if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule123() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule124() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule125() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule126() { - throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule127() { - - if ($this->semStack[$this->stackPos-(3-2)]) { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; $attrs = $this->startAttributeStack[$this->stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; - } else { - $startAttributes = $this->startAttributeStack[$this->stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; - if (null === $this->semValue) { $this->semValue = array(); } - } - - } - - protected function reduceRule128() { - $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(5-2)], ['stmts' => is_array($this->semStack[$this->stackPos-(5-3)]) ? $this->semStack[$this->stackPos-(5-3)] : array($this->semStack[$this->stackPos-(5-3)]), 'elseifs' => $this->semStack[$this->stackPos-(5-4)], 'else' => $this->semStack[$this->stackPos-(5-5)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule129() { - $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(8-2)], ['stmts' => $this->semStack[$this->stackPos-(8-4)], 'elseifs' => $this->semStack[$this->stackPos-(8-5)], 'else' => $this->semStack[$this->stackPos-(8-6)]], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); - } - - protected function reduceRule130() { - $this->semValue = new Stmt\While_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule131() { - $this->semValue = new Stmt\Do_($this->semStack[$this->stackPos-(5-4)], is_array($this->semStack[$this->stackPos-(5-2)]) ? $this->semStack[$this->stackPos-(5-2)] : array($this->semStack[$this->stackPos-(5-2)]), $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule132() { - $this->semValue = new Stmt\For_(['init' => $this->semStack[$this->stackPos-(9-3)], 'cond' => $this->semStack[$this->stackPos-(9-5)], 'loop' => $this->semStack[$this->stackPos-(9-7)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); - } - - protected function reduceRule133() { - $this->semValue = new Stmt\Switch_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule134() { - $this->semValue = new Stmt\Break_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule135() { - $this->semValue = new Stmt\Break_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule136() { - $this->semValue = new Stmt\Continue_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule137() { - $this->semValue = new Stmt\Continue_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule138() { - $this->semValue = new Stmt\Return_(null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule139() { - $this->semValue = new Stmt\Return_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule140() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule141() { - $this->semValue = new Stmt\Global_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule142() { - $this->semValue = new Stmt\Static_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule143() { - $this->semValue = new Stmt\Echo_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule144() { - $this->semValue = new Stmt\InlineHTML($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule145() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule146() { - $this->semValue = new Stmt\Unset_($this->semStack[$this->stackPos-(5-3)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule147() { - $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(7-3)], $this->semStack[$this->stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$this->stackPos-(7-5)][1], 'stmts' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - } - - protected function reduceRule148() { - $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(9-3)], $this->semStack[$this->stackPos-(9-7)][0], ['keyVar' => $this->semStack[$this->stackPos-(9-5)], 'byRef' => $this->semStack[$this->stackPos-(9-7)][1], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); - } - - protected function reduceRule149() { - $this->semValue = new Stmt\Declare_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule150() { - $this->semValue = new Stmt\TryCatch($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-5)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); - } - - protected function reduceRule151() { - $this->semValue = new Stmt\Throw_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule152() { - $this->semValue = new Stmt\Goto_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule153() { - $this->semValue = new Stmt\Label($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule154() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule155() { - $this->semValue = array(); /* means: no statement */ - } - - protected function reduceRule156() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule157() { - $startAttributes = $this->startAttributeStack[$this->stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; - if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ - } - - protected function reduceRule158() { - $this->semValue = array(); - } - - protected function reduceRule159() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule160() { - $this->semValue = new Stmt\Catch_(array($this->semStack[$this->stackPos-(8-3)]), substr($this->semStack[$this->stackPos-(8-4)], 1), $this->semStack[$this->stackPos-(8-7)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); - } - - protected function reduceRule161() { - $this->semValue = null; - } - - protected function reduceRule162() { - $this->semValue = new Stmt\Finally_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule163() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule164() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule165() { - $this->semValue = false; - } - - protected function reduceRule166() { - $this->semValue = true; - } - - protected function reduceRule167() { - $this->semValue = false; - } - - protected function reduceRule168() { - $this->semValue = true; - } - - protected function reduceRule169() { - $this->semValue = new Stmt\Function_($this->semStack[$this->stackPos-(10-3)], ['byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-5)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); - } - - protected function reduceRule170() { - $this->semValue = new Stmt\Class_($this->semStack[$this->stackPos-(7-2)], ['type' => $this->semStack[$this->stackPos-(7-1)], 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - $this->checkClass($this->semValue, $this->stackPos-(7-2)); - } - - protected function reduceRule171() { - $this->semValue = new Stmt\Interface_($this->semStack[$this->stackPos-(6-2)], ['extends' => $this->semStack[$this->stackPos-(6-3)], 'stmts' => $this->semStack[$this->stackPos-(6-5)]], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - $this->checkInterface($this->semValue, $this->stackPos-(6-2)); - } - - protected function reduceRule172() { - $this->semValue = new Stmt\Trait_($this->semStack[$this->stackPos-(5-2)], ['stmts' => $this->semStack[$this->stackPos-(5-4)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule173() { - $this->semValue = 0; - } - - protected function reduceRule174() { - $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; - } - - protected function reduceRule175() { - $this->semValue = Stmt\Class_::MODIFIER_FINAL; - } - - protected function reduceRule176() { - $this->semValue = null; - } - - protected function reduceRule177() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule178() { - $this->semValue = array(); - } - - protected function reduceRule179() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule180() { - $this->semValue = array(); - } - - protected function reduceRule181() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule182() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule183() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule184() { - $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule185() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule186() { - $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule187() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule188() { - $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule189() { - $this->semValue = null; - } - - protected function reduceRule190() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule191() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule192() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule193() { - $this->semValue = new Stmt\DeclareDeclare($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule194() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule195() { - $this->semValue = $this->semStack[$this->stackPos-(4-3)]; - } - - protected function reduceRule196() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule197() { - $this->semValue = $this->semStack[$this->stackPos-(5-3)]; - } - - protected function reduceRule198() { - $this->semValue = array(); - } - - protected function reduceRule199() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule200() { - $this->semValue = new Stmt\Case_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule201() { - $this->semValue = new Stmt\Case_(null, $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule202() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule203() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule204() { - $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule205() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule206() { - $this->semValue = array(); - } - - protected function reduceRule207() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule208() { - $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(3-2)], is_array($this->semStack[$this->stackPos-(3-3)]) ? $this->semStack[$this->stackPos-(3-3)] : array($this->semStack[$this->stackPos-(3-3)]), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule209() { - $this->semValue = array(); - } - - protected function reduceRule210() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule211() { - $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule212() { - $this->semValue = null; - } - - protected function reduceRule213() { - $this->semValue = new Stmt\Else_(is_array($this->semStack[$this->stackPos-(2-2)]) ? $this->semStack[$this->stackPos-(2-2)] : array($this->semStack[$this->stackPos-(2-2)]), $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule214() { - $this->semValue = null; - } - - protected function reduceRule215() { - $this->semValue = new Stmt\Else_($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule216() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); - } - - protected function reduceRule217() { - $this->semValue = array($this->semStack[$this->stackPos-(2-2)], true); - } - - protected function reduceRule218() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); - } - - protected function reduceRule219() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule220() { - $this->semValue = array(); - } - - protected function reduceRule221() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule222() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule223() { - $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(4-4)], 1), null, $this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); - } - - protected function reduceRule224() { - $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(6-4)], 1), $this->semStack[$this->stackPos-(6-6)], $this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-3)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); - } - - protected function reduceRule225() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule226() { - $this->semValue = 'array'; - } - - protected function reduceRule227() { - $this->semValue = 'callable'; - } - - protected function reduceRule228() { - $this->semValue = null; - } - - protected function reduceRule229() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule230() { - $this->semValue = null; - } - - protected function reduceRule231() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule232() { - $this->semValue = array(); - } - - protected function reduceRule233() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule234() { - $this->semValue = array(new Node\Arg($this->semStack[$this->stackPos-(3-2)], false, false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes)); - } - - protected function reduceRule235() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule236() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule237() { - $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(1-1)], false, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule238() { - $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], true, false, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule239() { - $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], false, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule240() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule241() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule242() { - $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule243() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule244() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule245() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule246() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule247() { - $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule248() { - $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule249() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule250() { - $this->semValue = array(); - } - - protected function reduceRule251() { - $this->semValue = new Stmt\Property($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $this->stackPos-(3-1)); - } - - protected function reduceRule252() { - $this->semValue = new Stmt\ClassConst($this->semStack[$this->stackPos-(3-2)], 0, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule253() { - $this->semValue = new Stmt\ClassMethod($this->semStack[$this->stackPos-(9-4)], ['type' => $this->semStack[$this->stackPos-(9-1)], 'byRef' => $this->semStack[$this->stackPos-(9-3)], 'params' => $this->semStack[$this->stackPos-(9-6)], 'returnType' => $this->semStack[$this->stackPos-(9-8)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); - $this->checkClassMethod($this->semValue, $this->stackPos-(9-1)); - } - - protected function reduceRule254() { - $this->semValue = new Stmt\TraitUse($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule255() { - $this->semValue = array(); - } - - protected function reduceRule256() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule257() { - $this->semValue = array(); - } - - protected function reduceRule258() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule259() { - $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule260() { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(5-1)][0], $this->semStack[$this->stackPos-(5-1)][1], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule261() { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], null, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule262() { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule263() { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule264() { - $this->semValue = array($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)]); - } - - protected function reduceRule265() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule266() { - $this->semValue = array(null, $this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule267() { - $this->semValue = null; - } - - protected function reduceRule268() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule269() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule270() { - $this->semValue = 0; - } - - protected function reduceRule271() { - $this->semValue = 0; - } - - protected function reduceRule272() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule273() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule274() { - $this->checkModifier($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->stackPos-(2-2)); $this->semValue = $this->semStack[$this->stackPos-(2-1)] | $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule275() { - $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; - } - - protected function reduceRule276() { - $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; - } - - protected function reduceRule277() { - $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; - } - - protected function reduceRule278() { - $this->semValue = Stmt\Class_::MODIFIER_STATIC; - } - - protected function reduceRule279() { - $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; - } - - protected function reduceRule280() { - $this->semValue = Stmt\Class_::MODIFIER_FINAL; - } - - protected function reduceRule281() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule282() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule283() { - $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule284() { - $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule285() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule286() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule287() { - $this->semValue = array(); - } - - protected function reduceRule288() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule289() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule290() { - $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule291() { - $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule292() { - $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule293() { - $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule294() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule295() { - $this->semValue = new Expr\Clone_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule296() { - $this->semValue = new Expr\AssignOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule297() { - $this->semValue = new Expr\AssignOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule298() { - $this->semValue = new Expr\AssignOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule299() { - $this->semValue = new Expr\AssignOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule300() { - $this->semValue = new Expr\AssignOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule301() { - $this->semValue = new Expr\AssignOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule302() { - $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule303() { - $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule304() { - $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule305() { - $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule306() { - $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule307() { - $this->semValue = new Expr\AssignOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule308() { - $this->semValue = new Expr\PostInc($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule309() { - $this->semValue = new Expr\PreInc($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule310() { - $this->semValue = new Expr\PostDec($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule311() { - $this->semValue = new Expr\PreDec($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule312() { - $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule313() { - $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule314() { - $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule315() { - $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule316() { - $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule317() { - $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule318() { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule319() { - $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule320() { - $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule321() { - $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule322() { - $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule323() { - $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule324() { - $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule325() { - $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule326() { - $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule327() { - $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule328() { - $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule329() { - $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule330() { - $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule331() { - $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule332() { - $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule333() { - $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule334() { - $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule335() { - $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule336() { - $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule337() { - $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule338() { - $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule339() { - $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule340() { - $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule341() { - $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule342() { - $this->semValue = new Expr\Instanceof_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule343() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule344() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule345() { - $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule346() { - $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule347() { - $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule348() { - $this->semValue = new Expr\Isset_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule349() { - $this->semValue = new Expr\Empty_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule350() { - $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule351() { - $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule352() { - $this->semValue = new Expr\Eval_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule353() { - $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule354() { - $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule355() { - $this->semValue = new Expr\Cast\Int_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule356() { - $this->semValue = new Expr\Cast\Double($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule357() { - $this->semValue = new Expr\Cast\String_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule358() { - $this->semValue = new Expr\Cast\Array_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule359() { - $this->semValue = new Expr\Cast\Object_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule360() { - $this->semValue = new Expr\Cast\Bool_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule361() { - $this->semValue = new Expr\Cast\Unset_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule362() { - $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; - $attrs['kind'] = strtolower($this->semStack[$this->stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; - $this->semValue = new Expr\Exit_($this->semStack[$this->stackPos-(2-2)], $attrs); - } - - protected function reduceRule363() { - $this->semValue = new Expr\ErrorSuppress($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule364() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule365() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule366() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule367() { - $this->semValue = new Expr\ShellExec($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule368() { - $this->semValue = new Expr\Print_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule369() { - $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule370() { - $this->semValue = new Expr\YieldFrom($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule371() { - $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-4)], 'uses' => $this->semStack[$this->stackPos-(10-6)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); - } - - protected function reduceRule372() { - $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$this->stackPos-(11-3)], 'params' => $this->semStack[$this->stackPos-(11-5)], 'uses' => $this->semStack[$this->stackPos-(11-7)], 'returnType' => $this->semStack[$this->stackPos-(11-8)], 'stmts' => $this->semStack[$this->stackPos-(11-10)]], $this->startAttributeStack[$this->stackPos-(11-1)] + $this->endAttributes); - } - - protected function reduceRule373() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule374() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule375() { - $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(2-2)], null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule376() { - $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule377() { - $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; - $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $attrs); - } - - protected function reduceRule378() { - $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; - $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $attrs); - } - - protected function reduceRule379() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule380() { - $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(4-1)][0] === "'" || ($this->semStack[$this->stackPos-(4-1)][1] === "'" && ($this->semStack[$this->stackPos-(4-1)][0] === 'b' || $this->semStack[$this->stackPos-(4-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); - $this->semValue = new Expr\ArrayDimFetch(new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(4-1)]), $attrs), $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule381() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule382() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule383() { - $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(7-2)]); - $this->checkClass($this->semValue[0], -1); - } - - protected function reduceRule384() { - $this->semValue = new Expr\New_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule385() { - list($class, $ctorArgs) = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule386() { - $this->semValue = array(); - } - - protected function reduceRule387() { - $this->semValue = $this->semStack[$this->stackPos-(4-3)]; - } - - protected function reduceRule388() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule389() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule390() { - $this->semValue = new Expr\ClosureUse(substr($this->semStack[$this->stackPos-(2-2)], 1), $this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule391() { - $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule392() { - $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule393() { - $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-4)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - } - - protected function reduceRule394() { - - if ($this->semStack[$this->stackPos-(2-1)] instanceof Node\Expr\StaticPropertyFetch) { - $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(2-1)]->class, new Expr\Variable($this->semStack[$this->stackPos-(2-1)]->name, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } elseif ($this->semStack[$this->stackPos-(2-1)] instanceof Node\Expr\ArrayDimFetch) { - $tmp = $this->semStack[$this->stackPos-(2-1)]; - while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { - $tmp = $tmp->var; - } - - $this->semValue = new Expr\StaticCall($tmp->var->class, $this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - $tmp->var = new Expr\Variable($tmp->var->name, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } else { - throw new \Exception; - } - - } - - protected function reduceRule395() { - $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule396() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule397() { - $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule398() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule399() { - $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule400() { - $this->semValue = new Name\FullyQualified($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule401() { - $this->semValue = new Name\Relative($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule402() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule403() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule404() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule405() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule406() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule407() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule408() { - $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule409() { - $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule410() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule411() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule412() { - $this->semValue = null; - } - - protected function reduceRule413() { - $this->semValue = null; - } - - protected function reduceRule414() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule415() { - $this->semValue = array(); - } - - protected function reduceRule416() { - $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$this->stackPos-(1-1)], '`', false), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); - } - - protected function reduceRule417() { - foreach ($this->semStack[$this->stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', false); } }; $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule418() { - $this->semValue = array(); - } - - protected function reduceRule419() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule420() { - $this->semValue = $this->parseLNumber($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes, true); - } - - protected function reduceRule421() { - $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$this->stackPos-(1-1)]), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule422() { - $attrs = $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(1-1)][0] === "'" || ($this->semStack[$this->stackPos-(1-1)][1] === "'" && ($this->semStack[$this->stackPos-(1-1)][0] === 'b' || $this->semStack[$this->stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); - $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(1-1)], false), $attrs); - } - - protected function reduceRule423() { - $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule424() { - $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule425() { - $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule426() { - $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule427() { - $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule428() { - $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule429() { - $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule430() { - $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule431() { - $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; - $this->semValue = new Scalar\String_(Scalar\String_::parseDocString($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], false), $attrs); - } - - protected function reduceRule432() { - $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(2-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(2-1)], $matches); $attrs['docLabel'] = $matches[1];; + }, + 131 => function ($stackPos) { + $this->semValue = new Stmt\If_($this->semStack[$stackPos-(5-2)], ['stmts' => is_array($this->semStack[$stackPos-(5-3)]) ? $this->semStack[$stackPos-(5-3)] : array($this->semStack[$stackPos-(5-3)]), 'elseifs' => $this->semStack[$stackPos-(5-4)], 'else' => $this->semStack[$stackPos-(5-5)]], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 132 => function ($stackPos) { + $this->semValue = new Stmt\If_($this->semStack[$stackPos-(8-2)], ['stmts' => $this->semStack[$stackPos-(8-4)], 'elseifs' => $this->semStack[$stackPos-(8-5)], 'else' => $this->semStack[$stackPos-(8-6)]], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 133 => function ($stackPos) { + $this->semValue = new Stmt\While_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 134 => function ($stackPos) { + $this->semValue = new Stmt\Do_($this->semStack[$stackPos-(5-4)], is_array($this->semStack[$stackPos-(5-2)]) ? $this->semStack[$stackPos-(5-2)] : array($this->semStack[$stackPos-(5-2)]), $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 135 => function ($stackPos) { + $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos-(9-3)], 'cond' => $this->semStack[$stackPos-(9-5)], 'loop' => $this->semStack[$stackPos-(9-7)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 136 => function ($stackPos) { + $this->semValue = new Stmt\Switch_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 137 => function ($stackPos) { + $this->semValue = new Stmt\Break_(null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 138 => function ($stackPos) { + $this->semValue = new Stmt\Break_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 139 => function ($stackPos) { + $this->semValue = new Stmt\Continue_(null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 140 => function ($stackPos) { + $this->semValue = new Stmt\Continue_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 141 => function ($stackPos) { + $this->semValue = new Stmt\Return_(null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 142 => function ($stackPos) { + $this->semValue = new Stmt\Return_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 143 => function ($stackPos) { + $this->semValue = new Stmt\Global_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 144 => function ($stackPos) { + $this->semValue = new Stmt\Static_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 145 => function ($stackPos) { + $this->semValue = new Stmt\Echo_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 146 => function ($stackPos) { + $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 147 => function ($stackPos) { + $this->semValue = new Stmt\Expression($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 148 => function ($stackPos) { + $this->semValue = new Stmt\Expression($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 149 => function ($stackPos) { + $this->semValue = new Stmt\Unset_($this->semStack[$stackPos-(5-3)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 150 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(7-3)], $this->semStack[$stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos-(7-5)][1], 'stmts' => $this->semStack[$stackPos-(7-7)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 151 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(9-3)], $this->semStack[$stackPos-(9-7)][0], ['keyVar' => $this->semStack[$stackPos-(9-5)], 'byRef' => $this->semStack[$stackPos-(9-7)][1], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 152 => function ($stackPos) { + $this->semValue = new Stmt\Declare_($this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 153 => function ($stackPos) { + $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-5)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); + }, + 154 => function ($stackPos) { + $this->semValue = new Stmt\Throw_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 155 => function ($stackPos) { + $this->semValue = new Stmt\Goto_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 156 => function ($stackPos) { + $this->semValue = new Stmt\Label($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 157 => function ($stackPos) { + $this->semValue = new Stmt\Expression($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 158 => function ($stackPos) { + $this->semValue = array(); /* means: no statement */ + }, + 159 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 160 => function ($stackPos) { + $startAttributes = $this->startAttributeStack[$stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $this->semValue = null; }; + if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ + }, + 161 => function ($stackPos) { + $this->semValue = array(); + }, + 162 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 163 => function ($stackPos) { + $this->semValue = new Stmt\Catch_(array($this->semStack[$stackPos-(8-3)]), $this->semStack[$stackPos-(8-4)], $this->semStack[$stackPos-(8-7)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 164 => function ($stackPos) { + $this->semValue = null; + }, + 165 => function ($stackPos) { + $this->semValue = new Stmt\Finally_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 166 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 167 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 168 => function ($stackPos) { + $this->semValue = false; + }, + 169 => function ($stackPos) { + $this->semValue = true; + }, + 170 => function ($stackPos) { + $this->semValue = false; + }, + 171 => function ($stackPos) { + $this->semValue = true; + }, + 172 => function ($stackPos) { + $this->semValue = new Stmt\Function_($this->semStack[$stackPos-(10-3)], ['byRef' => $this->semStack[$stackPos-(10-2)], 'params' => $this->semStack[$stackPos-(10-5)], 'returnType' => $this->semStack[$stackPos-(10-7)], 'stmts' => $this->semStack[$stackPos-(10-9)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); + }, + 173 => function ($stackPos) { + $this->semValue = new Stmt\Class_($this->semStack[$stackPos-(7-2)], ['type' => $this->semStack[$stackPos-(7-1)], 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + $this->checkClass($this->semValue, $stackPos-(7-2)); + }, + 174 => function ($stackPos) { + $this->semValue = new Stmt\Interface_($this->semStack[$stackPos-(6-2)], ['extends' => $this->semStack[$stackPos-(6-3)], 'stmts' => $this->semStack[$stackPos-(6-5)]], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + $this->checkInterface($this->semValue, $stackPos-(6-2)); + }, + 175 => function ($stackPos) { + $this->semValue = new Stmt\Trait_($this->semStack[$stackPos-(5-2)], ['stmts' => $this->semStack[$stackPos-(5-4)]], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 176 => function ($stackPos) { + $this->semValue = 0; + }, + 177 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + }, + 178 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + }, + 179 => function ($stackPos) { + $this->semValue = null; + }, + 180 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 181 => function ($stackPos) { + $this->semValue = array(); + }, + 182 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 183 => function ($stackPos) { + $this->semValue = array(); + }, + 184 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 185 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 186 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 187 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 188 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 189 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 190 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 191 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 192 => function ($stackPos) { + $this->semValue = null; + }, + 193 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 194 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 195 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 196 => function ($stackPos) { + $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 197 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 198 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 199 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 200 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(5-3)]; + }, + 201 => function ($stackPos) { + $this->semValue = array(); + }, + 202 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 203 => function ($stackPos) { + $this->semValue = new Stmt\Case_($this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 204 => function ($stackPos) { + $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 205 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 206 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 207 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 208 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 209 => function ($stackPos) { + $this->semValue = array(); + }, + 210 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 211 => function ($stackPos) { + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(3-2)], is_array($this->semStack[$stackPos-(3-3)]) ? $this->semStack[$stackPos-(3-3)] : array($this->semStack[$stackPos-(3-3)]), $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 212 => function ($stackPos) { + $this->semValue = array(); + }, + 213 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 214 => function ($stackPos) { + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 215 => function ($stackPos) { + $this->semValue = null; + }, + 216 => function ($stackPos) { + $this->semValue = new Stmt\Else_(is_array($this->semStack[$stackPos-(2-2)]) ? $this->semStack[$stackPos-(2-2)] : array($this->semStack[$stackPos-(2-2)]), $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 217 => function ($stackPos) { + $this->semValue = null; + }, + 218 => function ($stackPos) { + $this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 219 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 220 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(2-2)], true); + }, + 221 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 222 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 223 => function ($stackPos) { + $this->semValue = array(); + }, + 224 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 225 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 226 => function ($stackPos) { + $this->semValue = new Node\Param($this->semStack[$stackPos-(4-4)], null, $this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); + }, + 227 => function ($stackPos) { + $this->semValue = new Node\Param($this->semStack[$stackPos-(6-4)], $this->semStack[$stackPos-(6-6)], $this->semStack[$stackPos-(6-1)], $this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-3)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); + }, + 228 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 229 => function ($stackPos) { + $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 230 => function ($stackPos) { + $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 231 => function ($stackPos) { + $this->semValue = null; + }, + 232 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 233 => function ($stackPos) { + $this->semValue = null; + }, + 234 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 235 => function ($stackPos) { + $this->semValue = array(); + }, + 236 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 237 => function ($stackPos) { + $this->semValue = array(new Node\Arg($this->semStack[$stackPos-(3-2)], false, false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes)); + }, + 238 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 239 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 240 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(1-1)], false, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 241 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], true, false, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 242 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], false, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 243 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 244 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 245 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 246 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 247 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 248 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 249 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 250 => function ($stackPos) { + $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 251 => function ($stackPos) { + $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 252 => function ($stackPos) { + if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; } + }, + 253 => function ($stackPos) { + $this->semValue = array(); + }, + 254 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 255 => function ($stackPos) { + $this->semValue = new Stmt\Property($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $stackPos-(3-1)); + }, + 256 => function ($stackPos) { + $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos-(3-2)], 0, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 257 => function ($stackPos) { + $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos-(9-4)], ['type' => $this->semStack[$stackPos-(9-1)], 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-6)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + $this->checkClassMethod($this->semValue, $stackPos-(9-1)); + }, + 258 => function ($stackPos) { + $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 259 => function ($stackPos) { + $this->semValue = array(); + }, + 260 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 261 => function ($stackPos) { + $this->semValue = array(); + }, + 262 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 263 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 264 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(5-1)][0], $this->semStack[$stackPos-(5-1)][1], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 265 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], null, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 266 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 267 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 268 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)]); + }, + 269 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 270 => function ($stackPos) { + $this->semValue = array(null, $this->semStack[$stackPos-(1-1)]); + }, + 271 => function ($stackPos) { + $this->semValue = null; + }, + 272 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 273 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 274 => function ($stackPos) { + $this->semValue = 0; + }, + 275 => function ($stackPos) { + $this->semValue = 0; + }, + 276 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 277 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 278 => function ($stackPos) { + $this->checkModifier($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $this->semValue = $this->semStack[$stackPos-(2-1)] | $this->semStack[$stackPos-(2-2)]; + }, + 279 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; + }, + 280 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; + }, + 281 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; + }, + 282 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_STATIC; + }, + 283 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + }, + 284 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + }, + 285 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 286 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 287 => function ($stackPos) { + $this->semValue = new Node\VarLikeIdentifier(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 288 => function ($stackPos) { + $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 289 => function ($stackPos) { + $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 290 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 291 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 292 => function ($stackPos) { + $this->semValue = array(); + }, + 293 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 294 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 295 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 296 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 297 => function ($stackPos) { + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 298 => function ($stackPos) { + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 299 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 300 => function ($stackPos) { + $this->semValue = new Expr\Clone_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 301 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 302 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 303 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 304 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 305 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 306 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 307 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 308 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 309 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 310 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 311 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 312 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 313 => function ($stackPos) { + $this->semValue = new Expr\PostInc($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 314 => function ($stackPos) { + $this->semValue = new Expr\PreInc($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 315 => function ($stackPos) { + $this->semValue = new Expr\PostDec($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 316 => function ($stackPos) { + $this->semValue = new Expr\PreDec($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 317 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 318 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 319 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 320 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 321 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 322 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 323 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 324 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 325 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 326 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 327 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 328 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 329 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 330 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 331 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 332 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 333 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 334 => function ($stackPos) { + $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 335 => function ($stackPos) { + $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 336 => function ($stackPos) { + $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 337 => function ($stackPos) { + $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 338 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 339 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 340 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 341 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 342 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 343 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 344 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 345 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 346 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 347 => function ($stackPos) { + $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 348 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 349 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 350 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(5-1)], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 351 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(4-1)], null, $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 352 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 353 => function ($stackPos) { + $this->semValue = new Expr\Isset_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 354 => function ($stackPos) { + $this->semValue = new Expr\Empty_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 355 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 356 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 357 => function ($stackPos) { + $this->semValue = new Expr\Eval_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 358 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 359 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 360 => function ($stackPos) { + $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 361 => function ($stackPos) { + $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 362 => function ($stackPos) { + $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 363 => function ($stackPos) { + $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 364 => function ($stackPos) { + $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 365 => function ($stackPos) { + $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 366 => function ($stackPos) { + $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 367 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; + $attrs['kind'] = strtolower($this->semStack[$stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $this->semValue = new Expr\Exit_($this->semStack[$stackPos-(2-2)], $attrs); + }, + 368 => function ($stackPos) { + $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 369 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 370 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 371 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 372 => function ($stackPos) { + $this->semValue = new Expr\ShellExec($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 373 => function ($stackPos) { + $this->semValue = new Expr\Print_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 374 => function ($stackPos) { + $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 375 => function ($stackPos) { + $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 376 => function ($stackPos) { + $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$stackPos-(10-2)], 'params' => $this->semStack[$stackPos-(10-4)], 'uses' => $this->semStack[$stackPos-(10-6)], 'returnType' => $this->semStack[$stackPos-(10-7)], 'stmts' => $this->semStack[$stackPos-(10-9)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); + }, + 377 => function ($stackPos) { + $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$stackPos-(11-3)], 'params' => $this->semStack[$stackPos-(11-5)], 'uses' => $this->semStack[$stackPos-(11-7)], 'returnType' => $this->semStack[$stackPos-(11-8)], 'stmts' => $this->semStack[$stackPos-(11-10)]], $this->startAttributeStack[$stackPos-(11-1)] + $this->endAttributes); + }, + 378 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 379 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 380 => function ($stackPos) { + $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(2-2)], null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 381 => function ($stackPos) { + $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 382 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(4-3)], $attrs); + }, + 383 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(3-2)], $attrs); + }, + 384 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 385 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(4-1)][0] === "'" || ($this->semStack[$stackPos-(4-1)][1] === "'" && ($this->semStack[$stackPos-(4-1)][0] === 'b' || $this->semStack[$stackPos-(4-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Expr\ArrayDimFetch(new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(4-1)]), $attrs), $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 386 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 387 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 388 => function ($stackPos) { + $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes), $this->semStack[$stackPos-(7-2)]); + $this->checkClass($this->semValue[0], -1); + }, + 389 => function ($stackPos) { + $this->semValue = new Expr\New_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 390 => function ($stackPos) { + list($class, $ctorArgs) = $this->semStack[$stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 391 => function ($stackPos) { + $this->semValue = array(); + }, + 392 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 393 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 394 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 395 => function ($stackPos) { + $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos-(2-2)], $this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 396 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 397 => function ($stackPos) { + $this->semValue = new Expr\StaticCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 398 => function ($stackPos) { + $this->semValue = new Expr\StaticCall($this->semStack[$stackPos-(6-1)], $this->semStack[$stackPos-(6-4)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 399 => function ($stackPos) { + $this->semValue = $this->fixupPhp5StaticPropCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 400 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 401 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 402 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 403 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 404 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 405 => function ($stackPos) { + $this->semValue = new Name\FullyQualified($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 406 => function ($stackPos) { + $this->semValue = new Name\Relative($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 407 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 408 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 409 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 410 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 411 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 412 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 413 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 414 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 415 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 416 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 417 => function ($stackPos) { + $this->semValue = null; + }, + 418 => function ($stackPos) { + $this->semValue = null; + }, + 419 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 420 => function ($stackPos) { + $this->semValue = array(); + }, + 421 => function ($stackPos) { + $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos-(1-1)], '`', false), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes)); + }, + 422 => function ($stackPos) { + foreach ($this->semStack[$stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', false); } }; $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 423 => function ($stackPos) { + $this->semValue = array(); + }, + 424 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 425 => function ($stackPos) { + $this->semValue = $this->parseLNumber($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes, true); + }, + 426 => function ($stackPos) { + $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$stackPos-(1-1)]), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 427 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(1-1)][0] === "'" || ($this->semStack[$stackPos-(1-1)][1] === "'" && ($this->semStack[$stackPos-(1-1)][0] === 'b' || $this->semStack[$stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(1-1)], false), $attrs); + }, + 428 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 429 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 430 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 431 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 432 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 433 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 434 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 435 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 436 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; + $this->semValue = new Scalar\String_(Scalar\String_::parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], false), $attrs); + }, + 437 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$stackPos-(2-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$stackPos-(2-1)], $matches); $attrs['docLabel'] = $matches[1];; $this->semValue = new Scalar\String_('', $attrs); - } - - protected function reduceRule433() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule434() { - $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule435() { - $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule436() { - $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule437() { - $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule438() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule439() { - $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule440() { - $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule441() { - $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule442() { - $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule443() { - $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule444() { - $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule445() { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule446() { - $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule447() { - $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule448() { - $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule449() { - $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule450() { - $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule451() { - $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule452() { - $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule453() { - $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule454() { - $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule455() { - $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule456() { - $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule457() { - $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule458() { - $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule459() { - $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule460() { - $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule461() { - $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule462() { - $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule463() { - $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule464() { - $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule465() { - $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule466() { - $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule467() { - $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule468() { - $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule469() { - $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule470() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule471() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule472() { - $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule473() { - $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule474() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule475() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule476() { - $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; - foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); - } - - protected function reduceRule477() { - $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; - foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, true); } } $s->value = preg_replace('~(\r\n|\n|\r)\z~', '', $s->value); if ('' === $s->value) array_pop($this->semStack[$this->stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); - } - - protected function reduceRule478() { - $this->semValue = array(); - } - - protected function reduceRule479() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule480() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule481() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule482() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule483() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule484() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule485() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule486() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule487() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule488() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule489() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule490() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-5)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - } - - protected function reduceRule491() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule492() { - $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule493() { - $this->semValue = new Expr\MethodCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule494() { - $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule495() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule496() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule497() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule498() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule499() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule500() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule501() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule502() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule503() { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule504() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule505() { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], substr($this->semStack[$this->stackPos-(3-3)], 1), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule506() { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-5)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - } - - protected function reduceRule507() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule508() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule509() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule510() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule511() { - $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule512() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule513() { - $this->semValue = null; - } - - protected function reduceRule514() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule515() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule516() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule517() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule518() { - $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; - } - - protected function reduceRule519() { - $this->semValue = new Expr\List_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule520() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule521() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule522() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule523() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule524() { - $this->semValue = null; - } - - protected function reduceRule525() { - $this->semValue = array(); - } - - protected function reduceRule526() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule527() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule528() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule529() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule530() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule531() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-1)], true, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule532() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(2-2)], null, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule533() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule534() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule535() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule536() { - $this->semValue = array($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); - } - - protected function reduceRule537() { - $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule538() { - $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule539() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule540() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule541() { - $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule542() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule543() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule544() { - $this->semValue = new Expr\ArrayDimFetch(new Expr\Variable($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(6-4)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - } - - protected function reduceRule545() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule546() { - $this->semValue = new Scalar\String_($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule547() { - $this->semValue = $this->parseNumString($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule548() { - $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + }, + 438 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 439 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 440 => function ($stackPos) { + $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 441 => function ($stackPos) { + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 442 => function ($stackPos) { + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 443 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 444 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 445 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 446 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 447 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 448 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 449 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 450 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 451 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 452 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 453 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 454 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 455 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 456 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 457 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 458 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 459 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 460 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 461 => function ($stackPos) { + $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 462 => function ($stackPos) { + $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 463 => function ($stackPos) { + $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 464 => function ($stackPos) { + $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 465 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 466 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 467 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 468 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 469 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 470 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 471 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 472 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 473 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(5-1)], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 474 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(4-1)], null, $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 475 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 476 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 477 => function ($stackPos) { + $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 478 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 479 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 480 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 481 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($this->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos-(3-2)], $attrs); + }, + 482 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; + foreach ($this->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, true); } } $s->value = preg_replace('~(\r\n|\n|\r)\z~', '', $s->value); if ('' === $s->value) array_pop($this->semStack[$stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos-(3-2)], $attrs); + }, + 483 => function ($stackPos) { + $this->semValue = array(); + }, + 484 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 485 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 486 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 487 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 488 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 489 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 490 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 491 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 492 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 493 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 494 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 495 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-5)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 496 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 497 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 498 => function ($stackPos) { + $this->semValue = new Expr\MethodCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 499 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 500 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 501 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 502 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 503 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 504 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 505 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 506 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 507 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 508 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 509 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 510 => function ($stackPos) { + $var = substr($this->semStack[$stackPos-(1-1)], 1); $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes) : $var; + }, + 511 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 512 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(6-1)], $this->semStack[$stackPos-(6-5)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 513 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 514 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 515 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 516 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 517 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 518 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 519 => function ($stackPos) { + $this->semValue = null; + }, + 520 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 521 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 522 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 523 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 524 => function ($stackPos) { + $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + }, + 525 => function ($stackPos) { + $this->semValue = new Expr\List_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 526 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 527 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 528 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 529 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 530 => function ($stackPos) { + $this->semValue = null; + }, + 531 => function ($stackPos) { + $this->semValue = array(); + }, + 532 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 533 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 534 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 535 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 536 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 537 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-1)], true, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 538 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 539 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 540 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 541 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 542 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); + }, + 543 => function ($stackPos) { + $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 544 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 545 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 546 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 547 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 548 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 549 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 550 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-4)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 551 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 552 => function ($stackPos) { + $this->semValue = new Scalar\String_($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 553 => function ($stackPos) { + $this->semValue = $this->parseNumString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 554 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + ]; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php b/app/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php index 56f526876..24ce4d14b 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/Parser/Php7.php @@ -18,16 +18,16 @@ class Php7 extends \PhpParser\ParserAbstract { protected $tokenToSymbolMapSize = 392; - protected $actionTableSize = 891; - protected $gotoTableSize = 429; + protected $actionTableSize = 940; + protected $gotoTableSize = 486; protected $invalidSymbol = 157; protected $errorSymbol = 1; protected $defaultAction = -32766; protected $unexpectedTokenRule = 32767; - protected $YY2TBLSTATE = 328; - protected $YYNLSTATES = 576; + protected $YY2TBLSTATE = 336; + protected $numNonLeafStates = 581; protected $symbolToName = array( "EOF", @@ -233,195 +233,260 @@ class Php7 extends \PhpParser\ParserAbstract ); protected $action = array( - 581, 582, 583, 584, 585, 0, 586, 587, 588, 624, - 625, 477, 27, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110,-32766,-32766,-32766, 95, 96, - 97, 361, 239, 263, -282,-32766,-32766,-32766, -488, -487, - 1079, 542, 1082, 1080, 98,-32766, 272,-32766,-32766,-32766, - -32766,-32766, 589, 899, 901,-32766,-32766,-32766,-32766,-32766, - -32766,-32766,-32766, 240,-32766, 662, 590, 591, 592, 593, - 594, 595, 596,-32766, 289, 656, 867, 868, 869, 866, - 865, 864, 597, 598, 599, 600, 601, 602, 603, 604, - 605, 606, 607, 627, 628, 629, 630, 631, 619, 620, - 621, 622, 623, 608, 609, 610, 611, 612, 613, 614, - 650, 651, 652, 653, 654, 655, 615, 616, 617, 618, - 648, 639, 637, 638, 634, 635, 215, 626, 632, 633, - 640, 641, 643, 642, 644, 645, 42, 43, 390, 44, - 45, 636, 647, 646, 224, 46, 47, 982, 48,-32767, - -32767,-32767,-32767, 90, 91, 92, 93, 94, 258, 440, - 22, 867, 868, 869, 866, 865, 864, 859,-32766,-32766, - -32766, 1071, 1032, 1032, 1070, 1049, 998, 293, -443, 246, - 287, 49, 50, -488, -487, -488, -487, 51,-32766, 52, - 219, 220, 53, 54, 55, 56, 57, 58, 59, 60, - 125, 22, 232, 61, 345, 975,-32766,-32766,-32766, 999, - 1000, 658, 661, 1032, 28, -477, 1012, 998,-32766,-32766, - -32766, 737, 407, 408, 246, 1032,-32766, 246,-32766,-32766, - -32766,-32766, 25, 222, 373, 385, 349, 226,-32766, -443, - -32766,-32766,-32766, 1035, 65, 342, 416, 216, 41, 264, - 264, 1046, 7, -443, 403, 404, 120, 21, 975, 24, - -443, 822, -446, 407, 408, -227, 1004, 1005, 1006, 1007, - 1001, 1002, 243, 116, -442, -441, 265, 417, 1008, 1003, - 347, 816, 817, 1076, 994, 63, 369, 255, 362, 260, - 264, 391, -133, -133, -133, -4, 737, 392, 658, 224, - -441, 727, 264, -88, 32, 17, 393, -133, 394, -133, - 395, -133, 396, -133, 128, 397, -133, -133, -133, 34, - 35, 398, 346, 122, 36, 399, 816, 817, 62, 816, - 817, 286, 288, 400, 401, -442, -441, 465, -251, 402, - 38, 40, 713, 758, 405, 406, -172, 22, -232, -442, - -441,-32766,-32766,-32766, 374, -173, -442, -441, -445, 1032, - -477, -441, 1032, 998, 417, -479, 391, 347, 739, 547, - -133,-32766, 392,-32766,-32766, -441, 727, 678, 679, 32, - 17, 393, -441, 394, 276, 395, 357, 396, 789, 549, - 397, 71, 975, 1050, 34, 35, 398, 346, 335, 36, - 399, 247, 248, 62, 254, 737, 286, 288, 400, 401, - 408, 120, 131, 530, 402, 982, 306, 670, 758, 405, - 406, 337, 113, 115,-32766,-32766, 72, 73, 74, 242, - 529, 65, 121, 553, 502, 18, 264, 126, 274, 264, - -32766,-32766,-32766, 739, 547, -4, 26, 751, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 586, 587, 588, 589, 590, 218, 591, 592, 593, 629, + 630, 665, 32, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113,-32766,-32766,-32766, 881, 882, + 883, 880, 879, 878, 0,-32766,-32766,-32766,-32766,-32766, + -32766, 663, 824, 117, 24,-32766, 428,-32766,-32766,-32766, + -32766,-32766, 594, 914, 916,-32766, 9,-32766,-32766,-32766, + -32766,-32766,-32766, 857, 250, 350, 595, 596, 597, 598, + 599, 600, 601, 119, 250, 661, 881, 882, 883, 880, + 879, 878, 602, 603, 604, 605, 606, 607, 608, 609, + 610, 611, 612, 632, 633, 634, 635, 636, 624, 625, + 626, 627, 628, 613, 614, 615, 616, 617, 618, 619, + 655, 656, 657, 658, 659, 660, 620, 621, 622, 623, + 653, 644, 642, 643, 639, 640, 800, 631, 637, 638, + 645, 646, 648, 647, 649, 650, 45, 46, 405, 47, + 48, 641, 652, 651, -233, 49, 50, 231, 51,-32767, + -32767,-32767,-32767, 93, 94, 95, 96, 97,-32766,-32766, + -32766, 42, -451, 25, -293, -293, 828, 829, 98, 99, + 100, 260, 241, 230, -453, 1047, 828, 829,-32766, 1013, + 873, 52, 53, 486, 101, 670, 242, 54, -238, 55, + 223, 224, 56, 57, 58, 59, 60, 61, 62, 63, + -452, 25, 234, 64, 357,-32766,-32766,-32766, 990, 1014, + 1015, 407, -271, 1047, -488, 665, 265, 1013,-32766,-32766, + -32766, 746, 248, -451, 250,-32766, 420,-32766,-32766,-32766, + -32766, 388, -258, 1078, 277, -453, 365, -451,-32766, 1077, + -32766,-32766,-32766, 116, -451, 801, 291, 68, 665, -453, + 428, 292, 267, 1065, 417, 418, -453, -489, -456, 373, + 997, -452, 557, 419, 420, 1050, 1019, 1020, 1021, 1022, + 1016, 1017, 245, 764, -451, -452, 217, 429, 1023, 1018, + 362, 295, -452, 1047, -455, 66, 1009, 257,-32766, 262, + 267, 406, -136, -136, -136, -4, 746, 686, 687, 299, + 668, 735, 266, 1090, 37, 20, 408, -136, 409, -136, + 410, -136, 411, -136, 429, 412, 229, 362, 490, 38, + 39, 358, 359, 355, 40, 413, 828, 829, 65, 663, + 44, 290, 669, 414, 415, -451, -492, 33, 1047, 416, + 122, 346, 721, 769, 360, 361, 353, 1099, -91, -451, + 1100, 389,-32766,-32766,-32766, 354, -451, 121, 665, -488, + 267, 28, 226, 379, 1047, 228, 406, 746, 748, 555, + -136, 990,-32766, 219,-32766,-32766, 735, -258, 233, 37, + 20, 408, 351, 409, -495, 410, -495, 411, 665, 451, + 412, 249, 232, 428, 38, 39, 358, 359, 342, 40, + 413, 125, -489, 65, 256, 294, 290, 665, 414, 415, + 25, 30, 118, 74, 416, 267, 356, 678, 769, 360, + 361, 568, 1047, 428, 25, 127, 1013, 540, 123,-32766, + -32766,-32766, -176, 834, 124, -177, 1047, 406, 279, 746, + 1013, 267, 428, 748, 555, -4, 1027, 735, 665, 474, + 37, 20, 408, 281, 409, 990, 410, 115, 411,-32766, + -32766, 412, -218, -218, -218, 38, 39, 358, 359, 990, + 40, 413, 419, 420, 65, -491, 225, 290, 229, 414, + 415, -492, 569, 428, 114, 416, 419, 420, 721, 769, + 360, 361, 131, 541, 68, 133, 362, 130, 317, 267, + 859, 134, 227, 529, 530, 997, 517, 21, 68, 406, + 95, 96, 97, 267, 748, 555, -218, 120, 665, 735, + 665, 129, 37, 20, 408, 745, 409, 244, 410, -82, + 411, 686, 687, 412, -217, -217, -217, 38, 39, 358, + 359, 572, 40, 413, 665, 760, 65, 241, 746, 290, + 101, 414, 415, 428, 43, 428, 1066, 416, 398, 8, + 721, 769, 360, 361, 508, 509, 828, 829, 128, 75, + 76, 77, 858, 578, 665, 1101, 570, -176, -291, 428, + -177, 537, 666, 1047, 523, 663, 748, 555, -217, 31, + 123, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 111, 239, 118, 737, 391, 92, 93, 94, 531, - 112, 392, 347, -251, 98, 727, 845, 124, 32, 17, - 393, -172, 394, 1032, 395, 130, 396, 515, 516, 397, - -173, 117, 554, 34, 35, 398, 737, 790, 36, 399, - -479, 736, 62, 383, 6, 286, 288,-32766,-32766,-32766, - 127, 311, 114, 402, 678, 679, 975, 495, 496, 816, - 817, 856, 565, 119, 552, 844, 575, 343, 223, 564, - 559, 221, 225, 239, 391, 98, 658, 439, 39, 525, - 392, 659, 775, 547, 727, 435, 971, 32, 17, 393, - 358, 394, 356, 395, 299, 396, 319, 694, 397, 1074, - 264, 451, 34, 35, 398, 737, 391, 36, 399, 453, - 511, 62, 392, 449, 286, 288, 727, 499, 540, 32, - 17, 393, 402, 394, 438, 395, 1081, 396, 354, 444, - 397,-32766, 493, 551, 34, 35, 398, 737, 503, 36, - 399, 526, -80, 62, 759, 507, 286, 288, 214, 456, - 10, 739, 547, 519, 402, 508, 975, 257, 15, 0, - 338, 0, 0, 259, 1011, 560, 760, 1014, 262, 0, - 0, 0, 0, 0, 0, 391, 0, 0, 0, 0, - 0, 392, 0, 739, 547, 727, 227, 256, 32, 17, - 393, 0, 394, 0, 395, 0, 396, 0, 0, 397, - 3, 0, 9, 34, 35, 398, 737, 391, 36, 399, - 305, -400, 62, 392, 753, 286, 288, 727, 22, 339, - 32, 17, 393, 402, 394, 327, 395, 324, 396, 316, - 1032, 397, 323, 357, 998, 34, 35, 398, 446, 773, - 36, 399, 31, 573, 62, 574, 718, 286, 288, 840, - 850, 792, 739, 547, 30, 402, 849, 852, 851, 848, - 771, 776, 716, 975, 784, 841, 783, 19, 548, 333, - 550, 555, 557, 558, 270, 271, 391, 332, 571, 570, - 407, 408, 392, 568, 739, 547, 727, 566, 563, 32, - 17, 393, 562, 394, 757, 395, 756, 396, 755, 963, - 397, -444, 65, 857, 34, 35, 398, 264, 744, 36, - 399, 962, 961, 62, 754, 746, 286, 288,-32766,-32766, - -32766, 681, 1077, 680, 402, 683, 682, 672, 673, 782, - 567, 714, 1078, 781, 1047, 1044, 1039, 1026,-32766, 1033, - -32766,-32766,-32766,-32766,-32766,-32766,-32767,-32767,-32767,-32767, - -32767, 1075, 250, 739, 547, -467, 955, -446, -445, 20, - 23, 29, 33, 37, 64, 336, 334, 273, 238, 237, - 236, 235, 218, 217, 132, 129, 123, 70, 69, 68, - 67, 66, -469, 0, 308, 473, 939, 489, 539, -230, - 942, 11, 967, 823, 996, 938, 986, 536, 388, -88, - 381, 378, 375, 309, 16, 14, 13, 12, -227, -228, - 0, -412, 0, 995, 501, 1073, 1038, 1025, 1024, 0, - 1013 + 97, 98, 99, 100, 887, 241, 990, 746, 406, 668, + -491, 455, 460,-32766, 518, 532, -80, 101, 735, 533, + 370, 37, 20, 408, 549, 409, 377, 410, 10, 411, + 507, 990, 412, 770, 524, 566, 38, 39, 358, 746, + 771, 40, 413, 261, 1029, 65, 264, 1026, 290, 12, + 267, 293, 373, -410, 258, 5, 416, 970, 347, 0, + 335, 348, 331, 259, 0, 0, 0, 563, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 406, 0, 0, + 0, 0, 0, 0, 0, 748, 555, 735, 330, 324, + 37, 20, 408, 457, 409, 762, 410, 853, 411, 556, + 870, 412, 726, 577, 36, 38, 39, 358, 746, 406, + 40, 413, 35, 576, 65, 803, 863, 290, 866, 735, + 787, 865, 37, 20, 408, 416, 409, 862, 410, 782, + 411, 724, 795, 412, 784, 854, 561, 38, 39, 358, + 746, 794, 40, 413, 864, 793, 65, 558, 341, 290, + 340, 560, 276, 275, 748, 555, 571, 416, 567, 565, + 564, 559, 514, 792, 753, 763, 755, 689, 562, 978, + 766, 1097, 1048, 722, 1096, 1098, 681, 768, 406, 746, + 680, 690, 767, 691, 688, 1095, 786, 555, 735, 1063, + 1041, 37, 20, 408, 1055, 409, 1060, 410, 573, 411, + 41, 34, 412, 27, 26, 23, 38, 39, 358, -454, + 406, 40, 413, -455, -456, 65, -478, -480, 290, 237, + 735, 345, 343, 37, 20, 408, 416, 409, 278, 410, + 240, 411, 239, 238, 412, 222, 221, 135, 38, 39, + 358, 132, 126, 40, 413, 73, 72, 65, 71, 406, + 290, 70, 69, 67, 1028, 748, 555, 954, 416, 735, + 957, 548, 37, 20, 408, 503, 409, 484, 410, 313, + 411, 252, 22, 412, 18, 13, -236, 38, 39, 358, + 982, 835, 40, 413, 1011, 953, 65, 748, 555, 290, + -32766,-32766,-32766, 1001, 546, 403, 396, 416, 394, 390, + 314, 19, 17, 16, -91, 15, 14, -233, -234, 0, + -32766, -422,-32766,-32766,-32766,-32766,-32766,-32766,-32767,-32767, + -32767,-32767,-32767, 1010, 1093, 1054, 748, 555, 1040, 1039 ); protected $actionCheck = array( - 2, 3, 4, 5, 6, 0, 8, 9, 10, 11, - 12, 48, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 8, 9, 10, 50, 51, - 52, 7, 54, 7, 79, 8, 9, 10, 7, 7, - 77, 77, 79, 80, 66, 28, 7, 30, 31, 32, - 33, 34, 54, 56, 57, 28, 8, 30, 31, 32, - 33, 34, 35, 7, 109, 1, 68, 69, 70, 71, - 72, 73, 74, 118, 7, 77, 112, 113, 114, 115, + 2, 3, 4, 5, 6, 13, 8, 9, 10, 11, + 12, 77, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 8, 9, 10, 112, 113, + 114, 115, 116, 117, 0, 8, 9, 10, 8, 9, + 10, 77, 1, 13, 7, 28, 112, 30, 31, 32, + 33, 34, 54, 56, 57, 28, 7, 30, 31, 32, + 33, 34, 35, 1, 28, 7, 68, 69, 70, 71, + 72, 73, 74, 7, 28, 77, 112, 113, 114, 115, 116, 117, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 13, 129, 130, 131, + 122, 123, 124, 125, 126, 127, 29, 129, 130, 131, 132, 133, 134, 135, 136, 137, 2, 3, 4, 5, - 6, 143, 144, 145, 35, 11, 12, 1, 14, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 109, 82, - 67, 112, 113, 114, 115, 116, 117, 118, 8, 9, - 10, 79, 79, 79, 82, 1, 83, 7, 67, 28, - 7, 47, 48, 152, 152, 154, 154, 53, 28, 55, + 6, 143, 144, 145, 152, 11, 12, 7, 14, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 8, 9, + 10, 67, 67, 67, 102, 103, 130, 131, 50, 51, + 52, 109, 54, 35, 67, 79, 130, 131, 28, 83, + 118, 47, 48, 1, 66, 1, 7, 53, 152, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 67, 67, 68, 69, 70, 112, 8, 9, 10, 75, - 76, 77, 148, 79, 13, 7, 139, 83, 8, 9, - 10, 1, 129, 130, 28, 79, 28, 28, 30, 31, - 32, 33, 140, 141, 29, 7, 102, 7, 28, 128, - 30, 31, 32, 1, 151, 7, 112, 13, 7, 156, - 156, 77, 7, 142, 120, 121, 147, 7, 112, 7, - 149, 152, 151, 129, 130, 152, 132, 133, 134, 135, - 136, 137, 138, 7, 67, 67, 67, 143, 144, 145, - 146, 130, 131, 150, 1, 151, 7, 153, 7, 155, - 156, 71, 72, 73, 74, 0, 1, 77, 77, 35, - 67, 81, 156, 152, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 15, 95, 96, 97, 98, 99, - 100, 101, 102, 149, 104, 105, 130, 131, 108, 130, - 131, 111, 112, 113, 114, 128, 128, 128, 7, 119, - 67, 67, 122, 123, 124, 125, 7, 67, 152, 142, - 142, 8, 9, 10, 149, 7, 149, 149, 151, 79, - 152, 128, 79, 83, 143, 7, 71, 146, 148, 149, - 150, 28, 77, 30, 31, 142, 81, 102, 103, 84, - 85, 86, 149, 88, 33, 90, 146, 92, 29, 149, - 95, 149, 112, 152, 99, 100, 101, 102, 103, 104, - 105, 128, 128, 108, 109, 1, 111, 112, 113, 114, - 130, 147, 15, 77, 119, 1, 142, 122, 123, 124, - 125, 146, 149, 149, 8, 9, 8, 9, 10, 29, - 79, 151, 149, 29, 72, 73, 156, 29, 143, 156, - 8, 9, 10, 148, 149, 150, 28, 35, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 15, 54, 15, 1, 71, 47, 48, 49, 143, - 15, 77, 146, 152, 66, 81, 150, 15, 84, 85, - 86, 152, 88, 79, 90, 15, 92, 72, 73, 95, - 152, 15, 29, 99, 100, 101, 1, 148, 104, 105, - 152, 29, 108, 102, 103, 111, 112, 8, 9, 10, - 97, 98, 13, 119, 102, 103, 112, 106, 107, 130, - 131, 148, 149, 29, 29, 148, 149, 123, 35, 29, - 29, 35, 35, 54, 71, 66, 77, 77, 67, 74, - 77, 77, 148, 149, 81, 77, 79, 84, 85, 86, - 77, 88, 77, 90, 77, 92, 78, 77, 95, 77, - 156, 77, 99, 100, 101, 1, 71, 104, 105, 77, - 79, 108, 77, 86, 111, 112, 81, 79, 89, 84, - 85, 86, 119, 88, 79, 90, 80, 92, 102, 82, - 95, 82, 109, 29, 99, 100, 101, 1, 87, 104, - 105, 91, 94, 108, 123, 93, 111, 112, 94, 94, - 94, 148, 149, 96, 119, 96, 112, 127, 152, -1, - 146, -1, -1, 110, 139, 29, 123, 139, 126, -1, - -1, -1, -1, -1, -1, 71, -1, -1, -1, -1, - -1, 77, -1, 148, 149, 81, 35, 126, 84, 85, - 86, -1, 88, -1, 90, -1, 92, -1, -1, 95, - 142, -1, 142, 99, 100, 101, 1, 71, 104, 105, - 142, 142, 108, 77, 147, 111, 112, 81, 67, 146, - 84, 85, 86, 119, 88, 146, 90, 146, 92, 146, - 79, 95, 146, 146, 83, 99, 100, 101, 146, 148, - 104, 105, 148, 148, 108, 148, 148, 111, 112, 148, - 148, 148, 148, 149, 148, 119, 148, 148, 148, 148, - 148, 148, 148, 112, 148, 148, 148, 152, 149, 149, - 149, 149, 149, 149, 149, 149, 71, 149, 149, 149, - 129, 130, 77, 149, 148, 149, 81, 149, 149, 84, - 85, 86, 149, 88, 150, 90, 150, 92, 150, 150, - 95, 151, 151, 150, 99, 100, 101, 156, 150, 104, - 105, 150, 150, 108, 150, 150, 111, 112, 8, 9, - 10, 150, 150, 150, 119, 150, 150, 150, 150, 150, - 150, 150, 150, 150, 150, 150, 150, 150, 28, 150, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 150, 152, 148, 149, 151, 153, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, 151, 151, 151, 151, 151, 151, 151, - 151, 151, 151, -1, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, - 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, - -1, 153, -1, 154, 154, 154, 154, 154, 154, -1, - 155 + 67, 67, 68, 69, 70, 8, 9, 10, 112, 75, + 76, 77, 150, 79, 7, 77, 7, 83, 8, 9, + 10, 1, 128, 128, 28, 28, 130, 30, 31, 32, + 33, 29, 7, 1, 7, 128, 102, 142, 28, 7, + 30, 31, 32, 149, 149, 148, 112, 151, 77, 142, + 112, 7, 156, 1, 120, 121, 149, 7, 151, 146, + 1, 128, 149, 129, 130, 1, 132, 133, 134, 135, + 136, 137, 138, 1, 67, 142, 94, 143, 144, 145, + 146, 7, 149, 79, 151, 151, 1, 153, 8, 155, + 156, 71, 72, 73, 74, 0, 1, 102, 103, 7, + 79, 81, 67, 82, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 143, 95, 35, 146, 48, 99, + 100, 101, 102, 7, 104, 105, 130, 131, 108, 77, + 67, 111, 148, 113, 114, 128, 7, 13, 79, 119, + 29, 146, 122, 123, 124, 125, 7, 77, 152, 142, + 80, 149, 8, 9, 10, 7, 149, 15, 77, 152, + 156, 140, 141, 128, 79, 35, 71, 1, 148, 149, + 150, 112, 28, 13, 30, 31, 81, 152, 35, 84, + 85, 86, 123, 88, 152, 90, 154, 92, 77, 82, + 95, 128, 35, 112, 99, 100, 101, 102, 103, 104, + 105, 149, 152, 108, 109, 142, 111, 77, 113, 114, + 67, 7, 149, 149, 119, 156, 7, 122, 123, 124, + 125, 149, 79, 112, 67, 15, 83, 77, 147, 8, + 9, 10, 7, 152, 149, 7, 79, 71, 143, 1, + 83, 156, 112, 148, 149, 150, 139, 81, 77, 78, + 84, 85, 86, 33, 88, 112, 90, 15, 92, 8, + 9, 95, 96, 97, 98, 99, 100, 101, 102, 112, + 104, 105, 129, 130, 108, 7, 35, 111, 35, 113, + 114, 152, 29, 112, 15, 119, 129, 130, 122, 123, + 124, 125, 15, 143, 151, 15, 146, 97, 98, 156, + 150, 15, 35, 72, 73, 1, 72, 73, 151, 71, + 47, 48, 49, 156, 148, 149, 150, 15, 77, 81, + 77, 29, 84, 85, 86, 29, 88, 29, 90, 29, + 92, 102, 103, 95, 96, 97, 98, 99, 100, 101, + 102, 29, 104, 105, 77, 35, 108, 54, 1, 111, + 66, 113, 114, 112, 67, 112, 152, 119, 102, 103, + 122, 123, 124, 125, 106, 107, 130, 131, 67, 8, + 9, 10, 148, 149, 77, 80, 29, 152, 79, 112, + 152, 74, 77, 79, 93, 77, 148, 149, 150, 28, + 147, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 79, 54, 112, 1, 71, 79, + 152, 82, 86, 82, 87, 91, 94, 66, 81, 96, + 102, 84, 85, 86, 89, 88, 94, 90, 94, 92, + 109, 112, 95, 123, 96, 29, 99, 100, 101, 1, + 123, 104, 105, 110, 139, 108, 126, 139, 111, 142, + 156, 142, 146, 142, 126, 142, 119, 153, 146, -1, + 146, 146, 146, 127, -1, -1, -1, 29, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 71, -1, -1, + -1, -1, -1, -1, -1, 148, 149, 81, 146, 146, + 84, 85, 86, 146, 88, 147, 90, 148, 92, 149, + 148, 95, 148, 148, 148, 99, 100, 101, 1, 71, + 104, 105, 148, 148, 108, 148, 148, 111, 148, 81, + 148, 148, 84, 85, 86, 119, 88, 148, 90, 148, + 92, 148, 148, 95, 148, 148, 29, 99, 100, 101, + 1, 148, 104, 105, 148, 150, 108, 149, 149, 111, + 149, 149, 149, 149, 148, 149, 149, 119, 149, 149, + 149, 149, 154, 150, 150, 150, 150, 150, 29, 150, + 150, 150, 150, 150, 150, 150, 150, 150, 71, 1, + 150, 150, 150, 150, 150, 150, 148, 149, 81, 150, + 150, 84, 85, 86, 150, 88, 150, 90, 150, 92, + 151, 151, 95, 151, 151, 151, 99, 100, 101, 151, + 71, 104, 105, 151, 151, 108, 151, 151, 111, 151, + 81, 151, 151, 84, 85, 86, 119, 88, 151, 90, + 151, 92, 151, 151, 95, 151, 151, 151, 99, 100, + 101, 151, 151, 104, 105, 151, 151, 108, 151, 71, + 111, 151, 151, 151, 155, 148, 149, 152, 119, 81, + 152, 152, 84, 85, 86, 152, 88, 152, 90, 152, + 92, 152, 152, 95, 152, 152, 152, 99, 100, 101, + 152, 152, 104, 105, 152, 152, 108, 148, 149, 111, + 8, 9, 10, 152, 152, 152, 152, 119, 152, 152, + 152, 152, 152, 152, 152, 152, 152, 152, 152, -1, + 28, 153, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 154, 154, 154, 148, 149, 154, 154 ); protected $actionBase = array( - 0, 220, 295, 283, 336, 572, -2, -2, -2, -2, - -36, 505, 473, 606, 473, 574, 404, 675, 675, 675, - 109, 264, 506, 506, 506, 488, 504, 503, 507, 134, + 0, 220, 295, 366, 438, 285, 350, 606, -2, -2, + -36, -2, -2, 749, 616, 616, 547, 616, 717, 648, + 788, 788, 788, 281, 443, 441, 441, 467, 371, 441, + 467, 311, 330, 138, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, -66, -66, -66, -66, + -66, -66, -66, -66, -66, -66, 184, 184, 97, 182, + 324, 729, 718, 725, 732, 733, 727, 715, 360, 645, + 632, 492, 650, 654, 656, 649, 723, 618, 730, 719, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 280, 30, 451, 421, + 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, + 421, 421, 421, 421, 421, 421, 421, 421, 150, 150, + 150, 344, 210, 207, 197, 17, 95, 27, 892, 892, + 892, 892, 892, 108, 108, 108, 108, 357, 357, 343, + 62, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 259, 463, 463, 36, 36, 36, + 36, 504, 196, 499, 46, 307, 515, 709, 252, 252, + 436, 107, 133, 118, 118, 118, 195, 539, 529, 529, + 529, 529, 221, 221, 529, 529, 270, 264, 232, 95, + 95, 263, 95, 95, 95, 429, 429, 429, 171, 113, + 541, 171, 562, 622, 548, 623, 533, 605, 94, 522, + 204, 528, 525, 204, 204, 204, 458, 434, 431, 762, + 184, 521, 184, 184, 184, 184, 678, 184, 184, 184, + 184, 184, 184, 202, 184, 41, 424, 97, 272, 272, + 420, 272, 493, 235, 614, 425, 404, 493, 493, 493, + 613, 611, 250, 225, -8, 609, 428, 456, 468, 329, + 497, 497, 508, 508, 535, 510, 497, 497, 497, 497, + 497, 664, 664, 508, 540, 508, 535, 659, 508, 510, + 508, 508, 497, 508, 664, 510, 66, 339, 244, 274, + 510, 348, 538, 497, 530, 530, 316, 508, 140, 508, + 37, 546, 664, 664, 546, 179, 510, 209, 575, 565, + 531, 558, 227, 498, 498, 58, 531, 409, 510, 498, + 49, 540, 292, 498, 34, 712, 711, 500, 710, 660, + 707, 681, 705, 560, 520, 527, 695, 694, 704, 662, + 663, 496, 557, 469, 442, 523, 487, 668, 528, 516, + 484, 484, 484, 487, 673, 484, 484, 484, 484, 484, + 484, 484, 484, 779, 519, 536, 502, 553, 542, 342, + 608, 518, 557, 557, 633, 768, 514, 505, 678, 751, + 701, 574, 410, 759, 692, 658, 552, 526, 691, 758, + 743, 612, 469, 742, 634, 501, 635, 557, 636, 484, + 675, 676, 785, 784, 672, 781, 764, 757, 524, 637, + 495, 780, 640, 739, 621, 620, 566, 763, 734, 756, + 641, 754, 642, 564, 537, 766, 491, 680, 687, 619, + 643, 644, 559, 477, 631, 630, 629, 700, 577, 761, + 534, 760, 765, 582, 603, 480, 627, 486, 597, 696, + 453, 507, 596, 594, 738, 626, 689, 593, 625, 752, + 532, 516, 517, 543, 544, 545, 617, 753, 512, 591, + 589, 583, 580, 624, 578, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 134, 134, 134, 134, -2, -2, -2, 0, + 0, -2, 0, 0, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, @@ -432,273 +497,232 @@ class Php7 extends \PhpParser\ParserAbstract 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 64, 64, 359, 201, 670, 708, 703, - 476, 709, 524, 702, 704, 234, 671, 659, 408, 657, - 656, 655, 654, 705, 730, 585, 706, 418, 418, 418, - 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, 418, 48, 509, 416, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 432, 432, 432, 432, 432, - 432, 432, 432, 432, 432, 160, 160, 160, 343, 210, - 208, 198, 17, 233, 27, 780, 780, 780, 780, 780, - 108, 108, 108, 108, 621, 621, 93, 280, 280, 280, - 280, 280, 280, 280, 280, 280, 280, 280, 614, 616, - 618, 619, 414, 429, 429, 196, 196, 196, 196, 146, - 151, -45, 199, 77, 498, 735, 399, 174, 174, 111, - 207, -22, -22, -22, 275, 517, 514, 514, 514, 514, - 92, 92, 514, 514, 242, -37, 233, 233, 274, 233, - 422, 422, 422, 221, 240, 519, 221, 591, 529, 653, - 527, 649, 273, 31, 32, 484, 94, 543, 496, 94, - 421, 362, 425, 717, 64, 539, 64, 64, 64, 64, - 64, 64, 64, 64, 64, 94, 94, 64, 205, 64, - 387, 359, 383, 489, 502, 209, 595, 339, 241, 133, - 489, 489, 489, 596, 598, 331, 113, 590, 348, 411, - 358, 351, 469, 469, 412, 478, 494, 469, 469, 469, - 469, 508, 469, 678, 678, 682, 412, 469, 678, 412, - 266, 24, 173, 67, 412, 281, 531, 469, 512, 512, - 279, 478, 515, 230, 250, 500, 678, 678, 500, 494, - 56, 412, 26, 565, 567, 493, 537, 39, 400, 400, - 238, 493, 228, 412, 400, 508, 245, 170, 400, 5, - 683, 700, 482, 699, 680, 698, 684, 697, 487, 589, - 491, 513, 692, 691, 696, 470, 485, 681, 679, 562, - 483, 456, 465, 528, 481, 620, 496, 557, 479, 479, - 479, 481, 676, 479, 479, 479, 479, 479, 479, 479, - 479, 729, 252, 538, 497, 486, 553, 525, 458, 608, - 495, 562, 562, 651, 728, 673, 474, 690, 714, 695, - 576, 472, 722, 689, 650, 556, 490, 551, 688, 721, - 713, 604, 456, 712, 652, 492, 562, 648, 479, 674, - 701, 734, 733, 677, 732, 720, 549, 516, 731, 647, - 711, 600, 599, 564, 725, 707, 719, 646, 718, 568, - 521, 727, 522, 685, 501, 686, 592, 645, 643, 299, - 571, 642, 694, 573, 724, 723, 726, 583, 588, 593, - 594, 480, 641, 397, 587, 693, 511, 475, 520, 586, - 477, 710, 635, 613, 687, 584, 561, 634, 632, 715, - 518, 557, 530, 523, 526, 499, 609, 631, 716, 510, - 582, 581, 580, 579, 628, 578, 623, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 134, 134, -2, - -2, -2, 0, 0, 0, 0, -2, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, - 134, 134, 134, 134, 134, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, - 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, 418, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 418, - 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, - 418, 418, 418, 418, 418, 418, -3, 418, 418, -3, - 418, 418, 418, 418, 418, 418, -22, -22, -22, -22, - 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, - 221, 221, 221, 221, 49, 49, 49, 49, 221, -22, - -22, 221, 221, 221, 221, 221, 221, 49, 221, 92, - 92, 92, 221, 94, 94, 0, 0, 0, 0, 0, - 469, 92, 221, 221, 221, 221, 0, 0, 221, 221, - 94, 0, 0, 0, 0, 0, 469, 469, 469, 0, - 469, 92, 0, 64, 423, 423, 423, 423, 0, 0, - 0, 469, 0, 469, 515, 0, 0, 0, 0, 412, - 0, 678, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 479, - 690, 0, 474, 0, 0, 0, 479, 479, 479, 474, - 474, 0, 0, 474 + 134, 134, 134, 134, 134, 134, 134, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 561, 561, 561, -3, 561, 561, -3, 561, 561, + 561, 561, 561, 561, 118, 118, 118, 118, 171, 171, + 171, -84, 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 118, 118, 171, 171, + 171, 171, 171, 171, -84, 171, 221, 221, 221, 204, + 204, 171, 0, 0, 0, 0, 0, 497, 221, 171, + 171, 171, 171, 0, 0, 171, 171, 540, 204, 0, + 0, 0, 0, 0, 0, 0, 497, 497, 497, 0, + 497, 221, 0, 272, 184, 400, 400, 400, 400, 0, + 497, 0, 540, 497, 0, 0, 0, 0, 0, 0, + 510, 0, 664, 0, 0, 0, 0, 508, 0, 0, + 0, 0, 0, 0, 0, 0, 540, 0, 0, 0, + 0, 540, 0, 484, 0, 505, 0, 0, 484, 484, + 484, 505, 505, 0, 0, 0, 505 ); protected $actionDefault = array( - 3,32767,32767,32767,32767,32767,32767, 88,32767,32767, + 3,32767,32767,32767,32767,32767,32767,32767,32767, 91, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767, 93, 504, 504, 494,32767, 504, + 494,32767,32767,32767, 312, 312, 312,32767, 449, 449, + 449, 449, 449, 449, 449,32767,32767,32767,32767,32767, + 391,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767, 88, 489, 489, 489,32767,32767,32767,32767, 302, - 302, 302,32767, 481, 439, 439, 439, 439, 439, 439, - 439, 481,32767,32767,32767,32767,32767, 381,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 91, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 501,32767,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767, 88,32767,32767,32767, + 374, 375, 377, 378, 311, 450, 257, 500, 310, 129, + 268, 259, 210, 308, 242, 133, 339, 392, 341, 390, + 394, 340, 317, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, 315, 316, 393, 371, 370, + 369, 337, 338, 314, 342, 344, 314, 343, 360, 361, + 358, 359, 362, 363, 364, 365, 366,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767, 486,32767,32767,32767, + 32767, 93,32767,32767,32767, 351, 352, 249, 249, 249, + 249,32767, 249, 294,32767,32767,32767,32767,32767,32767, + 32767, 443, 368, 346, 347, 345,32767, 421,32767,32767, + 32767,32767,32767, 423,32767, 91,32767,32767,32767, 334, + 336, 415, 503, 318, 502,32767,32767, 93,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 418,32767, + 32767, 409, 91,32767,32767, 91, 173, 229, 231, 178, + 32767, 426,32767,32767,32767,32767,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767, 364, 365, 367, - 368, 301, 440, 250, 485, 300, 126, 261, 252, 204, - 298, 236, 130, 329, 382, 331, 380, 384, 330, 307, - 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, - 321, 322, 305, 306, 383, 361, 360, 359, 327, 328, - 304, 332, 334, 304, 333, 350, 351, 348, 349, 352, - 353, 354, 355, 356,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767, 88,32767, 284, 284, - 284, 284,32767, 341, 342, 242, 242, 242, 242,32767, - 242, 285,32767,32767,32767,32767,32767,32767,32767, 433, - 358, 336, 337, 335,32767, 411,32767,32767,32767,32767, - 32767, 413,32767, 88,32767,32767, 324, 326, 405, 308, - 32767,32767, 90,32767,32767,32767,32767,32767,32767,32767, - 32767,32767, 408, 441, 441,32767,32767, 88, 399, 88, - 169, 223, 225, 174,32767, 416,32767,32767,32767,32767, + 32767,32767, 356, 511,32767, 451,32767, 348, 349, 350, + 32767,32767, 451, 451, 451,32767, 451,32767, 451, 451, + 32767,32767,32767,32767,32767, 178,32767,32767,32767,32767, + 93, 424, 424, 91, 91, 91, 91, 419,32767, 178, + 32767,32767,32767,32767,32767, 178, 90, 90, 90, 90, + 178, 90, 193,32767, 191, 191, 90,32767, 92,32767, + 92, 195,32767, 465, 195, 90, 178, 90, 215, 215, + 400, 180, 92, 251, 251, 92, 400, 90, 178, 251, + 90,32767, 90, 251,32767,32767,32767, 84,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767, 346,32767, 496,32767, 441,32767,32767, - 338, 339, 340,32767,32767, 441, 441,32767, 441,32767, - 441,32767,32767,32767, 174,32767,32767,32767,32767,32767, - 32767,32767, 90, 414, 414, 409, 174,32767,32767, 174, - 87, 87, 87, 87, 174, 87, 187,32767, 185, 185, - 87, 88, 88, 87, 87, 189,32767, 455, 189, 88, - 87, 174, 87, 209, 209, 390, 176, 89, 244, 244, - 89, 390, 87, 174, 244, 88, 87, 87, 244,32767, - 32767,32767, 82,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767,32767, 401, - 32767,32767, 421,32767, 434, 453, 399,32767, 344, 345, - 347,32767, 443, 369, 370, 371, 372, 373, 374, 375, - 377,32767, 482, 404,32767,32767, 84, 117, 260,32767, - 494, 84, 402,32767, 494,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767, 84,32767, 84,32767,32767, - 32767,32767, 478,32767, 441,32767, 403,32767, 343, 417, - 460,32767,32767, 442,32767,32767, 84,32767,32767,32767, - 32767,32767,32767,32767,32767, 421,32767,32767,32767,32767, - 32767, 441,32767,32767,32767,32767,32767,32767,32767, 297, - 32767,32767,32767,32767,32767,32767, 441,32767,32767,32767, - 32767, 235,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 411,32767, 431,32767, 444, 463, 409,32767, + 354, 355, 357,32767, 453, 379, 380, 381, 382, 383, + 384, 385, 387,32767, 414,32767,32767, 86, 120, 267, + 32767, 509, 86, 412,32767, 509,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767, 86, 86,32767,32767, + 32767,32767, 490,32767, 510,32767, 451, 413,32767, 353, + 427, 470,32767,32767, 452,32767,32767,32767, 86,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 431,32767, + 32767,32767,32767,32767,32767, 451,32767,32767,32767,32767, + 32767,32767,32767, 307,32767,32767,32767,32767,32767,32767, + 32767,32767, 451,32767,32767, 241,32767,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 82, 60,32767, 278,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767, 132, 132, 3, - 3, 132, 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 263, 164, 263, 217, - 263, 263, 220, 209, 209, 270 + 84, 60,32767, 287,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 135, 135, 3, 270, 3, + 270, 135, 135, 135, 270, 270, 135, 135, 135, 135, + 135, 135, 135, 168, 223, 226, 215, 215, 279, 135, + 135 ); protected $goto = array( - 163, 163, 136, 136, 136, 146, 148, 179, 164, 161, - 161, 161, 161, 145, 162, 162, 162, 162, 162, 162, - 162, 145, 157, 158, 159, 160, 176, 174, 177, 418, - 419, 313, 420, 423, 424, 425, 426, 427, 428, 429, - 430, 886, 134, 137, 138, 139, 140, 141, 142, 143, - 144, 147, 173, 175, 178, 195, 198, 199, 201, 202, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 233, 234, 251, 252, 253, 320, 321, 322, 468, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 149, 194, 150, 165, 166, 167, 196, - 168, 151, 152, 153, 169, 154, 197, 135, 170, 155, - 171, 172, 156, 532, 200, 436, 734, 704, 469, 855, - 545, 279, 200, 524, 853, 470, 710, 667, 5, 462, - 669, 441, 441, 441, 261, 441, 791, 462, 770, 245, - 569, 668, 434, 800, 795, 543, 457, 454, 441, 774, - 572, 490, 492, 518, 522, 788, 527, 528, 802, 535, - 787, 537, 544, 798, 546, 422, 422, 422, 422, 422, - 422, 422, 422, 422, 422, 422, 422, 422, 422, 421, - 421, 421, 421, 421, 421, 421, 421, 421, 421, 421, - 421, 421, 421, 441, 441, 486, 488, 538, 455, 476, - 441, 441, 972, 441, 229, 731, 230, 231, 442, 298, - 301, 448, 471, 472, 474, 766, 310, 541, 466, 485, - 485, 997, 997, 997, 997, 997, 997, 997, 997, 997, - 997, 997, 997, 699, 687, 829, 433, 833, 463, 695, - 1066, 1066, 777, 433, 825, 747, 480, 483, 504, 1059, - 314, 296, 807, 447, 767, 973, 505, 1066, 458, 671, - 768, 768, 768, 768, 870, 1051, 762, 769, 703, 968, - 695, 1069, 695, 974, 1028, 376, 676, 460, 726, 721, - 722, 735, 677, 723, 674, 724, 725, 8, 933, 675, - 810, 729, 1067, 1067, 821, 326, 506, 330, 317, 317, - 266, 267, 283, 464, 269, 325, 284, 328, 491, 1067, - 805, 805, 1056, 467, 479, 814, 1040, 686, 686, 285, - 280, 281, 696, 696, 696, 698, 510, 685, 497, 277, - 691, 523, 307, 688, 830, 312, 556, 969, 964, 512, - 368, 976, 482, 684, 815, 815, 815, 815, 976, 815, - 700, 815, 834, 779, 1037, 815, 384, 872, 0, 863, - 0, 1037, 0, 0, 0, 976, 976, 976, 976, 1048, - 1048, 976, 976, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 742, 0, 0, 743, 1034, 0, 0, 0, + 166, 166, 140, 140, 148, 149, 140, 148, 151, 182, + 167, 164, 164, 164, 164, 165, 165, 165, 165, 165, + 165, 165, 160, 161, 162, 163, 179, 177, 180, 430, + 431, 322, 432, 435, 436, 437, 438, 439, 440, 441, + 442, 901, 137, 141, 142, 143, 144, 145, 139, 146, + 147, 150, 176, 178, 181, 198, 201, 202, 204, 205, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 235, 236, 253, 254, 255, 327, 328, 329, 479, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 152, 197, 153, 168, 169, 170, 199, + 171, 154, 155, 156, 172, 157, 200, 138, 173, 158, + 174, 175, 159, 542, 203, 447, 551, 203, 743, 444, + 304, 308, 459, 482, 483, 485, 444, 493, 496, 519, + 1087, 1087, 987, 481, 452, 452, 452, 472, 452, 698, + 472, 677, 692, 779, 779, 779, 779, 1087, 467, 773, + 780, 452, 433, 433, 433, 285, 433, 433, 433, 433, + 433, 433, 433, 433, 433, 433, 433, 433, 433, 434, + 434, 434, 676, 434, 434, 434, 434, 434, 434, 434, + 434, 434, 434, 434, 434, 434, 480, 869, 554, 319, + 664, 263, 536, 867, 321, 988, 247, 502, 282, 452, + 452, 515, 516, 1057, 1058, 466, 488, 452, 452, 452, + 3, 4, 465, 989, 1043, 712, 785, 575, 504, 506, + 837, 453, 520, 535, 538, 813, 545, 553, 809, 498, + 498, 1012, 477, 1012, 1012, 1012, 1012, 1012, 1012, 1012, + 1012, 1012, 1012, 1012, 1012, 1012, 703, 675, 976, 765, + 738, 977, 739, 1086, 1086, 499, 501, 547, 802, 783, + 783, 781, 783, 574, 679, 445, 811, 806, 473, 1079, + 1086, 876, 1102, 777, 316, 550, 478, 1067, 492, 703, + 302, 684, 703, 734, 729, 730, 744, 1089, 685, 731, + 682, 732, 733, 683, 877, 737, 306, 449, 521, 470, + 948, 833, 458, 821, 334, 522, 338, 468, 325, 325, + 269, 270, 272, 476, 332, 273, 333, 274, 336, 505, + 339, 525, 1056, 391, 826, 289, 539, 816, 816, 1074, + 694, 694, 510, 283, 312, 11, 704, 704, 704, 706, + 693, 991, 286, 287, 827, 827, 827, 827, 991, 827, + 696, 827, 699, 579, 1062, 1062, 526, 827, 842, 846, + 449, 984, 1053, 708, 790, 991, 991, 991, 991, 1053, + 979, 991, 991, 384, 399, 886, 1064, 1064, 707, 695, + 841, 495, 845, 0, 0, 751, 0, 788, 752, 0, + 0, 0, 0, 0, 0, 1049, 818, 0, 778, 0, + 0, 0, 0, 0, 0, 0, 0, 986, 884, 0, + 0, 711, 464, 983, 0, 0, 0, 0, 844, 0, + 0, 1051, 1051, 844, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 446, 462, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 446, + 0, 462, 0, 0, 305, 0, 450, 372, 0, 374, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 832, 0, - 0, 832, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1041, 1042 + 0, 0, 0, 702, 0, 1094 ); protected $gotoCheck = array( - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 60, 53, 8, 10, 33, 7, 7, - 7, 76, 53, 7, 7, 93, 13, 13, 106, 81, - 15, 8, 8, 8, 128, 8, 13, 81, 13, 128, - 13, 14, 13, 13, 13, 5, 8, 36, 8, 37, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, 131, 129, - 129, 129, 129, 129, 129, 129, 129, 129, 129, 129, - 129, 129, 129, 8, 8, 64, 64, 64, 8, 8, - 8, 8, 88, 8, 69, 52, 69, 69, 8, 46, - 46, 46, 46, 46, 46, 72, 72, 72, 8, 82, - 82, 82, 82, 82, 82, 82, 82, 82, 82, 82, - 82, 82, 82, 11, 11, 11, 71, 11, 130, 23, - 139, 139, 11, 71, 90, 11, 11, 43, 43, 138, - 62, 49, 11, 62, 11, 88, 51, 139, 62, 10, - 71, 71, 71, 71, 11, 136, 71, 71, 11, 11, - 23, 139, 23, 88, 88, 62, 10, 50, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 62, 112, 10, - 84, 10, 140, 140, 86, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 140, - 81, 81, 81, 2, 2, 87, 133, 23, 23, 17, - 76, 76, 23, 23, 23, 23, 65, 23, 21, 9, - 27, 65, 16, 25, 92, 65, 78, 121, 118, 20, - 67, 60, 68, 12, 60, 60, 60, 60, 60, 60, - 29, 60, 95, 75, 93, 60, 116, 109, -1, 106, - -1, 93, -1, -1, -1, 60, 60, 60, 60, 93, - 93, 60, 60, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 60, -1, -1, 60, 93, -1, -1, -1, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 63, 56, 10, 8, 56, 13, 75, + 49, 49, 49, 49, 49, 49, 75, 15, 46, 46, + 148, 148, 92, 97, 10, 10, 10, 85, 10, 15, + 85, 18, 15, 75, 75, 75, 75, 148, 10, 75, + 75, 10, 135, 135, 135, 80, 135, 135, 135, 135, + 135, 135, 135, 135, 135, 135, 135, 135, 135, 137, + 137, 137, 17, 137, 137, 137, 137, 137, 137, 137, + 137, 137, 137, 137, 137, 137, 7, 7, 7, 69, + 5, 134, 7, 7, 69, 92, 134, 73, 69, 10, + 10, 73, 73, 141, 141, 10, 10, 10, 10, 10, + 37, 37, 39, 92, 92, 36, 40, 39, 39, 39, + 94, 10, 39, 39, 39, 39, 39, 39, 39, 86, + 86, 86, 10, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 26, 16, 67, 67, + 55, 67, 55, 147, 147, 68, 68, 68, 16, 16, + 16, 16, 16, 16, 13, 16, 16, 16, 136, 146, + 147, 111, 12, 76, 76, 76, 2, 143, 2, 26, + 52, 13, 26, 13, 13, 13, 13, 147, 13, 13, + 13, 13, 13, 13, 111, 13, 65, 12, 54, 53, + 118, 90, 65, 88, 56, 56, 56, 65, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, + 56, 12, 139, 65, 91, 20, 12, 85, 85, 85, + 26, 26, 24, 11, 19, 65, 26, 26, 26, 26, + 26, 63, 80, 80, 63, 63, 63, 63, 63, 63, + 28, 63, 30, 82, 8, 8, 23, 63, 96, 99, + 12, 127, 97, 32, 79, 63, 63, 63, 63, 97, + 124, 63, 63, 71, 122, 114, 97, 97, 14, 14, + 14, 72, 14, -1, -1, 63, -1, 14, 63, -1, + -1, -1, -1, -1, -1, 97, 14, -1, 14, -1, + -1, -1, -1, -1, -1, -1, -1, 12, 14, -1, + -1, 14, 8, 14, -1, -1, -1, -1, 97, -1, + -1, 97, 97, 97, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 93, -1, - -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 93, 93 + -1, -1, -1, -1, -1, -1, -1, -1, 8, 8, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, + -1, 8, -1, -1, 8, -1, 8, 8, -1, 8, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8, -1, 8 ); protected $gotoBase = array( - 0, 0, -236, 0, 0, 135, 0, 115, -139, 55, - -18, -118, -37, 125, 139, 128, 47, 65, 0, 0, - 6, 57, 0, -15, 0, 46, 0, 58, 0, -11, - -20, 0, 0, 110, 0, 0, -401, 133, 0, 0, - 0, 0, 0, 217, 0, 0, 174, 0, 0, 219, - 59, 41, 191, 81, 0, 0, 0, 0, 0, 0, - 109, 0, -96, 0, -41, -53, 0, -19, -26, -364, - 0, 4, -42, 0, 0, -16, -253, 0, 25, 0, - 0, 96, 5, 0, 50, 0, 52, 69, -93, 0, - 223, 0, 45, 122, 0, -10, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 118, 0, 0, -28, - 0, 0, 49, 0, 0, 0, -25, 0, -6, 0, - 0, 3, 0, 0, 0, 0, 0, 0, -121, -35, - 215, -49, 0, 68, 0, 0, 224, 0, 225, -4, - 48, 0, 0 + 0, 0, -281, 0, 0, 180, 0, 181, 106, 0, + -141, 54, 6, -19, 11, -253, 245, 170, 139, 45, + 69, 0, 0, 15, 56, 0, -10, 0, 58, 0, + 75, 0, 10, -23, 0, 0, 206, -369, 0, -344, + 197, 0, 0, 0, 0, 0, 93, 0, 0, 81, + 0, 0, 243, 77, 80, 235, 87, 0, 0, 0, + 0, 0, 0, 107, 0, -63, 0, -70, 17, -205, + 0, -2, -3, -363, 0, -115, 14, 0, 0, 9, + -234, 0, 36, 0, 0, 110, 12, 0, 61, 0, + 57, 74, -169, 0, 196, 0, 63, 128, 0, 5, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 51, 0, 0, 19, 0, 0, 0, 59, 0, + 0, 0, -22, 0, 18, 0, 0, 16, 0, 0, + 0, 0, 0, 0, -66, -65, 242, -48, 0, 73, + 0, -90, 0, 247, 0, 0, 240, 7, -116, 0, + 0 ); protected $gotoDefault = array( - -32768, 389, 577, 2, 578, 649, 657, 513, 409, 437, - 728, 875, 690, 772, 711, 712, 302, 340, 294, 300, - 498, 487, 380, 697, 352, 689, 377, 692, 351, 701, - 133, 514, 386, 705, 1, 707, 443, 738, 291, 715, - 292, 517, 717, 450, 719, 720, 297, 303, 304, 879, - 459, 484, 730, 203, 452, 732, 290, 733, 741, 331, - 295, 363, 520, 494, 475, 509, 410, 365, 481, 228, - 461, 983, 764, 372, 360, 778, 278, 786, 561, 794, - 797, 411, 412, 370, 809, 371, 819, 813, 991, 364, - 824, 353, 831, 1023, 355, 835, 838, 341, 500, 329, - 842, 843, 4, 847, 533, 534, 862, 241, 382, 871, - 350, 885, 344, 952, 954, 445, 379, 965, 359, 521, - 387, 970, 1027, 348, 413, 366, 268, 282, 244, 414, - 431, 249, 415, 367, 1030, 318, 1052, 432, 1060, 1068, - 275, 315, 478 + -32768, 404, 582, 2, 583, 654, 662, 527, 421, 552, + 422, 448, 323, 736, 890, 756, 718, 719, 720, 309, + 349, 300, 307, 511, 500, 395, 705, 368, 697, 392, + 700, 367, 709, 136, 528, 400, 713, 1, 715, 454, + 747, 297, 723, 298, 531, 725, 461, 727, 728, 303, + 310, 311, 894, 469, 497, 740, 206, 463, 741, 296, + 742, 750, 320, 301, 378, 401, 315, 871, 487, 318, + 363, 381, 494, 489, 471, 998, 775, 387, 376, 789, + 284, 797, 580, 805, 808, 423, 424, 385, 820, 386, + 831, 825, 1006, 380, 836, 369, 843, 1038, 371, 847, + 220, 850, 344, 512, 337, 855, 856, 6, 861, 543, + 544, 7, 243, 397, 885, 513, 366, 900, 352, 967, + 969, 456, 393, 980, 375, 534, 402, 985, 1042, 364, + 425, 382, 271, 288, 246, 426, 443, 251, 427, 383, + 1045, 1052, 326, 1068, 268, 29, 1080, 1088, 280, 475, + 491 ); protected $ruleToNonTerminal = array( @@ -710,49 +734,51 @@ class Php7 extends \PhpParser\ParserAbstract 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 8, 8, 9, 10, 10, 11, 11, 12, - 12, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 17, 17, 18, 18, 18, 18, 20, 22, - 22, 16, 24, 24, 21, 26, 26, 23, 23, 25, - 25, 27, 27, 19, 28, 28, 29, 31, 32, 32, - 33, 34, 34, 36, 35, 35, 35, 35, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 13, 13, 56, 56, 59, 59, 58, 57, - 57, 50, 61, 61, 62, 62, 63, 63, 14, 15, - 15, 15, 66, 66, 66, 67, 67, 70, 70, 68, - 68, 72, 73, 73, 44, 44, 52, 52, 55, 55, - 55, 54, 74, 74, 75, 45, 45, 45, 45, 76, - 76, 77, 77, 78, 78, 42, 42, 38, 38, 79, - 40, 40, 80, 39, 39, 41, 41, 51, 51, 51, - 51, 64, 64, 83, 83, 84, 84, 86, 86, 87, - 87, 87, 85, 85, 65, 65, 88, 88, 89, 89, - 90, 90, 90, 47, 91, 91, 92, 48, 94, 94, - 95, 95, 69, 69, 96, 96, 96, 96, 101, 101, - 102, 102, 103, 103, 103, 103, 103, 104, 105, 105, - 100, 100, 97, 97, 99, 99, 107, 107, 106, 106, - 106, 106, 106, 106, 98, 108, 108, 109, 109, 49, - 110, 110, 43, 43, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 117, 111, 111, - 116, 116, 119, 120, 120, 121, 122, 122, 122, 71, - 71, 60, 60, 60, 112, 112, 112, 124, 124, 113, - 113, 115, 115, 115, 118, 118, 129, 129, 129, 82, - 131, 131, 131, 114, 114, 114, 114, 114, 114, 114, - 114, 114, 114, 114, 114, 114, 114, 114, 114, 46, - 46, 127, 127, 127, 123, 123, 123, 132, 132, 132, - 132, 132, 132, 53, 53, 53, 93, 93, 93, 93, - 134, 126, 126, 126, 126, 126, 126, 125, 125, 125, - 133, 133, 133, 133, 81, 135, 135, 136, 136, 136, - 136, 136, 130, 137, 137, 138, 138, 138, 138, 138, - 128, 128, 128, 128, 140, 141, 139, 139, 139, 139, - 139, 139, 139, 142, 142, 142, 142 + 7, 7, 8, 9, 10, 10, 11, 12, 13, 13, + 14, 14, 15, 15, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 20, 20, 21, 21, 21, + 21, 23, 25, 25, 19, 27, 27, 24, 29, 29, + 26, 26, 28, 28, 30, 30, 22, 31, 31, 32, + 34, 35, 35, 36, 37, 37, 39, 38, 38, 38, + 38, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 16, 16, 59, 59, + 62, 62, 61, 60, 60, 53, 64, 64, 65, 65, + 66, 66, 67, 67, 17, 18, 18, 18, 70, 70, + 70, 71, 71, 74, 74, 72, 72, 76, 77, 77, + 47, 47, 55, 55, 58, 58, 58, 57, 78, 78, + 79, 48, 48, 48, 48, 80, 80, 81, 81, 82, + 82, 45, 45, 41, 41, 83, 43, 43, 84, 42, + 42, 44, 44, 54, 54, 54, 54, 68, 68, 87, + 87, 88, 88, 88, 90, 90, 91, 91, 91, 89, + 89, 69, 69, 92, 92, 93, 93, 94, 94, 94, + 50, 95, 95, 96, 51, 98, 98, 99, 99, 100, + 100, 73, 101, 101, 101, 101, 101, 106, 106, 107, + 107, 108, 108, 108, 108, 108, 109, 110, 110, 105, + 105, 102, 102, 104, 104, 112, 112, 111, 111, 111, + 111, 111, 111, 103, 113, 113, 115, 114, 114, 52, + 116, 116, 46, 46, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 33, 33, 123, 117, 117, + 122, 122, 125, 126, 126, 127, 128, 128, 128, 75, + 75, 63, 63, 63, 118, 118, 118, 130, 130, 119, + 119, 121, 121, 121, 124, 124, 135, 135, 135, 86, + 137, 137, 137, 120, 120, 120, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, 120, 49, + 49, 133, 133, 133, 129, 129, 129, 138, 138, 138, + 138, 138, 138, 56, 56, 56, 97, 97, 97, 97, + 141, 140, 132, 132, 132, 132, 132, 132, 131, 131, + 131, 139, 139, 139, 139, 85, 142, 142, 143, 143, + 143, 143, 143, 143, 143, 136, 145, 145, 144, 144, + 146, 146, 146, 146, 146, 134, 134, 134, 134, 148, + 149, 147, 147, 147, 147, 147, 147, 147, 150, 150, + 150, 150 ); protected $ruleToLength = array( @@ -764,28 +790,29 @@ class Php7 extends \PhpParser\ParserAbstract 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 0, 1, 0, - 1, 1, 1, 1, 1, 3, 5, 4, 3, 4, - 2, 3, 1, 1, 7, 8, 6, 7, 2, 3, - 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, - 2, 1, 2, 2, 3, 1, 3, 2, 3, 1, - 3, 2, 0, 1, 1, 1, 1, 1, 3, 7, - 10, 5, 7, 9, 5, 3, 3, 3, 3, 3, - 3, 1, 2, 5, 7, 9, 5, 6, 3, 3, - 2, 1, 1, 1, 0, 2, 1, 3, 8, 0, - 4, 2, 1, 3, 0, 1, 0, 1, 10, 7, - 6, 5, 1, 2, 2, 0, 2, 0, 2, 0, - 2, 2, 1, 3, 1, 4, 1, 4, 1, 1, - 4, 2, 1, 3, 3, 3, 4, 4, 5, 0, - 2, 4, 3, 1, 1, 1, 4, 0, 2, 5, - 0, 2, 6, 0, 2, 0, 3, 1, 2, 1, - 1, 2, 0, 1, 3, 4, 6, 1, 2, 1, - 1, 1, 0, 1, 0, 2, 2, 4, 1, 3, - 1, 2, 2, 2, 3, 1, 1, 2, 3, 1, - 1, 3, 2, 0, 3, 4, 9, 3, 1, 3, - 0, 2, 4, 5, 4, 4, 4, 3, 1, 1, - 1, 3, 1, 1, 0, 1, 1, 2, 1, 1, - 1, 1, 1, 1, 2, 1, 3, 1, 3, 2, + 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, + 0, 1, 0, 1, 1, 1, 1, 1, 3, 5, + 4, 3, 4, 2, 3, 1, 1, 7, 8, 6, + 7, 2, 3, 1, 2, 3, 1, 2, 3, 1, + 1, 3, 1, 2, 1, 2, 2, 3, 1, 3, + 2, 3, 1, 3, 2, 0, 1, 1, 1, 1, + 1, 3, 7, 10, 5, 7, 9, 5, 3, 3, + 3, 3, 3, 3, 1, 2, 5, 7, 9, 6, + 5, 6, 3, 3, 2, 1, 1, 1, 0, 2, + 1, 3, 8, 0, 4, 2, 1, 3, 0, 1, + 0, 1, 3, 1, 8, 7, 6, 5, 1, 2, + 2, 0, 2, 0, 2, 0, 2, 2, 1, 3, + 1, 4, 1, 4, 1, 1, 4, 2, 1, 3, + 3, 3, 4, 4, 5, 0, 2, 4, 3, 1, + 1, 1, 4, 0, 2, 5, 0, 2, 6, 0, + 2, 0, 3, 1, 2, 1, 1, 2, 0, 1, + 3, 4, 6, 4, 1, 2, 1, 1, 1, 0, + 1, 0, 2, 2, 4, 1, 3, 1, 2, 2, + 2, 3, 1, 1, 2, 3, 1, 1, 3, 2, + 0, 1, 3, 4, 9, 3, 1, 1, 3, 0, + 2, 4, 5, 4, 4, 4, 3, 1, 1, 1, + 1, 1, 1, 0, 1, 1, 2, 1, 1, 1, + 1, 1, 1, 2, 1, 3, 1, 1, 3, 2, 3, 1, 0, 1, 1, 3, 3, 3, 4, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, @@ -794,7 +821,7 @@ class Php7 extends \PhpParser\ParserAbstract 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 4, 3, 4, 4, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, - 2, 1, 2, 4, 2, 10, 11, 7, 3, 2, + 2, 1, 2, 4, 2, 8, 9, 7, 3, 2, 0, 4, 2, 1, 3, 2, 2, 2, 4, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 0, 3, 0, 1, 1, 0, 1, 1, 3, 3, 3, @@ -802,2067 +829,1612 @@ class Php7 extends \PhpParser\ParserAbstract 1, 1, 1, 1, 1, 3, 2, 3, 3, 0, 1, 1, 3, 1, 1, 3, 1, 1, 4, 4, 4, 1, 4, 1, 1, 3, 1, 4, 2, 2, - 3, 1, 4, 4, 3, 3, 3, 1, 3, 1, - 1, 3, 1, 1, 4, 3, 1, 1, 1, 3, - 3, 0, 1, 3, 1, 3, 1, 4, 2, 0, - 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, - 3, 6, 3, 1, 1, 2, 1 + 1, 3, 1, 4, 4, 3, 3, 3, 1, 3, + 1, 1, 3, 1, 1, 4, 3, 1, 1, 2, + 1, 3, 4, 3, 0, 1, 1, 1, 3, 1, + 3, 1, 4, 2, 0, 2, 2, 1, 2, 1, + 1, 1, 4, 3, 3, 3, 6, 3, 1, 1, + 2, 1 ); - protected function reduceRule0() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule1() { - $this->semValue = $this->handleNamespaces($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule2() { - if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; - } - - protected function reduceRule3() { - $this->semValue = array(); - } - - protected function reduceRule4() { - $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; - if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule5() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule6() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule7() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule8() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule9() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule10() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule11() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule12() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule13() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule14() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule15() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule16() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule17() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule18() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule19() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule20() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule21() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule22() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule23() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule24() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule25() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule26() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule27() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule28() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule29() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule30() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule31() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule32() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule33() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule34() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule35() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule36() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule37() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule38() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule39() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule40() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule41() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule42() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule43() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule44() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule45() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule46() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule47() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule48() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule49() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule50() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule51() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule52() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule53() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule54() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule55() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule56() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule57() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule58() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule59() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule60() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule61() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule62() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule63() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule64() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule65() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule66() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule67() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule68() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule69() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule70() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule71() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule72() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule73() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule74() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule75() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule76() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule77() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule78() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule79() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule80() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule81() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule82() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule83() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule84() { - $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule85() { - /* nothing */ - } - - protected function reduceRule86() { - /* nothing */ - } - - protected function reduceRule87() { - /* nothing */ - } - - protected function reduceRule88() { - $this->emitError(new Error('A trailing comma is not allowed here', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); - } - - protected function reduceRule89() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule90() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule91() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule92() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule93() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule94() { - $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule95() { - $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(3-2)], null, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); + protected function initReduceCallbacks() { + $this->reduceCallbacks = [ + 0 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 1 => function ($stackPos) { + $this->semValue = $this->handleNamespaces($this->semStack[$stackPos-(1-1)]); + }, + 2 => function ($stackPos) { + if (is_array($this->semStack[$stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); } else { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }; + }, + 3 => function ($stackPos) { + $this->semValue = array(); + }, + 4 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 5 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 6 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 7 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 8 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 9 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 10 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 11 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 12 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 13 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 14 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 15 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 16 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 17 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 18 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 19 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 20 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 21 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 22 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 23 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 24 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 25 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 26 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 27 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 28 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 29 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 30 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 31 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 32 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 33 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 34 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 35 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 36 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 37 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 38 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 39 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 40 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 41 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 42 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 43 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 44 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 45 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 46 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 47 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 48 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 49 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 50 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 51 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 52 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 53 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 54 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 55 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 56 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 57 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 58 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 59 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 60 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 61 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 62 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 63 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 64 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 65 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 66 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 67 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 68 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 69 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 70 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 71 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 72 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 73 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 74 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 75 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 76 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 77 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 78 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 79 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 80 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 81 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 82 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 83 => function ($stackPos) { + $this->semValue = new Node\Identifier($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 84 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 85 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 86 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 87 => function ($stackPos) { + $this->semValue = new Expr\Variable(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 88 => function ($stackPos) { + /* nothing */ + }, + 89 => function ($stackPos) { + /* nothing */ + }, + 90 => function ($stackPos) { + /* nothing */ + }, + 91 => function ($stackPos) { + $this->emitError(new Error('A trailing comma is not allowed here', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes)); + }, + 92 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 93 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 94 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 95 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 96 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 97 => function ($stackPos) { + $this->semValue = new Stmt\HaltCompiler($this->lexer->handleHaltCompiler(), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 98 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos-(3-2)], null, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_SEMICOLON); $this->checkNamespace($this->semValue); - } - - protected function reduceRule96() { - $this->semValue = new Stmt\Namespace_($this->semStack[$this->stackPos-(5-2)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); + }, + 99 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_($this->semStack[$stackPos-(5-2)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); - } - - protected function reduceRule97() { - $this->semValue = new Stmt\Namespace_(null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); + }, + 100 => function ($stackPos) { + $this->semValue = new Stmt\Namespace_(null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); $this->semValue->setAttribute('kind', Stmt\Namespace_::KIND_BRACED); $this->checkNamespace($this->semValue); - } - - protected function reduceRule98() { - $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule99() { - $this->semValue = new Stmt\Use_($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule100() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule101() { - $this->semValue = new Stmt\Const_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule102() { - $this->semValue = Stmt\Use_::TYPE_FUNCTION; - } - - protected function reduceRule103() { - $this->semValue = Stmt\Use_::TYPE_CONSTANT; - } - - protected function reduceRule104() { - $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], $this->semStack[$this->stackPos-(7-2)], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - } - - protected function reduceRule105() { - $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(8-4)], $this->startAttributeStack[$this->stackPos-(8-4)] + $this->endAttributeStack[$this->stackPos-(8-4)]), $this->semStack[$this->stackPos-(8-7)], $this->semStack[$this->stackPos-(8-2)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); - } - - protected function reduceRule106() { - $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-2)] + $this->endAttributeStack[$this->stackPos-(6-2)]), $this->semStack[$this->stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - } - - protected function reduceRule107() { - $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$this->stackPos-(7-3)], $this->startAttributeStack[$this->stackPos-(7-3)] + $this->endAttributeStack[$this->stackPos-(7-3)]), $this->semStack[$this->stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - } - - protected function reduceRule108() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule109() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule110() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule111() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule112() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule113() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule114() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule115() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule116() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } + }, + 101 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(3-2)], Stmt\Use_::TYPE_NORMAL, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 102 => function ($stackPos) { + $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 103 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 104 => function ($stackPos) { + $this->semValue = new Stmt\Const_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 105 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_FUNCTION; + }, + 106 => function ($stackPos) { + $this->semValue = Stmt\Use_::TYPE_CONSTANT; + }, + 107 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(7-3)], $this->startAttributeStack[$stackPos-(7-3)] + $this->endAttributeStack[$stackPos-(7-3)]), $this->semStack[$stackPos-(7-6)], $this->semStack[$stackPos-(7-2)], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 108 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(8-4)], $this->startAttributeStack[$stackPos-(8-4)] + $this->endAttributeStack[$stackPos-(8-4)]), $this->semStack[$stackPos-(8-7)], $this->semStack[$stackPos-(8-2)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 109 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(6-2)], $this->startAttributeStack[$stackPos-(6-2)] + $this->endAttributeStack[$stackPos-(6-2)]), $this->semStack[$stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 110 => function ($stackPos) { + $this->semValue = new Stmt\GroupUse(new Name($this->semStack[$stackPos-(7-3)], $this->startAttributeStack[$stackPos-(7-3)] + $this->endAttributeStack[$stackPos-(7-3)]), $this->semStack[$stackPos-(7-6)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 111 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 112 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 113 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 114 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 115 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 116 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 117 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 118 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 119 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 120 => function ($stackPos) { + $this->semValue = new Stmt\UseUse($this->semStack[$stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $stackPos-(1-1)); + }, + 121 => function ($stackPos) { + $this->semValue = new Stmt\UseUse($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $stackPos-(3-3)); + }, + 122 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 123 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 124 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; + }, + 125 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; $this->semValue->type = $this->semStack[$stackPos-(2-1)]; + }, + 126 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 127 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 128 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 129 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 130 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 131 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 132 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 133 => function ($stackPos) { + $this->semValue = new Node\Const_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 134 => function ($stackPos) { + if (is_array($this->semStack[$stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); } else { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }; + }, + 135 => function ($stackPos) { + $this->semValue = array(); + }, + 136 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 137 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 138 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 139 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 140 => function ($stackPos) { + throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 141 => function ($stackPos) { + + if ($this->semStack[$stackPos-(3-2)]) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; $attrs = $this->startAttributeStack[$stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; + } else { + $startAttributes = $this->startAttributeStack[$stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $this->semValue = null; }; + if (null === $this->semValue) { $this->semValue = array(); } + } - protected function reduceRule117() { - $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(1-1)], null, Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(1-1)); - } - - protected function reduceRule118() { - $this->semValue = new Stmt\UseUse($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkUseUse($this->semValue, $this->stackPos-(3-3)); - } - - protected function reduceRule119() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule120() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule121() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $this->semValue->type = Stmt\Use_::TYPE_NORMAL; - } - - protected function reduceRule122() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; $this->semValue->type = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule123() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule124() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule125() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule126() { - $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule127() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule128() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule129() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule130() { - $this->semValue = new Node\Const_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule131() { - if (is_array($this->semStack[$this->stackPos-(2-2)])) { $this->semValue = array_merge($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); } else { $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; }; - } - - protected function reduceRule132() { - $this->semValue = array(); - } - - protected function reduceRule133() { - $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $nop = null; }; - if ($nop !== null) { $this->semStack[$this->stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule134() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule135() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule136() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule137() { - throw new Error('__HALT_COMPILER() can only be used from the outermost scope', $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule138() { - - if ($this->semStack[$this->stackPos-(3-2)]) { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; $attrs = $this->startAttributeStack[$this->stackPos-(3-1)]; $stmts = $this->semValue; if (!empty($attrs['comments'])) {$stmts[0]->setAttribute('comments', array_merge($attrs['comments'], $stmts[0]->getAttribute('comments', []))); }; - } else { - $startAttributes = $this->startAttributeStack[$this->stackPos-(3-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; - if (null === $this->semValue) { $this->semValue = array(); } - } - - } - - protected function reduceRule139() { - $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(7-3)], ['stmts' => is_array($this->semStack[$this->stackPos-(7-5)]) ? $this->semStack[$this->stackPos-(7-5)] : array($this->semStack[$this->stackPos-(7-5)]), 'elseifs' => $this->semStack[$this->stackPos-(7-6)], 'else' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - } - - protected function reduceRule140() { - $this->semValue = new Stmt\If_($this->semStack[$this->stackPos-(10-3)], ['stmts' => $this->semStack[$this->stackPos-(10-6)], 'elseifs' => $this->semStack[$this->stackPos-(10-7)], 'else' => $this->semStack[$this->stackPos-(10-8)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); - } - - protected function reduceRule141() { - $this->semValue = new Stmt\While_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule142() { - $this->semValue = new Stmt\Do_($this->semStack[$this->stackPos-(7-5)], is_array($this->semStack[$this->stackPos-(7-2)]) ? $this->semStack[$this->stackPos-(7-2)] : array($this->semStack[$this->stackPos-(7-2)]), $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - } - - protected function reduceRule143() { - $this->semValue = new Stmt\For_(['init' => $this->semStack[$this->stackPos-(9-3)], 'cond' => $this->semStack[$this->stackPos-(9-5)], 'loop' => $this->semStack[$this->stackPos-(9-7)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); - } - - protected function reduceRule144() { - $this->semValue = new Stmt\Switch_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule145() { - $this->semValue = new Stmt\Break_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule146() { - $this->semValue = new Stmt\Continue_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule147() { - $this->semValue = new Stmt\Return_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule148() { - $this->semValue = new Stmt\Global_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule149() { - $this->semValue = new Stmt\Static_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule150() { - $this->semValue = new Stmt\Echo_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule151() { - $this->semValue = new Stmt\InlineHTML($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule152() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule153() { - $this->semValue = new Stmt\Unset_($this->semStack[$this->stackPos-(5-3)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule154() { - $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(7-3)], $this->semStack[$this->stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$this->stackPos-(7-5)][1], 'stmts' => $this->semStack[$this->stackPos-(7-7)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - } - - protected function reduceRule155() { - $this->semValue = new Stmt\Foreach_($this->semStack[$this->stackPos-(9-3)], $this->semStack[$this->stackPos-(9-7)][0], ['keyVar' => $this->semStack[$this->stackPos-(9-5)], 'byRef' => $this->semStack[$this->stackPos-(9-7)][1], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); - } - - protected function reduceRule156() { - $this->semValue = new Stmt\Declare_($this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule157() { - $this->semValue = new Stmt\TryCatch($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-5)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); - } - - protected function reduceRule158() { - $this->semValue = new Stmt\Throw_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule159() { - $this->semValue = new Stmt\Goto_($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule160() { - $this->semValue = new Stmt\Label($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule161() { - $this->semValue = array(); /* means: no statement */ - } - - protected function reduceRule162() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule163() { - $startAttributes = $this->startAttributeStack[$this->stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop(['comments' => $startAttributes['comments']]); } else { $this->semValue = null; }; - if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ - } - - protected function reduceRule164() { - $this->semValue = array(); - } - - protected function reduceRule165() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule166() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule167() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule168() { - $this->semValue = new Stmt\Catch_($this->semStack[$this->stackPos-(8-3)], substr($this->semStack[$this->stackPos-(8-4)], 1), $this->semStack[$this->stackPos-(8-7)], $this->startAttributeStack[$this->stackPos-(8-1)] + $this->endAttributes); - } - - protected function reduceRule169() { - $this->semValue = null; - } - - protected function reduceRule170() { - $this->semValue = new Stmt\Finally_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule171() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule172() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule173() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule174() { - $this->semValue = false; - } - - protected function reduceRule175() { - $this->semValue = true; - } - - protected function reduceRule176() { - $this->semValue = false; - } - - protected function reduceRule177() { - $this->semValue = true; - } - - protected function reduceRule178() { - $this->semValue = new Stmt\Function_($this->semStack[$this->stackPos-(10-3)], ['byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-5)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); - } - - protected function reduceRule179() { - $this->semValue = new Stmt\Class_($this->semStack[$this->stackPos-(7-2)], ['type' => $this->semStack[$this->stackPos-(7-1)], 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes); - $this->checkClass($this->semValue, $this->stackPos-(7-2)); - } - - protected function reduceRule180() { - $this->semValue = new Stmt\Interface_($this->semStack[$this->stackPos-(6-2)], ['extends' => $this->semStack[$this->stackPos-(6-3)], 'stmts' => $this->semStack[$this->stackPos-(6-5)]], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - $this->checkInterface($this->semValue, $this->stackPos-(6-2)); - } - - protected function reduceRule181() { - $this->semValue = new Stmt\Trait_($this->semStack[$this->stackPos-(5-2)], ['stmts' => $this->semStack[$this->stackPos-(5-4)]], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule182() { - $this->semValue = 0; - } - - protected function reduceRule183() { - $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; - } - - protected function reduceRule184() { - $this->semValue = Stmt\Class_::MODIFIER_FINAL; - } - - protected function reduceRule185() { - $this->semValue = null; - } - - protected function reduceRule186() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule187() { - $this->semValue = array(); - } - - protected function reduceRule188() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule189() { - $this->semValue = array(); - } - - protected function reduceRule190() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule191() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule192() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule193() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule194() { - $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule195() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule196() { - $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule197() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule198() { - $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule199() { - $this->semValue = null; - } - - protected function reduceRule200() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule201() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule202() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule203() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule204() { - $this->semValue = new Stmt\DeclareDeclare($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule205() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule206() { - $this->semValue = $this->semStack[$this->stackPos-(4-3)]; - } - - protected function reduceRule207() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule208() { - $this->semValue = $this->semStack[$this->stackPos-(5-3)]; - } - - protected function reduceRule209() { - $this->semValue = array(); - } - - protected function reduceRule210() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule211() { - $this->semValue = new Stmt\Case_($this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule212() { - $this->semValue = new Stmt\Case_(null, $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule213() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule214() { - $this->semValue = $this->semStack[$this->stackPos]; - } - - protected function reduceRule215() { - $this->semValue = is_array($this->semStack[$this->stackPos-(1-1)]) ? $this->semStack[$this->stackPos-(1-1)] : array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule216() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule217() { - $this->semValue = array(); - } - - protected function reduceRule218() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule219() { - $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(5-3)], is_array($this->semStack[$this->stackPos-(5-5)]) ? $this->semStack[$this->stackPos-(5-5)] : array($this->semStack[$this->stackPos-(5-5)]), $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule220() { - $this->semValue = array(); - } - - protected function reduceRule221() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule222() { - $this->semValue = new Stmt\ElseIf_($this->semStack[$this->stackPos-(6-3)], $this->semStack[$this->stackPos-(6-6)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - } - - protected function reduceRule223() { - $this->semValue = null; - } - - protected function reduceRule224() { - $this->semValue = new Stmt\Else_(is_array($this->semStack[$this->stackPos-(2-2)]) ? $this->semStack[$this->stackPos-(2-2)] : array($this->semStack[$this->stackPos-(2-2)]), $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule225() { - $this->semValue = null; - } - - protected function reduceRule226() { - $this->semValue = new Stmt\Else_($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule227() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); - } - - protected function reduceRule228() { - $this->semValue = array($this->semStack[$this->stackPos-(2-2)], true); - } - - protected function reduceRule229() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); - } - - protected function reduceRule230() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)], false); - } - - protected function reduceRule231() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule232() { - $this->semValue = array(); - } - - protected function reduceRule233() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule234() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule235() { - $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(4-4)], 1), null, $this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-2)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); - } - - protected function reduceRule236() { - $this->semValue = new Node\Param(substr($this->semStack[$this->stackPos-(6-4)], 1), $this->semStack[$this->stackPos-(6-6)], $this->semStack[$this->stackPos-(6-1)], $this->semStack[$this->stackPos-(6-2)], $this->semStack[$this->stackPos-(6-3)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); - } - - protected function reduceRule237() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule238() { - $this->semValue = new Node\NullableType($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule239() { - $this->semValue = $this->handleBuiltinTypes($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule240() { - $this->semValue = 'array'; - } - - protected function reduceRule241() { - $this->semValue = 'callable'; - } - - protected function reduceRule242() { - $this->semValue = null; - } - - protected function reduceRule243() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule244() { - $this->semValue = null; - } - - protected function reduceRule245() { - $this->semValue = $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule246() { - $this->semValue = array(); - } - - protected function reduceRule247() { - $this->semValue = $this->semStack[$this->stackPos-(4-2)]; - } - - protected function reduceRule248() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule249() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule250() { - $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(1-1)], false, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule251() { - $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], true, false, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule252() { - $this->semValue = new Node\Arg($this->semStack[$this->stackPos-(2-2)], false, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule253() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule254() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule255() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule256() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule257() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule258() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule259() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule260() { - $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule261() { - $this->semValue = new Stmt\StaticVar(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule262() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule263() { - $this->semValue = array(); - } - - protected function reduceRule264() { - $this->semValue = new Stmt\Property($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $this->stackPos-(3-1)); - } - - protected function reduceRule265() { - $this->semValue = new Stmt\ClassConst($this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-1)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); $this->checkClassConst($this->semValue, $this->stackPos-(4-1)); - } - - protected function reduceRule266() { - $this->semValue = new Stmt\ClassMethod($this->semStack[$this->stackPos-(9-4)], ['type' => $this->semStack[$this->stackPos-(9-1)], 'byRef' => $this->semStack[$this->stackPos-(9-3)], 'params' => $this->semStack[$this->stackPos-(9-6)], 'returnType' => $this->semStack[$this->stackPos-(9-8)], 'stmts' => $this->semStack[$this->stackPos-(9-9)]], $this->startAttributeStack[$this->stackPos-(9-1)] + $this->endAttributes); - $this->checkClassMethod($this->semValue, $this->stackPos-(9-1)); - } - - protected function reduceRule267() { - $this->semValue = new Stmt\TraitUse($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule268() { - $this->semValue = array(); - } - - protected function reduceRule269() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule270() { - $this->semValue = array(); - } - - protected function reduceRule271() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule272() { - $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule273() { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(5-1)][0], $this->semStack[$this->stackPos-(5-1)][1], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-4)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule274() { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], $this->semStack[$this->stackPos-(4-3)], null, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule275() { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule276() { - $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$this->stackPos-(4-1)][0], $this->semStack[$this->stackPos-(4-1)][1], null, $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule277() { - $this->semValue = array($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)]); - } - - protected function reduceRule278() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule279() { - $this->semValue = array(null, $this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule280() { - $this->semValue = null; - } - - protected function reduceRule281() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule282() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule283() { - $this->semValue = 0; - } - - protected function reduceRule284() { - $this->semValue = 0; - } - - protected function reduceRule285() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule286() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule287() { - $this->checkModifier($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->stackPos-(2-2)); $this->semValue = $this->semStack[$this->stackPos-(2-1)] | $this->semStack[$this->stackPos-(2-2)]; - } - - protected function reduceRule288() { - $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; - } - - protected function reduceRule289() { - $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; - } - - protected function reduceRule290() { - $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; - } - - protected function reduceRule291() { - $this->semValue = Stmt\Class_::MODIFIER_STATIC; - } - - protected function reduceRule292() { - $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; - } - - protected function reduceRule293() { - $this->semValue = Stmt\Class_::MODIFIER_FINAL; - } - - protected function reduceRule294() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule295() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule296() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule297() { - $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(1-1)], 1), null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule298() { - $this->semValue = new Stmt\PropertyProperty(substr($this->semStack[$this->stackPos-(3-1)], 1), $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule299() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule300() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule301() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule302() { - $this->semValue = array(); - } - - protected function reduceRule303() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule304() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule305() { - $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule306() { - $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule307() { - $this->semValue = new Expr\Assign($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule308() { - $this->semValue = new Expr\AssignRef($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule309() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule310() { - $this->semValue = new Expr\Clone_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule311() { - $this->semValue = new Expr\AssignOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule312() { - $this->semValue = new Expr\AssignOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule313() { - $this->semValue = new Expr\AssignOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule314() { - $this->semValue = new Expr\AssignOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule315() { - $this->semValue = new Expr\AssignOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule316() { - $this->semValue = new Expr\AssignOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule317() { - $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule318() { - $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule319() { - $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule320() { - $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule321() { - $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule322() { - $this->semValue = new Expr\AssignOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule323() { - $this->semValue = new Expr\PostInc($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule324() { - $this->semValue = new Expr\PreInc($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule325() { - $this->semValue = new Expr\PostDec($this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule326() { - $this->semValue = new Expr\PreDec($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule327() { - $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule328() { - $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule329() { - $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule330() { - $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule331() { - $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule332() { - $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule333() { - $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule334() { - $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule335() { - $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule336() { - $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule337() { - $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule338() { - $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule339() { - $this->semValue = new Expr\BinaryOp\Div($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule340() { - $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule341() { - $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule342() { - $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule343() { - $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule344() { - $this->semValue = new Expr\UnaryPlus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule345() { - $this->semValue = new Expr\UnaryMinus($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule346() { - $this->semValue = new Expr\BooleanNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule347() { - $this->semValue = new Expr\BitwiseNot($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule348() { - $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule349() { - $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule350() { - $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule351() { - $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule352() { - $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule353() { - $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule354() { - $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule355() { - $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule356() { - $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule357() { - $this->semValue = new Expr\Instanceof_($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule358() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule359() { - $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(5-1)], $this->semStack[$this->stackPos-(5-3)], $this->semStack[$this->stackPos-(5-5)], $this->startAttributeStack[$this->stackPos-(5-1)] + $this->endAttributes); - } - - protected function reduceRule360() { - $this->semValue = new Expr\Ternary($this->semStack[$this->stackPos-(4-1)], null, $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule361() { - $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule362() { - $this->semValue = new Expr\Isset_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule363() { - $this->semValue = new Expr\Empty_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule364() { - $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule365() { - $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule366() { - $this->semValue = new Expr\Eval_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule367() { - $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule368() { - $this->semValue = new Expr\Include_($this->semStack[$this->stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule369() { - $this->semValue = new Expr\Cast\Int_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule370() { - $this->semValue = new Expr\Cast\Double($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule371() { - $this->semValue = new Expr\Cast\String_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule372() { - $this->semValue = new Expr\Cast\Array_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule373() { - $this->semValue = new Expr\Cast\Object_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule374() { - $this->semValue = new Expr\Cast\Bool_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule375() { - $this->semValue = new Expr\Cast\Unset_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule376() { - $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; - $attrs['kind'] = strtolower($this->semStack[$this->stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; - $this->semValue = new Expr\Exit_($this->semStack[$this->stackPos-(2-2)], $attrs); - } - - protected function reduceRule377() { - $this->semValue = new Expr\ErrorSuppress($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule378() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule379() { - $this->semValue = new Expr\ShellExec($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule380() { - $this->semValue = new Expr\Print_($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule381() { - $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule382() { - $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(2-2)], null, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule383() { - $this->semValue = new Expr\Yield_($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-2)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule384() { - $this->semValue = new Expr\YieldFrom($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule385() { - $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$this->stackPos-(10-2)], 'params' => $this->semStack[$this->stackPos-(10-4)], 'uses' => $this->semStack[$this->stackPos-(10-6)], 'returnType' => $this->semStack[$this->stackPos-(10-7)], 'stmts' => $this->semStack[$this->stackPos-(10-9)]], $this->startAttributeStack[$this->stackPos-(10-1)] + $this->endAttributes); - } - - protected function reduceRule386() { - $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$this->stackPos-(11-3)], 'params' => $this->semStack[$this->stackPos-(11-5)], 'uses' => $this->semStack[$this->stackPos-(11-7)], 'returnType' => $this->semStack[$this->stackPos-(11-8)], 'stmts' => $this->semStack[$this->stackPos-(11-10)]], $this->startAttributeStack[$this->stackPos-(11-1)] + $this->endAttributes); - } - - protected function reduceRule387() { - $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$this->stackPos-(7-3)], 'implements' => $this->semStack[$this->stackPos-(7-4)], 'stmts' => $this->semStack[$this->stackPos-(7-6)]], $this->startAttributeStack[$this->stackPos-(7-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(7-2)]); + }, + 142 => function ($stackPos) { + $this->semValue = new Stmt\If_($this->semStack[$stackPos-(7-3)], ['stmts' => is_array($this->semStack[$stackPos-(7-5)]) ? $this->semStack[$stackPos-(7-5)] : array($this->semStack[$stackPos-(7-5)]), 'elseifs' => $this->semStack[$stackPos-(7-6)], 'else' => $this->semStack[$stackPos-(7-7)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 143 => function ($stackPos) { + $this->semValue = new Stmt\If_($this->semStack[$stackPos-(10-3)], ['stmts' => $this->semStack[$stackPos-(10-6)], 'elseifs' => $this->semStack[$stackPos-(10-7)], 'else' => $this->semStack[$stackPos-(10-8)]], $this->startAttributeStack[$stackPos-(10-1)] + $this->endAttributes); + }, + 144 => function ($stackPos) { + $this->semValue = new Stmt\While_($this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 145 => function ($stackPos) { + $this->semValue = new Stmt\Do_($this->semStack[$stackPos-(7-5)], is_array($this->semStack[$stackPos-(7-2)]) ? $this->semStack[$stackPos-(7-2)] : array($this->semStack[$stackPos-(7-2)]), $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 146 => function ($stackPos) { + $this->semValue = new Stmt\For_(['init' => $this->semStack[$stackPos-(9-3)], 'cond' => $this->semStack[$stackPos-(9-5)], 'loop' => $this->semStack[$stackPos-(9-7)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 147 => function ($stackPos) { + $this->semValue = new Stmt\Switch_($this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 148 => function ($stackPos) { + $this->semValue = new Stmt\Break_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 149 => function ($stackPos) { + $this->semValue = new Stmt\Continue_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 150 => function ($stackPos) { + $this->semValue = new Stmt\Return_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 151 => function ($stackPos) { + $this->semValue = new Stmt\Global_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 152 => function ($stackPos) { + $this->semValue = new Stmt\Static_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 153 => function ($stackPos) { + $this->semValue = new Stmt\Echo_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 154 => function ($stackPos) { + $this->semValue = new Stmt\InlineHTML($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 155 => function ($stackPos) { + $this->semValue = new Stmt\Expression($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 156 => function ($stackPos) { + $this->semValue = new Stmt\Unset_($this->semStack[$stackPos-(5-3)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 157 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(7-3)], $this->semStack[$stackPos-(7-5)][0], ['keyVar' => null, 'byRef' => $this->semStack[$stackPos-(7-5)][1], 'stmts' => $this->semStack[$stackPos-(7-7)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + }, + 158 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(9-3)], $this->semStack[$stackPos-(9-7)][0], ['keyVar' => $this->semStack[$stackPos-(9-5)], 'byRef' => $this->semStack[$stackPos-(9-7)][1], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 159 => function ($stackPos) { + $this->semValue = new Stmt\Foreach_($this->semStack[$stackPos-(6-3)], new Expr\Error($this->startAttributeStack[$stackPos-(6-4)] + $this->endAttributeStack[$stackPos-(6-4)]), ['stmts' => $this->semStack[$stackPos-(6-6)]], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 160 => function ($stackPos) { + $this->semValue = new Stmt\Declare_($this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 161 => function ($stackPos) { + $this->semValue = new Stmt\TryCatch($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-5)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->checkTryCatch($this->semValue); + }, + 162 => function ($stackPos) { + $this->semValue = new Stmt\Throw_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 163 => function ($stackPos) { + $this->semValue = new Stmt\Goto_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 164 => function ($stackPos) { + $this->semValue = new Stmt\Label($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 165 => function ($stackPos) { + $this->semValue = array(); /* means: no statement */ + }, + 166 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 167 => function ($stackPos) { + $startAttributes = $this->startAttributeStack[$stackPos-(1-1)]; if (isset($startAttributes['comments'])) { $this->semValue = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $this->semValue = null; }; + if ($this->semValue === null) $this->semValue = array(); /* means: no statement */ + }, + 168 => function ($stackPos) { + $this->semValue = array(); + }, + 169 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 170 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 171 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 172 => function ($stackPos) { + $this->semValue = new Stmt\Catch_($this->semStack[$stackPos-(8-3)], $this->semStack[$stackPos-(8-4)], $this->semStack[$stackPos-(8-7)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 173 => function ($stackPos) { + $this->semValue = null; + }, + 174 => function ($stackPos) { + $this->semValue = new Stmt\Finally_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 175 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 176 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 177 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 178 => function ($stackPos) { + $this->semValue = false; + }, + 179 => function ($stackPos) { + $this->semValue = true; + }, + 180 => function ($stackPos) { + $this->semValue = false; + }, + 181 => function ($stackPos) { + $this->semValue = true; + }, + 182 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 183 => function ($stackPos) { + $this->semValue = []; + }, + 184 => function ($stackPos) { + $this->semValue = new Stmt\Function_($this->semStack[$stackPos-(8-3)], ['byRef' => $this->semStack[$stackPos-(8-2)], 'params' => $this->semStack[$stackPos-(8-5)], 'returnType' => $this->semStack[$stackPos-(8-7)], 'stmts' => $this->semStack[$stackPos-(8-8)]], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 185 => function ($stackPos) { + $this->semValue = new Stmt\Class_($this->semStack[$stackPos-(7-2)], ['type' => $this->semStack[$stackPos-(7-1)], 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + $this->checkClass($this->semValue, $stackPos-(7-2)); + }, + 186 => function ($stackPos) { + $this->semValue = new Stmt\Interface_($this->semStack[$stackPos-(6-2)], ['extends' => $this->semStack[$stackPos-(6-3)], 'stmts' => $this->semStack[$stackPos-(6-5)]], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + $this->checkInterface($this->semValue, $stackPos-(6-2)); + }, + 187 => function ($stackPos) { + $this->semValue = new Stmt\Trait_($this->semStack[$stackPos-(5-2)], ['stmts' => $this->semStack[$stackPos-(5-4)]], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 188 => function ($stackPos) { + $this->semValue = 0; + }, + 189 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + }, + 190 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + }, + 191 => function ($stackPos) { + $this->semValue = null; + }, + 192 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 193 => function ($stackPos) { + $this->semValue = array(); + }, + 194 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 195 => function ($stackPos) { + $this->semValue = array(); + }, + 196 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 197 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 198 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 199 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 200 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 201 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 202 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 203 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 204 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 205 => function ($stackPos) { + $this->semValue = null; + }, + 206 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 207 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 208 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 209 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 210 => function ($stackPos) { + $this->semValue = new Stmt\DeclareDeclare($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 211 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 212 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 213 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 214 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(5-3)]; + }, + 215 => function ($stackPos) { + $this->semValue = array(); + }, + 216 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 217 => function ($stackPos) { + $this->semValue = new Stmt\Case_($this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 218 => function ($stackPos) { + $this->semValue = new Stmt\Case_(null, $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 219 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 220 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 221 => function ($stackPos) { + $this->semValue = is_array($this->semStack[$stackPos-(1-1)]) ? $this->semStack[$stackPos-(1-1)] : array($this->semStack[$stackPos-(1-1)]); + }, + 222 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 223 => function ($stackPos) { + $this->semValue = array(); + }, + 224 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 225 => function ($stackPos) { + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(5-3)], is_array($this->semStack[$stackPos-(5-5)]) ? $this->semStack[$stackPos-(5-5)] : array($this->semStack[$stackPos-(5-5)]), $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 226 => function ($stackPos) { + $this->semValue = array(); + }, + 227 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 228 => function ($stackPos) { + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 229 => function ($stackPos) { + $this->semValue = null; + }, + 230 => function ($stackPos) { + $this->semValue = new Stmt\Else_(is_array($this->semStack[$stackPos-(2-2)]) ? $this->semStack[$stackPos-(2-2)] : array($this->semStack[$stackPos-(2-2)]), $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 231 => function ($stackPos) { + $this->semValue = null; + }, + 232 => function ($stackPos) { + $this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 233 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 234 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(2-2)], true); + }, + 235 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 236 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)], false); + }, + 237 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 238 => function ($stackPos) { + $this->semValue = array(); + }, + 239 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 240 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 241 => function ($stackPos) { + $this->semValue = new Node\Param($this->semStack[$stackPos-(4-4)], null, $this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); $this->checkParam($this->semValue); + }, + 242 => function ($stackPos) { + $this->semValue = new Node\Param($this->semStack[$stackPos-(6-4)], $this->semStack[$stackPos-(6-6)], $this->semStack[$stackPos-(6-1)], $this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-3)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->checkParam($this->semValue); + }, + 243 => function ($stackPos) { + $this->semValue = new Node\Param(new Expr\Error($this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes), null, $this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-2)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 244 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 245 => function ($stackPos) { + $this->semValue = new Node\NullableType($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 246 => function ($stackPos) { + $this->semValue = $this->handleBuiltinTypes($this->semStack[$stackPos-(1-1)]); + }, + 247 => function ($stackPos) { + $this->semValue = new Node\Identifier('array', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 248 => function ($stackPos) { + $this->semValue = new Node\Identifier('callable', $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 249 => function ($stackPos) { + $this->semValue = null; + }, + 250 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 251 => function ($stackPos) { + $this->semValue = null; + }, + 252 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-2)]; + }, + 253 => function ($stackPos) { + $this->semValue = array(); + }, + 254 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-2)]; + }, + 255 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 256 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 257 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(1-1)], false, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 258 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], true, false, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 259 => function ($stackPos) { + $this->semValue = new Node\Arg($this->semStack[$stackPos-(2-2)], false, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 260 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 261 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 262 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 263 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 264 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 265 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 266 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 267 => function ($stackPos) { + $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 268 => function ($stackPos) { + $this->semValue = new Stmt\StaticVar($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 269 => function ($stackPos) { + if ($this->semStack[$stackPos-(2-2)] !== null) { $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; } + }, + 270 => function ($stackPos) { + $this->semValue = array(); + }, + 271 => function ($stackPos) { + $startAttributes = $this->lookaheadStartAttributes; if (isset($startAttributes['comments'])) { $nop = new Stmt\Nop($startAttributes + $this->endAttributes); } else { $nop = null; }; + if ($nop !== null) { $this->semStack[$stackPos-(1-1)][] = $nop; } $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 272 => function ($stackPos) { + $this->semValue = new Stmt\Property($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->checkProperty($this->semValue, $stackPos-(3-1)); + }, + 273 => function ($stackPos) { + $this->semValue = new Stmt\ClassConst($this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-1)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); $this->checkClassConst($this->semValue, $stackPos-(4-1)); + }, + 274 => function ($stackPos) { + $this->semValue = new Stmt\ClassMethod($this->semStack[$stackPos-(9-4)], ['type' => $this->semStack[$stackPos-(9-1)], 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-6)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + $this->checkClassMethod($this->semValue, $stackPos-(9-1)); + }, + 275 => function ($stackPos) { + $this->semValue = new Stmt\TraitUse($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 276 => function ($stackPos) { + $this->semValue = null; /* will be skipped */ + }, + 277 => function ($stackPos) { + $this->semValue = array(); + }, + 278 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 279 => function ($stackPos) { + $this->semValue = array(); + }, + 280 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 281 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Precedence($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 282 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(5-1)][0], $this->semStack[$stackPos-(5-1)][1], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-4)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 283 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], $this->semStack[$stackPos-(4-3)], null, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 284 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 285 => function ($stackPos) { + $this->semValue = new Stmt\TraitUseAdaptation\Alias($this->semStack[$stackPos-(4-1)][0], $this->semStack[$stackPos-(4-1)][1], null, $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 286 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)]); + }, + 287 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 288 => function ($stackPos) { + $this->semValue = array(null, $this->semStack[$stackPos-(1-1)]); + }, + 289 => function ($stackPos) { + $this->semValue = null; + }, + 290 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 291 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 292 => function ($stackPos) { + $this->semValue = 0; + }, + 293 => function ($stackPos) { + $this->semValue = 0; + }, + 294 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 295 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 296 => function ($stackPos) { + $this->checkModifier($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $stackPos-(2-2)); $this->semValue = $this->semStack[$stackPos-(2-1)] | $this->semStack[$stackPos-(2-2)]; + }, + 297 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PUBLIC; + }, + 298 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PROTECTED; + }, + 299 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_PRIVATE; + }, + 300 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_STATIC; + }, + 301 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_ABSTRACT; + }, + 302 => function ($stackPos) { + $this->semValue = Stmt\Class_::MODIFIER_FINAL; + }, + 303 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 304 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 305 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 306 => function ($stackPos) { + $this->semValue = new Node\VarLikeIdentifier(substr($this->semStack[$stackPos-(1-1)], 1), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 307 => function ($stackPos) { + $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(1-1)], null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 308 => function ($stackPos) { + $this->semValue = new Stmt\PropertyProperty($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 309 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 310 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 311 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 312 => function ($stackPos) { + $this->semValue = array(); + }, + 313 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 314 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 315 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 316 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 317 => function ($stackPos) { + $this->semValue = new Expr\Assign($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 318 => function ($stackPos) { + $this->semValue = new Expr\AssignRef($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 319 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 320 => function ($stackPos) { + $this->semValue = new Expr\Clone_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 321 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 322 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 323 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 324 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 325 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 326 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 327 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 328 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 329 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 330 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 331 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 332 => function ($stackPos) { + $this->semValue = new Expr\AssignOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 333 => function ($stackPos) { + $this->semValue = new Expr\PostInc($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 334 => function ($stackPos) { + $this->semValue = new Expr\PreInc($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 335 => function ($stackPos) { + $this->semValue = new Expr\PostDec($this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 336 => function ($stackPos) { + $this->semValue = new Expr\PreDec($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 337 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 338 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BooleanAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 339 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 340 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 341 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\LogicalXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 342 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseOr($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 343 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseAnd($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 344 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\BitwiseXor($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 345 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Concat($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 346 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Plus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 347 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Minus($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 348 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mul($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 349 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Div($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 350 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Mod($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 351 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftLeft($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 352 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\ShiftRight($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 353 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Pow($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 354 => function ($stackPos) { + $this->semValue = new Expr\UnaryPlus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 355 => function ($stackPos) { + $this->semValue = new Expr\UnaryMinus($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 356 => function ($stackPos) { + $this->semValue = new Expr\BooleanNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 357 => function ($stackPos) { + $this->semValue = new Expr\BitwiseNot($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 358 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Identical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 359 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotIdentical($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 360 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Equal($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 361 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\NotEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 362 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Spaceship($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 363 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Smaller($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 364 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\SmallerOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 365 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Greater($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 366 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\GreaterOrEqual($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 367 => function ($stackPos) { + $this->semValue = new Expr\Instanceof_($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 368 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 369 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(5-1)], $this->semStack[$stackPos-(5-3)], $this->semStack[$stackPos-(5-5)], $this->startAttributeStack[$stackPos-(5-1)] + $this->endAttributes); + }, + 370 => function ($stackPos) { + $this->semValue = new Expr\Ternary($this->semStack[$stackPos-(4-1)], null, $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 371 => function ($stackPos) { + $this->semValue = new Expr\BinaryOp\Coalesce($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 372 => function ($stackPos) { + $this->semValue = new Expr\Isset_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 373 => function ($stackPos) { + $this->semValue = new Expr\Empty_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 374 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 375 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_INCLUDE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 376 => function ($stackPos) { + $this->semValue = new Expr\Eval_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 377 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 378 => function ($stackPos) { + $this->semValue = new Expr\Include_($this->semStack[$stackPos-(2-2)], Expr\Include_::TYPE_REQUIRE_ONCE, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 379 => function ($stackPos) { + $this->semValue = new Expr\Cast\Int_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 380 => function ($stackPos) { + $this->semValue = new Expr\Cast\Double($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 381 => function ($stackPos) { + $this->semValue = new Expr\Cast\String_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 382 => function ($stackPos) { + $this->semValue = new Expr\Cast\Array_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 383 => function ($stackPos) { + $this->semValue = new Expr\Cast\Object_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 384 => function ($stackPos) { + $this->semValue = new Expr\Cast\Bool_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 385 => function ($stackPos) { + $this->semValue = new Expr\Cast\Unset_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 386 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; + $attrs['kind'] = strtolower($this->semStack[$stackPos-(2-1)]) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE; + $this->semValue = new Expr\Exit_($this->semStack[$stackPos-(2-2)], $attrs); + }, + 387 => function ($stackPos) { + $this->semValue = new Expr\ErrorSuppress($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 388 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 389 => function ($stackPos) { + $this->semValue = new Expr\ShellExec($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 390 => function ($stackPos) { + $this->semValue = new Expr\Print_($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 391 => function ($stackPos) { + $this->semValue = new Expr\Yield_(null, null, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 392 => function ($stackPos) { + $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(2-2)], null, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 393 => function ($stackPos) { + $this->semValue = new Expr\Yield_($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 394 => function ($stackPos) { + $this->semValue = new Expr\YieldFrom($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 395 => function ($stackPos) { + $this->semValue = new Expr\Closure(['static' => false, 'byRef' => $this->semStack[$stackPos-(8-2)], 'params' => $this->semStack[$stackPos-(8-4)], 'uses' => $this->semStack[$stackPos-(8-6)], 'returnType' => $this->semStack[$stackPos-(8-7)], 'stmts' => $this->semStack[$stackPos-(8-8)]], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); + }, + 396 => function ($stackPos) { + $this->semValue = new Expr\Closure(['static' => true, 'byRef' => $this->semStack[$stackPos-(9-3)], 'params' => $this->semStack[$stackPos-(9-5)], 'uses' => $this->semStack[$stackPos-(9-7)], 'returnType' => $this->semStack[$stackPos-(9-8)], 'stmts' => $this->semStack[$stackPos-(9-9)]], $this->startAttributeStack[$stackPos-(9-1)] + $this->endAttributes); + }, + 397 => function ($stackPos) { + $this->semValue = array(new Stmt\Class_(null, ['type' => 0, 'extends' => $this->semStack[$stackPos-(7-3)], 'implements' => $this->semStack[$stackPos-(7-4)], 'stmts' => $this->semStack[$stackPos-(7-6)]], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes), $this->semStack[$stackPos-(7-2)]); $this->checkClass($this->semValue[0], -1); - } - - protected function reduceRule388() { - $this->semValue = new Expr\New_($this->semStack[$this->stackPos-(3-2)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule389() { - list($class, $ctorArgs) = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule390() { - $this->semValue = array(); - } - - protected function reduceRule391() { - $this->semValue = $this->semStack[$this->stackPos-(4-3)]; - } - - protected function reduceRule392() { - $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule393() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule394() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule395() { - $this->semValue = new Expr\ClosureUse(substr($this->semStack[$this->stackPos-(2-2)], 1), $this->semStack[$this->stackPos-(2-1)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule396() { - $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule397() { - $this->semValue = new Expr\FuncCall($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule398() { - $this->semValue = new Expr\StaticCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule399() { - $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule400() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule401() { - $this->semValue = new Name($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule402() { - $this->semValue = new Name\FullyQualified($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule403() { - $this->semValue = new Name\Relative($this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule404() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule405() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule406() { - $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; - } - - protected function reduceRule407() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule408() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule409() { - $this->semValue = null; - } - - protected function reduceRule410() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule411() { - $this->semValue = array(); - } - - protected function reduceRule412() { - $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$this->stackPos-(1-1)], '`'), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes)); - } - - protected function reduceRule413() { - foreach ($this->semStack[$this->stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', true); } }; $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule414() { - $this->semValue = array(); - } - - protected function reduceRule415() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule416() { - $this->semValue = new Expr\ConstFetch($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule417() { - $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule418() { - $this->semValue = new Expr\ClassConstFetch($this->semStack[$this->stackPos-(3-1)], new Expr\Error($this->startAttributeStack[$this->stackPos-(3-3)] + $this->endAttributeStack[$this->stackPos-(3-3)]), $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); $this->errorState = 2; - } - - protected function reduceRule419() { - $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; - $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(3-2)], $attrs); - } - - protected function reduceRule420() { - $attrs = $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; - $this->semValue = new Expr\Array_($this->semStack[$this->stackPos-(4-3)], $attrs); - } - - protected function reduceRule421() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule422() { - $attrs = $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$this->stackPos-(1-1)][0] === "'" || ($this->semStack[$this->stackPos-(1-1)][1] === "'" && ($this->semStack[$this->stackPos-(1-1)][0] === 'b' || $this->semStack[$this->stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); - $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$this->stackPos-(1-1)]), $attrs); - } - - protected function reduceRule423() { - $this->semValue = $this->parseLNumber($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule424() { - $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$this->stackPos-(1-1)]), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule425() { - $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule426() { - $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule427() { - $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule428() { - $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule429() { - $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule430() { - $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule431() { - $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule432() { - $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule433() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule434() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule435() { - $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; - $this->semValue = new Scalar\String_(Scalar\String_::parseDocString($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-2)]), $attrs); - } - - protected function reduceRule436() { - $attrs = $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(2-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(2-1)], $matches); $attrs['docLabel'] = $matches[1];; + }, + 398 => function ($stackPos) { + $this->semValue = new Expr\New_($this->semStack[$stackPos-(3-2)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 399 => function ($stackPos) { + list($class, $ctorArgs) = $this->semStack[$stackPos-(2-2)]; $this->semValue = new Expr\New_($class, $ctorArgs, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 400 => function ($stackPos) { + $this->semValue = array(); + }, + 401 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 402 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 403 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 404 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 405 => function ($stackPos) { + $this->semValue = new Expr\ClosureUse($this->semStack[$stackPos-(2-2)], $this->semStack[$stackPos-(2-1)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 406 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 407 => function ($stackPos) { + $this->semValue = new Expr\FuncCall($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 408 => function ($stackPos) { + $this->semValue = new Expr\StaticCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 409 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 410 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 411 => function ($stackPos) { + $this->semValue = new Name($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 412 => function ($stackPos) { + $this->semValue = new Name\FullyQualified($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 413 => function ($stackPos) { + $this->semValue = new Name\Relative($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 414 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 415 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 416 => function ($stackPos) { + $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + }, + 417 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 418 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 419 => function ($stackPos) { + $this->semValue = null; + }, + 420 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 421 => function ($stackPos) { + $this->semValue = array(); + }, + 422 => function ($stackPos) { + $this->semValue = array(new Scalar\EncapsedStringPart(Scalar\String_::parseEscapeSequences($this->semStack[$stackPos-(1-1)], '`'), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes)); + }, + 423 => function ($stackPos) { + foreach ($this->semStack[$stackPos-(1-1)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '`', true); } }; $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 424 => function ($stackPos) { + $this->semValue = array(); + }, + 425 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 426 => function ($stackPos) { + $this->semValue = new Expr\ConstFetch($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 427 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 428 => function ($stackPos) { + $this->semValue = new Expr\ClassConstFetch($this->semStack[$stackPos-(3-1)], new Expr\Error($this->startAttributeStack[$stackPos-(3-3)] + $this->endAttributeStack[$stackPos-(3-3)]), $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->errorState = 2; + }, + 429 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_SHORT; + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(3-2)], $attrs); + }, + 430 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes; $attrs['kind'] = Expr\Array_::KIND_LONG; + $this->semValue = new Expr\Array_($this->semStack[$stackPos-(4-3)], $attrs); + }, + 431 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 432 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes; $attrs['kind'] = ($this->semStack[$stackPos-(1-1)][0] === "'" || ($this->semStack[$stackPos-(1-1)][1] === "'" && ($this->semStack[$stackPos-(1-1)][0] === 'b' || $this->semStack[$stackPos-(1-1)][0] === 'B')) ? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED); + $this->semValue = new Scalar\String_(Scalar\String_::parse($this->semStack[$stackPos-(1-1)]), $attrs); + }, + 433 => function ($stackPos) { + $this->semValue = $this->parseLNumber($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 434 => function ($stackPos) { + $this->semValue = new Scalar\DNumber(Scalar\DNumber::parse($this->semStack[$stackPos-(1-1)]), $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 435 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Line($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 436 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\File($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 437 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Dir($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 438 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Class_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 439 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Trait_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 440 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Method($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 441 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Function_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 442 => function ($stackPos) { + $this->semValue = new Scalar\MagicConst\Namespace_($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 443 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 444 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 445 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; + $this->semValue = new Scalar\String_(Scalar\String_::parseDocString($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-2)]), $attrs); + }, + 446 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$stackPos-(2-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$stackPos-(2-1)], $matches); $attrs['docLabel'] = $matches[1];; $this->semValue = new Scalar\String_('', $attrs); - } - - protected function reduceRule437() { - $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; - foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); - } - - protected function reduceRule438() { - $attrs = $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$this->stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$this->stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; - foreach ($this->semStack[$this->stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, true); } } $s->value = preg_replace('~(\r\n|\n|\r)\z~', '', $s->value); if ('' === $s->value) array_pop($this->semStack[$this->stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$this->stackPos-(3-2)], $attrs); - } - - protected function reduceRule439() { - $this->semValue = null; - } - - protected function reduceRule440() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule441() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule442() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule443() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule444() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule445() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule446() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule447() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule448() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule449() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule450() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule451() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule452() { - $this->semValue = new Expr\MethodCall($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->semStack[$this->stackPos-(4-4)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule453() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule454() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule455() { - $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule456() { - $this->semValue = substr($this->semStack[$this->stackPos-(1-1)], 1); - } - - protected function reduceRule457() { - $this->semValue = $this->semStack[$this->stackPos-(4-3)]; - } - - protected function reduceRule458() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule459() { - $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); $this->errorState = 2; - } - - protected function reduceRule460() { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule461() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule462() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule463() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule464() { - $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule465() { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule466() { - $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule467() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule468() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule469() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule470() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule471() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule472() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule473() { - $this->semValue = new Expr\Error($this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; - } - - protected function reduceRule474() { - $this->semValue = new Expr\List_($this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule475() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule476() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule477() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule478() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule479() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule480() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule481() { - $this->semValue = null; - } - - protected function reduceRule482() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; $end = count($this->semValue)-1; if ($this->semValue[$end] === null) unset($this->semValue[$end]); - } - - protected function reduceRule483() { - $this->semStack[$this->stackPos-(3-1)][] = $this->semStack[$this->stackPos-(3-3)]; $this->semValue = $this->semStack[$this->stackPos-(3-1)]; - } - - protected function reduceRule484() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule485() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(3-3)], $this->semStack[$this->stackPos-(3-1)], false, $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule486() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(1-1)], null, false, $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule487() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(4-4)], $this->semStack[$this->stackPos-(4-1)], true, $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule488() { - $this->semValue = new Expr\ArrayItem($this->semStack[$this->stackPos-(2-2)], null, true, $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule489() { - $this->semValue = null; - } - - protected function reduceRule490() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule491() { - $this->semStack[$this->stackPos-(2-1)][] = $this->semStack[$this->stackPos-(2-2)]; $this->semValue = $this->semStack[$this->stackPos-(2-1)]; - } - - protected function reduceRule492() { - $this->semValue = array($this->semStack[$this->stackPos-(1-1)]); - } - - protected function reduceRule493() { - $this->semValue = array($this->semStack[$this->stackPos-(2-1)], $this->semStack[$this->stackPos-(2-2)]); - } - - protected function reduceRule494() { - $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule495() { - $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule496() { - $this->semValue = $this->semStack[$this->stackPos-(1-1)]; - } - - protected function reduceRule497() { - $this->semValue = new Expr\ArrayDimFetch($this->semStack[$this->stackPos-(4-1)], $this->semStack[$this->stackPos-(4-3)], $this->startAttributeStack[$this->stackPos-(4-1)] + $this->endAttributes); - } - - protected function reduceRule498() { - $this->semValue = new Expr\PropertyFetch($this->semStack[$this->stackPos-(3-1)], $this->semStack[$this->stackPos-(3-3)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule499() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule500() { - $this->semValue = new Expr\Variable($this->semStack[$this->stackPos-(3-2)], $this->startAttributeStack[$this->stackPos-(3-1)] + $this->endAttributes); - } - - protected function reduceRule501() { - $this->semValue = new Expr\ArrayDimFetch(new Expr\Variable($this->semStack[$this->stackPos-(6-2)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes), $this->semStack[$this->stackPos-(6-4)], $this->startAttributeStack[$this->stackPos-(6-1)] + $this->endAttributes); - } - - protected function reduceRule502() { - $this->semValue = $this->semStack[$this->stackPos-(3-2)]; - } - - protected function reduceRule503() { - $this->semValue = new Scalar\String_($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule504() { - $this->semValue = $this->parseNumString($this->semStack[$this->stackPos-(1-1)], $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); - } - - protected function reduceRule505() { - $this->semValue = $this->parseNumString('-' . $this->semStack[$this->stackPos-(2-2)], $this->startAttributeStack[$this->stackPos-(2-1)] + $this->endAttributes); - } - - protected function reduceRule506() { - $this->semValue = new Expr\Variable(substr($this->semStack[$this->stackPos-(1-1)], 1), $this->startAttributeStack[$this->stackPos-(1-1)] + $this->endAttributes); + }, + 447 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = Scalar\String_::KIND_DOUBLE_QUOTED; + foreach ($this->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, '"', true); } }; $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos-(3-2)], $attrs); + }, + 448 => function ($stackPos) { + $attrs = $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes; $attrs['kind'] = strpos($this->semStack[$stackPos-(3-1)], "'") === false ? Scalar\String_::KIND_HEREDOC : Scalar\String_::KIND_NOWDOC; preg_match('/\A[bB]?<<<[ \t]*[\'"]?([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)[\'"]?(?:\r\n|\n|\r)\z/', $this->semStack[$stackPos-(3-1)], $matches); $attrs['docLabel'] = $matches[1];; + foreach ($this->semStack[$stackPos-(3-2)] as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) { $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, null, true); } } $s->value = preg_replace('~(\r\n|\n|\r)\z~', '', $s->value); if ('' === $s->value) array_pop($this->semStack[$stackPos-(3-2)]);; $this->semValue = new Scalar\Encapsed($this->semStack[$stackPos-(3-2)], $attrs); + }, + 449 => function ($stackPos) { + $this->semValue = null; + }, + 450 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 451 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 452 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 453 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 454 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 455 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 456 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 457 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 458 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 459 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 460 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 461 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 462 => function ($stackPos) { + $this->semValue = new Expr\MethodCall($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-4)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 463 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 464 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 465 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 466 => function ($stackPos) { + $this->semValue = substr($this->semStack[$stackPos-(1-1)], 1); + }, + 467 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(4-3)]; + }, + 468 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 469 => function ($stackPos) { + $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); $this->errorState = 2; + }, + 470 => function ($stackPos) { + $var = $this->semStack[$stackPos-(1-1)]; $this->semValue = \is_string($var) ? new Node\VarLikeIdentifier($var, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes) : $var; + }, + 471 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 472 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 473 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 474 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 475 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 476 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 477 => function ($stackPos) { + $this->semValue = new Expr\StaticPropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 478 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 479 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 480 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 481 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 482 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 483 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 484 => function ($stackPos) { + $this->semValue = new Expr\Error($this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); $this->errorState = 2; + }, + 485 => function ($stackPos) { + $this->semValue = new Expr\List_($this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 486 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 487 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 488 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 489 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 490 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 491 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 492 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-1)], true, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 493 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 494 => function ($stackPos) { + $this->semValue = null; + }, + 495 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; $end = count($this->semValue)-1; if ($this->semValue[$end] === null) array_pop($this->semValue); + }, + 496 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 497 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos]; + }, + 498 => function ($stackPos) { + $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; + }, + 499 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 500 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(3-3)], $this->semStack[$stackPos-(3-1)], false, $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 501 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(1-1)], null, false, $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 502 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(4-4)], $this->semStack[$stackPos-(4-1)], true, $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 503 => function ($stackPos) { + $this->semValue = new Expr\ArrayItem($this->semStack[$stackPos-(2-2)], null, true, $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 504 => function ($stackPos) { + $this->semValue = null; + }, + 505 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 506 => function ($stackPos) { + $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; + }, + 507 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(1-1)]); + }, + 508 => function ($stackPos) { + $this->semValue = array($this->semStack[$stackPos-(2-1)], $this->semStack[$stackPos-(2-2)]); + }, + 509 => function ($stackPos) { + $this->semValue = new Scalar\EncapsedStringPart($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 510 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 511 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + 512 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(4-1)], $this->semStack[$stackPos-(4-3)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); + }, + 513 => function ($stackPos) { + $this->semValue = new Expr\PropertyFetch($this->semStack[$stackPos-(3-1)], $this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 514 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 515 => function ($stackPos) { + $this->semValue = new Expr\Variable($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + }, + 516 => function ($stackPos) { + $this->semValue = new Expr\ArrayDimFetch($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-4)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + }, + 517 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(3-2)]; + }, + 518 => function ($stackPos) { + $this->semValue = new Scalar\String_($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 519 => function ($stackPos) { + $this->semValue = $this->parseNumString($this->semStack[$stackPos-(1-1)], $this->startAttributeStack[$stackPos-(1-1)] + $this->endAttributes); + }, + 520 => function ($stackPos) { + $this->semValue = $this->parseNumString('-' . $this->semStack[$stackPos-(2-2)], $this->startAttributeStack[$stackPos-(2-1)] + $this->endAttributes); + }, + 521 => function ($stackPos) { + $this->semValue = $this->semStack[$stackPos-(1-1)]; + }, + ]; } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php b/app/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php index e0f6e2592..dab6aea7a 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/ParserAbstract.php @@ -1,4 +1,4 @@ -lexer = $lexer; - $this->errors = array(); if (isset($options['throwOnError'])) { throw new \LogicException( '"throwOnError" is no longer supported, use "errorHandler" instead'); } + + $this->initReduceCallbacks(); } /** @@ -137,45 +146,56 @@ public function __construct(Lexer $lexer, array $options = array()) { * @param ErrorHandler|null $errorHandler Error handler to use for lexer/parser errors, defaults * to ErrorHandler\Throwing. * - * @return Node[]|null Array of statements (or null if the 'throwOnError' option is disabled and the parser was - * unable to recover from an error). + * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and + * the parser was unable to recover from an error). */ - public function parse($code, ErrorHandler $errorHandler = null) { + public function parse(string $code, ErrorHandler $errorHandler = null) { $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing; - // Initialize the lexer $this->lexer->startLexing($code, $this->errorHandler); + $result = $this->doParse(); + + // Clear out some of the interior state, so we don't hold onto unnecessary + // memory between uses of the parser + $this->startAttributeStack = []; + $this->endAttributeStack = []; + $this->semStack = []; + $this->semValue = null; + + return $result; + } + protected function doParse() { // We start off with no lookahead-token $symbol = self::SYMBOL_NONE; // The attributes for a node are taken from the first and last token of the node. // From the first token only the startAttributes are taken and from the last only // the endAttributes. Both are merged using the array union operator (+). - $startAttributes = '*POISON'; - $endAttributes = '*POISON'; + $startAttributes = []; + $endAttributes = []; $this->endAttributes = $endAttributes; // Keep stack of start and end attributes - $this->startAttributeStack = array(); - $this->endAttributeStack = array($endAttributes); + $this->startAttributeStack = []; + $this->endAttributeStack = [$endAttributes]; // Start off in the initial state and keep a stack of previous states $state = 0; - $stateStack = array($state); + $stateStack = [$state]; // Semantic value stack (contains values of tokens and semantic action results) - $this->semStack = array(); + $this->semStack = []; // Current position in the stack(s) - $this->stackPos = 0; + $stackPos = 0; $this->errorState = 0; for (;;) { //$this->traceNewState($state, $symbol); - if ($this->actionBase[$state] == 0) { + if ($this->actionBase[$state] === 0) { $rule = $this->actionDefault[$state]; } else { if ($symbol === self::SYMBOL_NONE) { @@ -199,21 +219,21 @@ public function parse($code, ErrorHandler $errorHandler = null) { // This is necessary to assign some meaningful attributes to /* empty */ productions. They'll get // the attributes of the next token, even though they don't contain it themselves. - $this->startAttributeStack[$this->stackPos+1] = $startAttributes; - $this->endAttributeStack[$this->stackPos+1] = $endAttributes; + $this->startAttributeStack[$stackPos+1] = $startAttributes; + $this->endAttributeStack[$stackPos+1] = $endAttributes; $this->lookaheadStartAttributes = $startAttributes; //$this->traceRead($symbol); } $idx = $this->actionBase[$state] + $symbol; - if ((($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $symbol) + if ((($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol) || ($state < $this->YY2TBLSTATE - && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $symbol) >= 0 - && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $symbol)) - && ($action = $this->action[$idx]) != $this->defaultAction) { + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol)) + && ($action = $this->action[$idx]) !== $this->defaultAction) { /* - * >= YYNLSTATES: shift and reduce + * >= numNonLeafStates: shift and reduce * > 0: shift * = 0: accept * < 0: reduce @@ -223,11 +243,11 @@ public function parse($code, ErrorHandler $errorHandler = null) { /* shift */ //$this->traceShift($symbol); - ++$this->stackPos; - $stateStack[$this->stackPos] = $state = $action; - $this->semStack[$this->stackPos] = $tokenValue; - $this->startAttributeStack[$this->stackPos] = $startAttributes; - $this->endAttributeStack[$this->stackPos] = $endAttributes; + ++$stackPos; + $stateStack[$stackPos] = $state = $action; + $this->semStack[$stackPos] = $tokenValue; + $this->startAttributeStack[$stackPos] = $startAttributes; + $this->endAttributeStack[$stackPos] = $endAttributes; $this->endAttributes = $endAttributes; $symbol = self::SYMBOL_NONE; @@ -235,12 +255,12 @@ public function parse($code, ErrorHandler $errorHandler = null) { --$this->errorState; } - if ($action < $this->YYNLSTATES) { + if ($action < $this->numNonLeafStates) { continue; } - /* $yyn >= YYNLSTATES means shift-and-reduce */ - $rule = $action - $this->YYNLSTATES; + /* $yyn >= numNonLeafStates means shift-and-reduce */ + $rule = $action - $this->numNonLeafStates; } else { $rule = -$action; } @@ -259,7 +279,7 @@ public function parse($code, ErrorHandler $errorHandler = null) { //$this->traceReduce($rule); try { - $this->{'reduceRule' . $rule}(); + $this->reduceCallbacks[$rule]($stackPos); } catch (Error $e) { if (-1 === $e->getStartLine() && isset($startAttributes['startLine'])) { $e->setStartLine($startAttributes['startLine']); @@ -271,20 +291,20 @@ public function parse($code, ErrorHandler $errorHandler = null) { } /* Goto - shift nonterminal */ - $lastEndAttributes = $this->endAttributeStack[$this->stackPos]; - $this->stackPos -= $this->ruleToLength[$rule]; + $lastEndAttributes = $this->endAttributeStack[$stackPos]; + $stackPos -= $this->ruleToLength[$rule]; $nonTerminal = $this->ruleToNonTerminal[$rule]; - $idx = $this->gotoBase[$nonTerminal] + $stateStack[$this->stackPos]; - if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] == $nonTerminal) { + $idx = $this->gotoBase[$nonTerminal] + $stateStack[$stackPos]; + if ($idx >= 0 && $idx < $this->gotoTableSize && $this->gotoCheck[$idx] === $nonTerminal) { $state = $this->goto[$idx]; } else { $state = $this->gotoDefault[$nonTerminal]; } - ++$this->stackPos; - $stateStack[$this->stackPos] = $state; - $this->semStack[$this->stackPos] = $this->semValue; - $this->endAttributeStack[$this->stackPos] = $lastEndAttributes; + ++$stackPos; + $stateStack[$stackPos] = $state; + $this->semStack[$stackPos] = $this->semValue; + $this->endAttributeStack[$stackPos] = $lastEndAttributes; } else { /* error */ switch ($this->errorState) { @@ -299,27 +319,27 @@ public function parse($code, ErrorHandler $errorHandler = null) { // Pop until error-expecting state uncovered while (!( (($idx = $this->actionBase[$state] + $this->errorSymbol) >= 0 - && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) || ($state < $this->YY2TBLSTATE - && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $this->errorSymbol) >= 0 - && $idx < $this->actionTableSize && $this->actionCheck[$idx] == $this->errorSymbol) - ) || ($action = $this->action[$idx]) == $this->defaultAction) { // Not totally sure about this - if ($this->stackPos <= 0) { + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $this->errorSymbol) >= 0 + && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $this->errorSymbol) + ) || ($action = $this->action[$idx]) === $this->defaultAction) { // Not totally sure about this + if ($stackPos <= 0) { // Could not recover from error return null; } - $state = $stateStack[--$this->stackPos]; + $state = $stateStack[--$stackPos]; //$this->tracePop($state); } //$this->traceShift($this->errorSymbol); - ++$this->stackPos; - $stateStack[$this->stackPos] = $state = $action; + ++$stackPos; + $stateStack[$stackPos] = $state = $action; // We treat the error symbol as being empty, so we reset the end attributes // to the end attributes of the last non-error symbol - $this->endAttributeStack[$this->stackPos] = $this->endAttributeStack[$this->stackPos - 1]; - $this->endAttributes = $this->endAttributeStack[$this->stackPos - 1]; + $this->endAttributeStack[$stackPos] = $this->endAttributeStack[$stackPos - 1]; + $this->endAttributes = $this->endAttributeStack[$stackPos - 1]; break; case 3: @@ -334,12 +354,12 @@ public function parse($code, ErrorHandler $errorHandler = null) { } } - if ($state < $this->YYNLSTATES) { + if ($state < $this->numNonLeafStates) { break; } - /* >= YYNLSTATES means shift-and-reduce */ - $rule = $state - $this->YYNLSTATES; + /* >= numNonLeafStates means shift-and-reduce */ + $rule = $state - $this->numNonLeafStates; } } @@ -350,7 +370,15 @@ protected function emitError(Error $error) { $this->errorHandler->handleError($error); } - protected function getErrorMessage($symbol, $state) { + /** + * Format error message including expected tokens. + * + * @param int $symbol Unexpected symbol + * @param int $state State at time of error + * + * @return string Formatted error message + */ + protected function getErrorMessage(int $symbol, int $state) : string { $expectedString = ''; if ($expected = $this->getExpectedTokens($state)) { $expectedString = ', expecting ' . implode(' or ', $expected); @@ -359,24 +387,31 @@ protected function getErrorMessage($symbol, $state) { return 'Syntax error, unexpected ' . $this->symbolToName[$symbol] . $expectedString; } - protected function getExpectedTokens($state) { - $expected = array(); + /** + * Get limited number of expected tokens in given state. + * + * @param int $state State + * + * @return string[] Expected tokens. If too many, an empty array is returned. + */ + protected function getExpectedTokens(int $state) : array { + $expected = []; $base = $this->actionBase[$state]; foreach ($this->symbolToName as $symbol => $name) { $idx = $base + $symbol; if ($idx >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol || $state < $this->YY2TBLSTATE - && ($idx = $this->actionBase[$state + $this->YYNLSTATES] + $symbol) >= 0 + && ($idx = $this->actionBase[$state + $this->numNonLeafStates] + $symbol) >= 0 && $idx < $this->actionTableSize && $this->actionCheck[$idx] === $symbol ) { - if ($this->action[$idx] != $this->unexpectedTokenRule - && $this->action[$idx] != $this->defaultAction - && $symbol != $this->errorSymbol + if ($this->action[$idx] !== $this->unexpectedTokenRule + && $this->action[$idx] !== $this->defaultAction + && $symbol !== $this->errorSymbol ) { - if (count($expected) == 4) { + if (count($expected) === 4) { /* Too many expected tokens */ - return array(); + return []; } $expected[] = $name; @@ -429,10 +464,10 @@ protected function traceDiscard($symbol) { /** * Moves statements of semicolon-style namespaces into $ns->stmts and checks various error conditions. * - * @param Node[] $stmts - * @return Node[] + * @param Node\Stmt[] $stmts + * @return Node\Stmt[] */ - protected function handleNamespaces(array $stmts) { + protected function handleNamespaces(array $stmts) : array { $hasErrored = false; $style = $this->getNamespacingStyle($stmts); if (null === $style) { @@ -455,12 +490,16 @@ protected function handleNamespaces(array $stmts) { return $stmts; } else { // For semicolon namespaces we have to move the statements after a namespace declaration into ->stmts - $resultStmts = array(); + $resultStmts = []; $targetStmts =& $resultStmts; + $lastNs = null; foreach ($stmts as $stmt) { if ($stmt instanceof Node\Stmt\Namespace_) { + if ($lastNs !== null) { + $this->fixupNamespaceAttributes($lastNs); + } if ($stmt->stmts === null) { - $stmt->stmts = array(); + $stmt->stmts = []; $targetStmts =& $stmt->stmts; $resultStmts[] = $stmt; } else { @@ -468,6 +507,7 @@ protected function handleNamespaces(array $stmts) { $resultStmts[] = $stmt; $targetStmts =& $resultStmts; } + $lastNs = $stmt; } elseif ($stmt instanceof Node\Stmt\HaltCompiler) { // __halt_compiler() is not moved into the namespace $resultStmts[] = $stmt; @@ -475,10 +515,38 @@ protected function handleNamespaces(array $stmts) { $targetStmts[] = $stmt; } } + if ($lastNs !== null) { + $this->fixupNamespaceAttributes($lastNs); + } return $resultStmts; } } + private function fixupNamespaceAttributes(Node\Stmt\Namespace_ $stmt) { + // We moved the statements into the namespace node, as such the end of the namespace node + // needs to be extended to the end of the statements. + if (empty($stmt->stmts)) { + return; + } + + // We only move the builtin end attributes here. This is the best we can do with the + // knowledge we have. + $endAttributes = ['endLine', 'endFilePos', 'endTokenPos']; + $lastStmt = $stmt->stmts[count($stmt->stmts) - 1]; + foreach ($endAttributes as $endAttribute) { + if ($lastStmt->hasAttribute($endAttribute)) { + $stmt->setAttribute($endAttribute, $lastStmt->getAttribute($endAttribute)); + } + } + } + + /** + * Determine namespacing style (semicolon or brace) + * + * @param Node[] $stmts Top-level statements. + * + * @return null|string One of "semicolon", "brace" or null (no namespaces) + */ private function getNamespacingStyle(array $stmts) { $style = null; $hasNotAllowedStmts = false; @@ -512,7 +580,7 @@ private function getNamespacingStyle(array $stmts) { } /* There may be a hashbang line at the very start of the file */ - if ($i == 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) { + if ($i === 0 && $stmt instanceof Node\Stmt\InlineHTML && preg_match('/\A#!.*\r?\n\z/', $stmt->value)) { continue; } @@ -522,6 +590,61 @@ private function getNamespacingStyle(array $stmts) { return $style; } + /** + * Fix up parsing of static property calls in PHP 5. + * + * In PHP 5 A::$b[c][d] and A::$b[c][d]() have very different interpretation. The former is + * interpreted as (A::$b)[c][d], while the latter is the same as A::{$b[c][d]}(). We parse the + * latter as the former initially and this method fixes the AST into the correct form when we + * encounter the "()". + * + * @param Node\Expr\StaticPropertyFetch|Node\Expr\ArrayDimFetch $prop + * @param Node\Arg[] $args + * @param array $attributes + * + * @return Expr\StaticCall + */ + protected function fixupPhp5StaticPropCall($prop, array $args, array $attributes) : Expr\StaticCall { + if ($prop instanceof Node\Expr\StaticPropertyFetch) { + $name = $prop->name instanceof VarLikeIdentifier + ? $prop->name->toString() : $prop->name; + $var = new Expr\Variable($name, $prop->name->getAttributes()); + return new Expr\StaticCall($prop->class, $var, $args, $attributes); + } elseif ($prop instanceof Node\Expr\ArrayDimFetch) { + $tmp = $prop; + while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { + $tmp = $tmp->var; + } + + /** @var Expr\StaticPropertyFetch $staticProp */ + $staticProp = $tmp->var; + + // Set start attributes to attributes of innermost node + $tmp = $prop; + $this->fixupStartAttributes($tmp, $staticProp->name); + while ($tmp->var instanceof Node\Expr\ArrayDimFetch) { + $tmp = $tmp->var; + $this->fixupStartAttributes($tmp, $staticProp->name); + } + + $name = $staticProp->name instanceof VarLikeIdentifier + ? $staticProp->name->toString() : $staticProp->name; + $tmp->var = new Expr\Variable($name, $staticProp->name->getAttributes()); + return new Expr\StaticCall($staticProp->class, $prop, $args, $attributes); + } else { + throw new \Exception; + } + } + + protected function fixupStartAttributes(Node $to, Node $from) { + $startAttributes = ['startLine', 'startFilePos', 'startTokenPos']; + foreach ($startAttributes as $startAttribute) { + if ($from->hasAttribute($startAttribute)) { + $to->setAttribute($startAttribute, $from->getAttribute($startAttribute)); + } + } + } + protected function handleBuiltinTypes(Name $name) { $scalarTypes = [ 'bool' => true, @@ -537,17 +660,22 @@ protected function handleBuiltinTypes(Name $name) { return $name; } - $lowerName = strtolower($name->toString()); - return isset($scalarTypes[$lowerName]) ? $lowerName : $name; - } + $lowerName = $name->toLowerString(); + if (!isset($scalarTypes[$lowerName])) { + return $name; + } - protected static $specialNames = array( - 'self' => true, - 'parent' => true, - 'static' => true, - ); + return new Node\Identifier($lowerName, $name->getAttributes()); + } - protected function getAttributesAt($pos) { + /** + * Get combined start and end attributes at a stack location + * + * @param int $pos Stack location + * + * @return array Combined start and end attributes + */ + protected function getAttributesAt(int $pos) : array { return $this->startAttributeStack[$pos] + $this->endAttributeStack[$pos]; } @@ -561,7 +689,15 @@ protected function parseLNumber($str, $attributes, $allowInvalidOctal = false) { } } - protected function parseNumString($str, $attributes) { + /** + * Parse a T_NUM_STRING token into either an integer or string node. + * + * @param string $str Number string + * @param array $attributes Attributes + * + * @return LNumber|String_ Integer or string node. + */ + protected function parseNumString(string $str, array $attributes) { if (!preg_match('/^(?:0|-?[1-9][0-9]*)$/', $str)) { return new String_($str, $attributes); } @@ -602,7 +738,7 @@ protected function checkTryCatch(TryCatch $node) { } protected function checkNamespace(Namespace_ $node) { - if (isset(self::$specialNames[strtolower($node->name)])) { + if ($node->name && $node->name->isSpecialClassName()) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as namespace name', $node->name), $node->name->getAttributes() @@ -621,14 +757,14 @@ protected function checkNamespace(Namespace_ $node) { } protected function checkClass(Class_ $node, $namePos) { - if (null !== $node->name && isset(self::$specialNames[strtolower($node->name)])) { + if (null !== $node->name && $node->name->isSpecialClassName()) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as class name as it is reserved', $node->name), $this->getAttributesAt($namePos) )); } - if (isset(self::$specialNames[strtolower($node->extends)])) { + if ($node->extends && $node->extends->isSpecialClassName()) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as class name as it is reserved', $node->extends), $node->extends->getAttributes() @@ -636,7 +772,7 @@ protected function checkClass(Class_ $node, $namePos) { } foreach ($node->implements as $interface) { - if (isset(self::$specialNames[strtolower($interface)])) { + if ($interface->isSpecialClassName()) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), $interface->getAttributes() @@ -646,7 +782,7 @@ protected function checkClass(Class_ $node, $namePos) { } protected function checkInterface(Interface_ $node, $namePos) { - if (null !== $node->name && isset(self::$specialNames[strtolower($node->name)])) { + if (null !== $node->name && $node->name->isSpecialClassName()) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as class name as it is reserved', $node->name), $this->getAttributesAt($namePos) @@ -654,7 +790,7 @@ protected function checkInterface(Interface_ $node, $namePos) { } foreach ($node->extends as $interface) { - if (isset(self::$specialNames[strtolower($interface)])) { + if ($interface->isSpecialClassName()) { $this->emitError(new Error( sprintf('Cannot use \'%s\' as interface name as it is reserved', $interface), $interface->getAttributes() @@ -665,7 +801,7 @@ protected function checkInterface(Interface_ $node, $namePos) { protected function checkClassMethod(ClassMethod $node, $modifierPos) { if ($node->flags & Class_::MODIFIER_STATIC) { - switch (strtolower($node->name)) { + switch ($node->name->toLowerString()) { case '__construct': $this->emitError(new Error( sprintf('Constructor %s() cannot be static', $node->name), @@ -716,7 +852,7 @@ protected function checkProperty(Property $node, $modifierPos) { } protected function checkUseUse(UseUse $node, $namePos) { - if ('self' == strtolower($node->alias) || 'parent' == strtolower($node->alias)) { + if ($node->alias && $node->alias->isSpecialClassName()) { $this->emitError(new Error( sprintf( 'Cannot use %s as %s because \'%2$s\' is a special class name', diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php b/app/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php index 28b9070d4..f041e7ffe 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/ParserFactory.php @@ -1,8 +1,9 @@ -type ? $this->pType($node->type) . ' ' : '') + return ($node->type ? $this->p($node->type) . ' ' : '') . ($node->byRef ? '&' : '') . ($node->variadic ? '...' : '') - . '$' . $node->name + . $this->p($node->var) . ($node->default ? ' = ' . $this->p($node->default) : ''); } @@ -34,7 +34,15 @@ protected function pConst(Node\Const_ $node) { } protected function pNullableType(Node\NullableType $node) { - return '?' . $this->pType($node->type); + return '?' . $this->p($node->type); + } + + protected function pIdentifier(Node\Identifier $node) { + return $node->name; + } + + protected function pVarLikeIdentifier(Node\VarLikeIdentifier $node) { + return '$' . $node->name; } // Names @@ -94,24 +102,24 @@ protected function pScalar_String(Scalar\String_ $node) { $label = $node->getAttribute('docLabel'); if ($label && !$this->containsEndLabel($node->value, $label)) { if ($node->value === '') { - return $this->pNoIndent("<<<'$label'\n$label") . $this->docStringEndToken; + return "<<<'$label'\n$label" . $this->docStringEndToken; } - return $this->pNoIndent("<<<'$label'\n$node->value\n$label") + return "<<<'$label'\n$node->value\n$label" . $this->docStringEndToken; } /* break missing intentionally */ case Scalar\String_::KIND_SINGLE_QUOTED: - return '\'' . $this->pNoIndent(addcslashes($node->value, '\'\\')) . '\''; + return $this->pSingleQuotedString($node->value); case Scalar\String_::KIND_HEREDOC: $label = $node->getAttribute('docLabel'); if ($label && !$this->containsEndLabel($node->value, $label)) { if ($node->value === '') { - return $this->pNoIndent("<<<$label\n$label") . $this->docStringEndToken; + return "<<<$label\n$label" . $this->docStringEndToken; } $escaped = $this->escapeString($node->value, null); - return $this->pNoIndent("<<<$label\n" . $escaped ."\n$label") + return "<<<$label\n" . $escaped . "\n$label" . $this->docStringEndToken; } /* break missing intentionally */ @@ -129,12 +137,11 @@ protected function pScalar_Encapsed(Scalar\Encapsed $node) { && $node->parts[0] instanceof Scalar\EncapsedStringPart && $node->parts[0]->value === '' ) { - return $this->pNoIndent("<<<$label\n$label") . $this->docStringEndToken; + return "<<<$label\n$label" . $this->docStringEndToken; } - return $this->pNoIndent( - "<<<$label\n" . $this->pEncapsList($node->parts, null) . "\n$label" - ) . $this->docStringEndToken; + return "<<<$label\n" . $this->pEncapsList($node->parts, null) . "\n$label" + . $this->docStringEndToken; } } return '"' . $this->pEncapsList($node->parts, '"') . '"'; @@ -191,186 +198,190 @@ protected function pScalar_DNumber(Scalar\DNumber $node) { return preg_match('/^-?[0-9]+$/', $stringValue) ? $stringValue . '.0' : $stringValue; } + protected function pScalar_EncapsedStringPart(Scalar\EncapsedStringPart $node) { + throw new \LogicException('Cannot directly print EncapsedStringPart'); + } + // Assignments protected function pExpr_Assign(Expr\Assign $node) { - return $this->pInfixOp('Expr_Assign', $node->var, ' = ', $node->expr); + return $this->pInfixOp(Expr\Assign::class, $node->var, ' = ', $node->expr); } protected function pExpr_AssignRef(Expr\AssignRef $node) { - return $this->pInfixOp('Expr_AssignRef', $node->var, ' =& ', $node->expr); + return $this->pInfixOp(Expr\AssignRef::class, $node->var, ' =& ', $node->expr); } protected function pExpr_AssignOp_Plus(AssignOp\Plus $node) { - return $this->pInfixOp('Expr_AssignOp_Plus', $node->var, ' += ', $node->expr); + return $this->pInfixOp(AssignOp\Plus::class, $node->var, ' += ', $node->expr); } protected function pExpr_AssignOp_Minus(AssignOp\Minus $node) { - return $this->pInfixOp('Expr_AssignOp_Minus', $node->var, ' -= ', $node->expr); + return $this->pInfixOp(AssignOp\Minus::class, $node->var, ' -= ', $node->expr); } protected function pExpr_AssignOp_Mul(AssignOp\Mul $node) { - return $this->pInfixOp('Expr_AssignOp_Mul', $node->var, ' *= ', $node->expr); + return $this->pInfixOp(AssignOp\Mul::class, $node->var, ' *= ', $node->expr); } protected function pExpr_AssignOp_Div(AssignOp\Div $node) { - return $this->pInfixOp('Expr_AssignOp_Div', $node->var, ' /= ', $node->expr); + return $this->pInfixOp(AssignOp\Div::class, $node->var, ' /= ', $node->expr); } protected function pExpr_AssignOp_Concat(AssignOp\Concat $node) { - return $this->pInfixOp('Expr_AssignOp_Concat', $node->var, ' .= ', $node->expr); + return $this->pInfixOp(AssignOp\Concat::class, $node->var, ' .= ', $node->expr); } protected function pExpr_AssignOp_Mod(AssignOp\Mod $node) { - return $this->pInfixOp('Expr_AssignOp_Mod', $node->var, ' %= ', $node->expr); + return $this->pInfixOp(AssignOp\Mod::class, $node->var, ' %= ', $node->expr); } protected function pExpr_AssignOp_BitwiseAnd(AssignOp\BitwiseAnd $node) { - return $this->pInfixOp('Expr_AssignOp_BitwiseAnd', $node->var, ' &= ', $node->expr); + return $this->pInfixOp(AssignOp\BitwiseAnd::class, $node->var, ' &= ', $node->expr); } protected function pExpr_AssignOp_BitwiseOr(AssignOp\BitwiseOr $node) { - return $this->pInfixOp('Expr_AssignOp_BitwiseOr', $node->var, ' |= ', $node->expr); + return $this->pInfixOp(AssignOp\BitwiseOr::class, $node->var, ' |= ', $node->expr); } protected function pExpr_AssignOp_BitwiseXor(AssignOp\BitwiseXor $node) { - return $this->pInfixOp('Expr_AssignOp_BitwiseXor', $node->var, ' ^= ', $node->expr); + return $this->pInfixOp(AssignOp\BitwiseXor::class, $node->var, ' ^= ', $node->expr); } protected function pExpr_AssignOp_ShiftLeft(AssignOp\ShiftLeft $node) { - return $this->pInfixOp('Expr_AssignOp_ShiftLeft', $node->var, ' <<= ', $node->expr); + return $this->pInfixOp(AssignOp\ShiftLeft::class, $node->var, ' <<= ', $node->expr); } protected function pExpr_AssignOp_ShiftRight(AssignOp\ShiftRight $node) { - return $this->pInfixOp('Expr_AssignOp_ShiftRight', $node->var, ' >>= ', $node->expr); + return $this->pInfixOp(AssignOp\ShiftRight::class, $node->var, ' >>= ', $node->expr); } protected function pExpr_AssignOp_Pow(AssignOp\Pow $node) { - return $this->pInfixOp('Expr_AssignOp_Pow', $node->var, ' **= ', $node->expr); + return $this->pInfixOp(AssignOp\Pow::class, $node->var, ' **= ', $node->expr); } // Binary expressions protected function pExpr_BinaryOp_Plus(BinaryOp\Plus $node) { - return $this->pInfixOp('Expr_BinaryOp_Plus', $node->left, ' + ', $node->right); + return $this->pInfixOp(BinaryOp\Plus::class, $node->left, ' + ', $node->right); } protected function pExpr_BinaryOp_Minus(BinaryOp\Minus $node) { - return $this->pInfixOp('Expr_BinaryOp_Minus', $node->left, ' - ', $node->right); + return $this->pInfixOp(BinaryOp\Minus::class, $node->left, ' - ', $node->right); } protected function pExpr_BinaryOp_Mul(BinaryOp\Mul $node) { - return $this->pInfixOp('Expr_BinaryOp_Mul', $node->left, ' * ', $node->right); + return $this->pInfixOp(BinaryOp\Mul::class, $node->left, ' * ', $node->right); } protected function pExpr_BinaryOp_Div(BinaryOp\Div $node) { - return $this->pInfixOp('Expr_BinaryOp_Div', $node->left, ' / ', $node->right); + return $this->pInfixOp(BinaryOp\Div::class, $node->left, ' / ', $node->right); } protected function pExpr_BinaryOp_Concat(BinaryOp\Concat $node) { - return $this->pInfixOp('Expr_BinaryOp_Concat', $node->left, ' . ', $node->right); + return $this->pInfixOp(BinaryOp\Concat::class, $node->left, ' . ', $node->right); } protected function pExpr_BinaryOp_Mod(BinaryOp\Mod $node) { - return $this->pInfixOp('Expr_BinaryOp_Mod', $node->left, ' % ', $node->right); + return $this->pInfixOp(BinaryOp\Mod::class, $node->left, ' % ', $node->right); } protected function pExpr_BinaryOp_BooleanAnd(BinaryOp\BooleanAnd $node) { - return $this->pInfixOp('Expr_BinaryOp_BooleanAnd', $node->left, ' && ', $node->right); + return $this->pInfixOp(BinaryOp\BooleanAnd::class, $node->left, ' && ', $node->right); } protected function pExpr_BinaryOp_BooleanOr(BinaryOp\BooleanOr $node) { - return $this->pInfixOp('Expr_BinaryOp_BooleanOr', $node->left, ' || ', $node->right); + return $this->pInfixOp(BinaryOp\BooleanOr::class, $node->left, ' || ', $node->right); } protected function pExpr_BinaryOp_BitwiseAnd(BinaryOp\BitwiseAnd $node) { - return $this->pInfixOp('Expr_BinaryOp_BitwiseAnd', $node->left, ' & ', $node->right); + return $this->pInfixOp(BinaryOp\BitwiseAnd::class, $node->left, ' & ', $node->right); } protected function pExpr_BinaryOp_BitwiseOr(BinaryOp\BitwiseOr $node) { - return $this->pInfixOp('Expr_BinaryOp_BitwiseOr', $node->left, ' | ', $node->right); + return $this->pInfixOp(BinaryOp\BitwiseOr::class, $node->left, ' | ', $node->right); } protected function pExpr_BinaryOp_BitwiseXor(BinaryOp\BitwiseXor $node) { - return $this->pInfixOp('Expr_BinaryOp_BitwiseXor', $node->left, ' ^ ', $node->right); + return $this->pInfixOp(BinaryOp\BitwiseXor::class, $node->left, ' ^ ', $node->right); } protected function pExpr_BinaryOp_ShiftLeft(BinaryOp\ShiftLeft $node) { - return $this->pInfixOp('Expr_BinaryOp_ShiftLeft', $node->left, ' << ', $node->right); + return $this->pInfixOp(BinaryOp\ShiftLeft::class, $node->left, ' << ', $node->right); } protected function pExpr_BinaryOp_ShiftRight(BinaryOp\ShiftRight $node) { - return $this->pInfixOp('Expr_BinaryOp_ShiftRight', $node->left, ' >> ', $node->right); + return $this->pInfixOp(BinaryOp\ShiftRight::class, $node->left, ' >> ', $node->right); } protected function pExpr_BinaryOp_Pow(BinaryOp\Pow $node) { - return $this->pInfixOp('Expr_BinaryOp_Pow', $node->left, ' ** ', $node->right); + return $this->pInfixOp(BinaryOp\Pow::class, $node->left, ' ** ', $node->right); } protected function pExpr_BinaryOp_LogicalAnd(BinaryOp\LogicalAnd $node) { - return $this->pInfixOp('Expr_BinaryOp_LogicalAnd', $node->left, ' and ', $node->right); + return $this->pInfixOp(BinaryOp\LogicalAnd::class, $node->left, ' and ', $node->right); } protected function pExpr_BinaryOp_LogicalOr(BinaryOp\LogicalOr $node) { - return $this->pInfixOp('Expr_BinaryOp_LogicalOr', $node->left, ' or ', $node->right); + return $this->pInfixOp(BinaryOp\LogicalOr::class, $node->left, ' or ', $node->right); } protected function pExpr_BinaryOp_LogicalXor(BinaryOp\LogicalXor $node) { - return $this->pInfixOp('Expr_BinaryOp_LogicalXor', $node->left, ' xor ', $node->right); + return $this->pInfixOp(BinaryOp\LogicalXor::class, $node->left, ' xor ', $node->right); } protected function pExpr_BinaryOp_Equal(BinaryOp\Equal $node) { - return $this->pInfixOp('Expr_BinaryOp_Equal', $node->left, ' == ', $node->right); + return $this->pInfixOp(BinaryOp\Equal::class, $node->left, ' == ', $node->right); } protected function pExpr_BinaryOp_NotEqual(BinaryOp\NotEqual $node) { - return $this->pInfixOp('Expr_BinaryOp_NotEqual', $node->left, ' != ', $node->right); + return $this->pInfixOp(BinaryOp\NotEqual::class, $node->left, ' != ', $node->right); } protected function pExpr_BinaryOp_Identical(BinaryOp\Identical $node) { - return $this->pInfixOp('Expr_BinaryOp_Identical', $node->left, ' === ', $node->right); + return $this->pInfixOp(BinaryOp\Identical::class, $node->left, ' === ', $node->right); } protected function pExpr_BinaryOp_NotIdentical(BinaryOp\NotIdentical $node) { - return $this->pInfixOp('Expr_BinaryOp_NotIdentical', $node->left, ' !== ', $node->right); + return $this->pInfixOp(BinaryOp\NotIdentical::class, $node->left, ' !== ', $node->right); } protected function pExpr_BinaryOp_Spaceship(BinaryOp\Spaceship $node) { - return $this->pInfixOp('Expr_BinaryOp_Spaceship', $node->left, ' <=> ', $node->right); + return $this->pInfixOp(BinaryOp\Spaceship::class, $node->left, ' <=> ', $node->right); } protected function pExpr_BinaryOp_Greater(BinaryOp\Greater $node) { - return $this->pInfixOp('Expr_BinaryOp_Greater', $node->left, ' > ', $node->right); + return $this->pInfixOp(BinaryOp\Greater::class, $node->left, ' > ', $node->right); } protected function pExpr_BinaryOp_GreaterOrEqual(BinaryOp\GreaterOrEqual $node) { - return $this->pInfixOp('Expr_BinaryOp_GreaterOrEqual', $node->left, ' >= ', $node->right); + return $this->pInfixOp(BinaryOp\GreaterOrEqual::class, $node->left, ' >= ', $node->right); } protected function pExpr_BinaryOp_Smaller(BinaryOp\Smaller $node) { - return $this->pInfixOp('Expr_BinaryOp_Smaller', $node->left, ' < ', $node->right); + return $this->pInfixOp(BinaryOp\Smaller::class, $node->left, ' < ', $node->right); } protected function pExpr_BinaryOp_SmallerOrEqual(BinaryOp\SmallerOrEqual $node) { - return $this->pInfixOp('Expr_BinaryOp_SmallerOrEqual', $node->left, ' <= ', $node->right); + return $this->pInfixOp(BinaryOp\SmallerOrEqual::class, $node->left, ' <= ', $node->right); } protected function pExpr_BinaryOp_Coalesce(BinaryOp\Coalesce $node) { - return $this->pInfixOp('Expr_BinaryOp_Coalesce', $node->left, ' ?? ', $node->right); + return $this->pInfixOp(BinaryOp\Coalesce::class, $node->left, ' ?? ', $node->right); } protected function pExpr_Instanceof(Expr\Instanceof_ $node) { - return $this->pInfixOp('Expr_Instanceof', $node->expr, ' instanceof ', $node->class); + return $this->pInfixOp(Expr\Instanceof_::class, $node->expr, ' instanceof ', $node->class); } // Unary expressions protected function pExpr_BooleanNot(Expr\BooleanNot $node) { - return $this->pPrefixOp('Expr_BooleanNot', '!', $node->expr); + return $this->pPrefixOp(Expr\BooleanNot::class, '!', $node->expr); } protected function pExpr_BitwiseNot(Expr\BitwiseNot $node) { - return $this->pPrefixOp('Expr_BitwiseNot', '~', $node->expr); + return $this->pPrefixOp(Expr\BitwiseNot::class, '~', $node->expr); } protected function pExpr_UnaryMinus(Expr\UnaryMinus $node) { @@ -378,7 +389,7 @@ protected function pExpr_UnaryMinus(Expr\UnaryMinus $node) { // Enforce -(-$expr) instead of --$expr return '-(' . $this->p($node->expr) . ')'; } - return $this->pPrefixOp('Expr_UnaryMinus', '-', $node->expr); + return $this->pPrefixOp(Expr\UnaryMinus::class, '-', $node->expr); } protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) { @@ -386,65 +397,65 @@ protected function pExpr_UnaryPlus(Expr\UnaryPlus $node) { // Enforce +(+$expr) instead of ++$expr return '+(' . $this->p($node->expr) . ')'; } - return $this->pPrefixOp('Expr_UnaryPlus', '+', $node->expr); + return $this->pPrefixOp(Expr\UnaryPlus::class, '+', $node->expr); } protected function pExpr_PreInc(Expr\PreInc $node) { - return $this->pPrefixOp('Expr_PreInc', '++', $node->var); + return $this->pPrefixOp(Expr\PreInc::class, '++', $node->var); } protected function pExpr_PreDec(Expr\PreDec $node) { - return $this->pPrefixOp('Expr_PreDec', '--', $node->var); + return $this->pPrefixOp(Expr\PreDec::class, '--', $node->var); } protected function pExpr_PostInc(Expr\PostInc $node) { - return $this->pPostfixOp('Expr_PostInc', $node->var, '++'); + return $this->pPostfixOp(Expr\PostInc::class, $node->var, '++'); } protected function pExpr_PostDec(Expr\PostDec $node) { - return $this->pPostfixOp('Expr_PostDec', $node->var, '--'); + return $this->pPostfixOp(Expr\PostDec::class, $node->var, '--'); } protected function pExpr_ErrorSuppress(Expr\ErrorSuppress $node) { - return $this->pPrefixOp('Expr_ErrorSuppress', '@', $node->expr); + return $this->pPrefixOp(Expr\ErrorSuppress::class, '@', $node->expr); } protected function pExpr_YieldFrom(Expr\YieldFrom $node) { - return $this->pPrefixOp('Expr_YieldFrom', 'yield from ', $node->expr); + return $this->pPrefixOp(Expr\YieldFrom::class, 'yield from ', $node->expr); } protected function pExpr_Print(Expr\Print_ $node) { - return $this->pPrefixOp('Expr_Print', 'print ', $node->expr); + return $this->pPrefixOp(Expr\Print_::class, 'print ', $node->expr); } // Casts protected function pExpr_Cast_Int(Cast\Int_ $node) { - return $this->pPrefixOp('Expr_Cast_Int', '(int) ', $node->expr); + return $this->pPrefixOp(Cast\Int_::class, '(int) ', $node->expr); } protected function pExpr_Cast_Double(Cast\Double $node) { - return $this->pPrefixOp('Expr_Cast_Double', '(double) ', $node->expr); + return $this->pPrefixOp(Cast\Double::class, '(double) ', $node->expr); } protected function pExpr_Cast_String(Cast\String_ $node) { - return $this->pPrefixOp('Expr_Cast_String', '(string) ', $node->expr); + return $this->pPrefixOp(Cast\String_::class, '(string) ', $node->expr); } protected function pExpr_Cast_Array(Cast\Array_ $node) { - return $this->pPrefixOp('Expr_Cast_Array', '(array) ', $node->expr); + return $this->pPrefixOp(Cast\Array_::class, '(array) ', $node->expr); } protected function pExpr_Cast_Object(Cast\Object_ $node) { - return $this->pPrefixOp('Expr_Cast_Object', '(object) ', $node->expr); + return $this->pPrefixOp(Cast\Object_::class, '(object) ', $node->expr); } protected function pExpr_Cast_Bool(Cast\Bool_ $node) { - return $this->pPrefixOp('Expr_Cast_Bool', '(bool) ', $node->expr); + return $this->pPrefixOp(Cast\Bool_::class, '(bool) ', $node->expr); } protected function pExpr_Cast_Unset(Cast\Unset_ $node) { - return $this->pPrefixOp('Expr_Cast_Unset', '(unset) ', $node->expr); + return $this->pPrefixOp(Cast\Unset_::class, '(unset) ', $node->expr); } // Function calls and similar constructs @@ -482,12 +493,12 @@ protected function pExpr_Eval(Expr\Eval_ $node) { } protected function pExpr_Include(Expr\Include_ $node) { - static $map = array( + static $map = [ Expr\Include_::TYPE_INCLUDE => 'include', Expr\Include_::TYPE_INCLUDE_ONCE => 'include_once', Expr\Include_::TYPE_REQUIRE => 'require', Expr\Include_::TYPE_REQUIRE_ONCE => 'require_once', - ); + ]; return $map[$node->type] . ' ' . $this->p($node->expr); } @@ -535,8 +546,7 @@ protected function pExpr_ConstFetch(Expr\ConstFetch $node) { } protected function pExpr_ClassConstFetch(Expr\ClassConstFetch $node) { - return $this->p($node->class) . '::' - . (is_string($node->name) ? $node->name : $this->p($node->name)); + return $this->p($node->class) . '::' . $this->p($node->name); } protected function pExpr_PropertyFetch(Expr\PropertyFetch $node) { @@ -555,13 +565,13 @@ protected function pExpr_Closure(Expr\Closure $node) { return ($node->static ? 'static ' : '') . 'function ' . ($node->byRef ? '&' : '') . '(' . $this->pCommaSeparated($node->params) . ')' - . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')': '') - . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') - . ' {' . $this->pStmts($node->stmts) . "\n" . '}'; + . (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')' : '') + . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') + . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pExpr_ClosureUse(Expr\ClosureUse $node) { - return ($node->byRef ? '&' : '') . '$' . $node->var; + return ($node->byRef ? '&' : '') . $this->p($node->var); } protected function pExpr_New(Expr\New_ $node) { @@ -579,7 +589,7 @@ protected function pExpr_Clone(Expr\Clone_ $node) { protected function pExpr_Ternary(Expr\Ternary $node) { // a bit of cheating: we treat the ternary as a binary op where the ?...: part is the operator. // this is okay because the part between ? and : never needs parentheses. - return $this->pInfixOp('Expr_Ternary', + return $this->pInfixOp(Expr\Ternary::class, $node->cond, ' ?' . (null !== $node->if ? ' ' . $this->p($node->if) . ' ' : '') . ': ', $node->else ); } @@ -606,10 +616,11 @@ protected function pExpr_Yield(Expr\Yield_ $node) { protected function pStmt_Namespace(Stmt\Namespace_ $node) { if ($this->canUseSemicolonNamespaces) { - return 'namespace ' . $this->p($node->name) . ';' . "\n" . $this->pStmts($node->stmts, false); + return 'namespace ' . $this->p($node->name) . ';' + . $this->nl . $this->pStmts($node->stmts, false); } else { return 'namespace' . (null !== $node->name ? ' ' . $this->p($node->name) : '') - . ' {' . $this->pStmts($node->stmts) . "\n" . '}'; + . ' {' . $this->pStmts($node->stmts) . $this->nl . '}'; } } @@ -625,7 +636,7 @@ protected function pStmt_GroupUse(Stmt\GroupUse $node) { protected function pStmt_UseUse(Stmt\UseUse $node) { return $this->pUseType($node->type) . $this->p($node->name) - . ($node->name->getLast() !== $node->alias ? ' as ' . $node->alias : ''); + . (null !== $node->alias ? ' as ' . $node->alias : ''); } protected function pUseType($type) { @@ -636,7 +647,7 @@ protected function pUseType($type) { protected function pStmt_Interface(Stmt\Interface_ $node) { return 'interface ' . $node->name . (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '') - . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_Class(Stmt\Class_ $node) { @@ -645,14 +656,14 @@ protected function pStmt_Class(Stmt\Class_ $node) { protected function pStmt_Trait(Stmt\Trait_ $node) { return 'trait ' . $node->name - . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_TraitUse(Stmt\TraitUse $node) { return 'use ' . $this->pCommaSeparated($node->traits) . (empty($node->adaptations) ? ';' - : ' {' . $this->pStmts($node->adaptations) . "\n" . '}'); + : ' {' . $this->pStmts($node->adaptations) . $this->nl . '}'); } protected function pStmt_TraitUseAdaptation_Precedence(Stmt\TraitUseAdaptation\Precedence $node) { @@ -681,9 +692,9 @@ protected function pStmt_ClassMethod(Stmt\ClassMethod $node) { return $this->pModifiers($node->flags) . 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pCommaSeparated($node->params) . ')' - . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') + . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') . (null !== $node->stmts - ? "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}' + ? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}' : ';'); } @@ -695,8 +706,8 @@ protected function pStmt_ClassConst(Stmt\ClassConst $node) { protected function pStmt_Function(Stmt\Function_ $node) { return 'function ' . ($node->byRef ? '&' : '') . $node->name . '(' . $this->pCommaSeparated($node->params) . ')' - . (null !== $node->returnType ? ' : ' . $this->pType($node->returnType) : '') - . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + . (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '') + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_Const(Stmt\Const_ $node) { @@ -705,7 +716,7 @@ protected function pStmt_Const(Stmt\Const_ $node) { protected function pStmt_Declare(Stmt\Declare_ $node) { return 'declare (' . $this->pCommaSeparated($node->declares) . ')' - . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . "\n" . '}' : ';'); + . (null !== $node->stmts ? ' {' . $this->pStmts($node->stmts) . $this->nl . '}' : ';'); } protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) { @@ -716,18 +727,18 @@ protected function pStmt_DeclareDeclare(Stmt\DeclareDeclare $node) { protected function pStmt_If(Stmt\If_ $node) { return 'if (' . $this->p($node->cond) . ') {' - . $this->pStmts($node->stmts) . "\n" . '}' - . $this->pImplode($node->elseifs) - . (null !== $node->else ? $this->p($node->else) : ''); + . $this->pStmts($node->stmts) . $this->nl . '}' + . ($node->elseifs ? ' ' . $this->pImplode($node->elseifs, ' ') : '') + . (null !== $node->else ? ' ' . $this->p($node->else) : ''); } protected function pStmt_ElseIf(Stmt\ElseIf_ $node) { - return ' elseif (' . $this->p($node->cond) . ') {' - . $this->pStmts($node->stmts) . "\n" . '}'; + return 'elseif (' . $this->p($node->cond) . ') {' + . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_Else(Stmt\Else_ $node) { - return ' else {' . $this->pStmts($node->stmts) . "\n" . '}'; + return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_For(Stmt\For_ $node) { @@ -735,29 +746,29 @@ protected function pStmt_For(Stmt\For_ $node) { . $this->pCommaSeparated($node->init) . ';' . (!empty($node->cond) ? ' ' : '') . $this->pCommaSeparated($node->cond) . ';' . (!empty($node->loop) ? ' ' : '') . $this->pCommaSeparated($node->loop) - . ') {' . $this->pStmts($node->stmts) . "\n" . '}'; + . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_Foreach(Stmt\Foreach_ $node) { return 'foreach (' . $this->p($node->expr) . ' as ' . (null !== $node->keyVar ? $this->p($node->keyVar) . ' => ' : '') . ($node->byRef ? '&' : '') . $this->p($node->valueVar) . ') {' - . $this->pStmts($node->stmts) . "\n" . '}'; + . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_While(Stmt\While_ $node) { return 'while (' . $this->p($node->cond) . ') {' - . $this->pStmts($node->stmts) . "\n" . '}'; + . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_Do(Stmt\Do_ $node) { - return 'do {' . $this->pStmts($node->stmts) . "\n" + return 'do {' . $this->pStmts($node->stmts) . $this->nl . '} while (' . $this->p($node->cond) . ');'; } protected function pStmt_Switch(Stmt\Switch_ $node) { return 'switch (' . $this->p($node->cond) . ') {' - . $this->pStmts($node->cases) . "\n" . '}'; + . $this->pStmts($node->cases) . $this->nl . '}'; } protected function pStmt_Case(Stmt\Case_ $node) { @@ -766,18 +777,19 @@ protected function pStmt_Case(Stmt\Case_ $node) { } protected function pStmt_TryCatch(Stmt\TryCatch $node) { - return 'try {' . $this->pStmts($node->stmts) . "\n" . '}' - . $this->pImplode($node->catches) - . ($node->finally !== null ? $this->p($node->finally) : ''); + return 'try {' . $this->pStmts($node->stmts) . $this->nl . '}' + . ($node->catches ? ' ' . $this->pImplode($node->catches, ' ') : '') + . ($node->finally !== null ? ' ' . $this->p($node->finally) : ''); } protected function pStmt_Catch(Stmt\Catch_ $node) { - return ' catch (' . $this->pImplode($node->types, '|') . ' $' . $node->var . ') {' - . $this->pStmts($node->stmts) . "\n" . '}'; + return 'catch (' . $this->pImplode($node->types, '|') . ' ' + . $this->p($node->var) + . ') {' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_Finally(Stmt\Finally_ $node) { - return ' finally {' . $this->pStmts($node->stmts) . "\n" . '}'; + return 'finally {' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pStmt_Break(Stmt\Break_ $node) { @@ -806,6 +818,10 @@ protected function pStmt_Goto(Stmt\Goto_ $node) { // Other + protected function pStmt_Expression(Stmt\Expression $node) { + return $this->p($node->expr) . ';'; + } + protected function pStmt_Echo(Stmt\Echo_ $node) { return 'echo ' . $this->pCommaSeparated($node->exprs) . ';'; } @@ -819,7 +835,7 @@ protected function pStmt_Global(Stmt\Global_ $node) { } protected function pStmt_StaticVar(Stmt\StaticVar $node) { - return '$' . $node->name + return $this->p($node->var) . (null !== $node->default ? ' = ' . $this->p($node->default) : ''); } @@ -829,7 +845,7 @@ protected function pStmt_Unset(Stmt\Unset_ $node) { protected function pStmt_InlineHTML(Stmt\InlineHTML $node) { $newline = $node->getAttribute('hasLeadingNewline', true) ? "\n" : ''; - return '?>' . $this->pNoIndent($newline . $node->value) . '' . $newline . $node->value . 'p($node); - } - protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) { return $this->pModifiers($node->flags) . 'class' . $afterClassToken . (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '') . (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '') - . "\n" . '{' . $this->pStmts($node->stmts) . "\n" . '}'; + . $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'; } protected function pObjectProperty($node) { @@ -862,15 +874,6 @@ protected function pObjectProperty($node) { } } - protected function pModifiers($modifiers) { - return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '') - . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '') - . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '') - . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '') - . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '') - . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : ''); - } - protected function pEncapsList(array $encapsList, $quote) { $return = ''; foreach ($encapsList as $element) { @@ -884,6 +887,10 @@ protected function pEncapsList(array $encapsList, $quote) { return $return; } + protected function pSingleQuotedString(string $string) { + return '\'' . addcslashes($string, '\'\\') . '\''; + } + protected function escapeString($string, $quote) { if (null === $quote) { // For doc strings, don't escape newlines @@ -897,7 +904,7 @@ protected function escapeString($string, $quote) { $oct = decoct(ord($matches[1])); if ($matches[2] !== '') { // If there is a trailing digit, use the full three character form - return '\\' . str_pad($oct, 3, '0', STR_PAD_LEFT); + return '\\' . str_pad($oct, 3, '0', \STR_PAD_LEFT); } return '\\' . $oct; }, $escaped); @@ -924,19 +931,7 @@ protected function encapsedContainsEndLabel(array $parts, $label) { } protected function pDereferenceLhs(Node $node) { - if ($node instanceof Expr\Variable - || $node instanceof Name - || $node instanceof Expr\ArrayDimFetch - || $node instanceof Expr\PropertyFetch - || $node instanceof Expr\StaticPropertyFetch - || $node instanceof Expr\FuncCall - || $node instanceof Expr\MethodCall - || $node instanceof Expr\StaticCall - || $node instanceof Expr\Array_ - || $node instanceof Scalar\String_ - || $node instanceof Expr\ConstFetch - || $node instanceof Expr\ClassConstFetch - ) { + if (!$this->dereferenceLhsRequiresParens($node)) { return $this->p($node); } else { return '(' . $this->p($node) . ')'; @@ -944,23 +939,20 @@ protected function pDereferenceLhs(Node $node) { } protected function pCallLhs(Node $node) { - if ($node instanceof Name - || $node instanceof Expr\Variable - || $node instanceof Expr\ArrayDimFetch - || $node instanceof Expr\FuncCall - || $node instanceof Expr\MethodCall - || $node instanceof Expr\StaticCall - || $node instanceof Expr\Array_ - ) { + if (!$this->callLhsRequiresParens($node)) { return $this->p($node); } else { return '(' . $this->p($node) . ')'; } } + /** + * @param Node[] $nodes + * @return bool + */ private function hasNodeWithComments(array $nodes) { foreach ($nodes as $node) { - if ($node && $node->getAttribute('comments')) { + if ($node && $node->getComments()) { return true; } } @@ -971,7 +963,7 @@ private function pMaybeMultiline(array $nodes, $trailingComma = false) { if (!$this->hasNodeWithComments($nodes)) { return $this->pCommaSeparated($nodes); } else { - return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . "\n"; + return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl; } } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php b/app/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php index 24bae5936..2339c75a3 100644 --- a/app/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php +++ b/app/vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php @@ -1,84 +1,139 @@ - array( 0, 1), - 'Expr_BitwiseNot' => array( 10, 1), - 'Expr_PreInc' => array( 10, 1), - 'Expr_PreDec' => array( 10, 1), - 'Expr_PostInc' => array( 10, -1), - 'Expr_PostDec' => array( 10, -1), - 'Expr_UnaryPlus' => array( 10, 1), - 'Expr_UnaryMinus' => array( 10, 1), - 'Expr_Cast_Int' => array( 10, 1), - 'Expr_Cast_Double' => array( 10, 1), - 'Expr_Cast_String' => array( 10, 1), - 'Expr_Cast_Array' => array( 10, 1), - 'Expr_Cast_Object' => array( 10, 1), - 'Expr_Cast_Bool' => array( 10, 1), - 'Expr_Cast_Unset' => array( 10, 1), - 'Expr_ErrorSuppress' => array( 10, 1), - 'Expr_Instanceof' => array( 20, 0), - 'Expr_BooleanNot' => array( 30, 1), - 'Expr_BinaryOp_Mul' => array( 40, -1), - 'Expr_BinaryOp_Div' => array( 40, -1), - 'Expr_BinaryOp_Mod' => array( 40, -1), - 'Expr_BinaryOp_Plus' => array( 50, -1), - 'Expr_BinaryOp_Minus' => array( 50, -1), - 'Expr_BinaryOp_Concat' => array( 50, -1), - 'Expr_BinaryOp_ShiftLeft' => array( 60, -1), - 'Expr_BinaryOp_ShiftRight' => array( 60, -1), - 'Expr_BinaryOp_Smaller' => array( 70, 0), - 'Expr_BinaryOp_SmallerOrEqual' => array( 70, 0), - 'Expr_BinaryOp_Greater' => array( 70, 0), - 'Expr_BinaryOp_GreaterOrEqual' => array( 70, 0), - 'Expr_BinaryOp_Equal' => array( 80, 0), - 'Expr_BinaryOp_NotEqual' => array( 80, 0), - 'Expr_BinaryOp_Identical' => array( 80, 0), - 'Expr_BinaryOp_NotIdentical' => array( 80, 0), - 'Expr_BinaryOp_Spaceship' => array( 80, 0), - 'Expr_BinaryOp_BitwiseAnd' => array( 90, -1), - 'Expr_BinaryOp_BitwiseXor' => array(100, -1), - 'Expr_BinaryOp_BitwiseOr' => array(110, -1), - 'Expr_BinaryOp_BooleanAnd' => array(120, -1), - 'Expr_BinaryOp_BooleanOr' => array(130, -1), - 'Expr_BinaryOp_Coalesce' => array(140, 1), - 'Expr_Ternary' => array(150, -1), + const FIXUP_PREC_LEFT = 0; // LHS operand affected by precedence + const FIXUP_PREC_RIGHT = 1; // RHS operand affected by precedence + const FIXUP_CALL_LHS = 2; // LHS of call + const FIXUP_DEREF_LHS = 3; // LHS of dereferencing operation + const FIXUP_BRACED_NAME = 4; // Name operand that may require bracing + const FIXUP_VAR_BRACED_NAME = 5; // Name operand that may require ${} bracing + const FIXUP_ENCAPSED = 6; // Encapsed string part + + protected $precedenceMap = [ + // [precedence, associativity] + // where for precedence -1 is %left, 0 is %nonassoc and 1 is %right + BinaryOp\Pow::class => [ 0, 1], + Expr\BitwiseNot::class => [ 10, 1], + Expr\PreInc::class => [ 10, 1], + Expr\PreDec::class => [ 10, 1], + Expr\PostInc::class => [ 10, -1], + Expr\PostDec::class => [ 10, -1], + Expr\UnaryPlus::class => [ 10, 1], + Expr\UnaryMinus::class => [ 10, 1], + Cast\Int_::class => [ 10, 1], + Cast\Double::class => [ 10, 1], + Cast\String_::class => [ 10, 1], + Cast\Array_::class => [ 10, 1], + Cast\Object_::class => [ 10, 1], + Cast\Bool_::class => [ 10, 1], + Cast\Unset_::class => [ 10, 1], + Expr\ErrorSuppress::class => [ 10, 1], + Expr\Instanceof_::class => [ 20, 0], + Expr\BooleanNot::class => [ 30, 1], + BinaryOp\Mul::class => [ 40, -1], + BinaryOp\Div::class => [ 40, -1], + BinaryOp\Mod::class => [ 40, -1], + BinaryOp\Plus::class => [ 50, -1], + BinaryOp\Minus::class => [ 50, -1], + BinaryOp\Concat::class => [ 50, -1], + BinaryOp\ShiftLeft::class => [ 60, -1], + BinaryOp\ShiftRight::class => [ 60, -1], + BinaryOp\Smaller::class => [ 70, 0], + BinaryOp\SmallerOrEqual::class => [ 70, 0], + BinaryOp\Greater::class => [ 70, 0], + BinaryOp\GreaterOrEqual::class => [ 70, 0], + BinaryOp\Equal::class => [ 80, 0], + BinaryOp\NotEqual::class => [ 80, 0], + BinaryOp\Identical::class => [ 80, 0], + BinaryOp\NotIdentical::class => [ 80, 0], + BinaryOp\Spaceship::class => [ 80, 0], + BinaryOp\BitwiseAnd::class => [ 90, -1], + BinaryOp\BitwiseXor::class => [100, -1], + BinaryOp\BitwiseOr::class => [110, -1], + BinaryOp\BooleanAnd::class => [120, -1], + BinaryOp\BooleanOr::class => [130, -1], + BinaryOp\Coalesce::class => [140, 1], + Expr\Ternary::class => [150, -1], // parser uses %left for assignments, but they really behave as %right - 'Expr_Assign' => array(160, 1), - 'Expr_AssignRef' => array(160, 1), - 'Expr_AssignOp_Plus' => array(160, 1), - 'Expr_AssignOp_Minus' => array(160, 1), - 'Expr_AssignOp_Mul' => array(160, 1), - 'Expr_AssignOp_Div' => array(160, 1), - 'Expr_AssignOp_Concat' => array(160, 1), - 'Expr_AssignOp_Mod' => array(160, 1), - 'Expr_AssignOp_BitwiseAnd' => array(160, 1), - 'Expr_AssignOp_BitwiseOr' => array(160, 1), - 'Expr_AssignOp_BitwiseXor' => array(160, 1), - 'Expr_AssignOp_ShiftLeft' => array(160, 1), - 'Expr_AssignOp_ShiftRight' => array(160, 1), - 'Expr_AssignOp_Pow' => array(160, 1), - 'Expr_YieldFrom' => array(165, 1), - 'Expr_Print' => array(168, 1), - 'Expr_BinaryOp_LogicalAnd' => array(170, -1), - 'Expr_BinaryOp_LogicalXor' => array(180, -1), - 'Expr_BinaryOp_LogicalOr' => array(190, -1), - 'Expr_Include' => array(200, -1), - ); - - protected $noIndentToken; + Expr\Assign::class => [160, 1], + Expr\AssignRef::class => [160, 1], + AssignOp\Plus::class => [160, 1], + AssignOp\Minus::class => [160, 1], + AssignOp\Mul::class => [160, 1], + AssignOp\Div::class => [160, 1], + AssignOp\Concat::class => [160, 1], + AssignOp\Mod::class => [160, 1], + AssignOp\BitwiseAnd::class => [160, 1], + AssignOp\BitwiseOr::class => [160, 1], + AssignOp\BitwiseXor::class => [160, 1], + AssignOp\ShiftLeft::class => [160, 1], + AssignOp\ShiftRight::class => [160, 1], + AssignOp\Pow::class => [160, 1], + Expr\YieldFrom::class => [165, 1], + Expr\Print_::class => [168, 1], + BinaryOp\LogicalAnd::class => [170, -1], + BinaryOp\LogicalXor::class => [180, -1], + BinaryOp\LogicalOr::class => [190, -1], + Expr\Include_::class => [200, -1], + ]; + + /** @var int Current indentation level. */ + protected $indentLevel; + /** @var string Newline including current indentation. */ + protected $nl; + /** @var string Token placed at end of doc string to ensure it is followed by a newline. */ protected $docStringEndToken; + /** @var bool Whether semicolon namespaces can be used (i.e. no global namespace is used) */ protected $canUseSemicolonNamespaces; + /** @var array Pretty printer options */ protected $options; + /** @var TokenStream Original tokens for use in format-preserving pretty print */ + protected $origTokens; + /** @var Internal\Differ Differ for node lists */ + protected $nodeListDiffer; + /** @var bool[] Map determining whether a certain character is a label character */ + protected $labelCharMap; + /** + * @var int[][] Map from token classes and subnode names to FIXUP_* constants. This is used + * during format-preserving prints to place additional parens/braces if necessary. + */ + protected $fixupMap; + /** + * @var int[][] Map from "{$node->getType()}->{$subNode}" to ['left' => $l, 'right' => $r], + * where $l and $r specify the token type that needs to be stripped when removing + * this node. + */ + protected $removalMap; + /** + * @var mixed[] Map from "{$node->getType()}->{$subNode}" to [$find, $extraLeft, $extraRight]. + * $find is an optional token after which the insertion occurs. $extraLeft/Right + * are optionally added before/after the main insertions. + */ + protected $insertionMap; + /** + * @var string[] Map From "{$node->getType()}->{$subNode}" to string that should be inserted + * between elements of this list subnode. + */ + protected $listInsertionMap; + /** @var int[] Map from "{$node->getType()}->{$subNode}" to token before which the modifiers + * should be reprinted. */ + protected $modifierChangeMap; + /** * Creates a pretty printer instance using the given options. * @@ -89,13 +144,48 @@ abstract class PrettyPrinterAbstract * @param array $options Dictionary of formatting options */ public function __construct(array $options = []) { - $this->noIndentToken = '_NO_INDENT_' . mt_rand(); $this->docStringEndToken = '_DOC_STRING_END_' . mt_rand(); $defaultOptions = ['shortArraySyntax' => false]; $this->options = $options + $defaultOptions; } + /** + * Reset pretty printing state. + */ + protected function resetState() { + $this->indentLevel = 0; + $this->nl = "\n"; + $this->origTokens = null; + } + + /** + * Set indentation level + * + * @param int $level Level in number of spaces + */ + protected function setIndentLevel(int $level) { + $this->indentLevel = $level; + $this->nl = "\n" . \str_repeat(' ', $level); + } + + /** + * Increase indentation level. + */ + protected function indent() { + $this->indentLevel += 4; + $this->nl .= ' '; + } + + /** + * Decrease indentation level. + */ + protected function outdent() { + assert($this->indentLevel >= 4); + $this->indentLevel -= 4; + $this->nl = "\n" . str_repeat(' ', $this->indentLevel); + } + /** * Pretty prints an array of statements. * @@ -103,7 +193,8 @@ public function __construct(array $options = []) { * * @return string Pretty printed statements */ - public function prettyPrint(array $stmts) { + public function prettyPrint(array $stmts) : string { + $this->resetState(); $this->preprocessNodes($stmts); return ltrim($this->handleMagicTokens($this->pStmts($stmts, false))); @@ -116,7 +207,8 @@ public function prettyPrint(array $stmts) { * * @return string Pretty printed node */ - public function prettyPrintExpr(Expr $node) { + public function prettyPrintExpr(Expr $node) : string { + $this->resetState(); return $this->handleMagicTokens($this->p($node)); } @@ -127,7 +219,7 @@ public function prettyPrintExpr(Expr $node) { * * @return string Pretty printed statements */ - public function prettyPrintFile(array $stmts) { + public function prettyPrintFile(array $stmts) : string { if (!$stmts) { return "name) { $this->canUseSemicolonNamespaces = false; + break; } } } - protected function handleMagicTokens($str) { - // Drop no-indent tokens - $str = str_replace($this->noIndentToken, '', $str); - + /** + * Handles (and removes) no-indent and doc-string-end tokens. + * + * @param string $str + * @return string + */ + protected function handleMagicTokens(string $str) : string { // Replace doc-string-end tokens with nothing or a newline $str = str_replace($this->docStringEndToken . ";\n", ";\n", $str); $str = str_replace($this->docStringEndToken, "\n", $str); @@ -178,53 +274,74 @@ protected function handleMagicTokens($str) { * * @return string Pretty printed statements */ - protected function pStmts(array $nodes, $indent = true) { + protected function pStmts(array $nodes, bool $indent = true) : string { + if ($indent) { + $this->indent(); + } + $result = ''; foreach ($nodes as $node) { - $comments = $node->getAttribute('comments', array()); + $comments = $node->getComments(); if ($comments) { - $result .= "\n" . $this->pComments($comments); + $result .= $this->nl . $this->pComments($comments); if ($node instanceof Stmt\Nop) { continue; } } - $result .= "\n" . $this->p($node) . ($node instanceof Expr ? ';' : ''); + $result .= $this->nl . $this->p($node); } if ($indent) { - return preg_replace('~\n(?!$|' . $this->noIndentToken . ')~', "\n ", $result); - } else { - return $result; + $this->outdent(); } + + return $result; } /** - * Pretty prints a node. + * Pretty-print an infix operation while taking precedence into account. * - * @param Node $node Node to be pretty printed + * @param string $class Node class of operator + * @param Node $leftNode Left-hand side node + * @param string $operatorString String representation of the operator + * @param Node $rightNode Right-hand side node * - * @return string Pretty printed node + * @return string Pretty printed infix operation */ - protected function p(Node $node) { - return $this->{'p' . $node->getType()}($node); - } - - protected function pInfixOp($type, Node $leftNode, $operatorString, Node $rightNode) { - list($precedence, $associativity) = $this->precedenceMap[$type]; + protected function pInfixOp(string $class, Node $leftNode, string $operatorString, Node $rightNode) : string { + list($precedence, $associativity) = $this->precedenceMap[$class]; return $this->pPrec($leftNode, $precedence, $associativity, -1) . $operatorString . $this->pPrec($rightNode, $precedence, $associativity, 1); } - protected function pPrefixOp($type, $operatorString, Node $node) { - list($precedence, $associativity) = $this->precedenceMap[$type]; + /** + * Pretty-print a prefix operation while taking precedence into account. + * + * @param string $class Node class of operator + * @param string $operatorString String representation of the operator + * @param Node $node Node + * + * @return string Pretty printed prefix operation + */ + protected function pPrefixOp(string $class, string $operatorString, Node $node) : string { + list($precedence, $associativity) = $this->precedenceMap[$class]; return $operatorString . $this->pPrec($node, $precedence, $associativity, 1); } - protected function pPostfixOp($type, Node $node, $operatorString) { - list($precedence, $associativity) = $this->precedenceMap[$type]; + /** + * Pretty-print a postfix operation while taking precedence into account. + * + * @param string $class Node class of operator + * @param string $operatorString String representation of the operator + * @param Node $node Node + * + * @return string Pretty printed postfix operation + */ + protected function pPostfixOp(string $class, Node $node, string $operatorString) : string { + list($precedence, $associativity) = $this->precedenceMap[$class]; return $this->pPrec($node, $precedence, $associativity, -1) . $operatorString; } @@ -240,12 +357,12 @@ protected function pPostfixOp($type, Node $node, $operatorString) { * * @return string The pretty printed node */ - protected function pPrec(Node $node, $parentPrecedence, $parentAssociativity, $childPosition) { - $type = $node->getType(); - if (isset($this->precedenceMap[$type])) { - $childPrecedence = $this->precedenceMap[$type][0]; + protected function pPrec(Node $node, int $parentPrecedence, int $parentAssociativity, int $childPosition) : string { + $class = \get_class($node); + if (isset($this->precedenceMap[$class])) { + $childPrecedence = $this->precedenceMap[$class][0]; if ($childPrecedence > $parentPrecedence - || ($parentPrecedence == $childPrecedence && $parentAssociativity != $childPosition) + || ($parentPrecedence === $childPrecedence && $parentAssociativity !== $childPosition) ) { return '(' . $this->p($node) . ')'; } @@ -262,8 +379,8 @@ protected function pPrec(Node $node, $parentPrecedence, $parentAssociativity, $c * * @return string Imploded pretty printed nodes */ - protected function pImplode(array $nodes, $glue = '') { - $pNodes = array(); + protected function pImplode(array $nodes, string $glue = '') : string { + $pNodes = []; foreach ($nodes as $node) { if (null === $node) { $pNodes[] = ''; @@ -282,7 +399,7 @@ protected function pImplode(array $nodes, $glue = '') { * * @return string Comma separated pretty printed nodes */ - protected function pCommaSeparated(array $nodes) { + protected function pCommaSeparated(array $nodes) : string { return $this->pImplode($nodes, ', '); } @@ -296,53 +413,934 @@ protected function pCommaSeparated(array $nodes) { * * @return string Comma separated pretty printed nodes in multiline style */ - protected function pCommaSeparatedMultiline(array $nodes, $trailingComma) { + protected function pCommaSeparatedMultiline(array $nodes, bool $trailingComma) : string { + $this->indent(); + $result = ''; $lastIdx = count($nodes) - 1; foreach ($nodes as $idx => $node) { if ($node !== null) { - $comments = $node->getAttribute('comments', array()); + $comments = $node->getComments(); if ($comments) { - $result .= "\n" . $this->pComments($comments); + $result .= $this->nl . $this->pComments($comments); } - $result .= "\n" . $this->p($node); + $result .= $this->nl . $this->p($node); } else { - $result .= "\n"; + $result .= $this->nl; } if ($trailingComma || $idx !== $lastIdx) { $result .= ','; } } - return preg_replace('~\n(?!$|' . $this->noIndentToken . ')~', "\n ", $result); + $this->outdent(); + return $result; } /** - * Signals the pretty printer that a string shall not be indented. + * Prints reformatted text of the passed comments. * - * @param string $string Not to be indented string + * @param Comment[] $comments List of comments * - * @return string String marked with $this->noIndentToken's. + * @return string Reformatted text of comments */ - protected function pNoIndent($string) { - return str_replace("\n", "\n" . $this->noIndentToken, $string); + protected function pComments(array $comments) : string { + $formattedComments = []; + + foreach ($comments as $comment) { + $formattedComments[] = str_replace("\n", $this->nl, $comment->getReformattedText()); + } + + return implode($this->nl, $formattedComments); } /** - * Prints reformatted text of the passed comments. + * Perform a format-preserving pretty print of an AST. * - * @param Comment[] $comments List of comments + * The format preservation is best effort. For some changes to the AST the formatting will not + * be preserved (at least not locally). * - * @return string Reformatted text of comments + * In order to use this method a number of prerequisites must be satisfied: + * * The startTokenPos and endTokenPos attributes in the lexer must be enabled. + * * The CloningVisitor must be run on the AST prior to modification. + * * The original tokens must be provided, using the getTokens() method on the lexer. + * + * @param Node[] $stmts Modified AST with links to original AST + * @param Node[] $origStmts Original AST with token offset information + * @param array $origTokens Tokens of the original code + * + * @return string */ - protected function pComments(array $comments) { - $formattedComments = []; + public function printFormatPreserving(array $stmts, array $origStmts, array $origTokens) : string { + $this->initializeNodeListDiffer(); + $this->initializeLabelCharMap(); + $this->initializeFixupMap(); + $this->initializeRemovalMap(); + $this->initializeInsertionMap(); + $this->initializeListInsertionMap(); + $this->initializeModifierChangeMap(); - foreach ($comments as $comment) { - $formattedComments[] = $comment->getReformattedText(); + $this->resetState(); + $this->origTokens = new TokenStream($origTokens); + + $this->preprocessNodes($stmts); + + $pos = 0; + $result = $this->pArray($stmts, $origStmts, $pos, 0, 'stmts', null, "\n"); + if (null !== $result) { + $result .= $this->origTokens->getTokenCode($pos, count($origTokens), 0); + } else { + // Fallback + // TODO Add pStmts($stmts, false); + } + + return ltrim($this->handleMagicTokens($result)); + } + + protected function pFallback(Node $node) { + return $this->{'p' . $node->getType()}($node); + } + + /** + * Pretty prints a node. + * + * This method also handles formatting preservation for nodes. + * + * @param Node $node Node to be pretty printed + * @param bool $parentFormatPreserved Whether parent node has preserved formatting + * + * @return string Pretty printed node + */ + protected function p(Node $node, $parentFormatPreserved = false) : string { + // No orig tokens means this is a normal pretty print without preservation of formatting + if (!$this->origTokens) { + return $this->{'p' . $node->getType()}($node); } - return implode("\n", $formattedComments); + /** @var Node $origNode */ + $origNode = $node->getAttribute('origNode'); + if (null === $origNode) { + return $this->pFallback($node); + } + + $class = \get_class($node); + \assert($class === \get_class($origNode)); + + $startPos = $origNode->getStartTokenPos(); + $endPos = $origNode->getEndTokenPos(); + \assert($startPos >= 0 && $endPos >= 0); + + $fallbackNode = $node; + if ($node instanceof Expr\New_ && $node->class instanceof Stmt\Class_) { + // Normalize node structure of anonymous classes + $node = PrintableNewAnonClassNode::fromNewNode($node); + $origNode = PrintableNewAnonClassNode::fromNewNode($origNode); + } + + // InlineHTML node does not contain closing and opening PHP tags. If the parent formatting + // is not preserved, then we need to use the fallback code to make sure the tags are + // printed. + if ($node instanceof Stmt\InlineHTML && !$parentFormatPreserved) { + return $this->pFallback($fallbackNode); + } + + $indentAdjustment = $this->indentLevel - $this->origTokens->getIndentationBefore($startPos); + + $type = $node->getType(); + $fixupInfo = $this->fixupMap[$class] ?? null; + + $result = ''; + $pos = $startPos; + foreach ($node->getSubNodeNames() as $subNodeName) { + $subNode = $node->$subNodeName; + $origSubNode = $origNode->$subNodeName; + + if ((!$subNode instanceof Node && $subNode !== null) + || (!$origSubNode instanceof Node && $origSubNode !== null) + ) { + if ($subNode === $origSubNode) { + // Unchanged, can reuse old code + continue; + } + + if (is_array($subNode) && is_array($origSubNode)) { + // Array subnode changed, we might be able to reconstruct it + $listResult = $this->pArray( + $subNode, $origSubNode, $pos, $indentAdjustment, $subNodeName, + $fixupInfo[$subNodeName] ?? null, + $this->listInsertionMap[$type . '->' . $subNodeName] ?? null + ); + if (null === $listResult) { + return $this->pFallback($fallbackNode); + } + + $result .= $listResult; + continue; + } + + if (is_int($subNode) && is_int($origSubNode)) { + // Check if this is a modifier change + $key = $type . '->' . $subNodeName; + if (!isset($this->modifierChangeMap[$key])) { + return $this->pFallback($fallbackNode); + } + + $findToken = $this->modifierChangeMap[$key]; + $result .= $this->pModifiers($subNode); + $pos = $this->origTokens->findRight($pos, $findToken); + continue; + } + + // If a non-node, non-array subnode changed, we don't be able to do a partial + // reconstructions, as we don't have enough offset information. Pretty print the + // whole node instead. + return $this->pFallback($fallbackNode); + } + + $extraLeft = ''; + $extraRight = ''; + if ($origSubNode !== null) { + $subStartPos = $origSubNode->getStartTokenPos(); + $subEndPos = $origSubNode->getEndTokenPos(); + \assert($subStartPos >= 0 && $subEndPos >= 0); + } else { + if ($subNode === null) { + // Both null, nothing to do + continue; + } + + // A node has been inserted, check if we have insertion information for it + $key = $type . '->' . $subNodeName; + if (!isset($this->insertionMap[$key])) { + return $this->pFallback($fallbackNode); + } + + list($findToken, $extraLeft, $extraRight) = $this->insertionMap[$key]; + if (null !== $findToken) { + $subStartPos = $this->origTokens->findRight($pos, $findToken) + 1; + } else { + $subStartPos = $pos; + } + if (null === $extraLeft && null !== $extraRight) { + // If inserting on the right only, skipping whitespace looks better + $subStartPos = $this->origTokens->skipRightWhitespace($subStartPos); + } + $subEndPos = $subStartPos - 1; + } + + if (null === $subNode) { + // A node has been removed, check if we have removal information for it + $key = $type . '->' . $subNodeName; + if (!isset($this->removalMap[$key])) { + return $this->pFallback($fallbackNode); + } + + // Adjust positions to account for additional tokens that must be skipped + $removalInfo = $this->removalMap[$key]; + if (isset($removalInfo['left'])) { + $subStartPos = $this->origTokens->skipLeft($subStartPos - 1, $removalInfo['left']) + 1; + } + if (isset($removalInfo['right'])) { + $subEndPos = $this->origTokens->skipRight($subEndPos + 1, $removalInfo['right']) - 1; + } + } + + $result .= $this->origTokens->getTokenCode($pos, $subStartPos, $indentAdjustment); + + if (null !== $subNode) { + $result .= $extraLeft; + + $origIndentLevel = $this->indentLevel; + $this->setIndentLevel($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment); + + // If it's the same node that was previously in this position, it certainly doesn't + // need fixup. It's important to check this here, because our fixup checks are more + // conservative than strictly necessary. + if (isset($fixupInfo[$subNodeName]) + && $subNode->getAttribute('origNode') !== $origSubNode + ) { + $fixup = $fixupInfo[$subNodeName]; + $res = $this->pFixup($fixup, $subNode, $class, $subStartPos, $subEndPos); + } else { + $res = $this->p($subNode, true); + } + + $this->safeAppend($result, $res); + $this->setIndentLevel($origIndentLevel); + + $result .= $extraRight; + } + + $pos = $subEndPos + 1; + } + + $result .= $this->origTokens->getTokenCode($pos, $endPos + 1, $indentAdjustment); + return $result; + } + + /** + * Perform a format-preserving pretty print of an array. + * + * @param array $nodes New nodes + * @param array $origNodes Original nodes + * @param int $pos Current token position (updated by reference) + * @param int $indentAdjustment Adjustment for indentation + * @param string $subNodeName Name of array subnode. + * @param null|int $fixup Fixup information for array item nodes + * @param null|string $insertStr Separator string to use for insertions + * + * @return null|string Result of pretty print or null if cannot preserve formatting + */ + protected function pArray( + array $nodes, array $origNodes, int &$pos, int $indentAdjustment, + string $subNodeName, $fixup, $insertStr + ) { + $diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes); + + $beforeFirstKeepOrReplace = true; + $delayedAdd = []; + $lastElemIndentLevel = $this->indentLevel; + + $insertNewline = false; + if ($insertStr === "\n") { + $insertStr = ''; + $insertNewline = true; + } + + if ($subNodeName === 'stmts' && \count($origNodes) === 1 && \count($nodes) !== 1) { + $startPos = $origNodes[0]->getStartTokenPos(); + $endPos = $origNodes[0]->getEndTokenPos(); + \assert($startPos >= 0 && $endPos >= 0); + if (!$this->origTokens->haveBraces($startPos, $endPos)) { + // This was a single statement without braces, but either additional statements + // have been added, or the single statement has been removed. This requires the + // addition of braces. For now fall back. + // TODO: Try to preserve formatting + return null; + } + } + + $result = ''; + foreach ($diff as $i => $diffElem) { + $diffType = $diffElem->type; + /** @var Node|null $arrItem */ + $arrItem = $diffElem->new; + /** @var Node|null $origArrItem */ + $origArrItem = $diffElem->old; + + if ($diffType === DiffElem::TYPE_KEEP || $diffType === DiffElem::TYPE_REPLACE) { + $beforeFirstKeepOrReplace = false; + + if ($origArrItem === null || $arrItem === null) { + // We can only handle the case where both are null + if ($origArrItem === $arrItem) { + continue; + } + return null; + } + + if (!$arrItem instanceof Node || !$origArrItem instanceof Node) { + // We can only deal with nodes. This can occur for Names, which use string arrays. + return null; + } + + $itemStartPos = $origArrItem->getStartTokenPos(); + $itemEndPos = $origArrItem->getEndTokenPos(); + \assert($itemStartPos >= 0 && $itemEndPos >= 0); + + if ($itemEndPos < $itemStartPos) { + // End can be before start for Nop nodes, because offsets refer to non-whitespace + // locations, which for an "empty" node might result in an inverted order. + assert($origArrItem instanceof Stmt\Nop); + continue; + } + + $origIndentLevel = $this->indentLevel; + $lastElemIndentLevel = $this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment; + $this->setIndentLevel($lastElemIndentLevel); + + $comments = $arrItem->getComments(); + $origComments = $origArrItem->getComments(); + $commentStartPos = $origComments ? $origComments[0]->getTokenPos() : $itemStartPos; + \assert($commentStartPos >= 0); + + $commentsChanged = $comments !== $origComments; + if ($commentsChanged) { + // Remove old comments + $itemStartPos = $commentStartPos; + } + + if (!empty($delayedAdd)) { + $result .= $this->origTokens->getTokenCode( + $pos, $commentStartPos, $indentAdjustment); + + /** @var Node $delayedAddNode */ + foreach ($delayedAdd as $delayedAddNode) { + if ($insertNewline) { + $delayedAddComments = $delayedAddNode->getComments(); + if ($delayedAddComments) { + $result .= $this->pComments($delayedAddComments) . $this->nl; + } + } + + $this->safeAppend($result, $this->p($delayedAddNode, true)); + + if ($insertNewline) { + $result .= $insertStr . $this->nl; + } else { + $result .= $insertStr; + } + } + + $result .= $this->origTokens->getTokenCode( + $commentStartPos, $itemStartPos, $indentAdjustment); + + $delayedAdd = []; + } else { + $result .= $this->origTokens->getTokenCode( + $pos, $itemStartPos, $indentAdjustment); + } + + if ($commentsChanged && $comments) { + // Add new comments + $result .= $this->pComments($comments) . $this->nl; + } + } elseif ($diffType === DiffElem::TYPE_ADD) { + if (null === $insertStr) { + // We don't have insertion information for this list type + return null; + } + + if ($insertStr === ', ' && $this->isMultiline($origNodes)) { + $insertStr = ','; + $insertNewline = true; + } + + if ($beforeFirstKeepOrReplace) { + // Will be inserted at the next "replace" or "keep" element + $delayedAdd[] = $arrItem; + continue; + } + + $itemStartPos = $pos; + $itemEndPos = $pos - 1; + + $origIndentLevel = $this->indentLevel; + $this->setIndentLevel($lastElemIndentLevel); + + if ($insertNewline) { + $comments = $arrItem->getComments(); + if ($comments) { + $result .= $this->nl . $this->pComments($comments); + } + $result .= $insertStr . $this->nl; + } else { + $result .= $insertStr; + } + } elseif ($diffType === DiffElem::TYPE_REMOVE) { + if ($i === 0) { + // TODO Handle removal at the start + return null; + } + + if (!$origArrItem instanceof Node) { + // We only support removal for nodes + return null; + } + + $itemEndPos = $origArrItem->getEndTokenPos(); + \assert($itemEndPos >= 0); + + $pos = $itemEndPos + 1; + continue; + } else { + throw new \Exception("Shouldn't happen"); + } + + if (null !== $fixup && $arrItem->getAttribute('origNode') !== $origArrItem) { + $res = $this->pFixup($fixup, $arrItem, null, $itemStartPos, $itemEndPos); + } else { + $res = $this->p($arrItem, true); + } + $this->safeAppend($result, $res); + + $this->setIndentLevel($origIndentLevel); + $pos = $itemEndPos + 1; + } + + if (!empty($delayedAdd)) { + // TODO Handle insertion into empty list + return null; + } + + return $result; + } + + /** + * Print node with fixups. + * + * Fixups here refer to the addition of extra parentheses, braces or other characters, that + * are required to preserve program semantics in a certain context (e.g. to maintain precedence + * or because only certain expressions are allowed in certain places). + * + * @param int $fixup Fixup type + * @param Node $subNode Subnode to print + * @param string|null $parentClass Class of parent node + * @param int $subStartPos Original start pos of subnode + * @param int $subEndPos Original end pos of subnode + * + * @return string Result of fixed-up print of subnode + */ + protected function pFixup(int $fixup, Node $subNode, $parentClass, int $subStartPos, int $subEndPos) : string { + switch ($fixup) { + case self::FIXUP_PREC_LEFT: + case self::FIXUP_PREC_RIGHT: + if (!$this->origTokens->haveParens($subStartPos, $subEndPos)) { + list($precedence, $associativity) = $this->precedenceMap[$parentClass]; + return $this->pPrec($subNode, $precedence, $associativity, + $fixup === self::FIXUP_PREC_LEFT ? -1 : 1); + } + break; + case self::FIXUP_CALL_LHS: + if ($this->callLhsRequiresParens($subNode) + && !$this->origTokens->haveParens($subStartPos, $subEndPos) + ) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_DEREF_LHS: + if ($this->dereferenceLhsRequiresParens($subNode) + && !$this->origTokens->haveParens($subStartPos, $subEndPos) + ) { + return '(' . $this->p($subNode) . ')'; + } + break; + case self::FIXUP_BRACED_NAME: + case self::FIXUP_VAR_BRACED_NAME: + if ($subNode instanceof Expr + && !$this->origTokens->haveBraces($subStartPos, $subEndPos) + ) { + return ($fixup === self::FIXUP_VAR_BRACED_NAME ? '$' : '') + . '{' . $this->p($subNode) . '}'; + } + break; + case self::FIXUP_ENCAPSED: + if (!$subNode instanceof Scalar\EncapsedStringPart + && !$this->origTokens->haveBraces($subStartPos, $subEndPos) + ) { + return '{' . $this->p($subNode) . '}'; + } + break; + default: + throw new \Exception('Cannot happen'); + } + + // Nothing special to do + return $this->p($subNode); + } + + /** + * Appends to a string, ensuring whitespace between label characters. + * + * Example: "echo" and "$x" result in "echo$x", but "echo" and "x" result in "echo x". + * Without safeAppend the result would be "echox", which does not preserve semantics. + * + * @param string $str + * @param string $append + */ + protected function safeAppend(string &$str, string $append) { + if ($str === "") { + $str = $append; + return; + } + + if ($append === "") { + return; + } + + if (!$this->labelCharMap[$append[0]] + || !$this->labelCharMap[$str[\strlen($str) - 1]]) { + $str .= $append; + } else { + $str .= " " . $append; + } + } + + /** + * Determines whether the LHS of a call must be wrapped in parenthesis. + * + * @param Node $node LHS of a call + * + * @return bool Whether parentheses are required + */ + protected function callLhsRequiresParens(Node $node) : bool { + return !($node instanceof Node\Name + || $node instanceof Expr\Variable + || $node instanceof Expr\ArrayDimFetch + || $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\StaticCall + || $node instanceof Expr\Array_); + } + + /** + * Determines whether the LHS of a dereferencing operation must be wrapped in parenthesis. + * + * @param Node $node LHS of dereferencing operation + * + * @return bool Whether parentheses are required + */ + protected function dereferenceLhsRequiresParens(Node $node) : bool { + return !($node instanceof Expr\Variable + || $node instanceof Node\Name + || $node instanceof Expr\ArrayDimFetch + || $node instanceof Expr\PropertyFetch + || $node instanceof Expr\StaticPropertyFetch + || $node instanceof Expr\FuncCall + || $node instanceof Expr\MethodCall + || $node instanceof Expr\StaticCall + || $node instanceof Expr\Array_ + || $node instanceof Scalar\String_ + || $node instanceof Expr\ConstFetch + || $node instanceof Expr\ClassConstFetch); + } + + /** + * Print modifiers, including trailing whitespace. + * + * @param int $modifiers Modifier mask to print + * + * @return string Printed modifiers + */ + protected function pModifiers(int $modifiers) { + return ($modifiers & Stmt\Class_::MODIFIER_PUBLIC ? 'public ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_PROTECTED ? 'protected ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_PRIVATE ? 'private ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_STATIC ? 'static ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_ABSTRACT ? 'abstract ' : '') + . ($modifiers & Stmt\Class_::MODIFIER_FINAL ? 'final ' : ''); + } + + /** + * Determine whether a list of nodes uses multiline formatting. + * + * @param (Node|null)[] $nodes Node list + * + * @return bool Whether multiline formatting is used + */ + protected function isMultiline(array $nodes) : bool { + if (\count($nodes) < 2) { + return false; + } + + $pos = -1; + foreach ($nodes as $node) { + if (null === $node) { + continue; + } + + $endPos = $node->getEndTokenPos() + 1; + if ($pos >= 0) { + $text = $this->origTokens->getTokenCode($pos, $endPos, 0); + if (false === strpos($text, "\n")) { + // We require that a newline is present between *every* item. If the formatting + // is inconsistent, with only some items having newlines, we don't consider it + // as multiline + return false; + } + } + $pos = $endPos; + } + + return true; + } + + /** + * Lazily initializes label char map. + * + * The label char map determines whether a certain character may occur in a label. + */ + protected function initializeLabelCharMap() { + if ($this->labelCharMap) return; + + $this->labelCharMap = []; + for ($i = 0; $i < 256; $i++) { + // Since PHP 7.1 The lower range is 0x80. However, we also want to support code for + // older versions. + $this->labelCharMap[chr($i)] = $i >= 0x7f || ctype_alnum($i); + } + } + + /** + * Lazily initializes node list differ. + * + * The node list differ is used to determine differences between two array subnodes. + */ + protected function initializeNodeListDiffer() { + if ($this->nodeListDiffer) return; + + $this->nodeListDiffer = new Internal\Differ(function ($a, $b) { + if ($a instanceof Node && $b instanceof Node) { + return $a === $b->getAttribute('origNode'); + } + // Can happen for array destructuring + return $a === null && $b === null; + }); + } + + /** + * Lazily initializes fixup map. + * + * The fixup map is used to determine whether a certain subnode of a certain node may require + * some kind of "fixup" operation, e.g. the addition of parenthesis or braces. + */ + protected function initializeFixupMap() { + if ($this->fixupMap) return; + + $this->fixupMap = [ + Expr\PreInc::class => ['var' => self::FIXUP_PREC_RIGHT], + Expr\PreDec::class => ['var' => self::FIXUP_PREC_RIGHT], + Expr\PostInc::class => ['var' => self::FIXUP_PREC_LEFT], + Expr\PostDec::class => ['var' => self::FIXUP_PREC_LEFT], + Expr\Instanceof_::class => [ + 'expr' => self::FIXUP_PREC_LEFT, + 'class' => self::FIXUP_PREC_RIGHT, + ], + Expr\Ternary::class => [ + 'cond' => self::FIXUP_PREC_LEFT, + 'else' => self::FIXUP_PREC_RIGHT, + ], + + Expr\FuncCall::class => ['name' => self::FIXUP_CALL_LHS], + Expr\StaticCall::class => ['class' => self::FIXUP_DEREF_LHS], + Expr\ArrayDimFetch::class => ['var' => self::FIXUP_DEREF_LHS], + Expr\MethodCall::class => [ + 'var' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Expr\StaticPropertyFetch::class => [ + 'class' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_VAR_BRACED_NAME, + ], + Expr\PropertyFetch::class => [ + 'var' => self::FIXUP_DEREF_LHS, + 'name' => self::FIXUP_BRACED_NAME, + ], + Scalar\Encapsed::class => [ + 'parts' => self::FIXUP_ENCAPSED, + ], + ]; + + $binaryOps = [ + BinaryOp\Pow::class, BinaryOp\Mul::class, BinaryOp\Div::class, BinaryOp\Mod::class, + BinaryOp\Plus::class, BinaryOp\Minus::class, BinaryOp\Concat::class, + BinaryOp\ShiftLeft::class, BinaryOp\ShiftRight::class, BinaryOp\Smaller::class, + BinaryOp\SmallerOrEqual::class, BinaryOp\Greater::class, BinaryOp\GreaterOrEqual::class, + BinaryOp\Equal::class, BinaryOp\NotEqual::class, BinaryOp\Identical::class, + BinaryOp\NotIdentical::class, BinaryOp\Spaceship::class, BinaryOp\BitwiseAnd::class, + BinaryOp\BitwiseXor::class, BinaryOp\BitwiseOr::class, BinaryOp\BooleanAnd::class, + BinaryOp\BooleanOr::class, BinaryOp\Coalesce::class, BinaryOp\LogicalAnd::class, + BinaryOp\LogicalXor::class, BinaryOp\LogicalOr::class, + ]; + foreach ($binaryOps as $binaryOp) { + $this->fixupMap[$binaryOp] = [ + 'left' => self::FIXUP_PREC_LEFT, + 'right' => self::FIXUP_PREC_RIGHT + ]; + } + + $assignOps = [ + Expr\Assign::class, Expr\AssignRef::class, AssignOp\Plus::class, AssignOp\Minus::class, + AssignOp\Mul::class, AssignOp\Div::class, AssignOp\Concat::class, AssignOp\Mod::class, + AssignOp\BitwiseAnd::class, AssignOp\BitwiseOr::class, AssignOp\BitwiseXor::class, + AssignOp\ShiftLeft::class, AssignOp\ShiftRight::class, AssignOp\Pow::class, + ]; + foreach ($assignOps as $assignOp) { + $this->fixupMap[$assignOp] = [ + 'var' => self::FIXUP_PREC_LEFT, + 'expr' => self::FIXUP_PREC_RIGHT, + ]; + } + + $prefixOps = [ + Expr\BitwiseNot::class, Expr\BooleanNot::class, Expr\UnaryPlus::class, Expr\UnaryMinus::class, + Cast\Int_::class, Cast\Double::class, Cast\String_::class, Cast\Array_::class, + Cast\Object_::class, Cast\Bool_::class, Cast\Unset_::class, Expr\ErrorSuppress::class, + Expr\YieldFrom::class, Expr\Print_::class, Expr\Include_::class, + ]; + foreach ($prefixOps as $prefixOp) { + $this->fixupMap[$prefixOp] = ['expr' => self::FIXUP_PREC_RIGHT]; + } + } + + /** + * Lazily initializes the removal map. + * + * The removal map is used to determine which additional tokens should be returned when a + * certain node is replaced by null. + */ + protected function initializeRemovalMap() { + if ($this->removalMap) return; + + $stripBoth = ['left' => \T_WHITESPACE, 'right' => \T_WHITESPACE]; + $stripLeft = ['left' => \T_WHITESPACE]; + $stripRight = ['right' => \T_WHITESPACE]; + $stripDoubleArrow = ['right' => \T_DOUBLE_ARROW]; + $stripColon = ['left' => ':']; + $stripEquals = ['left' => '=']; + $this->removalMap = [ + 'Expr_ArrayDimFetch->dim' => $stripBoth, + 'Expr_ArrayItem->key' => $stripDoubleArrow, + 'Expr_Closure->returnType' => $stripColon, + 'Expr_Exit->expr' => $stripBoth, + 'Expr_Ternary->if' => $stripBoth, + 'Expr_Yield->key' => $stripDoubleArrow, + 'Expr_Yield->value' => $stripBoth, + 'Param->type' => $stripRight, + 'Param->default' => $stripEquals, + 'Stmt_Break->num' => $stripBoth, + 'Stmt_ClassMethod->returnType' => $stripColon, + 'Stmt_Class->extends' => ['left' => \T_EXTENDS], + 'Expr_PrintableNewAnonClass->extends' => ['left' => \T_EXTENDS], + 'Stmt_Continue->num' => $stripBoth, + 'Stmt_Foreach->keyVar' => $stripDoubleArrow, + 'Stmt_Function->returnType' => $stripColon, + 'Stmt_If->else' => $stripLeft, + 'Stmt_Namespace->name' => $stripLeft, + 'Stmt_PropertyProperty->default' => $stripEquals, + 'Stmt_Return->expr' => $stripBoth, + 'Stmt_StaticVar->default' => $stripEquals, + 'Stmt_TraitUseAdaptation_Alias->newName' => $stripLeft, + 'Stmt_TryCatch->finally' => $stripLeft, + // 'Stmt_Case->cond': Replace with "default" + // 'Stmt_Class->name': Unclear what to do + // 'Stmt_Declare->stmts': Not a plain node + // 'Stmt_TraitUseAdaptation_Alias->newModifier': Not a plain node + ]; + } + + protected function initializeInsertionMap() { + if ($this->insertionMap) return; + + // TODO: "yield" where both key and value are inserted doesn't work + $this->insertionMap = [ + 'Expr_ArrayDimFetch->dim' => ['[', null, null], + 'Expr_ArrayItem->key' => [null, null, ' => '], + 'Expr_Closure->returnType' => [')', ' : ', null], + 'Expr_Ternary->if' => ['?', ' ', ' '], + 'Expr_Yield->key' => [\T_YIELD, null, ' => '], + 'Expr_Yield->value' => [\T_YIELD, ' ', null], + 'Param->type' => [null, null, ' '], + 'Param->default' => [null, ' = ', null], + 'Stmt_Break->num' => [\T_BREAK, ' ', null], + 'Stmt_ClassMethod->returnType' => [')', ' : ', null], + 'Stmt_Class->extends' => [null, ' extends ', null], + 'Expr_PrintableNewAnonClass->extends' => [null, ' extends ', null], + 'Stmt_Continue->num' => [\T_CONTINUE, ' ', null], + 'Stmt_Foreach->keyVar' => [\T_AS, null, ' => '], + 'Stmt_Function->returnType' => [')', ' : ', null], + 'Stmt_If->else' => [null, ' ', null], + 'Stmt_Namespace->name' => [\T_NAMESPACE, ' ', null], + 'Stmt_PropertyProperty->default' => [null, ' = ', null], + 'Stmt_Return->expr' => [\T_RETURN, ' ', null], + 'Stmt_StaticVar->default' => [null, ' = ', null], + //'Stmt_TraitUseAdaptation_Alias->newName' => [T_AS, ' ', null], // TODO + 'Stmt_TryCatch->finally' => [null, ' ', null], + + // 'Expr_Exit->expr': Complicated due to optional () + // 'Stmt_Case->cond': Conversion from default to case + // 'Stmt_Class->name': Unclear + // 'Stmt_Declare->stmts': Not a proper node + // 'Stmt_TraitUseAdaptation_Alias->newModifier': Not a proper node + ]; + } + + protected function initializeListInsertionMap() { + if ($this->listInsertionMap) return; + + $this->listInsertionMap = [ + // special + //'Expr_ShellExec->parts' => '', // TODO These need to be treated more carefully + //'Scalar_Encapsed->parts' => '', + 'Stmt_Catch->types' => '|', + 'Stmt_If->elseifs' => ' ', + 'Stmt_TryCatch->catches' => ' ', + + // comma-separated lists + 'Expr_Array->items' => ', ', + 'Expr_Closure->params' => ', ', + 'Expr_Closure->uses' => ', ', + 'Expr_FuncCall->args' => ', ', + 'Expr_Isset->vars' => ', ', + 'Expr_List->items' => ', ', + 'Expr_MethodCall->args' => ', ', + 'Expr_New->args' => ', ', + 'Expr_PrintableNewAnonClass->args' => ', ', + 'Expr_StaticCall->args' => ', ', + 'Stmt_ClassConst->consts' => ', ', + 'Stmt_ClassMethod->params' => ', ', + 'Stmt_Class->implements' => ', ', + 'Expr_PrintableNewAnonClass->implements' => ', ', + 'Stmt_Const->consts' => ', ', + 'Stmt_Declare->declares' => ', ', + 'Stmt_Echo->exprs' => ', ', + 'Stmt_For->init' => ', ', + 'Stmt_For->cond' => ', ', + 'Stmt_For->loop' => ', ', + 'Stmt_Function->params' => ', ', + 'Stmt_Global->vars' => ', ', + 'Stmt_GroupUse->uses' => ', ', + 'Stmt_Interface->extends' => ', ', + 'Stmt_Property->props' => ', ', + 'Stmt_StaticVar->vars' => ', ', + 'Stmt_TraitUse->traits' => ', ', + 'Stmt_TraitUseAdaptation_Precedence->insteadof' => ', ', + 'Stmt_Unset->vars' => ', ', + 'Stmt_Use->uses' => ', ', + + // statement lists + 'Expr_Closure->stmts' => "\n", + 'Stmt_Case->stmts' => "\n", + 'Stmt_Catch->stmts' => "\n", + 'Stmt_Class->stmts' => "\n", + 'Expr_PrintableNewAnonClass->stmts' => "\n", + 'Stmt_Interface->stmts' => "\n", + 'Stmt_Trait->stmts' => "\n", + 'Stmt_ClassMethod->stmts' => "\n", + 'Stmt_Declare->stmts' => "\n", + 'Stmt_Do->stmts' => "\n", + 'Stmt_ElseIf->stmts' => "\n", + 'Stmt_Else->stmts' => "\n", + 'Stmt_Finally->stmts' => "\n", + 'Stmt_Foreach->stmts' => "\n", + 'Stmt_For->stmts' => "\n", + 'Stmt_Function->stmts' => "\n", + 'Stmt_If->stmts' => "\n", + 'Stmt_Namespace->stmts' => "\n", + 'Stmt_Switch->cases' => "\n", + 'Stmt_TraitUse->adaptations' => "\n", + 'Stmt_TryCatch->stmts' => "\n", + 'Stmt_While->stmts' => "\n", + ]; + } + + protected function initializeModifierChangeMap() { + if ($this->modifierChangeMap) return; + + $this->modifierChangeMap = [ + 'Stmt_ClassConst->flags' => \T_CONST, + 'Stmt_ClassMethod->flags' => \T_FUNCTION, + 'Stmt_Class->flags' => \T_CLASS, + 'Stmt_Property->flags' => \T_VARIABLE, + //'Stmt_TraitUseAdaptation_Alias->newModifier' => 0, // TODO + ]; + + // List of integer subnodes that are not modifiers: + // Expr_Include->type + // Stmt_GroupUse->type + // Stmt_Use->type + // Stmt_UseUse->type } } diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Serializer.php b/app/vendor/nikic/php-parser/lib/PhpParser/Serializer.php deleted file mode 100644 index 1dd790666..000000000 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Serializer.php +++ /dev/null @@ -1,18 +0,0 @@ -writer = new XMLWriter; - $this->writer->openMemory(); - $this->writer->setIndent(true); - } - - public function serialize(array $nodes) { - $this->writer->flush(); - $this->writer->startDocument('1.0', 'UTF-8'); - - $this->writer->startElement('AST'); - $this->writer->writeAttribute('xmlns:node', 'http://nikic.github.com/PHPParser/XML/node'); - $this->writer->writeAttribute('xmlns:subNode', 'http://nikic.github.com/PHPParser/XML/subNode'); - $this->writer->writeAttribute('xmlns:attribute', 'http://nikic.github.com/PHPParser/XML/attribute'); - $this->writer->writeAttribute('xmlns:scalar', 'http://nikic.github.com/PHPParser/XML/scalar'); - - $this->_serialize($nodes); - - $this->writer->endElement(); - - return $this->writer->outputMemory(); - } - - protected function _serialize($node) { - if ($node instanceof Node) { - $this->writer->startElement('node:' . $node->getType()); - - foreach ($node->getAttributes() as $name => $value) { - $this->writer->startElement('attribute:' . $name); - $this->_serialize($value); - $this->writer->endElement(); - } - - foreach ($node as $name => $subNode) { - $this->writer->startElement('subNode:' . $name); - $this->_serialize($subNode); - $this->writer->endElement(); - } - - $this->writer->endElement(); - } elseif ($node instanceof Comment) { - $this->writer->startElement('comment'); - $this->writer->writeAttribute('isDocComment', $node instanceof Comment\Doc ? 'true' : 'false'); - $this->writer->writeAttribute('line', (string) $node->getLine()); - $this->writer->text($node->getText()); - $this->writer->endElement(); - } elseif (is_array($node)) { - $this->writer->startElement('scalar:array'); - foreach ($node as $subNode) { - $this->_serialize($subNode); - } - $this->writer->endElement(); - } elseif (is_string($node)) { - $this->writer->writeElement('scalar:string', $node); - } elseif (is_int($node)) { - $this->writer->writeElement('scalar:int', (string) $node); - } elseif (is_float($node)) { - // TODO Higher precision conversion? - $this->writer->writeElement('scalar:float', (string) $node); - } elseif (true === $node) { - $this->writer->writeElement('scalar:true'); - } elseif (false === $node) { - $this->writer->writeElement('scalar:false'); - } elseif (null === $node) { - $this->writer->writeElement('scalar:null'); - } else { - throw new \InvalidArgumentException('Unexpected node type'); - } - } -} diff --git a/app/vendor/nikic/php-parser/lib/PhpParser/Unserializer.php b/app/vendor/nikic/php-parser/lib/PhpParser/Unserializer.php deleted file mode 100644 index 9c221a141..000000000 --- a/app/vendor/nikic/php-parser/lib/PhpParser/Unserializer.php +++ /dev/null @@ -1,18 +0,0 @@ -reader = new XMLReader; - } - - public function unserialize($string) { - $this->reader->XML($string); - - $this->reader->read(); - if ('AST' !== $this->reader->name) { - throw new DomainException('AST root element not found'); - } - - return $this->read($this->reader->depth); - } - - protected function read($depthLimit, $throw = true, &$nodeFound = null) { - $nodeFound = true; - while ($this->reader->read() && $depthLimit < $this->reader->depth) { - if (XMLReader::ELEMENT !== $this->reader->nodeType) { - continue; - } - - if ('node' === $this->reader->prefix) { - return $this->readNode(); - } elseif ('scalar' === $this->reader->prefix) { - return $this->readScalar(); - } elseif ('comment' === $this->reader->name) { - return $this->readComment(); - } else { - throw new DomainException(sprintf('Unexpected node of type "%s"', $this->reader->name)); - } - } - - $nodeFound = false; - if ($throw) { - throw new DomainException('Expected node or scalar'); - } - } - - protected function readNode() { - $className = $this->getClassNameFromType($this->reader->localName); - - // create the node without calling it's constructor - $node = unserialize( - sprintf( - "O:%d:\"%s\":1:{s:13:\"\0*\0attributes\";a:0:{}}", - strlen($className), $className - ) - ); - - $depthLimit = $this->reader->depth; - while ($this->reader->read() && $depthLimit < $this->reader->depth) { - if (XMLReader::ELEMENT !== $this->reader->nodeType) { - continue; - } - - $type = $this->reader->prefix; - if ('subNode' !== $type && 'attribute' !== $type) { - throw new DomainException( - sprintf('Expected sub node or attribute, got node of type "%s"', $this->reader->name) - ); - } - - $name = $this->reader->localName; - $value = $this->read($this->reader->depth); - - if ('subNode' === $type) { - $node->$name = $value; - } else { - $node->setAttribute($name, $value); - } - } - - return $node; - } - - protected function readScalar() { - switch ($name = $this->reader->localName) { - case 'array': - $depth = $this->reader->depth; - $array = array(); - while (true) { - $node = $this->read($depth, false, $nodeFound); - if (!$nodeFound) { - break; - } - $array[] = $node; - } - return $array; - case 'string': - return $this->reader->readString(); - case 'int': - return $this->parseInt($this->reader->readString()); - case 'float': - $text = $this->reader->readString(); - if (false === $float = filter_var($text, FILTER_VALIDATE_FLOAT)) { - throw new DomainException(sprintf('"%s" is not a valid float', $text)); - } - return $float; - case 'true': - case 'false': - case 'null': - if (!$this->reader->isEmptyElement) { - throw new DomainException(sprintf('"%s" scalar must be empty', $name)); - } - return constant($name); - default: - throw new DomainException(sprintf('Unknown scalar type "%s"', $name)); - } - } - - private function parseInt($text) { - if (false === $int = filter_var($text, FILTER_VALIDATE_INT)) { - throw new DomainException(sprintf('"%s" is not a valid integer', $text)); - } - return $int; - } - - protected function readComment() { - $className = $this->reader->getAttribute('isDocComment') === 'true' - ? 'PhpParser\Comment\Doc' - : 'PhpParser\Comment' - ; - return new $className( - $this->reader->readString(), - $this->parseInt($this->reader->getAttribute('line')) - ); - } - - protected function getClassNameFromType($type) { - $className = 'PhpParser\\Node\\' . strtr($type, '_', '\\'); - if (!class_exists($className)) { - $className .= '_'; - } - if (!class_exists($className)) { - throw new DomainException(sprintf('Unknown node type "%s"', $type)); - } - return $className; - } -} diff --git a/app/vendor/nikic/php-parser/lib/bootstrap.php b/app/vendor/nikic/php-parser/lib/bootstrap.php deleted file mode 100644 index b0f517822..000000000 --- a/app/vendor/nikic/php-parser/lib/bootstrap.php +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/app/vendor/nikic/php-parser/test/PhpParser/AutoloaderTest.php b/app/vendor/nikic/php-parser/test/PhpParser/AutoloaderTest.php deleted file mode 100644 index 8eeded839..000000000 --- a/app/vendor/nikic/php-parser/test/PhpParser/AutoloaderTest.php +++ /dev/null @@ -1,15 +0,0 @@ -assertTrue(class_exists('PhpParser\NodeVisitorAbstract')); - $this->assertFalse(class_exists('PHPParser_NodeVisitor_NameResolver')); - - $this->assertFalse(class_exists('PhpParser\FooBar')); - $this->assertFalse(class_exists('PHPParser_FooBar')); - } -} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php index 0f7418212..fe324d766 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/ClassTest.php @@ -1,4 +1,4 @@ -assertEquals( - new Stmt\Class_('SomeLogger', array( + new Stmt\Class_('SomeLogger', [ 'extends' => new Name('BaseLogger'), - 'implements' => array( + 'implements' => [ new Name('Namespaced\Logger'), new Name('SomeInterface'), new Name\FullyQualified('Fully\Qualified'), new Name\Relative('NamespaceRelative'), - ), - )), + ], + ]), $node ); } @@ -42,9 +43,9 @@ public function testAbstract() { ; $this->assertEquals( - new Stmt\Class_('Test', array( + new Stmt\Class_('Test', [ 'flags' => Stmt\Class_::MODIFIER_ABSTRACT - )), + ]), $node ); } @@ -56,9 +57,9 @@ public function testFinal() { ; $this->assertEquals( - new Stmt\Class_('Test', array( + new Stmt\Class_('Test', [ 'flags' => Stmt\Class_::MODIFIER_FINAL - )), + ]), $node ); } @@ -67,24 +68,24 @@ public function testStatementOrder() { $method = new Stmt\ClassMethod('testMethod'); $property = new Stmt\Property( Stmt\Class_::MODIFIER_PUBLIC, - array(new Stmt\PropertyProperty('testProperty')) + [new Stmt\PropertyProperty('testProperty')] ); - $const = new Stmt\ClassConst(array( + $const = new Stmt\ClassConst([ new Node\Const_('TEST_CONST', new Node\Scalar\String_('ABC')) - )); - $use = new Stmt\TraitUse(array(new Name('SomeTrait'))); + ]); + $use = new Stmt\TraitUse([new Name('SomeTrait')]); $node = $this->createClassBuilder('Test') ->addStmt($method) ->addStmt($property) - ->addStmts(array($const, $use)) + ->addStmts([$const, $use]) ->getNode() ; $this->assertEquals( - new Stmt\Class_('Test', array( - 'stmts' => array($use, $const, $property, $method) - )), + new Stmt\Class_('Test', [ + 'stmts' => [$use, $const, $property, $method] + ]), $node ); } @@ -100,11 +101,11 @@ public function testDocComment() { ->getNode(); $this->assertEquals( - new Stmt\Class_('Test', array(), array( - 'comments' => array( + new Stmt\Class_('Test', [], [ + 'comments' => [ new Comment\Doc($docComment) - ) - )), + ] + ]), $class ); @@ -113,11 +114,11 @@ public function testDocComment() { ->getNode(); $this->assertEquals( - new Stmt\Class_('Test', array(), array( - 'comments' => array( + new Stmt\Class_('Test', [], [ + 'comments' => [ new Comment\Doc($docComment) - ) - )), + ] + ]), $class ); } @@ -128,7 +129,7 @@ public function testDocComment() { */ public function testInvalidStmtError() { $this->createClassBuilder('Test') - ->addStmt(new Stmt\Echo_(array())) + ->addStmt(new Stmt\Echo_([])) ; } @@ -152,10 +153,10 @@ public function testEmptyName() { /** * @expectedException \LogicException - * @expectedExceptionMessage Name must be a string or an instance of PhpParser\Node\Name + * @expectedExceptionMessage Name must be a string or an instance of Node\Name */ public function testInvalidName() { $this->createClassBuilder('Test') - ->extend(array('Foo')); + ->extend(['Foo']); } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php index f6a9381d6..a2c621922 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/FunctionTest.php @@ -1,14 +1,16 @@ -assertEquals( - new Stmt\Function_('test', array( + new Stmt\Function_('test', [ 'byRef' => true - )), + ]), $node ); } public function testParams() { - $param1 = new Node\Param('test1'); - $param2 = new Node\Param('test2'); - $param3 = new Node\Param('test3'); + $param1 = new Node\Param(new Variable('test1')); + $param2 = new Node\Param(new Variable('test2')); + $param3 = new Node\Param(new Variable('test3')); $node = $this->createFunctionBuilder('test') ->addParam($param1) - ->addParams(array($param2, $param3)) + ->addParams([$param2, $param3]) ->getNode() ; $this->assertEquals( - new Stmt\Function_('test', array( - 'params' => array($param1, $param2, $param3) - )), + new Stmt\Function_('test', [ + 'params' => [$param1, $param2, $param3] + ]), $node ); } @@ -54,14 +56,18 @@ public function testStmts() { $node = $this->createFunctionBuilder('test') ->addStmt($stmt1) - ->addStmts(array($stmt2, $stmt3)) + ->addStmts([$stmt2, $stmt3]) ->getNode() ; $this->assertEquals( - new Stmt\Function_('test', array( - 'stmts' => array($stmt1, $stmt2, $stmt3) - )), + new Stmt\Function_('test', [ + 'stmts' => [ + new Stmt\Expression($stmt1), + new Stmt\Expression($stmt2), + new Stmt\Expression($stmt3), + ] + ]), $node ); } @@ -71,9 +77,9 @@ public function testDocComment() { ->setDocComment('/** Test */') ->getNode(); - $this->assertEquals(new Stmt\Function_('test', array(), array( - 'comments' => array(new Comment\Doc('/** Test */')) - )), $node); + $this->assertEquals(new Stmt\Function_('test', [], [ + 'comments' => [new Comment\Doc('/** Test */')] + ]), $node); } public function testReturnType() { @@ -81,9 +87,9 @@ public function testReturnType() { ->setReturnType('void') ->getNode(); - $this->assertEquals(new Stmt\Function_('test', array( + $this->assertEquals(new Stmt\Function_('test', [ 'returnType' => 'void' - ), array()), $node); + ], []), $node); } /** @@ -103,4 +109,13 @@ public function testInvalidParamError() { ->addParam(new Node\Name('foo')) ; } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Expected statement or expression node + */ + public function testAddNonStmt() { + $this->createFunctionBuilder('test') + ->addStmt(new Node\Name('Test')); + } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php index 72c586688..2c926b605 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/InterfaceTest.php @@ -1,4 +1,4 @@ -prettyPrint(array($node)); + return $pp->prettyPrint([$node]); } public function testEmpty() { $contract = $this->builder->getNode(); - $this->assertInstanceOf('PhpParser\Node\Stmt\Interface_', $contract); - $this->assertSame('Contract', $contract->name); + $this->assertInstanceOf(Stmt\Interface_::class, $contract); + $this->assertEquals(new Node\Identifier('Contract'), $contract->name); } public function testExtending() { $contract = $this->builder->extend('Space\Root1', 'Root2')->getNode(); $this->assertEquals( - new Stmt\Interface_('Contract', array( - 'extends' => array( + new Stmt\Interface_('Contract', [ + 'extends' => [ new Node\Name('Space\Root1'), new Node\Name('Root2') - ), - )), $contract + ], + ]), $contract ); } public function testAddMethod() { $method = new Stmt\ClassMethod('doSomething'); $contract = $this->builder->addStmt($method)->getNode(); - $this->assertSame(array($method), $contract->stmts); + $this->assertSame([$method], $contract->stmts); } public function testAddConst() { - $const = new Stmt\ClassConst(array( + $const = new Stmt\ClassConst([ new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458.0)) - )); + ]); $contract = $this->builder->addStmt($const)->getNode(); $this->assertSame(299792458.0, $contract->stmts[0]->consts[0]->value->value); } public function testOrder() { - $const = new Stmt\ClassConst(array( + $const = new Stmt\ClassConst([ new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458)) - )); + ]); $method = new Stmt\ClassMethod('doSomething'); $contract = $this->builder ->addStmt($method) @@ -64,8 +65,8 @@ public function testOrder() { ->getNode() ; - $this->assertInstanceOf('PhpParser\Node\Stmt\ClassConst', $contract->stmts[0]); - $this->assertInstanceOf('PhpParser\Node\Stmt\ClassMethod', $contract->stmts[1]); + $this->assertInstanceOf(Stmt\ClassConst::class, $contract->stmts[0]); + $this->assertInstanceOf(Stmt\ClassMethod::class, $contract->stmts[1]); } public function testDocComment() { @@ -73,9 +74,9 @@ public function testDocComment() { ->setDocComment('/** Test */') ->getNode(); - $this->assertEquals(new Stmt\Interface_('Contract', array(), array( - 'comments' => array(new Comment\Doc('/** Test */')) - )), $node); + $this->assertEquals(new Stmt\Interface_('Contract', [], [ + 'comments' => [new Comment\Doc('/** Test */')] + ]), $node); } /** @@ -87,9 +88,9 @@ public function testInvalidStmtError() { } public function testFullFunctional() { - $const = new Stmt\ClassConst(array( + $const = new Stmt\ClassConst([ new Node\Const_('SPEED_OF_LIGHT', new DNumber(299792458)) - )); + ]); $method = new Stmt\ClassMethod('doSomething'); $contract = $this->builder ->addStmt($method) @@ -102,4 +103,3 @@ public function testFullFunctional() { $this->assertTrue(interface_exists('Contract', false)); } } - diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php index 21c5617a2..0decbed0d 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/MethodTest.php @@ -1,14 +1,16 @@ -assertEquals( - new Stmt\ClassMethod('test', array( + new Stmt\ClassMethod('test', [ 'flags' => Stmt\Class_::MODIFIER_PUBLIC | Stmt\Class_::MODIFIER_ABSTRACT | Stmt\Class_::MODIFIER_STATIC, 'stmts' => null, - )), + ]), $node ); @@ -39,10 +41,10 @@ public function testModifiers() { ; $this->assertEquals( - new Stmt\ClassMethod('test', array( + new Stmt\ClassMethod('test', [ 'flags' => Stmt\Class_::MODIFIER_PROTECTED | Stmt\Class_::MODIFIER_FINAL - )), + ]), $node ); @@ -52,9 +54,9 @@ public function testModifiers() { ; $this->assertEquals( - new Stmt\ClassMethod('test', array( + new Stmt\ClassMethod('test', [ 'type' => Stmt\Class_::MODIFIER_PRIVATE - )), + ]), $node ); } @@ -66,28 +68,28 @@ public function testReturnByRef() { ; $this->assertEquals( - new Stmt\ClassMethod('test', array( + new Stmt\ClassMethod('test', [ 'byRef' => true - )), + ]), $node ); } public function testParams() { - $param1 = new Node\Param('test1'); - $param2 = new Node\Param('test2'); - $param3 = new Node\Param('test3'); + $param1 = new Node\Param(new Variable('test1')); + $param2 = new Node\Param(new Variable('test2')); + $param3 = new Node\Param(new Variable('test3')); $node = $this->createMethodBuilder('test') ->addParam($param1) - ->addParams(array($param2, $param3)) + ->addParams([$param2, $param3]) ->getNode() ; $this->assertEquals( - new Stmt\ClassMethod('test', array( - 'params' => array($param1, $param2, $param3) - )), + new Stmt\ClassMethod('test', [ + 'params' => [$param1, $param2, $param3] + ]), $node ); } @@ -99,14 +101,18 @@ public function testStmts() { $node = $this->createMethodBuilder('test') ->addStmt($stmt1) - ->addStmts(array($stmt2, $stmt3)) + ->addStmts([$stmt2, $stmt3]) ->getNode() ; $this->assertEquals( - new Stmt\ClassMethod('test', array( - 'stmts' => array($stmt1, $stmt2, $stmt3) - )), + new Stmt\ClassMethod('test', [ + 'stmts' => [ + new Stmt\Expression($stmt1), + new Stmt\Expression($stmt2), + new Stmt\Expression($stmt3), + ] + ]), $node ); } @@ -115,18 +121,18 @@ public function testDocComment() { ->setDocComment('/** Test */') ->getNode(); - $this->assertEquals(new Stmt\ClassMethod('test', array(), array( - 'comments' => array(new Comment\Doc('/** Test */')) - )), $node); + $this->assertEquals(new Stmt\ClassMethod('test', [], [ + 'comments' => [new Comment\Doc('/** Test */')] + ]), $node); } public function testReturnType() { $node = $this->createMethodBuilder('test') ->setReturnType('bool') ->getNode(); - $this->assertEquals(new Stmt\ClassMethod('test', array( + $this->assertEquals(new Stmt\ClassMethod('test', [ 'returnType' => 'bool' - ), array()), $node); + ], []), $node); } /** diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php index 88131fc33..b8dce39c2 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/NamespaceTest.php @@ -1,12 +1,13 @@ - array($docComment)) + [$stmt1, $stmt2, $stmt3], + ['comments' => [$docComment]] ); $node = $this->createNamespaceBuilder('Name\Space') ->addStmt($stmt1) - ->addStmts(array($stmt2, $stmt3)) + ->addStmts([$stmt2, $stmt3]) ->setDocComment($docComment) ->getNode() ; $this->assertEquals($expected, $node); - $node = $this->createNamespaceBuilder(new Node\Name(array('Name', 'Space'))) + $node = $this->createNamespaceBuilder(new Node\Name(['Name', 'Space'])) ->setDocComment($docComment) - ->addStmts(array($stmt1, $stmt2)) + ->addStmts([$stmt1, $stmt2]) ->addStmt($stmt3) ->getNode() ; diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php index e67ae99f2..e0606259c 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/ParamTest.php @@ -1,12 +1,13 @@ - 'bar', 'bar' => 'foo'), - new Expr\Array_(array( + ]) + ], + [ + ['foo' => 'bar', 'bar' => 'foo'], + new Expr\Array_([ new Expr\ArrayItem( new Scalar\String_('bar'), new Scalar\String_('foo') @@ -69,19 +70,19 @@ public function provideTestDefaultValues() { new Scalar\String_('foo'), new Scalar\String_('bar') ), - )) - ), - array( + ]) + ], + [ new Scalar\MagicConst\Dir, new Scalar\MagicConst\Dir - ) - ); + ] + ]; } /** - * @dataProvider provideTestTypeHints + * @dataProvider provideTestTypes */ - public function testTypeHints($typeHint, $expectedType) { + public function testTypes($typeHint, $expectedType) { $node = $this->createParamBuilder('test') ->setTypeHint($typeHint) ->getNode() @@ -95,38 +96,37 @@ public function testTypeHints($typeHint, $expectedType) { $type = $type->type; } - if ($expectedType instanceof Node\Name) { - $this->assertInstanceOf(get_class($expectedType), $type); - $this->assertEquals($expectedType, $type); - } else { - $this->assertSame($expectedType, $type); - } + $this->assertInstanceOf(get_class($expectedType), $type); + $this->assertEquals($expectedType, $type); } - public function provideTestTypeHints() { - return array( - array('array', 'array'), - array('callable', 'callable'), - array('bool', 'bool'), - array('int', 'int'), - array('float', 'float'), - array('string', 'string'), - array('iterable', 'iterable'), - array('object', 'object'), - array('Array', 'array'), - array('CALLABLE', 'callable'), - array('Some\Class', new Node\Name('Some\Class')), - array('\Foo', new Node\Name\FullyQualified('Foo')), - array('self', new Node\Name('self')), - array('?array', new Node\NullableType('array')), - array('?Some\Class', new Node\NullableType(new Node\Name('Some\Class'))), - array(new Node\Name('Some\Class'), new Node\Name('Some\Class')), - array(new Node\NullableType('int'), new Node\NullableType('int')), - array( + public function provideTestTypes() { + return [ + ['array', new Node\Identifier('array')], + ['callable', new Node\Identifier('callable')], + ['bool', new Node\Identifier('bool')], + ['int', new Node\Identifier('int')], + ['float', new Node\Identifier('float')], + ['string', new Node\Identifier('string')], + ['iterable', new Node\Identifier('iterable')], + ['object', new Node\Identifier('object')], + ['Array', new Node\Identifier('array')], + ['CALLABLE', new Node\Identifier('callable')], + ['Some\Class', new Node\Name('Some\Class')], + ['\Foo', new Node\Name\FullyQualified('Foo')], + ['self', new Node\Name('self')], + ['?array', new Node\NullableType(new Node\Identifier('array'))], + ['?Some\Class', new Node\NullableType(new Node\Name('Some\Class'))], + [new Node\Name('Some\Class'), new Node\Name('Some\Class')], + [ + new Node\NullableType(new Node\Identifier('int')), + new Node\NullableType(new Node\Identifier('int')) + ], + [ new Node\NullableType(new Node\Name('Some\Class')), new Node\NullableType(new Node\Name('Some\Class')) - ), - ); + ], + ]; } /** @@ -134,15 +134,15 @@ public function provideTestTypeHints() { * @expectedExceptionMessage Parameter type cannot be void */ public function testVoidTypeError() { - $this->createParamBuilder('test')->setTypeHint('void'); + $this->createParamBuilder('test')->setType('void'); } /** * @expectedException \LogicException - * @expectedExceptionMessage Type must be a string, or an instance of Name or NullableType + * @expectedExceptionMessage Type must be a string, or an instance of Name, Identifier or NullableType */ public function testInvalidTypeError() { - $this->createParamBuilder('test')->setTypeHint(new \stdClass); + $this->createParamBuilder('test')->setType(new \stdClass); } public function testByRef() { @@ -152,7 +152,7 @@ public function testByRef() { ; $this->assertEquals( - new Node\Param('test', null, null, true), + new Node\Param(new Expr\Variable('test'), null, null, true), $node ); } @@ -164,7 +164,7 @@ public function testVariadic() { ; $this->assertEquals( - new Node\Param('test', null, null, false, true), + new Node\Param(new Expr\Variable('test'), null, null, false, true), $node ); } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php index de8f4ce63..d7a5a70e2 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/PropertyTest.php @@ -1,4 +1,4 @@ -assertEquals( new Stmt\Property( Stmt\Class_::MODIFIER_PROTECTED, - array( + [ new Stmt\PropertyProperty('test') - ) + ] ), $node ); @@ -55,9 +56,9 @@ public function testModifiers() { $this->assertEquals( new Stmt\Property( Stmt\Class_::MODIFIER_PUBLIC, - array( + [ new Stmt\PropertyProperty('test') - ) + ] ), $node ); @@ -70,12 +71,12 @@ public function testDocComment() { $this->assertEquals(new Stmt\Property( Stmt\Class_::MODIFIER_PUBLIC, - array( + [ new Stmt\PropertyProperty('test') - ), - array( - 'comments' => array(new Comment\Doc('/** Test */')) - ) + ], + [ + 'comments' => [new Comment\Doc('/** Test */')] + ] ), $node); } @@ -92,42 +93,42 @@ public function testDefaultValues($value, $expectedValueNode) { } public function provideTestDefaultValues() { - return array( - array( + return [ + [ null, new Expr\ConstFetch(new Name('null')) - ), - array( + ], + [ true, new Expr\ConstFetch(new Name('true')) - ), - array( + ], + [ false, new Expr\ConstFetch(new Name('false')) - ), - array( + ], + [ 31415, new Scalar\LNumber(31415) - ), - array( + ], + [ 3.1415, new Scalar\DNumber(3.1415) - ), - array( + ], + [ 'Hallo World', new Scalar\String_('Hallo World') - ), - array( - array(1, 2, 3), - new Expr\Array_(array( + ], + [ + [1, 2, 3], + new Expr\Array_([ new Expr\ArrayItem(new Scalar\LNumber(1)), new Expr\ArrayItem(new Scalar\LNumber(2)), new Expr\ArrayItem(new Scalar\LNumber(3)), - )) - ), - array( - array('foo' => 'bar', 'bar' => 'foo'), - new Expr\Array_(array( + ]) + ], + [ + ['foo' => 'bar', 'bar' => 'foo'], + new Expr\Array_([ new Expr\ArrayItem( new Scalar\String_('bar'), new Scalar\String_('foo') @@ -136,12 +137,12 @@ public function provideTestDefaultValues() { new Scalar\String_('foo'), new Scalar\String_('bar') ), - )) - ), - array( + ]) + ], + [ new Scalar\MagicConst\Dir, new Scalar\MagicConst\Dir - ) - ); + ] + ]; } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php index 874bc4d27..666769dc3 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitTest.php @@ -1,12 +1,13 @@ -createTraitBuilder('TestTrait') ->setDocComment('/** Nice trait */') @@ -42,7 +43,7 @@ public function testStmtAddition() { */ public function testInvalidStmtError() { $this->createTraitBuilder('Test') - ->addStmt(new Stmt\Echo_(array())) + ->addStmt(new Stmt\Echo_([])) ; } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseAdaptationTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseAdaptationTest.php new file mode 100644 index 000000000..06f99dc35 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseAdaptationTest.php @@ -0,0 +1,121 @@ +createTraitUseAdaptationBuilder(null, 'foo'); + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar'), + (clone $builder)->as('bar')->getNode() + ); + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PUBLIC, null), + (clone $builder)->makePublic()->getNode() + ); + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PROTECTED, null), + (clone $builder)->makeProtected()->getNode() + ); + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Alias(null, 'foo', Class_::MODIFIER_PRIVATE, null), + (clone $builder)->makePrivate()->getNode() + ); + } + + public function testInsteadof() { + $node = $this->createTraitUseAdaptationBuilder('SomeTrait', 'foo') + ->insteadof('AnotherTrait') + ->getNode() + ; + + $this->assertEquals( + new Stmt\TraitUseAdaptation\Precedence( + new Name('SomeTrait'), + 'foo', + [new Name('AnotherTrait')] + ), + $node + ); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot set alias for not alias adaptation buider + */ + public function testAsOnNotAlias() { + $this->createTraitUseAdaptationBuilder('Test', 'foo') + ->insteadof('AnotherTrait') + ->as('bar') + ; + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot add overwritten traits for not precedence adaptation buider + */ + public function testInsteadofOnNotPrecedence() { + $this->createTraitUseAdaptationBuilder('Test', 'foo') + ->as('bar') + ->insteadof('AnotherTrait') + ; + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Precedence adaptation must have trait + */ + public function testInsteadofWithoutTrait() { + $this->createTraitUseAdaptationBuilder(null, 'foo') + ->insteadof('AnotherTrait') + ; + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot set access modifier for not alias adaptation buider + */ + public function testMakeOnNotAlias() { + $this->createTraitUseAdaptationBuilder('Test', 'foo') + ->insteadof('AnotherTrait') + ->makePublic() + ; + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Multiple access type modifiers are not allowed + */ + public function testMultipleMake() { + $this->createTraitUseAdaptationBuilder(null, 'foo') + ->makePrivate() + ->makePublic() + ; + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Type of adaptation is not defined + */ + public function testUndefinedType() { + $this->createTraitUseAdaptationBuilder(null, 'foo') + ->getNode() + ; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseTest.php new file mode 100644 index 000000000..fe5b3ee1b --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/TraitUseTest.php @@ -0,0 +1,57 @@ +createTraitUseBuilder('SomeTrait') + ->and('AnotherTrait') + ->getNode() + ; + + $this->assertEquals( + new Stmt\TraitUse([ + new Name('SomeTrait'), + new Name('AnotherTrait') + ]), + $node + ); + } + + public function testWith() { + $node = $this->createTraitUseBuilder('SomeTrait') + ->with(new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar')) + ->with((new TraitUseAdaptation(null, 'test'))->as('baz')) + ->getNode() + ; + + $this->assertEquals( + new Stmt\TraitUse([new Name('SomeTrait')], [ + new Stmt\TraitUseAdaptation\Alias(null, 'foo', null, 'bar'), + new Stmt\TraitUseAdaptation\Alias(null, 'test', null, 'baz') + ]), + $node + ); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Adaptation must have type TraitUseAdaptation + */ + public function testInvalidAdaptationNode() { + $this->createTraitUseBuilder('Test') + ->with(new Stmt\Echo_([])) + ; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php index adaeb3a5e..54ede584c 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Builder/UseTest.php @@ -1,10 +1,11 @@ -createUseBuilder('Foo\Bar')->getNode(); - $this->assertEquals(new Stmt\Use_(array( - new Stmt\UseUse(new Name('Foo\Bar'), 'Bar') - )), $node); + $this->assertEquals(new Stmt\Use_([ + new Stmt\UseUse(new Name('Foo\Bar'), null) + ]), $node); $node = $this->createUseBuilder(new Name('Foo\Bar'))->as('XYZ')->getNode(); - $this->assertEquals(new Stmt\Use_(array( + $this->assertEquals(new Stmt\Use_([ new Stmt\UseUse(new Name('Foo\Bar'), 'XYZ') - )), $node); + ]), $node); $node = $this->createUseBuilder('foo\bar', Stmt\Use_::TYPE_FUNCTION)->as('foo')->getNode(); - $this->assertEquals(new Stmt\Use_(array( + $this->assertEquals(new Stmt\Use_([ new Stmt\UseUse(new Name('foo\bar'), 'foo') - ), Stmt\Use_::TYPE_FUNCTION), $node); - } + ], Stmt\Use_::TYPE_FUNCTION), $node); - public function testNonExistingMethod() { - $this->setExpectedException('LogicException', 'Method "foo" does not exist'); - $builder = $this->createUseBuilder('Test'); - $builder->foo(); + $node = $this->createUseBuilder('foo\BAR', Stmt\Use_::TYPE_CONSTANT)->as('FOO')->getNode(); + $this->assertEquals(new Stmt\Use_([ + new Stmt\UseUse(new Name('foo\BAR'), 'FOO') + ], Stmt\Use_::TYPE_CONSTANT), $node); } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php b/app/vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php index 1c3ef18df..08b0736d0 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/BuilderFactoryTest.php @@ -1,10 +1,19 @@ -assertEquals( + new String_("foo"), + $factory->val("foo") ); } - public function testNonExistingMethod() { - $this->setExpectedException('LogicException', 'Method "foo" does not exist'); + public function testConcat() { $factory = new BuilderFactory(); - $factory->foo(); + $varA = new Expr\Variable('a'); + $varB = new Expr\Variable('b'); + $varC = new Expr\Variable('c'); + + $this->assertEquals( + new Concat($varA, $varB), + $factory->concat($varA, $varB) + ); + $this->assertEquals( + new Concat(new Concat($varA, $varB), $varC), + $factory->concat($varA, $varB, $varC) + ); + $this->assertEquals( + new Concat(new Concat(new String_("a"), $varB), new String_("c")), + $factory->concat("a", $varB, "c") + ); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Expected at least two expressions + */ + public function testConcatOneError() { + (new BuilderFactory())->concat("a"); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Expected string or Expr + */ + public function testConcatInvalidExpr() { + (new BuilderFactory())->concat("a", 42); + } + + public function testArgs() { + $factory = new BuilderFactory(); + $unpack = new Arg(new Expr\Variable('c'), false, true); + $this->assertEquals( + [ + new Arg(new Expr\Variable('a')), + new Arg(new String_('b')), + $unpack + ], + $factory->args([new Expr\Variable('a'), 'b', $unpack]) + ); + } + + public function testCalls() { + $factory = new BuilderFactory(); + + // Simple function call + $this->assertEquals( + new Expr\FuncCall( + new Name('var_dump'), + [new Arg(new String_('str'))] + ), + $factory->funcCall('var_dump', ['str']) + ); + // Dynamic function call + $this->assertEquals( + new Expr\FuncCall(new Expr\Variable('fn')), + $factory->funcCall(new Expr\Variable('fn')) + ); + + // Simple method call + $this->assertEquals( + new Expr\MethodCall( + new Expr\Variable('obj'), + new Identifier('method'), + [new Arg(new LNumber(42))] + ), + $factory->methodCall(new Expr\Variable('obj'), 'method', [42]) + ); + // Explicitly pass Identifier node + $this->assertEquals( + new Expr\MethodCall( + new Expr\Variable('obj'), + new Identifier('method') + ), + $factory->methodCall(new Expr\Variable('obj'), new Identifier('method')) + ); + // Dynamic method call + $this->assertEquals( + new Expr\MethodCall( + new Expr\Variable('obj'), + new Expr\Variable('method') + ), + $factory->methodCall(new Expr\Variable('obj'), new Expr\Variable('method')) + ); + + // Simple static method call + $this->assertEquals( + new Expr\StaticCall( + new Name\FullyQualified('Foo'), + new Identifier('bar'), + [new Arg(new Expr\Variable('baz'))] + ), + $factory->staticCall('\Foo', 'bar', [new Expr\Variable('baz')]) + ); + // Dynamic static method call + $this->assertEquals( + new Expr\StaticCall( + new Expr\Variable('foo'), + new Expr\Variable('bar') + ), + $factory->staticCall(new Expr\Variable('foo'), new Expr\Variable('bar')) + ); + + // Simple new call + $this->assertEquals( + new Expr\New_(new Name\FullyQualified('stdClass')), + $factory->new('\stdClass') + ); + // Dynamic new call + $this->assertEquals( + new Expr\New_( + new Expr\Variable('foo'), + [new Arg(new String_('bar'))] + ), + $factory->new(new Expr\Variable('foo'), ['bar']) + ); + } + + public function testConstFetches() { + $factory = new BuilderFactory(); + $this->assertEquals( + new Expr\ConstFetch(new Name('FOO')), + $factory->constFetch('FOO') + ); + $this->assertEquals( + new Expr\ClassConstFetch(new Name('Foo'), new Identifier('BAR')), + $factory->classConstFetch('Foo', 'BAR') + ); + $this->assertEquals( + new Expr\ClassConstFetch(new Expr\Variable('foo'), new Identifier('BAR')), + $factory->classConstFetch(new Expr\Variable('foo'), 'BAR') + ); + } + + public function testVar() { + $factory = new BuilderFactory(); + $this->assertEquals( + new Expr\Variable("foo"), + $factory->var("foo") + ); + $this->assertEquals( + new Expr\Variable(new Expr\Variable("foo")), + $factory->var($factory->var("foo")) + ); + } + + public function testPropertyFetch() { + $f = new BuilderFactory(); + $this->assertEquals( + new Expr\PropertyFetch(new Expr\Variable('foo'), 'bar'), + $f->propertyFetch($f->var('foo'), 'bar') + ); + $this->assertEquals( + new Expr\PropertyFetch(new Expr\Variable('foo'), 'bar'), + $f->propertyFetch($f->var('foo'), new Identifier('bar')) + ); + $this->assertEquals( + new Expr\PropertyFetch(new Expr\Variable('foo'), new Expr\Variable('bar')), + $f->propertyFetch($f->var('foo'), $f->var('bar')) + ); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Expected string or instance of Node\Identifier + */ + public function testInvalidIdentifier() { + (new BuilderFactory())->classConstFetch('Foo', new Expr\Variable('foo')); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Expected string or instance of Node\Identifier or Node\Expr + */ + public function testInvalidIdentifierOrExpr() { + (new BuilderFactory())->staticCall('Foo', new Name('bar')); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Name must be a string or an instance of Node\Name or Node\Expr + */ + public function testInvalidNameOrExpr() { + (new BuilderFactory())->funcCall(new Node\Stmt\Return_()); + } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Variable name must be string or Expr + */ + public function testInvalidVar() { + (new BuilderFactory())->var(new Node\Stmt\Return_()); } public function testIntegration() { @@ -39,18 +255,28 @@ public function testIntegration() { $node = $factory->namespace('Name\Space') ->addStmt($factory->use('Foo\Bar\SomeOtherClass')) ->addStmt($factory->use('Foo\Bar')->as('A')) + ->addStmt($factory->useFunction('strlen')) + ->addStmt($factory->useConst('PHP_VERSION')) ->addStmt($factory ->class('SomeClass') ->extend('SomeOtherClass') ->implement('A\Few', '\Interfaces') ->makeAbstract() + ->addStmt($factory->useTrait('FirstTrait')) + + ->addStmt($factory->useTrait('SecondTrait', 'ThirdTrait') + ->and('AnotherTrait') + ->with($factory->traitUseAdaptation('foo')->as('bar')) + ->with($factory->traitUseAdaptation('AnotherTrait', 'baz')->as('test')) + ->with($factory->traitUseAdaptation('AnotherTrait', 'func')->insteadof('SecondTrait'))) + ->addStmt($factory->method('firstMethod')) ->addStmt($factory->method('someMethod') ->makePublic() ->makeAbstract() - ->addParam($factory->param('someParam')->setTypeHint('SomeClass')) + ->addParam($factory->param('someParam')->setType('SomeClass')) ->setDocComment('/** * This method does something. * @@ -65,7 +291,7 @@ public function testIntegration() { ->addStmt($factory->property('someProperty')->makeProtected()) ->addStmt($factory->property('anotherProperty') ->makePrivate() - ->setDefault(array(1, 2, 3)))) + ->setDefault([1, 2, 3]))) ->getNode() ; @@ -76,8 +302,16 @@ public function testIntegration() { use Foo\Bar\SomeOtherClass; use Foo\Bar as A; +use function strlen; +use const PHP_VERSION; abstract class SomeClass extends SomeOtherClass implements A\Few, \Interfaces { + use FirstTrait; + use SecondTrait, ThirdTrait, AnotherTrait { + foo as bar; + AnotherTrait::baz as test; + AnotherTrait::func insteadof SecondTrait; + } protected $someProperty; private $anotherProperty = array(1, 2, 3); function firstMethod() @@ -96,7 +330,7 @@ protected function anotherMethod($someParam = 'test') } EOC; - $stmts = array($node); + $stmts = [$node]; $prettyPrinter = new PrettyPrinter\Standard(); $generated = $prettyPrinter->prettyPrintFile($stmts); diff --git a/app/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php b/app/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php index 1a4a9ad1d..459996c55 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/CodeParsingTest.php @@ -1,7 +1,10 @@ - array( - 'startLine', 'endLine', 'startFilePos', 'endFilePos', 'comments' - ))); - $parser5 = new Parser\Php5($lexer); - $parser7 = new Parser\Php7($lexer); - - $dumpPositions = isset($modes['positions']); - $output5 = $this->getParseOutput($parser5, $code, $dumpPositions); - $output7 = $this->getParseOutput($parser7, $code, $dumpPositions); + list($parser5, $parser7) = $this->createParsers($modes); + list($stmts5, $output5) = $this->getParseOutput($parser5, $code, $modes); + list($stmts7, $output7) = $this->getParseOutput($parser7, $code, $modes); if (isset($modes['php5'])) { $this->assertSame($expected, $output5, $name); $this->assertNotSame($expected, $output7, $name); - } else if (isset($modes['php7'])) { + } elseif (isset($modes['php7'])) { $this->assertNotSame($expected, $output5, $name); $this->assertSame($expected, $output7, $name); } else { $this->assertSame($expected, $output5, $name); $this->assertSame($expected, $output7, $name); } + + $this->checkAttributes($stmts5); + $this->checkAttributes($stmts7); + } + + public function createParsers(array $modes) { + $lexer = new Lexer\Emulative(['usedAttributes' => [ + 'startLine', 'endLine', + 'startFilePos', 'endFilePos', + 'startTokenPos', 'endTokenPos', + 'comments' + ]]); + + return [ + new Parser\Php5($lexer), + new Parser\Php7($lexer), + ]; } - private function getParseOutput(Parser $parser, $code, $dumpPositions) { + // Must be public for updateTests.php + public function getParseOutput(Parser $parser, $code, array $modes) { + $dumpPositions = isset($modes['positions']); + $errors = new ErrorHandler\Collecting; $stmts = $parser->parse($code, $errors); @@ -53,7 +69,7 @@ private function getParseOutput(Parser $parser, $code, $dumpPositions) { $output .= $dumper->dump($stmts, $code); } - return canonicalize($output); + return [$stmts, canonicalize($output)]; } public function provideTestParse() { @@ -67,4 +83,39 @@ private function formatErrorMessage(Error $e, $code) { return $e->getMessage(); } } + + private function checkAttributes($stmts) { + if ($stmts === null) { + return; + } + + $traverser = new NodeTraverser(); + $traverser->addVisitor(new class extends NodeVisitorAbstract { + public function enterNode(Node $node) { + $startLine = $node->getStartLine(); + $endLine = $node->getEndLine(); + $startFilePos = $node->getStartFilePos(); + $endFilePos = $node->getEndFilePos(); + $startTokenPos = $node->getStartTokenPos(); + $endTokenPos = $node->getEndTokenPos(); + if ($startLine < 0 || $endLine < 0 || + $startFilePos < 0 || $endFilePos < 0 || + $startTokenPos < 0 || $endTokenPos < 0 + ) { + throw new \Exception('Missing location information on ' . $node->getType()); + } + + if ($endLine < $startLine || + $endFilePos < $startFilePos || + $endTokenPos < $startTokenPos + ) { + // Nops and error can have inverted order, if they are empty + if (!$node instanceof Stmt\Nop && !$node instanceof Expr\Error) { + throw new \Exception('End < start on ' . $node->getType()); + } + } + } + }); + $traverser->traverse($stmts); + } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php b/app/vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php index 369ee41b8..5eaf9d1b2 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/CodeTestAbstract.php @@ -1,61 +1,30 @@ -getPathname(); - $fileContents = file_get_contents($fileName); - $fileContents = canonicalize($fileContents); +use PHPUnit\Framework\TestCase; - // evaluate @@{expr}@@ expressions - $fileContents = preg_replace_callback( - '/@@\{(.*?)\}@@/', - function($matches) { - return eval('return ' . $matches[1] . ';'); - }, - $fileContents - ); +require_once __DIR__ . '/CodeTestParser.php'; - // parse sections - $parts = preg_split("/\n-----(?:\n|$)/", $fileContents); +abstract class CodeTestAbstract extends TestCase +{ + protected function getTests($directory, $fileExtension, $chunksPerTest = 2) { + $parser = new CodeTestParser; + $allTests = []; + foreach (filesInDir($directory, $fileExtension) as $fileName => $fileContents) { + list($name, $tests) = $parser->parseTest($fileContents, $chunksPerTest); // first part is the name - $name = array_shift($parts) . ' (' . $fileName . ')'; + $name .= ' (' . $fileName . ')'; $shortName = ltrim(str_replace($directory, '', $fileName), '/\\'); // multiple sections possible with always two forming a pair - $chunks = array_chunk($parts, 2); - foreach ($chunks as $i => $chunk) { - $dataSetName = $shortName . (count($chunks) > 1 ? '#' . $i : ''); - list($expected, $mode) = $this->extractMode($chunk[1]); - $tests[$dataSetName] = array($name, $chunk[0], $expected, $mode); + foreach ($tests as $i => list($mode, $parts)) { + $dataSetName = $shortName . (count($parts) > 1 ? '#' . $i : ''); + $allTests[$dataSetName] = array_merge([$name], $parts, [$mode]); } } - return $tests; - } - - private function extractMode($expected) { - $firstNewLine = strpos($expected, "\n"); - if (false === $firstNewLine) { - $firstNewLine = strlen($expected); - } - - $firstLine = substr($expected, 0, $firstNewLine); - if (0 !== strpos($firstLine, '!!')) { - return [$expected, null]; - } - - $expected = (string) substr($expected, $firstNewLine + 1); - return [$expected, substr($firstLine, 2)]; + return $allTests; } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/CodeTestParser.php b/app/vendor/nikic/php-parser/test/PhpParser/CodeTestParser.php new file mode 100644 index 000000000..f63dc9265 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/CodeTestParser.php @@ -0,0 +1,68 @@ + $chunk) { + $lastPart = array_pop($chunk); + list($lastPart, $mode) = $this->extractMode($lastPart); + $tests[] = [$mode, array_merge($chunk, [$lastPart])]; + } + + return [$name, $tests]; + } + + public function reconstructTest($name, array $tests) { + $result = $name; + foreach ($tests as list($mode, $parts)) { + $lastPart = array_pop($parts); + foreach ($parts as $part) { + $result .= "\n-----\n$part"; + } + + $result .= "\n-----\n"; + if (null !== $mode) { + $result .= "!!$mode\n"; + } + $result .= $lastPart; + } + return $result; + } + + private function extractMode($expected) { + $firstNewLine = strpos($expected, "\n"); + if (false === $firstNewLine) { + $firstNewLine = strlen($expected); + } + + $firstLine = substr($expected, 0, $firstNewLine); + if (0 !== strpos($firstLine, '!!')) { + return [$expected, null]; + } + + $expected = (string) substr($expected, $firstNewLine + 1); + return [$expected, substr($firstLine, 2)]; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/CommentTest.php b/app/vendor/nikic/php-parser/test/PhpParser/CommentTest.php index 081dd57b7..7b6c2aabe 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/CommentTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/CommentTest.php @@ -1,16 +1,19 @@ -assertSame('/* Some comment */', $comment->getText()); $this->assertSame('/* Some comment */', (string) $comment); $this->assertSame(1, $comment->getLine()); $this->assertSame(10, $comment->getFilePos()); + $this->assertSame(2, $comment->getTokenPos()); } /** @@ -22,10 +25,10 @@ public function testReformatting($commentText, $reformattedText) { } public function provideTestReformatting() { - return array( - array('// Some text' . "\n", '// Some text'), - array('/* Some text */', '/* Some text */'), - array( + return [ + ['// Some text' . "\n", '// Some text'], + ['/* Some text */', '/* Some text */'], + [ '/** * Some text. * Some more text. @@ -34,8 +37,8 @@ public function provideTestReformatting() { * Some text. * Some more text. */' - ), - array( + ], + [ '/* Some text. Some more text. @@ -44,30 +47,30 @@ public function provideTestReformatting() { Some text. Some more text. */' - ), - array( + ], + [ '/* Some text. More text. Even more text. */', '/* Some text. More text. Even more text. */' - ), - array( + ], + [ '/* Some text. More text. Indented text. */', '/* Some text. More text. Indented text. */', - ), + ], // invalid comment -> no reformatting - array( + [ 'hallo world', 'hallo world', - ), - ); + ], + ]; } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/ConstExprEvaluatorTest.php b/app/vendor/nikic/php-parser/test/PhpParser/ConstExprEvaluatorTest.php new file mode 100644 index 000000000..d0a83fff9 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/ConstExprEvaluatorTest.php @@ -0,0 +1,133 @@ +parse('expr; + $evaluator = new ConstExprEvaluator(); + $this->assertSame($expected, $evaluator->evaluateDirectly($expr)); + } + + public function provideTestEvaluate() { + return [ + ['1', 1], + ['1.0', 1.0], + ['"foo"', "foo"], + ['[0, 1]', [0, 1]], + ['["foo" => "bar"]', ["foo" => "bar"]], + ['NULL', null], + ['False', false], + ['true', true], + ['+1', 1], + ['-1', -1], + ['~0', -1], + ['!true', false], + ['[0][0]', 0], + ['"a"[0]', "a"], + ['true ? 1 : (1/0)', 1], + ['false ? (1/0) : 1', 1], + ['42 ?: (1/0)', 42], + ['false ?: 42', 42], + ['false ?? 42', false], + ['null ?? 42', 42], + ['[0][0] ?? 42', 0], + ['[][0] ?? 42', 42], + ['0b11 & 0b10', 0b10], + ['0b11 | 0b10', 0b11], + ['0b11 ^ 0b10', 0b01], + ['1 << 2', 4], + ['4 >> 2', 1], + ['"a" . "b"', "ab"], + ['4 + 2', 6], + ['4 - 2', 2], + ['4 * 2', 8], + ['4 / 2', 2], + ['4 % 2', 0], + ['4 ** 2', 16], + ['1 == 1.0', true], + ['1 != 1.0', false], + ['1 < 2.0', true], + ['1 <= 2.0', true], + ['1 > 2.0', false], + ['1 >= 2.0', false], + ['1 <=> 2.0', -1], + ['1 === 1.0', false], + ['1 !== 1.0', true], + ['true && true', true], + ['true and true', true], + ['false && (1/0)', false], + ['false and (1/0)', false], + ['false || false', false], + ['false or false', false], + ['true || (1/0)', true], + ['true or (1/0)', true], + ['true xor false', true], + ]; + } + + /** + * @expectedException \PhpParser\ConstExprEvaluationException + * @expectedExceptionMessage Expression of type Expr_Variable cannot be evaluated + */ + public function testEvaluateFails() { + $evaluator = new ConstExprEvaluator(); + $evaluator->evaluateDirectly(new Expr\Variable('a')); + } + + public function testEvaluateFallback() { + $evaluator = new ConstExprEvaluator(function(Expr $expr) { + if ($expr instanceof Scalar\MagicConst\Line) { + return 42; + } + throw new ConstExprEvaluationException(); + }); + $expr = new Expr\BinaryOp\Plus( + new Scalar\LNumber(8), + new Scalar\MagicConst\Line() + ); + $this->assertSame(50, $evaluator->evaluateDirectly($expr)); + } + + /** + * @dataProvider provideTestEvaluateSilently + */ + public function testEvaluateSilently($expr, $exception, $msg) { + $evaluator = new ConstExprEvaluator(); + + try { + $evaluator->evaluateSilently($expr); + } catch (ConstExprEvaluationException $e) { + $this->assertSame( + 'An error occurred during constant expression evaluation', + $e->getMessage() + ); + + $prev = $e->getPrevious(); + $this->assertInstanceOf($exception, $prev); + $this->assertSame($msg, $prev->getMessage()); + } + } + + public function provideTestEvaluateSilently() { + return [ + [ + new Expr\BinaryOp\Mod(new Scalar\LNumber(42), new Scalar\LNumber(0)), + \Error::class, + 'Modulo by zero' + ], + [ + new Expr\BinaryOp\Div(new Scalar\LNumber(42), new Scalar\LNumber(0)), + \ErrorException::class, + 'Division by zero' + ], + ]; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php b/app/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php index 37429817e..842f131dd 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/CollectingTest.php @@ -1,10 +1,12 @@ -assertFalse($errorHandler->hasErrors()); @@ -19,4 +21,4 @@ public function testHandleError() { $this->assertFalse($errorHandler->hasErrors()); $this->assertEmpty($errorHandler->getErrors()); } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php b/app/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php index d7df7c267..31d349ae4 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/ErrorHandler/ThrowingTest.php @@ -1,10 +1,12 @@ -handleError(new Error('Test')); } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/ErrorTest.php b/app/vendor/nikic/php-parser/test/PhpParser/ErrorTest.php index 59e880c30..4b9d73a16 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/ErrorTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/ErrorTest.php @@ -1,14 +1,16 @@ - 10, 'endLine' => 11, - ); + ]; $error = new Error('Some error', $attributes); $this->assertSame('Some error', $error->getRawMessage()); @@ -42,42 +44,42 @@ public function testUnknownLine() { /** @dataProvider provideTestColumnInfo */ public function testColumnInfo($code, $startPos, $endPos, $startColumn, $endColumn) { - $error = new Error('Some error', array( + $error = new Error('Some error', [ 'startFilePos' => $startPos, 'endFilePos' => $endPos, - )); + ]); - $this->assertSame(true, $error->hasColumnInfo()); + $this->assertTrue($error->hasColumnInfo()); $this->assertSame($startColumn, $error->getStartColumn($code)); $this->assertSame($endColumn, $error->getEndColumn($code)); } public function provideTestColumnInfo() { - return array( + return [ // Error at "bar" - array("assertSame(false, $error->hasColumnInfo()); + $this->assertFalse($error->hasColumnInfo()); try { $error->getStartColumn(''); $this->fail('Expected RuntimeException'); @@ -97,10 +99,10 @@ public function testNoColumnInfo() { * @expectedExceptionMessage Invalid position information */ public function testInvalidPosInfo() { - $error = new Error('Some error', array( + $error = new Error('Some error', [ 'startFilePos' => 10, 'endFilePos' => 11, - )); + ]); $error->getStartColumn('code'); } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Internal/DifferTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Internal/DifferTest.php new file mode 100644 index 000000000..0cf878b6f --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/Internal/DifferTest.php @@ -0,0 +1,67 @@ +type) { + case DiffElem::TYPE_KEEP: + $diffStr .= $diffElem->old; + break; + case DiffElem::TYPE_REMOVE: + $diffStr .= '-' . $diffElem->old; + break; + case DiffElem::TYPE_ADD: + $diffStr .= '+' . $diffElem->new; + break; + case DiffElem::TYPE_REPLACE: + $diffStr .= '/' . $diffElem->old . $diffElem->new; + break; + default: + assert(false); + break; + } + } + return $diffStr; + } + + /** @dataProvider provideTestDiff */ + public function testDiff($oldStr, $newStr, $expectedDiffStr) { + $differ = new Differ(function($a, $b) { return $a === $b; }); + $diff = $differ->diff(str_split($oldStr), str_split($newStr)); + $this->assertSame($expectedDiffStr, $this->formatDiffString($diff)); + } + + public function provideTestDiff() { + return [ + ['abc', 'abc', 'abc'], + ['abc', 'abcdef', 'abc+d+e+f'], + ['abcdef', 'abc', 'abc-d-e-f'], + ['abcdef', 'abcxyzdef', 'abc+x+y+zdef'], + ['axyzb', 'ab', 'a-x-y-zb'], + ['abcdef', 'abxyef', 'ab-c-d+x+yef'], + ['abcdef', 'cdefab', '-a-bcdef+a+b'], + ]; + } + + /** @dataProvider provideTestDiffWithReplacements */ + public function testDiffWithReplacements($oldStr, $newStr, $expectedDiffStr) { + $differ = new Differ(function($a, $b) { return $a === $b; }); + $diff = $differ->diffWithReplacements(str_split($oldStr), str_split($newStr)); + $this->assertSame($expectedDiffStr, $this->formatDiffString($diff)); + } + + public function provideTestDiffWithReplacements() { + return [ + ['abcde', 'axyze', 'a/bx/cy/dze'], + ['abcde', 'xbcdy', '/axbcd/ey'], + ['abcde', 'axye', 'a-b-c-d+x+ye'], + ['abcde', 'axyzue', 'a-b-c-d+x+y+z+ue'], + ]; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/JsonDecoderTest.php b/app/vendor/nikic/php-parser/test/PhpParser/JsonDecoderTest.php new file mode 100644 index 000000000..7ef60787b --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/JsonDecoderTest.php @@ -0,0 +1,45 @@ +parse($code); + $json = json_encode($stmts); + + $jsonDecoder = new JsonDecoder(); + $decodedStmts = $jsonDecoder->decode($json); + $this->assertEquals($stmts, $decodedStmts); + } + + /** @dataProvider provideTestDecodingError */ + public function testDecodingError($json, $expectedMessage) { + $jsonDecoder = new JsonDecoder(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage($expectedMessage); + $jsonDecoder->decode($json); + } + + public function provideTestDecodingError() { + return [ + ['???', 'JSON decoding error: Syntax error'], + ['{"nodeType":123}', 'Node type must be a string'], + ['{"nodeType":"Name","attributes":123}', 'Attributes must be an array'], + ['{"nodeType":"Comment"}', 'Comment must have text'], + ['{"nodeType":"xxx"}', 'Unknown node type "xxx"'], + ]; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php index f1fe6183a..3a33ba820 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Lexer/EmulativeTest.php @@ -1,4 +1,4 @@ -', array( - array(Tokens::T_SPACESHIP, '<=>'), - )), - array('0b1010110', array( - array(Tokens::T_LNUMBER, '0b1010110'), - )), - array('0b1011010101001010110101010010101011010101010101101011001110111100', array( - array(Tokens::T_DNUMBER, '0b1011010101001010110101010010101011010101010101101011001110111100'), - )), - array('\\', array( - array(Tokens::T_NS_SEPARATOR, '\\'), - )), - array("<<<'NOWDOC'\nNOWDOC;\n", array( - array(Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"), - array(Tokens::T_END_HEREDOC, 'NOWDOC'), - array(ord(';'), ';'), - )), - array("<<<'NOWDOC'\nFoobar\nNOWDOC;\n", array( - array(Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"), - array(Tokens::T_ENCAPSED_AND_WHITESPACE, "Foobar\n"), - array(Tokens::T_END_HEREDOC, 'NOWDOC'), - array(ord(';'), ';'), - )), - ); + return [ + ['yield from', [ + [Tokens::T_YIELD_FROM, 'yield from'], + ]], + ["yield\r\nfrom", [ + [Tokens::T_YIELD_FROM, "yield\r\nfrom"], + ]], + ['...', [ + [Tokens::T_ELLIPSIS, '...'], + ]], + ['**', [ + [Tokens::T_POW, '**'], + ]], + ['**=', [ + [Tokens::T_POW_EQUAL, '**='], + ]], + ['??', [ + [Tokens::T_COALESCE, '??'], + ]], + ['<=>', [ + [Tokens::T_SPACESHIP, '<=>'], + ]], + ['0b1010110', [ + [Tokens::T_LNUMBER, '0b1010110'], + ]], + ['0b1011010101001010110101010010101011010101010101101011001110111100', [ + [Tokens::T_DNUMBER, '0b1011010101001010110101010010101011010101010101101011001110111100'], + ]], + ['\\', [ + [Tokens::T_NS_SEPARATOR, '\\'], + ]], + ["<<<'NOWDOC'\nNOWDOC;\n", [ + [Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"], + [Tokens::T_END_HEREDOC, 'NOWDOC'], + [ord(';'), ';'], + ]], + ["<<<'NOWDOC'\nFoobar\nNOWDOC;\n", [ + [Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"], + [Tokens::T_ENCAPSED_AND_WHITESPACE, "Foobar\n"], + [Tokens::T_END_HEREDOC, 'NOWDOC'], + [ord(';'), ';'], + ]], + ]; } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/LexerTest.php b/app/vendor/nikic/php-parser/test/PhpParser/LexerTest.php index bf7a5d32f..c34cc71e4 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/LexerTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/LexerTest.php @@ -1,13 +1,14 @@ -startLexing($code, $errorHandler); $errors = $errorHandler->getErrors(); - $this->assertSame(count($messages), count($errors)); + $this->assertCount(count($messages), $errors); for ($i = 0; $i < count($messages); $i++) { $this->assertSame($messages[$i], $errors[$i]->getMessageWithColumnInfo($code)); } } public function provideTestError() { - return array( - array("plaintext', - array(), - array( - array( + [], + [ + [ Tokens::T_STRING, 'tokens', - array('startLine' => 1), array('endLine' => 1) - ), - array( + ['startLine' => 1], ['endLine' => 1] + ], + [ ord(';'), '?>', - array('startLine' => 1), array('endLine' => 1) - ), - array( + ['startLine' => 1], ['endLine' => 1] + ], + [ Tokens::T_INLINE_HTML, 'plaintext', - array('startLine' => 1, 'hasLeadingNewline' => false), - array('endLine' => 1) - ), - ) - ), + ['startLine' => 1, 'hasLeadingNewline' => false], + ['endLine' => 1] + ], + ] + ], // tests line numbers - array( + [ ' 2), array('endLine' => 2) - ), - array( + ['startLine' => 2], ['endLine' => 2] + ], + [ Tokens::T_STRING, 'token', - array('startLine' => 2), array('endLine' => 2) - ), - array( + ['startLine' => 2], ['endLine' => 2] + ], + [ ord('$'), '$', - array( + [ 'startLine' => 3, - 'comments' => array( - new Comment\Doc('/** doc' . "\n" . 'comment */', 2, 14), - ) - ), - array('endLine' => 3) - ), - ) - ), + 'comments' => [ + new Comment\Doc('/** doc' . "\n" . 'comment */', 2, 14, 5), + ] + ], + ['endLine' => 3] + ], + ] + ], // tests comment extraction - array( + [ ' 2, - 'comments' => array( - new Comment('/* comment */', 1, 6), - new Comment('// comment' . "\n", 1, 20), - new Comment\Doc('/** docComment 1 */', 2, 31), - new Comment\Doc('/** docComment 2 */', 2, 50), - ), - ), - array('endLine' => 2) - ), - ) - ), + 'comments' => [ + new Comment('/* comment */', 1, 6, 1), + new Comment('// comment' . "\n", 1, 20, 3), + new Comment\Doc('/** docComment 1 */', 2, 31, 4), + new Comment\Doc('/** docComment 2 */', 2, 50, 5), + ], + ], + ['endLine' => 2] + ], + ] + ], // tests differing start and end line - array( + [ ' 1), array('endLine' => 2) - ), - ) - ), + ['startLine' => 1], ['endLine' => 2] + ], + ] + ], // tests exact file offsets - array( + [ ' array('startFilePos', 'endFilePos')), - array( - array( + ['usedAttributes' => ['startFilePos', 'endFilePos']], + [ + [ Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"', - array('startFilePos' => 6), array('endFilePos' => 8) - ), - array( + ['startFilePos' => 6], ['endFilePos' => 8] + ], + [ ord(';'), ';', - array('startFilePos' => 9), array('endFilePos' => 9) - ), - array( + ['startFilePos' => 9], ['endFilePos' => 9] + ], + [ Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"', - array('startFilePos' => 18), array('endFilePos' => 20) - ), - array( + ['startFilePos' => 18], ['endFilePos' => 20] + ], + [ ord(';'), ';', - array('startFilePos' => 21), array('endFilePos' => 21) - ), - ) - ), + ['startFilePos' => 21], ['endFilePos' => 21] + ], + ] + ], // tests token offsets - array( + [ ' array('startTokenPos', 'endTokenPos')), - array( - array( + ['usedAttributes' => ['startTokenPos', 'endTokenPos']], + [ + [ Tokens::T_CONSTANT_ENCAPSED_STRING, '"a"', - array('startTokenPos' => 1), array('endTokenPos' => 1) - ), - array( + ['startTokenPos' => 1], ['endTokenPos' => 1] + ], + [ ord(';'), ';', - array('startTokenPos' => 2), array('endTokenPos' => 2) - ), - array( + ['startTokenPos' => 2], ['endTokenPos' => 2] + ], + [ Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"', - array('startTokenPos' => 5), array('endTokenPos' => 5) - ), - array( + ['startTokenPos' => 5], ['endTokenPos' => 5] + ], + [ ord(';'), ';', - array('startTokenPos' => 6), array('endTokenPos' => 6) - ), - ) - ), + ['startTokenPos' => 6], ['endTokenPos' => 6] + ], + ] + ], // tests all attributes being disabled - array( + [ ' array()), - array( - array( + ['usedAttributes' => []], + [ + [ Tokens::T_VARIABLE, '$bar', - array(), array() - ), - array( + [], [] + ], + [ ord(';'), ';', - array(), array() - ) - ) - ), + [], [] + ] + ] + ], // tests no tokens - array( + [ '', - array(), - array() - ), - ); + [], + [] + ], + ]; } /** @@ -225,13 +226,13 @@ public function testHandleHaltCompiler($code, $remaining) { } public function provideTestHaltCompiler() { - return array( - array('Remaining Text', 'Remaining Text'), + return [ + ['Remaining Text', 'Remaining Text'], //array('getLexer(); $lexer->startLexing($code); diff --git a/app/vendor/nikic/php-parser/test/PhpParser/NameContextTest.php b/app/vendor/nikic/php-parser/test/PhpParser/NameContextTest.php new file mode 100644 index 000000000..41c3460d4 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/NameContextTest.php @@ -0,0 +1,66 @@ +startNamespace(new Name('NS')); + $nameContext->addAlias(new Name('Foo'), 'Foo', Use_::TYPE_NORMAL); + $nameContext->addAlias(new Name('Foo\Bar'), 'Alias', Use_::TYPE_NORMAL); + $nameContext->addAlias(new Name('Foo\fn'), 'fn', Use_::TYPE_FUNCTION); + $nameContext->addAlias(new Name('Foo\CN'), 'CN', Use_::TYPE_CONSTANT); + + $possibleNames = $nameContext->getPossibleNames($name, $type); + $possibleNames = array_map(function (Name $name) { + return $name->toCodeString(); + }, $possibleNames); + + $this->assertSame($expectedPossibleNames, $possibleNames); + + // Here the last name is always the shortest one + $expectedShortName = $expectedPossibleNames[count($expectedPossibleNames) - 1]; + $this->assertSame( + $expectedShortName, + $nameContext->getShortName($name, $type)->toCodeString() + ); + } + + public function provideTestGetPossibleNames() { + return [ + [Use_::TYPE_NORMAL, 'Test', ['\Test']], + [Use_::TYPE_NORMAL, 'Test\Namespaced', ['\Test\Namespaced']], + [Use_::TYPE_NORMAL, 'NS\Test', ['\NS\Test', 'Test']], + [Use_::TYPE_NORMAL, 'ns\Test', ['\ns\Test', 'Test']], + [Use_::TYPE_NORMAL, 'NS\Foo\Bar', ['\NS\Foo\Bar']], + [Use_::TYPE_NORMAL, 'ns\foo\Bar', ['\ns\foo\Bar']], + [Use_::TYPE_NORMAL, 'Foo', ['\Foo', 'Foo']], + [Use_::TYPE_NORMAL, 'Foo\Bar', ['\Foo\Bar', 'Foo\Bar', 'Alias']], + [Use_::TYPE_NORMAL, 'Foo\Bar\Baz', ['\Foo\Bar\Baz', 'Foo\Bar\Baz', 'Alias\Baz']], + [Use_::TYPE_NORMAL, 'Foo\fn\Bar', ['\Foo\fn\Bar', 'Foo\fn\Bar']], + [Use_::TYPE_FUNCTION, 'Foo\fn\bar', ['\Foo\fn\bar', 'Foo\fn\bar']], + [Use_::TYPE_FUNCTION, 'Foo\fn', ['\Foo\fn', 'Foo\fn', 'fn']], + [Use_::TYPE_FUNCTION, 'Foo\FN', ['\Foo\FN', 'Foo\FN', 'fn']], + [Use_::TYPE_CONSTANT, 'Foo\CN\BAR', ['\Foo\CN\BAR', 'Foo\CN\BAR']], + [Use_::TYPE_CONSTANT, 'Foo\CN', ['\Foo\CN', 'Foo\CN', 'CN']], + [Use_::TYPE_CONSTANT, 'foo\CN', ['\foo\CN', 'Foo\CN', 'CN']], + [Use_::TYPE_CONSTANT, 'foo\cn', ['\foo\cn', 'Foo\cn']], + // self/parent/static must not be fully qualified + [Use_::TYPE_NORMAL, 'self', ['self']], + [Use_::TYPE_NORMAL, 'parent', ['parent']], + [Use_::TYPE_NORMAL, 'static', ['static']], + // true/false/null do not need to be fully qualified, even in namespaces + [Use_::TYPE_CONSTANT, 'true', ['\true', 'true']], + [Use_::TYPE_CONSTANT, 'false', ['\false', 'false']], + [Use_::TYPE_CONSTANT, 'null', ['\null', 'null']], + ]; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Node/IdentifierTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Node/IdentifierTest.php new file mode 100644 index 000000000..fa2e72a86 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/Node/IdentifierTest.php @@ -0,0 +1,31 @@ +assertSame('Foo', (string) $identifier); + $this->assertSame('Foo', $identifier->toString()); + $this->assertSame('foo', $identifier->toLowerString()); + } + + /** @dataProvider provideTestIsSpecialClassName */ + public function testIsSpecialClassName($identifier, $expected) { + $identifier = new Identifier($identifier); + $this->assertSame($expected, $identifier->isSpecialClassName()); + } + + public function provideTestIsSpecialClassName() { + return [ + ['self', true], + ['PARENT', true], + ['Static', true], + ['other', false], + ]; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php index 76a89c3ec..8fe9ed63e 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Node/NameTest.php @@ -1,18 +1,20 @@ -assertSame(array('foo', 'bar'), $name->parts); + $name = new Name(['foo', 'bar']); + $this->assertSame(['foo', 'bar'], $name->parts); $name = new Name('foo\bar'); - $this->assertSame(array('foo', 'bar'), $name->parts); + $this->assertSame(['foo', 'bar'], $name->parts); $name = new Name($name); - $this->assertSame(array('foo', 'bar'), $name->parts); + $this->assertSame(['foo', 'bar'], $name->parts); } public function testGet() { @@ -26,10 +28,11 @@ public function testGet() { } public function testToString() { - $name = new Name('foo\bar'); + $name = new Name('Foo\Bar'); - $this->assertSame('foo\bar', (string) $name); - $this->assertSame('foo\bar', $name->toString()); + $this->assertSame('Foo\Bar', (string) $name); + $this->assertSame('Foo\Bar', $name->toString()); + $this->assertSame('foo\bar', $name->toLowerString()); } public function testSlice() { @@ -98,37 +101,73 @@ public function testConcat() { $this->assertNull(Name::concat(null, null)); } - public function testIs() { + public function testNameTypes() { $name = new Name('foo'); - $this->assertTrue ($name->isUnqualified()); + $this->assertTrue($name->isUnqualified()); $this->assertFalse($name->isQualified()); $this->assertFalse($name->isFullyQualified()); $this->assertFalse($name->isRelative()); + $this->assertSame('foo', $name->toCodeString()); $name = new Name('foo\bar'); $this->assertFalse($name->isUnqualified()); - $this->assertTrue ($name->isQualified()); + $this->assertTrue($name->isQualified()); $this->assertFalse($name->isFullyQualified()); $this->assertFalse($name->isRelative()); + $this->assertSame('foo\bar', $name->toCodeString()); $name = new Name\FullyQualified('foo'); $this->assertFalse($name->isUnqualified()); $this->assertFalse($name->isQualified()); - $this->assertTrue ($name->isFullyQualified()); + $this->assertTrue($name->isFullyQualified()); $this->assertFalse($name->isRelative()); + $this->assertSame('\foo', $name->toCodeString()); $name = new Name\Relative('foo'); $this->assertFalse($name->isUnqualified()); $this->assertFalse($name->isQualified()); $this->assertFalse($name->isFullyQualified()); - $this->assertTrue ($name->isRelative()); + $this->assertTrue($name->isRelative()); + $this->assertSame('namespace\foo', $name->toCodeString()); } /** - * @expectedException \InvalidArgumentException + * @expectedException \InvalidArgumentException * @expectedExceptionMessage Expected string, array of parts or Name instance */ public function testInvalidArg() { Name::concat('foo', new \stdClass); } -} \ No newline at end of file + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Name cannot be empty + */ + public function testInvalidEmptyString() { + new Name(''); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Name cannot be empty + */ + public function testInvalidEmptyArray() { + new Name([]); + } + + /** @dataProvider provideTestIsSpecialClassName */ + public function testIsSpecialClassName($name, $expected) { + $name = new Name($name); + $this->assertSame($expected, $name->isSpecialClassName()); + } + + public function provideTestIsSpecialClassName() { + return [ + ['self', true], + ['PARENT', true], + ['Static', true], + ['self\not', false], + ['not\self', false], + ]; + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php index 3141f563d..42b94874a 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Node/Scalar/MagicConstTest.php @@ -1,8 +1,11 @@ -provideTestParseEscapeSequences() as $i => $test) { // skip second and third tests, they aren't for double quotes - if ($i != 1 && $i != 2) { - $tests[] = array($test[0], '"' . $test[1] . '"'); + if ($i !== 1 && $i !== 2) { + $tests[] = [$test[0], '"' . $test[1] . '"']; } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php index 610972c6b..a5b6ce460 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassConstTest.php @@ -1,15 +1,17 @@ -assertTrue($node->isPublic()); $this->assertFalse($node->isProtected()); $this->assertFalse($node->isPrivate()); - $this->assertFalse($node->isStatic()); } public function provideModifiers() { - return array( - array('public'), - array('protected'), - array('private'), - ); + return [ + ['public'], + ['protected'], + ['private'], + ]; } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php index fa8aed808..4000495e6 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassMethodTest.php @@ -1,22 +1,27 @@ - constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier)) - )); + ]); $this->assertTrue($node->{'is' . $modifier}()); } public function testNoModifiers() { - $node = new ClassMethod('foo', array('type' => 0)); + $node = new ClassMethod('foo', ['type' => 0]); $this->assertTrue($node->isPublic()); $this->assertFalse($node->isProtected()); @@ -24,17 +29,18 @@ public function testNoModifiers() { $this->assertFalse($node->isAbstract()); $this->assertFalse($node->isFinal()); $this->assertFalse($node->isStatic()); + $this->assertFalse($node->isMagic()); } public function provideModifiers() { - return array( - array('public'), - array('protected'), - array('private'), - array('abstract'), - array('final'), - array('static'), - ); + return [ + ['public'], + ['protected'], + ['private'], + ['abstract'], + ['final'], + ['static'], + ]; } /** @@ -42,22 +48,77 @@ public function provideModifiers() { * * @dataProvider implicitPublicModifiers * - * @param integer $modifier Node type modifier + * @param string $modifier Node type modifier */ - public function testImplicitPublic($modifier) + public function testImplicitPublic(string $modifier) { - $node = new ClassMethod('foo', array( + $node = new ClassMethod('foo', [ 'type' => constant('PhpParser\Node\Stmt\Class_::MODIFIER_' . strtoupper($modifier)) - )); + ]); $this->assertTrue($node->isPublic(), 'Node should be implicitly public'); } public function implicitPublicModifiers() { - return array( - array('abstract'), - array('final'), - array('static'), - ); + return [ + ['abstract'], + ['final'], + ['static'], + ]; + } + + /** + * @dataProvider provideMagics + * + * @param string $name Node name + */ + public function testMagic(string $name) { + $node = new ClassMethod($name); + $this->assertTrue($node->isMagic(), 'Method should be magic'); + } + + public function provideMagics() { + return [ + ['__construct'], + ['__DESTRUCT'], + ['__caLL'], + ['__callstatic'], + ['__get'], + ['__set'], + ['__isset'], + ['__unset'], + ['__sleep'], + ['__wakeup'], + ['__tostring'], + ['__set_state'], + ['__clone'], + ['__invoke'], + ['__debuginfo'], + ]; + } + + public function testFunctionLike() { + $param = new Param(new Variable('a')); + $type = new Name('Foo'); + $return = new Return_(new Variable('a')); + $method = new ClassMethod('test', [ + 'byRef' => false, + 'params' => [$param], + 'returnType' => $type, + 'stmts' => [$return], + ]); + + $this->assertFalse($method->returnsByRef()); + $this->assertSame([$param], $method->getParams()); + $this->assertSame($type, $method->getReturnType()); + $this->assertSame([$return], $method->getStmts()); + + $method = new ClassMethod('test', [ + 'byRef' => true, + 'stmts' => null, + ]); + + $this->assertTrue($method->returnsByRef()); + $this->assertNull($method->getStmts()); } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php index 75d49e3a8..5d2b5dc03 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/ClassTest.php @@ -1,11 +1,13 @@ - Class_::MODIFIER_ABSTRACT)); + $class = new Class_('Foo', ['type' => Class_::MODIFIER_ABSTRACT]); $this->assertTrue($class->isAbstract()); $class = new Class_('Foo'); @@ -13,7 +15,7 @@ public function testIsAbstract() { } public function testIsFinal() { - $class = new Class_('Foo', array('type' => Class_::MODIFIER_FINAL)); + $class = new Class_('Foo', ['type' => Class_::MODIFIER_FINAL]); $this->assertTrue($class->isFinal()); $class = new Class_('Foo'); @@ -21,21 +23,21 @@ public function testIsFinal() { } public function testGetMethods() { - $methods = array( + $methods = [ new ClassMethod('foo'), new ClassMethod('bar'), new ClassMethod('fooBar'), - ); - $class = new Class_('Foo', array( - 'stmts' => array( - new TraitUse(array()), + ]; + $class = new Class_('Foo', [ + 'stmts' => [ + new TraitUse([]), $methods[0], - new ClassConst(array()), + new ClassConst([]), $methods[1], - new Property(0, array()), + new Property(0, []), $methods[2], - ) - )); + ] + ]); $this->assertSame($methods, $class->getMethods()); } @@ -43,24 +45,17 @@ public function testGetMethods() { public function testGetMethod() { $methodConstruct = new ClassMethod('__CONSTRUCT'); $methodTest = new ClassMethod('test'); - $class = new Class_('Foo', array( - 'stmts' => array( - new ClassConst(array()), + $class = new Class_('Foo', [ + 'stmts' => [ + new ClassConst([]), $methodConstruct, - new Property(0, array()), + new Property(0, []), $methodTest, - ) - )); + ] + ]); $this->assertSame($methodConstruct, $class->getMethod('__construct')); $this->assertSame($methodTest, $class->getMethod('test')); $this->assertNull($class->getMethod('nonExisting')); } - - public function testDeprecatedTypeNode() { - $class = new Class_('Foo', array('type' => Class_::MODIFIER_ABSTRACT)); - $this->assertTrue($class->isAbstract()); - $this->assertSame(Class_::MODIFIER_ABSTRACT, $class->flags); - $this->assertSame(Class_::MODIFIER_ABSTRACT, $class->type); - } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php index c49905826..e3e90e47c 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/InterfaceTest.php @@ -1,25 +1,26 @@ - array( - new Node\Stmt\ClassConst(array(new Node\Const_('C1', new Node\Scalar\String_('C1')))), + ]; + $interface = new Class_('Foo', [ + 'stmts' => [ + new Node\Stmt\ClassConst([new Node\Const_('C1', new Node\Scalar\String_('C1'))]), $methods[0], - new Node\Stmt\ClassConst(array(new Node\Const_('C2', new Node\Scalar\String_('C2')))), + new Node\Stmt\ClassConst([new Node\Const_('C2', new Node\Scalar\String_('C2'))]), $methods[1], - new Node\Stmt\ClassConst(array(new Node\Const_('C3', new Node\Scalar\String_('C3')))), - ) - )); + new Node\Stmt\ClassConst([new Node\Const_('C3', new Node\Scalar\String_('C3'))]), + ] + ]); $this->assertSame($methods, $interface->getMethods()); } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php index bcfc0c6bd..39387f96f 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Node/Stmt/PropertyTest.php @@ -1,8 +1,10 @@ -assertTrue($node->{'is' . $modifier}()); } public function testNoModifiers() { - $node = new Property(0, array()); + $node = new Property(0, []); $this->assertTrue($node->isPublic()); $this->assertFalse($node->isProtected()); @@ -26,7 +28,7 @@ public function testNoModifiers() { } public function testStaticImplicitlyPublic() { - $node = new Property(Class_::MODIFIER_STATIC, array()); + $node = new Property(Class_::MODIFIER_STATIC, []); $this->assertTrue($node->isPublic()); $this->assertFalse($node->isProtected()); $this->assertFalse($node->isPrivate()); @@ -34,11 +36,11 @@ public function testStaticImplicitlyPublic() { } public function provideModifiers() { - return array( - array('public'), - array('protected'), - array('private'), - array('static'), - ); + return [ + ['public'], + ['protected'], + ['private'], + ['static'], + ]; } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php b/app/vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php index 7fd0a39c7..c8c785db6 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/NodeAbstractTest.php @@ -1,8 +1,11 @@ -subNode2 = $subNode2; } - public function getSubNodeNames() { - return array('subNode1', 'subNode2'); + public function getSubNodeNames() : array { + return ['subNode1', 'subNode2']; } // This method is only overwritten because the node is located in an unusual namespace - public function getType() { + public function getType() : string { return 'Dummy'; } } -class NodeAbstractTest extends \PHPUnit_Framework_TestCase +class NodeAbstractTest extends TestCase { public function provideNodes() { - $attributes = array( + $attributes = [ 'startLine' => 10, - 'comments' => array( + 'endLine' => 11, + 'startTokenPos' => 12, + 'endTokenPos' => 13, + 'startFilePos' => 14, + 'endFilePos' => 15, + 'comments' => [ new Comment('// Comment' . "\n"), new Comment\Doc('/** doc comment */'), - ), - ); + ], + ]; $node = new DummyNode('value1', 'value2', $attributes); $node->notSubNode = 'value3'; - return array( - array($attributes, $node), - ); + return [ + [$attributes, $node], + ]; } /** @@ -46,15 +54,22 @@ public function provideNodes() { */ public function testConstruct(array $attributes, Node $node) { $this->assertSame('Dummy', $node->getType()); - $this->assertSame(array('subNode1', 'subNode2'), $node->getSubNodeNames()); + $this->assertSame(['subNode1', 'subNode2'], $node->getSubNodeNames()); $this->assertSame(10, $node->getLine()); + $this->assertSame(10, $node->getStartLine()); + $this->assertSame(11, $node->getEndLine()); + $this->assertSame(12, $node->getStartTokenPos()); + $this->assertSame(13, $node->getEndTokenPos()); + $this->assertSame(14, $node->getStartFilePos()); + $this->assertSame(15, $node->getEndFilePos()); $this->assertSame('/** doc comment */', $node->getDocComment()->getText()); $this->assertSame('value1', $node->subNode1); $this->assertSame('value2', $node->subNode2); - $this->assertTrue(isset($node->subNode1)); - $this->assertTrue(isset($node->subNode2)); - $this->assertFalse(isset($node->subNode3)); + $this->assertObjectHasAttribute('subNode1', $node); + $this->assertObjectHasAttribute('subNode2', $node); + $this->assertObjectNotHasAttribute('subNode3', $node); $this->assertSame($attributes, $node->getAttributes()); + $this->assertSame($attributes['comments'], $node->getComments()); return $node; } @@ -64,9 +79,14 @@ public function testConstruct(array $attributes, Node $node) { */ public function testGetDocComment(array $attributes, Node $node) { $this->assertSame('/** doc comment */', $node->getDocComment()->getText()); - array_pop($node->getAttribute('comments')); // remove doc comment + $comments = $node->getComments(); + + array_pop($comments); // remove doc comment + $node->setAttribute('comments', $comments); $this->assertNull($node->getDocComment()); - array_pop($node->getAttribute('comments')); // remove comment + + array_pop($comments); // remove comment + $node->setAttribute('comments', $comments); $this->assertNull($node->getDocComment()); } @@ -96,10 +116,6 @@ public function testSetDocComment() { * @dataProvider provideNodes */ public function testChange(array $attributes, Node $node) { - // change of line - $node->setLine(15); - $this->assertSame(15, $node->getLine()); - // direct modification $node->subNode = 'newValue'; $this->assertSame('newValue', $node->subNode); @@ -111,7 +127,7 @@ public function testChange(array $attributes, Node $node) { // removal unset($node->subNode); - $this->assertFalse(isset($node->subNode)); + $this->assertObjectNotHasAttribute('subNode', $node); } /** @@ -125,10 +141,10 @@ public function testIteration(array $attributes, Node $node) { if ($i === 0) { $this->assertSame('subNode1', $key); $this->assertSame('value1', $value); - } else if ($i === 1) { + } elseif ($i === 1) { $this->assertSame('subNode2', $key); $this->assertSame('value2', $value); - } else if ($i === 2) { + } elseif ($i === 2) { $this->assertSame('notSubNode', $key); $this->assertSame('value3', $value); } else { @@ -141,7 +157,7 @@ public function testIteration(array $attributes, Node $node) { public function testAttributes() { /** @var $node Node */ - $node = $this->getMockForAbstractClass('PhpParser\NodeAbstract'); + $node = $this->getMockForAbstractClass(NodeAbstract::class); $this->assertEmpty($node->getAttributes()); @@ -159,10 +175,24 @@ public function testAttributes() { $this->assertNull($node->getAttribute('null', 'default')); $this->assertSame( - array( + [ 'key' => 'value', 'null' => null, - ), + ], + $node->getAttributes() + ); + + $node->setAttributes( + [ + 'a' => 'b', + 'c' => null, + ] + ); + $this->assertSame( + [ + 'a' => 'b', + 'c' => null, + ], $node->getAttributes() ); } @@ -181,14 +211,28 @@ function functionName(&$a = 0, $b = 1.0) { { "nodeType": "Stmt_Function", "byRef": false, - "name": "functionName", + "name": { + "nodeType": "Identifier", + "name": "functionName", + "attributes": { + "startLine": 4, + "endLine": 4 + } + }, "params": [ { "nodeType": "Param", "type": null, "byRef": true, "variadic": false, - "name": "a", + "var": { + "nodeType": "Expr_Variable", + "name": "a", + "attributes": { + "startLine": 4, + "endLine": 4 + } + }, "default": { "nodeType": "Scalar_LNumber", "value": 0, @@ -208,7 +252,14 @@ function functionName(&$a = 0, $b = 1.0) { "type": null, "byRef": false, "variadic": false, - "name": "b", + "var": { + "nodeType": "Expr_Variable", + "name": "b", + "attributes": { + "startLine": 4, + "endLine": 4 + } + }, "default": { "nodeType": "Scalar_DNumber", "value": 1, @@ -251,13 +302,15 @@ function functionName(&$a = 0, $b = 1.0) { "nodeType": "Comment", "text": "\/\/ comment\n", "line": 2, - "filePos": 6 + "filePos": 6, + "tokenPos": 1 }, { "nodeType": "Comment_Doc", "text": "\/** doc comment *\/", "line": 3, - "filePos": 17 + "filePos": 17, + "tokenPos": 2 } ], "endLine": 6 diff --git a/app/vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php b/app/vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php index 9bb65a747..64d53117a 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/NodeDumperTest.php @@ -1,8 +1,10 @@ - 'FooBar'), + ], + [ + ['Foo', 'Bar', 'Key' => 'FooBar'], 'array( 0: Foo 1: Bar Key: FooBar )' - ), - array( - new Node\Name(array('Hallo', 'World')), + ], + [ + new Node\Name(['Hallo', 'World']), 'Name( parts: array( 0: Hallo 1: World ) )' - ), - array( - new Node\Expr\Array_(array( + ], + [ + new Node\Expr\Array_([ new Node\Expr\ArrayItem(new Node\Scalar\String_('Foo')) - )), + ]), 'Expr_Array( items: array( 0: Expr_ArrayItem( @@ -56,8 +58,8 @@ public function provideTestDump() { ) ) )' - ), - ); + ], + ]; } public function testDumpWithPositions() { @@ -70,12 +72,14 @@ public function testDumpWithPositions() { $code = "var, $assign->expr->left, $assign->expr->right]; + return [$stmts, $vars]; + } + + public function testFind() { + $finder = new NodeFinder; + list($stmts, $vars) = $this->getStmtsAndVars(); + $varFilter = function(Node $node) { + return $node instanceof Expr\Variable; + }; + $this->assertSame($vars, $finder->find($stmts, $varFilter)); + $this->assertSame($vars, $finder->find($stmts[0], $varFilter)); + + $noneFilter = function () { return false; }; + $this->assertSame([], $finder->find($stmts, $noneFilter)); + } + + public function testFindInstanceOf() { + $finder = new NodeFinder; + list($stmts, $vars) = $this->getStmtsAndVars(); + $this->assertSame($vars, $finder->findInstanceOf($stmts, Expr\Variable::class)); + $this->assertSame($vars, $finder->findInstanceOf($stmts[0], Expr\Variable::class)); + $this->assertSame([], $finder->findInstanceOf($stmts, Expr\BinaryOp\Mul::class)); + } + + public function testFindFirst() { + $finder = new NodeFinder; + list($stmts, $vars) = $this->getStmtsAndVars(); + $varFilter = function(Node $node) { + return $node instanceof Expr\Variable; + }; + $this->assertSame($vars[0], $finder->findFirst($stmts, $varFilter)); + $this->assertSame($vars[0], $finder->findFirst($stmts[0], $varFilter)); + + $noneFilter = function () { return false; }; + $this->assertNull($finder->findFirst($stmts, $noneFilter)); + } + + public function testFindFirstInstanceOf() { + $finder = new NodeFinder; + list($stmts, $vars) = $this->getStmtsAndVars(); + $this->assertSame($vars[0], $finder->findFirstInstanceOf($stmts, Expr\Variable::class)); + $this->assertSame($vars[0], $finder->findFirstInstanceOf($stmts[0], Expr\Variable::class)); + $this->assertNull($finder->findFirstInstanceOf($stmts, Expr\BinaryOp\Mul::class)); + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php b/app/vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php index 9d27edcb6..61c8e25bb 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/NodeTraverserTest.php @@ -1,19 +1,21 @@ -getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); $visitor->expects($this->at(0))->method('beforeTraverse')->with($stmts); $visitor->expects($this->at(1))->method('enterNode')->with($echoNode); @@ -36,13 +38,13 @@ public function testModifying() { $printNode = new Expr\Print_($str1Node); // first visitor changes the node, second verifies the change - $visitor1 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); - $visitor2 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); // replace empty statements with string1 node - $visitor1->expects($this->at(0))->method('beforeTraverse')->with(array()) - ->will($this->returnValue(array($str1Node))); - $visitor2->expects($this->at(0))->method('beforeTraverse')->with(array($str1Node)); + $visitor1->expects($this->at(0))->method('beforeTraverse')->with([]) + ->will($this->returnValue([$str1Node])); + $visitor2->expects($this->at(0))->method('beforeTraverse')->with([$str1Node]); // replace string1 node with print node $visitor1->expects($this->at(1))->method('enterNode')->with($str1Node) @@ -65,32 +67,32 @@ public function testModifying() { $visitor2->expects($this->at(4))->method('leaveNode')->with($str1Node); // replace string1 node with empty statements again - $visitor1->expects($this->at(5))->method('afterTraverse')->with(array($str1Node)) - ->will($this->returnValue(array())); - $visitor2->expects($this->at(5))->method('afterTraverse')->with(array()); + $visitor1->expects($this->at(5))->method('afterTraverse')->with([$str1Node]) + ->will($this->returnValue([])); + $visitor2->expects($this->at(5))->method('afterTraverse')->with([]); $traverser = new NodeTraverser; $traverser->addVisitor($visitor1); $traverser->addVisitor($visitor2); // as all operations are reversed we end where we start - $this->assertEquals(array(), $traverser->traverse(array())); + $this->assertEquals([], $traverser->traverse([])); } public function testRemove() { $str1Node = new String_('Foo'); $str2Node = new String_('Bar'); - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); // remove the string1 node, leave the string2 node $visitor->expects($this->at(2))->method('leaveNode')->with($str1Node) - ->will($this->returnValue(false)); + ->will($this->returnValue(NodeTraverser::REMOVE_NODE)); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); - $this->assertEquals(array($str2Node), $traverser->traverse(array($str1Node, $str2Node))); + $this->assertEquals([$str2Node], $traverser->traverse([$str1Node, $str2Node])); } public function testMerge() { @@ -100,31 +102,30 @@ public function testMerge() { $strR1 = new String_('Replacement 1'); $strR2 = new String_('Replacement 2'); - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); // replace strMiddle with strR1 and strR2 by merge $visitor->expects($this->at(4))->method('leaveNode')->with($strMiddle) - ->will($this->returnValue(array($strR1, $strR2))); + ->will($this->returnValue([$strR1, $strR2])); $traverser = new NodeTraverser; $traverser->addVisitor($visitor); $this->assertEquals( - array($strStart, $strR1, $strR2, $strEnd), - $traverser->traverse(array($strStart, $strMiddle, $strEnd)) + [$strStart, $strR1, $strR2, $strEnd], + $traverser->traverse([$strStart, $strMiddle, $strEnd]) ); } - public function testDeepArray() { + /** + * @expectedException \LogicException + * @expectedExceptionMessage Invalid node structure: Contains nested arrays + */ + public function testInvalidDeepArray() { $strNode = new String_('Foo'); - $stmts = array(array(array($strNode))); - - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); - $visitor->expects($this->at(1))->method('enterNode')->with($strNode); + $stmts = [[[$strNode]]]; $traverser = new NodeTraverser; - $traverser->addVisitor($visitor); - $this->assertEquals($stmts, $traverser->traverse($stmts)); } @@ -134,10 +135,10 @@ public function testDontTraverseChildren() { $varNode = new Expr\Variable('foo'); $mulNode = new Expr\BinaryOp\Mul($varNode, $varNode); $negNode = new Expr\UnaryMinus($mulNode); - $stmts = array($printNode, $negNode); + $stmts = [$printNode, $negNode]; - $visitor1 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); - $visitor2 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); $visitor1->expects($this->at(1))->method('enterNode')->with($printNode) ->will($this->returnValue(NodeTraverser::DONT_TRAVERSE_CHILDREN)); @@ -175,7 +176,7 @@ public function testStopTraversal() { $stmts = [$mulNode, $printNode]; // From enterNode() with array parent - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); $visitor->expects($this->at(1))->method('enterNode')->with($mulNode) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(2))->method('afterTraverse'); @@ -184,7 +185,7 @@ public function testStopTraversal() { $this->assertEquals($stmts, $traverser->traverse($stmts)); // From enterNode with Node parent - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); $visitor->expects($this->at(2))->method('enterNode')->with($varNode1) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(3))->method('afterTraverse'); @@ -193,7 +194,7 @@ public function testStopTraversal() { $this->assertEquals($stmts, $traverser->traverse($stmts)); // From leaveNode with Node parent - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); $visitor->expects($this->at(3))->method('leaveNode')->with($varNode1) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(4))->method('afterTraverse'); @@ -202,7 +203,7 @@ public function testStopTraversal() { $this->assertEquals($stmts, $traverser->traverse($stmts)); // From leaveNode with array parent - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); $visitor->expects($this->at(6))->method('leaveNode')->with($mulNode) ->will($this->returnValue(NodeTraverser::STOP_TRAVERSAL)); $visitor->expects($this->at(7))->method('afterTraverse'); @@ -211,7 +212,7 @@ public function testStopTraversal() { $this->assertEquals($stmts, $traverser->traverse($stmts)); // Check that pending array modifications are still carried out - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor = $this->getMockBuilder(NodeVisitor::class)->getMock(); $visitor->expects($this->at(6))->method('leaveNode')->with($mulNode) ->will($this->returnValue(NodeTraverser::REMOVE_NODE)); $visitor->expects($this->at(7))->method('enterNode')->with($printNode) @@ -224,26 +225,26 @@ public function testStopTraversal() { } public function testRemovingVisitor() { - $visitor1 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); - $visitor2 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); - $visitor3 = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor3 = $this->getMockBuilder(NodeVisitor::class)->getMock(); $traverser = new NodeTraverser; $traverser->addVisitor($visitor1); $traverser->addVisitor($visitor2); $traverser->addVisitor($visitor3); - $preExpected = array($visitor1, $visitor2, $visitor3); + $preExpected = [$visitor1, $visitor2, $visitor3]; $this->assertAttributeSame($preExpected, 'visitors', $traverser, 'The appropriate visitors have not been added'); $traverser->removeVisitor($visitor2); - $postExpected = array(0 => $visitor1, 2 => $visitor3); + $postExpected = [0 => $visitor1, 2 => $visitor3]; $this->assertAttributeSame($postExpected, 'visitors', $traverser, 'The appropriate visitors are not present after removal'); } public function testNoCloneNodes() { - $stmts = array(new Node\Stmt\Echo_(array(new String_('Foo'), new String_('Bar')))); + $stmts = [new Node\Stmt\Echo_([new String_('Foo'), new String_('Bar')])]; $traverser = new NodeTraverser; @@ -251,17 +252,61 @@ public function testNoCloneNodes() { } /** - * @expectedException \LogicException - * @expectedExceptionMessage leaveNode() may only return an array if the parent structure is an array + * @dataProvider provideTestInvalidReturn */ - public function testReplaceByArrayOnlyAllowedIfParentIsArray() { - $stmts = array(new Node\Expr\UnaryMinus(new Node\Scalar\LNumber(42))); + public function testInvalidReturn($visitor, $message) { + $this->expectException(\LogicException::class); + $this->expectExceptionMessage($message); - $visitor = $this->getMockBuilder('PhpParser\NodeVisitor')->getMock(); - $visitor->method('leaveNode')->willReturn(array(new Node\Scalar\DNumber(42.0))); + $stmts = [new Node\Stmt\Expression(new Node\Scalar\LNumber(42))]; $traverser = new NodeTraverser(); $traverser->addVisitor($visitor); $traverser->traverse($stmts); } + + public function provideTestInvalidReturn() { + $visitor1 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor1->expects($this->at(1))->method('enterNode') + ->willReturn('foobar'); + + $visitor2 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor2->expects($this->at(2))->method('enterNode') + ->willReturn('foobar'); + + $visitor3 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor3->expects($this->at(3))->method('leaveNode') + ->willReturn('foobar'); + + $visitor4 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor4->expects($this->at(4))->method('leaveNode') + ->willReturn('foobar'); + + $visitor5 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor5->expects($this->at(3))->method('leaveNode') + ->willReturn([new Node\Scalar\DNumber(42.0)]); + + $visitor6 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor6->expects($this->at(4))->method('leaveNode') + ->willReturn(false); + + $visitor7 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor7->expects($this->at(1))->method('enterNode') + ->willReturn(new Node\Scalar\LNumber(42)); + + $visitor8 = $this->getMockBuilder(NodeVisitor::class)->getMock(); + $visitor8->expects($this->at(2))->method('enterNode') + ->willReturn(new Node\Stmt\Return_()); + + return [ + [$visitor1, 'enterNode() returned invalid value of type string'], + [$visitor2, 'enterNode() returned invalid value of type string'], + [$visitor3, 'leaveNode() returned invalid value of type string'], + [$visitor4, 'leaveNode() returned invalid value of type string'], + [$visitor5, 'leaveNode() may only return an array if the parent structure is an array'], + [$visitor6, 'bool(false) return from leaveNode() no longer supported. Return NodeTraverser::REMOVE_NODE instead'], + [$visitor7, 'Trying to replace statement (Stmt_Expression) with expression (Scalar_LNumber). Are you missing a Stmt_Expression wrapper?'], + [$visitor8, 'Trying to replace expression (Scalar_LNumber) with statement (Stmt_Return)'], + ]; + } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FindingVisitorTest.php b/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FindingVisitorTest.php new file mode 100644 index 000000000..2e87600b6 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FindingVisitorTest.php @@ -0,0 +1,54 @@ +addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat( + new Expr\Variable('b'), new Expr\Variable('c') + )); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertSame([ + $assign->var, + $assign->expr->left, + $assign->expr->right, + ], $visitor->getFoundNodes()); + } + + public function testFindAll() { + $traverser = new NodeTraverser(); + $visitor = new FindingVisitor(function(Node $node) { + return true; // All nodes + }); + $traverser->addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\BinaryOp\Concat( + new Expr\Variable('b'), new Expr\Variable('c') + )); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertSame([ + $stmts[0], + $assign, + $assign->var, + $assign->expr, + $assign->expr->left, + $assign->expr->right, + ], $visitor->getFoundNodes()); + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FirstFindingVisitorTest.php b/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FirstFindingVisitorTest.php new file mode 100644 index 000000000..78bc1c7a0 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/FirstFindingVisitorTest.php @@ -0,0 +1,39 @@ +addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertSame($assign->var, $visitor->getFoundNode()); + } + + public function testFindNone() { + $traverser = new NodeTraverser(); + $visitor = new FirstFindingVisitor(function(Node $node) { + return $node instanceof Node\Expr\BinaryOp; + }); + $traverser->addVisitor($visitor); + + $assign = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); + $stmts = [new Node\Stmt\Expression($assign)]; + + $traverser->traverse($stmts); + $this->assertNull($visitor->getFoundNode()); + } +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php b/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php index 031337459..1ffd15aa8 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/NodeVisitor/NameResolverTest.php @@ -1,4 +1,4 @@ -addVisitor(new NameResolver); @@ -288,16 +289,16 @@ public function testNoResolveSpecialName() { } public function testAddDeclarationNamespacedName() { - $nsStmts = array( + $nsStmts = [ new Stmt\Class_('A'), new Stmt\Interface_('B'), new Stmt\Function_('C'), - new Stmt\Const_(array( + new Stmt\Const_([ new Node\Const_('D', new Node\Scalar\LNumber(42)) - )), + ]), new Stmt\Trait_('E'), new Expr\New_(new Stmt\Class_(null)), - ); + ]; $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); @@ -320,21 +321,21 @@ public function testAddDeclarationNamespacedName() { } public function testAddRuntimeResolvedNamespacedName() { - $stmts = array( - new Stmt\Namespace_(new Name('NS'), array( + $stmts = [ + new Stmt\Namespace_(new Name('NS'), [ new Expr\FuncCall(new Name('foo')), new Expr\ConstFetch(new Name('FOO')), - )), - new Stmt\Namespace_(null, array( + ]), + new Stmt\Namespace_(null, [ new Expr\FuncCall(new Name('foo')), new Expr\ConstFetch(new Name('FOO')), - )), - ); + ]), + ]; $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); $stmts = $traverser->traverse($stmts); - + $this->assertSame('NS\\foo', (string) $stmts[0]->stmts[0]->name->getAttribute('namespacedName')); $this->assertSame('NS\\FOO', (string) $stmts[0]->stmts[1]->name->getAttribute('namespacedName')); @@ -346,53 +347,54 @@ public function testAddRuntimeResolvedNamespacedName() { * @dataProvider provideTestError */ public function testError(Node $stmt, $errorMsg) { - $this->setExpectedException('PhpParser\Error', $errorMsg); + $this->expectException(\PhpParser\Error::class); + $this->expectExceptionMessage($errorMsg); $traverser = new PhpParser\NodeTraverser; $traverser->addVisitor(new NameResolver); - $traverser->traverse(array($stmt)); + $traverser->traverse([$stmt]); } public function provideTestError() { - return array( - array( - new Stmt\Use_(array( - new Stmt\UseUse(new Name('A\B'), 'B', 0, array('startLine' => 1)), - new Stmt\UseUse(new Name('C\D'), 'B', 0, array('startLine' => 2)), - ), Stmt\Use_::TYPE_NORMAL), + return [ + [ + new Stmt\Use_([ + new Stmt\UseUse(new Name('A\B'), 'B', 0, ['startLine' => 1]), + new Stmt\UseUse(new Name('C\D'), 'B', 0, ['startLine' => 2]), + ], Stmt\Use_::TYPE_NORMAL), 'Cannot use C\D as B because the name is already in use on line 2' - ), - array( - new Stmt\Use_(array( - new Stmt\UseUse(new Name('a\b'), 'b', 0, array('startLine' => 1)), - new Stmt\UseUse(new Name('c\d'), 'B', 0, array('startLine' => 2)), - ), Stmt\Use_::TYPE_FUNCTION), + ], + [ + new Stmt\Use_([ + new Stmt\UseUse(new Name('a\b'), 'b', 0, ['startLine' => 1]), + new Stmt\UseUse(new Name('c\d'), 'B', 0, ['startLine' => 2]), + ], Stmt\Use_::TYPE_FUNCTION), 'Cannot use function c\d as B because the name is already in use on line 2' - ), - array( - new Stmt\Use_(array( - new Stmt\UseUse(new Name('A\B'), 'B', 0, array('startLine' => 1)), - new Stmt\UseUse(new Name('C\D'), 'B', 0, array('startLine' => 2)), - ), Stmt\Use_::TYPE_CONSTANT), + ], + [ + new Stmt\Use_([ + new Stmt\UseUse(new Name('A\B'), 'B', 0, ['startLine' => 1]), + new Stmt\UseUse(new Name('C\D'), 'B', 0, ['startLine' => 2]), + ], Stmt\Use_::TYPE_CONSTANT), 'Cannot use const C\D as B because the name is already in use on line 2' - ), - array( - new Expr\New_(new Name\FullyQualified('self', array('startLine' => 3))), + ], + [ + new Expr\New_(new Name\FullyQualified('self', ['startLine' => 3])), "'\\self' is an invalid class name on line 3" - ), - array( - new Expr\New_(new Name\Relative('self', array('startLine' => 3))), + ], + [ + new Expr\New_(new Name\Relative('self', ['startLine' => 3])), "'\\self' is an invalid class name on line 3" - ), - array( - new Expr\New_(new Name\FullyQualified('PARENT', array('startLine' => 3))), + ], + [ + new Expr\New_(new Name\FullyQualified('PARENT', ['startLine' => 3])), "'\\PARENT' is an invalid class name on line 3" - ), - array( - new Expr\New_(new Name\Relative('STATIC', array('startLine' => 3))), + ], + [ + new Expr\New_(new Name\Relative('STATIC', ['startLine' => 3])), "'\\STATIC' is an invalid class name on line 3" - ), - ); + ], + ]; } public function testClassNameIsCaseInsensitive() @@ -413,7 +415,8 @@ public function testClassNameIsCaseInsensitive() $stmts = $traverser->traverse($stmts); $stmt = $stmts[0]; - $this->assertSame(array('Bar', 'Baz'), $stmt->stmts[1]->expr->class->parts); + $assign = $stmt->stmts[1]->expr; + $this->assertSame(['Bar', 'Baz'], $assign->expr->class->parts); } public function testSpecialClassNamesAreCaseInsensitive() { @@ -442,9 +445,9 @@ public static function method() $classStmt = $stmts[0]; $methodStmt = $classStmt->stmts[0]->stmts[0]; - $this->assertSame('SELF', (string)$methodStmt->stmts[0]->class); - $this->assertSame('PARENT', (string)$methodStmt->stmts[1]->class); - $this->assertSame('STATIC', (string)$methodStmt->stmts[2]->class); + $this->assertSame('SELF', (string) $methodStmt->stmts[0]->expr->class); + $this->assertSame('PARENT', (string) $methodStmt->stmts[1]->expr->class); + $this->assertSame('STATIC', (string) $methodStmt->stmts[2]->expr->class); } public function testAddOriginalNames() { @@ -465,4 +468,26 @@ public function testAddOriginalNames() { $this->assertSame($n1, $stmts[0]->stmts[0]->class->getAttribute('originalName')); $this->assertSame($n2, $stmts[0]->stmts[1]->name->getAttribute('originalName')); } + + public function testAttributeOnlyMode() { + $traverser = new PhpParser\NodeTraverser; + $traverser->addVisitor(new NameResolver(null, ['replaceNodes' => false])); + + $n1 = new Name('Bar'); + $n2 = new Name('bar'); + $origStmts = [ + new Stmt\Namespace_(new Name('Foo'), [ + new Expr\ClassConstFetch($n1, 'FOO'), + new Expr\FuncCall($n2), + ]) + ]; + + $traverser->traverse($origStmts); + + $this->assertEquals( + new Name\FullyQualified('Foo\Bar'), $n1->getAttribute('resolvedName')); + $this->assertFalse($n2->hasAttribute('resolvedName')); + $this->assertEquals( + new Name\FullyQualified('Foo\bar'), $n2->getAttribute('namespacedName')); + } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php index 01d3b6040..f7decb76c 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Parser/MultipleTest.php @@ -1,4 +1,4 @@ -getPrefer5(), [ - new Expr\Variable( + new Stmt\Expression(new Expr\Variable( new Expr\ArrayDimFetch(new Expr\Variable('a'), LNumber::fromString('0')) - ) + )) ] ], [ @@ -69,26 +70,27 @@ public function provideTestParse() { 'getPrefer7(), [ - new Expr\ArrayDimFetch( + new Stmt\Expression(new Expr\ArrayDimFetch( new Expr\Variable(new Expr\Variable('a')), LNumber::fromString('0') - ) + )) ] ], ]; } public function testThrownError() { - $this->setExpectedException('PhpParser\Error', 'FAIL A'); + $this->expectException(Error::class); + $this->expectExceptionMessage('FAIL A'); - $parserA = $this->getMockBuilder('PhpParser\Parser')->getMock(); + $parserA = $this->getMockBuilder(\PhpParser\Parser::class)->getMock(); $parserA->expects($this->at(0)) ->method('parse')->will($this->throwException(new Error('FAIL A'))); - $parserB = $this->getMockBuilder('PhpParser\Parser')->getMock(); + $parserB = $this->getMockBuilder(\PhpParser\Parser::class)->getMock(); $parserB->expects($this->at(0)) ->method('parse')->will($this->throwException(new Error('FAIL B'))); $parser = new Multiple([$parserA, $parserB]); $parser->parse('dummy'); } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php b/app/vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php index 58c4e617c..bb36a2517 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/Parser/Php5Test.php @@ -1,4 +1,4 @@ -assertInstanceOf($expected, (new ParserFactory)->create($kind, $lexer)); @@ -15,20 +18,20 @@ public function provideTestCreate() { return [ [ ParserFactory::PREFER_PHP7, $lexer, - 'PhpParser\Parser\Multiple' + Parser\Multiple::class ], [ ParserFactory::PREFER_PHP5, null, - 'PhpParser\Parser\Multiple' + Parser\Multiple::class ], [ ParserFactory::ONLY_PHP7, null, - 'PhpParser\Parser\Php7' + Parser\Php7::class ], [ ParserFactory::ONLY_PHP5, $lexer, - 'PhpParser\Parser\Php5' + Parser\Php5::class ] ]; } -} \ No newline at end of file +} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/ParserTest.php b/app/vendor/nikic/php-parser/test/PhpParser/ParserTest.php index 0dabba216..9c4412dc1 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/ParserTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/ParserTest.php @@ -1,13 +1,14 @@ - array( + $lexer = new Lexer([ + 'usedAttributes' => [ 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', - ) - )); + ] + ]); $code = <<<'EOC' getParser($lexer); $stmts = $parser->parse($code); - /** @var \PhpParser\Node\Stmt\Function_ $fn */ + /** @var Stmt\Function_ $fn */ $fn = $stmts[0]; - $this->assertInstanceOf('PhpParser\Node\Stmt\Function_', $fn); - $this->assertEquals(array( - 'comments' => array( - new Comment\Doc('/** Doc comment */', 2, 6), - ), + $this->assertInstanceOf(Stmt\Function_::class, $fn); + $this->assertEquals([ + 'comments' => [ + new Comment\Doc('/** Doc comment */', 2, 6, 1), + ], 'startLine' => 3, 'endLine' => 7, 'startTokenPos' => 3, 'endTokenPos' => 21, - ), $fn->getAttributes()); + ], $fn->getAttributes()); $param = $fn->params[0]; - $this->assertInstanceOf('PhpParser\Node\Param', $param); - $this->assertEquals(array( + $this->assertInstanceOf(Node\Param::class, $param); + $this->assertEquals([ 'startLine' => 3, 'endLine' => 3, 'startTokenPos' => 7, 'endTokenPos' => 7, - ), $param->getAttributes()); + ], $param->getAttributes()); - /** @var \PhpParser\Node\Stmt\Echo_ $echo */ + /** @var Stmt\Echo_ $echo */ $echo = $fn->stmts[0]; - $this->assertInstanceOf('PhpParser\Node\Stmt\Echo_', $echo); - $this->assertEquals(array( - 'comments' => array( - new Comment("// Line\n", 4, 49), - new Comment("// Comments\n", 5, 61), - ), + $this->assertInstanceOf(Stmt\Echo_::class, $echo); + $this->assertEquals([ + 'comments' => [ + new Comment("// Line\n", 4, 49, 12), + new Comment("// Comments\n", 5, 61, 14), + ], 'startLine' => 6, 'endLine' => 6, 'startTokenPos' => 16, 'endTokenPos' => 19, - ), $echo->getAttributes()); + ], $echo->getAttributes()); /** @var \PhpParser\Node\Expr\Variable $var */ $var = $echo->exprs[0]; - $this->assertInstanceOf('PhpParser\Node\Expr\Variable', $var); - $this->assertEquals(array( + $this->assertInstanceOf(Expr\Variable::class, $var); + $this->assertEquals([ 'startLine' => 6, 'endLine' => 6, 'startTokenPos' => 18, 'endTokenPos' => 18, - ), $var->getAttributes()); + ], $var->getAttributes()); } /** @@ -124,60 +125,60 @@ public function testInvalidToken() { public function testExtraAttributes($code, $expectedAttributes) { $parser = $this->getParser(new Lexer); $stmts = $parser->parse("getAttributes(); + $node = $stmts[0] instanceof Stmt\Expression ? $stmts[0]->expr : $stmts[0]; + $attributes = $node->getAttributes(); foreach ($expectedAttributes as $name => $value) { $this->assertSame($value, $attributes[$name]); } } public function provideTestExtraAttributes() { - return array( - array('0', ['kind' => Scalar\LNumber::KIND_DEC]), - array('9', ['kind' => Scalar\LNumber::KIND_DEC]), - array('07', ['kind' => Scalar\LNumber::KIND_OCT]), - array('0xf', ['kind' => Scalar\LNumber::KIND_HEX]), - array('0XF', ['kind' => Scalar\LNumber::KIND_HEX]), - array('0b1', ['kind' => Scalar\LNumber::KIND_BIN]), - array('0B1', ['kind' => Scalar\LNumber::KIND_BIN]), - array('[]', ['kind' => Expr\Array_::KIND_SHORT]), - array('array()', ['kind' => Expr\Array_::KIND_LONG]), - array("'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]), - array("b'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]), - array("B'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]), - array('"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]), - array('b"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]), - array('B"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]), - array('"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]), - array('b"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]), - array('B"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]), - array("<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), - array("<< String_::KIND_HEREDOC, 'docLabel' => 'STR']), - array("<<<\"STR\"\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), - array("b<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), - array("B<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), - array("<<< \t 'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']), - // HHVM doesn't support this due to a lexer bug - // (https://github.com/facebook/hhvm/issues/6970) - // array("<<<'\xff'\n\xff\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => "\xff"]), - array("<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), - array("b<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), - array("B<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), - array("<<< \t \"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']), - array("die", ['kind' => Expr\Exit_::KIND_DIE]), - array("die('done')", ['kind' => Expr\Exit_::KIND_DIE]), - array("exit", ['kind' => Expr\Exit_::KIND_EXIT]), - array("exit(1)", ['kind' => Expr\Exit_::KIND_EXIT]), - array("?>Foo", ['hasLeadingNewline' => false]), - array("?>\nFoo", ['hasLeadingNewline' => true]), - array("namespace Foo;", ['kind' => Node\Stmt\Namespace_::KIND_SEMICOLON]), - array("namespace Foo {}", ['kind' => Node\Stmt\Namespace_::KIND_BRACED]), - array("namespace {}", ['kind' => Node\Stmt\Namespace_::KIND_BRACED]), - ); + return [ + ['0', ['kind' => Scalar\LNumber::KIND_DEC]], + ['9', ['kind' => Scalar\LNumber::KIND_DEC]], + ['07', ['kind' => Scalar\LNumber::KIND_OCT]], + ['0xf', ['kind' => Scalar\LNumber::KIND_HEX]], + ['0XF', ['kind' => Scalar\LNumber::KIND_HEX]], + ['0b1', ['kind' => Scalar\LNumber::KIND_BIN]], + ['0B1', ['kind' => Scalar\LNumber::KIND_BIN]], + ['[]', ['kind' => Expr\Array_::KIND_SHORT]], + ['array()', ['kind' => Expr\Array_::KIND_LONG]], + ["'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]], + ["b'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]], + ["B'foo'", ['kind' => String_::KIND_SINGLE_QUOTED]], + ['"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['b"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['B"foo"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['b"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ['B"foo$bar"', ['kind' => String_::KIND_DOUBLE_QUOTED]], + ["<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']], + ["<< String_::KIND_HEREDOC, 'docLabel' => 'STR']], + ["<<<\"STR\"\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']], + ["b<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']], + ["B<<<'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']], + ["<<< \t 'STR'\nSTR\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => 'STR']], + ["<<<'\xff'\n\xff\n", ['kind' => String_::KIND_NOWDOC, 'docLabel' => "\xff"]], + ["<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']], + ["b<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']], + ["B<<<\"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']], + ["<<< \t \"STR\"\n\$a\nSTR\n", ['kind' => String_::KIND_HEREDOC, 'docLabel' => 'STR']], + ["die", ['kind' => Expr\Exit_::KIND_DIE]], + ["die('done')", ['kind' => Expr\Exit_::KIND_DIE]], + ["exit", ['kind' => Expr\Exit_::KIND_EXIT]], + ["exit(1)", ['kind' => Expr\Exit_::KIND_EXIT]], + ["?>Foo", ['hasLeadingNewline' => false]], + ["?>\nFoo", ['hasLeadingNewline' => true]], + ["namespace Foo;", ['kind' => Stmt\Namespace_::KIND_SEMICOLON]], + ["namespace Foo {}", ['kind' => Stmt\Namespace_::KIND_BRACED]], + ["namespace {}", ['kind' => Stmt\Namespace_::KIND_BRACED]], + ]; } } -class InvalidTokenLexer extends Lexer { - public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) { +class InvalidTokenLexer extends Lexer +{ + public function getNextToken(&$value = null, &$startAttributes = null, &$endAttributes = null) : int { $value = 'foobar'; return 999; } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php b/app/vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php index 908c18b2b..b15557194 100644 --- a/app/vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php +++ b/app/vendor/nikic/php-parser/test/PhpParser/PrettyPrinterTest.php @@ -1,8 +1,7 @@ -assertSame($expected, $output5, $name); $this->assertNotSame($expected, $output7, $name); - } else if ('php7' === $version) { + } elseif ('php7' === $version) { $this->assertSame($expected, $output7, $name); $this->assertNotSame($expected, $output5, $name); } else { @@ -57,7 +56,7 @@ protected function doTestPrettyPrintMethod($method, $name, $code, $expected, $mo /** * @dataProvider provideTestPrettyPrint - * @covers PhpParser\PrettyPrinter\Standard + * @covers \PhpParser\PrettyPrinter\Standard */ public function testPrettyPrint($name, $code, $expected, $mode) { $this->doTestPrettyPrintMethod('prettyPrint', $name, $code, $expected, $mode); @@ -65,7 +64,7 @@ public function testPrettyPrint($name, $code, $expected, $mode) { /** * @dataProvider provideTestPrettyPrintFile - * @covers PhpParser\PrettyPrinter\Standard + * @covers \PhpParser\PrettyPrinter\Standard */ public function testPrettyPrintFile($name, $code, $expected, $mode) { $this->doTestPrettyPrintMethod('prettyPrintFile', $name, $code, $expected, $mode); @@ -87,9 +86,9 @@ public function testPrettyPrintExpr() { ); $this->assertEquals('($a + $b) * $c', $prettyPrinter->prettyPrintExpr($expr)); - $expr = new Expr\Closure(array( - 'stmts' => array(new Stmt\Return_(new String_("a\nb"))) - )); + $expr = new Expr\Closure([ + 'stmts' => [new Stmt\Return_(new String_("a\nb"))] + ]); $this->assertEquals("function () {\n return 'a\nb';\n}", $prettyPrinter->prettyPrintExpr($expr)); } @@ -102,8 +101,8 @@ public function testCommentBeforeInlineHTML() { } private function parseModeLine($modeLine) { - $parts = explode(' ', $modeLine, 2); - $version = isset($parts[0]) ? $parts[0] : 'both'; + $parts = explode(' ', (string) $modeLine, 2); + $version = $parts[0] ?? 'both'; $options = isset($parts[1]) ? json_decode($parts[1], true) : []; return [$version, $options]; } @@ -190,7 +189,9 @@ public function provideTestUnnaturalLiterals() { * @expectedExceptionMessage Cannot pretty-print AST with Error nodes */ public function testPrettyPrintWithError() { - $stmts = [new Expr\PropertyFetch(new Expr\Variable('a'), new Expr\Error())]; + $stmts = [new Stmt\Expression( + new Expr\PropertyFetch(new Expr\Variable('a'), new Expr\Error()) + )]; $prettyPrinter = new PrettyPrinter\Standard; $prettyPrinter->prettyPrint($stmts); } @@ -200,8 +201,115 @@ public function testPrettyPrintWithError() { * @expectedExceptionMessage Cannot pretty-print AST with Error nodes */ public function testPrettyPrintWithErrorInClassConstFetch() { - $stmts = [new Expr\ClassConstFetch(new Name('Foo'), new Expr\Error())]; + $stmts = [new Stmt\Expression( + new Expr\ClassConstFetch(new Name('Foo'), new Expr\Error()) + )]; $prettyPrinter = new PrettyPrinter\Standard; $prettyPrinter->prettyPrint($stmts); } + + /** + * @expectedException \LogicException + * @expectedExceptionMessage Cannot directly print EncapsedStringPart + */ + public function testPrettyPrintEncapsedStringPart() { + $expr = new Node\Scalar\EncapsedStringPart('foo'); + $prettyPrinter = new PrettyPrinter\Standard; + $prettyPrinter->prettyPrintExpr($expr); + } + + /** + * @dataProvider provideTestFormatPreservingPrint + * @covers \PhpParser\PrettyPrinter\Standard + */ + public function testFormatPreservingPrint($name, $code, $modification, $expected, $modeLine) { + $lexer = new Lexer\Emulative([ + 'usedAttributes' => [ + 'comments', + 'startLine', 'endLine', + 'startTokenPos', 'endTokenPos', + ], + ]); + + $parser = new Parser\Php7($lexer); + $traverser = new NodeTraverser(); + $traverser->addVisitor(new NodeVisitor\CloningVisitor()); + + $printer = new PrettyPrinter\Standard(); + + $oldStmts = $parser->parse($code); + $oldTokens = $lexer->getTokens(); + + $newStmts = $traverser->traverse($oldStmts); + + /** @var callable $fn */ + eval(<<printFormatPreserving($newStmts, $oldStmts, $oldTokens); + $this->assertSame(canonicalize($expected), canonicalize($newCode), $name); + } + + public function provideTestFormatPreservingPrint() { + return $this->getTests(__DIR__ . '/../code/formatPreservation', 'test', 3); + } + + /** + * @dataProvider provideTestRoundTripPrint + * @covers \PhpParser\PrettyPrinter\Standard + */ + public function testRoundTripPrint($name, $code, $expected, $modeLine) { + /** + * This test makes sure that the format-preserving pretty printer round-trips for all + * the pretty printer tests (i.e. returns the input if no changes occurred). + */ + + list($version) = $this->parseModeLine($modeLine); + + $lexer = new Lexer\Emulative([ + 'usedAttributes' => [ + 'comments', + 'startLine', 'endLine', + 'startTokenPos', 'endTokenPos', + ], + ]); + + $parserClass = $version === 'php5' ? Parser\Php5::class : Parser\Php7::class; + /** @var Parser $parser */ + $parser = new $parserClass($lexer); + + $traverser = new NodeTraverser(); + $traverser->addVisitor(new NodeVisitor\CloningVisitor()); + + $printer = new PrettyPrinter\Standard(); + + try { + $oldStmts = $parser->parse($code); + } catch (Error $e) { + // Can't do a format-preserving print on a file with errors + return; + } + + $oldTokens = $lexer->getTokens(); + + $newStmts = $traverser->traverse($oldStmts); + + $newCode = $printer->printFormatPreserving($newStmts, $oldStmts, $oldTokens); + $this->assertSame(canonicalize($code), canonicalize($newCode), $name); + } + + public function provideTestRoundTripPrint() { + return array_merge( + $this->getTests(__DIR__ . '/../code/prettyPrinter', 'test'), + $this->getTests(__DIR__ . '/../code/parser', 'test') + ); + } } diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Serializer/XMLTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Serializer/XMLTest.php deleted file mode 100644 index e1186f4d5..000000000 --- a/app/vendor/nikic/php-parser/test/PhpParser/Serializer/XMLTest.php +++ /dev/null @@ -1,172 +0,0 @@ - - */ - public function testSerialize() { - $code = << - - - - - 4 - - - - // comment - - /** doc comment */ - - - - 6 - - - - - - functionName - - - - - - 4 - - - 4 - - - - - - - - - - - - a - - - - - 4 - - - 4 - - - 10 - - - 0 - - - - - - - 4 - - - 4 - - - - - - - - - - - - b - - - - - 4 - - - 4 - - - 1 - - - - - - - - - - - - - - 5 - - - 5 - - - - - - 5 - - - 5 - - - 1 - - - Foo - - - - - - - - - - -XML; - - $parser = new PhpParser\Parser\Php7(new PhpParser\Lexer); - $serializer = new XML; - - $code = str_replace("\r\n", "\n", $code); - $stmts = $parser->parse($code); - $this->assertXmlStringEqualsXmlString($xml, $serializer->serialize($stmts)); - } - - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Unexpected node type - */ - public function testError() { - $serializer = new XML; - $serializer->serialize(array(new \stdClass)); - } -} diff --git a/app/vendor/nikic/php-parser/test/PhpParser/Unserializer/XMLTest.php b/app/vendor/nikic/php-parser/test/PhpParser/Unserializer/XMLTest.php deleted file mode 100644 index 3bc86dbed..000000000 --- a/app/vendor/nikic/php-parser/test/PhpParser/Unserializer/XMLTest.php +++ /dev/null @@ -1,150 +0,0 @@ - - - - - 1 - - - - // comment - - /** doc comment */ - - - - Test - - - -XML; - - $unserializer = new XML; - $this->assertEquals( - new Scalar\String_('Test', array( - 'startLine' => 1, - 'comments' => array( - new Comment('// comment' . "\n", 2), - new Comment\Doc('/** doc comment */', 3), - ), - )), - $unserializer->unserialize($xml) - ); - } - - public function testEmptyNode() { - $xml = << - - - -XML; - - $unserializer = new XML; - - $this->assertEquals( - new Scalar\MagicConst\Class_, - $unserializer->unserialize($xml) - ); - } - - public function testScalars() { - $xml = << - - - - - test - - - 1 - 1 - 1.5 - - - - - -XML; - $result = array( - array(), array(), - 'test', '', '', - 1, - 1, 1.5, - true, false, null - ); - - $unserializer = new XML; - $this->assertEquals($result, $unserializer->unserialize($xml)); - } - - /** - * @expectedException \DomainException - * @expectedExceptionMessage AST root element not found - */ - public function testWrongRootElementError() { - $xml = << - -XML; - - $unserializer = new XML; - $unserializer->unserialize($xml); - } - - /** - * @dataProvider provideTestErrors - */ - public function testErrors($xml, $errorMsg) { - $this->setExpectedException('DomainException', $errorMsg); - - $xml = << - - $xml - -XML; - - $unserializer = new XML; - $unserializer->unserialize($xml); - } - - public function provideTestErrors() { - return array( - array('test', '"true" scalar must be empty'), - array('test', '"false" scalar must be empty'), - array('test', '"null" scalar must be empty'), - array('bar', 'Unknown scalar type "foo"'), - array('x', '"x" is not a valid int'), - array('x', '"x" is not a valid float'), - array('', 'Expected node or scalar'), - array('test', 'Unexpected node of type "foo:bar"'), - array( - 'test', - 'Expected sub node or attribute, got node of type "foo:bar"' - ), - array( - '', - 'Expected node or scalar' - ), - array( - '', - 'Unknown node type "Foo"' - ), - ); - } -} diff --git a/app/vendor/nikic/php-parser/test/bootstrap.php b/app/vendor/nikic/php-parser/test/bootstrap.php index 9526b648b..0bfa9d0ad 100644 --- a/app/vendor/nikic/php-parser/test/bootstrap.php +++ b/app/vendor/nikic/php-parser/test/bootstrap.php @@ -18,3 +18,14 @@ function canonicalize($str) { }, $lines); return implode("\n", $lines); } + +function filesInDir($directory, $fileExtension) { + $directory = realpath($directory); + $it = new \RecursiveDirectoryIterator($directory); + $it = new \RecursiveIteratorIterator($it, \RecursiveIteratorIterator::LEAVES_ONLY); + $it = new \RegexIterator($it, '(\.' . preg_quote($fileExtension) . '$)'); + foreach ($it as $file) { + $fileName = $file->getPathname(); + yield $fileName => file_get_contents($fileName); + } +} diff --git a/app/vendor/nikic/php-parser/test/code/formatPreservation/anonClasses.test b/app/vendor/nikic/php-parser/test/code/formatPreservation/anonClasses.test new file mode 100644 index 000000000..7551059f7 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/code/formatPreservation/anonClasses.test @@ -0,0 +1,16 @@ +Anonymous classes +----- +expr; +$new->class->extends = null; +$new->args[] = new Expr\Variable('y'); +----- +exprs[0]->left->right->value = 42; +----- +name = new Node\Identifier('bar'); +----- +byRef = true; +----- +byRef = true; +----- +stmts[0]; +$stmts[0]->stmts[0] = $stmts[1]; +$stmts[1] = $tmp; +----- +stmts[0]; +$stmts[1]->stmts[0] = $stmts[2]; +$stmts[2] = $tmp; +// Same test, but also removing first statement, triggering fallback +array_splice($stmts, 0, 1, []); +----- +exprs[0] = new Expr\ConstFetch(new Node\Name('C')); +----- +exprs[0]->parts[0] = new Expr\Variable('bar'); +$stmts[1]->exprs[0]->parts[0] = new Expr\Variable('bar'); +----- +stmts[] = new Stmt\Expression(new Expr\Variable('c')); +----- +stmts[] = new Stmt\Expression(new Expr\Variable('c')); +----- +setAttribute('comments', []); +----- +getComments(); +$comments[] = new Comment("// foo"); +$stmts[1]->setAttribute('comments', $comments); +----- +stmts[0]; +$method->setAttribute('comments', [new Comment\Doc("/**\n *\n */")]); +----- +expr->left = new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')); +// The parens here are "correct", because add is left assoc +$stmts[1]->expr->right = new Expr\BinaryOp\Plus(new Expr\Variable('b'), new Expr\Variable('c')); +// No parens necessary +$stmts[2]->expr->left = new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')); +// Parens for RHS not strictly necessary due to assign speciality +$stmts[3]->expr->cond = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[3]->expr->if = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[3]->expr->else = new Expr\Assign(new Expr\Variable('a'), new Expr\Variable('b')); +// Already has parens +$stmts[4]->expr->left = new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[5]->expr->left = new Expr\BinaryOp\Plus(new Expr\Variable('a'), new Expr\Variable('b')); +----- + bar; +$foo -> bar; +$foo -> bar; +$foo -> bar; +$foo -> bar; +self :: $foo; +self :: $foo; +----- +$stmts[0]->expr->name = new Expr\Variable('a'); +$stmts[1]->expr->name = new Expr\BinaryOp\Concat(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[2]->expr->var = new Expr\Variable('bar'); +$stmts[3]->expr->var = new Expr\BinaryOp\Concat(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[4]->expr->name = new Node\Identifier('foo'); +// In this case the braces are not strictly necessary. However, on PHP 5 they may be required +// depending on where the property fetch node itself occurs. +$stmts[5]->expr->name = new Expr\Variable('bar'); +$stmts[6]->expr->name = new Expr\BinaryOp\Concat(new Expr\Variable('a'), new Expr\Variable('b')); +$stmts[7]->expr->name = new Node\VarLikeIdentifier('bar'); +$stmts[8]->expr->name = new Expr\BinaryOp\Concat(new Expr\Variable('a'), new Expr\Variable('b')); +----- + bar; +($a . $b) -> bar; +$foo -> foo; +$foo -> {$bar}; +$foo -> {$a . $b}; +self :: $bar; +self :: ${$a . $b}; \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/formatPreservation/inlineHtml.test b/app/vendor/nikic/php-parser/test/code/formatPreservation/inlineHtml.test new file mode 100644 index 000000000..7494e5359 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/code/formatPreservation/inlineHtml.test @@ -0,0 +1,54 @@ +Handling of inline HTML +----- +FoosetAttribute('origNode', null); +----- +FooBarstmts[2] = $stmts[0]->stmts[1]; +----- +BarBarstmts[1] = $stmts[0]->stmts[2]; +----- +returnType = new Node\Name('Foo'); +$stmts[0]->params[0]->type = new Node\Identifier('int'); +$stmts[0]->params[1]->type = new Node\Identifier('array'); +$stmts[0]->params[1]->default = new Expr\ConstFetch(new Node\Name('null')); +$stmts[1]->expr->dim = new Expr\Variable('a'); +$stmts[2]->expr->items[0]->key = new Scalar\String_('X'); +$stmts[3]->expr->returnType = new Node\Name('Bar'); +$stmts[4]->expr->if = new Expr\Variable('z'); +$stmts[5]->expr->key = new Expr\Variable('k'); +$stmts[6]->expr->value = new Expr\Variable('v'); +$stmts[7]->num = new Scalar\LNumber(2); +$stmts[8]->num = new Scalar\LNumber(2); +$stmts[9]->expr = new Expr\Variable('x'); +$stmts[10]->extends = new Node\Name\FullyQualified('Bar'); +$stmts[10]->stmts[0]->returnType = new Node\Name('Y'); +$stmts[10]->stmts[1]->props[0]->default = new Scalar\DNumber(42.0); +$stmts[11]->keyVar = new Expr\Variable('z'); +$stmts[12]->vars[0]->default = new Scalar\String_('abc'); +$stmts[13]->finally = new Stmt\Finally_([]); +$stmts[14]->else = new Stmt\Else_([]); +----- + $value +]; + +function +() : Bar +{}; + +$x +? $z +: +$y; + +yield +$k => $v ; +yield $v ; + +break 2 +; +continue 2 +; +return $x +; + +class +X extends \Bar +{ + public + function y() : Y + {} + + private + $x = 42.0 + ; +} + +foreach ( + $x + as + $z => $y +) {} + +static +$var = 'abc' +; + +try { +} catch (X +$y) { +} finally { +} + +if ($cond) { // Foo +} elseif ($cond2) { // Bar +} else { +} +----- +name = new Node\Name('Foo'); +----- +stmts[] = new Stmt\Expression(new Expr\Variable('baz')); +----- +params[] = new Node\Param(new Expr\Variable('param2')); +----- +catches[0]->types[] = new Node\Name('Bar'); +----- +params, new Node\Param(new Expr\Variable('param0'))); +----- +params[] = new Node\Param(new Expr\Variable('param0')); +/* Insertion into empty list not handled yet */ +----- +elseifs[] = new Stmt\ElseIf_(new Expr\Variable('cond3'), []); +----- +catches[] = new Stmt\Catch_([new Node\Name('Bar')], new Expr\Variable('bar'), []); +----- +setAttribute('comments', [new Comment('// Test')]); +$stmts[] = $node; +----- +setAttribute('comments', [new Comment('// Test'), new Comment('// Test 2')]); +$stmts[0]->stmts[] = $node; +----- +name->parts[0] = 'Xyz'; +----- +stmts, $node); +----- +setAttribute('comments', [new Comment('// Test')]); +array_unshift($stmts[0]->stmts, $node); +----- +setAttribute('comments', [new Comment('// Test')]); +array_unshift($stmts[0]->stmts, $node); +----- +setAttribute('comments', [new Comment('// Test')]); +array_unshift($stmts[0]->stmts, $node); +$stmts[0]->stmts[1]->setAttribute('comments', [new Comment('// Bar foo')]); +----- +setAttribute('comments', [new Comment('// Test')]); +array_unshift($stmts[0]->stmts, $node); +$stmts[0]->stmts[1]->setAttribute('comments', []); +----- +stmts, + new Stmt\Expression(new Expr\Variable('a')), + new Stmt\Expression(new Expr\Variable('b'))); +----- +stmts = [ + new Stmt\Expression(new Expr\Variable('a')), + new Stmt\Expression(new Expr\Variable('b')), +]; +----- +expr->expr->items, new Expr\ArrayItem(new Scalar\LNumber(42))); +$stmts[0]->expr->expr->items[] = new Expr\ArrayItem(new Scalar\LNumber(24)); +----- +expr->expr->items[] = new Expr\ArrayItem(new Scalar\LNumber(24)); +----- +foo = new Foo; +$this->foo->a() + ->b(); +----- +$outerCall = $stmts[1]->expr; +$innerCall = $outerCall->var; +$var = $innerCall->var; +$stmts[1]->expr = $innerCall; +$stmts[2] = new Stmt\Expression(new Expr\MethodCall($var, $outerCall->name)); +----- +foo = new Foo; +$this->foo->a(); +$this->foo->b(); \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/formatPreservation/listRemoval.test b/app/vendor/nikic/php-parser/test/code/formatPreservation/listRemoval.test new file mode 100644 index 000000000..0ac423901 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/code/formatPreservation/listRemoval.test @@ -0,0 +1,41 @@ +Removing from list nodes +----- +params); +----- +params); +$stmts[0]->params[] = new Node\Param(new Expr\Variable('x')); +$stmts[0]->params[] = new Node\Param(new Expr\Variable('y')); +----- +flags = Stmt\Class_::MODIFIER_ABSTRACT; +$stmts[1]->flags = 0; +$stmts[1]->stmts[0]->flags = Stmt\Class_::MODIFIER_PRIVATE; +$stmts[1]->stmts[1]->flags = Stmt\Class_::MODIFIER_PROTECTED; +$stmts[1]->stmts[2]->flags |= Stmt\Class_::MODIFIER_FINAL; +----- + [new Comment('//Some comment here')]]); +----- + $b +, $c => $d]; + +yield +$foo +=> +$bar; +yield +$bar; + +break +2 +; +continue +2 +; + +foreach( + $array +as + $key + => + $value +) {} + +if +($x) +{ +} + +else {} + +return +$val +; +static + $x + = + $y +; + +try {} catch + (X $y) + {} +finally +{} +----- +$stmts[0]->returnType = null; +$stmts[0]->params[0]->default = null; +$stmts[0]->params[1]->type = null; +$stmts[1]->expr->returnType = null; +$stmts[2]->extends = null; +$stmts[2]->stmts[0]->returnType = null; +$stmts[2]->stmts[1]->props[0]->default = null; +$stmts[2]->stmts[2]->adaptations[0]->newName = null; +$stmts[3]->expr->dim = null; +$stmts[4]->expr->expr = null; +$stmts[5]->expr->if = null; +$stmts[6]->expr->items[1]->key = null; +$stmts[7]->expr->key = null; +$stmts[8]->expr->value = null; +$stmts[9]->num = null; +$stmts[10]->num = null; +$stmts[11]->keyVar = null; +$stmts[12]->else = null; +$stmts[13]->expr = null; +$stmts[14]->vars[0]->default = null; +$stmts[15]->finally = null; +----- + $b +, $d]; + +yield +$bar; +yield; + +break; +continue; + +foreach( + $array +as + $value +) {} + +if +($x) +{ +} + +return; +static + $x +; + +try {} catch + (X $y) + {} +----- +name = null; +----- + !!positions Syntax error, unexpected ';', expecting T_STRING or T_VARIABLE or '{' or '$' from 3:1 to 3:1 array( - 0: Expr_PropertyFetch[2:1 - 2:6]( - var: Expr_Variable[2:1 - 2:4]( - name: foo - ) - name: Expr_Error[3:1 - 2:6]( + 0: Stmt_Expression[2:1 - 3:1]( + expr: Expr_PropertyFetch[2:1 - 2:6]( + var: Expr_Variable[2:1 - 2:4]( + name: foo + ) + name: Expr_Error[3:1 - 2:6]( + ) ) ) ) @@ -267,16 +307,20 @@ Syntax error, unexpected '}', expecting T_STRING or T_VARIABLE or '{' or '$' fro array( 0: Stmt_Function[2:1 - 4:1]( byRef: false - name: foo + name: Identifier[2:10 - 2:12]( + name: foo + ) params: array( ) returnType: null stmts: array( - 0: Expr_PropertyFetch[3:5 - 3:10]( - var: Expr_Variable[3:5 - 3:8]( - name: bar - ) - name: Expr_Error[4:1 - 3:10]( + 0: Stmt_Expression[3:5 - 3:10]( + expr: Expr_PropertyFetch[3:5 - 3:10]( + var: Expr_Variable[3:5 - 3:8]( + name: bar + ) + name: Expr_Error[4:1 - 3:10]( + ) ) ) ) @@ -288,13 +332,15 @@ new T ----- Syntax error, unexpected EOF from 2:6 to 2:6 array( - 0: Expr_New( - class: Name( - parts: array( - 0: T + 0: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: T + ) + ) + args: array( ) - ) - args: array( ) ) ) @@ -305,10 +351,12 @@ new !!php7,positions Syntax error, unexpected EOF from 2:4 to 2:4 array( - 0: Expr_New[2:1 - 2:3]( - class: Expr_Error[2:4 - 2:3]( - ) - args: array( + 0: Stmt_Expression[2:1 - 2:3]( + expr: Expr_New[2:1 - 2:3]( + class: Expr_Error[2:4 - 2:3]( + ) + args: array( + ) ) ) ) @@ -319,11 +367,13 @@ $foo instanceof !!php7 Syntax error, unexpected EOF from 2:16 to 2:16 array( - 0: Expr_Instanceof( - expr: Expr_Variable( - name: foo - ) - class: Expr_Error( + 0: Stmt_Expression( + expr: Expr_Instanceof( + expr: Expr_Variable( + name: foo + ) + class: Expr_Error( + ) ) ) ) @@ -334,8 +384,10 @@ $ !!php7 Syntax error, unexpected EOF, expecting T_VARIABLE or '{' or '$' from 2:2 to 2:2 array( - 0: Expr_Variable( - name: Expr_Error( + 0: Stmt_Expression( + expr: Expr_Variable( + name: Expr_Error( + ) ) ) ) @@ -346,13 +398,15 @@ Foo::$ !!php7 Syntax error, unexpected EOF, expecting T_VARIABLE or '{' or '$' from 2:7 to 2:7 array( - 0: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: Foo + 0: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: Foo + ) + ) + name: Expr_Error( ) - ) - name: Expr_Error( ) ) ) @@ -363,13 +417,15 @@ Foo:: !!php7 Syntax error, unexpected EOF from 2:6 to 2:6 array( - 0: Expr_ClassConstFetch( - class: Name( - parts: array( - 0: Foo + 0: Stmt_Expression( + expr: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: Foo + ) + ) + name: Expr_Error( ) - ) - name: Expr_Error( ) ) ) @@ -415,7 +471,7 @@ array( 0: A ) ) - alias: A + alias: null ) ) ) @@ -429,7 +485,7 @@ array( 0: a ) ) - alias: a + alias: null ) ) ) @@ -448,14 +504,16 @@ array( 0: B ) ) - alias: B + alias: null ) ) ) 3: Stmt_Const( consts: array( 0: Const( - name: A + name: Identifier( + name: A + ) value: Scalar_LNumber( value: 1 ) @@ -506,7 +564,9 @@ array( ) ) 13: Stmt_Goto( - name: label + name: Identifier( + name: label + ) ) ) ) @@ -553,11 +613,8 @@ A trailing comma is not allowed here from 11:25 to 11:25 A trailing comma is not allowed here from 13:17 to 13:17 A trailing comma is not allowed here from 14:14 to 14:14 A trailing comma is not allowed here from 16:22 to 16:22 -A trailing comma is not allowed here from 18:9 to 18:9 -A trailing comma is not allowed here from 19:9 to 19:9 A trailing comma is not allowed here from 21:13 to 21:13 A trailing comma is not allowed here from 23:16 to 23:16 -A trailing comma is not allowed here from 24:7 to 24:7 A trailing comma is not allowed here from 25:10 to 25:10 A trailing comma is not allowed here from 26:10 to 26:10 A trailing comma is not allowed here from 27:8 to 27:8 @@ -582,7 +639,7 @@ array( 0: B ) ) - alias: B + alias: null ) ) ) @@ -601,7 +658,7 @@ array( 0: b ) ) - alias: b + alias: null ) ) ) @@ -615,14 +672,16 @@ array( 0: A ) ) - alias: A + alias: null ) ) ) 3: Stmt_Const( consts: array( 0: Const( - name: A + name: Identifier( + name: A + ) value: Scalar_LNumber( value: 42 ) @@ -631,7 +690,9 @@ array( ) 4: Stmt_Class( flags: 0 - name: X + name: Identifier( + name: X + ) extends: null implements: array( 0: Name( @@ -667,7 +728,9 @@ array( 0: A ) ) - method: b + method: Identifier( + name: b + ) insteadof: array( 0: Name( parts: array( @@ -682,7 +745,9 @@ array( flags: 0 consts: array( 0: Const( - name: A + name: Identifier( + name: A + ) value: Scalar_LNumber( value: 42 ) @@ -693,7 +758,9 @@ array( flags: MODIFIER_PUBLIC (1) props: array( 0: Stmt_PropertyProperty( - name: x + name: VarLikeIdentifier( + name: x + ) default: null ) ) @@ -701,7 +768,9 @@ array( ) ) 5: Stmt_Interface( - name: I + name: Identifier( + name: I + ) extends: array( 0: Name( parts: array( @@ -719,17 +788,21 @@ array( ) ) ) - 7: Expr_Isset( - vars: array( - 0: Expr_Variable( - name: x + 7: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_Variable( + name: x + ) ) ) ) 8: Stmt_Declare( declares: array( 0: Stmt_DeclareDeclare( - key: a + key: Identifier( + name: a + ) value: Scalar_LNumber( value: 42 ) @@ -739,13 +812,17 @@ array( ) 9: Stmt_Function( byRef: false - name: foo + name: Identifier( + name: foo + ) params: array( 0: Param( type: null byRef: false variadic: false - name: a + var: Expr_Variable( + name: a + ) default: null ) ) @@ -753,19 +830,21 @@ array( stmts: array( ) ) - 10: Expr_FuncCall( - name: Name( - parts: array( - 0: foo + 10: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: foo + ) ) - ) - args: array( - 0: Arg( - value: Expr_Variable( - name: a + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) @@ -779,7 +858,9 @@ array( 12: Stmt_Static( vars: array( 0: Stmt_StaticVar( - name: a + var: Expr_Variable( + name: a + ) default: null ) ) @@ -810,56 +891,485 @@ array( stmts: array( ) ) - 15: Expr_Closure( - static: false + 15: Stmt_Expression( + expr: Expr_Closure( + static: false + byRef: false + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: a + ) + default: null + ) + ) + uses: array( + 0: Expr_ClosureUse( + var: Expr_Variable( + name: b + ) + byRef: false + ) + ) + returnType: null + stmts: array( + ) + ) + ) +) +----- +value $oopsAnotherValue->get() +]; +$array = [ + $value $oopsAnotherValue +]; +$array = [ + 'key' => $value $oopsAnotherValue +]; ----- -!!php7,positions -Syntax error, unexpected ')' from 3:10 to 3:10 +!!php7 +Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 3:18 to 3:34 +Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 6:12 to 6:28 +Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 9:21 to 9:37 array( - 0: Expr_FuncCall[3:1 - 3:10]( - name: Name[3:1 - 3:3]( - parts: array( - 0: foo + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: array + ) + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_PropertyFetch( + var: Expr_Variable( + name: this + ) + name: Identifier( + name: value + ) + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_MethodCall( + var: Expr_Variable( + name: oopsAnotherValue + ) + name: Identifier( + name: get + ) + args: array( + ) + ) + byRef: false + ) + ) ) ) - args: array( - 0: Arg[3:5 - 3:9]( - value: Expr_ClassConstFetch[3:5 - 3:9]( - class: Name[3:5 - 3:7]( - parts: array( - 0: Bar + ) + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: array + ) + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: value ) + byRef: false ) - name: Expr_Error[3:10 - 3:9]( + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: oopsAnotherValue + ) + byRef: false + ) + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: array + ) + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: key + ) + value: Expr_Variable( + name: value + ) + byRef: false + ) + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: oopsAnotherValue + ) + byRef: false ) ) - byRef: false - unpack: false ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/arrayDef.test b/app/vendor/nikic/php-parser/test/code/parser/expr/arrayDef.test index 28baf2664..510a93f8a 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/arrayDef.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/arrayDef.test @@ -14,128 +14,147 @@ array('a', &$b, 'c' => 'd', 'e' => &$f); ['a' => 'b']; ----- array( - 0: Expr_Array( - items: array( + 0: Stmt_Expression( + expr: Expr_Array( + items: array( + ) ) ) - 1: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_String( - value: a + 1: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: a + ) + byRef: false ) - byRef: false ) ) ) - 2: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_String( - value: a + 2: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: a + ) + byRef: false ) - byRef: false ) ) ) - 3: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_String( - value: a + 3: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: a + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_String( - value: b + 1: Expr_ArrayItem( + key: null + value: Scalar_String( + value: b + ) + byRef: false ) - byRef: false ) ) ) - 4: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_String( - value: a - ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: b - ) - byRef: true - ) - 2: Expr_ArrayItem( - key: Scalar_String( - value: c + 4: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: a + ) + byRef: false ) - value: Scalar_String( - value: d + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: true ) - byRef: false - ) - 3: Expr_ArrayItem( - key: Scalar_String( - value: e + 2: Expr_ArrayItem( + key: Scalar_String( + value: c + ) + value: Scalar_String( + value: d + ) + byRef: false ) - value: Expr_Variable( - name: f + 3: Expr_ArrayItem( + key: Scalar_String( + value: e + ) + value: Expr_Variable( + name: f + ) + byRef: true ) - byRef: true ) ) ) - 5: Expr_Array( - items: array( + 5: Stmt_Expression( + expr: Expr_Array( + items: array( + ) + comments: array( + 0: // short array syntax + ) ) comments: array( 0: // short array syntax ) ) - 6: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 1 + 6: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 2 + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 2 + ) + byRef: false ) - byRef: false - ) - 2: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 3 + 2: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 3 + ) + byRef: false ) - byRef: false ) ) ) - 7: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: Scalar_String( - value: a - ) - value: Scalar_String( - value: b + 7: Stmt_Expression( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Scalar_String( + value: b + ) + byRef: false ) - byRef: false ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/arrayDestructuring.test b/app/vendor/nikic/php-parser/test/code/parser/expr/arrayDestructuring.test index 4ca76b216..7865e6ffb 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/arrayDestructuring.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/arrayDestructuring.test @@ -9,136 +9,144 @@ Array destructuring ----- !!php7 array( - 0: Expr_Assign( - var: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: b + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false ) - byRef: false ) ) - ) - expr: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: c + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: c + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: d + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: d + ) + byRef: false ) - byRef: false ) ) ) ) - 1: Expr_Assign( - var: Expr_Array( - items: array( - 0: null - 1: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: a + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: null + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false ) - byRef: false - ) - 2: null - 3: null - 4: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: b + 2: null + 3: null + 4: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false ) - byRef: false + 5: null ) - 5: null ) - ) - expr: Expr_Variable( - name: foo + expr: Expr_Variable( + name: foo + ) ) ) - 2: Expr_Assign( - var: Expr_Array( - items: array( - 0: null - 1: Expr_ArrayItem( - key: null - value: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: a + 2: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: null + 1: Expr_ArrayItem( + key: null + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false ) - byRef: false ) ) + byRef: false ) - byRef: false ) ) + byRef: false ) - byRef: false - ) - 2: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: b + 2: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false ) - byRef: false ) ) - ) - expr: Expr_Variable( - name: bar + expr: Expr_Variable( + name: bar + ) ) ) - 3: Expr_Assign( - var: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: Scalar_String( - value: a - ) - value: Expr_Variable( - name: b - ) - byRef: false - ) - 1: Expr_ArrayItem( - key: Scalar_String( - value: b + 3: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Expr_Variable( + name: b + ) + byRef: false ) - value: Expr_Variable( - name: a + 1: Expr_ArrayItem( + key: Scalar_String( + value: b + ) + value: Expr_Variable( + name: a + ) + byRef: false ) - byRef: false ) ) - ) - expr: Expr_Variable( - name: baz + expr: Expr_Variable( + name: baz + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/assign.test b/app/vendor/nikic/php-parser/test/code/parser/expr/assign.test index 1d6b187ad..33335f89d 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/assign.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/assign.test @@ -36,266 +36,328 @@ $a++; $a--; ----- array( - 0: Expr_Assign( - var: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: a + comments: array( + 0: // simple assign + ) + ) + expr: Expr_Variable( + name: b + ) comments: array( 0: // simple assign ) ) - expr: Expr_Variable( - name: b - ) comments: array( 0: // simple assign ) ) - 1: Expr_AssignOp_BitwiseAnd( - var: Expr_Variable( - name: a + 1: Stmt_Expression( + expr: Expr_AssignOp_BitwiseAnd( + var: Expr_Variable( + name: a + comments: array( + 0: // combined assign + ) + ) + expr: Expr_Variable( + name: b + ) comments: array( 0: // combined assign ) ) - expr: Expr_Variable( - name: b - ) comments: array( 0: // combined assign ) ) - 2: Expr_AssignOp_BitwiseOr( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b - ) - ) - 3: Expr_AssignOp_BitwiseXor( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 2: Stmt_Expression( + expr: Expr_AssignOp_BitwiseOr( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 4: Expr_AssignOp_Concat( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 3: Stmt_Expression( + expr: Expr_AssignOp_BitwiseXor( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 5: Expr_AssignOp_Div( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 4: Stmt_Expression( + expr: Expr_AssignOp_Concat( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 6: Expr_AssignOp_Minus( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 5: Stmt_Expression( + expr: Expr_AssignOp_Div( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 7: Expr_AssignOp_Mod( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 6: Stmt_Expression( + expr: Expr_AssignOp_Minus( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 8: Expr_AssignOp_Mul( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 7: Stmt_Expression( + expr: Expr_AssignOp_Mod( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 9: Expr_AssignOp_Plus( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 8: Stmt_Expression( + expr: Expr_AssignOp_Mul( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 10: Expr_AssignOp_ShiftLeft( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 9: Stmt_Expression( + expr: Expr_AssignOp_Plus( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 11: Expr_AssignOp_ShiftRight( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 10: Stmt_Expression( + expr: Expr_AssignOp_ShiftLeft( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 12: Expr_AssignOp_Pow( - var: Expr_Variable( - name: a - ) - expr: Expr_Variable( - name: b + 11: Stmt_Expression( + expr: Expr_AssignOp_ShiftRight( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) ) ) - 13: Expr_Assign( - var: Expr_Variable( - name: a - comments: array( - 0: // chained assign + 12: Stmt_Expression( + expr: Expr_AssignOp_Pow( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b ) ) - expr: Expr_AssignOp_Mul( + ) + 13: Stmt_Expression( + expr: Expr_Assign( var: Expr_Variable( - name: b + name: a + comments: array( + 0: // chained assign + ) ) - expr: Expr_AssignOp_Pow( + expr: Expr_AssignOp_Mul( var: Expr_Variable( - name: c + name: b ) - expr: Expr_Variable( - name: d + expr: Expr_AssignOp_Pow( + var: Expr_Variable( + name: c + ) + expr: Expr_Variable( + name: d + ) ) ) + comments: array( + 0: // chained assign + ) ) comments: array( 0: // chained assign ) ) - 14: Expr_AssignRef( - var: Expr_Variable( - name: a + 14: Stmt_Expression( + expr: Expr_AssignRef( + var: Expr_Variable( + name: a + comments: array( + 0: // by ref assign + ) + ) + expr: Expr_Variable( + name: b + ) comments: array( 0: // by ref assign ) ) - expr: Expr_Variable( - name: b - ) comments: array( 0: // by ref assign ) ) - 15: Expr_Assign( - var: Expr_List( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: a + 15: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false ) - byRef: false + ) + comments: array( + 0: // list() assign ) ) + expr: Expr_Variable( + name: b + ) comments: array( 0: // list() assign ) ) - expr: Expr_Variable( - name: b - ) comments: array( 0: // list() assign ) ) - 16: Expr_Assign( - var: Expr_List( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: a + 16: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false ) - byRef: false - ) - 1: null - 2: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: b + 1: null + 2: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: b + ) + byRef: false ) - byRef: false ) ) - ) - expr: Expr_Variable( - name: c + expr: Expr_Variable( + name: c + ) ) ) - 17: Expr_Assign( - var: Expr_List( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: a + 17: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: a + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Expr_List( - items: array( - 0: null - 1: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: c + 1: Expr_ArrayItem( + key: null + value: Expr_List( + items: array( + 0: null + 1: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: c + ) + byRef: false ) - byRef: false ) ) + byRef: false ) - byRef: false - ) - 2: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: d + 2: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: d + ) + byRef: false ) - byRef: false ) ) - ) - expr: Expr_Variable( - name: e + expr: Expr_Variable( + name: e + ) ) ) - 18: Expr_PreInc( - var: Expr_Variable( - name: a + 18: Stmt_Expression( + expr: Expr_PreInc( + var: Expr_Variable( + name: a + ) + comments: array( + 0: // inc/dec + ) ) comments: array( 0: // inc/dec ) ) - 19: Expr_PostInc( - var: Expr_Variable( - name: a + 19: Stmt_Expression( + expr: Expr_PostInc( + var: Expr_Variable( + name: a + ) ) ) - 20: Expr_PreDec( - var: Expr_Variable( - name: a + 20: Stmt_Expression( + expr: Expr_PreDec( + var: Expr_Variable( + name: a + ) ) ) - 21: Expr_PostDec( - var: Expr_Variable( - name: a + 21: Stmt_Expression( + expr: Expr_PostDec( + var: Expr_Variable( + name: a + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/assignNewByRef.test b/app/vendor/nikic/php-parser/test/code/parser/expr/assignNewByRef.test index 10e1317f0..a66d943a4 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/assignNewByRef.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/assignNewByRef.test @@ -5,17 +5,19 @@ $a =& new B; ----- !!php5 array( - 0: Expr_AssignRef( - var: Expr_Variable( - name: a - ) - expr: Expr_New( - class: Name( - parts: array( - 0: B - ) + 0: Stmt_Expression( + expr: Expr_AssignRef( + var: Expr_Variable( + name: a ) - args: array( + expr: Expr_New( + class: Name( + parts: array( + 0: B + ) + ) + args: array( + ) ) ) ) @@ -27,13 +29,15 @@ $a =& new B; !!php7 Syntax error, unexpected T_NEW from 2:7 to 2:9 array( - 0: Expr_New( - class: Name( - parts: array( - 0: B + 0: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: B + ) + ) + args: array( ) - ) - args: array( ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/cast.test b/app/vendor/nikic/php-parser/test/code/parser/expr/cast.test index 3c54ba72d..a875bb47f 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/cast.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/cast.test @@ -14,59 +14,81 @@ Casts (unset) $a; ----- array( - 0: Expr_Cast_Array( - expr: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Cast_Array( + expr: Expr_Variable( + name: a + ) ) ) - 1: Expr_Cast_Bool( - expr: Expr_Variable( - name: a + 1: Stmt_Expression( + expr: Expr_Cast_Bool( + expr: Expr_Variable( + name: a + ) ) ) - 2: Expr_Cast_Bool( - expr: Expr_Variable( - name: a + 2: Stmt_Expression( + expr: Expr_Cast_Bool( + expr: Expr_Variable( + name: a + ) ) ) - 3: Expr_Cast_Double( - expr: Expr_Variable( - name: a + 3: Stmt_Expression( + expr: Expr_Cast_Double( + expr: Expr_Variable( + name: a + ) ) ) - 4: Expr_Cast_Double( - expr: Expr_Variable( - name: a + 4: Stmt_Expression( + expr: Expr_Cast_Double( + expr: Expr_Variable( + name: a + ) ) ) - 5: Expr_Cast_Double( - expr: Expr_Variable( - name: a + 5: Stmt_Expression( + expr: Expr_Cast_Double( + expr: Expr_Variable( + name: a + ) ) ) - 6: Expr_Cast_Int( - expr: Expr_Variable( - name: a + 6: Stmt_Expression( + expr: Expr_Cast_Int( + expr: Expr_Variable( + name: a + ) ) ) - 7: Expr_Cast_Int( - expr: Expr_Variable( - name: a + 7: Stmt_Expression( + expr: Expr_Cast_Int( + expr: Expr_Variable( + name: a + ) ) ) - 8: Expr_Cast_Object( - expr: Expr_Variable( - name: a + 8: Stmt_Expression( + expr: Expr_Cast_Object( + expr: Expr_Variable( + name: a + ) ) ) - 9: Expr_Cast_String( - expr: Expr_Variable( - name: a + 9: Stmt_Expression( + expr: Expr_Cast_String( + expr: Expr_Variable( + name: a + ) ) ) - 10: Expr_Cast_Unset( - expr: Expr_Variable( - name: a + 10: Stmt_Expression( + expr: Expr_Cast_Unset( + expr: Expr_Variable( + name: a + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/clone.test b/app/vendor/nikic/php-parser/test/code/parser/expr/clone.test index 640156606..418eb0e65 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/clone.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/clone.test @@ -5,9 +5,11 @@ Clone clone $a; ----- array( - 0: Expr_Clone( - expr: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Clone( + expr: Expr_Variable( + name: a + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/closure.test b/app/vendor/nikic/php-parser/test/code/parser/expr/closure.test index f459b602d..c88de78b4 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/closure.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/closure.test @@ -10,133 +10,167 @@ function($a) : array {}; function() use($a) : \Foo\Bar {}; ----- array( - 0: Expr_Closure( - static: false - byRef: false - params: array( - 0: Param( - type: null - byRef: false - variadic: false - name: a - default: null + 0: Stmt_Expression( + expr: Expr_Closure( + static: false + byRef: false + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: a + ) + default: null + ) ) - ) - uses: array( - ) - returnType: null - stmts: array( - 0: Expr_Variable( - name: a + uses: array( + ) + returnType: null + stmts: array( + 0: Stmt_Expression( + expr: Expr_Variable( + name: a + ) + ) ) ) ) - 1: Expr_Closure( - static: false - byRef: false - params: array( - 0: Param( - type: null - byRef: false - variadic: false - name: a - default: null + 1: Stmt_Expression( + expr: Expr_Closure( + static: false + byRef: false + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: a + ) + default: null + ) ) - ) - uses: array( - 0: Expr_ClosureUse( - var: b - byRef: false + uses: array( + 0: Expr_ClosureUse( + var: Expr_Variable( + name: b + ) + byRef: false + ) + ) + returnType: null + stmts: array( ) - ) - returnType: null - stmts: array( ) ) - 2: Expr_Closure( - static: false - byRef: false - params: array( - ) - uses: array( - 0: Expr_ClosureUse( - var: a - byRef: false + 2: Stmt_Expression( + expr: Expr_Closure( + static: false + byRef: false + params: array( ) - 1: Expr_ClosureUse( - var: b - byRef: true + uses: array( + 0: Expr_ClosureUse( + var: Expr_Variable( + name: a + ) + byRef: false + ) + 1: Expr_ClosureUse( + var: Expr_Variable( + name: b + ) + byRef: true + ) + ) + returnType: null + stmts: array( ) - ) - returnType: null - stmts: array( ) ) - 3: Expr_Closure( - static: false - byRef: true - params: array( - 0: Param( - type: null - byRef: false - variadic: false - name: a - default: null + 3: Stmt_Expression( + expr: Expr_Closure( + static: false + byRef: true + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: a + ) + default: null + ) + ) + uses: array( + ) + returnType: null + stmts: array( ) - ) - uses: array( - ) - returnType: null - stmts: array( ) ) - 4: Expr_Closure( - static: true - byRef: false - params: array( - ) - uses: array( - ) - returnType: null - stmts: array( + 4: Stmt_Expression( + expr: Expr_Closure( + static: true + byRef: false + params: array( + ) + uses: array( + ) + returnType: null + stmts: array( + ) ) ) - 5: Expr_Closure( - static: false - byRef: false - params: array( - 0: Param( - type: null - byRef: false - variadic: false - name: a - default: null + 5: Stmt_Expression( + expr: Expr_Closure( + static: false + byRef: false + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: a + ) + default: null + ) + ) + uses: array( + ) + returnType: Identifier( + name: array + ) + stmts: array( ) - ) - uses: array( - ) - returnType: array - stmts: array( ) ) - 6: Expr_Closure( - static: false - byRef: false - params: array( - ) - uses: array( - 0: Expr_ClosureUse( - var: a - byRef: false + 6: Stmt_Expression( + expr: Expr_Closure( + static: false + byRef: false + params: array( ) - ) - returnType: Name_FullyQualified( - parts: array( - 0: Foo - 1: Bar + uses: array( + 0: Expr_ClosureUse( + var: Expr_Variable( + name: a + ) + byRef: false + ) + ) + returnType: Name_FullyQualified( + parts: array( + 0: Foo + 1: Bar + ) + ) + stmts: array( ) - ) - stmts: array( ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/comparison.test b/app/vendor/nikic/php-parser/test/code/parser/expr/comparison.test index d5b1e3540..011692f06 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/comparison.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/comparison.test @@ -14,94 +14,116 @@ $a instanceof B; $a instanceof $b; ----- array( - 0: Expr_BinaryOp_Smaller( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 0: Stmt_Expression( + expr: Expr_BinaryOp_Smaller( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 1: Expr_BinaryOp_SmallerOrEqual( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 1: Stmt_Expression( + expr: Expr_BinaryOp_SmallerOrEqual( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 2: Expr_BinaryOp_Greater( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 2: Stmt_Expression( + expr: Expr_BinaryOp_Greater( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 3: Expr_BinaryOp_GreaterOrEqual( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 3: Stmt_Expression( + expr: Expr_BinaryOp_GreaterOrEqual( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 4: Expr_BinaryOp_Equal( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 4: Stmt_Expression( + expr: Expr_BinaryOp_Equal( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 5: Expr_BinaryOp_Identical( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 5: Stmt_Expression( + expr: Expr_BinaryOp_Identical( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 6: Expr_BinaryOp_NotEqual( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 6: Stmt_Expression( + expr: Expr_BinaryOp_NotEqual( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 7: Expr_BinaryOp_NotIdentical( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 7: Stmt_Expression( + expr: Expr_BinaryOp_NotIdentical( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 8: Expr_BinaryOp_Spaceship( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 8: Stmt_Expression( + expr: Expr_BinaryOp_Spaceship( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 9: Expr_Instanceof( - expr: Expr_Variable( - name: a - ) - class: Name( - parts: array( - 0: B + 9: Stmt_Expression( + expr: Expr_Instanceof( + expr: Expr_Variable( + name: a + ) + class: Name( + parts: array( + 0: B + ) ) ) ) - 10: Expr_Instanceof( - expr: Expr_Variable( - name: a - ) - class: Expr_Variable( - name: b + 10: Stmt_Expression( + expr: Expr_Instanceof( + expr: Expr_Variable( + name: a + ) + class: Expr_Variable( + name: b + ) ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/constant_expr.test b/app/vendor/nikic/php-parser/test/code/parser/expr/constant_expr.test index 3e7a23ef0..d774de71e 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/constant_expr.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/constant_expr.test @@ -44,7 +44,9 @@ array( 0: Stmt_Const( consts: array( 0: Const( - name: T_1 + name: Identifier( + name: T_1 + ) value: Expr_BinaryOp_ShiftLeft( left: Scalar_LNumber( value: 1 @@ -59,7 +61,9 @@ array( 1: Stmt_Const( consts: array( 0: Const( - name: T_2 + name: Identifier( + name: T_2 + ) value: Expr_BinaryOp_Div( left: Scalar_LNumber( value: 1 @@ -74,7 +78,9 @@ array( 2: Stmt_Const( consts: array( 0: Const( - name: T_3 + name: Identifier( + name: T_3 + ) value: Expr_BinaryOp_Plus( left: Scalar_DNumber( value: 1.5 @@ -89,7 +95,9 @@ array( 3: Stmt_Const( consts: array( 0: Const( - name: T_4 + name: Identifier( + name: T_4 + ) value: Expr_BinaryOp_Concat( left: Scalar_String( value: foo @@ -104,7 +112,9 @@ array( 4: Stmt_Const( consts: array( 0: Const( - name: T_5 + name: Identifier( + name: T_5 + ) value: Expr_BinaryOp_Mul( left: Expr_BinaryOp_Plus( left: Scalar_DNumber( @@ -124,7 +134,9 @@ array( 5: Stmt_Const( consts: array( 0: Const( - name: T_6 + name: Identifier( + name: T_6 + ) value: Expr_BinaryOp_Concat( left: Expr_BinaryOp_Concat( left: Expr_BinaryOp_Concat( @@ -149,7 +161,9 @@ array( 6: Stmt_Const( consts: array( 0: Const( - name: T_7 + name: Identifier( + name: T_7 + ) value: Scalar_MagicConst_Line( ) ) @@ -158,7 +172,9 @@ array( 7: Stmt_Const( consts: array( 0: Const( - name: T_8 + name: Identifier( + name: T_8 + ) value: Scalar_String( value: This is a test string ) @@ -168,7 +184,9 @@ array( 8: Stmt_Const( consts: array( 0: Const( - name: T_9 + name: Identifier( + name: T_9 + ) value: Expr_BitwiseNot( expr: Expr_UnaryMinus( expr: Scalar_LNumber( @@ -182,7 +200,9 @@ array( 9: Stmt_Const( consts: array( 0: Const( - name: T_10 + name: Identifier( + name: T_10 + ) value: Expr_BinaryOp_Plus( left: Expr_Ternary( cond: Expr_UnaryMinus( @@ -213,7 +233,9 @@ array( 10: Stmt_Const( consts: array( 0: Const( - name: T_11 + name: Identifier( + name: T_11 + ) value: Expr_BinaryOp_BooleanAnd( left: Scalar_LNumber( value: 1 @@ -228,7 +250,9 @@ array( 11: Stmt_Const( consts: array( 0: Const( - name: T_12 + name: Identifier( + name: T_12 + ) value: Expr_BinaryOp_LogicalAnd( left: Scalar_LNumber( value: 1 @@ -243,7 +267,9 @@ array( 12: Stmt_Const( consts: array( 0: Const( - name: T_13 + name: Identifier( + name: T_13 + ) value: Expr_BinaryOp_BooleanOr( left: Scalar_LNumber( value: 0 @@ -258,7 +284,9 @@ array( 13: Stmt_Const( consts: array( 0: Const( - name: T_14 + name: Identifier( + name: T_14 + ) value: Expr_BinaryOp_LogicalOr( left: Scalar_LNumber( value: 1 @@ -273,7 +301,9 @@ array( 14: Stmt_Const( consts: array( 0: Const( - name: T_15 + name: Identifier( + name: T_15 + ) value: Expr_BinaryOp_LogicalXor( left: Scalar_LNumber( value: 1 @@ -288,7 +318,9 @@ array( 15: Stmt_Const( consts: array( 0: Const( - name: T_16 + name: Identifier( + name: T_16 + ) value: Expr_BinaryOp_LogicalXor( left: Scalar_LNumber( value: 1 @@ -303,7 +335,9 @@ array( 16: Stmt_Const( consts: array( 0: Const( - name: T_17 + name: Identifier( + name: T_17 + ) value: Expr_BinaryOp_Smaller( left: Scalar_LNumber( value: 1 @@ -318,7 +352,9 @@ array( 17: Stmt_Const( consts: array( 0: Const( - name: T_18 + name: Identifier( + name: T_18 + ) value: Expr_BinaryOp_SmallerOrEqual( left: Scalar_LNumber( value: 0 @@ -333,7 +369,9 @@ array( 18: Stmt_Const( consts: array( 0: Const( - name: T_19 + name: Identifier( + name: T_19 + ) value: Expr_BinaryOp_Greater( left: Scalar_LNumber( value: 1 @@ -348,7 +386,9 @@ array( 19: Stmt_Const( consts: array( 0: Const( - name: T_20 + name: Identifier( + name: T_20 + ) value: Expr_BinaryOp_GreaterOrEqual( left: Scalar_LNumber( value: 1 @@ -363,7 +403,9 @@ array( 20: Stmt_Const( consts: array( 0: Const( - name: T_21 + name: Identifier( + name: T_21 + ) value: Expr_BinaryOp_Identical( left: Scalar_LNumber( value: 1 @@ -378,7 +420,9 @@ array( 21: Stmt_Const( consts: array( 0: Const( - name: T_22 + name: Identifier( + name: T_22 + ) value: Expr_BinaryOp_NotIdentical( left: Scalar_LNumber( value: 1 @@ -393,7 +437,9 @@ array( 22: Stmt_Const( consts: array( 0: Const( - name: T_23 + name: Identifier( + name: T_23 + ) value: Expr_BinaryOp_NotEqual( left: Scalar_LNumber( value: 0 @@ -408,7 +454,9 @@ array( 23: Stmt_Const( consts: array( 0: Const( - name: T_24 + name: Identifier( + name: T_24 + ) value: Expr_BinaryOp_Equal( left: Scalar_LNumber( value: 1 @@ -423,7 +471,9 @@ array( 24: Stmt_Const( consts: array( 0: Const( - name: T_25 + name: Identifier( + name: T_25 + ) value: Expr_BinaryOp_Plus( left: Scalar_LNumber( value: 1 @@ -443,7 +493,9 @@ array( 25: Stmt_Const( consts: array( 0: Const( - name: T_26 + name: Identifier( + name: T_26 + ) value: Expr_BinaryOp_Plus( left: Expr_BinaryOp_Plus( left: Scalar_String( @@ -463,7 +515,9 @@ array( 26: Stmt_Const( consts: array( 0: Const( - name: T_27 + name: Identifier( + name: T_27 + ) value: Expr_BinaryOp_Pow( left: Scalar_LNumber( value: 2 @@ -478,7 +532,9 @@ array( 27: Stmt_Const( consts: array( 0: Const( - name: T_28 + name: Identifier( + name: T_28 + ) value: Expr_ArrayDimFetch( var: Expr_Array( items: array( @@ -515,7 +571,9 @@ array( 28: Stmt_Const( consts: array( 0: Const( - name: T_29 + name: Identifier( + name: T_29 + ) value: Expr_BinaryOp_Minus( left: Scalar_LNumber( value: 12 @@ -530,7 +588,9 @@ array( 29: Stmt_Const( consts: array( 0: Const( - name: T_30 + name: Identifier( + name: T_30 + ) value: Expr_BinaryOp_BitwiseXor( left: Scalar_LNumber( value: 12 @@ -545,7 +605,9 @@ array( 30: Stmt_Const( consts: array( 0: Const( - name: T_31 + name: Identifier( + name: T_31 + ) value: Expr_BinaryOp_BitwiseAnd( left: Scalar_LNumber( value: 12 @@ -560,7 +622,9 @@ array( 31: Stmt_Const( consts: array( 0: Const( - name: T_32 + name: Identifier( + name: T_32 + ) value: Expr_BinaryOp_BitwiseOr( left: Scalar_LNumber( value: 12 @@ -575,7 +639,9 @@ array( 32: Stmt_Const( consts: array( 0: Const( - name: T_33 + name: Identifier( + name: T_33 + ) value: Expr_BinaryOp_Mod( left: Scalar_LNumber( value: 12 @@ -590,7 +656,9 @@ array( 33: Stmt_Const( consts: array( 0: Const( - name: T_34 + name: Identifier( + name: T_34 + ) value: Expr_BinaryOp_ShiftRight( left: Scalar_LNumber( value: 100 @@ -605,7 +673,9 @@ array( 34: Stmt_Const( consts: array( 0: Const( - name: T_35 + name: Identifier( + name: T_35 + ) value: Expr_BooleanNot( expr: Expr_ConstFetch( name: Name( diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/errorSuppress.test b/app/vendor/nikic/php-parser/test/code/parser/expr/errorSuppress.test index ce3fce96a..7f099988a 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/errorSuppress.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/errorSuppress.test @@ -4,9 +4,11 @@ Error suppression @$a; ----- array( - 0: Expr_ErrorSuppress( - expr: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_ErrorSuppress( + expr: Expr_Variable( + name: a + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/exit.test b/app/vendor/nikic/php-parser/test/code/parser/expr/exit.test index 8f21e5ba9..c880921f3 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/exit.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/exit.test @@ -9,26 +9,38 @@ die(); die('Exit!'); ----- array( - 0: Expr_Exit( - expr: null + 0: Stmt_Expression( + expr: Expr_Exit( + expr: null + ) ) - 1: Expr_Exit( - expr: null + 1: Stmt_Expression( + expr: Expr_Exit( + expr: null + ) ) - 2: Expr_Exit( - expr: Scalar_String( - value: Die! + 2: Stmt_Expression( + expr: Expr_Exit( + expr: Scalar_String( + value: Die! + ) ) ) - 3: Expr_Exit( - expr: null + 3: Stmt_Expression( + expr: Expr_Exit( + expr: null + ) ) - 4: Expr_Exit( - expr: null + 4: Stmt_Expression( + expr: Expr_Exit( + expr: null + ) ) - 5: Expr_Exit( - expr: Scalar_String( - value: Exit! + 5: Stmt_Expression( + expr: Expr_Exit( + expr: Scalar_String( + value: Exit! + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/args.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/args.test index 6d7352099..24ca03105 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/args.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/args.test @@ -9,90 +9,100 @@ f(&$a); f($a, ...$b); ----- array( - 0: Expr_FuncCall( - name: Name( - parts: array( - 0: f + 0: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: f + ) + ) + args: array( ) - ) - args: array( ) ) - 1: Expr_FuncCall( - name: Name( - parts: array( - 0: f + 1: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: f + ) ) - ) - args: array( - 0: Arg( - value: Expr_Variable( - name: a + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) - 2: Expr_FuncCall( - name: Name( - parts: array( - 0: f - ) - ) - args: array( - 0: Arg( - value: Expr_Variable( - name: a + 2: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: f ) - byRef: false - unpack: false ) - 1: Arg( - value: Expr_Variable( - name: b + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) - 3: Expr_FuncCall( - name: Name( - parts: array( - 0: f + 3: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: f + ) ) - ) - args: array( - 0: Arg( - value: Expr_Variable( - name: a + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: true + unpack: false ) - byRef: true - unpack: false ) ) ) - 4: Expr_FuncCall( - name: Name( - parts: array( - 0: f - ) - ) - args: array( - 0: Arg( - value: Expr_Variable( - name: a + 4: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: f ) - byRef: false - unpack: false ) - 1: Arg( - value: Expr_Variable( - name: b + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: true ) - byRef: false - unpack: true ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/constFetch.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/constFetch.test index 7686d2d96..d00084baf 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/constFetch.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/constFetch.test @@ -7,27 +7,37 @@ A::B; A::class; ----- array( - 0: Expr_ConstFetch( - name: Name( - parts: array( - 0: A + 0: Stmt_Expression( + expr: Expr_ConstFetch( + name: Name( + parts: array( + 0: A + ) ) ) ) - 1: Expr_ClassConstFetch( - class: Name( - parts: array( - 0: A + 1: Stmt_Expression( + expr: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: Identifier( + name: B ) ) - name: B ) - 2: Expr_ClassConstFetch( - class: Name( - parts: array( - 0: A + 2: Stmt_Expression( + expr: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: Identifier( + name: class ) ) - name: class ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/constantDeref.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/constantDeref.test index 682f78082..4d14c09ad 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/constantDeref.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/constantDeref.test @@ -16,216 +16,238 @@ Foo::BAR[1]; $foo::BAR[2][1][0]; ----- array( - 0: Expr_ArrayDimFetch( - var: Scalar_String( - value: abc - ) - dim: Scalar_LNumber( - value: 2 + 0: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Scalar_String( + value: abc + ) + dim: Scalar_LNumber( + value: 2 + ) ) ) - 1: Expr_ArrayDimFetch( - var: Expr_ArrayDimFetch( + 1: Stmt_Expression( + expr: Expr_ArrayDimFetch( var: Expr_ArrayDimFetch( - var: Scalar_String( - value: abc + var: Expr_ArrayDimFetch( + var: Scalar_String( + value: abc + ) + dim: Scalar_LNumber( + value: 2 + ) ) dim: Scalar_LNumber( - value: 2 + value: 0 ) ) dim: Scalar_LNumber( value: 0 ) ) - dim: Scalar_LNumber( - value: 0 - ) ) - 2: Expr_ArrayDimFetch( - var: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 1 - ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 2 + 2: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false ) - byRef: false - ) - 2: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 3 + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 2 + ) + byRef: false + ) + 2: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 3 + ) + byRef: false ) - byRef: false ) ) - ) - dim: Scalar_LNumber( - value: 2 + dim: Scalar_LNumber( + value: 2 + ) ) ) - 3: Expr_ArrayDimFetch( - var: Expr_ArrayDimFetch( + 3: Stmt_Expression( + expr: Expr_ArrayDimFetch( var: Expr_ArrayDimFetch( - var: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 1 + var: Expr_ArrayDimFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 2 + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 2 + ) + byRef: false ) - byRef: false - ) - 2: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 3 + 2: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 3 + ) + byRef: false ) - byRef: false ) ) + dim: Scalar_LNumber( + value: 2 + ) ) dim: Scalar_LNumber( - value: 2 + value: 0 ) ) dim: Scalar_LNumber( value: 0 ) ) - dim: Scalar_LNumber( - value: 0 - ) ) - 4: Expr_ArrayDimFetch( - var: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 1 - ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 2 + 4: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false ) - byRef: false - ) - 2: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 3 + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 2 + ) + byRef: false + ) + 2: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 3 + ) + byRef: false ) - byRef: false ) ) - ) - dim: Scalar_LNumber( - value: 2 + dim: Scalar_LNumber( + value: 2 + ) ) ) - 5: Expr_ArrayDimFetch( - var: Expr_ArrayDimFetch( + 5: Stmt_Expression( + expr: Expr_ArrayDimFetch( var: Expr_ArrayDimFetch( - var: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 1 + var: Expr_ArrayDimFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 2 + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 2 + ) + byRef: false ) - byRef: false - ) - 2: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 3 + 2: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 3 + ) + byRef: false ) - byRef: false ) ) + dim: Scalar_LNumber( + value: 2 + ) ) dim: Scalar_LNumber( - value: 2 + value: 0 ) ) dim: Scalar_LNumber( value: 0 ) ) - dim: Scalar_LNumber( - value: 0 - ) ) - 6: Expr_ArrayDimFetch( - var: Expr_ConstFetch( - name: Name( - parts: array( - 0: FOO + 6: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_ConstFetch( + name: Name( + parts: array( + 0: FOO + ) ) ) - ) - dim: Scalar_LNumber( - value: 0 + dim: Scalar_LNumber( + value: 0 + ) ) ) - 7: Expr_ArrayDimFetch( - var: Expr_ClassConstFetch( - class: Name( - parts: array( - 0: Foo + 7: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: Foo + ) + ) + name: Identifier( + name: BAR ) ) - name: BAR - ) - dim: Scalar_LNumber( - value: 1 + dim: Scalar_LNumber( + value: 1 + ) ) ) - 8: Expr_ArrayDimFetch( - var: Expr_ArrayDimFetch( + 8: Stmt_Expression( + expr: Expr_ArrayDimFetch( var: Expr_ArrayDimFetch( - var: Expr_ClassConstFetch( - class: Expr_Variable( - name: foo + var: Expr_ArrayDimFetch( + var: Expr_ClassConstFetch( + class: Expr_Variable( + name: foo + ) + name: Identifier( + name: BAR + ) + ) + dim: Scalar_LNumber( + value: 2 ) - name: BAR ) dim: Scalar_LNumber( - value: 2 + value: 1 ) ) dim: Scalar_LNumber( - value: 1 + value: 0 ) ) - dim: Scalar_LNumber( - value: 0 - ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/funcCall.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/funcCall.test index 62f69e347..4a8265140 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/funcCall.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/funcCall.test @@ -16,115 +16,141 @@ $a->b['c'](); a()['b']; ----- array( - 0: Expr_FuncCall( - name: Name( - parts: array( - 0: a + 0: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: a + ) + comments: array( + 0: // function name variations + ) + ) + args: array( ) comments: array( 0: // function name variations ) ) - args: array( - ) comments: array( 0: // function name variations ) ) - 1: Expr_FuncCall( - name: Expr_Variable( - name: a - ) - args: array( - ) - ) - 2: Expr_FuncCall( - name: Expr_Variable( - name: Scalar_String( - value: a + 1: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_Variable( + name: a + ) + args: array( ) - ) - args: array( ) ) - 3: Expr_FuncCall( - name: Expr_Variable( + 2: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_Variable( - name: a + name: Scalar_String( + value: a + ) + ) + args: array( ) - ) - args: array( ) ) - 4: Expr_FuncCall( - name: Expr_Variable( + 3: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_Variable( name: Expr_Variable( name: a ) ) - ) - args: array( + args: array( + ) ) ) - 5: Expr_FuncCall( - name: Expr_ArrayDimFetch( - var: Expr_Variable( - name: a + 4: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_Variable( + name: Expr_Variable( + name: Expr_Variable( + name: a + ) + ) ) - dim: Scalar_String( - value: b + args: array( ) ) - args: array( - ) ) - 6: Expr_FuncCall( - name: Expr_ArrayDimFetch( - var: Expr_Variable( - name: a + 5: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: Scalar_String( + value: b + ) ) - dim: Scalar_String( - value: b + args: array( ) ) - args: array( - ) ) - 7: Expr_FuncCall( - name: Expr_ArrayDimFetch( - var: Expr_PropertyFetch( + 6: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_ArrayDimFetch( var: Expr_Variable( name: a ) - name: b + dim: Scalar_String( + value: b + ) ) - dim: Scalar_String( - value: c + args: array( ) ) - args: array( + ) + 7: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c + ) + ) + args: array( + ) ) ) - 8: Expr_ArrayDimFetch( - var: Expr_FuncCall( - name: Name( - parts: array( - 0: a + 8: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_FuncCall( + name: Name( + parts: array( + 0: a + ) + comments: array( + 0: // array dereferencing + ) + ) + args: array( ) comments: array( 0: // array dereferencing ) ) - args: array( + dim: Scalar_String( + value: b ) comments: array( 0: // array dereferencing ) ) - dim: Scalar_String( - value: b - ) comments: array( 0: // array dereferencing ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/newDeref.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/newDeref.test index 5e36ff810..a4b7a7240 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/newDeref.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/newDeref.test @@ -8,48 +8,42 @@ New expression dereferencing (new A)['b']['c']; ----- array( - 0: Expr_PropertyFetch( - var: Expr_New( - class: Name( - parts: array( - 0: A + 0: Stmt_Expression( + expr: Expr_PropertyFetch( + var: Expr_New( + class: Name( + parts: array( + 0: A + ) ) - ) - args: array( - ) - ) - name: b - ) - 1: Expr_MethodCall( - var: Expr_New( - class: Name( - parts: array( - 0: A + args: array( ) ) - args: array( + name: Identifier( + name: b ) ) - name: b - args: array( - ) ) - 2: Expr_ArrayDimFetch( - var: Expr_New( - class: Name( - parts: array( - 0: A + 1: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( ) ) + name: Identifier( + name: b + ) args: array( ) ) - dim: Scalar_String( - value: b - ) ) - 3: Expr_ArrayDimFetch( - var: Expr_ArrayDimFetch( + 2: Stmt_Expression( + expr: Expr_ArrayDimFetch( var: Expr_New( class: Name( parts: array( @@ -63,8 +57,26 @@ array( value: b ) ) - dim: Scalar_String( - value: c + ) + 3: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_ArrayDimFetch( + var: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( + ) + ) + dim: Scalar_String( + value: b + ) + ) + dim: Scalar_String( + value: c + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/objectAccess.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/objectAccess.test index 584461bde..2d1808b05 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/objectAccess.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/objectAccess.test @@ -19,123 +19,162 @@ $a->b(){'c'}; // invalid PHP: drop Support? ----- !!php5 array( - 0: Expr_PropertyFetch( - var: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_PropertyFetch( + var: Expr_Variable( + name: a + comments: array( + 0: // property fetch variations + ) + ) + name: Identifier( + name: b + ) comments: array( 0: // property fetch variations ) ) - name: b comments: array( 0: // property fetch variations ) ) - 1: Expr_ArrayDimFetch( - var: Expr_PropertyFetch( - var: Expr_Variable( - name: a + 1: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c ) - name: b ) - dim: Scalar_String( - value: c + ) + 2: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c + ) ) ) - 2: Expr_ArrayDimFetch( - var: Expr_PropertyFetch( + 3: Stmt_Expression( + expr: Expr_MethodCall( var: Expr_Variable( name: a + comments: array( + 0: // method call variations + ) + ) + name: Identifier( + name: b + ) + args: array( ) - name: b - ) - dim: Scalar_String( - value: c - ) - ) - 3: Expr_MethodCall( - var: Expr_Variable( - name: a comments: array( 0: // method call variations ) ) - name: b - args: array( - ) comments: array( 0: // method call variations ) ) - 4: Expr_MethodCall( - var: Expr_Variable( - name: a - ) - name: Scalar_String( - value: b - ) - args: array( - ) - ) - 5: Expr_MethodCall( - var: Expr_Variable( - name: a - ) - name: Expr_Variable( - name: b - ) - args: array( + 4: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: a + ) + name: Scalar_String( + value: b + ) + args: array( + ) ) ) - 6: Expr_MethodCall( - var: Expr_Variable( - name: a - ) - name: Expr_ArrayDimFetch( + 5: Stmt_Expression( + expr: Expr_MethodCall( var: Expr_Variable( + name: a + ) + name: Expr_Variable( name: b ) - dim: Scalar_String( - value: c + args: array( ) ) - args: array( - ) ) - 7: Expr_ArrayDimFetch( - var: Expr_MethodCall( + 6: Stmt_Expression( + expr: Expr_MethodCall( var: Expr_Variable( name: a + ) + name: Expr_ArrayDimFetch( + var: Expr_Variable( + name: b + ) + dim: Scalar_String( + value: c + ) + ) + args: array( + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_MethodCall( + var: Expr_Variable( + name: a + comments: array( + 0: // array dereferencing + ) + ) + name: Identifier( + name: b + ) + args: array( + ) comments: array( 0: // array dereferencing ) ) - name: b - args: array( + dim: Scalar_String( + value: c ) comments: array( 0: // array dereferencing ) ) - dim: Scalar_String( - value: c - ) comments: array( 0: // array dereferencing ) ) - 8: Expr_ArrayDimFetch( - var: Expr_MethodCall( - var: Expr_Variable( - name: a + 8: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_MethodCall( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + args: array( + ) ) - name: b - args: array( + dim: Scalar_String( + value: c ) ) - dim: Scalar_String( - value: c - ) ) 9: Stmt_Nop( comments: array( diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/simpleArrayAccess.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/simpleArrayAccess.test index ea3f9ef43..133771b75 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/simpleArrayAccess.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/simpleArrayAccess.test @@ -9,16 +9,8 @@ $a{'b'}; ${$a}['b']; ----- array( - 0: Expr_ArrayDimFetch( - var: Expr_Variable( - name: a - ) - dim: Scalar_String( - value: b - ) - ) - 1: Expr_ArrayDimFetch( - var: Expr_ArrayDimFetch( + 0: Stmt_Expression( + expr: Expr_ArrayDimFetch( var: Expr_Variable( name: a ) @@ -26,37 +18,55 @@ array( value: b ) ) - dim: Scalar_String( - value: c - ) ) - 2: Expr_Assign( - var: Expr_ArrayDimFetch( - var: Expr_Variable( - name: a + 1: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: Scalar_String( + value: b + ) + ) + dim: Scalar_String( + value: c ) - dim: null - ) - expr: Expr_Variable( - name: b ) ) - 3: Expr_ArrayDimFetch( - var: Expr_Variable( - name: a - ) - dim: Scalar_String( - value: b + 2: Stmt_Expression( + expr: Expr_Assign( + var: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: null + ) + expr: Expr_Variable( + name: b + ) ) ) - 4: Expr_ArrayDimFetch( - var: Expr_Variable( - name: Expr_Variable( + 3: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_Variable( name: a ) + dim: Scalar_String( + value: b + ) ) - dim: Scalar_String( - value: b + ) + 4: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_Variable( + name: Expr_Variable( + name: a + ) + ) + dim: Scalar_String( + value: b + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/staticCall.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/staticCall.test index b806f7de4..a34a3e4bc 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/staticCall.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/staticCall.test @@ -20,71 +20,65 @@ $a['b']::c(); ----- !!php5 array( - 0: Expr_StaticCall( - class: Name( - parts: array( - 0: A + 0: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: A + ) + comments: array( + 0: // method name variations + ) + ) + name: Identifier( + name: b + ) + args: array( ) comments: array( 0: // method name variations ) ) - name: b - args: array( - ) comments: array( 0: // method name variations ) ) - 1: Expr_StaticCall( - class: Name( - parts: array( - 0: A + 1: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: A + ) ) - ) - name: Scalar_String( - value: b - ) - args: array( - ) - ) - 2: Expr_StaticCall( - class: Name( - parts: array( - 0: A + name: Scalar_String( + value: b + ) + args: array( ) - ) - name: Expr_Variable( - name: b - ) - args: array( ) ) - 3: Expr_StaticCall( - class: Name( - parts: array( - 0: A + 2: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: A + ) ) - ) - name: Expr_ArrayDimFetch( - var: Expr_Variable( + name: Expr_Variable( name: b ) - dim: Scalar_String( - value: c + args: array( ) ) - args: array( - ) ) - 4: Expr_StaticCall( - class: Name( - parts: array( - 0: A + 3: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: A + ) ) - ) - name: Expr_ArrayDimFetch( - var: Expr_ArrayDimFetch( + name: Expr_ArrayDimFetch( var: Expr_Variable( name: b ) @@ -92,82 +86,129 @@ array( value: c ) ) - dim: Scalar_String( - value: d + args: array( ) ) - args: array( - ) ) - 5: Expr_ArrayDimFetch( - var: Expr_StaticCall( + 4: Stmt_Expression( + expr: Expr_StaticCall( class: Name( parts: array( 0: A ) + ) + name: Expr_ArrayDimFetch( + var: Expr_ArrayDimFetch( + var: Expr_Variable( + name: b + ) + dim: Scalar_String( + value: c + ) + ) + dim: Scalar_String( + value: d + ) + ) + args: array( + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_StaticCall( + class: Name( + parts: array( + 0: A + ) + comments: array( + 0: // array dereferencing + ) + ) + name: Identifier( + name: b + ) + args: array( + ) comments: array( 0: // array dereferencing ) ) - name: b - args: array( + dim: Scalar_String( + value: c ) comments: array( 0: // array dereferencing ) ) - dim: Scalar_String( - value: c - ) comments: array( 0: // array dereferencing ) ) - 6: Expr_StaticCall( - class: Name( - parts: array( - 0: static + 6: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: static + ) + comments: array( + 0: // class name variations + ) + ) + name: Identifier( + name: b + ) + args: array( ) comments: array( 0: // class name variations ) ) - name: b - args: array( - ) comments: array( 0: // class name variations ) ) - 7: Expr_StaticCall( - class: Expr_Variable( - name: a - ) - name: b - args: array( + 7: Stmt_Expression( + expr: Expr_StaticCall( + class: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + args: array( + ) ) ) - 8: Expr_StaticCall( - class: Expr_Variable( - name: Scalar_String( - value: a + 8: Stmt_Expression( + expr: Expr_StaticCall( + class: Expr_Variable( + name: Scalar_String( + value: a + ) + ) + name: Identifier( + name: b + ) + args: array( ) - ) - name: b - args: array( ) ) - 9: Expr_StaticCall( - class: Expr_ArrayDimFetch( - var: Expr_Variable( - name: a + 9: Stmt_Expression( + expr: Expr_StaticCall( + class: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: Scalar_String( + value: b + ) ) - dim: Scalar_String( - value: b + name: Identifier( + name: c + ) + args: array( ) - ) - name: c - args: array( ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/staticPropertyFetch.test b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/staticPropertyFetch.test index 3d3cde510..a1de3c8c1 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/staticPropertyFetch.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/fetchAndCall/staticPropertyFetch.test @@ -14,73 +14,95 @@ A::$b{'c'}; // class name variations can be found in staticCall.test ----- array( - 0: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: A + 0: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) + comments: array( + 0: // property name variations + ) + ) + name: VarLikeIdentifier( + name: b ) comments: array( 0: // property name variations ) ) - name: b comments: array( 0: // property name variations ) ) - 1: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: A + 1: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) ) - ) - name: Expr_Variable( - name: b - ) - ) - 2: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: A + name: Expr_Variable( + name: b ) ) - name: Scalar_String( - value: b - ) ) - 3: Expr_ArrayDimFetch( - var: Expr_StaticPropertyFetch( + 2: Stmt_Expression( + expr: Expr_StaticPropertyFetch( class: Name( parts: array( 0: A ) + ) + name: Scalar_String( + value: b + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) + comments: array( + 0: // array access + ) + ) + name: VarLikeIdentifier( + name: b + ) comments: array( 0: // array access ) ) - name: b + dim: Scalar_String( + value: c + ) comments: array( 0: // array access ) ) - dim: Scalar_String( - value: c - ) comments: array( 0: // array access ) ) - 4: Expr_ArrayDimFetch( - var: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: A + 4: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: VarLikeIdentifier( + name: b ) ) - name: b - ) - dim: Scalar_String( - value: c + dim: Scalar_String( + value: c + ) ) ) 5: Stmt_Nop( diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/includeAndEval.test b/app/vendor/nikic/php-parser/test/code/parser/expr/includeAndEval.test index 8870ea5e7..0ab189081 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/includeAndEval.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/includeAndEval.test @@ -8,33 +8,43 @@ require_once 'A.php'; eval('A'); ----- array( - 0: Expr_Include( - expr: Scalar_String( - value: A.php + 0: Stmt_Expression( + expr: Expr_Include( + expr: Scalar_String( + value: A.php + ) + type: TYPE_INCLUDE (1) ) - type: TYPE_INCLUDE (1) ) - 1: Expr_Include( - expr: Scalar_String( - value: A.php + 1: Stmt_Expression( + expr: Expr_Include( + expr: Scalar_String( + value: A.php + ) + type: TYPE_INCLUDE_ONCE (2) ) - type: TYPE_INCLUDE_ONCE (2) ) - 2: Expr_Include( - expr: Scalar_String( - value: A.php + 2: Stmt_Expression( + expr: Expr_Include( + expr: Scalar_String( + value: A.php + ) + type: TYPE_REQUIRE (3) ) - type: TYPE_REQUIRE (3) ) - 3: Expr_Include( - expr: Scalar_String( - value: A.php + 3: Stmt_Expression( + expr: Expr_Include( + expr: Scalar_String( + value: A.php + ) + type: TYPE_REQUIRE_ONCE (4) ) - type: TYPE_REQURE_ONCE (4) ) - 4: Expr_Eval( - expr: Scalar_String( - value: A + 4: Stmt_Expression( + expr: Expr_Eval( + expr: Scalar_String( + value: A + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/issetAndEmpty.test b/app/vendor/nikic/php-parser/test/code/parser/expr/issetAndEmpty.test index 3a43d0d42..cd074b1a4 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/issetAndEmpty.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/issetAndEmpty.test @@ -9,65 +9,75 @@ empty(foo()); empty(array(1, 2, 3)); ----- array( - 0: Expr_Isset( - vars: array( - 0: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_Variable( + name: a + ) ) ) ) - 1: Expr_Isset( - vars: array( - 0: Expr_Variable( - name: a - ) - 1: Expr_Variable( - name: b - ) - 2: Expr_Variable( - name: c + 1: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_Variable( + name: a + ) + 1: Expr_Variable( + name: b + ) + 2: Expr_Variable( + name: c + ) ) ) ) - 2: Expr_Empty( - expr: Expr_Variable( - name: a + 2: Stmt_Expression( + expr: Expr_Empty( + expr: Expr_Variable( + name: a + ) ) ) - 3: Expr_Empty( - expr: Expr_FuncCall( - name: Name( - parts: array( - 0: foo + 3: Stmt_Expression( + expr: Expr_Empty( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: foo + ) + ) + args: array( ) - ) - args: array( ) ) ) - 4: Expr_Empty( - expr: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 1 + 4: Stmt_Expression( + expr: Expr_Empty( + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 2 + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 2 + ) + byRef: false ) - byRef: false - ) - 2: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 3 + 2: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 3 + ) + byRef: false ) - byRef: false ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/listReferences.test b/app/vendor/nikic/php-parser/test/code/parser/expr/listReferences.test new file mode 100644 index 000000000..fd9b1e87c --- /dev/null +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/listReferences.test @@ -0,0 +1,88 @@ +List reference assignments (PHP 7.3) +----- + &$v) = $x; +[&$v] = $x; +['k' => &$v] = $x; +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: v + ) + byRef: true + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: k + ) + value: Expr_Variable( + name: v + ) + byRef: true + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: v + ) + byRef: true + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: k + ) + value: Expr_Variable( + name: v + ) + byRef: true + ) + ) + ) + expr: Expr_Variable( + name: x + ) + ) + ) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/listWithKeys.test b/app/vendor/nikic/php-parser/test/code/parser/expr/listWithKeys.test index 48e9637a6..d0cfbb5ff 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/listWithKeys.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/listWithKeys.test @@ -7,69 +7,73 @@ list('a' => list($b => $c), 'd' => $e) = $x; ----- !!php7 array( - 0: Expr_Assign( - var: Expr_List( - items: array( - 0: Expr_ArrayItem( - key: Scalar_String( - value: a - ) - value: Expr_Variable( - name: b + 0: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Expr_Variable( + name: b + ) + byRef: false ) - byRef: false ) ) - ) - expr: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: Scalar_String( - value: a - ) - value: Scalar_String( - value: b + expr: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Scalar_String( + value: b + ) + byRef: false ) - byRef: false ) ) ) ) - 1: Expr_Assign( - var: Expr_List( - items: array( - 0: Expr_ArrayItem( - key: Scalar_String( - value: a - ) - value: Expr_List( - items: array( - 0: Expr_ArrayItem( - key: Expr_Variable( - name: b - ) - value: Expr_Variable( - name: c + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Expr_List( + items: array( + 0: Expr_ArrayItem( + key: Expr_Variable( + name: b + ) + value: Expr_Variable( + name: c + ) + byRef: false ) - byRef: false ) ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: Scalar_String( - value: d - ) - value: Expr_Variable( - name: e + 1: Expr_ArrayItem( + key: Scalar_String( + value: d + ) + value: Expr_Variable( + name: e + ) + byRef: false ) - byRef: false ) ) - ) - expr: Expr_Variable( - name: x + expr: Expr_Variable( + name: x + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/logic.test b/app/vendor/nikic/php-parser/test/code/parser/expr/logic.test index b3634e91a..6b434565f 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/logic.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/logic.test @@ -21,139 +21,170 @@ $a = $b || $c; $a = $b or $c; ----- array( - 0: Expr_BinaryOp_BooleanAnd( - left: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_BinaryOp_BooleanAnd( + left: Expr_Variable( + name: a + comments: array( + 0: // boolean ops + ) + ) + right: Expr_Variable( + name: b + ) comments: array( 0: // boolean ops ) ) - right: Expr_Variable( - name: b - ) comments: array( 0: // boolean ops ) ) - 1: Expr_BinaryOp_BooleanOr( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b - ) - ) - 2: Expr_BooleanNot( - expr: Expr_Variable( - name: a + 1: Stmt_Expression( + expr: Expr_BinaryOp_BooleanOr( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 3: Expr_BooleanNot( + 2: Stmt_Expression( expr: Expr_BooleanNot( expr: Expr_Variable( name: a ) ) ) - 4: Expr_BinaryOp_LogicalAnd( - left: Expr_Variable( - name: a - comments: array( - 0: // logical ops + 3: Stmt_Expression( + expr: Expr_BooleanNot( + expr: Expr_BooleanNot( + expr: Expr_Variable( + name: a + ) ) ) - right: Expr_Variable( - name: b - ) - comments: array( - 0: // logical ops - ) - ) - 5: Expr_BinaryOp_LogicalOr( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b - ) ) - 6: Expr_BinaryOp_LogicalXor( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b - ) - ) - 7: Expr_BinaryOp_BooleanOr( - left: Expr_BinaryOp_BooleanAnd( + 4: Stmt_Expression( + expr: Expr_BinaryOp_LogicalAnd( left: Expr_Variable( name: a comments: array( - 0: // precedence + 0: // logical ops ) ) right: Expr_Variable( name: b ) comments: array( - 0: // precedence + 0: // logical ops ) ) - right: Expr_BinaryOp_BooleanAnd( + comments: array( + 0: // logical ops + ) + ) + 5: Stmt_Expression( + expr: Expr_BinaryOp_LogicalOr( left: Expr_Variable( - name: c + name: a ) right: Expr_Variable( - name: d + name: b ) ) - comments: array( - 0: // precedence - ) ) - 8: Expr_BinaryOp_BooleanAnd( - left: Expr_BinaryOp_BooleanAnd( + 6: Stmt_Expression( + expr: Expr_BinaryOp_LogicalXor( left: Expr_Variable( name: a ) - right: Expr_BinaryOp_BooleanOr( + right: Expr_Variable( + name: b + ) + ) + ) + 7: Stmt_Expression( + expr: Expr_BinaryOp_BooleanOr( + left: Expr_BinaryOp_BooleanAnd( left: Expr_Variable( - name: b + name: a + comments: array( + 0: // precedence + ) ) right: Expr_Variable( + name: b + ) + comments: array( + 0: // precedence + ) + ) + right: Expr_BinaryOp_BooleanAnd( + left: Expr_Variable( name: c ) + right: Expr_Variable( + name: d + ) + ) + comments: array( + 0: // precedence ) ) - right: Expr_Variable( - name: d + comments: array( + 0: // precedence ) ) - 9: Expr_Assign( - var: Expr_Variable( - name: a - ) - expr: Expr_BinaryOp_BooleanOr( - left: Expr_Variable( - name: b + 8: Stmt_Expression( + expr: Expr_BinaryOp_BooleanAnd( + left: Expr_BinaryOp_BooleanAnd( + left: Expr_Variable( + name: a + ) + right: Expr_BinaryOp_BooleanOr( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) + ) ) right: Expr_Variable( - name: c + name: d ) ) ) - 10: Expr_BinaryOp_LogicalOr( - left: Expr_Assign( + 9: Stmt_Expression( + expr: Expr_Assign( var: Expr_Variable( name: a ) - expr: Expr_Variable( - name: b + expr: Expr_BinaryOp_BooleanOr( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) ) ) - right: Expr_Variable( - name: c + ) + 10: Stmt_Expression( + expr: Expr_BinaryOp_LogicalOr( + left: Expr_Assign( + var: Expr_Variable( + name: a + ) + expr: Expr_Variable( + name: b + ) + ) + right: Expr_Variable( + name: c + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/math.test b/app/vendor/nikic/php-parser/test/code/parser/expr/math.test index 3c00ebc70..8399400c0 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/math.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/math.test @@ -34,223 +34,280 @@ $a ** $b ** $c; ($a ** $b) ** $c; ----- array( - 0: Expr_BitwiseNot( - expr: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_BitwiseNot( + expr: Expr_Variable( + name: a + ) + comments: array( + 0: // unary ops + ) ) comments: array( 0: // unary ops ) ) - 1: Expr_UnaryPlus( - expr: Expr_Variable( - name: a + 1: Stmt_Expression( + expr: Expr_UnaryPlus( + expr: Expr_Variable( + name: a + ) ) ) - 2: Expr_UnaryMinus( - expr: Expr_Variable( - name: a + 2: Stmt_Expression( + expr: Expr_UnaryMinus( + expr: Expr_Variable( + name: a + ) ) ) - 3: Expr_BinaryOp_BitwiseAnd( - left: Expr_Variable( - name: a + 3: Stmt_Expression( + expr: Expr_BinaryOp_BitwiseAnd( + left: Expr_Variable( + name: a + comments: array( + 0: // binary ops + ) + ) + right: Expr_Variable( + name: b + ) comments: array( 0: // binary ops ) ) - right: Expr_Variable( - name: b - ) comments: array( 0: // binary ops ) ) - 4: Expr_BinaryOp_BitwiseOr( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b - ) - ) - 5: Expr_BinaryOp_BitwiseXor( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 4: Stmt_Expression( + expr: Expr_BinaryOp_BitwiseOr( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 6: Expr_BinaryOp_Concat( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 5: Stmt_Expression( + expr: Expr_BinaryOp_BitwiseXor( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 7: Expr_BinaryOp_Div( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 6: Stmt_Expression( + expr: Expr_BinaryOp_Concat( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 8: Expr_BinaryOp_Minus( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 7: Stmt_Expression( + expr: Expr_BinaryOp_Div( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 9: Expr_BinaryOp_Mod( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 8: Stmt_Expression( + expr: Expr_BinaryOp_Minus( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 10: Expr_BinaryOp_Mul( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 9: Stmt_Expression( + expr: Expr_BinaryOp_Mod( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 11: Expr_BinaryOp_Plus( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 10: Stmt_Expression( + expr: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 12: Expr_BinaryOp_ShiftLeft( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 11: Stmt_Expression( + expr: Expr_BinaryOp_Plus( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 13: Expr_BinaryOp_ShiftRight( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 12: Stmt_Expression( + expr: Expr_BinaryOp_ShiftLeft( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 14: Expr_BinaryOp_Pow( - left: Expr_Variable( - name: a - ) - right: Expr_Variable( - name: b + 13: Stmt_Expression( + expr: Expr_BinaryOp_ShiftRight( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) ) - 15: Expr_BinaryOp_Mul( - left: Expr_BinaryOp_Mul( + 14: Stmt_Expression( + expr: Expr_BinaryOp_Pow( left: Expr_Variable( name: a + ) + right: Expr_Variable( + name: b + ) + ) + ) + 15: Stmt_Expression( + expr: Expr_BinaryOp_Mul( + left: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: a + comments: array( + 0: // associativity + ) + ) + right: Expr_Variable( + name: b + ) comments: array( 0: // associativity ) ) right: Expr_Variable( - name: b + name: c ) comments: array( 0: // associativity ) ) - right: Expr_Variable( - name: c - ) comments: array( 0: // associativity ) ) - 16: Expr_BinaryOp_Mul( - left: Expr_Variable( - name: a - ) - right: Expr_BinaryOp_Mul( + 16: Stmt_Expression( + expr: Expr_BinaryOp_Mul( left: Expr_Variable( - name: b + name: a ) - right: Expr_Variable( - name: c + right: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) ) ) ) - 17: Expr_BinaryOp_Plus( - left: Expr_Variable( - name: a + 17: Stmt_Expression( + expr: Expr_BinaryOp_Plus( + left: Expr_Variable( + name: a + comments: array( + 0: // precedence + ) + ) + right: Expr_BinaryOp_Mul( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) + ) comments: array( 0: // precedence ) ) - right: Expr_BinaryOp_Mul( - left: Expr_Variable( - name: b + comments: array( + 0: // precedence + ) + ) + 18: Stmt_Expression( + expr: Expr_BinaryOp_Mul( + left: Expr_BinaryOp_Plus( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) right: Expr_Variable( name: c ) ) - comments: array( - 0: // precedence - ) ) - 18: Expr_BinaryOp_Mul( - left: Expr_BinaryOp_Plus( + 19: Stmt_Expression( + expr: Expr_BinaryOp_Pow( left: Expr_Variable( name: a + comments: array( + 0: // pow is special + ) ) - right: Expr_Variable( - name: b + right: Expr_BinaryOp_Pow( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) ) - ) - right: Expr_Variable( - name: c - ) - ) - 19: Expr_BinaryOp_Pow( - left: Expr_Variable( - name: a comments: array( 0: // pow is special ) ) - right: Expr_BinaryOp_Pow( - left: Expr_Variable( - name: b - ) - right: Expr_Variable( - name: c - ) - ) comments: array( 0: // pow is special ) ) - 20: Expr_BinaryOp_Pow( - left: Expr_BinaryOp_Pow( - left: Expr_Variable( - name: a + 20: Stmt_Expression( + expr: Expr_BinaryOp_Pow( + left: Expr_BinaryOp_Pow( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) right: Expr_Variable( - name: b + name: c ) ) - right: Expr_Variable( - name: c - ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/new.test b/app/vendor/nikic/php-parser/test/code/parser/expr/new.test index a132bbb45..2735bfe93 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/new.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/new.test @@ -19,128 +19,169 @@ new $a->b{'c'}(); (new A); ----- array( - 0: Expr_New( - class: Name( - parts: array( - 0: A + 0: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( ) - ) - args: array( ) ) - 1: Expr_New( - class: Name( - parts: array( - 0: A + 1: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: A + ) ) - ) - args: array( - 0: Arg( - value: Expr_Variable( - name: b + args: array( + 0: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) - 2: Expr_New( - class: Expr_Variable( - name: a - ) - args: array( + 2: Stmt_Expression( + expr: Expr_New( + class: Expr_Variable( + name: a + ) + args: array( + ) + comments: array( + 0: // class name variations + ) ) comments: array( 0: // class name variations ) ) - 3: Expr_New( - class: Expr_ArrayDimFetch( - var: Expr_Variable( - name: a + 3: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: Scalar_String( + value: b + ) ) - dim: Scalar_String( - value: b + args: array( ) ) - args: array( - ) ) - 4: Expr_New( - class: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: A + 4: Stmt_Expression( + expr: Expr_New( + class: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: VarLikeIdentifier( + name: b ) ) - name: b - ) - args: array( + args: array( + ) ) ) - 5: Expr_New( - class: Expr_PropertyFetch( - var: Expr_Variable( - name: a + 5: Stmt_Expression( + expr: Expr_New( + class: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + args: array( + ) + comments: array( + 0: // DNCR object access ) - name: b - ) - args: array( ) comments: array( 0: // DNCR object access ) ) - 6: Expr_New( - class: Expr_PropertyFetch( - var: Expr_PropertyFetch( - var: Expr_Variable( - name: a + 6: Stmt_Expression( + expr: Expr_New( + class: Expr_PropertyFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + name: Identifier( + name: c ) - name: b ) - name: c - ) - args: array( + args: array( + ) ) ) - 7: Expr_New( - class: Expr_ArrayDimFetch( - var: Expr_PropertyFetch( - var: Expr_Variable( - name: a + 7: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c ) - name: b ) - dim: Scalar_String( - value: c + args: array( ) ) - args: array( - ) ) - 8: Expr_New( - class: Expr_ArrayDimFetch( - var: Expr_PropertyFetch( - var: Expr_Variable( - name: a + 8: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Variable( + name: a + ) + name: Identifier( + name: b + ) + ) + dim: Scalar_String( + value: c ) - name: b ) - dim: Scalar_String( - value: c + args: array( ) ) - args: array( - ) ) - 9: Expr_New( - class: Name( - parts: array( - 0: A + 9: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: A + ) + ) + args: array( ) ) - args: array( + comments: array( + 0: // test regression introduces by new dereferencing syntax ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/newWithoutClass.test b/app/vendor/nikic/php-parser/test/code/parser/expr/newWithoutClass.test index ca7f4981e..318f9301f 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/newWithoutClass.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/newWithoutClass.test @@ -14,10 +14,12 @@ new; !!php7 Syntax error, unexpected ';' from 2:4 to 2:4 array( - 0: Expr_New( - class: Expr_Error( - ) - args: array( + 0: Stmt_Expression( + expr: Expr_New( + class: Expr_Error( + ) + args: array( + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/print.test b/app/vendor/nikic/php-parser/test/code/parser/expr/print.test index d07afda09..84ed7775b 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/print.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/print.test @@ -4,9 +4,11 @@ Print print $a; ----- array( - 0: Expr_Print( - expr: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Print( + expr: Expr_Variable( + name: a + ) ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/shellExec.test b/app/vendor/nikic/php-parser/test/code/parser/expr/shellExec.test index 2304fd985..115d9f0a3 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/shellExec.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/shellExec.test @@ -8,38 +8,48 @@ Shell execution `test \"`; ----- array( - 0: Expr_ShellExec( - parts: array( + 0: Stmt_Expression( + expr: Expr_ShellExec( + parts: array( + ) ) ) - 1: Expr_ShellExec( - parts: array( - 0: Scalar_EncapsedStringPart( - value: test + 1: Stmt_Expression( + expr: Expr_ShellExec( + parts: array( + 0: Scalar_EncapsedStringPart( + value: test + ) ) ) ) - 2: Expr_ShellExec( - parts: array( - 0: Scalar_EncapsedStringPart( - value: test - ) - 1: Expr_Variable( - name: A + 2: Stmt_Expression( + expr: Expr_ShellExec( + parts: array( + 0: Scalar_EncapsedStringPart( + value: test + ) + 1: Expr_Variable( + name: A + ) ) ) ) - 3: Expr_ShellExec( - parts: array( - 0: Scalar_EncapsedStringPart( - value: test ` + 3: Stmt_Expression( + expr: Expr_ShellExec( + parts: array( + 0: Scalar_EncapsedStringPart( + value: test ` + ) ) ) ) - 4: Expr_ShellExec( - parts: array( - 0: Scalar_EncapsedStringPart( - value: test \" + 4: Stmt_Expression( + expr: Expr_ShellExec( + parts: array( + 0: Scalar_EncapsedStringPart( + value: test \" + ) ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/ternaryAndCoalesce.test b/app/vendor/nikic/php-parser/test/code/parser/expr/ternaryAndCoalesce.test index 268935dbd..ea1010caa 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/ternaryAndCoalesce.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/ternaryAndCoalesce.test @@ -17,133 +17,158 @@ $a ?? $b ? $c : $d; $a && $b ?? $c; ----- array( - 0: Expr_Ternary( - cond: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Ternary( + cond: Expr_Variable( + name: a + comments: array( + 0: // ternary + ) + ) + if: Expr_Variable( + name: b + ) + else: Expr_Variable( + name: c + ) comments: array( 0: // ternary ) ) - if: Expr_Variable( - name: b - ) - else: Expr_Variable( - name: c - ) comments: array( 0: // ternary ) ) - 1: Expr_Ternary( - cond: Expr_Variable( - name: a - ) - if: null - else: Expr_Variable( - name: c - ) - ) - 2: Expr_Ternary( - cond: Expr_Ternary( + 1: Stmt_Expression( + expr: Expr_Ternary( cond: Expr_Variable( name: a + ) + if: null + else: Expr_Variable( + name: c + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_Ternary( + cond: Expr_Ternary( + cond: Expr_Variable( + name: a + comments: array( + 0: // precedence + ) + ) + if: Expr_Variable( + name: b + ) + else: Expr_Variable( + name: c + ) comments: array( 0: // precedence ) ) if: Expr_Variable( - name: b + name: d ) else: Expr_Variable( - name: c + name: e ) comments: array( 0: // precedence ) ) - if: Expr_Variable( - name: d - ) - else: Expr_Variable( - name: e - ) comments: array( 0: // precedence ) ) - 3: Expr_Ternary( - cond: Expr_Variable( - name: a - ) - if: Expr_Variable( - name: b - ) - else: Expr_Ternary( + 3: Stmt_Expression( + expr: Expr_Ternary( cond: Expr_Variable( - name: c + name: a ) if: Expr_Variable( - name: d + name: b ) - else: Expr_Variable( - name: e + else: Expr_Ternary( + cond: Expr_Variable( + name: c + ) + if: Expr_Variable( + name: d + ) + else: Expr_Variable( + name: e + ) ) ) ) - 4: Expr_BinaryOp_Coalesce( - left: Expr_Variable( - name: a + 4: Stmt_Expression( + expr: Expr_BinaryOp_Coalesce( + left: Expr_Variable( + name: a + comments: array( + 0: // null coalesce + ) + ) + right: Expr_Variable( + name: b + ) comments: array( 0: // null coalesce ) ) - right: Expr_Variable( - name: b - ) comments: array( 0: // null coalesce ) ) - 5: Expr_BinaryOp_Coalesce( - left: Expr_Variable( - name: a - ) - right: Expr_BinaryOp_Coalesce( + 5: Stmt_Expression( + expr: Expr_BinaryOp_Coalesce( left: Expr_Variable( - name: b + name: a ) - right: Expr_Variable( - name: c + right: Expr_BinaryOp_Coalesce( + left: Expr_Variable( + name: b + ) + right: Expr_Variable( + name: c + ) ) ) ) - 6: Expr_Ternary( - cond: Expr_BinaryOp_Coalesce( - left: Expr_Variable( - name: a + 6: Stmt_Expression( + expr: Expr_Ternary( + cond: Expr_BinaryOp_Coalesce( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) - right: Expr_Variable( - name: b + if: Expr_Variable( + name: c + ) + else: Expr_Variable( + name: d ) - ) - if: Expr_Variable( - name: c - ) - else: Expr_Variable( - name: d ) ) - 7: Expr_BinaryOp_Coalesce( - left: Expr_BinaryOp_BooleanAnd( - left: Expr_Variable( - name: a + 7: Stmt_Expression( + expr: Expr_BinaryOp_Coalesce( + left: Expr_BinaryOp_BooleanAnd( + left: Expr_Variable( + name: a + ) + right: Expr_Variable( + name: b + ) ) right: Expr_Variable( - name: b + name: c ) ) - right: Expr_Variable( - name: c - ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/trailingCommas.test b/app/vendor/nikic/php-parser/test/code/parser/expr/trailingCommas.test new file mode 100644 index 000000000..11092d981 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/trailingCommas.test @@ -0,0 +1,140 @@ +PHP 7.3 trailing comma additions +----- +bar($a, $b, ); +Foo::bar($a, $b, ); +new Foo($a, $b, ); +unset($a, $b, ); +isset($a, $b, ); +----- +!!php7 +array( + 0: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: foo + ) + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 1: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: foo + ) + name: Identifier( + name: bar + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 2: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: Foo + ) + ) + name: Identifier( + name: bar + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: Foo + ) + ) + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false + ) + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false + ) + ) + ) + ) + 4: Stmt_Unset( + vars: array( + 0: Expr_Variable( + name: a + ) + 1: Expr_Variable( + name: b + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_Variable( + name: a + ) + 1: Expr_Variable( + name: b + ) + ) + ) + ) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/globalNonSimpleVarError.test b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/globalNonSimpleVarError.test index 4cd2e680f..5ae4f958e 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/globalNonSimpleVarError.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/globalNonSimpleVarError.test @@ -15,10 +15,12 @@ array( ) ) ) - 1: Expr_ConstFetch( - name: Name( - parts: array( - 0: bar + 1: Stmt_Expression( + expr: Expr_ConstFetch( + name: Name( + parts: array( + 0: bar + ) ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/indirectCall.test b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/indirectCall.test index bb3e7fbea..2f36cc7af 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/indirectCall.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/indirectCall.test @@ -17,35 +17,8 @@ id(['udef', 'id'])[1]()('var_dump')(5); ----- !!php7 array( - 0: Expr_FuncCall( - name: Expr_FuncCall( - name: Name( - parts: array( - 0: id - ) - ) - args: array( - 0: Arg( - value: Scalar_String( - value: var_dump - ) - byRef: false - unpack: false - ) - ) - ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 1 - ) - byRef: false - unpack: false - ) - ) - ) - 1: Expr_FuncCall( - name: Expr_FuncCall( + 0: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_FuncCall( name: Name( parts: array( @@ -55,7 +28,7 @@ array( args: array( 0: Arg( value: Scalar_String( - value: id + value: var_dump ) byRef: false unpack: false @@ -64,26 +37,17 @@ array( ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 1 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 2 - ) - byRef: false - unpack: false - ) - ) ) - 2: Expr_FuncCall( - name: Expr_FuncCall( + 1: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_FuncCall( name: Expr_FuncCall( name: Name( @@ -92,123 +56,180 @@ array( ) ) args: array( + 0: Arg( + value: Scalar_String( + value: id + ) + byRef: false + unpack: false + ) ) ) args: array( + 0: Arg( + value: Scalar_String( + value: var_dump + ) + byRef: false + unpack: false + ) ) ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 2 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 4 - ) - byRef: false - unpack: false - ) - ) ) - 3: Expr_FuncCall( - name: Expr_FuncCall( + 2: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_FuncCall( - name: Expr_ArrayDimFetch( - var: Expr_FuncCall( + name: Expr_FuncCall( + name: Expr_FuncCall( name: Name( parts: array( 0: id ) ) args: array( - 0: Arg( - value: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_String( - value: udef + ) + ) + args: array( + ) + ) + args: array( + 0: Arg( + value: Scalar_String( + value: var_dump + ) + byRef: false + unpack: false + ) + ) + ) + args: array( + 0: Arg( + value: Scalar_LNumber( + value: 4 + ) + byRef: false + unpack: false + ) + ) + ) + ) + 3: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_FuncCall( + name: Expr_FuncCall( + name: Expr_ArrayDimFetch( + var: Expr_FuncCall( + name: Name( + parts: array( + 0: id + ) + ) + args: array( + 0: Arg( + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_String( + value: udef + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_String( - value: id + 1: Expr_ArrayItem( + key: null + value: Scalar_String( + value: id + ) + byRef: false ) - byRef: false ) ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) + dim: Scalar_LNumber( + value: 1 + ) ) - dim: Scalar_LNumber( - value: 1 + args: array( ) ) args: array( + 0: Arg( + value: Scalar_String( + value: var_dump + ) + byRef: false + unpack: false + ) ) ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 5 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 5 - ) - byRef: false - unpack: false - ) - ) ) - 4: Expr_FuncCall( - name: Expr_FuncCall( + 4: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_FuncCall( - name: Expr_Closure( - static: false - byRef: false - params: array( - 0: Param( - type: null - byRef: false - variadic: false - name: x - default: null + name: Expr_FuncCall( + name: Expr_Closure( + static: false + byRef: false + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: x + ) + default: null + ) + ) + uses: array( + ) + returnType: null + stmts: array( + 0: Stmt_Return( + expr: Expr_Variable( + name: x + ) + ) ) ) - uses: array( - ) - returnType: null - stmts: array( - 0: Stmt_Return( - expr: Expr_Variable( - name: x + args: array( + 0: Arg( + value: Scalar_String( + value: id ) + byRef: false + unpack: false ) ) ) args: array( 0: Arg( value: Scalar_String( - value: id + value: var_dump ) byRef: false unpack: false @@ -217,72 +238,71 @@ array( ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 8 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 8 - ) - byRef: false - unpack: false - ) - ) ) - 5: Expr_FuncCall( - name: Expr_FuncCall( + 5: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_FuncCall( name: Expr_FuncCall( name: Expr_FuncCall( - name: Expr_Assign( - var: Expr_Variable( - name: f - ) - expr: Expr_Closure( - static: false - byRef: false - params: array( - 0: Param( - type: null - byRef: false - variadic: false - name: x - default: Expr_ConstFetch( - name: Name( - parts: array( - 0: null + name: Expr_FuncCall( + name: Expr_Assign( + var: Expr_Variable( + name: f + ) + expr: Expr_Closure( + static: false + byRef: false + params: array( + 0: Param( + type: null + byRef: false + variadic: false + var: Expr_Variable( + name: x + ) + default: Expr_ConstFetch( + name: Name( + parts: array( + 0: null + ) ) ) ) ) - ) - uses: array( - 0: Expr_ClosureUse( - var: f - byRef: true - ) - ) - returnType: null - stmts: array( - 0: Stmt_Return( - expr: Expr_Ternary( - cond: Expr_Variable( - name: x - ) - if: null - else: Expr_Variable( + uses: array( + 0: Expr_ClosureUse( + var: Expr_Variable( name: f ) + byRef: true + ) + ) + returnType: null + stmts: array( + 0: Stmt_Return( + expr: Expr_Ternary( + cond: Expr_Variable( + name: x + ) + if: null + else: Expr_Variable( + name: f + ) + ) ) ) ) ) + args: array( + ) ) args: array( ) @@ -291,58 +311,67 @@ array( ) ) args: array( + 0: Arg( + value: Scalar_String( + value: var_dump + ) + byRef: false + unpack: false + ) ) ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 9 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 9 - ) - byRef: false - unpack: false - ) - ) ) - 6: Expr_FuncCall( - name: Expr_FuncCall( + 6: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_FuncCall( name: Expr_FuncCall( name: Expr_FuncCall( - name: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Variable( - name: obj + name: Expr_FuncCall( + name: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Variable( + name: obj + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_String( - value: id + 1: Expr_ArrayItem( + key: null + value: Scalar_String( + value: id + ) + byRef: false ) - byRef: false ) ) + args: array( + ) ) args: array( + 0: Arg( + value: Scalar_String( + value: id + ) + byRef: false + unpack: false + ) ) ) args: array( 0: Arg( - value: Scalar_String( - value: id + value: Expr_Variable( + name: id ) byRef: false unpack: false @@ -351,8 +380,8 @@ array( ) args: array( 0: Arg( - value: Expr_Variable( - name: id + value: Scalar_String( + value: var_dump ) byRef: false unpack: false @@ -361,38 +390,40 @@ array( ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 10 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 10 - ) - byRef: false - unpack: false - ) - ) ) - 7: Expr_FuncCall( - name: Expr_FuncCall( + 7: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_FuncCall( name: Expr_FuncCall( - name: Scalar_String( - value: id + name: Expr_FuncCall( + name: Scalar_String( + value: id + ) + args: array( + ) ) args: array( + 0: Arg( + value: Scalar_String( + value: id + ) + byRef: false + unpack: false + ) ) ) args: array( 0: Arg( value: Scalar_String( - value: id + value: var_dump ) byRef: false unpack: false @@ -401,81 +432,76 @@ array( ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 12 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 12 - ) - byRef: false - unpack: false - ) - ) ) - 8: Expr_FuncCall( - name: Expr_FuncCall( + 8: Stmt_Expression( + expr: Expr_FuncCall( name: Expr_FuncCall( - name: Expr_BinaryOp_Concat( - left: Scalar_String( - value: i + name: Expr_FuncCall( + name: Expr_BinaryOp_Concat( + left: Scalar_String( + value: i + ) + right: Scalar_String( + value: d + ) ) - right: Scalar_String( - value: d + args: array( ) ) args: array( + 0: Arg( + value: Scalar_String( + value: var_dump + ) + byRef: false + unpack: false + ) ) ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 13 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 13 - ) - byRef: false - unpack: false - ) - ) ) - 9: Expr_FuncCall( - name: Expr_FuncCall( - name: Scalar_String( - value: \id + 9: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_FuncCall( + name: Scalar_String( + value: \id + ) + args: array( + 0: Arg( + value: Scalar_String( + value: var_dump + ) + byRef: false + unpack: false + ) + ) ) args: array( 0: Arg( - value: Scalar_String( - value: var_dump + value: Scalar_LNumber( + value: 14 ) byRef: false unpack: false ) ) ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 14 - ) - byRef: false - unpack: false - ) - ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/isset.test b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/isset.test index 35bc8ed19..68133a864 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/isset.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/isset.test @@ -8,67 +8,77 @@ isset("str"->a); ----- !!php7 array( - 0: Expr_Isset( - vars: array( - 0: Expr_ArrayDimFetch( - var: Expr_BinaryOp_Plus( - left: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 0 + 0: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_ArrayDimFetch( + var: Expr_BinaryOp_Plus( + left: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 0 + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 1 + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false ) - byRef: false ) ) - ) - right: Expr_Array( - items: array( + right: Expr_Array( + items: array( + ) ) ) - ) - dim: Scalar_LNumber( - value: 0 + dim: Scalar_LNumber( + value: 0 + ) ) ) ) ) - 1: Expr_Isset( - vars: array( - 0: Expr_PropertyFetch( - var: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: Scalar_String( - value: a - ) - value: Scalar_String( - value: b + 1: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_PropertyFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Scalar_String( + value: a + ) + value: Scalar_String( + value: b + ) + byRef: false ) - byRef: false ) ) + name: Identifier( + name: a + ) ) - name: a ) ) ) - 2: Expr_Isset( - vars: array( - 0: Expr_PropertyFetch( - var: Scalar_String( - value: str + 2: Stmt_Expression( + expr: Expr_Isset( + vars: array( + 0: Expr_PropertyFetch( + var: Scalar_String( + value: str + ) + name: Identifier( + name: a + ) ) - name: a ) ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/misc.test b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/misc.test index 2c5ba900e..73b515f08 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/misc.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/misc.test @@ -10,100 +10,118 @@ A::A[0][1][2]; ----- !!php7 array( - 0: Expr_ArrayDimFetch( - var: Expr_ClassConstFetch( - class: Name( - parts: array( - 0: A + 0: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: Identifier( + name: A ) ) - name: A - ) - dim: Scalar_LNumber( - value: 0 + dim: Scalar_LNumber( + value: 0 + ) ) ) - 1: Expr_ArrayDimFetch( - var: Expr_ArrayDimFetch( + 1: Stmt_Expression( + expr: Expr_ArrayDimFetch( var: Expr_ArrayDimFetch( - var: Expr_ClassConstFetch( - class: Name( - parts: array( - 0: A + var: Expr_ArrayDimFetch( + var: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: Identifier( + name: A ) ) - name: A + dim: Scalar_LNumber( + value: 0 + ) ) dim: Scalar_LNumber( - value: 0 + value: 1 ) ) dim: Scalar_LNumber( - value: 1 + value: 2 ) ) - dim: Scalar_LNumber( - value: 2 - ) ) - 2: Expr_MethodCall( - var: Scalar_String( - value: string - ) - name: length - args: array( + 2: Stmt_Expression( + expr: Expr_MethodCall( + var: Scalar_String( + value: string + ) + name: Identifier( + name: length + ) + args: array( + ) ) ) - 3: Expr_FuncCall( - name: Expr_ArrayDimFetch( - var: Expr_PropertyFetch( - var: Expr_Clone( - expr: Expr_Variable( - name: obj + 3: Stmt_Expression( + expr: Expr_FuncCall( + name: Expr_ArrayDimFetch( + var: Expr_PropertyFetch( + var: Expr_Clone( + expr: Expr_Variable( + name: obj + ) + ) + name: Identifier( + name: b ) ) - name: b - ) - dim: Scalar_LNumber( - value: 0 + dim: Scalar_LNumber( + value: 0 + ) ) - ) - args: array( - 0: Arg( - value: Scalar_LNumber( - value: 1 + args: array( + 0: Arg( + value: Scalar_LNumber( + value: 1 + ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) - 4: Expr_Assign( - var: Expr_ArrayDimFetch( - var: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 0 + 4: Stmt_Expression( + expr: Expr_Assign( + var: Expr_ArrayDimFetch( + var: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 0 + ) + byRef: false ) - byRef: false - ) - 1: Expr_ArrayItem( - key: null - value: Scalar_LNumber( - value: 1 + 1: Expr_ArrayItem( + key: null + value: Scalar_LNumber( + value: 1 + ) + byRef: false ) - byRef: false ) ) + dim: Scalar_LNumber( + value: 0 + ) ) - dim: Scalar_LNumber( - value: 0 + expr: Scalar_LNumber( + value: 1 ) ) - expr: Scalar_LNumber( - value: 1 - ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/new.test b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/new.test index e5f92f97a..5e1caf2fc 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/new.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/new.test @@ -11,85 +11,109 @@ new $weird[0]->foo::$className; ----- !!php7 array( - 0: Expr_New( - class: Expr_Variable( - name: className - ) - args: array( + 0: Stmt_Expression( + expr: Expr_New( + class: Expr_Variable( + name: className + ) + args: array( + ) ) ) - 1: Expr_New( - class: Expr_ArrayDimFetch( - var: Expr_Variable( - name: array + 1: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_Variable( + name: array + ) + dim: Scalar_String( + value: className + ) ) - dim: Scalar_String( - value: className + args: array( ) ) - args: array( - ) ) - 2: Expr_New( - class: Expr_ArrayDimFetch( - var: Expr_Variable( - name: array + 2: Stmt_Expression( + expr: Expr_New( + class: Expr_ArrayDimFetch( + var: Expr_Variable( + name: array + ) + dim: Scalar_String( + value: className + ) ) - dim: Scalar_String( - value: className + args: array( ) ) - args: array( - ) ) - 3: Expr_New( - class: Expr_PropertyFetch( - var: Expr_Variable( - name: obj + 3: Stmt_Expression( + expr: Expr_New( + class: Expr_PropertyFetch( + var: Expr_Variable( + name: obj + ) + name: Identifier( + name: className + ) + ) + args: array( ) - name: className - ) - args: array( ) ) - 4: Expr_New( - class: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: Test + 4: Stmt_Expression( + expr: Expr_New( + class: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: Test + ) + ) + name: VarLikeIdentifier( + name: className ) ) - name: className - ) - args: array( + args: array( + ) ) ) - 5: Expr_New( - class: Expr_StaticPropertyFetch( - class: Expr_Variable( - name: test + 5: Stmt_Expression( + expr: Expr_New( + class: Expr_StaticPropertyFetch( + class: Expr_Variable( + name: test + ) + name: VarLikeIdentifier( + name: className + ) + ) + args: array( ) - name: className - ) - args: array( ) ) - 6: Expr_New( - class: Expr_StaticPropertyFetch( - class: Expr_PropertyFetch( - var: Expr_ArrayDimFetch( - var: Expr_Variable( - name: weird + 6: Stmt_Expression( + expr: Expr_New( + class: Expr_StaticPropertyFetch( + class: Expr_PropertyFetch( + var: Expr_ArrayDimFetch( + var: Expr_Variable( + name: weird + ) + dim: Scalar_LNumber( + value: 0 + ) ) - dim: Scalar_LNumber( - value: 0 + name: Identifier( + name: foo ) ) - name: foo + name: VarLikeIdentifier( + name: className + ) + ) + args: array( ) - name: className - ) - args: array( ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/staticProperty.test b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/staticProperty.test index 5fadfc483..bf3547ca7 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/staticProperty.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/uvs/staticProperty.test @@ -12,82 +12,112 @@ A::$A::$b; ----- !!php7 array( - 0: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: A + 0: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: VarLikeIdentifier( + name: b ) ) - name: b - ) - 1: Expr_StaticPropertyFetch( - class: Expr_Variable( - name: A - ) - name: b ) - 2: Expr_StaticPropertyFetch( - class: Scalar_String( - value: A + 1: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Expr_Variable( + name: A + ) + name: VarLikeIdentifier( + name: b + ) ) - name: b ) - 3: Expr_StaticPropertyFetch( - class: Expr_BinaryOp_Concat( - left: Scalar_String( + 2: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Scalar_String( value: A ) - right: Scalar_String( - value: + name: VarLikeIdentifier( + name: b ) ) - name: b ) - 4: Expr_StaticPropertyFetch( - class: Expr_ArrayDimFetch( - var: Scalar_String( - value: A + 3: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Expr_BinaryOp_Concat( + left: Scalar_String( + value: A + ) + right: Scalar_String( + value: + ) ) - dim: Scalar_LNumber( - value: 0 + name: VarLikeIdentifier( + name: b ) ) - name: b ) - 5: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: A + 4: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Expr_ArrayDimFetch( + var: Scalar_String( + value: A + ) + dim: Scalar_LNumber( + value: 0 + ) + ) + name: VarLikeIdentifier( + name: b ) - ) - name: Expr_Variable( - name: b ) ) - 6: Expr_ArrayDimFetch( - var: Expr_StaticPropertyFetch( + 5: Stmt_Expression( + expr: Expr_StaticPropertyFetch( class: Name( parts: array( 0: A ) ) name: Expr_Variable( - name: c + name: b ) ) - dim: Scalar_LNumber( - value: 1 + ) + 6: Stmt_Expression( + expr: Expr_ArrayDimFetch( + var: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: Expr_Variable( + name: c + ) + ) + dim: Scalar_LNumber( + value: 1 + ) ) ) - 7: Expr_StaticPropertyFetch( - class: Expr_StaticPropertyFetch( - class: Name( - parts: array( - 0: A + 7: Stmt_Expression( + expr: Expr_StaticPropertyFetch( + class: Expr_StaticPropertyFetch( + class: Name( + parts: array( + 0: A + ) + ) + name: VarLikeIdentifier( + name: A ) ) - name: A + name: VarLikeIdentifier( + name: b + ) ) - name: b ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/expr/variable.test b/app/vendor/nikic/php-parser/test/code/parser/expr/variable.test index 3a709f990..c30326cc5 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/expr/variable.test +++ b/app/vendor/nikic/php-parser/test/code/parser/expr/variable.test @@ -11,45 +11,57 @@ $$a['b']; ----- !!php5 array( - 0: Expr_Variable( - name: a - ) - 1: Expr_Variable( - name: Scalar_String( - value: a + 0: Stmt_Expression( + expr: Expr_Variable( + name: a ) ) - 2: Expr_Variable( - name: Expr_FuncCall( - name: Name( - parts: array( - 0: foo - ) - ) - args: array( + 1: Stmt_Expression( + expr: Expr_Variable( + name: Scalar_String( + value: a ) ) ) - 3: Expr_Variable( - name: Expr_Variable( - name: a + 2: Stmt_Expression( + expr: Expr_Variable( + name: Expr_FuncCall( + name: Name( + parts: array( + 0: foo + ) + ) + args: array( + ) + ) ) ) - 4: Expr_Variable( - name: Expr_Variable( + 3: Stmt_Expression( + expr: Expr_Variable( name: Expr_Variable( name: a ) ) ) - 5: Expr_Variable( - name: Expr_ArrayDimFetch( - var: Expr_Variable( - name: a + 4: Stmt_Expression( + expr: Expr_Variable( + name: Expr_Variable( + name: Expr_Variable( + name: a + ) ) - dim: Scalar_String( - value: b + ) + ) + 5: Stmt_Expression( + expr: Expr_Variable( + name: Expr_ArrayDimFetch( + var: Expr_Variable( + name: a + ) + dim: Scalar_String( + value: b + ) ) ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/exprStmtMode.test b/app/vendor/nikic/php-parser/test/code/parser/exprStmtMode.test new file mode 100644 index 000000000..759e9e545 --- /dev/null +++ b/app/vendor/nikic/php-parser/test/code/parser/exprStmtMode.test @@ -0,0 +1,57 @@ +Expression statement mode +----- + float overflows + 1: // (all are actually the same number, just in different representations) + ) + ) comments: array( 0: // various integer -> float overflows 1: // (all are actually the same number, just in different representations) ) ) - 11: Scalar_DNumber( - value: 1.844674407371E+19 + 11: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + ) ) - 12: Scalar_DNumber( - value: 1.844674407371E+19 + 12: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + ) ) - 13: Scalar_DNumber( - value: 1.844674407371E+19 + 13: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + ) ) - 14: Scalar_DNumber( - value: 1.844674407371E+19 + 14: Stmt_Expression( + expr: Scalar_DNumber( + value: 1.844674407371E+19 + ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/scalar/int.test b/app/vendor/nikic/php-parser/test/code/parser/scalar/int.test index 5a212677c..b65858dbb 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/scalar/int.test +++ b/app/vendor/nikic/php-parser/test/code/parser/scalar/int.test @@ -13,31 +13,49 @@ Different integer syntaxes 0b111000111000; ----- array( - 0: Scalar_LNumber( - value: 0 - ) - 1: Scalar_LNumber( - value: 1 - ) - 2: Scalar_LNumber( - value: @@{ PHP_INT_MAX }@@ - ) - 3: Scalar_DNumber( - value: @@{ PHP_INT_MAX + 1 }@@ - ) - 4: Scalar_LNumber( - value: 4095 - ) - 5: Scalar_LNumber( - value: 4095 - ) - 6: Scalar_LNumber( - value: 4095 - ) - 7: Scalar_LNumber( - value: 511 - ) - 8: Scalar_LNumber( - value: 3640 + 0: Stmt_Expression( + expr: Scalar_LNumber( + value: 0 + ) + ) + 1: Stmt_Expression( + expr: Scalar_LNumber( + value: 1 + ) + ) + 2: Stmt_Expression( + expr: Scalar_LNumber( + value: @@{ PHP_INT_MAX }@@ + ) + ) + 3: Stmt_Expression( + expr: Scalar_DNumber( + value: @@{ PHP_INT_MAX + 1 }@@ + ) + ) + 4: Stmt_Expression( + expr: Scalar_LNumber( + value: 4095 + ) + ) + 5: Stmt_Expression( + expr: Scalar_LNumber( + value: 4095 + ) + ) + 6: Stmt_Expression( + expr: Scalar_LNumber( + value: 4095 + ) + ) + 7: Stmt_Expression( + expr: Scalar_LNumber( + value: 511 + ) + ) + 8: Stmt_Expression( + expr: Scalar_LNumber( + value: 3640 + ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/scalar/invalidOctal.test b/app/vendor/nikic/php-parser/test/code/parser/scalar/invalidOctal.test index bef3061c8..cd0cbfba0 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/scalar/invalidOctal.test +++ b/app/vendor/nikic/php-parser/test/code/parser/scalar/invalidOctal.test @@ -6,8 +6,10 @@ Invalid octal literals !!php7 Invalid numeric literal from 2:1 to 2:4 array( - 0: Scalar_LNumber( - value: 0 + 0: Stmt_Expression( + expr: Scalar_LNumber( + value: 0 + ) ) ) ----- @@ -16,7 +18,9 @@ array( ----- !!php5 array( - 0: Scalar_LNumber( - value: 7 + 0: Stmt_Expression( + expr: Scalar_LNumber( + value: 7 + ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/scalar/magicConst.test b/app/vendor/nikic/php-parser/test/code/parser/scalar/magicConst.test index 9b981eb62..520ea1776 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/scalar/magicConst.test +++ b/app/vendor/nikic/php-parser/test/code/parser/scalar/magicConst.test @@ -12,20 +12,36 @@ __NAMESPACE__; __TRAIT__; ----- array( - 0: Scalar_MagicConst_Class( + 0: Stmt_Expression( + expr: Scalar_MagicConst_Class( + ) ) - 1: Scalar_MagicConst_Dir( + 1: Stmt_Expression( + expr: Scalar_MagicConst_Dir( + ) ) - 2: Scalar_MagicConst_File( + 2: Stmt_Expression( + expr: Scalar_MagicConst_File( + ) ) - 3: Scalar_MagicConst_Function( + 3: Stmt_Expression( + expr: Scalar_MagicConst_Function( + ) ) - 4: Scalar_MagicConst_Line( + 4: Stmt_Expression( + expr: Scalar_MagicConst_Line( + ) ) - 5: Scalar_MagicConst_Method( + 5: Stmt_Expression( + expr: Scalar_MagicConst_Method( + ) ) - 6: Scalar_MagicConst_Namespace( + 6: Stmt_Expression( + expr: Scalar_MagicConst_Namespace( + ) ) - 7: Scalar_MagicConst_Trait( + 7: Stmt_Expression( + expr: Scalar_MagicConst_Trait( + ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/scalar/unicodeEscape.test b/app/vendor/nikic/php-parser/test/code/parser/scalar/unicodeEscape.test index 33a96119a..95d982955 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/scalar/unicodeEscape.test +++ b/app/vendor/nikic/php-parser/test/code/parser/scalar/unicodeEscape.test @@ -8,13 +8,19 @@ Unicode escape sequence ----- !!php7 array( - 0: Scalar_String( - value: @@{"\0"}@@ + 0: Stmt_Expression( + expr: Scalar_String( + value: @@{"\0"}@@ + ) ) - 1: Scalar_String( - value: Ĕ + 1: Stmt_Expression( + expr: Scalar_String( + value: Ĕ + ) ) - 2: Scalar_String( - value: @@{"\xF0\x9F\x98\x82"}@@ + 2: Stmt_Expression( + expr: Scalar_String( + value: @@{"\xF0\x9F\x98\x82"}@@ + ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/semiReserved.test b/app/vendor/nikic/php-parser/test/code/parser/semiReserved.test index 34105300b..7446a875e 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/semiReserved.test +++ b/app/vendor/nikic/php-parser/test/code/parser/semiReserved.test @@ -55,7 +55,9 @@ class Foo { array( 0: Stmt_Class( flags: 0 - name: Test + name: Identifier( + name: Test + ) extends: null implements: array( ) @@ -63,7 +65,9 @@ array( 0: Stmt_ClassMethod( flags: 0 byRef: false - name: array + name: Identifier( + name: array + ) params: array( ) returnType: null @@ -73,7 +77,9 @@ array( 1: Stmt_ClassMethod( flags: 0 byRef: false - name: public + name: Identifier( + name: public + ) params: array( ) returnType: null @@ -83,7 +89,9 @@ array( 2: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: list + name: Identifier( + name: list + ) params: array( ) returnType: null @@ -93,7 +101,9 @@ array( 3: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: protected + name: Identifier( + name: protected + ) params: array( ) returnType: null @@ -104,7 +114,9 @@ array( flags: MODIFIER_PUBLIC (1) props: array( 0: Stmt_PropertyProperty( - name: class + name: VarLikeIdentifier( + name: class + ) default: null ) ) @@ -113,7 +125,9 @@ array( flags: MODIFIER_PUBLIC (1) props: array( 0: Stmt_PropertyProperty( - name: private + name: VarLikeIdentifier( + name: private + ) default: null ) ) @@ -122,13 +136,17 @@ array( flags: 0 consts: array( 0: Const( - name: TRAIT + name: Identifier( + name: TRAIT + ) value: Scalar_LNumber( value: 3 ) ) 1: Const( - name: FINAL + name: Identifier( + name: FINAL + ) value: Scalar_LNumber( value: 4 ) @@ -139,138 +157,195 @@ array( flags: 0 consts: array( 0: Const( - name: __CLASS__ + name: Identifier( + name: __CLASS__ + ) value: Scalar_LNumber( value: 1 ) ) 1: Const( - name: __TRAIT__ + name: Identifier( + name: __TRAIT__ + ) value: Scalar_LNumber( value: 2 ) ) 2: Const( - name: __FUNCTION__ + name: Identifier( + name: __FUNCTION__ + ) value: Scalar_LNumber( value: 3 ) ) 3: Const( - name: __METHOD__ + name: Identifier( + name: __METHOD__ + ) value: Scalar_LNumber( value: 4 ) ) 4: Const( - name: __LINE__ + name: Identifier( + name: __LINE__ + ) value: Scalar_LNumber( value: 5 ) ) 5: Const( - name: __FILE__ + name: Identifier( + name: __FILE__ + ) value: Scalar_LNumber( value: 6 ) ) 6: Const( - name: __DIR__ + name: Identifier( + name: __DIR__ + ) value: Scalar_LNumber( value: 7 ) ) 7: Const( - name: __NAMESPACE__ + name: Identifier( + name: __NAMESPACE__ + ) value: Scalar_LNumber( value: 8 ) ) ) ) + 8: Stmt_Nop( + comments: array( + 0: // __halt_compiler does not work + ) + ) ) ) - 1: Expr_Assign( - var: Expr_Variable( - name: t - ) - expr: Expr_New( - class: Name( - parts: array( - 0: Test - ) + 1: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: t ) - args: array( + expr: Expr_New( + class: Name( + parts: array( + 0: Test + ) + ) + args: array( + ) ) ) ) - 2: Expr_MethodCall( - var: Expr_Variable( - name: t - ) - name: array - args: array( + 2: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: t + ) + name: Identifier( + name: array + ) + args: array( + ) ) ) - 3: Expr_MethodCall( - var: Expr_Variable( - name: t - ) - name: public - args: array( + 3: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: t + ) + name: Identifier( + name: public + ) + args: array( + ) ) ) - 4: Expr_StaticCall( - class: Name( - parts: array( - 0: Test + 4: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: Test + ) + ) + name: Identifier( + name: list + ) + args: array( ) - ) - name: list - args: array( ) ) - 5: Expr_StaticCall( - class: Name( - parts: array( - 0: Test + 5: Stmt_Expression( + expr: Expr_StaticCall( + class: Name( + parts: array( + 0: Test + ) + ) + name: Identifier( + name: protected + ) + args: array( ) - ) - name: protected - args: array( ) ) - 6: Expr_PropertyFetch( - var: Expr_Variable( - name: t + 6: Stmt_Expression( + expr: Expr_PropertyFetch( + var: Expr_Variable( + name: t + ) + name: Identifier( + name: class + ) ) - name: class ) - 7: Expr_PropertyFetch( - var: Expr_Variable( - name: t + 7: Stmt_Expression( + expr: Expr_PropertyFetch( + var: Expr_Variable( + name: t + ) + name: Identifier( + name: private + ) ) - name: private ) - 8: Expr_ClassConstFetch( - class: Name( - parts: array( - 0: Test + 8: Stmt_Expression( + expr: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: Test + ) + ) + name: Identifier( + name: TRAIT ) ) - name: TRAIT ) - 9: Expr_ClassConstFetch( - class: Name( - parts: array( - 0: Test + 9: Stmt_Expression( + expr: Expr_ClassConstFetch( + class: Name( + parts: array( + 0: Test + ) + ) + name: Identifier( + name: FINAL ) ) - name: FINAL ) 10: Stmt_Class( flags: 0 - name: Foo + name: Identifier( + name: Foo + ) extends: null implements: array( ) @@ -295,7 +370,9 @@ array( 0: TraitA ) ) - method: catch + method: Identifier( + name: catch + ) insteadof: array( 0: Name_Relative( parts: array( @@ -310,9 +387,13 @@ array( 0: TraitA ) ) - method: list + method: Identifier( + name: list + ) newModifier: null - newName: foreach + newName: Identifier( + name: foreach + ) ) 2: Stmt_TraitUseAdaptation_Alias( trait: Name( @@ -320,9 +401,13 @@ array( 0: TraitB ) ) - method: throw + method: Identifier( + name: throw + ) newModifier: MODIFIER_PROTECTED (2) - newName: public + newName: Identifier( + name: public + ) ) 3: Stmt_TraitUseAdaptation_Alias( trait: Name( @@ -330,15 +415,21 @@ array( 0: TraitB ) ) - method: self + method: Identifier( + name: self + ) newModifier: MODIFIER_PROTECTED (2) newName: null ) 4: Stmt_TraitUseAdaptation_Alias( trait: null - method: exit + method: Identifier( + name: exit + ) newModifier: null - newName: die + newName: Identifier( + name: die + ) ) 5: Stmt_TraitUseAdaptation_Alias( trait: Name_FullyQualified( @@ -346,9 +437,13 @@ array( 0: TraitC ) ) - method: exit + method: Identifier( + name: exit + ) newModifier: null - newName: bye + newName: Identifier( + name: bye + ) ) 6: Stmt_TraitUseAdaptation_Alias( trait: Name_Relative( @@ -356,9 +451,13 @@ array( 0: TraitC ) ) - method: exit + method: Identifier( + name: exit + ) newModifier: null - newName: byebye + newName: Identifier( + name: byebye + ) ) 7: Stmt_TraitUseAdaptation_Precedence( trait: Name( @@ -366,7 +465,14 @@ array( 0: TraitA ) ) - method: catch + method: Identifier( + name: catch + comments: array( + 0: // + 1: /** doc comment */ + 2: # + ) + ) insteadof: array( 0: Name( parts: array( diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/blocklessStatement.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/blocklessStatement.test index ae83dabb9..abf586465 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/blocklessStatement.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/blocklessStatement.test @@ -22,8 +22,10 @@ array( name: a ) stmts: array( - 0: Expr_Variable( - name: A + 0: Stmt_Expression( + expr: Expr_Variable( + name: A + ) ) ) elseifs: array( @@ -32,16 +34,20 @@ array( name: b ) stmts: array( - 0: Expr_Variable( - name: B + 0: Stmt_Expression( + expr: Expr_Variable( + name: B + ) ) ) ) ) else: Stmt_Else( stmts: array( - 0: Expr_Variable( - name: C + 0: Stmt_Expression( + expr: Expr_Variable( + name: C + ) ) ) ) @@ -54,8 +60,10 @@ array( loop: array( ) stmts: array( - 0: Expr_Variable( - name: foo + 0: Stmt_Expression( + expr: Expr_Variable( + name: foo + ) ) ) ) @@ -69,8 +77,10 @@ array( name: b ) stmts: array( - 0: Expr_Variable( - name: AB + 0: Stmt_Expression( + expr: Expr_Variable( + name: AB + ) ) ) ) @@ -79,33 +89,41 @@ array( name: a ) stmts: array( - 0: Expr_Variable( - name: A + 0: Stmt_Expression( + expr: Expr_Variable( + name: A + ) ) ) ) 4: Stmt_Do( - cond: Expr_Variable( - name: a - ) stmts: array( - 0: Expr_Variable( - name: A + 0: Stmt_Expression( + expr: Expr_Variable( + name: A + ) ) ) + cond: Expr_Variable( + name: a + ) ) 5: Stmt_Declare( declares: array( 0: Stmt_DeclareDeclare( - key: a + key: Identifier( + name: a + ) value: Scalar_String( value: b ) ) ) stmts: array( - 0: Expr_Variable( - name: C + 0: Stmt_Expression( + expr: Expr_Variable( + name: C + ) ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/abstract.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/abstract.test index 8c9a99c7a..01a82e519 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/abstract.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/abstract.test @@ -10,7 +10,9 @@ abstract class A { array( 0: Stmt_Class( flags: MODIFIER_ABSTRACT (16) - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -18,7 +20,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_PUBLIC (1) byRef: false - name: a + name: Identifier( + name: a + ) params: array( ) returnType: null @@ -28,7 +32,9 @@ array( 1: Stmt_ClassMethod( flags: MODIFIER_PUBLIC | MODIFIER_ABSTRACT (17) byRef: false - name: b + name: Identifier( + name: b + ) params: array( ) returnType: null diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/anonymous.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/anonymous.test index 266d94354..a676db68a 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/anonymous.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/anonymous.test @@ -22,123 +22,137 @@ class A { } ----- array( - 0: Expr_New( - class: Stmt_Class( - flags: 0 - name: null - extends: null - implements: array( - ) - stmts: array( - 0: Stmt_ClassMethod( - flags: MODIFIER_PUBLIC (1) - byRef: false - name: test - params: array( - ) - returnType: null - stmts: array( + 0: Stmt_Expression( + expr: Expr_New( + class: Stmt_Class( + flags: 0 + name: null + extends: null + implements: array( + ) + stmts: array( + 0: Stmt_ClassMethod( + flags: MODIFIER_PUBLIC (1) + byRef: false + name: Identifier( + name: test + ) + params: array( + ) + returnType: null + stmts: array( + ) ) ) ) - ) - args: array( + args: array( + ) ) ) - 1: Expr_New( - class: Stmt_Class( - flags: 0 - name: null - extends: Name( - parts: array( - 0: A - ) - ) - implements: array( - 0: Name( + 1: Stmt_Expression( + expr: Expr_New( + class: Stmt_Class( + flags: 0 + name: null + extends: Name( parts: array( - 0: B + 0: A ) ) - 1: Name( - parts: array( - 0: C + implements: array( + 0: Name( + parts: array( + 0: B + ) ) + 1: Name( + parts: array( + 0: C + ) + ) + ) + stmts: array( ) ) - stmts: array( + args: array( ) ) - args: array( - ) ) - 2: Expr_New( - class: Stmt_Class( - flags: 0 - name: null - extends: null - implements: array( - ) - stmts: array( - 0: Stmt_Property( - flags: MODIFIER_PUBLIC (1) - props: array( - 0: Stmt_PropertyProperty( - name: foo - default: null + 2: Stmt_Expression( + expr: Expr_New( + class: Stmt_Class( + flags: 0 + name: null + extends: null + implements: array( + ) + stmts: array( + 0: Stmt_Property( + flags: MODIFIER_PUBLIC (1) + props: array( + 0: Stmt_PropertyProperty( + name: VarLikeIdentifier( + name: foo + ) + default: null + ) ) ) ) ) - ) - args: array( + args: array( + ) ) ) - 3: Expr_New( - class: Stmt_Class( - flags: 0 - name: null - extends: Name( - parts: array( - 0: A + 3: Stmt_Expression( + expr: Expr_New( + class: Stmt_Class( + flags: 0 + name: null + extends: Name( + parts: array( + 0: A + ) ) - ) - implements: array( - ) - stmts: array( - 0: Stmt_TraitUse( - traits: array( - 0: Name( - parts: array( - 0: T + implements: array( + ) + stmts: array( + 0: Stmt_TraitUse( + traits: array( + 0: Name( + parts: array( + 0: T + ) ) ) - ) - adaptations: array( + adaptations: array( + ) ) ) ) - ) - args: array( - 0: Arg( - value: Expr_Variable( - name: a + args: array( + 0: Arg( + value: Expr_Variable( + name: a + ) + byRef: false + unpack: false ) - byRef: false - unpack: false - ) - 1: Arg( - value: Expr_Variable( - name: b + 1: Arg( + value: Expr_Variable( + name: b + ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) 4: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -146,7 +160,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_PUBLIC (1) byRef: false - name: test + name: Identifier( + name: test + ) params: array( ) returnType: null @@ -168,7 +184,9 @@ array( flags: 0 consts: array( 0: Const( - name: A + name: Identifier( + name: A + ) value: Scalar_String( value: B ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/conditional.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/conditional.test index e18090c79..40a93508b 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/conditional.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/conditional.test @@ -18,7 +18,9 @@ array( stmts: array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/constModifierErrors.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/constModifierErrors.test index b3604ed6d..a6aa79721 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/constModifierErrors.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/constModifierErrors.test @@ -10,7 +10,9 @@ Cannot use 'static' as constant modifier from 3:5 to 3:10 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -19,7 +21,9 @@ array( flags: MODIFIER_STATIC (8) consts: array( 0: Const( - name: X + name: Identifier( + name: X + ) value: Scalar_LNumber( value: 1 ) @@ -40,7 +44,9 @@ Cannot use 'abstract' as constant modifier from 3:5 to 3:12 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -49,7 +55,9 @@ array( flags: MODIFIER_ABSTRACT (16) consts: array( 0: Const( - name: X + name: Identifier( + name: X + ) value: Scalar_LNumber( value: 1 ) @@ -70,7 +78,9 @@ Cannot use 'final' as constant modifier from 3:5 to 3:9 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -79,7 +89,9 @@ array( flags: MODIFIER_FINAL (32) consts: array( 0: Const( - name: X + name: Identifier( + name: X + ) value: Scalar_LNumber( value: 1 ) @@ -100,7 +112,9 @@ Multiple access type modifiers are not allowed from 3:12 to 3:17 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -109,7 +123,9 @@ array( flags: MODIFIER_PUBLIC (1) consts: array( 0: Const( - name: X + name: Identifier( + name: X + ) value: Scalar_LNumber( value: 1 ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/constModifiers.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/constModifiers.test index 7129d2846..24d721981 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/constModifiers.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/constModifiers.test @@ -13,7 +13,9 @@ class Foo { array( 0: Stmt_Class( flags: 0 - name: Foo + name: Identifier( + name: Foo + ) extends: null implements: array( ) @@ -22,7 +24,9 @@ array( flags: 0 consts: array( 0: Const( - name: A + name: Identifier( + name: A + ) value: Scalar_LNumber( value: 1 ) @@ -33,7 +37,9 @@ array( flags: MODIFIER_PUBLIC (1) consts: array( 0: Const( - name: B + name: Identifier( + name: B + ) value: Scalar_LNumber( value: 2 ) @@ -44,7 +50,9 @@ array( flags: MODIFIER_PROTECTED (2) consts: array( 0: Const( - name: C + name: Identifier( + name: C + ) value: Scalar_LNumber( value: 3 ) @@ -55,7 +63,9 @@ array( flags: MODIFIER_PRIVATE (4) consts: array( 0: Const( - name: D + name: Identifier( + name: D + ) value: Scalar_LNumber( value: 4 ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/final.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/final.test index 86cc45868..ecb7a5c3d 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/final.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/final.test @@ -7,7 +7,9 @@ final class A {} array( 0: Stmt_Class( flags: MODIFIER_FINAL (32) - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/implicitPublic.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/implicitPublic.test index 08452c156..bd43dce9c 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/implicitPublic.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/implicitPublic.test @@ -15,7 +15,9 @@ abstract class A { array( 0: Stmt_Class( flags: MODIFIER_ABSTRACT (16) - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -24,7 +26,9 @@ array( flags: 0 props: array( 0: Stmt_PropertyProperty( - name: a + name: VarLikeIdentifier( + name: a + ) default: null ) ) @@ -33,7 +37,9 @@ array( flags: MODIFIER_STATIC (8) props: array( 0: Stmt_PropertyProperty( - name: b + name: VarLikeIdentifier( + name: b + ) default: null ) ) @@ -41,7 +47,9 @@ array( 2: Stmt_ClassMethod( flags: MODIFIER_ABSTRACT (16) byRef: false - name: c + name: Identifier( + name: c + ) params: array( ) returnType: null @@ -50,7 +58,9 @@ array( 3: Stmt_ClassMethod( flags: MODIFIER_FINAL (32) byRef: false - name: d + name: Identifier( + name: d + ) params: array( ) returnType: null @@ -60,7 +70,9 @@ array( 4: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: e + name: Identifier( + name: e + ) params: array( ) returnType: null @@ -70,7 +82,9 @@ array( 5: Stmt_ClassMethod( flags: MODIFIER_STATIC | MODIFIER_FINAL (40) byRef: false - name: f + name: Identifier( + name: f + ) params: array( ) returnType: null @@ -80,7 +94,9 @@ array( 6: Stmt_ClassMethod( flags: 0 byRef: false - name: g + name: Identifier( + name: g + ) params: array( ) returnType: null diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/interface.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/interface.test index d00bdbdc8..7ac15970d 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/interface.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/interface.test @@ -8,7 +8,9 @@ interface A extends C, D { ----- array( 0: Stmt_Interface( - name: A + name: Identifier( + name: A + ) extends: array( 0: Name( parts: array( @@ -25,7 +27,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_PUBLIC (1) byRef: false - name: a + name: Identifier( + name: a + ) params: array( ) returnType: null diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/modifier.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/modifier.test index 5a1fd3fc5..cbeb57e11 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/modifier.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/modifier.test @@ -6,7 +6,9 @@ Multiple access type modifiers are not allowed from 1:24 to 1:29 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -15,7 +17,9 @@ array( flags: MODIFIER_PUBLIC (1) props: array( 0: Stmt_PropertyProperty( - name: a + name: VarLikeIdentifier( + name: a + ) default: null ) ) @@ -30,7 +34,9 @@ Multiple access type modifiers are not allowed from 1:24 to 1:32 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -39,7 +45,9 @@ array( flags: MODIFIER_PUBLIC | MODIFIER_PROTECTED (3) props: array( 0: Stmt_PropertyProperty( - name: a + name: VarLikeIdentifier( + name: a + ) default: null ) ) @@ -54,7 +62,9 @@ Multiple abstract modifiers are not allowed from 1:26 to 1:33 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -62,7 +72,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_ABSTRACT (16) byRef: false - name: a + name: Identifier( + name: a + ) params: array( ) returnType: null @@ -78,7 +90,9 @@ Multiple static modifiers are not allowed from 1:24 to 1:29 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -87,7 +101,9 @@ array( flags: MODIFIER_STATIC (8) props: array( 0: Stmt_PropertyProperty( - name: a + name: VarLikeIdentifier( + name: a + ) default: null ) ) @@ -102,7 +118,9 @@ Multiple final modifiers are not allowed from 1:23 to 1:27 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -110,7 +128,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_FINAL (32) byRef: false - name: a + name: Identifier( + name: a + ) params: array( ) returnType: null @@ -127,7 +147,9 @@ Cannot use the final modifier on an abstract class member from 1:26 to 1:30 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -135,7 +157,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_ABSTRACT | MODIFIER_FINAL (48) byRef: false - name: a + name: Identifier( + name: a + ) params: array( ) returnType: null @@ -152,7 +176,9 @@ Syntax error, unexpected T_FINAL, expecting T_CLASS from 1:16 to 1:20 array( 0: Stmt_Class( flags: MODIFIER_FINAL (32) - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -172,7 +198,9 @@ Properties cannot be declared abstract from 1:17 to 1:24 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -181,7 +209,9 @@ array( flags: MODIFIER_ABSTRACT (16) props: array( 0: Stmt_PropertyProperty( - name: a + name: VarLikeIdentifier( + name: a + ) default: null ) ) @@ -196,7 +226,9 @@ Properties cannot be declared final from 1:17 to 1:21 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -205,11 +237,13 @@ array( flags: MODIFIER_FINAL (32) props: array( 0: Stmt_PropertyProperty( - name: a + name: VarLikeIdentifier( + name: a + ) default: null ) ) ) ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/name.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/name.test index d53330521..40cb2fe27 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/name.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/name.test @@ -6,7 +6,9 @@ Cannot use 'self' as class name as it is reserved from 1:13 to 1:16 array( 0: Stmt_Class( flags: 0 - name: self + name: Identifier( + name: self + ) extends: null implements: array( ) @@ -21,7 +23,9 @@ Cannot use 'PARENT' as class name as it is reserved from 1:13 to 1:18 array( 0: Stmt_Class( flags: 0 - name: PARENT + name: Identifier( + name: PARENT + ) extends: null implements: array( ) @@ -42,7 +46,9 @@ Cannot use 'self' as class name as it is reserved from 1:23 to 1:26 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: Name( parts: array( 0: self @@ -61,7 +67,9 @@ Cannot use 'PARENT' as class name as it is reserved from 1:23 to 1:28 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: Name( parts: array( 0: PARENT @@ -80,7 +88,9 @@ Cannot use 'static' as class name as it is reserved from 1:23 to 1:28 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: Name( parts: array( 0: static @@ -99,7 +109,9 @@ Cannot use 'self' as interface name as it is reserved from 1:26 to 1:29 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( 0: Name( @@ -119,7 +131,9 @@ Cannot use 'PARENT' as interface name as it is reserved from 1:26 to 1:31 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( 0: Name( @@ -139,7 +153,9 @@ Cannot use 'static' as interface name as it is reserved from 1:26 to 1:31 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( 0: Name( @@ -158,7 +174,9 @@ array( Cannot use 'self' as class name as it is reserved from 1:17 to 1:20 array( 0: Stmt_Interface( - name: self + name: Identifier( + name: self + ) extends: array( ) stmts: array( @@ -171,7 +189,9 @@ array( Cannot use 'PARENT' as class name as it is reserved from 1:17 to 1:22 array( 0: Stmt_Interface( - name: PARENT + name: Identifier( + name: PARENT + ) extends: array( ) stmts: array( @@ -190,7 +210,9 @@ array( Cannot use 'self' as interface name as it is reserved from 1:27 to 1:30 array( 0: Stmt_Interface( - name: A + name: Identifier( + name: A + ) extends: array( 0: Name( parts: array( @@ -208,7 +230,9 @@ array( Cannot use 'PARENT' as interface name as it is reserved from 1:27 to 1:32 array( 0: Stmt_Interface( - name: A + name: Identifier( + name: A + ) extends: array( 0: Name( parts: array( @@ -226,7 +250,9 @@ array( Cannot use 'static' as interface name as it is reserved from 1:27 to 1:32 array( 0: Stmt_Interface( - name: A + name: Identifier( + name: A + ) extends: array( 0: Name( parts: array( diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/php4Style.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/php4Style.test index e459e1752..d6070b889 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/php4Style.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/php4Style.test @@ -11,7 +11,9 @@ class A { array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -20,7 +22,9 @@ array( flags: 0 props: array( 0: Stmt_PropertyProperty( - name: foo + name: VarLikeIdentifier( + name: foo + ) default: null ) ) @@ -28,7 +32,9 @@ array( 1: Stmt_ClassMethod( flags: 0 byRef: false - name: bar + name: Identifier( + name: bar + ) params: array( ) returnType: null @@ -38,7 +44,9 @@ array( 2: Stmt_ClassMethod( flags: MODIFIER_ABSTRACT | MODIFIER_STATIC (24) byRef: false - name: baz + name: Identifier( + name: baz + ) params: array( ) returnType: null diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/simple.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/simple.test index b2f899449..9247eec9f 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/simple.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/simple.test @@ -19,7 +19,9 @@ class A extends B implements C, D { array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: Name( parts: array( 0: B @@ -42,13 +44,17 @@ array( flags: 0 consts: array( 0: Const( - name: A + name: Identifier( + name: A + ) value: Scalar_String( value: B ) ) 1: Const( - name: C + name: Identifier( + name: C + ) value: Scalar_String( value: D ) @@ -59,13 +65,17 @@ array( flags: MODIFIER_PUBLIC (1) props: array( 0: Stmt_PropertyProperty( - name: a + name: VarLikeIdentifier( + name: a + ) default: Scalar_String( value: b ) ) 1: Stmt_PropertyProperty( - name: c + name: VarLikeIdentifier( + name: c + ) default: Scalar_String( value: d ) @@ -76,7 +86,9 @@ array( flags: MODIFIER_PROTECTED (2) props: array( 0: Stmt_PropertyProperty( - name: e + name: VarLikeIdentifier( + name: e + ) default: null ) ) @@ -85,7 +97,9 @@ array( flags: MODIFIER_PRIVATE (4) props: array( 0: Stmt_PropertyProperty( - name: f + name: VarLikeIdentifier( + name: f + ) default: null ) ) @@ -93,7 +107,9 @@ array( 4: Stmt_ClassMethod( flags: MODIFIER_PUBLIC (1) byRef: false - name: a + name: Identifier( + name: a + ) params: array( ) returnType: null @@ -103,13 +119,17 @@ array( 5: Stmt_ClassMethod( flags: MODIFIER_PUBLIC | MODIFIER_STATIC (9) byRef: false - name: b + name: Identifier( + name: b + ) params: array( 0: Param( type: null byRef: false variadic: false - name: a + var: Expr_Variable( + name: a + ) default: null ) ) @@ -120,7 +140,9 @@ array( 6: Stmt_ClassMethod( flags: MODIFIER_PUBLIC | MODIFIER_FINAL (33) byRef: false - name: c + name: Identifier( + name: c + ) params: array( ) returnType: Name( @@ -134,7 +156,9 @@ array( 7: Stmt_ClassMethod( flags: MODIFIER_PROTECTED (2) byRef: false - name: d + name: Identifier( + name: d + ) params: array( ) returnType: null @@ -144,7 +168,9 @@ array( 8: Stmt_ClassMethod( flags: MODIFIER_PRIVATE (4) byRef: false - name: e + name: Identifier( + name: e + ) params: array( ) returnType: null diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/staticMethod.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/staticMethod.test index 225596acb..0540930e4 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/staticMethod.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/staticMethod.test @@ -6,7 +6,9 @@ Constructor __construct() cannot be static from 1:17 to 1:22 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -14,7 +16,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: __construct + name: Identifier( + name: __construct + ) params: array( ) returnType: null @@ -31,7 +35,9 @@ Destructor __destruct() cannot be static from 1:17 to 1:22 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -39,7 +45,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: __destruct + name: Identifier( + name: __destruct + ) params: array( ) returnType: null @@ -56,7 +64,9 @@ Clone method __clone() cannot be static from 1:17 to 1:22 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -64,7 +74,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: __clone + name: Identifier( + name: __clone + ) params: array( ) returnType: null @@ -81,7 +93,9 @@ Constructor __CONSTRUCT() cannot be static from 1:17 to 1:22 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -89,7 +103,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: __CONSTRUCT + name: Identifier( + name: __CONSTRUCT + ) params: array( ) returnType: null @@ -106,7 +122,9 @@ Destructor __Destruct() cannot be static from 1:17 to 1:22 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -114,7 +132,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: __Destruct + name: Identifier( + name: __Destruct + ) params: array( ) returnType: null @@ -131,7 +151,9 @@ Clone method __cLoNe() cannot be static from 1:17 to 1:22 array( 0: Stmt_Class( flags: 0 - name: A + name: Identifier( + name: A + ) extends: null implements: array( ) @@ -139,7 +161,9 @@ array( 0: Stmt_ClassMethod( flags: MODIFIER_STATIC (8) byRef: false - name: __cLoNe + name: Identifier( + name: __cLoNe + ) params: array( ) returnType: null diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/trait.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/trait.test index 75c6ec66f..bda3cc56d 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/class/trait.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/class/trait.test @@ -23,12 +23,16 @@ class B { ----- array( 0: Stmt_Trait( - name: A + name: Identifier( + name: A + ) stmts: array( 0: Stmt_ClassMethod( flags: MODIFIER_PUBLIC (1) byRef: false - name: a + name: Identifier( + name: a + ) params: array( ) returnType: null @@ -39,7 +43,9 @@ array( ) 1: Stmt_Class( flags: 0 - name: B + name: Identifier( + name: B + ) extends: null implements: array( ) @@ -66,19 +72,29 @@ array( adaptations: array( 0: Stmt_TraitUseAdaptation_Alias( trait: null - method: a + method: Identifier( + name: a + ) newModifier: MODIFIER_PROTECTED (2) - newName: b + newName: Identifier( + name: b + ) ) 1: Stmt_TraitUseAdaptation_Alias( trait: null - method: c + method: Identifier( + name: c + ) newModifier: null - newName: d + newName: Identifier( + name: d + ) ) 2: Stmt_TraitUseAdaptation_Alias( trait: null - method: e + method: Identifier( + name: e + ) newModifier: MODIFIER_PRIVATE (4) newName: null ) @@ -109,7 +125,9 @@ array( 0: E ) ) - method: a + method: Identifier( + name: a + ) insteadof: array( 0: Name( parts: array( @@ -129,9 +147,13 @@ array( 0: E ) ) - method: b + method: Identifier( + name: b + ) newModifier: MODIFIER_PROTECTED (2) - newName: c + newName: Identifier( + name: c + ) ) 2: Stmt_TraitUseAdaptation_Alias( trait: Name( @@ -139,9 +161,13 @@ array( 0: E ) ) - method: d + method: Identifier( + name: d + ) newModifier: null - newName: e + newName: Identifier( + name: e + ) ) 3: Stmt_TraitUseAdaptation_Alias( trait: Name( @@ -149,7 +175,9 @@ array( 0: E ) ) - method: f + method: Identifier( + name: f + ) newModifier: MODIFIER_PRIVATE (4) newName: null ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/const.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/const.test index da21f416f..e6c4db84f 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/const.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/const.test @@ -8,25 +8,33 @@ array( 0: Stmt_Const( consts: array( 0: Const( - name: A + name: Identifier( + name: A + ) value: Scalar_LNumber( value: 0 ) ) 1: Const( - name: B + name: Identifier( + name: B + ) value: Scalar_DNumber( value: 1 ) ) 2: Const( - name: C + name: Identifier( + name: C + ) value: Scalar_String( value: A ) ) 3: Const( - name: D + name: Identifier( + name: D + ) value: Expr_ConstFetch( name: Name( parts: array( diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/controlFlow.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/controlFlow.test index 2de1c4f25..d9c9fcf35 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/controlFlow.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/controlFlow.test @@ -47,9 +47,13 @@ array( ) ) 7: Stmt_Label( - name: label + name: Identifier( + name: label + ) ) 8: Stmt_Goto( - name: label + name: Identifier( + name: label + ) ) ) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/declare.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/declare.test index 93afe67b9..f044d24f9 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/declare.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/declare.test @@ -13,7 +13,9 @@ array( 0: Stmt_Declare( declares: array( 0: Stmt_DeclareDeclare( - key: X + key: Identifier( + name: X + ) value: Scalar_String( value: Y ) @@ -24,13 +26,17 @@ array( 1: Stmt_Declare( declares: array( 0: Stmt_DeclareDeclare( - key: A + key: Identifier( + name: A + ) value: Scalar_String( value: B ) ) 1: Stmt_DeclareDeclare( - key: C + key: Identifier( + name: C + ) value: Scalar_String( value: D ) @@ -42,13 +48,17 @@ array( 2: Stmt_Declare( declares: array( 0: Stmt_DeclareDeclare( - key: A + key: Identifier( + name: A + ) value: Scalar_String( value: B ) ) 1: Stmt_DeclareDeclare( - key: C + key: Identifier( + name: C + ) value: Scalar_String( value: D ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/builtinTypeDeclarations.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/builtinTypeDeclarations.test index aecced5d6..b90fd019a 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/builtinTypeDeclarations.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/builtinTypeDeclarations.test @@ -7,52 +7,80 @@ function test(bool $a, Int $b, FLOAT $c, StRiNg $d, iterable $e, object $f) : vo array( 0: Stmt_Function( byRef: false - name: test + name: Identifier( + name: test + ) params: array( 0: Param( - type: bool + type: Identifier( + name: bool + ) byRef: false variadic: false - name: a + var: Expr_Variable( + name: a + ) default: null ) 1: Param( - type: int + type: Identifier( + name: int + ) byRef: false variadic: false - name: b + var: Expr_Variable( + name: b + ) default: null ) 2: Param( - type: float + type: Identifier( + name: float + ) byRef: false variadic: false - name: c + var: Expr_Variable( + name: c + ) default: null ) 3: Param( - type: string + type: Identifier( + name: string + ) byRef: false variadic: false - name: d + var: Expr_Variable( + name: d + ) default: null ) 4: Param( - type: iterable + type: Identifier( + name: iterable + ) byRef: false variadic: false - name: e + var: Expr_Variable( + name: e + ) default: null ) 5: Param( - type: object + type: Identifier( + name: object + ) byRef: false variadic: false - name: f + var: Expr_Variable( + name: f + ) default: null ) ) - returnType: void + returnType: Identifier( + name: void + ) stmts: array( ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/byRef.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/byRef.test index 1c1669c10..4b276e734 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/byRef.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/byRef.test @@ -8,13 +8,17 @@ function &a($b) {} array( 0: Stmt_Function( byRef: false - name: a + name: Identifier( + name: a + ) params: array( 0: Param( type: null byRef: true variadic: false - name: b + var: Expr_Variable( + name: b + ) default: null ) ) @@ -24,13 +28,17 @@ array( ) 1: Stmt_Function( byRef: true - name: a + name: Identifier( + name: a + ) params: array( 0: Param( type: null byRef: false variadic: false - name: b + var: Expr_Variable( + name: b + ) default: null ) ) @@ -38,4 +46,4 @@ array( stmts: array( ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/conditional.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/conditional.test index d9c886ed8..8495aad1f 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/conditional.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/conditional.test @@ -18,7 +18,9 @@ array( stmts: array( 0: Stmt_Function( byRef: false - name: A + name: Identifier( + name: A + ) params: array( ) returnType: null @@ -30,4 +32,4 @@ array( ) else: null ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/defaultValues.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/defaultValues.test index d77d4f354..6ae96fa65 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/defaultValues.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/defaultValues.test @@ -17,13 +17,17 @@ function a( array( 0: Stmt_Function( byRef: false - name: a + name: Identifier( + name: a + ) params: array( 0: Param( type: null byRef: false variadic: false - name: b + var: Expr_Variable( + name: b + ) default: Expr_ConstFetch( name: Name( parts: array( @@ -36,7 +40,9 @@ array( type: null byRef: false variadic: false - name: c + var: Expr_Variable( + name: c + ) default: Scalar_String( value: foo ) @@ -45,21 +51,27 @@ array( type: null byRef: false variadic: false - name: d + var: Expr_Variable( + name: d + ) default: Expr_ClassConstFetch( class: Name( parts: array( 0: A ) ) - name: B + name: Identifier( + name: B + ) ) ) 3: Param( type: null byRef: false variadic: false - name: f + var: Expr_Variable( + name: f + ) default: Expr_UnaryPlus( expr: Scalar_LNumber( value: 1 @@ -70,7 +82,9 @@ array( type: null byRef: false variadic: false - name: g + var: Expr_Variable( + name: g + ) default: Expr_UnaryMinus( expr: Scalar_DNumber( value: 1 @@ -81,7 +95,9 @@ array( type: null byRef: false variadic: false - name: h + var: Expr_Variable( + name: h + ) default: Expr_Array( items: array( ) @@ -91,7 +107,9 @@ array( type: null byRef: false variadic: false - name: i + var: Expr_Variable( + name: i + ) default: Expr_Array( items: array( ) @@ -101,7 +119,9 @@ array( type: null byRef: false variadic: false - name: j + var: Expr_Variable( + name: j + ) default: Expr_Array( items: array( 0: Expr_ArrayItem( @@ -118,7 +138,9 @@ array( type: null byRef: false variadic: false - name: k + var: Expr_Variable( + name: k + ) default: Expr_Array( items: array( 0: Expr_ArrayItem( @@ -145,4 +167,4 @@ array( stmts: array( ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/nullableTypes.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/nullableTypes.test index d96df4fae..8bf2d31da 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/nullableTypes.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/nullableTypes.test @@ -9,7 +9,9 @@ function test(?Foo $bar, ?string $foo) : ?Baz { array( 0: Stmt_Function( byRef: false - name: test + name: Identifier( + name: test + ) params: array( 0: Param( type: NullableType( @@ -21,16 +23,22 @@ array( ) byRef: false variadic: false - name: bar + var: Expr_Variable( + name: bar + ) default: null ) 1: Param( type: NullableType( - type: string + type: Identifier( + name: string + ) ) byRef: false variadic: false - name: foo + var: Expr_Variable( + name: foo + ) default: null ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/returnTypes.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/returnTypes.test index ca6c3106e..8b71595e7 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/returnTypes.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/returnTypes.test @@ -10,7 +10,9 @@ function test4() : Foo\Bar {} array( 0: Stmt_Function( byRef: false - name: test1 + name: Identifier( + name: test1 + ) params: array( ) returnType: null @@ -19,25 +21,35 @@ array( ) 1: Stmt_Function( byRef: false - name: test2 + name: Identifier( + name: test2 + ) params: array( ) - returnType: array + returnType: Identifier( + name: array + ) stmts: array( ) ) 2: Stmt_Function( byRef: false - name: test3 + name: Identifier( + name: test3 + ) params: array( ) - returnType: callable + returnType: Identifier( + name: callable + ) stmts: array( ) ) 3: Stmt_Function( byRef: false - name: test4 + name: Identifier( + name: test4 + ) params: array( ) returnType: Name( @@ -49,4 +61,4 @@ array( stmts: array( ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/specialVars.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/specialVars.test index f2f35acf4..10a9e0796 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/specialVars.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/specialVars.test @@ -10,7 +10,9 @@ function a() { array( 0: Stmt_Function( byRef: false - name: a + name: Identifier( + name: a + ) params: array( ) returnType: null @@ -35,11 +37,15 @@ array( 1: Stmt_Static( vars: array( 0: Stmt_StaticVar( - name: c + var: Expr_Variable( + name: c + ) default: null ) 1: Stmt_StaticVar( - name: d + var: Expr_Variable( + name: d + ) default: Scalar_String( value: e ) @@ -48,4 +54,4 @@ array( ) ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/typeDeclarations.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/typeDeclarations.test index 53c462c5a..8327cf32c 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/typeDeclarations.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/typeDeclarations.test @@ -7,27 +7,39 @@ function a($b, array $c, callable $d, E $f) {} array( 0: Stmt_Function( byRef: false - name: a + name: Identifier( + name: a + ) params: array( 0: Param( type: null byRef: false variadic: false - name: b + var: Expr_Variable( + name: b + ) default: null ) 1: Param( - type: array + type: Identifier( + name: array + ) byRef: false variadic: false - name: c + var: Expr_Variable( + name: c + ) default: null ) 2: Param( - type: callable + type: Identifier( + name: callable + ) byRef: false variadic: false - name: d + var: Expr_Variable( + name: d + ) default: null ) 3: Param( @@ -38,7 +50,9 @@ array( ) byRef: false variadic: false - name: f + var: Expr_Variable( + name: f + ) default: null ) ) @@ -46,4 +60,4 @@ array( stmts: array( ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/variadic.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/variadic.test index f9d848c7d..afbcf68fb 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/variadic.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/variadic.test @@ -9,20 +9,26 @@ function test($a, Type &... $b) {} array( 0: Stmt_Function( byRef: false - name: test + name: Identifier( + name: test + ) params: array( 0: Param( type: null byRef: false variadic: false - name: a + var: Expr_Variable( + name: a + ) default: null ) 1: Param( type: null byRef: false variadic: true - name: b + var: Expr_Variable( + name: b + ) default: null ) ) @@ -32,20 +38,26 @@ array( ) 1: Stmt_Function( byRef: false - name: test + name: Identifier( + name: test + ) params: array( 0: Param( type: null byRef: false variadic: false - name: a + var: Expr_Variable( + name: a + ) default: null ) 1: Param( type: null byRef: true variadic: true - name: b + var: Expr_Variable( + name: b + ) default: null ) ) @@ -55,13 +67,17 @@ array( ) 2: Stmt_Function( byRef: false - name: test + name: Identifier( + name: test + ) params: array( 0: Param( type: null byRef: false variadic: false - name: a + var: Expr_Variable( + name: a + ) default: null ) 1: Param( @@ -72,7 +88,9 @@ array( ) byRef: false variadic: true - name: b + var: Expr_Variable( + name: b + ) default: null ) ) @@ -82,13 +100,17 @@ array( ) 3: Stmt_Function( byRef: false - name: test + name: Identifier( + name: test + ) params: array( 0: Param( type: null byRef: false variadic: false - name: a + var: Expr_Variable( + name: a + ) default: null ) 1: Param( @@ -99,7 +121,9 @@ array( ) byRef: true variadic: true - name: b + var: Expr_Variable( + name: b + ) default: null ) ) @@ -107,4 +131,4 @@ array( stmts: array( ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/variadicDefaultValue.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/variadicDefaultValue.test index 0c3714f21..0431f39ac 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/function/variadicDefaultValue.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/function/variadicDefaultValue.test @@ -7,13 +7,17 @@ Variadic parameter cannot have a default value from 2:24 to 2:25 array( 0: Stmt_Function( byRef: false - name: foo + name: Identifier( + name: foo + ) params: array( 0: Param( type: null byRef: false variadic: true - name: foo + var: Expr_Variable( + name: foo + ) default: Expr_Array( items: array( ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/basic.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/basic.test index 8a184aaf6..78ea9c09e 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/basic.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/basic.test @@ -34,51 +34,26 @@ function gen() { array( 0: Stmt_Function( byRef: false - name: gen + name: Identifier( + name: gen + ) params: array( ) returnType: null stmts: array( - 0: Expr_Yield( - key: null - value: null - comments: array( - 0: // statements - ) - ) - 1: Expr_Yield( - key: null - value: Expr_Variable( - name: value - ) - ) - 2: Expr_Yield( - key: Expr_Variable( - name: key - ) - value: Expr_Variable( - name: value - ) - ) - 3: Expr_Assign( - var: Expr_Variable( - name: data - comments: array( - 0: // expressions - ) - ) + 0: Stmt_Expression( expr: Expr_Yield( key: null value: null + comments: array( + 0: // statements + ) ) comments: array( - 0: // expressions + 0: // statements ) ) - 4: Expr_Assign( - var: Expr_Variable( - name: data - ) + 1: Stmt_Expression( expr: Expr_Yield( key: null value: Expr_Variable( @@ -86,10 +61,7 @@ array( ) ) ) - 5: Expr_Assign( - var: Expr_Variable( - name: data - ) + 2: Stmt_Expression( expr: Expr_Yield( key: Expr_Variable( name: key @@ -99,6 +71,54 @@ array( ) ) ) + 3: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: data + comments: array( + 0: // expressions + ) + ) + expr: Expr_Yield( + key: null + value: null + ) + comments: array( + 0: // expressions + ) + ) + comments: array( + 0: // expressions + ) + ) + 4: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: data + ) + expr: Expr_Yield( + key: null + value: Expr_Variable( + name: value + ) + ) + ) + ) + 5: Stmt_Expression( + expr: Expr_Assign( + var: Expr_Variable( + name: data + ) + expr: Expr_Yield( + key: Expr_Variable( + name: key + ) + value: Expr_Variable( + name: value + ) + ) + ) + ) 6: Stmt_If( cond: Expr_Yield( key: null @@ -159,14 +179,14 @@ array( ) ) 9: Stmt_Do( + stmts: array( + ) cond: Expr_Yield( key: null value: Expr_Variable( name: foo ) ) - stmts: array( - ) ) 10: Stmt_Switch( cond: Expr_Yield( @@ -178,100 +198,119 @@ array( cases: array( ) ) - 11: Expr_Exit( - expr: Expr_Yield( - key: null - value: Expr_Variable( - name: foo + 11: Stmt_Expression( + expr: Expr_Exit( + expr: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) ) ) ) - 12: Expr_FuncCall( - name: Name( - parts: array( - 0: func - ) - comments: array( - 0: // yield in function calls + 12: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: func + ) + comments: array( + 0: // yield in function calls + ) ) - ) - args: array( - 0: Arg( - value: Expr_Yield( - key: null - value: Expr_Variable( - name: foo + args: array( + 0: Arg( + value: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) ) + byRef: false + unpack: false ) - byRef: false - unpack: false + ) + comments: array( + 0: // yield in function calls ) ) comments: array( 0: // yield in function calls ) ) - 13: Expr_MethodCall( - var: Expr_Variable( - name: foo - ) - name: func - args: array( - 0: Arg( - value: Expr_Yield( - key: null - value: Expr_Variable( - name: foo + 13: Stmt_Expression( + expr: Expr_MethodCall( + var: Expr_Variable( + name: foo + ) + name: Identifier( + name: func + ) + args: array( + 0: Arg( + value: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) - 14: Expr_New( - class: Name( - parts: array( - 0: Foo + 14: Stmt_Expression( + expr: Expr_New( + class: Name( + parts: array( + 0: Foo + ) ) - ) - args: array( - 0: Arg( - value: Expr_Yield( - key: null - value: Expr_Variable( - name: foo + args: array( + 0: Arg( + value: Expr_Yield( + key: null + value: Expr_Variable( + name: foo + ) ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) - 15: Expr_YieldFrom( - expr: Expr_Variable( - name: foo - ) - ) - 16: Expr_BinaryOp_LogicalAnd( - left: Expr_YieldFrom( + 15: Stmt_Expression( + expr: Expr_YieldFrom( expr: Expr_Variable( name: foo ) ) - right: Expr_YieldFrom( - expr: Expr_Variable( - name: bar + ) + 16: Stmt_Expression( + expr: Expr_BinaryOp_LogicalAnd( + left: Expr_YieldFrom( + expr: Expr_Variable( + name: foo + ) + ) + right: Expr_YieldFrom( + expr: Expr_Variable( + name: bar + ) ) ) ) - 17: Expr_YieldFrom( - expr: Expr_BinaryOp_Plus( - left: Expr_Variable( - name: foo - ) - right: Expr_Variable( - name: bar + 17: Stmt_Expression( + expr: Expr_YieldFrom( + expr: Expr_BinaryOp_Plus( + left: Expr_Variable( + name: foo + ) + right: Expr_Variable( + name: bar + ) ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldPrecedence.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldPrecedence.test index ff0d4df08..1f843c314 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldPrecedence.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldPrecedence.test @@ -18,213 +18,233 @@ function gen() { array( 0: Stmt_Function( byRef: false - name: gen + name: Identifier( + name: gen + ) params: array( ) returnType: null stmts: array( - 0: Expr_Yield( - key: null - value: Expr_BinaryOp_Concat( - left: Scalar_String( - value: a - ) - right: Scalar_String( - value: b - ) - ) - ) - 1: Expr_BinaryOp_LogicalOr( - left: Expr_Yield( + 0: Stmt_Expression( + expr: Expr_Yield( key: null - value: Scalar_String( - value: a + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) ) ) - right: Expr_Exit( - expr: null - ) ) - 2: Expr_Yield( - key: Scalar_String( - value: k - ) - value: Expr_BinaryOp_Concat( - left: Scalar_String( - value: a + 1: Stmt_Expression( + expr: Expr_BinaryOp_LogicalOr( + left: Expr_Yield( + key: null + value: Scalar_String( + value: a + ) ) - right: Scalar_String( - value: b + right: Expr_Exit( + expr: null ) ) ) - 3: Expr_BinaryOp_LogicalOr( - left: Expr_Yield( + 2: Stmt_Expression( + expr: Expr_Yield( key: Scalar_String( value: k ) - value: Scalar_String( - value: a + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) ) ) - right: Expr_Exit( - expr: null - ) ) - 4: Expr_FuncCall( - name: Name( - parts: array( - 0: var_dump + 3: Stmt_Expression( + expr: Expr_BinaryOp_LogicalOr( + left: Expr_Yield( + key: Scalar_String( + value: k + ) + value: Scalar_String( + value: a + ) + ) + right: Expr_Exit( + expr: null ) ) - args: array( - 0: Arg( - value: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Yield( - key: Scalar_String( - value: k - ) - value: Expr_BinaryOp_Concat( - left: Scalar_String( - value: a + ) + 4: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: var_dump + ) + ) + args: array( + 0: Arg( + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null + value: Expr_Yield( + key: Scalar_String( + value: k ) - right: Scalar_String( - value: b + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) ) ) + byRef: false ) - byRef: false ) ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) - 5: Expr_Yield( - key: null - value: Expr_Yield( - key: Scalar_String( - value: k1 - ) + 5: Stmt_Expression( + expr: Expr_Yield( + key: null value: Expr_Yield( key: Scalar_String( - value: k2 + value: k1 ) - value: Expr_BinaryOp_Concat( - left: Scalar_String( - value: a + value: Expr_Yield( + key: Scalar_String( + value: k2 ) - right: Scalar_String( - value: b + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) ) ) ) ) ) - 6: Expr_Yield( - key: Expr_Yield( - key: Scalar_String( - value: k1 - ) - value: Expr_Yield( - key: null - value: Scalar_String( - value: k2 + 6: Stmt_Expression( + expr: Expr_Yield( + key: Expr_Yield( + key: Scalar_String( + value: k1 + ) + value: Expr_Yield( + key: null + value: Scalar_String( + value: k2 + ) ) ) - ) - value: Expr_BinaryOp_Concat( - left: Scalar_String( - value: a - ) - right: Scalar_String( - value: b + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) ) ) ) - 7: Expr_FuncCall( - name: Name( - parts: array( - 0: var_dump + 7: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: var_dump + ) ) - ) - args: array( - 0: Arg( - value: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: null - value: Expr_Yield( - key: Scalar_String( - value: k1 - ) + args: array( + 0: Arg( + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: null value: Expr_Yield( key: Scalar_String( - value: k2 + value: k1 ) - value: Expr_BinaryOp_Concat( - left: Scalar_String( - value: a + value: Expr_Yield( + key: Scalar_String( + value: k2 ) - right: Scalar_String( - value: b + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) ) ) ) + byRef: false ) - byRef: false ) ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) - 8: Expr_FuncCall( - name: Name( - parts: array( - 0: var_dump + 8: Stmt_Expression( + expr: Expr_FuncCall( + name: Name( + parts: array( + 0: var_dump + ) ) - ) - args: array( - 0: Arg( - value: Expr_Array( - items: array( - 0: Expr_ArrayItem( - key: Expr_Yield( - key: Scalar_String( - value: k1 - ) - value: Expr_Yield( - key: null - value: Scalar_String( - value: k2 + args: array( + 0: Arg( + value: Expr_Array( + items: array( + 0: Expr_ArrayItem( + key: Expr_Yield( + key: Scalar_String( + value: k1 + ) + value: Expr_Yield( + key: null + value: Scalar_String( + value: k2 + ) ) ) - ) - value: Expr_BinaryOp_Concat( - left: Scalar_String( - value: a - ) - right: Scalar_String( - value: b + value: Expr_BinaryOp_Concat( + left: Scalar_String( + value: a + ) + right: Scalar_String( + value: b + ) ) + byRef: false ) - byRef: false ) ) + byRef: false + unpack: false ) - byRef: false - unpack: false ) ) ) ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldUnaryPrecedence.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldUnaryPrecedence.test index 13f96602c..6b77d3357 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldUnaryPrecedence.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/generator/yieldUnaryPrecedence.test @@ -11,38 +11,46 @@ function gen() { array( 0: Stmt_Function( byRef: false - name: gen + name: Identifier( + name: gen + ) params: array( ) returnType: null stmts: array( - 0: Expr_Yield( - key: null - value: Expr_UnaryPlus( - expr: Scalar_LNumber( - value: 1 + 0: Stmt_Expression( + expr: Expr_Yield( + key: null + value: Expr_UnaryPlus( + expr: Scalar_LNumber( + value: 1 + ) ) ) ) - 1: Expr_Yield( - key: null - value: Expr_UnaryMinus( - expr: Scalar_LNumber( - value: 1 + 1: Stmt_Expression( + expr: Expr_Yield( + key: null + value: Expr_UnaryMinus( + expr: Scalar_LNumber( + value: 1 + ) ) ) ) - 2: Expr_BinaryOp_Mul( - left: Expr_Yield( - key: null - value: null - ) - right: Expr_UnaryMinus( - expr: Scalar_LNumber( - value: 1 + 2: Stmt_Expression( + expr: Expr_BinaryOp_Mul( + left: Expr_Yield( + key: null + value: null + ) + right: Expr_UnaryMinus( + expr: Scalar_LNumber( + value: 1 + ) ) ) ) ) ) -) +) \ No newline at end of file diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/haltCompiler.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/haltCompiler.test index 67133ba74..112946ea7 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/haltCompiler.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/haltCompiler.test @@ -8,8 +8,10 @@ __halt_compiler() Hallo World! ----- array( - 0: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Variable( + name: a + ) ) 1: Stmt_HaltCompiler( remaining: Hallo World! @@ -22,8 +24,10 @@ $a; __halt_compiler();Hallo World! ----- array( - 0: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Variable( + name: a + ) ) 1: Stmt_HaltCompiler( remaining: Hallo World! @@ -44,8 +48,10 @@ array( ) ) stmts: array( - 0: Expr_Variable( - name: a + 0: Stmt_Expression( + expr: Expr_Variable( + name: a + ) ) ) ) diff --git a/app/vendor/nikic/php-parser/test/code/parser/stmt/haltCompilerInvalidSyntax.test b/app/vendor/nikic/php-parser/test/code/parser/stmt/haltCompilerInvalidSyntax.test index 597710f2d..381019a9b 100644 --- a/app/vendor/nikic/php-parser/test/code/parser/stmt/haltCompilerInvalidSyntax.test +++ b/app/vendor/nikic/php-parser/test/code/parser/stmt/haltCompilerInvalidSyntax.test @@ -3,4 +3,4 @@ Invalid __halt_compiler() syntax +Test + +Test + $code) { + if (false !== strpos($code, '@@{')) { + // Skip tests with evaluate segments + continue; + } + + list($name, $tests) = $testParser->parseTest($code, 2); + $newTests = []; + foreach ($tests as list($modeLine, list($input, $expected))) { + $modes = null !== $modeLine ? array_fill_keys(explode(',', $modeLine), true) : []; + list($parser5, $parser7) = $codeParsingTest->createParsers($modes); + list(, $output) = isset($modes['php5']) + ? $codeParsingTest->getParseOutput($parser5, $input, $modes) + : $codeParsingTest->getParseOutput($parser7, $input, $modes); + $newTests[] = [$modeLine, [$input, $output]]; + } + + $newCode = $testParser->reconstructTest($name, $newTests); + file_put_contents($fileName, $newCode); +} diff --git a/app/vendor/nikic/php-parser/test_old/run.php b/app/vendor/nikic/php-parser/test_old/run.php index bc14d893a..2d7cdaccb 100644 --- a/app/vendor/nikic/php-parser/test_old/run.php +++ b/app/vendor/nikic/php-parser/test_old/run.php @@ -110,17 +110,24 @@ function showHelp($error) { showHelp('Test type must be one of: PHP5, PHP7 or Symfony'); } -require_once dirname(__FILE__) . '/../lib/PhpParser/Autoloader.php'; -PhpParser\Autoloader::register(); - -$parserName = 'PhpParser\Parser\\' . $version; -$parser = new $parserName(new PhpParser\Lexer\Emulative); +require_once __DIR__ . '/../vendor/autoload.php'; + +$lexer = new PhpParser\Lexer\Emulative(['usedAttributes' => [ + 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', +]]); +$parserName = 'PhpParser\Parser\\' . $version; +/** @var PhpParser\Parser $parser */ +$parser = new $parserName($lexer); $prettyPrinter = new PhpParser\PrettyPrinter\Standard; -$nodeDumper = new PhpParser\NodeDumper; +$nodeDumper = new PhpParser\NodeDumper; + +$cloningTraverser = new PhpParser\NodeTraverser; +$cloningTraverser->addVisitor(new PhpParser\NodeVisitor\CloningVisitor); -$parseFail = $ppFail = $compareFail = $count = 0; +$parseFail = $fpppFail = $ppFail = $compareFail = $count = 0; -$readTime = $parseTime = $ppTime = $reparseTime = $compareTime = 0; +$readTime = $parseTime = $cloneTime = 0; +$fpppTime = $ppTime = $reparseTime = $compareTime = 0; $totalStartTime = microtime(true); foreach (new RecursiveIteratorIterator( @@ -132,10 +139,10 @@ function showHelp($error) { } $startTime = microtime(true); - $code = file_get_contents($file); + $origCode = file_get_contents($file); $readTime += microtime(true) - $startTime; - if (null === $code = $codeExtractor($file, $code)) { + if (null === $origCode = $codeExtractor($file, $origCode)) { continue; } @@ -149,11 +156,30 @@ function showHelp($error) { try { $startTime = microtime(true); - $stmts = $parser->parse($code); + $origStmts = $parser->parse($origCode); $parseTime += microtime(true) - $startTime; + $origTokens = $lexer->getTokens(); + $startTime = microtime(true); - $code = 'prettyPrint($stmts); + $stmts = $cloningTraverser->traverse($origStmts); + $cloneTime += microtime(true) - $startTime; + + $startTime = microtime(true); + $code = $prettyPrinter->printFormatPreserving($stmts, $origStmts, $origTokens); + $fpppTime += microtime(true) - $startTime; + + if ($code !== $origCode) { + echo $file, ":\n Result of format-preserving pretty-print differs\n"; + if ($verbose) { + echo "FPPP output:\n=====\n$code\n=====\n\n"; + } + + ++$fpppFail; + } + + $startTime = microtime(true); + $code = "prettyPrint($stmts); $ppTime += microtime(true) - $startTime; try { @@ -200,6 +226,9 @@ function showHelp($error) { if (0 !== $ppFail) { echo ' ', $ppFail, ' pretty print failures.', "\n"; } + if (0 !== $fpppFail) { + echo ' ', $fpppFail, ' FPPP failures.', "\n"; + } if (0 !== $compareFail) { echo ' ', $compareFail, ' compare failures.', "\n"; } @@ -210,6 +239,8 @@ function showHelp($error) { "\n", 'Reading files took: ', $readTime, "\n", 'Parsing took: ', $parseTime, "\n", + 'Cloning took: ', $cloneTime, "\n", + 'FPPP took: ', $fpppTime, "\n", 'Pretty printing took: ', $ppTime, "\n", 'Reparsing took: ', $reparseTime, "\n", 'Comparing took: ', $compareTime, "\n", diff --git a/app/vendor/psy/psysh/.editorconfig b/app/vendor/psy/psysh/.editorconfig index 779f99a12..fddf9c1c6 100644 --- a/app/vendor/psy/psysh/.editorconfig +++ b/app/vendor/psy/psysh/.editorconfig @@ -10,3 +10,6 @@ insert_final_newline = true [*.md] trim_trailing_whitespace = false + +[Makefile] +indent_style = tab diff --git a/app/vendor/psy/psysh/.github/CONTRIBUTING.md b/app/vendor/psy/psysh/.github/CONTRIBUTING.md new file mode 100644 index 000000000..efb87446c --- /dev/null +++ b/app/vendor/psy/psysh/.github/CONTRIBUTING.md @@ -0,0 +1,9 @@ +## Code style + +Please make your code look like the other code in the project. + +PsySH follows [PSR-1](http://php-fig.org/psr/psr-1/) and [PSR-2](http://php-fig.org/psr/psr-2/). The easiest way to do make sure you're following the coding standard is to [install `php-cs-fixer`](https://github.com/friendsofphp/php-cs-fixer) and run `php-cs-fixer fix` before committing. + +## Branching model + +Please branch off and send pull requests to the `develop` branch. diff --git a/app/vendor/psy/psysh/.gitignore b/app/vendor/psy/psysh/.gitignore index d4300e2bb..da05f58cb 100644 --- a/app/vendor/psy/psysh/.gitignore +++ b/app/vendor/psy/psysh/.gitignore @@ -1,11 +1,9 @@ -build-vendor/ -vendor/ -composer.lock -composer-compat.json -composer-compat.lock -manual/ -dist/ -__pycache__ -.php_cs.cache -psysh.phar -psysh-compat.phar +/build/ +/dist/ +/composer.lock +/manual/ +/psysh +/__pycache__ +/.php_cs.cache +/vendor/ +/vendor-bin/*/vendor/ diff --git a/app/vendor/psy/psysh/.php_cs b/app/vendor/psy/psysh/.php_cs index 94e2ce165..421c31d2a 100644 --- a/app/vendor/psy/psysh/.php_cs +++ b/app/vendor/psy/psysh/.php_cs @@ -10,7 +10,7 @@ $finder = PhpCsFixer\Finder::create() $header = <<setRules(array( '@Symfony' => true, - 'array_syntax' => array('syntax' => 'long'), + 'array_syntax' => array('syntax' => 'short'), 'binary_operator_spaces' => false, 'concat_space' => array('spacing' => 'one'), 'header_comment' => array('header' => $header), diff --git a/app/vendor/psy/psysh/.styleci.yml b/app/vendor/psy/psysh/.styleci.yml index 27a247ed2..96fc96bf4 100644 --- a/app/vendor/psy/psysh/.styleci.yml +++ b/app/vendor/psy/psysh/.styleci.yml @@ -3,7 +3,7 @@ preset: symfony enabled: - align_double_arrow - concat_with_spaces - - long_array_syntax + - short_array_syntax - ordered_use - strict @@ -18,6 +18,8 @@ disabled: - unalign_double_arrow - unalign_equals - yoda_style + - property_separation + - const_separation finder: name: diff --git a/app/vendor/psy/psysh/.travis.yml b/app/vendor/psy/psysh/.travis.yml index 20277ef97..3a77512aa 100644 --- a/app/vendor/psy/psysh/.travis.yml +++ b/app/vendor/psy/psysh/.travis.yml @@ -4,23 +4,32 @@ sudo: false matrix: include: - - php: 5.3 - dist: precise - php: 5.4 + - php: 5.4 + env: 'COMPOSER_FLAGS="--prefer-lowest --prefer-stable"' - php: 5.5 - php: 5.6 - php: 7.0 - php: 7.1 + - php: 7.2 - php: hhvm dist: trusty allow_failures: + - php: 5.4 + env: 'COMPOSER_FLAGS="--prefer-lowest --prefer-stable"' - php: hhvm + fast_finish: true + +install: travis_retry composer update --no-interaction $COMPOSER_FLAGS -install: travis_retry composer update --no-interaction +script: + - vendor/bin/phpunit --verbose --coverage-clover=coverage.xml + - '[[ $TRAVIS_PHP_VERSION = 7.2* ]] && make build -j 4 || true' -script: vendor/bin/phpunit --verbose +after_success: + - bash <(curl -s https://codecov.io/bash) -before_deploy: bin/package -v $TRAVIS_TAG +before_deploy: make dist -j 4 deploy: provider: releases @@ -32,4 +41,4 @@ deploy: on: tags: true repo: bobthecow/psysh - condition: ($TRAVIS_PHP_VERSION = 5.3* || $TRAVIS_PHP_VERSION = 7.0*) + condition: $TRAVIS_PHP_VERSION = 7.2* diff --git a/app/vendor/psy/psysh/CONTRIBUTING.md b/app/vendor/psy/psysh/CONTRIBUTING.md deleted file mode 100644 index a5c726ba2..000000000 --- a/app/vendor/psy/psysh/CONTRIBUTING.md +++ /dev/null @@ -1,18 +0,0 @@ -## Code style - -Please make your code look like the other code in the project. PsySH follows [PSR-1](http://php-fig.org/psr/psr-1/) and [PSR-2](http://php-fig.org/psr/psr-2/). The easiest way to do make sure you're following the coding standard is to run `vendor/bin/php-cs-fixer fix` before committing. - -## Branching model - -Please branch off and send pull requests to the `develop` branch. - -## Building the manual - -```sh -svn co https://svn.php.net/repository/phpdoc/en/trunk/reference/ php_manual -bin/build_manual phpdoc_manual ~/.local/share/psysh/php_manual.sqlite -``` - -To build the manual for another language, switch out `en` above for `de`, `es`, or any of the other languages listed in the docs. - -[Partial or outdated documentation is available for other languages](http://www.php.net/manual/help-translate.php) but these translations are outdated, so their content may be completely wrong or insecure! diff --git a/app/vendor/psy/psysh/LICENSE b/app/vendor/psy/psysh/LICENSE index fdd27fb73..2c6a45137 100644 --- a/app/vendor/psy/psysh/LICENSE +++ b/app/vendor/psy/psysh/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2012-2017 Justin Hileman +Copyright (c) 2012-2018 Justin Hileman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/app/vendor/psy/psysh/Makefile b/app/vendor/psy/psysh/Makefile new file mode 100644 index 000000000..a1fdb42ed --- /dev/null +++ b/app/vendor/psy/psysh/Makefile @@ -0,0 +1,95 @@ +PSYSH_SRC = bin src box.json.dist composer.json build/stub +PSYSH_SRC_FILES = $(shell find src -type f -name "*.php") +VERSION = $(shell git describe --tag --always --dirty=-dev) + +COMPOSER_OPTS = --no-interaction --no-progress --verbose +COMPOSER_REQUIRE_OPTS = $(COMPOSER_OPTS) --no-update +COMPOSER_UPDATE_OPTS = $(COMPOSER_OPTS) --prefer-stable --no-dev --classmap-authoritative --prefer-dist + + +# Commands + +.PHONY: help clean build dist +.DEFAULT_GOAL := help + +help: + @echo "\033[33mUsage:\033[0m\n make TARGET\n\n\033[33mTargets:\033[0m" + @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[32m%-7s\033[0m %s\n", $$1, $$2}' + +clean: ## Clean all created artifacts + rm -rf build/* + rm -rf dist/* + rm -rf vendor-bin/*/vendor/ + +build: ## Compile PHARs +build: build/psysh/psysh build/psysh-compat/psysh build/psysh-php54/psysh build/psysh-php54-compat/psysh + +dist: ## Build tarballs for distribution +dist: dist/psysh-$(VERSION).tar.gz dist/psysh-$(VERSION)-compat.tar.gz dist/psysh-$(VERSION)-php54.tar.gz dist/psysh-$(VERSION)-php54-compat.tar.gz + + +# All the composer stuffs + +composer.lock: composer.json + composer install + touch $@ + +vendor/autoload.php: composer.lock + composer install + touch $@ + +vendor/bin/box: vendor/autoload.php + composer bin box install + touch $@ + + +# Lots of PHARs + +build/stub: bin/build-stub bin/psysh LICENSE + bin/build-stub + +build/psysh: $(PSYSH_SRC) $(PSYSH_SRC_FILES) + rm -rf $@ || true + mkdir $@ + cp -R $(PSYSH_SRC) $@/ + composer config --working-dir $@ platform.php 7.0 + composer require --working-dir $@ $(COMPOSER_REQUIRE_OPTS) php:'>=7.0.0' + composer update --working-dir $@ $(COMPOSER_UPDATE_OPTS) + +build/psysh-compat: $(PSYSH_SRC) $(PSYSH_SRC_FILES) + rm -rf $@ || true + mkdir $@ + cp -R $(PSYSH_SRC) $@/ + composer config --working-dir $@ platform.php 7.0 + composer require --working-dir $@ $(COMPOSER_REQUIRE_OPTS) php:'>=7.0.0' + composer require --working-dir $@ $(COMPOSER_REQUIRE_OPTS) symfony/polyfill-iconv symfony/polyfill-mbstring hoa/console + composer update --working-dir $@ $(COMPOSER_UPDATE_OPTS) + +build/psysh-php54: $(PSYSH_SRC) $(PSYSH_SRC_FILES) + rm -rf $@ || true + mkdir $@ + cp -R $(PSYSH_SRC) $@/ + composer config --working-dir $@ platform.php 5.4 + composer update --working-dir $@ $(COMPOSER_UPDATE_OPTS) + +build/psysh-php54-compat: $(PSYSH_SRC) $(PSYSH_SRC_FILES) + rm -rf $@ || true + mkdir $@ + cp -R $(PSYSH_SRC) $@/ + composer config --working-dir $@ platform.php 5.4 + composer require --working-dir $@ $(COMPOSER_REQUIRE_OPTS) symfony/polyfill-iconv symfony/polyfill-mbstring hoa/console:^2.15 + composer update --working-dir $@ $(COMPOSER_UPDATE_OPTS) + +build/%/psysh: vendor/bin/box build/% + vendor/bin/box compile --working-dir $(dir $@) + + +# Dist packages + +dist/psysh-$(VERSION).tar.gz: build/psysh/psysh + @mkdir -p $(@D) + tar -C $(dir $<) -czf $@ $(notdir $<) + +dist/psysh-$(VERSION)-%.tar.gz: build/psysh-%/psysh + @mkdir -p $(@D) + tar -C $(dir $<) -czf $@ $(notdir $<) diff --git a/app/vendor/psy/psysh/README.md b/app/vendor/psy/psysh/README.md index 45dd6a3b2..710434caf 100644 --- a/app/vendor/psy/psysh/README.md +++ b/app/vendor/psy/psysh/README.md @@ -17,6 +17,7 @@ PsySH is a runtime developer console, interactive debugger and [REPL](https://en ### [💾 Installation](https://github.com/bobthecow/psysh/wiki/Installation) * [📕 PHP manual installation](https://github.com/bobthecow/psysh/wiki/PHP-manual) + * Windows ### [🖥 Usage](https://github.com/bobthecow/psysh/wiki/Usage) * [✨ Magic variables](https://github.com/bobthecow/psysh/wiki/Magic-variables) diff --git a/app/vendor/psy/psysh/bin/build b/app/vendor/psy/psysh/bin/build deleted file mode 100755 index 79f2192b2..000000000 --- a/app/vendor/psy/psysh/bin/build +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd "${BASH_SOURCE%/*}/.." - -echo "Building phar" -./bin/build-vendor -php -d 'phar.readonly=0' ./bin/build-phar - -echo "Building compat phar" -./bin/build-vendor-compat -php -d 'phar.readonly=0' ./bin/build-phar --compat diff --git a/app/vendor/psy/psysh/bin/build-manual b/app/vendor/psy/psysh/bin/build-manual deleted file mode 100755 index ece227817..000000000 --- a/app/vendor/psy/psysh/bin/build-manual +++ /dev/null @@ -1,312 +0,0 @@ -#!/usr/bin/env php -': - $inTag = false; - break; - } - - if ($inTag) { - $tagWidth++; - } - - $i++; - - if (!$inTag && ($i - $tagWidth > $width)) { - $lastSpace = $lastSpace ?: $width; - - $return[] = trim(substr($text, 0, $lastSpace)); - $text = substr($text, $lastSpace); - $len = strlen($text); - - $i = $tagWidth = 0; - } - } while ($i < $len); - - $return[] = trim($text); - - return implode("\n", $return); -} - -function extract_paragraphs($element) -{ - $paragraphs = array(); - foreach ($element->getElementsByTagName('para') as $p) { - $text = ''; - foreach ($p->childNodes as $child) { - // @todo figure out if there's something we can do with tables. - if ($child instanceof DOMElement && $child->tagName === 'table') { - continue; - } - - // skip references, because ugh. - if (preg_match('{^\s*&[a-z][a-z\.]+;\s*$}', $child->textContent)) { - continue; - } - - $text .= $child->ownerDocument->saveXML($child); - } - - if ($text = trim(preg_replace('{\n[ \t]+}', ' ', $text))) { - $paragraphs[] = $text; - } - } - - return implode("\n\n", $paragraphs); -} - -function format_doc($doc) -{ - $chunks = array(); - - if (!empty($doc['description'])) { - $chunks[] = 'Description:'; - $chunks[] = indent_text(htmlwrap(thunk_tags($doc['description']), WRAP_WIDTH - 2)); - $chunks[] = ''; - } - - if (!empty($doc['params'])) { - $chunks[] = 'Param:'; - - $typeMax = max(array_map(function ($param) { - return strlen($param['type']); - }, $doc['params'])); - - $max = max(array_map(function ($param) { - return strlen($param['name']); - }, $doc['params'])); - - $template = ' %-' . $typeMax . 's %-' . $max . 's %s'; - $indent = str_repeat(' ', $typeMax + $max + 6); - $wrapWidth = WRAP_WIDTH - strlen($indent); - - foreach ($doc['params'] as $param) { - $desc = indent_text(htmlwrap(thunk_tags($param['description']), $wrapWidth), $indent, false); - $chunks[] = sprintf($template, $param['type'], $param['name'], $desc); - } - $chunks[] = ''; - } - - if (isset($doc['return']) || isset($doc['return_type'])) { - $chunks[] = 'Return:'; - - $type = isset($doc['return_type']) ? $doc['return_type'] : 'unknown'; - $desc = isset($doc['return']) ? $doc['return'] : ''; - - $indent = str_repeat(' ', strlen($type) + 4); - $wrapWidth = WRAP_WIDTH - strlen($indent); - - if (!empty($desc)) { - $desc = indent_text(htmlwrap(thunk_tags($doc['return']), $wrapWidth), $indent, false); - } - - $chunks[] = sprintf(' %s %s', $type, $desc); - $chunks[] = ''; - } - - array_pop($chunks); // get rid of the trailing newline - - return implode("\n", $chunks); -} - -function thunk_tags($text) -{ - $tagMap = array( - 'parameter>' => 'strong>', - 'function>' => 'strong>', - 'literal>' => 'return>', - 'type>' => 'info>', - 'constant>' => 'info>', - ); - - $andBack = array( - '&' => '&', - '&true;' => 'true', - '&false;' => 'false', - '&null;' => 'null', - ); - - return strtr(strip_tags(strtr($text, $tagMap), ''), $andBack); -} - -function indent_text($text, $indent = ' ', $leading = true) -{ - return ($leading ? $indent : '') . str_replace("\n", "\n" . $indent, $text); -} - -function find_type($xml, $paramName) -{ - foreach ($xml->getElementsByTagName('methodparam') as $param) { - if ($type = $param->getElementsByTagName('type')->item(0)) { - if ($parameter = $param->getElementsByTagName('parameter')->item(0)) { - if ($paramName === $parameter->textContent) { - return $type->textContent; - } - } - } - } -} - -function format_function_doc($xml) -{ - $doc = array(); - $refsect1s = $xml->getElementsByTagName('refsect1'); - foreach ($refsect1s as $refsect1) { - $role = $refsect1->getAttribute('role'); - switch ($role) { - case 'description': - $doc['description'] = extract_paragraphs($refsect1); - - if ($synopsis = $refsect1->getElementsByTagName('methodsynopsis')->item(0)) { - foreach ($synopsis->childNodes as $node) { - if ($node instanceof DOMElement && $node->tagName === 'type') { - $doc['return_type'] = $node->textContent; - break; - } - } - } - break; - - case 'returnvalues': - // do nothing. - $doc['return'] = extract_paragraphs($refsect1); - break; - - case 'parameters': - $params = array(); - $vars = $refsect1->getElementsByTagName('varlistentry'); - foreach ($vars as $var) { - if ($name = $var->getElementsByTagName('parameter')->item(0)) { - $params[] = array( - 'name' => '$' . $name->textContent, - 'type' => find_type($xml, $name->textContent), - 'description' => extract_paragraphs($var), - ); - } - } - - $doc['params'] = $params; - break; - } - } - - // and the purpose - if ($purpose = $xml->getElementsByTagName('refpurpose')->item(0)) { - $desc = htmlwrap($purpose->textContent); - if (isset($doc['description'])) { - $desc .= "\n\n" . $doc['description']; - } - - $doc['description'] = trim($desc); - } - - $ids = array(); - foreach ($xml->getElementsByTagName('refname') as $ref) { - $ids[] = $ref->textContent; - } - - return array($ids, format_doc($doc)); -} - -function format_class_doc($xml) -{ - // @todo implement this - return array(array(), null); -} - -$dir = new RecursiveDirectoryIterator($argv[1]); -$filter = new RecursiveCallbackFilterIterator($dir, function ($current, $key, $iterator) { - return $current->getFilename()[0] !== '.' && - ($current->isDir() || $current->getExtension() === 'xml') && - strpos($current->getFilename(), 'entities.') !== 0 && - $current->getFilename() !== 'pdo_4d'; // Temporarily blacklist this one, the docs are weird. -}); -$iterator = new RecursiveIteratorIterator($filter); - -$docs = array(); -foreach ($iterator as $file) { - $xmlstr = str_replace('&', '&', file_get_contents($file)); - - $xml = new DOMDocument(); - $xml->preserveWhiteSpace = false; - - if (!@$xml->loadXml($xmlstr)) { - echo "XML Parse Error: $file\n"; - continue; - } - - if ($xml->getElementsByTagName('refentry')->length !== 0) { - list($ids, $doc) = format_function_doc($xml); - } elseif ($xml->getElementsByTagName('classref')->length !== 0) { - list($ids, $doc) = format_class_doc($xml); - } else { - $ids = array(); - $doc = null; - } - - foreach ($ids as $id) { - $docs[$id] = $doc; - } -} - -if (is_file($argv[2])) { - unlink($argv[2]); -} - -$db = new PDO('sqlite:' . $argv[2]); - -$db->query('CREATE TABLE php_manual (id char(256) PRIMARY KEY, doc TEXT)'); -$cmd = $db->prepare('INSERT INTO php_manual (id, doc) VALUES (?, ?)'); -foreach ($docs as $id => $doc) { - $cmd->execute(array($id, $doc)); -} diff --git a/app/vendor/psy/psysh/bin/build-phar b/app/vendor/psy/psysh/bin/build-phar deleted file mode 100755 index 43db2f6b7..000000000 --- a/app/vendor/psy/psysh/bin/build-phar +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env php -compile('psysh-compat.phar'); -} else { - $compiler->compile(); -} diff --git a/app/vendor/psy/psysh/bin/build-stub b/app/vendor/psy/psysh/bin/build-stub new file mode 100755 index 000000000..0d26110ea --- /dev/null +++ b/app/vendor/psy/psysh/bin/build-stub @@ -0,0 +1,22 @@ +#!/usr/bin/env php +>> \*/}sm', $autoload, $content); +$content = preg_replace('/\\(c\\) .*?with this source code./sm', $license, $content); + +$content .= '__HALT_COMPILER();'; + +@mkdir(dirname(__DIR__) . '/build'); + +file_put_contents(dirname(__DIR__) . '/build/stub', $content); diff --git a/app/vendor/psy/psysh/bin/build-vendor b/app/vendor/psy/psysh/bin/build-vendor deleted file mode 100755 index f0057d522..000000000 --- a/app/vendor/psy/psysh/bin/build-vendor +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd "${BASH_SOURCE%/*}/.." - -rm -rf build-vendor - -COMPOSER_VENDOR_DIR=build-vendor composer update \ - --prefer-stable --no-dev --no-progress --classmap-authoritative --no-interaction --verbose diff --git a/app/vendor/psy/psysh/bin/build-vendor-compat b/app/vendor/psy/psysh/bin/build-vendor-compat deleted file mode 100755 index a3cedb592..000000000 --- a/app/vendor/psy/psysh/bin/build-vendor-compat +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd "${BASH_SOURCE%/*}/.." - -rm -rf build-vendor -rm composer*.lock - -cp composer.json composer-compat.json - -if [[ $(php --version) = PHP\ 5.3* ]]; then - HOA_VERSION=^1.14 -fi - -COMPOSER=composer-compat.json COMPOSER_VENDOR_DIR=build-vendor \ - composer require symfony/intl hoa/console $HOA_VERSION --no-progress --no-update --no-interaction --verbose - -COMPOSER=composer-compat.json COMPOSER_VENDOR_DIR=build-vendor \ - composer update --prefer-stable --no-dev --no-progress --classmap-authoritative --no-interaction --verbose - diff --git a/app/vendor/psy/psysh/bin/package b/app/vendor/psy/psysh/bin/package deleted file mode 100755 index 2bb6e411e..000000000 --- a/app/vendor/psy/psysh/bin/package +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/env bash - -set -e - -cd "${BASH_SOURCE%/*}/.." - -USAGE="usage: bin/package [-v PACKAGE_VERSION]" - -while getopts ":v:h" opt; do - case $opt in - v) - PKG_VERSION=$OPTARG - ;; - h) - echo $USAGE >&2 - exit - ;; - \?) - echo "Invalid option: -$OPTARG" >&2 - echo $USAGE >&2 - exit 1 - ;; - :) - echo "Option -$OPTARG requires an argument" >&2 - echo $USAGE >&2 - exit 1 - ;; - esac -done - -if [ -z "$PKG_VERSION" ]; then - PKG_VERSION=$(git describe --tag --exact-match) -fi - -if [[ $(php --version) = PHP\ 5.3* ]]; then - PKG_VERSION=${PKG_VERSION}-php53 -fi - -echo "Packaging $PKG_VERSION" - -mkdir -p dist || exit 1 - -./bin/build || exit 1 -chmod +x *.phar - -echo "Creating tarballs" - -# Support BSD tar because OS X :( -if [[ $(tar --version) = bsdtar* ]]; then - tar -s "/.*/psysh/" -czf dist/psysh-${PKG_VERSION}.tar.gz psysh.phar - tar -s "/.*/psysh/" -czf dist/psysh-${PKG_VERSION}-compat.tar.gz psysh-compat.phar -else - tar --transform "s/.*/psysh/" -czf dist/psysh-${PKG_VERSION}.tar.gz psysh.phar - tar --transform "s/.*/psysh/" -czf dist/psysh-${PKG_VERSION}-compat.tar.gz psysh-compat.phar -fi diff --git a/app/vendor/psy/psysh/bin/psysh b/app/vendor/psy/psysh/bin/psysh index e1d6350c3..7dbd203e7 100755 --- a/app/vendor/psy/psysh/bin/psysh +++ b/app/vendor/psy/psysh/bin/psysh @@ -98,6 +98,9 @@ if (!class_exists('Psy\Shell')) { // If the psysh binary was included directly, assume they just wanted an // autoloader and bail early. +// +// Keep this PHP 5.3 code around for a while in case someone is using a globally +// installed psysh as a bin launcher for older local versions. if (version_compare(PHP_VERSION, '5.3.6', '<')) { $trace = debug_backtrace(); } elseif (version_compare(PHP_VERSION, '5.4.0', '<')) { diff --git a/app/vendor/psy/psysh/box.json.dist b/app/vendor/psy/psysh/box.json.dist new file mode 100644 index 000000000..32305a525 --- /dev/null +++ b/app/vendor/psy/psysh/box.json.dist @@ -0,0 +1,13 @@ +{ + "stub": "stub", + "output": "psysh", + "compactors": [ + "KevinGH\\Box\\Compactor\\Php" + ], + "chmod": "0755", + "blacklist": [ + "grammar", + "test_old", + "Documentation" + ] +} diff --git a/app/vendor/psy/psysh/composer.json b/app/vendor/psy/psysh/composer.json index 69c226cb3..7df60cf48 100644 --- a/app/vendor/psy/psysh/composer.json +++ b/app/vendor/psy/psysh/composer.json @@ -13,17 +13,19 @@ } ], "require": { - "php": ">=5.3.9", + "php": ">=5.4.0", + "ext-json": "*", + "ext-tokenizer": "*", "symfony/console": "~2.3.10|^2.4.2|~3.0|~4.0", "symfony/var-dumper": "~2.7|~3.0|~4.0", - "nikic/php-parser": "~1.3|~2.0|~3.0", + "nikic/php-parser": "~1.3|~2.0|~3.0|~4.0", "dnoegel/php-xdg-base-dir": "0.1", "jakub-onderka/php-console-highlighter": "0.3.*" }, "require-dev": { - "phpunit/phpunit": "^4.8.35|^5.4.3", - "symfony/finder": "~2.1|~3.0|~4.0", - "hoa/console": "~3.16|~1.14" + "phpunit/phpunit": "~4.8.35|~5.0|~6.0|~7.0", + "hoa/console": "~2.15|~3.16", + "bamarni/composer-bin-plugin": "^1.2" }, "suggest": { "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", @@ -33,20 +35,20 @@ "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." }, "autoload": { - "files": ["src/Psy/functions.php"], + "files": ["src/functions.php"], "psr-4": { - "Psy\\": "src/Psy/" + "Psy\\": "src/" } }, "autoload-dev": { "psr-4": { - "Psy\\Test\\": "test/Psy/Test/" + "Psy\\Test\\": "test/" } }, "bin": ["bin/psysh"], "extra": { "branch-alias": { - "dev-develop": "0.8.x-dev" + "dev-develop": "0.9.x-dev" } } } diff --git a/app/vendor/psy/psysh/phpunit.xml.dist b/app/vendor/psy/psysh/phpunit.xml.dist index 78b2b3305..3534fca27 100644 --- a/app/vendor/psy/psysh/phpunit.xml.dist +++ b/app/vendor/psy/psysh/phpunit.xml.dist @@ -6,7 +6,7 @@ - ./src/Psy + ./src diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner.php b/app/vendor/psy/psysh/src/CodeCleaner.php similarity index 68% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner.php rename to app/vendor/psy/psysh/src/CodeCleaner.php index fa3a87857..e44c2c18e 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner.php +++ b/app/vendor/psy/psysh/src/CodeCleaner.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,16 +26,17 @@ use Psy\CodeCleaner\InstanceOfPass; use Psy\CodeCleaner\LeavePsyshAlonePass; use Psy\CodeCleaner\LegacyEmptyPass; +use Psy\CodeCleaner\ListPass; use Psy\CodeCleaner\LoopContextPass; use Psy\CodeCleaner\MagicConstantsPass; use Psy\CodeCleaner\NamespacePass; use Psy\CodeCleaner\PassableByReferencePass; use Psy\CodeCleaner\RequirePass; -use Psy\CodeCleaner\StaticConstructorPass; use Psy\CodeCleaner\StrictTypesPass; use Psy\CodeCleaner\UseStatementPass; use Psy\CodeCleaner\ValidClassNamePass; use Psy\CodeCleaner\ValidConstantPass; +use Psy\CodeCleaner\ValidConstructorPass; use Psy\CodeCleaner\ValidFunctionNamePass; use Psy\Exception\ParseErrorException; @@ -80,7 +81,14 @@ public function __construct(Parser $parser = null, Printer $printer = null, Node */ private function getDefaultPasses() { - return array( + $useStatementPass = new UseStatementPass(); + $namespacePass = new NamespacePass($this); + + // Try to add implicit `use` statements and an implicit namespace, + // based on the file in which the `debug` call was made. + $this->addImplicitDebugContext([$useStatementPass, $namespacePass]); + + return [ // Validation passes new AbstractClassPass(), new AssignThisVariablePass(), @@ -92,16 +100,17 @@ private function getDefaultPasses() new InstanceOfPass(), new LeavePsyshAlonePass(), new LegacyEmptyPass(), + new ListPass(), new LoopContextPass(), new PassableByReferencePass(), - new StaticConstructorPass(), + new ValidConstructorPass(), // Rewriting shenanigans - new UseStatementPass(), // must run before the namespace pass + $useStatementPass, // must run before the namespace pass new ExitPass(), new ImplicitReturnPass(), new MagicConstantsPass(), - new NamespacePass($this), // must run after the implicit return pass + $namespacePass, // must run after the implicit return pass new RequirePass(), new StrictTypesPass(), @@ -109,7 +118,88 @@ private function getDefaultPasses() new ValidClassNamePass(), new ValidConstantPass(), new ValidFunctionNamePass(), - ); + ]; + } + + /** + * "Warm up" code cleaner passes when we're coming from a debug call. + * + * This is useful, for example, for `UseStatementPass` and `NamespacePass` + * which keep track of state between calls, to maintain the current + * namespace and a map of use statements. + * + * @param array $passes + */ + private function addImplicitDebugContext(array $passes) + { + $file = $this->getDebugFile(); + if ($file === null) { + return; + } + + try { + $code = @\file_get_contents($file); + if (!$code) { + return; + } + + $stmts = $this->parse($code, true); + if ($stmts === false) { + return; + } + + // Set up a clean traverser for just these code cleaner passes + $traverser = new NodeTraverser(); + foreach ($passes as $pass) { + $traverser->addVisitor($pass); + } + + $traverser->traverse($stmts); + } catch (\Throwable $e) { + // Don't care. + } catch (\Exception $e) { + // Still don't care. + } + } + + /** + * Search the stack trace for a file in which the user called Psy\debug. + * + * @return string|null + */ + private static function getDebugFile() + { + $trace = \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); + + foreach (\array_reverse($trace) as $stackFrame) { + if (!self::isDebugCall($stackFrame)) { + continue; + } + + if (\preg_match('/eval\(/', $stackFrame['file'])) { + \preg_match_all('/([^\(]+)\((\d+)/', $stackFrame['file'], $matches); + + return $matches[1][0]; + } + + return $stackFrame['file']; + } + } + + /** + * Check whether a given backtrace frame is a call to Psy\debug. + * + * @param array $stackFrame + * + * @return bool + */ + private static function isDebugCall(array $stackFrame) + { + $class = isset($stackFrame['class']) ? $stackFrame['class'] : null; + $function = isset($stackFrame['function']) ? $stackFrame['function'] : null; + + return ($class === null && $function === 'Psy\debug') || + ($class === 'Psy\Shell' && $function === 'debug'); } /** @@ -124,7 +214,7 @@ private function getDefaultPasses() */ public function clean(array $codeLines, $requireSemicolons = false) { - $stmts = $this->parse('parse('traverser->traverse($stmts); // Work around https://github.com/nikic/PHP-Parser/issues/399 - $oldLocale = setlocale(LC_NUMERIC, 0); - setlocale(LC_NUMERIC, 'C'); + $oldLocale = \setlocale(LC_NUMERIC, 0); + \setlocale(LC_NUMERIC, 'C'); $code = $this->printer->prettyPrint($stmts); // Now put the locale back - setlocale(LC_NUMERIC, $oldLocale); + \setlocale(LC_NUMERIC, $oldLocale); return $code; } @@ -217,7 +307,7 @@ private function parseErrorIsEOF(\PhpParser\Error $e) { $msg = $e->getRawMessage(); - return ($msg === 'Unexpected token EOF') || (strpos($msg, 'Syntax error, unexpected EOF') !== false); + return ($msg === 'Unexpected token EOF') || (\strpos($msg, 'Syntax error, unexpected EOF') !== false); } /** @@ -254,6 +344,6 @@ private function parseErrorIsUnterminatedComment(\PhpParser\Error $e, $code) private function parseErrorIsTrailingComma(\PhpParser\Error $e, $code) { - return ($e->getRawMessage() === 'A trailing comma is not allowed here') && (substr(rtrim($code), -1) === ','); + return ($e->getRawMessage() === 'A trailing comma is not allowed here') && (\substr(\rtrim($code), -1) === ','); } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/AbstractClassPass.php b/app/vendor/psy/psysh/src/CodeCleaner/AbstractClassPass.php similarity index 82% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/AbstractClassPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/AbstractClassPass.php index fad6d8f56..81d12b6a5 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/AbstractClassPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/AbstractClassPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -33,14 +33,14 @@ public function enterNode(Node $node) { if ($node instanceof Class_) { $this->class = $node; - $this->abstractMethods = array(); + $this->abstractMethods = []; } elseif ($node instanceof ClassMethod) { if ($node->isAbstract()) { - $name = sprintf('%s::%s', $this->class->name, $node->name); + $name = \sprintf('%s::%s', $this->class->name, $node->name); $this->abstractMethods[] = $name; if ($node->stmts !== null) { - $msg = sprintf('Abstract function %s cannot contain body', $name); + $msg = \sprintf('Abstract function %s cannot contain body', $name); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } @@ -55,14 +55,14 @@ public function enterNode(Node $node) public function leaveNode(Node $node) { if ($node instanceof Class_) { - $count = count($this->abstractMethods); + $count = \count($this->abstractMethods); if ($count > 0 && !$node->isAbstract()) { - $msg = sprintf( + $msg = \sprintf( 'Class %s contains %d abstract method%s must therefore be declared abstract or implement the remaining methods (%s)', $node->name, $count, ($count === 1) ? '' : 's', - implode(', ', $this->abstractMethods) + \implode(', ', $this->abstractMethods) ); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/AssignThisVariablePass.php b/app/vendor/psy/psysh/src/CodeCleaner/AssignThisVariablePass.php similarity index 96% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/AssignThisVariablePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/AssignThisVariablePass.php index b1b3eaf1d..4c42d97f3 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/AssignThisVariablePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/AssignThisVariablePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/CallTimePassByReferencePass.php b/app/vendor/psy/psysh/src/CodeCleaner/CallTimePassByReferencePass.php similarity index 90% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/CallTimePassByReferencePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/CallTimePassByReferencePass.php index 5a5eeba12..cff2c519b 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/CallTimePassByReferencePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/CallTimePassByReferencePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -31,16 +31,12 @@ class CallTimePassByReferencePass extends CodeCleanerPass /** * Validate of use call-time pass-by-reference. * - * @throws RuntimeException if the user used call-time pass-by-reference in PHP >= 5.4.0 + * @throws RuntimeException if the user used call-time pass-by-reference * * @param Node $node */ public function enterNode(Node $node) { - if (version_compare(PHP_VERSION, '5.4', '<')) { - return; - } - if (!$node instanceof FuncCall && !$node instanceof MethodCall && !$node instanceof StaticCall) { return; } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/CalledClassPass.php b/app/vendor/psy/psysh/src/CodeCleaner/CalledClassPass.php similarity index 85% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/CalledClassPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/CalledClassPass.php index 4a0f7ea8e..e78f08d07 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/CalledClassPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/CalledClassPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -58,9 +58,9 @@ public function enterNode(Node $node) return; } - $name = strtolower($node->name); - if (in_array($name, array('get_class', 'get_called_class'))) { - $msg = sprintf('%s() called without object from outside a class', $name); + $name = \strtolower($node->name); + if (\in_array($name, ['get_class', 'get_called_class'])) { + $msg = \sprintf('%s() called without object from outside a class', $name); throw new ErrorException($msg, 0, E_USER_WARNING, null, $node->getLine()); } } @@ -78,6 +78,6 @@ public function leaveNode(Node $node) private function isNull(Node $node) { - return $node->value instanceof ConstFetch && strtolower($node->value->name) === 'null'; + return $node->value instanceof ConstFetch && \strtolower($node->value->name) === 'null'; } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/CodeCleanerPass.php b/app/vendor/psy/psysh/src/CodeCleaner/CodeCleanerPass.php similarity index 92% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/CodeCleanerPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/CodeCleanerPass.php index 4c61b8b5c..58e5d05ec 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/CodeCleanerPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/CodeCleanerPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ExitPass.php b/app/vendor/psy/psysh/src/CodeCleaner/ExitPass.php similarity index 95% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/ExitPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/ExitPass.php index bdd132a7f..349a5c571 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ExitPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/ExitPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/FinalClassPass.php b/app/vendor/psy/psysh/src/CodeCleaner/FinalClassPass.php similarity index 78% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/FinalClassPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/FinalClassPass.php index c509bef50..23f143be5 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/FinalClassPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/FinalClassPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -27,7 +27,7 @@ class FinalClassPass extends CodeCleanerPass */ public function beforeTraverse(array $nodes) { - $this->finalClasses = array(); + $this->finalClasses = []; } /** @@ -41,13 +41,13 @@ public function enterNode(Node $node) if ($node->extends) { $extends = (string) $node->extends; if ($this->isFinalClass($extends)) { - $msg = sprintf('Class %s may not inherit from final class (%s)', $node->name, $extends); + $msg = \sprintf('Class %s may not inherit from final class (%s)', $node->name, $extends); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } if ($node->isFinal()) { - $this->finalClasses[strtolower($node->name)] = true; + $this->finalClasses[\strtolower($node->name)] = true; } } } @@ -59,8 +59,8 @@ public function enterNode(Node $node) */ private function isFinalClass($name) { - if (!class_exists($name)) { - return isset($this->finalClasses[strtolower($name)]); + if (!\class_exists($name)) { + return isset($this->finalClasses[\strtolower($name)]); } $refl = new \ReflectionClass($name); diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionContextPass.php b/app/vendor/psy/psysh/src/CodeCleaner/FunctionContextPass.php similarity index 97% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionContextPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/FunctionContextPass.php index 16ee9fc23..adff5ca10 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionContextPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/FunctionContextPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionReturnInWriteContextPass.php b/app/vendor/psy/psysh/src/CodeCleaner/FunctionReturnInWriteContextPass.php similarity index 86% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionReturnInWriteContextPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/FunctionReturnInWriteContextPass.php index 42aae5ec9..87e5e7abf 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/FunctionReturnInWriteContextPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/FunctionReturnInWriteContextPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -32,11 +32,11 @@ class FunctionReturnInWriteContextPass extends CodeCleanerPass const PHP55_MESSAGE = 'Cannot use isset() on the result of a function call (you can use "null !== func()" instead)'; const EXCEPTION_MESSAGE = "Can't use function return value in write context"; - private $isPhp55; + private $atLeastPhp55; public function __construct() { - $this->isPhp55 = version_compare(PHP_VERSION, '5.5', '>='); + $this->atLeastPhp55 = \version_compare(PHP_VERSION, '5.5', '>='); } /** @@ -64,11 +64,11 @@ public function enterNode(Node $node) continue; } - $msg = ($node instanceof Isset_ && $this->isPhp55) ? self::PHP55_MESSAGE : self::EXCEPTION_MESSAGE; + $msg = ($node instanceof Isset_ && $this->atLeastPhp55) ? self::PHP55_MESSAGE : self::EXCEPTION_MESSAGE; throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } - } elseif ($node instanceof Empty_ && !$this->isPhp55 && $this->isCallNode($node->expr)) { - throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); + } elseif ($node instanceof Empty_ && !$this->atLeastPhp55 && $this->isCallNode($node->expr)) { + throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); // @codeCoverageIgnore } elseif ($node instanceof Assign && $this->isCallNode($node->var)) { throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ImplicitReturnPass.php b/app/vendor/psy/psysh/src/CodeCleaner/ImplicitReturnPass.php similarity index 67% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/ImplicitReturnPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/ImplicitReturnPass.php index c738bdc12..06b069780 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ImplicitReturnPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/ImplicitReturnPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,12 +11,12 @@ namespace Psy\CodeCleaner; +use PhpParser\Node; use PhpParser\Node\Expr; use PhpParser\Node\Expr\Exit_; -use PhpParser\Node\Expr\New_; -use PhpParser\Node\Name\FullyQualified as FullyQualifiedName; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Break_; +use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\If_; use PhpParser\Node\Stmt\Namespace_; use PhpParser\Node\Stmt\Return_; @@ -46,10 +46,10 @@ private function addImplicitReturn(array $nodes) { // If nodes is empty, it can't have a return value. if (empty($nodes)) { - return array(new Return_(new New_(new FullyQualifiedName('Psy\CodeCleaner\NoReturnValue')))); + return [new Return_(NoReturnValue::create())]; } - $last = end($nodes); + $last = \end($nodes); // Special case a few types of statements to add an implicit return // value (even though they technically don't have any return value) @@ -68,17 +68,25 @@ private function addImplicitReturn(array $nodes) } elseif ($last instanceof Switch_) { foreach ($last->cases as $case) { // only add an implicit return to cases which end in break - $caseLast = end($case->stmts); + $caseLast = \end($case->stmts); if ($caseLast instanceof Break_) { - $case->stmts = $this->addImplicitReturn(array_slice($case->stmts, 0, -1)); + $case->stmts = $this->addImplicitReturn(\array_slice($case->stmts, 0, -1)); $case->stmts[] = $caseLast; } } } elseif ($last instanceof Expr && !($last instanceof Exit_)) { - $nodes[count($nodes) - 1] = new Return_($last, array( + // @codeCoverageIgnoreStart + $nodes[\count($nodes) - 1] = new Return_($last, [ 'startLine' => $last->getLine(), 'endLine' => $last->getLine(), - )); + ]); + // @codeCoverageIgnoreEnd + } elseif ($last instanceof Expression && !($last->expr instanceof Exit_)) { + // For PHP Parser 4.x + $nodes[\count($nodes) - 1] = new Return_($last->expr, [ + 'startLine' => $last->getLine(), + 'endLine' => $last->getLine(), + ]); } elseif ($last instanceof Namespace_) { $last->stmts = $this->addImplicitReturn($last->stmts); } @@ -93,10 +101,28 @@ private function addImplicitReturn(array $nodes) // We're not adding a fallback return after namespace statements, // because code outside namespace statements doesn't really work, and // there's already an implicit return in the namespace statement anyway. - if ($last instanceof Stmt && !$last instanceof Return_ && !$last instanceof Namespace_) { - $nodes[] = new Return_(new New_(new FullyQualifiedName('Psy\CodeCleaner\NoReturnValue'))); + if (self::isNonExpressionStmt($last)) { + $nodes[] = new Return_(NoReturnValue::create()); } return $nodes; } + + /** + * Check whether a given node is a non-expression statement. + * + * As of PHP Parser 4.x, Expressions are now instances of Stmt as well, so + * we'll exclude them here. + * + * @param Node $node + * + * @return bool + */ + private static function isNonExpressionStmt(Node $node) + { + return $node instanceof Stmt && + !$node instanceof Expression && + !$node instanceof Return_ && + !$node instanceof Namespace_; + } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/InstanceOfPass.php b/app/vendor/psy/psysh/src/CodeCleaner/InstanceOfPass.php similarity index 97% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/InstanceOfPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/InstanceOfPass.php index 78ce98e93..44e24cae7 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/InstanceOfPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/InstanceOfPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/LeavePsyshAlonePass.php b/app/vendor/psy/psysh/src/CodeCleaner/LeavePsyshAlonePass.php similarity index 92% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/LeavePsyshAlonePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/LeavePsyshAlonePass.php index e6a3bbde8..08f6fbee0 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/LeavePsyshAlonePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/LeavePsyshAlonePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -30,7 +30,7 @@ class LeavePsyshAlonePass extends CodeCleanerPass public function enterNode(Node $node) { if ($node instanceof Variable && $node->name === '__psysh__') { - throw new RuntimeException('Don\'t mess with $__psysh__. Bad things will happen.'); + throw new RuntimeException('Don\'t mess with $__psysh__; bad things will happen'); } } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/LegacyEmptyPass.php b/app/vendor/psy/psysh/src/CodeCleaner/LegacyEmptyPass.php similarity index 77% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/LegacyEmptyPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/LegacyEmptyPass.php index dc5a01ed7..9793d8c4c 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/LegacyEmptyPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/LegacyEmptyPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,9 +19,18 @@ /** * Validate that the user did not call the language construct `empty()` on a * statement in PHP < 5.5. + * + * @codeCoverageIgnore */ class LegacyEmptyPass extends CodeCleanerPass { + private $atLeastPhp55; + + public function __construct() + { + $this->atLeastPhp55 = \version_compare(PHP_VERSION, '5.5', '>='); + } + /** * Validate use of empty in PHP < 5.5. * @@ -31,7 +40,7 @@ class LegacyEmptyPass extends CodeCleanerPass */ public function enterNode(Node $node) { - if (version_compare(PHP_VERSION, '5.5', '>=')) { + if ($this->atLeastPhp55) { return; } @@ -40,7 +49,7 @@ public function enterNode(Node $node) } if (!$node->expr instanceof Variable) { - $msg = sprintf('syntax error, unexpected %s', $this->getUnexpectedThing($node->expr)); + $msg = \sprintf('syntax error, unexpected %s', $this->getUnexpectedThing($node->expr)); throw new ParseErrorException($msg, $node->expr->getLine()); } @@ -52,7 +61,7 @@ private function getUnexpectedThing(Node $node) case 'Scalar_String': case 'Scalar_LNumber': case 'Scalar_DNumber': - return json_encode($node->value); + return \json_encode($node->value); case 'Expr_ConstFetch': return (string) $node->name; diff --git a/app/vendor/psy/psysh/src/CodeCleaner/ListPass.php b/app/vendor/psy/psysh/src/CodeCleaner/ListPass.php new file mode 100644 index 000000000..aabf0c36b --- /dev/null +++ b/app/vendor/psy/psysh/src/CodeCleaner/ListPass.php @@ -0,0 +1,112 @@ +atLeastPhp71 = \version_compare(PHP_VERSION, '7.1', '>='); + } + + /** + * Validate use of list assignment. + * + * @throws ParseErrorException if the user used empty with anything but a variable + * + * @param Node $node + */ + public function enterNode(Node $node) + { + if (!$node instanceof Assign) { + return; + } + + if (!$node->var instanceof Array_ && !$node->var instanceof List_) { + return; + } + + if (!$this->atLeastPhp71 && $node->var instanceof Array_) { + $msg = "syntax error, unexpected '='"; + throw new ParseErrorException($msg, $node->expr->getLine()); + } + + // Polyfill for PHP-Parser 2.x + $items = isset($node->var->items) ? $node->var->items : $node->var->vars; + + if ($items === [] || $items === [null]) { + throw new ParseErrorException('Cannot use empty list', $node->var->getLine()); + } + + $itemFound = false; + foreach ($items as $item) { + if ($item === null) { + continue; + } + + $itemFound = true; + + // List_->$vars in PHP-Parser 2.x is Variable instead of ArrayItem. + if (!$this->atLeastPhp71 && $item instanceof ArrayItem && $item->key !== null) { + $msg = 'Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting \',\' or \')\''; + throw new ParseErrorException($msg, $item->key->getLine()); + } + + if (!self::isValidArrayItem($item)) { + $msg = 'Assignments can only happen to writable values'; + throw new ParseErrorException($msg, $item->getLine()); + } + } + + if (!$itemFound) { + throw new ParseErrorException('Cannot use empty list'); + } + } + + /** + * Validate whether a given item in an array is valid for short assignment. + * + * @param Expr $item + * + * @return bool + */ + private static function isValidArrayItem(Expr $item) + { + $value = ($item instanceof ArrayItem) ? $item->value : $item; + + if ($value instanceof Variable) { + return true; + } + + if ($value instanceof ArrayDimFetch || $value instanceof PropertyFetch) { + return isset($value->var) && $value->var instanceof Variable; + } + + return false; + } +} diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/LoopContextPass.php b/app/vendor/psy/psysh/src/CodeCleaner/LoopContextPass.php similarity index 80% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/LoopContextPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/LoopContextPass.php index e8f65bb9e..933278e73 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/LoopContextPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/LoopContextPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -28,14 +28,8 @@ */ class LoopContextPass extends CodeCleanerPass { - private $isPHP54; private $loopDepth; - public function __construct() - { - $this->isPHP54 = version_compare(PHP_VERSION, '5.4.0', '>='); - } - /** * {@inheritdoc} */ @@ -68,23 +62,23 @@ public function enterNode(Node $node) $operator = $node instanceof Break_ ? 'break' : 'continue'; if ($this->loopDepth === 0) { - $msg = sprintf("'%s' not in the 'loop' or 'switch' context", $operator); + $msg = \sprintf("'%s' not in the 'loop' or 'switch' context", $operator); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } if ($node->num instanceof LNumber || $node->num instanceof DNumber) { $num = $node->num->value; - if ($this->isPHP54 && ($node->num instanceof DNumber || $num < 1)) { - $msg = sprintf("'%s' operator accepts only positive numbers", $operator); + if ($node->num instanceof DNumber || $num < 1) { + $msg = \sprintf("'%s' operator accepts only positive numbers", $operator); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } if ($num > $this->loopDepth) { - $msg = sprintf("Cannot '%s' %d levels", $operator, $num); + $msg = \sprintf("Cannot '%s' %d levels", $operator, $num); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } - } elseif ($node->num && $this->isPHP54) { - $msg = sprintf("'%s' operator with non-constant operand is no longer supported", $operator); + } elseif ($node->num) { + $msg = \sprintf("'%s' operator with non-constant operand is no longer supported", $operator); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } break; diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/MagicConstantsPass.php b/app/vendor/psy/psysh/src/CodeCleaner/MagicConstantsPass.php similarity index 89% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/MagicConstantsPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/MagicConstantsPass.php index 328eb256a..50936b2cc 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/MagicConstantsPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/MagicConstantsPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -34,7 +34,7 @@ class MagicConstantsPass extends CodeCleanerPass public function enterNode(Node $node) { if ($node instanceof Dir) { - return new FuncCall(new Name('getcwd'), array(), $node->getAttributes()); + return new FuncCall(new Name('getcwd'), [], $node->getAttributes()); } elseif ($node instanceof File) { return new String_('', $node->getAttributes()); } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/NamespaceAwarePass.php b/app/vendor/psy/psysh/src/CodeCleaner/NamespaceAwarePass.php similarity index 83% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/NamespaceAwarePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/NamespaceAwarePass.php index 4a76d0f64..6679206dc 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/NamespaceAwarePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/NamespaceAwarePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -32,8 +32,8 @@ abstract class NamespaceAwarePass extends CodeCleanerPass */ public function beforeTraverse(array $nodes) { - $this->namespace = array(); - $this->currentScope = array(); + $this->namespace = []; + $this->currentScope = []; } /** @@ -45,7 +45,7 @@ public function beforeTraverse(array $nodes) public function enterNode(Node $node) { if ($node instanceof Namespace_) { - $this->namespace = isset($node->name) ? $node->name->parts : array(); + $this->namespace = isset($node->name) ? $node->name->parts : []; } } @@ -59,13 +59,13 @@ public function enterNode(Node $node) protected function getFullyQualifiedName($name) { if ($name instanceof FullyQualifiedName) { - return implode('\\', $name->parts); + return \implode('\\', $name->parts); } elseif ($name instanceof Name) { $name = $name->parts; - } elseif (!is_array($name)) { - $name = array($name); + } elseif (!\is_array($name)) { + $name = [$name]; } - return implode('\\', array_merge($this->namespace, $name)); + return \implode('\\', \array_merge($this->namespace, $name)); } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/NamespacePass.php b/app/vendor/psy/psysh/src/CodeCleaner/NamespacePass.php similarity index 68% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/NamespacePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/NamespacePass.php index 37ef9f240..d26f07cce 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/NamespacePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/NamespacePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -53,14 +53,25 @@ public function beforeTraverse(array $nodes) return $nodes; } - $last = end($nodes); - if (!$last instanceof Namespace_) { - return $this->namespace ? array(new Namespace_($this->namespace, $nodes)) : $nodes; - } + $last = \end($nodes); + + if ($last instanceof Namespace_) { + $kind = $last->getAttribute('kind'); + + // Treat all namespace statements pre-PHP-Parser v3.1.2 as "open", + // even though we really have no way of knowing. + if ($kind === null || $kind === Namespace_::KIND_SEMICOLON) { + // Save the current namespace for open namespaces + $this->setNamespace($last->name); + } else { + // Clear the current namespace after a braced namespace + $this->setNamespace(null); + } - $this->setNamespace($last->name); + return $nodes; + } - return $nodes; + return $this->namespace ? [new Namespace_($this->namespace, $nodes)] : $nodes; } /** diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/NoReturnValue.php b/app/vendor/psy/psysh/src/CodeCleaner/NoReturnValue.php similarity index 56% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/NoReturnValue.php rename to app/vendor/psy/psysh/src/CodeCleaner/NoReturnValue.php index 3784f4b35..90325701e 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/NoReturnValue.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/NoReturnValue.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,9 @@ namespace Psy\CodeCleaner; +use PhpParser\Node\Expr\New_; +use PhpParser\Node\Name\FullyQualified as FullyQualifiedName; + /** * A class used internally by CodeCleaner to represent input, such as * non-expression statements, with no return value. @@ -20,5 +23,13 @@ */ class NoReturnValue { - // this space intentionally left blank + /** + * Get PhpParser AST expression for creating a new NoReturnValue. + * + * @return PhpParser\Node\Expr\New_ + */ + public static function create() + { + return new New_(new FullyQualifiedName('Psy\CodeCleaner\NoReturnValue')); + } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/PassableByReferencePass.php b/app/vendor/psy/psysh/src/CodeCleaner/PassableByReferencePass.php similarity index 97% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/PassableByReferencePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/PassableByReferencePass.php index 5d9936c79..5b5dc0868 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/PassableByReferencePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/PassableByReferencePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -56,7 +56,7 @@ public function enterNode(Node $node) } foreach ($refl->getParameters() as $key => $param) { - if (array_key_exists($key, $node->args)) { + if (\array_key_exists($key, $node->args)) { $arg = $node->args[$key]; if ($param->isPassedByReference() && !$this->isPassableByReference($arg)) { throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/RequirePass.php b/app/vendor/psy/psysh/src/CodeCleaner/RequirePass.php similarity index 78% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/RequirePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/RequirePass.php index 00b506088..31c156a37 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/RequirePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/RequirePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,7 +26,7 @@ */ class RequirePass extends CodeCleanerPass { - private static $requireTypes = array(Include_::TYPE_REQUIRE, Include_::TYPE_REQUIRE_ONCE); + private static $requireTypes = [Include_::TYPE_REQUIRE, Include_::TYPE_REQUIRE_ONCE]; /** * {@inheritdoc} @@ -51,7 +51,7 @@ public function enterNode(Node $origNode) $node->expr = new StaticCall( new FullyQualifiedName('Psy\CodeCleaner\RequirePass'), 'resolve', - array(new Arg($origNode->expr), new Arg(new LNumber($origNode->getLine()))), + [new Arg($origNode->expr), new Arg(new LNumber($origNode->getLine()))], $origNode->getAttributes() ); @@ -79,16 +79,15 @@ public static function resolve($file, $lineNumber = null) // @todo Shell::handleError would be better here, because we could // fake the file and line number, but we can't call it statically. // So we're duplicating some of the logics here. - if (E_WARNING & error_reporting()) { + if (E_WARNING & \error_reporting()) { ErrorException::throwException(E_WARNING, 'Filename cannot be empty', null, $lineNumber); - } else { - // @todo trigger an error as fallback? this is pretty ugly… - // trigger_error('Filename cannot be empty', E_USER_WARNING); } + // @todo trigger an error as fallback? this is pretty ugly… + // trigger_error('Filename cannot be empty', E_USER_WARNING); } - if ($file === '' || !stream_resolve_include_path($file)) { - $msg = sprintf("Failed opening required '%s'", $file); + if ($file === '' || !\stream_resolve_include_path($file)) { + $msg = \sprintf("Failed opening required '%s'", $file); throw new FatalErrorException($msg, 0, E_ERROR, null, $lineNumber); } @@ -97,6 +96,6 @@ public static function resolve($file, $lineNumber = null) private function isRequireNode(Node $node) { - return $node instanceof Include_ && in_array($node->type, self::$requireTypes); + return $node instanceof Include_ && \in_array($node->type, self::$requireTypes); } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/StrictTypesPass.php b/app/vendor/psy/psysh/src/CodeCleaner/StrictTypesPass.php similarity index 74% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/StrictTypesPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/StrictTypesPass.php index 5966f0c51..058a5a829 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/StrictTypesPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/StrictTypesPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,7 @@ namespace Psy\CodeCleaner; +use PhpParser\Node\Identifier; use PhpParser\Node\Scalar\LNumber; use PhpParser\Node\Stmt\Declare_; use PhpParser\Node\Stmt\DeclareDeclare; @@ -31,6 +32,12 @@ class StrictTypesPass extends CodeCleanerPass const EXCEPTION_MESSAGE = 'strict_types declaration must have 0 or 1 as its value'; private $strictTypes = false; + private $atLeastPhp7; + + public function __construct() + { + $this->atLeastPhp7 = \version_compare(PHP_VERSION, '7.0', '>='); + } /** * If this is a standalone strict types declaration, remember it for later. @@ -44,8 +51,8 @@ class StrictTypesPass extends CodeCleanerPass */ public function beforeTraverse(array $nodes) { - if (version_compare(PHP_VERSION, '7.0', '<')) { - return; + if (!$this->atLeastPhp7) { + return; // @codeCoverageIgnore } $prependStrictTypes = $this->strictTypes; @@ -53,7 +60,9 @@ public function beforeTraverse(array $nodes) foreach ($nodes as $key => $node) { if ($node instanceof Declare_) { foreach ($node->declares as $declare) { - if ($declare->key === 'strict_types') { + // For PHP Parser 4.x + $declareKey = $declare->key instanceof Identifier ? $declare->key->toString() : $declare->key; + if ($declareKey === 'strict_types') { $value = $declare->value; if (!$value instanceof LNumber || ($value->value !== 0 && $value->value !== 1)) { throw new FatalErrorException(self::EXCEPTION_MESSAGE, 0, E_ERROR, null, $node->getLine()); @@ -66,10 +75,10 @@ public function beforeTraverse(array $nodes) } if ($prependStrictTypes) { - $first = reset($nodes); + $first = \reset($nodes); if (!$first instanceof Declare_) { - $declare = new Declare_(array(new DeclareDeclare('strict_types', new LNumber(1)))); - array_unshift($nodes, $declare); + $declare = new Declare_([new DeclareDeclare('strict_types', new LNumber(1))]); + \array_unshift($nodes, $declare); } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/UseStatementPass.php b/app/vendor/psy/psysh/src/CodeCleaner/UseStatementPass.php similarity index 80% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/UseStatementPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/UseStatementPass.php index c1ce64d3e..64ac5be6d 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/UseStatementPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/UseStatementPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,6 +17,7 @@ use PhpParser\Node\Stmt\GroupUse; use PhpParser\Node\Stmt\Namespace_; use PhpParser\Node\Stmt\Use_; +use PhpParser\NodeTraverser; /** * Provide implicit use statements for subsequent execution. @@ -30,8 +31,8 @@ */ class UseStatementPass extends CodeCleanerPass { - private $aliases = array(); - private $lastAliases = array(); + private $aliases = []; + private $lastAliases = []; private $lastNamespace = null; /** @@ -48,7 +49,7 @@ public function enterNode(Node $node) if ($node instanceof Namespace_) { // If this is the same namespace as last namespace, let's do ourselves // a favor and reload all the aliases... - if (strtolower($node->name) === strtolower($this->lastNamespace)) { + if (\strtolower($node->name) === \strtolower($this->lastNamespace)) { $this->aliases = $this->lastAliases; } } @@ -68,26 +69,28 @@ public function leaveNode(Node $node) // Store a reference to every "use" statement, because we'll need // them in a bit. foreach ($node->uses as $use) { - $this->aliases[strtolower($use->alias)] = $use->name; + $alias = $use->alias ?: \end($use->name->parts); + $this->aliases[\strtolower($alias)] = $use->name; } - return false; + return NodeTraverser::REMOVE_NODE; } elseif ($node instanceof GroupUse) { // Expand every "use" statement in the group into a full, standalone // "use" and store 'em with the others. foreach ($node->uses as $use) { - $this->aliases[strtolower($use->alias)] = Name::concat($node->prefix, $use->name, array( + $alias = $use->alias ?: \end($use->name->parts); + $this->aliases[\strtolower($alias)] = Name::concat($node->prefix, $use->name, [ 'startLine' => $node->prefix->getAttribute('startLine'), 'endLine' => $use->name->getAttribute('endLine'), - )); + ]); } - return false; + return NodeTraverser::REMOVE_NODE; } elseif ($node instanceof Namespace_) { // Start fresh, since we're done with this namespace. $this->lastNamespace = $node->name; $this->lastAliases = $this->aliases; - $this->aliases = array(); + $this->aliases = []; } else { foreach ($node as $name => $subNode) { if ($subNode instanceof Name) { @@ -111,12 +114,12 @@ public function leaveNode(Node $node) */ private function findAlias(Name $name) { - $that = strtolower($name); + $that = \strtolower($name); foreach ($this->aliases as $alias => $prefix) { if ($that === $alias) { return new FullyQualifiedName($prefix->toString()); - } elseif (substr($that, 0, strlen($alias) + 1) === $alias . '\\') { - return new FullyQualifiedName($prefix->toString() . substr($name, strlen($alias))); + } elseif (\substr($that, 0, \strlen($alias) + 1) === $alias . '\\') { + return new FullyQualifiedName($prefix->toString() . \substr($name, \strlen($alias))); } } } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidClassNamePass.php b/app/vendor/psy/psysh/src/CodeCleaner/ValidClassNamePass.php similarity index 81% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidClassNamePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/ValidClassNamePass.php index c91471efc..9578c9a86 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidClassNamePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/ValidClassNamePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -38,12 +38,12 @@ class ValidClassNamePass extends NamespaceAwarePass const INTERFACE_TYPE = 'interface'; const TRAIT_TYPE = 'trait'; - protected $checkTraits; private $conditionalScopes = 0; + private $atLeastPhp55; public function __construct() { - $this->checkTraits = function_exists('trait_exists'); + $this->atLeastPhp55 = \version_compare(PHP_VERSION, '5.5', '>='); } /** @@ -53,7 +53,7 @@ public function __construct() * presence and can validate constant fetches and static calls in class or * trait methods. * - * @param Node + * @param Node $node */ public function enterNode(Node $node) { @@ -115,7 +115,7 @@ private static function isConditional(Node $node) */ protected function validateClassStatement(Class_ $stmt) { - $this->ensureCanDefine($stmt); + $this->ensureCanDefine($stmt, self::CLASS_TYPE); if (isset($stmt->extends)) { $this->ensureClassExists($this->getFullyQualifiedName($stmt->extends), $stmt); } @@ -129,7 +129,7 @@ protected function validateClassStatement(Class_ $stmt) */ protected function validateInterfaceStatement(Interface_ $stmt) { - $this->ensureCanDefine($stmt); + $this->ensureCanDefine($stmt, self::INTERFACE_TYPE); $this->ensureInterfacesExist($stmt->extends, $stmt); } @@ -140,7 +140,7 @@ protected function validateInterfaceStatement(Interface_ $stmt) */ protected function validateTraitStatement(Trait_ $stmt) { - $this->ensureCanDefine($stmt); + $this->ensureCanDefine($stmt, self::TRAIT_TYPE); } /** @@ -164,8 +164,7 @@ protected function validateNewExpression(New_ $stmt) protected function validateClassConstFetchExpression(ClassConstFetch $stmt) { // there is no need to check exists for ::class const for php 5.5 or newer - if (strtolower($stmt->name) === 'class' - && version_compare(PHP_VERSION, '5.5', '>=')) { + if (\strtolower($stmt->name) === 'class' && $this->atLeastPhp55) { return; } @@ -193,9 +192,10 @@ protected function validateStaticCallExpression(StaticCall $stmt) * * @throws FatalErrorException * - * @param Stmt $stmt + * @param Stmt $stmt + * @param string $scopeType */ - protected function ensureCanDefine(Stmt $stmt) + protected function ensureCanDefine(Stmt $stmt, $scopeType = self::CLASS_TYPE) { $name = $this->getFullyQualifiedName($stmt->name); @@ -210,12 +210,12 @@ protected function ensureCanDefine(Stmt $stmt) } if ($errorType !== null) { - throw $this->createError(sprintf('%s named %s already exists', ucfirst($errorType), $name), $stmt); + throw $this->createError(\sprintf('%s named %s already exists', \ucfirst($errorType), $name), $stmt); } // Store creation for the rest of this code snippet so we can find local // issue too - $this->currentScope[strtolower($name)] = $this->getScopeType($stmt); + $this->currentScope[\strtolower($name)] = $scopeType; } /** @@ -229,7 +229,7 @@ protected function ensureCanDefine(Stmt $stmt) protected function ensureClassExists($name, $stmt) { if (!$this->classExists($name)) { - throw $this->createError(sprintf('Class \'%s\' not found', $name), $stmt); + throw $this->createError(\sprintf('Class \'%s\' not found', $name), $stmt); } } @@ -244,7 +244,22 @@ protected function ensureClassExists($name, $stmt) protected function ensureClassOrInterfaceExists($name, $stmt) { if (!$this->classExists($name) && !$this->interfaceExists($name)) { - throw $this->createError(sprintf('Class \'%s\' not found', $name), $stmt); + throw $this->createError(\sprintf('Class \'%s\' not found', $name), $stmt); + } + } + + /** + * Ensure that a referenced class _or trait_ exists. + * + * @throws FatalErrorException + * + * @param string $name + * @param Stmt $stmt + */ + protected function ensureClassOrTraitExists($name, $stmt) + { + if (!$this->classExists($name) && !$this->traitExists($name)) { + throw $this->createError(\sprintf('Class \'%s\' not found', $name), $stmt); } } @@ -259,10 +274,10 @@ protected function ensureClassOrInterfaceExists($name, $stmt) */ protected function ensureMethodExists($class, $name, $stmt) { - $this->ensureClassExists($class, $stmt); + $this->ensureClassOrTraitExists($class, $stmt); // let's pretend all calls to self, parent and static are valid - if (in_array(strtolower($class), array('self', 'parent', 'static'))) { + if (\in_array(\strtolower($class), ['self', 'parent', 'static'])) { return; } @@ -276,8 +291,8 @@ protected function ensureMethodExists($class, $name, $stmt) return; } - if (!method_exists($class, $name) && !method_exists($class, '__callStatic')) { - throw $this->createError(sprintf('Call to undefined method %s::%s()', $class, $name), $stmt); + if (!\method_exists($class, $name) && !\method_exists($class, '__callStatic')) { + throw $this->createError(\sprintf('Call to undefined method %s::%s()', $class, $name), $stmt); } } @@ -286,8 +301,8 @@ protected function ensureMethodExists($class, $name, $stmt) * * @throws FatalErrorException * - * @param $interfaces - * @param Stmt $stmt + * @param Interface_[] $interfaces + * @param Stmt $stmt */ protected function ensureInterfacesExist($interfaces, $stmt) { @@ -295,7 +310,7 @@ protected function ensureInterfacesExist($interfaces, $stmt) /** @var string $name */ $name = $this->getFullyQualifiedName($interface); if (!$this->interfaceExists($name)) { - throw $this->createError(sprintf('Interface \'%s\' not found', $name), $stmt); + throw $this->createError(\sprintf('Interface \'%s\' not found', $name), $stmt); } } } @@ -303,6 +318,9 @@ protected function ensureInterfacesExist($interfaces, $stmt) /** * Get a symbol type key for storing in the scope name cache. * + * @deprecated No longer used. Scope type should be passed into ensureCanDefine directly. + * @codeCoverageIgnore + * * @param Stmt $stmt * * @return string @@ -332,11 +350,11 @@ protected function classExists($name) // Give `self`, `static` and `parent` a pass. This will actually let // some errors through, since we're not checking whether the keyword is // being used in a class scope. - if (in_array(strtolower($name), array('self', 'static', 'parent'))) { + if (\in_array(\strtolower($name), ['self', 'static', 'parent'])) { return true; } - return class_exists($name) || $this->findInScope($name) === self::CLASS_TYPE; + return \class_exists($name) || $this->findInScope($name) === self::CLASS_TYPE; } /** @@ -348,7 +366,7 @@ protected function classExists($name) */ protected function interfaceExists($name) { - return interface_exists($name) || $this->findInScope($name) === self::INTERFACE_TYPE; + return \interface_exists($name) || $this->findInScope($name) === self::INTERFACE_TYPE; } /** @@ -360,7 +378,7 @@ protected function interfaceExists($name) */ protected function traitExists($name) { - return $this->checkTraits && (trait_exists($name) || $this->findInScope($name) === self::TRAIT_TYPE); + return \trait_exists($name) || $this->findInScope($name) === self::TRAIT_TYPE; } /** @@ -372,7 +390,7 @@ protected function traitExists($name) */ protected function findInScope($name) { - $name = strtolower($name); + $name = \strtolower($name); if (isset($this->currentScope[$name])) { return $this->currentScope[$name]; } diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidConstantPass.php b/app/vendor/psy/psysh/src/CodeCleaner/ValidConstantPass.php similarity index 77% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidConstantPass.php rename to app/vendor/psy/psysh/src/CodeCleaner/ValidConstantPass.php index e84f3de66..2d5e3e6d9 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidConstantPass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/ValidConstantPass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -15,6 +15,7 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Expr\ConstFetch; +use PhpParser\Node\Identifier; use Psy\Exception\FatalErrorException; /** @@ -42,10 +43,10 @@ class ValidConstantPass extends NamespaceAwarePass */ public function leaveNode(Node $node) { - if ($node instanceof ConstFetch && count($node->name->parts) > 1) { + if ($node instanceof ConstFetch && \count($node->name->parts) > 1) { $name = $this->getFullyQualifiedName($node->name); - if (!defined($name)) { - $msg = sprintf('Undefined constant %s', $name); + if (!\defined($name)) { + $msg = \sprintf('Undefined constant %s', $name); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } elseif ($node instanceof ClassConstFetch) { @@ -62,8 +63,11 @@ public function leaveNode(Node $node) */ protected function validateClassConstFetchExpression(ClassConstFetch $stmt) { + // For PHP Parser 4.x + $constName = $stmt->name instanceof Identifier ? $stmt->name->toString() : $stmt->name; + // give the `class` pseudo-constant a pass - if ($stmt->name === 'class') { + if ($constName === 'class') { return; } @@ -73,11 +77,11 @@ protected function validateClassConstFetchExpression(ClassConstFetch $stmt) // if the class doesn't exist, don't throw an exception… it might be // defined in the same line it's used or something stupid like that. - if (class_exists($className) || interface_exists($className)) { + if (\class_exists($className) || \interface_exists($className)) { $refl = new \ReflectionClass($className); - if (!$refl->hasConstant($stmt->name)) { - $constType = class_exists($className) ? 'Class' : 'Interface'; - $msg = sprintf('%s constant \'%s::%s\' not found', $constType, $className, $stmt->name); + if (!$refl->hasConstant($constName)) { + $constType = \class_exists($className) ? 'Class' : 'Interface'; + $msg = \sprintf('%s constant \'%s::%s\' not found', $constType, $className, $constName); throw new FatalErrorException($msg, 0, E_ERROR, null, $stmt->getLine()); } } diff --git a/app/vendor/psy/psysh/src/CodeCleaner/ValidConstructorPass.php b/app/vendor/psy/psysh/src/CodeCleaner/ValidConstructorPass.php new file mode 100644 index 000000000..a079e26c9 --- /dev/null +++ b/app/vendor/psy/psysh/src/CodeCleaner/ValidConstructorPass.php @@ -0,0 +1,112 @@ + + */ +class ValidConstructorPass extends CodeCleanerPass +{ + private $namespace; + + public function beforeTraverse(array $nodes) + { + $this->namespace = []; + } + + /** + * Validate that the constructor is not static and does not have a return type. + * + * @throws FatalErrorException the constructor function is static + * @throws FatalErrorException the constructor function has a return type + * + * @param Node $node + */ + public function enterNode(Node $node) + { + if ($node instanceof Namespace_) { + $this->namespace = isset($node->name) ? $node->name->parts : []; + } elseif ($node instanceof Class_) { + $constructor = null; + foreach ($node->stmts as $stmt) { + if ($stmt instanceof ClassMethod) { + // If we find a new-style constructor, no need to look for the old-style + if ('__construct' === \strtolower($stmt->name)) { + $this->validateConstructor($stmt, $node); + + return; + } + + // We found a possible old-style constructor (unless there is also a __construct method) + if (empty($this->namespace) && \strtolower($node->name) === \strtolower($stmt->name)) { + $constructor = $stmt; + } + } + } + + if ($constructor) { + $this->validateConstructor($constructor, $node); + } + } + } + + /** + * @throws FatalErrorException the constructor function is static + * @throws FatalErrorException the constructor function has a return type + * + * @param Node $constructor + * @param Node $classNode + */ + private function validateConstructor(Node $constructor, Node $classNode) + { + if ($constructor->isStatic()) { + // For PHP Parser 4.x + $className = $classNode->name instanceof Identifier ? $classNode->name->toString() : $classNode->name; + + $msg = \sprintf( + 'Constructor %s::%s() cannot be static', + \implode('\\', \array_merge($this->namespace, (array) $className)), + $constructor->name + ); + throw new FatalErrorException($msg, 0, E_ERROR, null, $classNode->getLine()); + } + + if (\method_exists($constructor, 'getReturnType') && $constructor->getReturnType()) { + // For PHP Parser 4.x + $className = $classNode->name instanceof Identifier ? $classNode->name->toString() : $classNode->name; + + $msg = \sprintf( + 'Constructor %s::%s() cannot declare a return type', + \implode('\\', \array_merge($this->namespace, (array) $className)), + $constructor->name + ); + throw new FatalErrorException($msg, 0, E_ERROR, null, $classNode->getLine()); + } + } +} diff --git a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidFunctionNamePass.php b/app/vendor/psy/psysh/src/CodeCleaner/ValidFunctionNamePass.php similarity index 81% rename from app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidFunctionNamePass.php rename to app/vendor/psy/psysh/src/CodeCleaner/ValidFunctionNamePass.php index 0da5138f0..dd1e05763 100644 --- a/app/vendor/psy/psysh/src/Psy/CodeCleaner/ValidFunctionNamePass.php +++ b/app/vendor/psy/psysh/src/CodeCleaner/ValidFunctionNamePass.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -49,14 +49,14 @@ public function enterNode(Node $node) // @todo add an "else" here which adds a runtime check for instances where we can't tell // whether a function is being redefined by static analysis alone. if ($this->conditionalScopes === 0) { - if (function_exists($name) || - isset($this->currentScope[strtolower($name)])) { - $msg = sprintf('Cannot redeclare %s()', $name); + if (\function_exists($name) || + isset($this->currentScope[\strtolower($name)])) { + $msg = \sprintf('Cannot redeclare %s()', $name); throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); } } - $this->currentScope[strtolower($name)] = true; + $this->currentScope[\strtolower($name)] = true; } } @@ -76,11 +76,11 @@ public function leaveNode(Node $node) // if function name is an expression or a variable, give it a pass for now. $name = $node->name; if (!$name instanceof Expr && !$name instanceof Variable) { - $shortName = implode('\\', $name->parts); + $shortName = \implode('\\', $name->parts); $fullName = $this->getFullyQualifiedName($name); - $inScope = isset($this->currentScope[strtolower($fullName)]); - if (!$inScope && !function_exists($shortName) && !function_exists($fullName)) { - $message = sprintf('Call to undefined function %s()', $name); + $inScope = isset($this->currentScope[\strtolower($fullName)]); + if (!$inScope && !\function_exists($shortName) && !\function_exists($fullName)) { + $message = \sprintf('Call to undefined function %s()', $name); throw new FatalErrorException($message, 0, E_ERROR, null, $node->getLine()); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/BufferCommand.php b/app/vendor/psy/psysh/src/Command/BufferCommand.php similarity index 87% rename from app/vendor/psy/psysh/src/Psy/Command/BufferCommand.php rename to app/vendor/psy/psysh/src/Command/BufferCommand.php index 3a8abcb10..83ba34a8a 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/BufferCommand.php +++ b/app/vendor/psy/psysh/src/Command/BufferCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -30,10 +30,10 @@ protected function configure() { $this ->setName('buffer') - ->setAliases(array('buf')) - ->setDefinition(array( + ->setAliases(['buf']) + ->setDefinition([ new InputOption('clear', '', InputOption::VALUE_NONE, 'Clear the current buffer.'), - )) + ]) ->setDescription('Show (or clear) the contents of the code input buffer.') ->setHelp( <<<'HELP' @@ -68,10 +68,10 @@ protected function execute(InputInterface $input, OutputInterface $output) */ protected function formatLines(array $lines, $type = 'return') { - $template = sprintf('<%s>%%s', $type, $type); + $template = \sprintf('<%s>%%s', $type, $type); - return array_map(function ($line) use ($template) { - return sprintf($template, $line); + return \array_map(function ($line) use ($template) { + return \sprintf($template, $line); }, $lines); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ClearCommand.php b/app/vendor/psy/psysh/src/Command/ClearCommand.php similarity index 87% rename from app/vendor/psy/psysh/src/Psy/Command/ClearCommand.php rename to app/vendor/psy/psysh/src/Command/ClearCommand.php index 470f61de5..6b12048a9 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ClearCommand.php +++ b/app/vendor/psy/psysh/src/Command/ClearCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -28,7 +28,7 @@ protected function configure() { $this ->setName('clear') - ->setDefinition(array()) + ->setDefinition([]) ->setDescription('Clear the Psy Shell screen.') ->setHelp( <<<'HELP' @@ -44,6 +44,6 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $output->write(sprintf('%c[2J%c[0;0f', 27, 27)); + $output->write(\sprintf('%c[2J%c[0;0f', 27, 27)); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/Command.php b/app/vendor/psy/psysh/src/Command/Command.php similarity index 67% rename from app/vendor/psy/psysh/src/Psy/Command/Command.php rename to app/vendor/psy/psysh/src/Command/Command.php index c8aaedeee..be013a1b9 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/Command.php +++ b/app/vendor/psy/psysh/src/Command/Command.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -34,7 +34,7 @@ abstract class Command extends BaseCommand public function setApplication(Application $application = null) { if ($application !== null && !$application instanceof Shell) { - throw new \InvalidArgumentException('PsySH Commands require an instance of Psy\Shell.'); + throw new \InvalidArgumentException('PsySH Commands require an instance of Psy\Shell'); } return parent::setApplication($application); @@ -45,11 +45,11 @@ public function setApplication(Application $application = null) */ public function asText() { - $messages = array( + $messages = [ 'Usage:', ' ' . $this->getSynopsis(), '', - ); + ]; if ($this->getAliases()) { $messages[] = $this->aliasesAsText(); @@ -65,10 +65,10 @@ public function asText() if ($help = $this->getProcessedHelp()) { $messages[] = 'Help:'; - $messages[] = ' ' . str_replace("\n", "\n ", $help) . "\n"; + $messages[] = ' ' . \str_replace("\n", "\n ", $help) . "\n"; } - return implode("\n", $messages); + return \implode("\n", $messages); } /** @@ -78,8 +78,8 @@ private function getArguments() { $hidden = $this->getHiddenArguments(); - return array_filter($this->getNativeDefinition()->getArguments(), function ($argument) use ($hidden) { - return !in_array($argument->getName(), $hidden); + return \array_filter($this->getNativeDefinition()->getArguments(), function ($argument) use ($hidden) { + return !\in_array($argument->getName(), $hidden); }); } @@ -90,7 +90,7 @@ private function getArguments() */ protected function getHiddenArguments() { - return array('command'); + return ['command']; } /** @@ -100,8 +100,8 @@ private function getOptions() { $hidden = $this->getHiddenOptions(); - return array_filter($this->getNativeDefinition()->getOptions(), function ($option) use ($hidden) { - return !in_array($option->getName(), $hidden); + return \array_filter($this->getNativeDefinition()->getOptions(), function ($option) use ($hidden) { + return !\in_array($option->getName(), $hidden); }); } @@ -112,7 +112,7 @@ private function getOptions() */ protected function getHiddenOptions() { - return array('verbose'); + return ['verbose']; } /** @@ -122,7 +122,7 @@ protected function getHiddenOptions() */ private function aliasesAsText() { - return 'Aliases: ' . implode(', ', $this->getAliases()) . '' . PHP_EOL; + return 'Aliases: ' . \implode(', ', $this->getAliases()) . '' . PHP_EOL; } /** @@ -133,27 +133,27 @@ private function aliasesAsText() private function argumentsAsText() { $max = $this->getMaxWidth(); - $messages = array(); + $messages = []; $arguments = $this->getArguments(); if (!empty($arguments)) { $messages[] = 'Arguments:'; foreach ($arguments as $argument) { - if (null !== $argument->getDefault() && (!is_array($argument->getDefault()) || count($argument->getDefault()))) { - $default = sprintf(' (default: %s)', $this->formatDefaultValue($argument->getDefault())); + if (null !== $argument->getDefault() && (!\is_array($argument->getDefault()) || \count($argument->getDefault()))) { + $default = \sprintf(' (default: %s)', $this->formatDefaultValue($argument->getDefault())); } else { $default = ''; } - $description = str_replace("\n", "\n" . str_pad('', $max + 2, ' '), $argument->getDescription()); + $description = \str_replace("\n", "\n" . \str_pad('', $max + 2, ' '), $argument->getDescription()); - $messages[] = sprintf(" %-${max}s %s%s", $argument->getName(), $description, $default); + $messages[] = \sprintf(" %-${max}s %s%s", $argument->getName(), $description, $default); } $messages[] = ''; } - return implode(PHP_EOL, $messages); + return \implode(PHP_EOL, $messages); } /** @@ -164,27 +164,27 @@ private function argumentsAsText() private function optionsAsText() { $max = $this->getMaxWidth(); - $messages = array(); + $messages = []; $options = $this->getOptions(); if ($options) { $messages[] = 'Options:'; foreach ($options as $option) { - if ($option->acceptValue() && null !== $option->getDefault() && (!is_array($option->getDefault()) || count($option->getDefault()))) { - $default = sprintf(' (default: %s)', $this->formatDefaultValue($option->getDefault())); + if ($option->acceptValue() && null !== $option->getDefault() && (!\is_array($option->getDefault()) || \count($option->getDefault()))) { + $default = \sprintf(' (default: %s)', $this->formatDefaultValue($option->getDefault())); } else { $default = ''; } $multiple = $option->isArray() ? ' (multiple values allowed)' : ''; - $description = str_replace("\n", "\n" . str_pad('', $max + 2, ' '), $option->getDescription()); + $description = \str_replace("\n", "\n" . \str_pad('', $max + 2, ' '), $option->getDescription()); - $optionMax = $max - strlen($option->getName()) - 2; - $messages[] = sprintf( + $optionMax = $max - \strlen($option->getName()) - 2; + $messages[] = \sprintf( " %s %-${optionMax}s%s%s%s", '--' . $option->getName(), - $option->getShortcut() ? sprintf('(-%s) ', $option->getShortcut()) : '', + $option->getShortcut() ? \sprintf('(-%s) ', $option->getShortcut()) : '', $description, $default, $multiple @@ -194,7 +194,7 @@ private function optionsAsText() $messages[] = ''; } - return implode(PHP_EOL, $messages); + return \implode(PHP_EOL, $messages); } /** @@ -207,16 +207,16 @@ private function getMaxWidth() $max = 0; foreach ($this->getOptions() as $option) { - $nameLength = strlen($option->getName()) + 2; + $nameLength = \strlen($option->getName()) + 2; if ($option->getShortcut()) { - $nameLength += strlen($option->getShortcut()) + 3; + $nameLength += \strlen($option->getShortcut()) + 3; } - $max = max($max, $nameLength); + $max = \max($max, $nameLength); } foreach ($this->getArguments() as $argument) { - $max = max($max, strlen($argument->getName())); + $max = \max($max, \strlen($argument->getName())); } return ++$max; @@ -231,11 +231,11 @@ private function getMaxWidth() */ private function formatDefaultValue($default) { - if (is_array($default) && $default === array_values($default)) { - return sprintf("array('%s')", implode("', '", $default)); + if (\is_array($default) && $default === \array_values($default)) { + return \sprintf("array('%s')", \implode("', '", $default)); } - return str_replace("\n", '', var_export($default, true)); + return \str_replace("\n", '', \var_export($default, true)); } /** @@ -247,7 +247,7 @@ private function formatDefaultValue($default) */ protected function getTable(OutputInterface $output) { - if (!class_exists('Symfony\Component\Console\Helper\Table')) { + if (!\class_exists('Symfony\Component\Console\Helper\Table')) { return $this->getTableHelper(); } @@ -260,7 +260,7 @@ protected function getTable(OutputInterface $output) $table = new Table($output); return $table - ->setRows(array()) + ->setRows([]) ->setStyle($style); } @@ -274,7 +274,7 @@ protected function getTableHelper() $table = $this->getApplication()->getHelperSet()->get('table'); return $table - ->setRows(array()) + ->setRows([]) ->setLayout(TableHelper::LAYOUT_BORDERLESS) ->setHorizontalBorderChar('') ->setCrossingChar(''); diff --git a/app/vendor/psy/psysh/src/Psy/Command/DocCommand.php b/app/vendor/psy/psysh/src/Command/DocCommand.php similarity index 77% rename from app/vendor/psy/psysh/src/Psy/Command/DocCommand.php rename to app/vendor/psy/psysh/src/Command/DocCommand.php index 9f5fb5b9a..913634a0a 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/DocCommand.php +++ b/app/vendor/psy/psysh/src/Command/DocCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,8 +13,8 @@ use Psy\Formatter\DocblockFormatter; use Psy\Formatter\SignatureFormatter; +use Psy\Input\CodeArgument; use Psy\Reflection\ReflectionLanguageConstruct; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -30,10 +30,10 @@ protected function configure() { $this ->setName('doc') - ->setAliases(array('rtfm', 'man')) - ->setDefinition(array( - new InputArgument('value', InputArgument::REQUIRED, 'Function, class, instance, constant, method or property to document.'), - )) + ->setAliases(['rtfm', 'man']) + ->setDefinition([ + new CodeArgument('target', CodeArgument::REQUIRED, 'Function, class, instance, constant, method or property to document.'), + ]) ->setDescription('Read the documentation for an object, class, constant, method or property.') ->setHelp( <<getArgument('value'); + $value = $input->getArgument('target'); if (ReflectionLanguageConstruct::isLanguageConstruct($value)) { $reflector = new ReflectionLanguageConstruct($value); $doc = $this->getManualDocById($value); @@ -86,7 +86,7 @@ protected function execute(InputInterface $input, OutputInterface $output) private function getManualDoc($reflector) { - switch (get_class($reflector)) { + switch (\get_class($reflector)) { case 'ReflectionClass': case 'ReflectionObject': case 'ReflectionFunction': @@ -101,6 +101,18 @@ private function getManualDoc($reflector) $id = $reflector->class . '::$' . $reflector->name; break; + case 'ReflectionClassConstant': + case 'Psy\Reflection\ReflectionClassConstant': + // @todo this is going to collide with ReflectionMethod ids + // someday... start running the query by id + type if the DB + // supports it. + $id = $reflector->class . '::' . $reflector->name; + break; + + case 'Psy\Reflection\ReflectionConstant_': + $id = $reflector->name; + break; + default: return false; } @@ -112,7 +124,7 @@ private function getManualDocById($id) { if ($db = $this->getApplication()->getManualDb()) { return $db - ->query(sprintf('SELECT doc FROM php_manual WHERE id = %s', $db->quote($id))) + ->query(\sprintf('SELECT doc FROM php_manual WHERE id = %s', $db->quote($id))) ->fetchColumn(0); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/DumpCommand.php b/app/vendor/psy/psysh/src/Command/DumpCommand.php similarity index 62% rename from app/vendor/psy/psysh/src/Psy/Command/DumpCommand.php rename to app/vendor/psy/psysh/src/Command/DumpCommand.php index abb9b88a9..9a8aad826 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/DumpCommand.php +++ b/app/vendor/psy/psysh/src/Command/DumpCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,10 +11,9 @@ namespace Psy\Command; -use Psy\Exception\RuntimeException; +use Psy\Input\CodeArgument; use Psy\VarDumper\Presenter; use Psy\VarDumper\PresenterAware; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -45,11 +44,11 @@ protected function configure() { $this ->setName('dump') - ->setDefinition(array( - new InputArgument('target', InputArgument::REQUIRED, 'A target object or primitive to dump.', null), - new InputOption('depth', '', InputOption::VALUE_REQUIRED, 'Depth to parse', 10), + ->setDefinition([ + new CodeArgument('target', CodeArgument::REQUIRED, 'A target object or primitive to dump.'), + new InputOption('depth', '', InputOption::VALUE_REQUIRED, 'Depth to parse.', 10), new InputOption('all', 'a', InputOption::VALUE_NONE, 'Include private and protected methods and properties.'), - )) + ]) ->setDescription('Dump an object or primitive.') ->setHelp( <<<'HELP' @@ -60,6 +59,7 @@ protected function configure() e.g. >>> dump $_ >>> dump $someVar +>>> dump $stuff->getAll() HELP ); } @@ -70,36 +70,25 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { $depth = $input->getOption('depth'); - $target = $this->resolveTarget($input->getArgument('target')); + $target = $this->resolveCode($input->getArgument('target')); $output->page($this->presenter->present($target, $depth, $input->getOption('all') ? Presenter::VERBOSE : 0)); - if (is_object($target)) { + if (\is_object($target)) { $this->setCommandScopeVariables(new \ReflectionObject($target)); } } /** - * Resolve dump target name. + * @deprecated Use `resolveCode` instead * - * @throws RuntimeException if target name does not exist in the current scope - * - * @param string $target + * @param string $name * * @return mixed */ - protected function resolveTarget($target) + protected function resolveTarget($name) { - $matches = array(); - if (preg_match(self::SUPERGLOBAL, $target, $matches)) { - if (!array_key_exists($matches[1], $GLOBALS)) { - throw new RuntimeException('Unknown target: ' . $target); - } + @\trigger_error('`resolveTarget` is deprecated; use `resolveCode` instead.', E_USER_DEPRECATED); - return $GLOBALS[$matches[1]]; - } elseif (preg_match(self::INSTANCE, $target, $matches)) { - return $this->getScopeVariable($matches[1]); - } else { - throw new RuntimeException('Unknown target: ' . $target); - } + return $this->resolveCode($name); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/EditCommand.php b/app/vendor/psy/psysh/src/Command/EditCommand.php similarity index 88% rename from app/vendor/psy/psysh/src/Psy/Command/EditCommand.php rename to app/vendor/psy/psysh/src/Command/EditCommand.php index a1c6ee434..057141494 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/EditCommand.php +++ b/app/vendor/psy/psysh/src/Command/EditCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -49,7 +49,7 @@ protected function configure() { $this ->setName('edit') - ->setDefinition(array( + ->setDefinition([ new InputArgument('file', InputArgument::OPTIONAL, 'The file to open for editing. If this is not given, edits a temporary file.', null), new InputOption( 'exec', @@ -65,7 +65,7 @@ protected function configure() 'Do not execute the file content after editing. This is the default when a file name argument is given.', null ), - )) + ]) ->setDescription('Open an external editor. Afterwards, get produced code in input buffer.') ->setHelp('Set the EDITOR environment variable to something you\'d like to use.'); } @@ -81,7 +81,7 @@ protected function execute(InputInterface $input, OutputInterface $output) { if ($input->getOption('exec') && $input->getOption('no-exec')) { - throw new \InvalidArgumentException('The --exec and --no-exec flags are mutually exclusive.'); + throw new \InvalidArgumentException('The --exec and --no-exec flags are mutually exclusive'); } $filePath = $this->extractFilePath($input->getArgument('file')); @@ -95,7 +95,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $shouldRemoveFile = false; if ($filePath === null) { - $filePath = tempnam($this->runtimeDir, 'psysh-edit-command'); + $filePath = \tempnam($this->runtimeDir, 'psysh-edit-command'); $shouldRemoveFile = true; } @@ -138,9 +138,9 @@ private function extractFilePath($fileArgument) { // If the file argument was a variable, get it from the context if ($fileArgument !== null && - strlen($fileArgument) > 0 && + \strlen($fileArgument) > 0 && $fileArgument[0] === '$') { - $fileArgument = $this->context->get(preg_replace('/^\$/', '', $fileArgument)); + $fileArgument = $this->context->get(\preg_replace('/^\$/', '', $fileArgument)); } return $fileArgument; @@ -156,16 +156,16 @@ private function extractFilePath($fileArgument) */ private function editFile($filePath, $shouldRemoveFile) { - $escapedFilePath = escapeshellarg($filePath); + $escapedFilePath = \escapeshellarg($filePath); - $pipes = array(); - $proc = proc_open((getenv('EDITOR') ?: 'nano') . " {$escapedFilePath}", array(STDIN, STDOUT, STDERR), $pipes); - proc_close($proc); + $pipes = []; + $proc = \proc_open((\getenv('EDITOR') ?: 'nano') . " {$escapedFilePath}", [STDIN, STDOUT, STDERR], $pipes); + \proc_close($proc); - $editedContent = @file_get_contents($filePath); + $editedContent = @\file_get_contents($filePath); if ($shouldRemoveFile) { - @unlink($filePath); + @\unlink($filePath); } if ($editedContent === false) { diff --git a/app/vendor/psy/psysh/src/Psy/Command/ExitCommand.php b/app/vendor/psy/psysh/src/Command/ExitCommand.php similarity index 85% rename from app/vendor/psy/psysh/src/Psy/Command/ExitCommand.php rename to app/vendor/psy/psysh/src/Command/ExitCommand.php index 10c64b476..433988612 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ExitCommand.php +++ b/app/vendor/psy/psysh/src/Command/ExitCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -29,8 +29,8 @@ protected function configure() { $this ->setName('exit') - ->setAliases(array('quit', 'q')) - ->setDefinition(array()) + ->setAliases(['quit', 'q']) + ->setDefinition([]) ->setDescription('End the current session and return to caller.') ->setHelp( <<<'HELP' @@ -47,6 +47,6 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - throw new BreakException('Goodbye.'); + throw new BreakException('Goodbye'); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/HelpCommand.php b/app/vendor/psy/psysh/src/Command/HelpCommand.php similarity index 86% rename from app/vendor/psy/psysh/src/Psy/Command/HelpCommand.php rename to app/vendor/psy/psysh/src/Command/HelpCommand.php index fd32ddefa..82ec3a835 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/HelpCommand.php +++ b/app/vendor/psy/psysh/src/Command/HelpCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -32,10 +32,10 @@ protected function configure() { $this ->setName('help') - ->setAliases(array('?')) - ->setDefinition(array( - new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', null), - )) + ->setAliases(['?']) + ->setDefinition([ + new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name.', null), + ]) ->setDescription('Show a list of commands. Type `help [foo]` for information about [foo].') ->setHelp('My. How meta.'); } @@ -74,16 +74,16 @@ protected function execute(InputInterface $input, OutputInterface $output) } if ($command->getAliases()) { - $aliases = sprintf('Aliases: %s', implode(', ', $command->getAliases())); + $aliases = \sprintf('Aliases: %s', \implode(', ', $command->getAliases())); } else { $aliases = ''; } - $table->addRow(array( - sprintf('%s', $name), + $table->addRow([ + \sprintf('%s', $name), $command->getDescription(), $aliases, - )); + ]); } $output->startPaging(); diff --git a/app/vendor/psy/psysh/src/Psy/Command/HistoryCommand.php b/app/vendor/psy/psysh/src/Command/HistoryCommand.php similarity index 75% rename from app/vendor/psy/psysh/src/Psy/Command/HistoryCommand.php rename to app/vendor/psy/psysh/src/Command/HistoryCommand.php index da2d32743..23f6899e3 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/HistoryCommand.php +++ b/app/vendor/psy/psysh/src/Command/HistoryCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -27,6 +27,7 @@ class HistoryCommand extends Command { private $filter; + private $readline; /** * {@inheritdoc} @@ -57,9 +58,9 @@ protected function configure() $this ->setName('history') - ->setAliases(array('hist')) - ->setDefinition(array( - new InputOption('show', 's', InputOption::VALUE_REQUIRED, 'Show the given range of lines'), + ->setAliases(['hist']) + ->setDefinition([ + new InputOption('show', 's', InputOption::VALUE_REQUIRED, 'Show the given range of lines.'), new InputOption('head', 'H', InputOption::VALUE_REQUIRED, 'Display the first N items.'), new InputOption('tail', 'T', InputOption::VALUE_REQUIRED, 'Display the last N items.'), @@ -70,9 +71,9 @@ protected function configure() new InputOption('no-numbers', 'N', InputOption::VALUE_NONE, 'Omit line numbers.'), new InputOption('save', '', InputOption::VALUE_REQUIRED, 'Save history to a file.'), - new InputOption('replay', '', InputOption::VALUE_NONE, 'Replay'), + new InputOption('replay', '', InputOption::VALUE_NONE, 'Replay.'), new InputOption('clear', '', InputOption::VALUE_NONE, 'Clear the history.'), - )) + ]) ->setDescription('Show the Psy Shell history.') ->setHelp( <<<'HELP' @@ -92,8 +93,8 @@ protected function configure() */ protected function execute(InputInterface $input, OutputInterface $output) { - $this->validateOnlyOne($input, array('show', 'head', 'tail')); - $this->validateOnlyOne($input, array('save', 'replay', 'clear')); + $this->validateOnlyOne($input, ['show', 'head', 'tail']); + $this->validateOnlyOne($input, ['save', 'replay', 'clear']); $history = $this->getHistorySlice( $input->getOption('show'), @@ -104,16 +105,16 @@ protected function execute(InputInterface $input, OutputInterface $output) $this->filter->bind($input); if ($this->filter->hasFilter()) { - $matches = array(); - $highlighted = array(); + $matches = []; + $highlighted = []; foreach ($history as $i => $line) { if ($this->filter->match($line, $matches)) { if (isset($matches[0])) { - $chunks = explode($matches[0], $history[$i]); - $chunks = array_map(array(__CLASS__, 'escape'), $chunks); - $glue = sprintf('%s', self::escape($matches[0])); + $chunks = \explode($matches[0], $history[$i]); + $chunks = \array_map([__CLASS__, 'escape'], $chunks); + $glue = \sprintf('%s', self::escape($matches[0])); - $highlighted[$i] = implode($glue, $chunks); + $highlighted[$i] = \implode($glue, $chunks); } } else { unset($history[$i]); @@ -122,16 +123,16 @@ protected function execute(InputInterface $input, OutputInterface $output) } if ($save = $input->getOption('save')) { - $output->writeln(sprintf('Saving history in %s...', $save)); - file_put_contents($save, implode(PHP_EOL, $history) . PHP_EOL); + $output->writeln(\sprintf('Saving history in %s...', $save)); + \file_put_contents($save, \implode(PHP_EOL, $history) . PHP_EOL); $output->writeln('History saved.'); } elseif ($input->getOption('replay')) { if (!($input->getOption('show') || $input->getOption('head') || $input->getOption('tail'))) { - throw new \InvalidArgumentException('You must limit history via --head, --tail or --show before replaying.'); + throw new \InvalidArgumentException('You must limit history via --head, --tail or --show before replaying'); } - $count = count($history); - $output->writeln(sprintf('Replaying %d line%s of history', $count, ($count !== 1) ? 's' : '')); + $count = \count($history); + $output->writeln(\sprintf('Replaying %d line%s of history', $count, ($count !== 1) ? 's' : '')); $this->getApplication()->addInput($history); } elseif ($input->getOption('clear')) { $this->clearHistory(); @@ -155,16 +156,16 @@ protected function execute(InputInterface $input, OutputInterface $output) */ private function extractRange($range) { - if (preg_match('/^\d+$/', $range)) { - return array($range, $range + 1); + if (\preg_match('/^\d+$/', $range)) { + return [$range, $range + 1]; } - $matches = array(); - if ($range !== '..' && preg_match('/^(\d*)\.\.(\d*)$/', $range, $matches)) { - $start = $matches[1] ? intval($matches[1]) : 0; - $end = $matches[2] ? intval($matches[2]) + 1 : PHP_INT_MAX; + $matches = []; + if ($range !== '..' && \preg_match('/^(\d*)\.\.(\d*)$/', $range, $matches)) { + $start = $matches[1] ? \intval($matches[1]) : 0; + $end = $matches[2] ? \intval($matches[2]) + 1 : PHP_INT_MAX; - return array($start, $end); + return [$start, $end]; } throw new \InvalidArgumentException('Unexpected range: ' . $range); @@ -184,30 +185,30 @@ private function getHistorySlice($show, $head, $tail) $history = $this->readline->listHistory(); // don't show the current `history` invocation - array_pop($history); + \array_pop($history); if ($show) { list($start, $end) = $this->extractRange($show); $length = $end - $start; } elseif ($head) { - if (!preg_match('/^\d+$/', $head)) { - throw new \InvalidArgumentException('Please specify an integer argument for --head.'); + if (!\preg_match('/^\d+$/', $head)) { + throw new \InvalidArgumentException('Please specify an integer argument for --head'); } $start = 0; - $length = intval($head); + $length = \intval($head); } elseif ($tail) { - if (!preg_match('/^\d+$/', $tail)) { - throw new \InvalidArgumentException('Please specify an integer argument for --tail.'); + if (!\preg_match('/^\d+$/', $tail)) { + throw new \InvalidArgumentException('Please specify an integer argument for --tail'); } - $start = count($history) - $tail; - $length = intval($tail) + 1; + $start = \count($history) - $tail; + $length = \intval($tail) + 1; } else { return $history; } - return array_slice($history, $start, $length, true); + return \array_slice($history, $start, $length, true); } /** @@ -226,7 +227,7 @@ private function validateOnlyOne(InputInterface $input, array $options) } if ($count > 1) { - throw new \InvalidArgumentException('Please specify only one of --' . implode(', --', $options)); + throw new \InvalidArgumentException('Please specify only one of --' . \implode(', --', $options)); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand.php b/app/vendor/psy/psysh/src/Command/ListCommand.php similarity index 86% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand.php rename to app/vendor/psy/psysh/src/Command/ListCommand.php index 8ce022757..67f4e041e 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,12 +20,12 @@ use Psy\Command\ListCommand\PropertyEnumerator; use Psy\Command\ListCommand\VariableEnumerator; use Psy\Exception\RuntimeException; +use Psy\Input\CodeArgument; use Psy\Input\FilterOptions; use Psy\VarDumper\Presenter; use Psy\VarDumper\PresenterAware; use Symfony\Component\Console\Formatter\OutputFormatter; use Symfony\Component\Console\Helper\TableHelper; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -41,7 +41,7 @@ class ListCommand extends ReflectingCommand implements PresenterAware /** * PresenterAware interface. * - * @param Presenter $manager + * @param Presenter $presenter */ public function setPresenter(Presenter $presenter) { @@ -57,9 +57,9 @@ protected function configure() $this ->setName('ls') - ->setAliases(array('list', 'dir')) - ->setDefinition(array( - new InputArgument('target', InputArgument::OPTIONAL, 'A target class or object to list.', null), + ->setAliases(['list', 'dir']) + ->setDefinition([ + new CodeArgument('target', CodeArgument::OPTIONAL, 'A target class or object to list.'), new InputOption('vars', '', InputOption::VALUE_NONE, 'Display variables.'), new InputOption('constants', 'c', InputOption::VALUE_NONE, 'Display defined constants.'), @@ -84,7 +84,7 @@ protected function configure() new InputOption('all', 'a', InputOption::VALUE_NONE, 'Include private and protected methods and properties.'), new InputOption('long', 'l', InputOption::VALUE_NONE, 'List in long format: includes class names and method signatures.'), - )) + ]) ->setDescription('List local, instance or class variables, methods and constants.') ->setHelp( <<<'HELP' @@ -104,6 +104,7 @@ protected function configure() >>> ls -al ReflectionClass >>> ls --constants --category date >>> ls -l --functions --grep /^array_.*/ +>>> ls -l --properties new DateTime() HELP ); } @@ -119,7 +120,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $method = $input->getOption('long') ? 'writeLong' : 'write'; if ($target = $input->getArgument('target')) { - list($target, $reflector) = $this->getTargetAndReflector($target, true); + list($target, $reflector) = $this->getTargetAndReflector($target); } else { $reflector = null; } @@ -151,7 +152,7 @@ protected function initEnumerators() if (!isset($this->enumerators)) { $mgr = $this->presenter; - $this->enumerators = array( + $this->enumerators = [ new ClassConstantEnumerator($mgr), new ClassEnumerator($mgr), new ConstantEnumerator($mgr), @@ -160,7 +161,7 @@ protected function initEnumerators() new PropertyEnumerator($mgr), new MethodEnumerator($mgr), new VariableEnumerator($mgr, $this->context), - ); + ]; } } @@ -177,8 +178,8 @@ protected function write(OutputInterface $output, array $result = null) } foreach ($result as $label => $items) { - $names = array_map(array($this, 'formatItemName'), $items); - $output->writeln(sprintf('%s: %s', $label, implode(', ', $names))); + $names = \array_map([$this, 'formatItemName'], $items); + $output->writeln(\sprintf('%s: %s', $label, \implode(', ', $names))); } } @@ -200,11 +201,11 @@ protected function writeLong(OutputInterface $output, array $result = null) foreach ($result as $label => $items) { $output->writeln(''); - $output->writeln(sprintf('%s:', $label)); + $output->writeln(\sprintf('%s:', $label)); - $table->setRows(array()); + $table->setRows([]); foreach ($items as $item) { - $table->addRow(array($this->formatItemName($item), $item['value'])); + $table->addRow([$this->formatItemName($item), $item['value']]); } if ($table instanceof TableHelper) { @@ -224,7 +225,7 @@ protected function writeLong(OutputInterface $output, array $result = null) */ private function formatItemName($item) { - return sprintf('<%s>%s', $item['style'], OutputFormatter::escape($item['name']), $item['style']); + return \sprintf('<%s>%s', $item['style'], OutputFormatter::escape($item['name']), $item['style']); } /** @@ -238,13 +239,13 @@ private function validateInput(InputInterface $input) { if (!$input->getArgument('target')) { // if no target is passed, there can be no properties or methods - foreach (array('properties', 'methods', 'no-inherit') as $option) { + foreach (['properties', 'methods', 'no-inherit'] as $option) { if ($input->getOption($option)) { - throw new RuntimeException('--' . $option . ' does not make sense without a specified target.'); + throw new RuntimeException('--' . $option . ' does not make sense without a specified target'); } } - foreach (array('globals', 'vars', 'constants', 'functions', 'classes', 'interfaces', 'traits') as $option) { + foreach (['globals', 'vars', 'constants', 'functions', 'classes', 'interfaces', 'traits'] as $option) { if ($input->getOption($option)) { return; } @@ -254,13 +255,13 @@ private function validateInput(InputInterface $input) $input->setOption('vars', true); } else { // if a target is passed, classes, functions, etc don't make sense - foreach (array('vars', 'globals', 'functions', 'classes', 'interfaces', 'traits') as $option) { + foreach (['vars', 'globals', 'functions', 'classes', 'interfaces', 'traits'] as $option) { if ($input->getOption($option)) { - throw new RuntimeException('--' . $option . ' does not make sense with a specified target.'); + throw new RuntimeException('--' . $option . ' does not make sense with a specified target'); } } - foreach (array('constants', 'properties', 'methods') as $option) { + foreach (['constants', 'properties', 'methods'] as $option) { if ($input->getOption($option)) { return; } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassConstantEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/ClassConstantEnumerator.php similarity index 84% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassConstantEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/ClassConstantEnumerator.php index fc974b2d9..a1d82ead6 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassConstantEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/ClassConstantEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,7 @@ namespace Psy\Command\ListCommand; -use Psy\Reflection\ReflectionConstant; +use Psy\Reflection\ReflectionClassConstant; use Symfony\Component\Console\Input\InputInterface; /** @@ -48,7 +48,7 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null return; } - $ret = array(); + $ret = []; $ret[$this->getKindLabel($reflector)] = $constants; return $ret; @@ -66,9 +66,9 @@ protected function getConstants(\Reflector $reflector, $noInherit = false) { $className = $reflector->getName(); - $constants = array(); + $constants = []; foreach ($reflector->getConstants() as $name => $constant) { - $constReflector = new ReflectionConstant($reflector, $name); + $constReflector = ReflectionClassConstant::create($reflector->name, $name); if ($noInherit && $constReflector->getDeclaringClass()->getName() !== $className) { continue; @@ -77,9 +77,7 @@ protected function getConstants(\Reflector $reflector, $noInherit = false) $constants[$name] = $constReflector; } - // @todo switch to ksort after we drop support for 5.3: - // ksort($constants, SORT_NATURAL | SORT_FLAG_CASE); - uksort($constants, 'strnatcasecmp'); + \ksort($constants, SORT_NATURAL | SORT_FLAG_CASE); return $constants; } @@ -94,15 +92,15 @@ protected function getConstants(\Reflector $reflector, $noInherit = false) protected function prepareConstants(array $constants) { // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($constants as $name => $constant) { if ($this->showItem($name)) { - $ret[$name] = array( + $ret[$name] = [ 'name' => $name, 'style' => self::IS_CONSTANT, 'value' => $this->presentRef($constant->getValue()), - ); + ]; } } @@ -120,7 +118,7 @@ protected function getKindLabel(\ReflectionClass $reflector) { if ($reflector->isInterface()) { return 'Interface Constants'; - } elseif (method_exists($reflector, 'isTrait') && $reflector->isTrait()) { + } elseif (\method_exists($reflector, 'isTrait') && $reflector->isTrait()) { return 'Trait Constants'; } else { return 'Class Constants'; diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/ClassEnumerator.php similarity index 73% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/ClassEnumerator.php index 6dcabe28d..8ab6d7a95 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/ClassEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/ClassEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -38,23 +38,23 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null $user = $input->getOption('user'); $internal = $input->getOption('internal'); - $ret = array(); + $ret = []; // only list classes, interfaces and traits if we are specifically asked if ($input->getOption('classes')) { - $ret = array_merge($ret, $this->filterClasses('Classes', get_declared_classes(), $internal, $user)); + $ret = \array_merge($ret, $this->filterClasses('Classes', \get_declared_classes(), $internal, $user)); } if ($input->getOption('interfaces')) { - $ret = array_merge($ret, $this->filterClasses('Interfaces', get_declared_interfaces(), $internal, $user)); + $ret = \array_merge($ret, $this->filterClasses('Interfaces', \get_declared_interfaces(), $internal, $user)); } - if (function_exists('get_declared_traits') && $input->getOption('traits')) { - $ret = array_merge($ret, $this->filterClasses('Traits', get_declared_traits(), $internal, $user)); + if ($input->getOption('traits')) { + $ret = \array_merge($ret, $this->filterClasses('Traits', \get_declared_traits(), $internal, $user)); } - return array_map(array($this, 'prepareClasses'), array_filter($ret)); + return \array_map([$this, 'prepareClasses'], \array_filter($ret)); } /** @@ -72,10 +72,10 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null */ protected function filterClasses($key, $classes, $internal, $user) { - $ret = array(); + $ret = []; if ($internal) { - $ret['Internal ' . $key] = array_filter($classes, function ($class) { + $ret['Internal ' . $key] = \array_filter($classes, function ($class) { $refl = new \ReflectionClass($class); return $refl->isInternal(); @@ -83,7 +83,7 @@ protected function filterClasses($key, $classes, $internal, $user) } if ($user) { - $ret['User ' . $key] = array_filter($classes, function ($class) { + $ret['User ' . $key] = \array_filter($classes, function ($class) { $refl = new \ReflectionClass($class); return !$refl->isInternal(); @@ -100,24 +100,24 @@ protected function filterClasses($key, $classes, $internal, $user) /** * Prepare formatted class array. * - * @param array $class + * @param array $classes * * @return array */ protected function prepareClasses(array $classes) { - natcasesort($classes); + \natcasesort($classes); // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($classes as $name) { if ($this->showItem($name)) { - $ret[$name] = array( + $ret[$name] = [ 'name' => $name, 'style' => self::IS_CLASS, 'value' => $this->presentSignature($name), - ); + ]; } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/ConstantEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/ConstantEnumerator.php similarity index 83% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/ConstantEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/ConstantEnumerator.php index 88d348d0a..ad4ce0d12 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/ConstantEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/ConstantEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -43,7 +43,7 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null $internal = $input->getOption('internal'); $category = $input->getOption('category'); - $ret = array(); + $ret = []; if ($user) { $ret['User Constants'] = $this->getConstants('user'); @@ -54,7 +54,7 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null } if ($category) { - $label = ucfirst($category) . ' Constants'; + $label = \ucfirst($category) . ' Constants'; $ret[$label] = $this->getConstants($category); } @@ -62,7 +62,7 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null $ret['Constants'] = $this->getConstants(); } - return array_map(array($this, 'prepareConstants'), array_filter($ret)); + return \array_map([$this, 'prepareConstants'], \array_filter($ret)); } /** @@ -78,18 +78,18 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null protected function getConstants($category = null) { if (!$category) { - return get_defined_constants(); + return \get_defined_constants(); } - $consts = get_defined_constants(true); + $consts = \get_defined_constants(true); if ($category === 'internal') { unset($consts['user']); - return call_user_func_array('array_merge', $consts); + return \call_user_func_array('array_merge', $consts); } - return isset($consts[$category]) ? $consts[$category] : array(); + return isset($consts[$category]) ? $consts[$category] : []; } /** @@ -102,18 +102,18 @@ protected function getConstants($category = null) protected function prepareConstants(array $constants) { // My kingdom for a generator. - $ret = array(); + $ret = []; - $names = array_keys($constants); - natcasesort($names); + $names = \array_keys($constants); + \natcasesort($names); foreach ($names as $name) { if ($this->showItem($name)) { - $ret[$name] = array( + $ret[$name] = [ 'name' => $name, 'style' => self::IS_CONSTANT, 'value' => $this->presentRef($constants[$name]), - ); + ]; } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/Enumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/Enumerator.php similarity index 95% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/Enumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/Enumerator.php index 2508f96fb..616543d0d 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/Enumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/Enumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -49,7 +49,7 @@ public function __construct(Presenter $presenter) * Return a list of categorized things with the given input options and target. * * @param InputInterface $input - * @param Reflector $reflector + * @param \Reflector $reflector * @param mixed $target * * @return array @@ -77,7 +77,7 @@ public function enumerate(InputInterface $input, \Reflector $reflector = null, $ * ] * * @param InputInterface $input - * @param Reflector $reflector + * @param \Reflector $reflector * @param mixed $target * * @return array diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/FunctionEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/FunctionEnumerator.php similarity index 89% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/FunctionEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/FunctionEnumerator.php index 40ba71c93..6c3fa5ea9 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/FunctionEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/FunctionEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -57,7 +57,7 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null return; } - $ret = array(); + $ret = []; $ret[$label] = $functions; return $ret; @@ -74,12 +74,12 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null */ protected function getFunctions($type = null) { - $funcs = get_defined_functions(); + $funcs = \get_defined_functions(); if ($type) { return $funcs[$type]; } else { - return array_merge($funcs['internal'], $funcs['user']); + return \array_merge($funcs['internal'], $funcs['user']); } } @@ -92,18 +92,18 @@ protected function getFunctions($type = null) */ protected function prepareFunctions(array $functions) { - natcasesort($functions); + \natcasesort($functions); // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($functions as $name) { if ($this->showItem($name)) { - $ret[$name] = array( + $ret[$name] = [ 'name' => $name, 'style' => self::IS_FUNCTION, 'value' => $this->presentSignature($name), - ); + ]; } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/GlobalVariableEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/GlobalVariableEnumerator.php similarity index 88% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/GlobalVariableEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/GlobalVariableEnumerator.php index d957e9f52..f51791cb6 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/GlobalVariableEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/GlobalVariableEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -39,9 +39,9 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null return; } - return array( + return [ 'Global Variables' => $globals, - ); + ]; } /** @@ -53,10 +53,10 @@ protected function getGlobals() { global $GLOBALS; - $names = array_keys($GLOBALS); - natcasesort($names); + $names = \array_keys($GLOBALS); + \natcasesort($names); - $ret = array(); + $ret = []; foreach ($names as $name) { $ret[$name] = $GLOBALS[$name]; } @@ -74,16 +74,16 @@ protected function getGlobals() protected function prepareGlobals($globals) { // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($globals as $name => $value) { if ($this->showItem($name)) { $fname = '$' . $name; - $ret[$fname] = array( + $ret[$fname] = [ 'name' => $fname, 'style' => self::IS_GLOBAL, 'value' => $this->presentRef($value), - ); + ]; } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/InterfaceEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/InterfaceEnumerator.php similarity index 82% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/InterfaceEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/InterfaceEnumerator.php index 91ba985d9..4531fce83 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/InterfaceEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/InterfaceEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,7 +23,8 @@ class InterfaceEnumerator extends Enumerator { public function __construct(Presenter $presenter) { - @trigger_error('InterfaceEnumerator is no longer used', E_USER_DEPRECATED); + @\trigger_error('InterfaceEnumerator is no longer used', E_USER_DEPRECATED); + parent::__construct($presenter); } /** @@ -48,15 +49,15 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null return; } - $interfaces = $this->prepareInterfaces(get_declared_interfaces()); + $interfaces = $this->prepareInterfaces(\get_declared_interfaces()); if (empty($interfaces)) { return; } - return array( + return [ 'Interfaces' => $interfaces, - ); + ]; } /** @@ -68,18 +69,18 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null */ protected function prepareInterfaces(array $interfaces) { - natcasesort($interfaces); + \natcasesort($interfaces); // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($interfaces as $name) { if ($this->showItem($name)) { - $ret[$name] = array( + $ret[$name] = [ 'name' => $name, 'style' => self::IS_CLASS, 'value' => $this->presentSignature($name), - ); + ]; } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/MethodEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/MethodEnumerator.php similarity index 89% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/MethodEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/MethodEnumerator.php index 963761cfc..49d7e104e 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/MethodEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/MethodEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -47,7 +47,7 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null return; } - $ret = array(); + $ret = []; $ret[$this->getKindLabel($reflector)] = $methods; return $ret; @@ -66,7 +66,7 @@ protected function getMethods($showAll, \Reflector $reflector, $noInherit = fals { $className = $reflector->getName(); - $methods = array(); + $methods = []; foreach ($reflector->getMethods() as $name => $method) { if ($noInherit && $method->getDeclaringClass()->getName() !== $className) { continue; @@ -77,9 +77,7 @@ protected function getMethods($showAll, \Reflector $reflector, $noInherit = fals } } - // @todo switch to ksort after we drop support for 5.3: - // ksort($methods, SORT_NATURAL | SORT_FLAG_CASE); - uksort($methods, 'strnatcasecmp'); + \ksort($methods, SORT_NATURAL | SORT_FLAG_CASE); return $methods; } @@ -94,15 +92,15 @@ protected function getMethods($showAll, \Reflector $reflector, $noInherit = fals protected function prepareMethods(array $methods) { // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($methods as $name => $method) { if ($this->showItem($name)) { - $ret[$name] = array( + $ret[$name] = [ 'name' => $name, 'style' => $this->getVisibilityStyle($method), 'value' => $this->presentSignature($method), - ); + ]; } } @@ -120,7 +118,7 @@ protected function getKindLabel(\ReflectionClass $reflector) { if ($reflector->isInterface()) { return 'Interface Methods'; - } elseif (method_exists($reflector, 'isTrait') && $reflector->isTrait()) { + } elseif (\method_exists($reflector, 'isTrait') && $reflector->isTrait()) { return 'Trait Methods'; } else { return 'Class Methods'; diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/PropertyEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/PropertyEnumerator.php similarity index 89% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/PropertyEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/PropertyEnumerator.php index db18d2ba3..d56caded6 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/PropertyEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/PropertyEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -47,7 +47,7 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null return; } - $ret = array(); + $ret = []; $ret[$this->getKindLabel($reflector)] = $properties; return $ret; @@ -66,7 +66,7 @@ protected function getProperties($showAll, \Reflector $reflector, $noInherit = f { $className = $reflector->getName(); - $properties = array(); + $properties = []; foreach ($reflector->getProperties() as $property) { if ($noInherit && $property->getDeclaringClass()->getName() !== $className) { continue; @@ -77,9 +77,7 @@ protected function getProperties($showAll, \Reflector $reflector, $noInherit = f } } - // @todo switch to ksort after we drop support for 5.3: - // ksort($properties, SORT_NATURAL | SORT_FLAG_CASE); - uksort($properties, 'strnatcasecmp'); + \ksort($properties, SORT_NATURAL | SORT_FLAG_CASE); return $properties; } @@ -94,16 +92,16 @@ protected function getProperties($showAll, \Reflector $reflector, $noInherit = f protected function prepareProperties(array $properties, $target = null) { // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($properties as $name => $property) { if ($this->showItem($name)) { $fname = '$' . $name; - $ret[$fname] = array( + $ret[$fname] = [ 'name' => $fname, 'style' => $this->getVisibilityStyle($property), 'value' => $this->presentValue($property, $target), - ); + ]; } } @@ -121,7 +119,7 @@ protected function getKindLabel(\ReflectionClass $reflector) { if ($reflector->isInterface()) { return 'Interface Properties'; - } elseif (method_exists($reflector, 'isTrait') && $reflector->isTrait()) { + } elseif (\method_exists($reflector, 'isTrait') && $reflector->isTrait()) { return 'Trait Properties'; } else { return 'Class Properties'; @@ -158,11 +156,11 @@ protected function presentValue(\ReflectionProperty $property, $target) { // If $target is a class, trait or interface (try to) get the default // value for the property. - if (!is_object($target)) { + if (!\is_object($target)) { try { $refl = new \ReflectionClass($target); $props = $refl->getDefaultProperties(); - if (array_key_exists($property->name, $props)) { + if (\array_key_exists($property->name, $props)) { $suffix = $property->isStatic() ? '' : ' '; return $this->presentRef($props[$property->name]) . $suffix; diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/TraitEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/TraitEnumerator.php similarity index 78% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/TraitEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/TraitEnumerator.php index 12941f4fe..3ee601558 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/TraitEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/TraitEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,7 +23,8 @@ class TraitEnumerator extends Enumerator { public function __construct(Presenter $presenter) { - @trigger_error('TraitEnumerator is no longer used', E_USER_DEPRECATED); + @\trigger_error('TraitEnumerator is no longer used', E_USER_DEPRECATED); + parent::__construct($presenter); } /** @@ -31,11 +32,6 @@ public function __construct(Presenter $presenter) */ protected function listItems(InputInterface $input, \Reflector $reflector = null, $target = null) { - // bail early if current PHP doesn't know about traits. - if (!function_exists('trait_exists')) { - return; - } - // only list traits when no Reflector is present. // // @todo make a NamespaceReflector and pass that in for commands like: @@ -53,15 +49,15 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null return; } - $traits = $this->prepareTraits(get_declared_traits()); + $traits = $this->prepareTraits(\get_declared_traits()); if (empty($traits)) { return; } - return array( + return [ 'Traits' => $traits, - ); + ]; } /** @@ -73,18 +69,18 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null */ protected function prepareTraits(array $traits) { - natcasesort($traits); + \natcasesort($traits); // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($traits as $name) { if ($this->showItem($name)) { - $ret[$name] = array( + $ret[$name] = [ 'name' => $name, 'style' => self::IS_CLASS, 'value' => $this->presentSignature($name), - ); + ]; } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/VariableEnumerator.php b/app/vendor/psy/psysh/src/Command/ListCommand/VariableEnumerator.php similarity index 80% rename from app/vendor/psy/psysh/src/Psy/Command/ListCommand/VariableEnumerator.php rename to app/vendor/psy/psysh/src/Command/ListCommand/VariableEnumerator.php index 55b5afcd4..0586c203e 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ListCommand/VariableEnumerator.php +++ b/app/vendor/psy/psysh/src/Command/ListCommand/VariableEnumerator.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,9 +21,9 @@ class VariableEnumerator extends Enumerator { // n.b. this array is the order in which special variables will be listed - private static $specialNames = array( + private static $specialNames = [ '_', '_e', '__out', '__function', '__method', '__class', '__namespace', '__file', '__line', '__dir', - ); + ]; private $context; @@ -64,9 +64,9 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null return; } - return array( + return [ 'Variables' => $variables, - ); + ]; } /** @@ -78,13 +78,10 @@ protected function listItems(InputInterface $input, \Reflector $reflector = null */ protected function getVariables($showAll) { - // self:: doesn't work inside closures in PHP 5.3 :-/ - $specialNames = self::$specialNames; - $scopeVars = $this->context->getAll(); - uksort($scopeVars, function ($a, $b) use ($specialNames) { - $aIndex = array_search($a, $specialNames); - $bIndex = array_search($b, $specialNames); + \uksort($scopeVars, function ($a, $b) { + $aIndex = \array_search($a, self::$specialNames); + $bIndex = \array_search($b, self::$specialNames); if ($aIndex !== false) { if ($bIndex !== false) { @@ -98,12 +95,12 @@ protected function getVariables($showAll) return -1; } - return strnatcasecmp($a, $b); + return \strnatcasecmp($a, $b); }); - $ret = array(); + $ret = []; foreach ($scopeVars as $name => $val) { - if (!$showAll && in_array($name, self::$specialNames)) { + if (!$showAll && \in_array($name, self::$specialNames)) { continue; } @@ -123,15 +120,15 @@ protected function getVariables($showAll) protected function prepareVariables(array $variables) { // My kingdom for a generator. - $ret = array(); + $ret = []; foreach ($variables as $name => $val) { if ($this->showItem($name)) { $fname = '$' . $name; - $ret[$fname] = array( + $ret[$fname] = [ 'name' => $fname, - 'style' => in_array($name, self::$specialNames) ? self::IS_PRIVATE : self::IS_PUBLIC, + 'style' => \in_array($name, self::$specialNames) ? self::IS_PRIVATE : self::IS_PUBLIC, 'value' => $this->presentRef($val), - ); + ]; } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ParseCommand.php b/app/vendor/psy/psysh/src/Command/ParseCommand.php similarity index 79% rename from app/vendor/psy/psysh/src/Psy/Command/ParseCommand.php rename to app/vendor/psy/psysh/src/Command/ParseCommand.php index 301bb614a..3f3286e8a 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ParseCommand.php +++ b/app/vendor/psy/psysh/src/Command/ParseCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,11 +13,12 @@ use PhpParser\Node; use PhpParser\Parser; +use Psy\Context; +use Psy\ContextAware; use Psy\Input\CodeArgument; use Psy\ParserFactory; use Psy\VarDumper\Presenter; use Psy\VarDumper\PresenterAware; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -26,8 +27,15 @@ /** * Parse PHP code and show the abstract syntax tree. */ -class ParseCommand extends Command implements PresenterAware +class ParseCommand extends Command implements ContextAware, PresenterAware { + /** + * Context instance (for ContextAware interface). + * + * @var Context + */ + protected $context; + private $presenter; private $parserFactory; private $parsers; @@ -38,11 +46,21 @@ class ParseCommand extends Command implements PresenterAware public function __construct($name = null) { $this->parserFactory = new ParserFactory(); - $this->parsers = array(); + $this->parsers = []; parent::__construct($name); } + /** + * ContextAware interface. + * + * @param Context $context + */ + public function setContext(Context $context) + { + $this->context = $context; + } + /** * PresenterAware interface. * @@ -51,12 +69,12 @@ public function __construct($name = null) public function setPresenter(Presenter $presenter) { $this->presenter = clone $presenter; - $this->presenter->addCasters(array( + $this->presenter->addCasters([ 'PhpParser\Node' => function (Node $node, array $a) { - $a = array( + $a = [ Caster::PREFIX_VIRTUAL . 'type' => $node->getType(), Caster::PREFIX_VIRTUAL . 'attributes' => $node->getAttributes(), - ); + ]; foreach ($node->getSubNodeNames() as $name) { $a[Caster::PREFIX_VIRTUAL . $name] = $node->$name; @@ -64,7 +82,7 @@ public function setPresenter(Presenter $presenter) return $a; }, - )); + ]); } /** @@ -72,15 +90,15 @@ public function setPresenter(Presenter $presenter) */ protected function configure() { - $definition = array( - new CodeArgument('code', InputArgument::REQUIRED, 'PHP code to parse.'), - new InputOption('depth', '', InputOption::VALUE_REQUIRED, 'Depth to parse', 10), - ); + $definition = [ + new CodeArgument('code', CodeArgument::REQUIRED, 'PHP code to parse.'), + new InputOption('depth', '', InputOption::VALUE_REQUIRED, 'Depth to parse.', 10), + ]; if ($this->parserFactory->hasKindsSupport()) { $msg = 'One of PhpParser\\ParserFactory constants: ' - . implode(', ', ParserFactory::getPossibleKinds()) - . " (default is based on current interpreter's version)"; + . \implode(', ', ParserFactory::getPossibleKinds()) + . " (default is based on current interpreter's version)."; $defaultKind = $this->parserFactory->getDefaultKind(); $definition[] = new InputOption('kind', '', InputOption::VALUE_REQUIRED, $msg, $defaultKind); @@ -110,7 +128,7 @@ protected function configure() protected function execute(InputInterface $input, OutputInterface $output) { $code = $input->getArgument('code'); - if (strpos('getOption('depth'); $nodes = $this->parse($this->getParser($parserKind), $code); $output->page($this->presenter->present($nodes, $depth)); + + $this->context->setReturnValue($nodes); } /** @@ -133,7 +153,7 @@ private function parse(Parser $parser, $code) try { return $parser->parse($code); } catch (\PhpParser\Error $e) { - if (strpos($e->getMessage(), 'unexpected EOF') === false) { + if (\strpos($e->getMessage(), 'unexpected EOF') === false) { throw $e; } @@ -151,7 +171,7 @@ private function parse(Parser $parser, $code) */ private function getParser($kind = null) { - if (!array_key_exists($kind, $this->parsers)) { + if (!\array_key_exists($kind, $this->parsers)) { $this->parsers[$kind] = $this->parserFactory->createParser($kind); } diff --git a/app/vendor/psy/psysh/src/Psy/Command/PsyVersionCommand.php b/app/vendor/psy/psysh/src/Command/PsyVersionCommand.php similarity index 92% rename from app/vendor/psy/psysh/src/Psy/Command/PsyVersionCommand.php rename to app/vendor/psy/psysh/src/Command/PsyVersionCommand.php index c245e0c5f..7d0846c1b 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/PsyVersionCommand.php +++ b/app/vendor/psy/psysh/src/Command/PsyVersionCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,7 +26,7 @@ protected function configure() { $this ->setName('version') - ->setDefinition(array()) + ->setDefinition([]) ->setDescription('Show Psy Shell version.') ->setHelp('Show Psy Shell version.'); } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ReflectingCommand.php b/app/vendor/psy/psysh/src/Command/ReflectingCommand.php similarity index 59% rename from app/vendor/psy/psysh/src/Psy/Command/ReflectingCommand.php rename to app/vendor/psy/psysh/src/Command/ReflectingCommand.php index ad142d071..328632805 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ReflectingCommand.php +++ b/app/vendor/psy/psysh/src/Command/ReflectingCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,8 +11,10 @@ namespace Psy\Command; +use Psy\CodeCleaner\NoReturnValue; use Psy\Context; use Psy\ContextAware; +use Psy\Exception\ErrorException; use Psy\Exception\RuntimeException; use Psy\Util\Mirror; @@ -22,12 +24,9 @@ abstract class ReflectingCommand extends Command implements ContextAware { const CLASS_OR_FUNC = '/^[\\\\\w]+$/'; - const INSTANCE = '/^\$(\w+)$/'; const CLASS_MEMBER = '/^([\\\\\w]+)::(\w+)$/'; const CLASS_STATIC = '/^([\\\\\w]+)::\$(\w+)$/'; - const INSTANCE_MEMBER = '/^\$(\w+)(::|->)(\w+)$/'; - const INSTANCE_STATIC = '/^\$(\w+)::\$(\w+)$/'; - const SUPERGLOBAL = '/^\$(GLOBALS|_(?:SERVER|ENV|FILES|COOKIE|POST|GET|SESSION))$/'; + const INSTANCE_MEMBER = '/^(\$\w+)(::|->)(\w+)$/'; /** * Context instance (for ContextAware interface). @@ -52,54 +51,42 @@ public function setContext(Context $context) * @throws \InvalidArgumentException when the value specified can't be resolved * * @param string $valueName Function, class, variable, constant, method or property name - * @param bool $classOnly True if the name should only refer to a class, function or instance * * @return array (class or instance name, member name, kind) */ - protected function getTarget($valueName, $classOnly = false) + protected function getTarget($valueName) { - $valueName = trim($valueName); - $matches = array(); + $valueName = \trim($valueName); + $matches = []; switch (true) { - case preg_match(self::SUPERGLOBAL, $valueName, $matches): - // @todo maybe do something interesting with these at some point? - if (array_key_exists($matches[1], $GLOBALS)) { - throw new RuntimeException('Unable to inspect a non-object'); - } - - throw new RuntimeException('Unknown target: ' . $valueName); - case preg_match(self::CLASS_OR_FUNC, $valueName, $matches): - return array($this->resolveName($matches[0], true), null, 0); - - case preg_match(self::INSTANCE, $valueName, $matches): - return array($this->resolveInstance($matches[1]), null, 0); + case \preg_match(self::CLASS_OR_FUNC, $valueName, $matches): + return [$this->resolveName($matches[0], true), null, 0]; - case !$classOnly && preg_match(self::CLASS_MEMBER, $valueName, $matches): - return array($this->resolveName($matches[1]), $matches[2], Mirror::CONSTANT | Mirror::METHOD); + case \preg_match(self::CLASS_MEMBER, $valueName, $matches): + return [$this->resolveName($matches[1]), $matches[2], Mirror::CONSTANT | Mirror::METHOD]; - case !$classOnly && preg_match(self::CLASS_STATIC, $valueName, $matches): - return array($this->resolveName($matches[1]), $matches[2], Mirror::STATIC_PROPERTY | Mirror::PROPERTY); + case \preg_match(self::CLASS_STATIC, $valueName, $matches): + return [$this->resolveName($matches[1]), $matches[2], Mirror::STATIC_PROPERTY | Mirror::PROPERTY]; - case !$classOnly && preg_match(self::INSTANCE_MEMBER, $valueName, $matches): + case \preg_match(self::INSTANCE_MEMBER, $valueName, $matches): if ($matches[2] === '->') { $kind = Mirror::METHOD | Mirror::PROPERTY; } else { $kind = Mirror::CONSTANT | Mirror::METHOD; } - return array($this->resolveInstance($matches[1]), $matches[3], $kind); - - case !$classOnly && preg_match(self::INSTANCE_STATIC, $valueName, $matches): - return array($this->resolveInstance($matches[1]), $matches[2], Mirror::STATIC_PROPERTY); + return [$this->resolveObject($matches[1]), $matches[3], $kind]; default: - throw new RuntimeException('Unknown target: ' . $valueName); + return [$this->resolveObject($valueName), null, 0]; } } /** * Resolve a class or function name (with the current shell namespace). * + * @throws ErrorException when `self` or `static` is used in a non-class scope + * * @param string $name * @param bool $includeFunctions (default: false) * @@ -107,14 +94,30 @@ protected function getTarget($valueName, $classOnly = false) */ protected function resolveName($name, $includeFunctions = false) { - if (substr($name, 0, 1) === '\\') { + $shell = $this->getApplication(); + + // While not *technically* 100% accurate, let's treat `self` and `static` as equivalent. + if (\in_array(\strtolower($name), ['self', 'static'])) { + if ($boundClass = $shell->getBoundClass()) { + return $boundClass; + } + + if ($boundObject = $shell->getBoundObject()) { + return \get_class($boundObject); + } + + $msg = \sprintf('Cannot use "%s" when no class scope is active', \strtolower($name)); + throw new ErrorException($msg, 0, E_USER_ERROR, "eval()'d code", 1); + } + + if (\substr($name, 0, 1) === '\\') { return $name; } - if ($namespace = $this->getApplication()->getNamespace()) { + if ($namespace = $shell->getNamespace()) { $fullName = $namespace . '\\' . $name; - if (class_exists($fullName) || interface_exists($fullName) || ($includeFunctions && function_exists($fullName))) { + if (\class_exists($fullName) || \interface_exists($fullName) || ($includeFunctions && \function_exists($fullName))) { return $fullName; } } @@ -126,36 +129,74 @@ protected function resolveName($name, $includeFunctions = false) * Get a Reflector and documentation for a function, class or instance, constant, method or property. * * @param string $valueName Function, class, variable, constant, method or property name - * @param bool $classOnly True if the name should only refer to a class, function or instance * * @return array (value, Reflector) */ - protected function getTargetAndReflector($valueName, $classOnly = false) + protected function getTargetAndReflector($valueName) { - list($value, $member, $kind) = $this->getTarget($valueName, $classOnly); + list($value, $member, $kind) = $this->getTarget($valueName); - return array($value, Mirror::get($value, $member, $kind)); + return [$value, Mirror::get($value, $member, $kind)]; } /** - * Return a variable instance from the current scope. + * Resolve code to a value in the current scope. * - * @throws \InvalidArgumentException when the requested variable does not exist in the current scope + * @throws RuntimeException when the code does not return a value in the current scope * - * @param string $name + * @param string $code * - * @return mixed Variable instance + * @return mixed Variable value */ - protected function resolveInstance($name) + protected function resolveCode($code) { - $value = $this->getScopeVariable($name); - if (!is_object($value)) { + try { + $value = $this->getApplication()->execute($code, true); + } catch (\Exception $e) { + // Swallow all exceptions? + } + + if (!isset($value) || $value instanceof NoReturnValue) { + throw new RuntimeException('Unknown target: ' . $code); + } + + return $value; + } + + /** + * Resolve code to an object in the current scope. + * + * @throws RuntimeException when the code resolves to a non-object value + * + * @param string $code + * + * @return object Variable instance + */ + private function resolveObject($code) + { + $value = $this->resolveCode($code); + + if (!\is_object($value)) { throw new RuntimeException('Unable to inspect a non-object'); } return $value; } + /** + * @deprecated Use `resolveCode` instead + * + * @param string $name + * + * @return mixed Variable instance + */ + protected function resolveInstance($name) + { + @\trigger_error('`resolveInstance` is deprecated; use `resolveCode` instead.', E_USER_DEPRECATED); + + return $this->resolveCode($name); + } + /** * Get a variable from the current shell scope. * @@ -187,9 +228,9 @@ protected function getScopeVariables() */ protected function setCommandScopeVariables(\Reflector $reflector) { - $vars = array(); + $vars = []; - switch (get_class($reflector)) { + switch (\get_class($reflector)) { case 'ReflectionClass': case 'ReflectionObject': $vars['__class'] = $reflector->name; @@ -199,7 +240,7 @@ protected function setCommandScopeVariables(\Reflector $reflector) break; case 'ReflectionMethod': - $vars['__method'] = sprintf('%s::%s', $reflector->class, $reflector->name); + $vars['__method'] = \sprintf('%s::%s', $reflector->class, $reflector->name); $vars['__class'] = $reflector->class; $classReflector = $reflector->getDeclaringClass(); if ($classReflector->inNamespace()) { @@ -223,12 +264,13 @@ protected function setCommandScopeVariables(\Reflector $reflector) if ($fileName = $reflector->getExecutingFile()) { $vars['__file'] = $fileName; $vars['__line'] = $reflector->getExecutingLine(); - $vars['__dir'] = dirname($fileName); + $vars['__dir'] = \dirname($fileName); } break; case 'ReflectionProperty': - case 'Psy\Reflection\ReflectionConstant': + case 'ReflectionClassConstant': + case 'Psy\Reflection\ReflectionClassConstant': $classReflector = $reflector->getDeclaringClass(); $vars['__class'] = $classReflector->name; if ($classReflector->inNamespace()) { @@ -237,7 +279,13 @@ protected function setCommandScopeVariables(\Reflector $reflector) // no line for these, but this'll do if ($fileName = $reflector->getDeclaringClass()->getFileName()) { $vars['__file'] = $fileName; - $vars['__dir'] = dirname($fileName); + $vars['__dir'] = \dirname($fileName); + } + break; + + case 'Psy\Reflection\ReflectionConstant_': + if ($reflector->inNamespace()) { + $vars['__namespace'] = $reflector->getNamespaceName(); } break; } @@ -246,7 +294,7 @@ protected function setCommandScopeVariables(\Reflector $reflector) if ($fileName = $reflector->getFileName()) { $vars['__file'] = $fileName; $vars['__line'] = $reflector->getStartLine(); - $vars['__dir'] = dirname($fileName); + $vars['__dir'] = \dirname($fileName); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/ShowCommand.php b/app/vendor/psy/psysh/src/Command/ShowCommand.php similarity index 80% rename from app/vendor/psy/psysh/src/Psy/Command/ShowCommand.php rename to app/vendor/psy/psysh/src/Command/ShowCommand.php index c4dab43d0..47d186548 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/ShowCommand.php +++ b/app/vendor/psy/psysh/src/Command/ShowCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,9 +17,9 @@ use Psy\Exception\RuntimeException; use Psy\Formatter\CodeFormatter; use Psy\Formatter\SignatureFormatter; +use Psy\Input\CodeArgument; use Psy\Output\ShellOutput; use Symfony\Component\Console\Formatter\OutputFormatter; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -41,7 +41,7 @@ public function __construct($colorMode = null) { $this->colorMode = $colorMode ?: Configuration::COLOR_MODE_AUTO; - return parent::__construct(); + parent::__construct(); } /** @@ -51,10 +51,10 @@ protected function configure() { $this ->setName('show') - ->setDefinition(array( - new InputArgument('value', InputArgument::OPTIONAL, 'Function, class, instance, constant, method or property to show.'), + ->setDefinition([ + new CodeArgument('target', CodeArgument::OPTIONAL, 'Function, class, instance, constant, method or property to show.'), new InputOption('ex', null, InputOption::VALUE_OPTIONAL, 'Show last exception context. Optionally specify a stack index.', 1), - )) + ]) ->setDescription('Show the code for an object, class, constant, method or property.') ->setHelp( <<getArgument('value')) { - throw new \InvalidArgumentException('Too many arguments (supply either "value" or "--ex")'); + if ($input->getArgument('target')) { + throw new \InvalidArgumentException('Too many arguments (supply either "target" or "--ex")'); } return $this->writeExceptionContext($input, $output); } - if ($input->getArgument('value')) { + if ($input->getArgument('target')) { return $this->writeCodeContext($input, $output); } - throw new RuntimeException('Not enough arguments (missing: "value").'); + throw new RuntimeException('Not enough arguments (missing: "target")'); } private function writeCodeContext(InputInterface $input, OutputInterface $output) { - list($value, $reflector) = $this->getTargetAndReflector($input->getArgument('value')); + list($target, $reflector) = $this->getTargetAndReflector($input->getArgument('target')); // Set some magic local variables $this->setCommandScopeVariables($reflector); @@ -140,16 +140,16 @@ private function writeExceptionContext(InputInterface $input, OutputInterface $o $index = 0; } } else { - $index = max(0, intval($input->getOption('ex')) - 1); + $index = \max(0, \intval($input->getOption('ex')) - 1); } $trace = $exception->getTrace(); - array_unshift($trace, array( + \array_unshift($trace, [ 'file' => $exception->getFile(), 'line' => $exception->getLine(), - )); + ]); - if ($index >= count($trace)) { + if ($index >= \count($trace)) { $index = 0; } @@ -169,25 +169,25 @@ private function writeTraceLine(OutputInterface $output, array $trace, $index) $file = isset($trace[$index]['file']) ? $this->replaceCwd($trace[$index]['file']) : 'n/a'; $line = isset($trace[$index]['line']) ? $trace[$index]['line'] : 'n/a'; - $output->writeln(sprintf( + $output->writeln(\sprintf( 'From %s:%d at level %d of backtrace (of %d).', OutputFormatter::escape($file), OutputFormatter::escape($line), $index + 1, - count($trace) + \count($trace) )); } private function replaceCwd($file) { - if ($cwd = getcwd()) { - $cwd = rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + if ($cwd = \getcwd()) { + $cwd = \rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } if ($cwd === false) { return $file; } else { - return preg_replace('/^' . preg_quote($cwd, '/') . '/', '', $file); + return \preg_replace('/^' . \preg_quote($cwd, '/') . '/', '', $file); } } @@ -208,8 +208,8 @@ private function writeTraceCodeSnippet(OutputInterface $output, array $trace, $i $line = $trace[$index]['line']; } - if (is_file($file)) { - $code = @file_get_contents($file); + if (\is_file($file)) { + $code = @\file_get_contents($file); } if (empty($code)) { @@ -231,16 +231,33 @@ private function getHighlighter() private function setCommandScopeVariablesFromContext(array $context) { - $vars = array(); + $vars = []; - // @todo __namespace? if (isset($context['class'])) { $vars['__class'] = $context['class']; if (isset($context['function'])) { $vars['__method'] = $context['function']; } + + try { + $refl = new \ReflectionClass($context['class']); + if ($namespace = $refl->getNamespaceName()) { + $vars['__namespace'] = $namespace; + } + } catch (\Exception $e) { + // oh well + } } elseif (isset($context['function'])) { $vars['__function'] = $context['function']; + + try { + $refl = new \ReflectionFunction($context['function']); + if ($namespace = $refl->getNamespaceName()) { + $vars['__namespace'] = $namespace; + } + } catch (\Exception $e) { + // oh well + } } if (isset($context['file'])) { @@ -251,12 +268,12 @@ private function setCommandScopeVariablesFromContext(array $context) $line = $context['line']; } - if (is_file($file)) { + if (\is_file($file)) { $vars['__file'] = $file; if (isset($line)) { $vars['__line'] = $line; } - $vars['__dir'] = dirname($file); + $vars['__dir'] = \dirname($file); } } @@ -265,8 +282,8 @@ private function setCommandScopeVariablesFromContext(array $context) private function extractEvalFileAndLine($file) { - if (preg_match('/(.*)\\((\\d+)\\) : eval\\(\\)\'d code$/', $file, $matches)) { - return array($matches[1], $matches[2]); + if (\preg_match('/(.*)\\((\\d+)\\) : eval\\(\\)\'d code$/', $file, $matches)) { + return [$matches[1], $matches[2]]; } } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/SudoCommand.php b/app/vendor/psy/psysh/src/Command/SudoCommand.php similarity index 87% rename from app/vendor/psy/psysh/src/Psy/Command/SudoCommand.php rename to app/vendor/psy/psysh/src/Command/SudoCommand.php index 1a0a65520..9d5afbf04 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/SudoCommand.php +++ b/app/vendor/psy/psysh/src/Command/SudoCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,7 +17,6 @@ use Psy\ParserFactory; use Psy\Readline\Readline; use Psy\Sudo\SudoVisitor; -use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -64,9 +63,9 @@ protected function configure() { $this ->setName('sudo') - ->setDefinition(array( - new CodeArgument('code', InputArgument::REQUIRED, 'Code to execute.'), - )) + ->setDefinition([ + new CodeArgument('code', CodeArgument::REQUIRED, 'Code to execute.'), + ]) ->setDescription('Evaluate PHP code, bypassing visibility restrictions.') ->setHelp( <<<'HELP' @@ -104,20 +103,21 @@ protected function execute(InputInterface $input, OutputInterface $output) // special case for !! if ($code === '!!') { $history = $this->readline->listHistory(); - if (count($history) < 2) { + if (\count($history) < 2) { throw new \InvalidArgumentException('No previous command to replay'); } - $code = $history[count($history) - 2]; + $code = $history[\count($history) - 2]; } - if (strpos('traverser->traverse($this->parse($code)); $sudoCode = $this->printer->prettyPrint($nodes); - $this->getApplication()->addInput($sudoCode, true); + $shell = $this->getApplication(); + $shell->addCode($sudoCode, !$shell->hasCode()); } /** @@ -132,7 +132,7 @@ private function parse($code) try { return $this->parser->parse($code); } catch (\PhpParser\Error $e) { - if (strpos($e->getMessage(), 'unexpected EOF') === false) { + if (\strpos($e->getMessage(), 'unexpected EOF') === false) { throw $e; } diff --git a/app/vendor/psy/psysh/src/Command/ThrowUpCommand.php b/app/vendor/psy/psysh/src/Command/ThrowUpCommand.php new file mode 100644 index 000000000..b37f7573c --- /dev/null +++ b/app/vendor/psy/psysh/src/Command/ThrowUpCommand.php @@ -0,0 +1,172 @@ +parser = $parserFactory->createParser(); + $this->printer = new Printer(); + + parent::__construct($name); + } + + /** + * ContextAware interface. + * + * @param Context $context + */ + public function setContext(Context $context) + { + $this->context = $context; + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('throw-up') + ->setDefinition([ + new CodeArgument('exception', CodeArgument::OPTIONAL, 'Exception or Error to throw.'), + ]) + ->setDescription('Throw an exception or error out of the Psy Shell.') + ->setHelp( + <<<'HELP' +Throws an exception or error out of the current the Psy Shell instance. + +By default it throws the most recent exception. + +e.g. +>>> throw-up +>>> throw-up $e +>>> throw-up new Exception('WHEEEEEE!') +>>> throw-up "bye!" +HELP + ); + } + + /** + * {@inheritdoc} + * + * @throws InvalidArgumentException if there is no exception to throw + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $args = $this->prepareArgs($input->getArgument('exception')); + $throwStmt = new Throw_(new StaticCall(new FullyQualifiedName(self::THROW_CLASS), 'fromThrowable', $args)); + $throwCode = $this->printer->prettyPrint([$throwStmt]); + + $shell = $this->getApplication(); + $shell->addCode($throwCode, !$shell->hasCode()); + } + + /** + * Parse the supplied command argument. + * + * If no argument was given, this falls back to `$_e` + * + * @throws InvalidArgumentException if there is no exception to throw + * + * @param string $code + * + * @return Arg[] + */ + private function prepareArgs($code = null) + { + if (!$code) { + // Default to last exception if nothing else was supplied + return [new Arg(new Variable('_e'))]; + } + + if (\strpos('parse($code); + if (\count($nodes) !== 1) { + throw new \InvalidArgumentException('No idea how to throw this'); + } + + $node = $nodes[0]; + + // Make this work for PHP Parser v3.x + $expr = isset($node->expr) ? $node->expr : $node; + + $args = [new Arg($expr, false, false, $node->getAttributes())]; + + // Allow throwing via a string, e.g. `throw-up "SUP"` + if ($expr instanceof String_) { + return [new New_(new FullyQualifiedName('Exception'), $args)]; + } + + return $args; + } + + /** + * Lex and parse a string of code into statements. + * + * @param string $code + * + * @return array Statements + */ + private function parse($code) + { + try { + return $this->parser->parse($code); + } catch (\PhpParser\Error $e) { + if (\strpos($e->getMessage(), 'unexpected EOF') === false) { + throw $e; + } + + // If we got an unexpected EOF, let's try it again with a semicolon. + return $this->parser->parse($code . ';'); + } + } +} diff --git a/app/vendor/psy/psysh/src/Command/TimeitCommand.php b/app/vendor/psy/psysh/src/Command/TimeitCommand.php new file mode 100644 index 000000000..c59663131 --- /dev/null +++ b/app/vendor/psy/psysh/src/Command/TimeitCommand.php @@ -0,0 +1,195 @@ +Command took %.6f seconds to complete.'; + const AVG_RESULT_MSG = 'Command took %.6f seconds on average (%.6f median; %.6f total) to complete.'; + + private static $start = null; + private static $times = []; + + private $parser; + private $traverser; + private $printer; + + /** + * {@inheritdoc} + */ + public function __construct($name = null) + { + $parserFactory = new ParserFactory(); + $this->parser = $parserFactory->createParser(); + + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor(new TimeitVisitor()); + + $this->printer = new Printer(); + + parent::__construct($name); + } + + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('timeit') + ->setDefinition([ + new InputOption('num', 'n', InputOption::VALUE_REQUIRED, 'Number of iterations.'), + new CodeArgument('code', CodeArgument::REQUIRED, 'Code to execute.'), + ]) + ->setDescription('Profiles with a timer.') + ->setHelp( + <<<'HELP' +Time profiling for functions and commands. + +e.g. +>>> timeit sleep(1) +>>> timeit -n1000 $closure() +HELP + ); + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $code = $input->getArgument('code'); + $num = $input->getOption('num') ?: 1; + $shell = $this->getApplication(); + + $instrumentedCode = $this->instrumentCode($code); + + self::$times = []; + + for ($i = 0; $i < $num; $i++) { + $_ = $shell->execute($instrumentedCode); + $this->ensureEndMarked(); + } + + $shell->writeReturnValue($_); + + $times = self::$times; + self::$times = []; + + if ($num === 1) { + $output->writeln(\sprintf(self::RESULT_MSG, $times[0])); + } else { + $total = \array_sum($times); + \rsort($times); + $median = $times[\round($num / 2)]; + + $output->writeln(\sprintf(self::AVG_RESULT_MSG, $total / $num, $median, $total)); + } + } + + /** + * Internal method for marking the start of timeit execution. + * + * A static call to this method will be injected at the start of the timeit + * input code to instrument the call. We will use the saved start time to + * more accurately calculate time elapsed during execution. + */ + public static function markStart() + { + self::$start = \microtime(true); + } + + /** + * Internal method for marking the end of timeit execution. + * + * A static call to this method is injected by TimeitVisitor at the end + * of the timeit input code to instrument the call. + * + * Note that this accepts an optional $ret parameter, which is used to pass + * the return value of the last statement back out of timeit. This saves us + * a bunch of code rewriting shenanigans. + * + * @param mixed $ret + * + * @return mixed it just passes $ret right back + */ + public static function markEnd($ret = null) + { + self::$times[] = \microtime(true) - self::$start; + self::$start = null; + + return $ret; + } + + /** + * Ensure that the end of code execution was marked. + * + * The end *should* be marked in the instrumented code, but just in case + * we'll add a fallback here. + */ + private function ensureEndMarked() + { + if (self::$start !== null) { + self::markEnd(); + } + } + + /** + * Instrument code for timeit execution. + * + * This inserts `markStart` and `markEnd` calls to ensure that (reasonably) + * accurate times are recorded for just the code being executed. + * + * @param string $code + * + * @return string + */ + private function instrumentCode($code) + { + return $this->printer->prettyPrint($this->traverser->traverse($this->parse($code))); + } + + /** + * Lex and parse a string of code into statements. + * + * @param string $code + * + * @return array Statements + */ + private function parse($code) + { + $code = 'parser->parse($code); + } catch (\PhpParser\Error $e) { + if (\strpos($e->getMessage(), 'unexpected EOF') === false) { + throw $e; + } + + // If we got an unexpected EOF, let's try it again with a semicolon. + return $this->parser->parse($code . ';'); + } + } +} diff --git a/app/vendor/psy/psysh/src/Command/TimeitCommand/TimeitVisitor.php b/app/vendor/psy/psysh/src/Command/TimeitCommand/TimeitVisitor.php new file mode 100644 index 000000000..841ba135d --- /dev/null +++ b/app/vendor/psy/psysh/src/Command/TimeitCommand/TimeitVisitor.php @@ -0,0 +1,139 @@ +functionDepth = 0; + } + + /** + * {@inheritdoc} + */ + public function enterNode(Node $node) + { + // keep track of nested function-like nodes, because they can have + // returns statements... and we don't want to call markEnd for those. + if ($node instanceof FunctionLike) { + $this->functionDepth++; + + return; + } + + // replace any top-level `return` statements with a `markEnd` call + if ($this->functionDepth === 0 && $node instanceof Return_) { + return new Return_($this->getEndCall($node->expr), $node->getAttributes()); + } + } + + /** + * {@inheritdoc} + */ + public function leaveNode(Node $node) + { + if ($node instanceof FunctionLike) { + $this->functionDepth--; + } + } + + /** + * {@inheritdoc} + */ + public function afterTraverse(array $nodes) + { + // prepend a `markStart` call + \array_unshift($nodes, $this->maybeExpression($this->getStartCall())); + + // append a `markEnd` call (wrapping the final node, if it's an expression) + $last = $nodes[\count($nodes) - 1]; + if ($last instanceof Expr) { + \array_pop($nodes); + $nodes[] = $this->getEndCall($last); + } elseif ($last instanceof Expression) { + \array_pop($nodes); + $nodes[] = new Expression($this->getEndCall($last->expr), $last->getAttributes()); + } elseif ($last instanceof Return_) { + // nothing to do here, we're already ending with a return call + } else { + $nodes[] = $this->maybeExpression($this->getEndCall()); + } + + return $nodes; + } + + /** + * Get PhpParser AST nodes for a `markStart` call. + * + * @return PhpParser\Node\Expr\StaticCall + */ + private function getStartCall() + { + return new StaticCall(new FullyQualifiedName('Psy\Command\TimeitCommand'), 'markStart'); + } + + /** + * Get PhpParser AST nodes for a `markEnd` call. + * + * Optionally pass in a return value. + * + * @param Expr|null $arg + * + * @return PhpParser\Node\Expr\StaticCall + */ + private function getEndCall(Expr $arg = null) + { + if ($arg === null) { + $arg = NoReturnValue::create(); + } + + return new StaticCall(new FullyQualifiedName('Psy\Command\TimeitCommand'), 'markEnd', [new Arg($arg)]); + } + + /** + * Compatibility shim for PHP Parser 3.x. + * + * Wrap $expr in a PhpParser\Node\Stmt\Expression if the class exists. + * + * @param PhpParser\Node $expr + * @param array $attrs + * + * @return PhpParser\Node\Expr|PhpParser\Node\Stmt\Expression + */ + private function maybeExpression($expr, $attrs = []) + { + return \class_exists('PhpParser\Node\Stmt\Expression') ? new Expression($expr, $attrs) : $expr; + } +} diff --git a/app/vendor/psy/psysh/src/Psy/Command/TraceCommand.php b/app/vendor/psy/psysh/src/Command/TraceCommand.php similarity index 82% rename from app/vendor/psy/psysh/src/Psy/Command/TraceCommand.php rename to app/vendor/psy/psysh/src/Command/TraceCommand.php index 00e5903fd..c28b0e728 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/TraceCommand.php +++ b/app/vendor/psy/psysh/src/Command/TraceCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -44,14 +44,14 @@ protected function configure() $this ->setName('trace') - ->setDefinition(array( + ->setDefinition([ new InputOption('include-psy', 'p', InputOption::VALUE_NONE, 'Include Psy in the call stack.'), new InputOption('num', 'n', InputOption::VALUE_REQUIRED, 'Only include NUM lines.'), $grep, $insensitive, $invert, - )) + ]) ->setDescription('Show the current call stack.') ->setHelp( <<<'HELP' @@ -90,35 +90,35 @@ protected function execute(InputInterface $input, OutputInterface $output) */ protected function getBacktrace(\Exception $e, $count = null, $includePsy = true) { - if ($cwd = getcwd()) { - $cwd = rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + if ($cwd = \getcwd()) { + $cwd = \rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } if ($count === null) { $count = PHP_INT_MAX; } - $lines = array(); + $lines = []; $trace = $e->getTrace(); - array_unshift($trace, array( + \array_unshift($trace, [ 'function' => '', 'file' => $e->getFile() !== null ? $e->getFile() : 'n/a', 'line' => $e->getLine() !== null ? $e->getLine() : 'n/a', - 'args' => array(), - )); + 'args' => [], + ]); if (!$includePsy) { - for ($i = count($trace) - 1; $i >= 0; $i--) { + for ($i = \count($trace) - 1; $i >= 0; $i--) { $thing = isset($trace[$i]['class']) ? $trace[$i]['class'] : $trace[$i]['function']; - if (preg_match('/\\\\?Psy\\\\/', $thing)) { - $trace = array_slice($trace, $i + 1); + if (\preg_match('/\\\\?Psy\\\\/', $thing)) { + $trace = \array_slice($trace, $i + 1); break; } } } - for ($i = 0, $count = min($count, count($trace)); $i < $count; $i++) { + for ($i = 0, $count = \min($count, \count($trace)); $i < $count; $i++) { $class = isset($trace[$i]['class']) ? $trace[$i]['class'] : ''; $type = isset($trace[$i]['type']) ? $trace[$i]['type'] : ''; $function = $trace[$i]['function']; @@ -126,16 +126,16 @@ protected function getBacktrace(\Exception $e, $count = null, $includePsy = true $line = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a'; // Leave execution loop out of the `eval()'d code` lines - if (preg_match("#/Psy/ExecutionLoop/Loop.php\(\d+\) : eval\(\)'d code$#", $file)) { + if (\preg_match("#/src/Execution(?:Loop)?Closure.php\(\d+\) : eval\(\)'d code$#", \str_replace('\\', '/', $file))) { $file = "eval()'d code"; } // Skip any lines that don't match our filter options - if (!$this->filter->match(sprintf('%s%s%s() at %s:%s', $class, $type, $function, $file, $line))) { + if (!$this->filter->match(\sprintf('%s%s%s() at %s:%s', $class, $type, $function, $file, $line))) { continue; } - $lines[] = sprintf( + $lines[] = \sprintf( ' %s%s%s() at %s:%s', OutputFormatter::escape($class), OutputFormatter::escape($type), @@ -161,7 +161,7 @@ private function replaceCwd($cwd, $file) if ($cwd === false) { return $file; } else { - return preg_replace('/^' . preg_quote($cwd, '/') . '/', '', $file); + return \preg_replace('/^' . \preg_quote($cwd, '/') . '/', '', $file); } } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/WhereamiCommand.php b/app/vendor/psy/psysh/src/Command/WhereamiCommand.php similarity index 75% rename from app/vendor/psy/psysh/src/Psy/Command/WhereamiCommand.php rename to app/vendor/psy/psysh/src/Command/WhereamiCommand.php index 065399bb4..98593d13a 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/WhereamiCommand.php +++ b/app/vendor/psy/psysh/src/Command/WhereamiCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -25,6 +25,7 @@ class WhereamiCommand extends Command { private $colorMode; + private $backtrace; /** * @param null|string $colorMode (default: null) @@ -32,14 +33,9 @@ class WhereamiCommand extends Command public function __construct($colorMode = null) { $this->colorMode = $colorMode ?: Configuration::COLOR_MODE_AUTO; + $this->backtrace = \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - if (version_compare(PHP_VERSION, '5.3.6', '>=')) { - $this->backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); - } else { - $this->backtrace = debug_backtrace(); - } - - return parent::__construct(); + parent::__construct(); } /** @@ -49,9 +45,9 @@ protected function configure() { $this ->setName('whereami') - ->setDefinition(array( + ->setDefinition([ new InputOption('num', 'n', InputOption::VALUE_OPTIONAL, 'Number of lines before and after.', '5'), - )) + ]) ->setDescription('Show where you are in the code.') ->setHelp( <<<'HELP' @@ -73,13 +69,13 @@ protected function configure() */ protected function trace() { - foreach (array_reverse($this->backtrace) as $stackFrame) { + foreach (\array_reverse($this->backtrace) as $stackFrame) { if ($this->isDebugCall($stackFrame)) { return $stackFrame; } } - return end($this->backtrace); + return \end($this->backtrace); } private static function isDebugCall(array $stackFrame) @@ -88,7 +84,7 @@ private static function isDebugCall(array $stackFrame) $function = isset($stackFrame['function']) ? $stackFrame['function'] : null; return ($class === null && $function === 'Psy\debug') || - ($class === 'Psy\Shell' && in_array($function, array('__construct', 'debug'))); + ($class === 'Psy\Shell' && \in_array($function, ['__construct', 'debug'])); } /** @@ -99,8 +95,8 @@ private static function isDebugCall(array $stackFrame) protected function fileInfo() { $stackFrame = $this->trace(); - if (preg_match('/eval\(/', $stackFrame['file'])) { - preg_match_all('/([^\(]+)\((\d+)/', $stackFrame['file'], $matches); + if (\preg_match('/eval\(/', $stackFrame['file'])) { + \preg_match_all('/([^\(]+)\((\d+)/', $stackFrame['file'], $matches); $file = $matches[1][0]; $line = (int) $matches[2][0]; } else { @@ -108,7 +104,7 @@ protected function fileInfo() $line = $stackFrame['line']; } - return compact('file', 'line'); + return \compact('file', 'line'); } /** @@ -121,11 +117,11 @@ protected function execute(InputInterface $input, OutputInterface $output) $factory = new ConsoleColorFactory($this->colorMode); $colors = $factory->getConsoleColor(); $highlighter = new Highlighter($colors); - $contents = file_get_contents($info['file']); + $contents = \file_get_contents($info['file']); $output->startPaging(); $output->writeln(''); - $output->writeln(sprintf('From %s:%s:', $this->replaceCwd($info['file']), $info['line'])); + $output->writeln(\sprintf('From %s:%s:', $this->replaceCwd($info['file']), $info['line'])); $output->writeln(''); $output->write($highlighter->getCodeSnippet($contents, $info['line'], $num, $num), ShellOutput::OUTPUT_RAW); $output->stopPaging(); @@ -140,13 +136,13 @@ protected function execute(InputInterface $input, OutputInterface $output) */ private function replaceCwd($file) { - $cwd = getcwd(); + $cwd = \getcwd(); if ($cwd === false) { return $file; } - $cwd = rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + $cwd = \rtrim($cwd, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - return preg_replace('/^' . preg_quote($cwd, '/') . '/', '', $file); + return \preg_replace('/^' . \preg_quote($cwd, '/') . '/', '', $file); } } diff --git a/app/vendor/psy/psysh/src/Psy/Command/WtfCommand.php b/app/vendor/psy/psysh/src/Command/WtfCommand.php similarity index 80% rename from app/vendor/psy/psysh/src/Psy/Command/WtfCommand.php rename to app/vendor/psy/psysh/src/Command/WtfCommand.php index af3bcd143..c6d53000e 100644 --- a/app/vendor/psy/psysh/src/Psy/Command/WtfCommand.php +++ b/app/vendor/psy/psysh/src/Command/WtfCommand.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -51,15 +51,15 @@ protected function configure() $this ->setName('wtf') - ->setAliases(array('last-exception', 'wtf?')) - ->setDefinition(array( - new InputArgument('incredulity', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Number of lines to show'), + ->setAliases(['last-exception', 'wtf?']) + ->setDefinition([ + new InputArgument('incredulity', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Number of lines to show.'), new InputOption('all', 'a', InputOption::VALUE_NONE, 'Show entire backtrace.'), $grep, $insensitive, $invert, - )) + ]) ->setDescription('Show the backtrace of the most recent exception.') ->setHelp( <<<'HELP' @@ -74,7 +74,7 @@ protected function configure() To see the entire backtrace, pass the -a/--all flag: e.g. ->>> wtf -v +>>> wtf -a HELP ); } @@ -86,26 +86,26 @@ protected function execute(InputInterface $input, OutputInterface $output) { $this->filter->bind($input); - $incredulity = implode('', $input->getArgument('incredulity')); - if (strlen(preg_replace('/[\\?!]/', '', $incredulity))) { - throw new \InvalidArgumentException('Incredulity must include only "?" and "!".'); + $incredulity = \implode('', $input->getArgument('incredulity')); + if (\strlen(\preg_replace('/[\\?!]/', '', $incredulity))) { + throw new \InvalidArgumentException('Incredulity must include only "?" and "!"'); } $exception = $this->context->getLastException(); - $count = $input->getOption('all') ? PHP_INT_MAX : max(3, pow(2, strlen($incredulity) + 1)); + $count = $input->getOption('all') ? PHP_INT_MAX : \max(3, \pow(2, \strlen($incredulity) + 1)); $shell = $this->getApplication(); $output->startPaging(); do { - $traceCount = count($exception->getTrace()); + $traceCount = \count($exception->getTrace()); $showLines = $count; // Show the whole trace if we'd only be hiding a few lines - if ($traceCount < max($count * 1.2, $count + 2)) { + if ($traceCount < \max($count * 1.2, $count + 2)) { $showLines = PHP_INT_MAX; } $trace = $this->getBacktrace($exception, $showLines); - $moreLines = $traceCount - count($trace); + $moreLines = $traceCount - \count($trace); $output->writeln($shell->formatException($exception)); $output->writeln('--'); @@ -113,7 +113,7 @@ protected function execute(InputInterface $input, OutputInterface $output) $output->writeln(''); if ($moreLines > 0) { - $output->writeln(sprintf( + $output->writeln(\sprintf( '', $moreLines )); diff --git a/app/vendor/psy/psysh/src/Psy/ConfigPaths.php b/app/vendor/psy/psysh/src/ConfigPaths.php similarity index 77% rename from app/vendor/psy/psysh/src/Psy/ConfigPaths.php rename to app/vendor/psy/psysh/src/ConfigPaths.php index 667249199..c4de2d576 100644 --- a/app/vendor/psy/psysh/src/Psy/ConfigPaths.php +++ b/app/vendor/psy/psysh/src/ConfigPaths.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -49,7 +49,7 @@ public static function getHomeConfigDirs() { $xdg = new Xdg(); - return self::getDirNames(array($xdg->getHomeConfigDir())); + return self::getDirNames([$xdg->getHomeConfigDir()]); } /** @@ -68,7 +68,7 @@ public static function getCurrentConfigDir() { $configDirs = self::getHomeConfigDirs(); foreach ($configDirs as $configDir) { - if (@is_dir($configDir)) { + if (@\is_dir($configDir)) { return $configDir; } } @@ -86,7 +86,7 @@ public static function getCurrentConfigDir() */ public static function getConfigFiles(array $names, $configDir = null) { - $dirs = ($configDir === null) ? self::getConfigDirs() : array($configDir); + $dirs = ($configDir === null) ? self::getConfigDirs() : [$configDir]; return self::getRealFiles($dirs, $names); } @@ -120,7 +120,7 @@ public static function getDataDirs() */ public static function getDataFiles(array $names, $dataDir = null) { - $dirs = ($dataDir === null) ? self::getDataDirs() : array($dataDir); + $dirs = ($dataDir === null) ? self::getDataDirs() : [$dataDir]; return self::getRealFiles($dirs, $names); } @@ -136,7 +136,7 @@ public static function getRuntimeDir() { $xdg = new Xdg(); - set_error_handler(array('Psy\Exception\ErrorException', 'throwException')); + \set_error_handler(['Psy\Exception\ErrorException', 'throwException']); try { // XDG doesn't really work on Windows, sometimes complains about @@ -146,34 +146,34 @@ public static function getRuntimeDir() } catch (\Exception $e) { // Well. That didn't work. Fall back to a boring old folder in the // system temp dir. - $runtimeDir = sys_get_temp_dir(); + $runtimeDir = \sys_get_temp_dir(); } - restore_error_handler(); + \restore_error_handler(); - return strtr($runtimeDir, '\\', '/') . '/psysh'; + return \strtr($runtimeDir, '\\', '/') . '/psysh'; } private static function getDirNames(array $baseDirs) { - $dirs = array_map(function ($dir) { - return strtr($dir, '\\', '/') . '/psysh'; + $dirs = \array_map(function ($dir) { + return \strtr($dir, '\\', '/') . '/psysh'; }, $baseDirs); // Add ~/.psysh - if ($home = getenv('HOME')) { - $dirs[] = strtr($home, '\\', '/') . '/.psysh'; + if ($home = \getenv('HOME')) { + $dirs[] = \strtr($home, '\\', '/') . '/.psysh'; } // Add some Windows specific ones :) - if (defined('PHP_WINDOWS_VERSION_MAJOR')) { - if ($appData = getenv('APPDATA')) { + if (\defined('PHP_WINDOWS_VERSION_MAJOR')) { + if ($appData = \getenv('APPDATA')) { // AppData gets preference - array_unshift($dirs, strtr($appData, '\\', '/') . '/PsySH'); + \array_unshift($dirs, \strtr($appData, '\\', '/') . '/PsySH'); } - $dir = strtr(getenv('HOMEDRIVE') . '/' . getenv('HOMEPATH'), '\\', '/') . '/.psysh'; - if (!in_array($dir, $dirs)) { + $dir = \strtr(\getenv('HOMEDRIVE') . '/' . \getenv('HOMEPATH'), '\\', '/') . '/.psysh'; + if (!\in_array($dir, $dirs)) { $dirs[] = $dir; } } @@ -183,11 +183,11 @@ private static function getDirNames(array $baseDirs) private static function getRealFiles(array $dirNames, array $fileNames) { - $files = array(); + $files = []; foreach ($dirNames as $dir) { foreach ($fileNames as $name) { $file = $dir . '/' . $name; - if (@is_file($file)) { + if (@\is_file($file)) { $files[] = $file; } } @@ -207,30 +207,30 @@ private static function getRealFiles(array $dirNames, array $fileNames) */ public static function touchFileWithMkdir($file) { - if (file_exists($file)) { - if (is_writable($file)) { + if (\file_exists($file)) { + if (\is_writable($file)) { return $file; } - trigger_error(sprintf('Writing to %s is not allowed.', $file), E_USER_NOTICE); + \trigger_error(\sprintf('Writing to %s is not allowed.', $file), E_USER_NOTICE); return false; } - $dir = dirname($file); + $dir = \dirname($file); - if (!is_dir($dir)) { + if (!\is_dir($dir)) { // Just try making it and see if it works - @mkdir($dir, 0700, true); + @\mkdir($dir, 0700, true); } - if (!is_dir($dir) || !is_writable($dir)) { - trigger_error(sprintf('Writing to %s is not allowed.', $dir), E_USER_NOTICE); + if (!\is_dir($dir) || !\is_writable($dir)) { + \trigger_error(\sprintf('Writing to %s is not allowed.', $dir), E_USER_NOTICE); return false; } - touch($file); + \touch($file); return $file; } diff --git a/app/vendor/psy/psysh/src/Psy/Configuration.php b/app/vendor/psy/psysh/src/Configuration.php similarity index 83% rename from app/vendor/psy/psysh/src/Psy/Configuration.php rename to app/vendor/psy/psysh/src/Configuration.php index b0953fabf..67c76e7b3 100644 --- a/app/vendor/psy/psysh/src/Psy/Configuration.php +++ b/app/vendor/psy/psysh/src/Configuration.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,8 +13,6 @@ use Psy\Exception\DeprecatedException; use Psy\Exception\RuntimeException; -use Psy\ExecutionLoop\ForkingLoop; -use Psy\ExecutionLoop\Loop; use Psy\Output\OutputPager; use Psy\Output\ShellOutput; use Psy\Readline\GNUReadline; @@ -28,7 +26,6 @@ use Psy\VersionUpdater\GitHubChecker; use Psy\VersionUpdater\IntervalChecker; use Psy\VersionUpdater\NoopChecker; -use XdgBaseDir\Xdg; /** * The Psy Shell configuration. @@ -39,7 +36,7 @@ class Configuration const COLOR_MODE_FORCED = 'forced'; const COLOR_MODE_DISABLED = 'disabled'; - private static $AVAILABLE_OPTIONS = array( + private static $AVAILABLE_OPTIONS = [ 'codeCleaner', 'colorMode', 'configDir', @@ -49,21 +46,20 @@ class Configuration 'errorLoggingLevel', 'forceArrayIndexes', 'historySize', - 'loop', 'manualDbFile', 'pager', 'prompt', 'requireSemicolons', 'runtimeDir', 'startupMessage', - 'tabCompletion', 'updateCheck', 'useBracketedPaste', 'usePcntl', 'useReadline', + 'useTabCompletion', 'useUnicode', 'warnOnMultipleConfigs', - ); + ]; private $defaultIncludes; private $configDir; @@ -80,12 +76,12 @@ class Configuration private $useBracketedPaste; private $hasPcntl; private $usePcntl; - private $newCommands = array(); + private $newCommands = []; private $requireSemicolons = false; private $useUnicode; - private $tabCompletion; - private $tabCompletionMatchers = array(); - private $errorLoggingLevel = E_ALL; + private $useTabCompletion; + private $newMatchers = []; + private $errorLoggingLevel = E_ALL; private $warnOnMultipleConfigs = false; private $colorMode; private $updateCheck; @@ -98,10 +94,9 @@ class Configuration private $shell; private $cleaner; private $pager; - private $loop; private $manualDb; private $presenter; - private $completer; + private $autoCompleter; private $checker; private $prompt; @@ -112,21 +107,21 @@ class Configuration * * @param array $config Optional array of configuration values */ - public function __construct(array $config = array()) + public function __construct(array $config = []) { $this->setColorMode(self::COLOR_MODE_AUTO); // explicit configFile option if (isset($config['configFile'])) { $this->configFile = $config['configFile']; - } elseif ($configFile = getenv('PSYSH_CONFIG')) { + } elseif ($configFile = \getenv('PSYSH_CONFIG')) { $this->configFile = $configFile; } // legacy baseDir option if (isset($config['baseDir'])) { - $msg = "The 'baseDir' configuration option is deprecated. " . - "Please specify 'configDir' and 'dataDir' options instead."; + $msg = "The 'baseDir' configuration option is deprecated; " . + "please specify 'configDir' and 'dataDir' options instead"; throw new DeprecatedException($msg); } @@ -150,8 +145,8 @@ public function __construct(array $config = array()) public function init() { // feature detection - $this->hasReadline = function_exists('readline'); - $this->hasPcntl = function_exists('pcntl_signal') && function_exists('posix_getpid'); + $this->hasReadline = \function_exists('readline'); + $this->hasPcntl = \function_exists('pcntl_signal') && \function_exists('posix_getpid'); if ($configFile = $this->getConfigFile()) { $this->loadConfigFile($configFile); @@ -182,12 +177,12 @@ public function getConfigFile() return $this->configFile; } - $files = ConfigPaths::getConfigFiles(array('config.php', 'rc.php'), $this->configDir); + $files = ConfigPaths::getConfigFiles(['config.php', 'rc.php'], $this->configDir); if (!empty($files)) { - if ($this->warnOnMultipleConfigs && count($files) > 1) { - $msg = sprintf('Multiple configuration files found: %s. Using %s', implode($files, ', '), $files[0]); - trigger_error($msg, E_USER_NOTICE); + if ($this->warnOnMultipleConfigs && \count($files) > 1) { + $msg = \sprintf('Multiple configuration files found: %s. Using %s', \implode($files, ', '), $files[0]); + \trigger_error($msg, E_USER_NOTICE); } return $files[0]; @@ -204,9 +199,9 @@ public function getConfigFile() */ public function getLocalConfigFile() { - $localConfig = getcwd() . '/.psysh.php'; + $localConfig = \getcwd() . '/.psysh.php'; - if (@is_file($localConfig)) { + if (@\is_file($localConfig)) { return $localConfig; } } @@ -220,17 +215,33 @@ public function loadConfig(array $options) { foreach (self::$AVAILABLE_OPTIONS as $option) { if (isset($options[$option])) { - $method = 'set' . ucfirst($option); + $method = 'set' . \ucfirst($option); $this->$method($options[$option]); } } - foreach (array('commands', 'tabCompletionMatchers', 'casters') as $option) { + // legacy `tabCompletion` option + if (isset($options['tabCompletion'])) { + $msg = '`tabCompletion` is deprecated; use `useTabCompletion` instead.'; + @\trigger_error($msg, E_USER_DEPRECATED); + + $this->setUseTabCompletion($options['tabCompletion']); + } + + foreach (['commands', 'matchers', 'casters'] as $option) { if (isset($options[$option])) { - $method = 'add' . ucfirst($option); + $method = 'add' . \ucfirst($option); $this->$method($options[$option]); } } + + // legacy `tabCompletionMatchers` option + if (isset($options['tabCompletionMatchers'])) { + $msg = '`tabCompletionMatchers` is deprecated; use `matchers` instead.'; + @\trigger_error($msg, E_USER_DEPRECATED); + + $this->addMatchers($options['tabCompletionMatchers']); + } } /** @@ -256,7 +267,7 @@ public function loadConfigFile($file) $result = $load($this); if (!empty($result)) { - if (is_array($result)) { + if (\is_array($result)) { $this->loadConfig($result); } else { throw new \InvalidArgumentException('Psy Shell configuration must return an array of options'); @@ -269,7 +280,7 @@ public function loadConfigFile($file) * * @param array $includes */ - public function setDefaultIncludes(array $includes = array()) + public function setDefaultIncludes(array $includes = []) { $this->defaultIncludes = $includes; } @@ -281,7 +292,7 @@ public function setDefaultIncludes(array $includes = array()) */ public function getDefaultIncludes() { - return $this->defaultIncludes ?: array(); + return $this->defaultIncludes ?: []; } /** @@ -348,8 +359,8 @@ public function getRuntimeDir() $this->runtimeDir = ConfigPaths::getRuntimeDir(); } - if (!is_dir($this->runtimeDir)) { - mkdir($this->runtimeDir, 0700, true); + if (!\is_dir($this->runtimeDir)) { + \mkdir($this->runtimeDir, 0700, true); } return $this->runtimeDir; @@ -379,31 +390,12 @@ public function getHistoryFile() return $this->historyFile; } - // Deprecation warning for incorrect psysh_history path. - // @todo remove this before v0.9.0 - $xdg = new Xdg(); - $oldHistory = $xdg->getHomeConfigDir() . '/psysh_history'; - if (@is_file($oldHistory)) { - $dir = $this->configDir ?: ConfigPaths::getCurrentConfigDir(); - $newHistory = $dir . '/psysh_history'; - - $msg = sprintf( - "PsySH history file found at '%s'. Please delete it or move it to '%s'.", - strtr($oldHistory, '\\', '/'), - $newHistory - ); - @trigger_error($msg, E_USER_DEPRECATED); - $this->setHistoryFile($oldHistory); - - return $this->historyFile; - } - - $files = ConfigPaths::getConfigFiles(array('psysh_history', 'history'), $this->configDir); + $files = ConfigPaths::getConfigFiles(['psysh_history', 'history'], $this->configDir); if (!empty($files)) { - if ($this->warnOnMultipleConfigs && count($files) > 1) { - $msg = sprintf('Multiple history files found: %s. Using %s', implode($files, ', '), $files[0]); - trigger_error($msg, E_USER_NOTICE); + if ($this->warnOnMultipleConfigs && \count($files) > 1) { + $msg = \sprintf('Multiple history files found: %s. Using %s', \implode($files, ', '), $files[0]); + \trigger_error($msg, E_USER_NOTICE); } $this->setHistoryFile($files[0]); @@ -470,7 +462,7 @@ public function getEraseDuplicates() */ public function getTempFile($type, $pid) { - return tempnam($this->getRuntimeDir(), $type . '_' . $pid . '_'); + return \tempnam($this->getRuntimeDir(), $type . '_' . $pid . '_'); } /** @@ -485,7 +477,7 @@ public function getTempFile($type, $pid) */ public function getPipe($type, $pid) { - return sprintf('%s/%s_%s', $this->getRuntimeDir(), $type, $pid); + return \sprintf('%s/%s_%s', $this->getRuntimeDir(), $type, $pid); } /** @@ -767,24 +759,44 @@ public function getCodeCleaner() /** * Enable or disable tab completion. * - * @param bool $tabCompletion + * @param bool $useTabCompletion */ - public function setTabCompletion($tabCompletion) + public function setUseTabCompletion($useTabCompletion) { - $this->tabCompletion = (bool) $tabCompletion; + $this->useTabCompletion = (bool) $useTabCompletion; + } + + /** + * @deprecated Call `setUseTabCompletion` instead + * + * @param bool $useTabCompletion + */ + public function setTabCompletion($useTabCompletion) + { + $this->setUseTabCompletion($useTabCompletion); } /** * Check whether to use tab completion. * - * If `setTabCompletion` has been set to true, but readline is not actually - * available, this will return false. + * If `setUseTabCompletion` has been set to true, but readline is not + * actually available, this will return false. * * @return bool True if the current Shell should use tab completion */ + public function useTabCompletion() + { + return isset($this->useTabCompletion) ? ($this->hasReadline && $this->useTabCompletion) : $this->hasReadline; + } + + /** + * @deprecated Call `useTabCompletion` instead + * + * @return bool + */ public function getTabCompletion() { - return isset($this->tabCompletion) ? ($this->hasReadline && $this->tabCompletion) : $this->hasReadline; + return $this->useTabCompletion(); } /** @@ -849,8 +861,8 @@ public function getOutputDecorated() */ public function setPager($pager) { - if ($pager && !is_string($pager) && !$pager instanceof OutputPager) { - throw new \InvalidArgumentException('Unexpected pager instance.'); + if ($pager && !\is_string($pager) && !$pager instanceof OutputPager) { + throw new \InvalidArgumentException('Unexpected pager instance'); } $this->pager = $pager; @@ -867,10 +879,10 @@ public function setPager($pager) public function getPager() { if (!isset($this->pager) && $this->usePcntl()) { - if ($pager = ini_get('cli.pager')) { - // use the default pager (5.4+) + if ($pager = \ini_get('cli.pager')) { + // use the default pager $this->pager = $pager; - } elseif ($less = exec('which less 2>/dev/null')) { + } elseif ($less = \exec('which less 2>/dev/null')) { // check for the presence of less... $this->pager = $less . ' -R -S -F -X'; } @@ -880,81 +892,77 @@ public function getPager() } /** - * Set the Shell evaluation Loop service. + * Set the Shell AutoCompleter service. * - * @param Loop $loop + * @param AutoCompleter $autoCompleter */ - public function setLoop(Loop $loop) + public function setAutoCompleter(AutoCompleter $autoCompleter) { - $this->loop = $loop; + $this->autoCompleter = $autoCompleter; } /** - * Get a Shell evaluation Loop service instance. - * - * If none has been explicitly defined, this will create a new instance. - * If Pcntl is available and enabled, the new instance will be a ForkingLoop. + * Get an AutoCompleter service instance. * - * @return Loop + * @return AutoCompleter */ - public function getLoop() + public function getAutoCompleter() { - if (!isset($this->loop)) { - if ($this->usePcntl()) { - $this->loop = new ForkingLoop($this); - } else { - $this->loop = new Loop($this); - } + if (!isset($this->autoCompleter)) { + $this->autoCompleter = new AutoCompleter(); } - return $this->loop; + return $this->autoCompleter; } /** - * Set the Shell autocompleter service. + * @deprecated Nothing should be using this anymore * - * @param AutoCompleter $completer + * @return array */ - public function setAutoCompleter(AutoCompleter $completer) + public function getTabCompletionMatchers() { - $this->completer = $completer; + return []; } /** - * Get an AutoCompleter service instance. + * Add tab completion matchers to the AutoCompleter. * - * @return AutoCompleter + * This will buffer new matchers in the event that the Shell has not yet + * been instantiated. This allows the user to specify matchers in their + * config rc file, despite the fact that their file is needed in the Shell + * constructor. + * + * @param array $matchers */ - public function getAutoCompleter() + public function addMatchers(array $matchers) { - if (!isset($this->completer)) { - $this->completer = new AutoCompleter(); + $this->newMatchers = \array_merge($this->newMatchers, $matchers); + if (isset($this->shell)) { + $this->doAddMatchers(); } - - return $this->completer; } /** - * Get user specified tab completion matchers for the AutoCompleter. - * - * @return array + * Internal method for adding tab completion matchers. This will set any new + * matchers once a Shell is available. */ - public function getTabCompletionMatchers() + private function doAddMatchers() { - return $this->tabCompletionMatchers; + if (!empty($this->newMatchers)) { + $this->shell->addMatchers($this->newMatchers); + $this->newMatchers = []; + } } /** - * Add additional tab completion matchers to the AutoCompleter. + * @deprecated Use `addMatchers` instead * * @param array $matchers */ public function addTabCompletionMatchers(array $matchers) { - $this->tabCompletionMatchers = array_merge($this->tabCompletionMatchers, $matchers); - if (isset($this->shell)) { - $this->shell->addTabCompletionMatchers($this->tabCompletionMatchers); - } + $this->addMatchers($matchers); } /** @@ -969,7 +977,7 @@ public function addTabCompletionMatchers(array $matchers) */ public function addCommands(array $commands) { - $this->newCommands = array_merge($this->newCommands, $commands); + $this->newCommands = \array_merge($this->newCommands, $commands); if (isset($this->shell)) { $this->doAddCommands(); } @@ -983,7 +991,7 @@ private function doAddCommands() { if (!empty($this->newCommands)) { $this->shell->addCommands($this->newCommands); - $this->newCommands = array(); + $this->newCommands = []; } } @@ -996,6 +1004,7 @@ public function setShell(Shell $shell) { $this->shell = $shell; $this->doAddCommands(); + $this->doAddMatchers(); } /** @@ -1022,11 +1031,11 @@ public function getManualDbFile() return $this->manualDbFile; } - $files = ConfigPaths::getDataFiles(array('php_manual.sqlite'), $this->dataDir); + $files = ConfigPaths::getDataFiles(['php_manual.sqlite'], $this->dataDir); if (!empty($files)) { - if ($this->warnOnMultipleConfigs && count($files) > 1) { - $msg = sprintf('Multiple manual database files found: %s. Using %s', implode($files, ', '), $files[0]); - trigger_error($msg, E_USER_NOTICE); + if ($this->warnOnMultipleConfigs && \count($files) > 1) { + $msg = \sprintf('Multiple manual database files found: %s. Using %s', \implode($files, ', '), $files[0]); + \trigger_error($msg, E_USER_NOTICE); } return $this->manualDbFile = $files[0]; @@ -1042,7 +1051,7 @@ public function getManualDb() { if (!isset($this->manualDb)) { $dbFile = $this->getManualDbFile(); - if (is_file($dbFile)) { + if (\is_file($dbFile)) { try { $this->manualDb = new \PDO('sqlite:' . $dbFile); } catch (\PDOException $e) { @@ -1118,13 +1127,13 @@ public function warnOnMultipleConfigs() */ public function setColorMode($colorMode) { - $validColorModes = array( + $validColorModes = [ self::COLOR_MODE_AUTO, self::COLOR_MODE_FORCED, self::COLOR_MODE_DISABLED, - ); + ]; - if (in_array($colorMode, $validColorModes)) { + if (\in_array($colorMode, $validColorModes)) { $this->colorMode = $colorMode; } else { throw new \InvalidArgumentException('invalid color mode: ' . $colorMode); @@ -1209,15 +1218,15 @@ public function getUpdateCheck() */ public function setUpdateCheck($interval) { - $validIntervals = array( + $validIntervals = [ Checker::ALWAYS, Checker::DAILY, Checker::WEEKLY, Checker::MONTHLY, Checker::NEVER, - ); + ]; - if (!in_array($interval, $validIntervals)) { + if (!\in_array($interval, $validIntervals)) { throw new \InvalidArgumentException('invalid update check interval: ' . $interval); } diff --git a/app/vendor/psy/psysh/src/Psy/ConsoleColorFactory.php b/app/vendor/psy/psysh/src/ConsoleColorFactory.php similarity index 66% rename from app/vendor/psy/psysh/src/Psy/ConsoleColorFactory.php rename to app/vendor/psy/psysh/src/ConsoleColorFactory.php index b3bcb53d7..76ad3b512 100644 --- a/app/vendor/psy/psysh/src/Psy/ConsoleColorFactory.php +++ b/app/vendor/psy/psysh/src/ConsoleColorFactory.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -49,10 +49,10 @@ public function getConsoleColor() private function getDefaultConsoleColor() { $color = new ConsoleColor(); - $color->addTheme(Highlighter::LINE_NUMBER, array('blue')); - $color->addTheme(Highlighter::TOKEN_KEYWORD, array('yellow')); - $color->addTheme(Highlighter::TOKEN_STRING, array('green')); - $color->addTheme(Highlighter::TOKEN_COMMENT, array('dark_gray')); + $color->addTheme(Highlighter::LINE_NUMBER, ['blue']); + $color->addTheme(Highlighter::TOKEN_KEYWORD, ['yellow']); + $color->addTheme(Highlighter::TOKEN_STRING, ['green']); + $color->addTheme(Highlighter::TOKEN_COMMENT, ['dark_gray']); return $color; } @@ -69,13 +69,13 @@ private function getDisabledConsoleColor() { $color = new ConsoleColor(); - $color->addTheme(Highlighter::TOKEN_STRING, array('none')); - $color->addTheme(Highlighter::TOKEN_COMMENT, array('none')); - $color->addTheme(Highlighter::TOKEN_KEYWORD, array('none')); - $color->addTheme(Highlighter::TOKEN_DEFAULT, array('none')); - $color->addTheme(Highlighter::TOKEN_HTML, array('none')); - $color->addTheme(Highlighter::ACTUAL_LINE_MARK, array('none')); - $color->addTheme(Highlighter::LINE_NUMBER, array('none')); + $color->addTheme(Highlighter::TOKEN_STRING, ['none']); + $color->addTheme(Highlighter::TOKEN_COMMENT, ['none']); + $color->addTheme(Highlighter::TOKEN_KEYWORD, ['none']); + $color->addTheme(Highlighter::TOKEN_DEFAULT, ['none']); + $color->addTheme(Highlighter::TOKEN_HTML, ['none']); + $color->addTheme(Highlighter::ACTUAL_LINE_MARK, ['none']); + $color->addTheme(Highlighter::LINE_NUMBER, ['none']); return $color; } diff --git a/app/vendor/psy/psysh/src/Psy/Context.php b/app/vendor/psy/psysh/src/Context.php similarity index 77% rename from app/vendor/psy/psysh/src/Psy/Context.php rename to app/vendor/psy/psysh/src/Context.php index 663f986b9..104dc8ffa 100644 --- a/app/vendor/psy/psysh/src/Psy/Context.php +++ b/app/vendor/psy/psysh/src/Context.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,20 +19,21 @@ */ class Context { - private static $specialNames = array('_', '_e', '__out', '__psysh__', 'this'); + private static $specialNames = ['_', '_e', '__out', '__psysh__', 'this']; // Whitelist a very limited number of command-scope magic variable names. // This might be a bad idea, but future me can sort it out. - private static $commandScopeNames = array( + private static $commandScopeNames = [ '__function', '__method', '__class', '__namespace', '__file', '__line', '__dir', - ); + ]; - private $scopeVariables = array(); - private $commandScopeVariables = array(); + private $scopeVariables = []; + private $commandScopeVariables = []; private $returnValue; private $lastException; private $lastStdout; private $boundObject; + private $boundClass; /** * Get a context variable. @@ -74,13 +75,13 @@ public function get($name) case '__file': case '__line': case '__dir': - if (array_key_exists($name, $this->commandScopeVariables)) { + if (\array_key_exists($name, $this->commandScopeVariables)) { return $this->commandScopeVariables[$name]; } break; default: - if (array_key_exists($name, $this->scopeVariables)) { + if (\array_key_exists($name, $this->scopeVariables)) { return $this->scopeVariables[$name]; } break; @@ -96,7 +97,7 @@ public function get($name) */ public function getAll() { - return array_merge($this->scopeVariables, $this->getSpecialVariables()); + return \array_merge($this->scopeVariables, $this->getSpecialVariables()); } /** @@ -106,9 +107,9 @@ public function getAll() */ public function getSpecialVariables() { - $vars = array( + $vars = [ '_' => $this->returnValue, - ); + ]; if (isset($this->lastException)) { $vars['_e'] = $this->lastException; @@ -122,7 +123,7 @@ public function getSpecialVariables() $vars['this'] = $this->boundObject; } - return array_merge($vars, $this->commandScopeVariables); + return \array_merge($vars, $this->commandScopeVariables); } /** @@ -179,9 +180,9 @@ public function setLastException(\Exception $e) /** * Get the most recent Exception. * - * @throws InvalidArgumentException If no Exception has been caught + * @throws \InvalidArgumentException If no Exception has been caught * - * @return null|Exception + * @return null|\Exception */ public function getLastException() { @@ -205,7 +206,7 @@ public function setLastStdout($lastStdout) /** * Get the most recent output from evaluated code. * - * @throws InvalidArgumentException If no output has happened yet + * @throws \InvalidArgumentException If no output has happened yet * * @return null|string */ @@ -221,11 +222,14 @@ public function getLastStdout() /** * Set the bound object ($this variable) for the interactive shell. * + * Note that this unsets the bound class, if any exists. + * * @param object|null $boundObject */ public function setBoundObject($boundObject) { - $this->boundObject = is_object($boundObject) ? $boundObject : null; + $this->boundObject = \is_object($boundObject) ? $boundObject : null; + $this->boundClass = null; } /** @@ -238,6 +242,29 @@ public function getBoundObject() return $this->boundObject; } + /** + * Set the bound class (self) for the interactive shell. + * + * Note that this unsets the bound object, if any exists. + * + * @param string|null $boundClass + */ + public function setBoundClass($boundClass) + { + $this->boundClass = (\is_string($boundClass) && $boundClass !== '') ? $boundClass : null; + $this->boundObject = null; + } + + /** + * Get the bound class (self) for the interactive shell. + * + * @return string|null + */ + public function getBoundClass() + { + return $this->boundClass; + } + /** * Set command-scope magic variables: $__class, $__file, etc. * @@ -245,10 +272,10 @@ public function getBoundObject() */ public function setCommandScopeVariables(array $commandScopeVariables) { - $vars = array(); + $vars = []; foreach ($commandScopeVariables as $key => $value) { // kind of type check - if (is_scalar($value) && in_array($key, self::$commandScopeNames)) { + if (\is_scalar($value) && \in_array($key, self::$commandScopeNames)) { $vars[$key] = $value; } } @@ -276,7 +303,7 @@ public function getCommandScopeVariables() */ public function getUnusedCommandScopeVariableNames() { - return array_diff(self::$commandScopeNames, array_keys($this->commandScopeVariables)); + return \array_diff(self::$commandScopeNames, \array_keys($this->commandScopeVariables)); } /** @@ -288,6 +315,6 @@ public function getUnusedCommandScopeVariableNames() */ public static function isSpecialVariableName($name) { - return in_array($name, self::$specialNames) || in_array($name, self::$commandScopeNames); + return \in_array($name, self::$specialNames) || \in_array($name, self::$commandScopeNames); } } diff --git a/app/vendor/psy/psysh/src/Psy/ContextAware.php b/app/vendor/psy/psysh/src/ContextAware.php similarity index 94% rename from app/vendor/psy/psysh/src/Psy/ContextAware.php rename to app/vendor/psy/psysh/src/ContextAware.php index d68caba66..748f13aa3 100644 --- a/app/vendor/psy/psysh/src/Psy/ContextAware.php +++ b/app/vendor/psy/psysh/src/ContextAware.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Exception/BreakException.php b/app/vendor/psy/psysh/src/Exception/BreakException.php similarity index 89% rename from app/vendor/psy/psysh/src/Psy/Exception/BreakException.php rename to app/vendor/psy/psysh/src/Exception/BreakException.php index 4592c51fa..2200e78dc 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/BreakException.php +++ b/app/vendor/psy/psysh/src/Exception/BreakException.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,7 +24,7 @@ class BreakException extends \Exception implements Exception public function __construct($message = '', $code = 0, \Exception $previous = null) { $this->rawMessage = $message; - parent::__construct(sprintf('Exit: %s', $message), $code, $previous); + parent::__construct(\sprintf('Exit: %s', $message), $code, $previous); } /** diff --git a/app/vendor/psy/psysh/src/Psy/Exception/DeprecatedException.php b/app/vendor/psy/psysh/src/Exception/DeprecatedException.php similarity index 91% rename from app/vendor/psy/psysh/src/Psy/Exception/DeprecatedException.php rename to app/vendor/psy/psysh/src/Exception/DeprecatedException.php index cd0185f1d..8ac0104b9 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/DeprecatedException.php +++ b/app/vendor/psy/psysh/src/Exception/DeprecatedException.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Exception/ErrorException.php b/app/vendor/psy/psysh/src/Exception/ErrorException.php similarity index 92% rename from app/vendor/psy/psysh/src/Psy/Exception/ErrorException.php rename to app/vendor/psy/psysh/src/Exception/ErrorException.php index 85820ac8c..822fa9275 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/ErrorException.php +++ b/app/vendor/psy/psysh/src/Exception/ErrorException.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -32,7 +32,7 @@ public function __construct($message = '', $code = 0, $severity = 1, $filename = { $this->rawMessage = $message; - if (!empty($filename) && preg_match('{Psy[/\\\\]ExecutionLoop}', $filename)) { + if (!empty($filename) && \preg_match('{Psy[/\\\\]ExecutionLoop}', $filename)) { $filename = ''; } @@ -67,7 +67,7 @@ public function __construct($message = '', $code = 0, $severity = 1, $filename = break; } - $message = sprintf('PHP %s: %s%s on line %d', $type, $message, $filename ? ' in ' . $filename : '', $lineno); + $message = \sprintf('PHP %s: %s%s on line %d', $type, $message, $filename ? ' in ' . $filename : '', $lineno); parent::__construct($message, $code, $severity, $filename, $lineno, $previous); } diff --git a/app/vendor/psy/psysh/src/Psy/Exception/Exception.php b/app/vendor/psy/psysh/src/Exception/Exception.php similarity index 93% rename from app/vendor/psy/psysh/src/Psy/Exception/Exception.php rename to app/vendor/psy/psysh/src/Exception/Exception.php index 80206f6f2..de6895479 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/Exception.php +++ b/app/vendor/psy/psysh/src/Exception/Exception.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Exception/FatalErrorException.php b/app/vendor/psy/psysh/src/Exception/FatalErrorException.php similarity index 89% rename from app/vendor/psy/psysh/src/Psy/Exception/FatalErrorException.php rename to app/vendor/psy/psysh/src/Exception/FatalErrorException.php index 5fe7fc61c..48a4e2b81 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/FatalErrorException.php +++ b/app/vendor/psy/psysh/src/Exception/FatalErrorException.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -36,7 +36,7 @@ public function __construct($message = '', $code = 0, $severity = 1, $filename = } $this->rawMessage = $message; - $message = sprintf('PHP Fatal error: %s in %s on line %d', $message, $filename ?: "eval()'d code", $lineno); + $message = \sprintf('PHP Fatal error: %s in %s on line %d', $message, $filename ?: "eval()'d code", $lineno); parent::__construct($message, $code, $severity, $filename, $lineno, $previous); } diff --git a/app/vendor/psy/psysh/src/Psy/Exception/ParseErrorException.php b/app/vendor/psy/psysh/src/Exception/ParseErrorException.php similarity index 90% rename from app/vendor/psy/psysh/src/Psy/Exception/ParseErrorException.php rename to app/vendor/psy/psysh/src/Exception/ParseErrorException.php index 0fb397dc6..cb6380e6b 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/ParseErrorException.php +++ b/app/vendor/psy/psysh/src/Exception/ParseErrorException.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,7 +24,7 @@ class ParseErrorException extends \PhpParser\Error implements Exception */ public function __construct($message = '', $line = -1) { - $message = sprintf('PHP Parse error: %s', $message); + $message = \sprintf('PHP Parse error: %s', $message); parent::__construct($message, $line); } diff --git a/app/vendor/psy/psysh/src/Psy/Exception/RuntimeException.php b/app/vendor/psy/psysh/src/Exception/RuntimeException.php similarity index 96% rename from app/vendor/psy/psysh/src/Psy/Exception/RuntimeException.php rename to app/vendor/psy/psysh/src/Exception/RuntimeException.php index 1e767af03..09e68483e 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/RuntimeException.php +++ b/app/vendor/psy/psysh/src/Exception/RuntimeException.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Exception/ThrowUpException.php b/app/vendor/psy/psysh/src/Exception/ThrowUpException.php similarity index 52% rename from app/vendor/psy/psysh/src/Psy/Exception/ThrowUpException.php rename to app/vendor/psy/psysh/src/Exception/ThrowUpException.php index acc87c23e..b0ca490a7 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/ThrowUpException.php +++ b/app/vendor/psy/psysh/src/Exception/ThrowUpException.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,7 +21,7 @@ class ThrowUpException extends \Exception implements Exception */ public function __construct(\Exception $exception) { - $message = sprintf("Throwing %s with message '%s'", get_class($exception), $exception->getMessage()); + $message = \sprintf("Throwing %s with message '%s'", \get_class($exception), $exception->getMessage()); parent::__construct($message, $exception->getCode(), $exception); } @@ -34,4 +34,24 @@ public function getRawMessage() { return $this->getPrevious()->getMessage(); } + + /** + * Create a ThrowUpException from a Throwable. + * + * @param \Throwable $throwable + * + * @return ThrowUpException + */ + public static function fromThrowable($throwable) + { + if ($throwable instanceof \Error) { + $throwable = ErrorException::fromError($throwable); + } + + if (!$throwable instanceof \Exception) { + throw new \InvalidArgumentException('throw-up can only throw Exceptions and Errors'); + } + + return new self($throwable); + } } diff --git a/app/vendor/psy/psysh/src/Psy/Exception/TypeErrorException.php b/app/vendor/psy/psysh/src/Exception/TypeErrorException.php similarity index 79% rename from app/vendor/psy/psysh/src/Psy/Exception/TypeErrorException.php rename to app/vendor/psy/psysh/src/Exception/TypeErrorException.php index 756b06a9b..b6894983f 100644 --- a/app/vendor/psy/psysh/src/Psy/Exception/TypeErrorException.php +++ b/app/vendor/psy/psysh/src/Exception/TypeErrorException.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -27,8 +27,8 @@ class TypeErrorException extends \Exception implements Exception public function __construct($message = '', $code = 0) { $this->rawMessage = $message; - $message = preg_replace('/, called in .*?: eval\\(\\)\'d code/', '', $message); - parent::__construct(sprintf('TypeError: %s', $message), $code); + $message = \preg_replace('/, called in .*?: eval\\(\\)\'d code/', '', $message); + parent::__construct(\sprintf('TypeError: %s', $message), $code); } /** @@ -50,6 +50,6 @@ public function getRawMessage() */ public static function fromTypeError(\TypeError $e) { - return new self($e->getMessage(), $e->getLine()); + return new self($e->getMessage(), $e->getCode()); } } diff --git a/app/vendor/psy/psysh/src/ExecutionClosure.php b/app/vendor/psy/psysh/src/ExecutionClosure.php new file mode 100644 index 000000000..5c7cd25ac --- /dev/null +++ b/app/vendor/psy/psysh/src/ExecutionClosure.php @@ -0,0 +1,119 @@ +setClosure($__psysh__, function () use ($__psysh__) { + try { + // Restore execution scope variables + \extract($__psysh__->getScopeVariables(false)); + + // Buffer stdout; we'll need it later + \ob_start([$__psysh__, 'writeStdout'], 1); + + // Convert all errors to exceptions + \set_error_handler([$__psysh__, 'handleError']); + + // Evaluate the current code buffer + $_ = eval($__psysh__->onExecute($__psysh__->flushCode() ?: ExecutionClosure::NOOP_INPUT)); + } catch (\Throwable $_e) { + // Clean up on our way out. + \restore_error_handler(); + if (\ob_get_level() > 0) { + \ob_end_clean(); + } + + throw $_e; + } catch (\Exception $_e) { + // Clean up on our way out. + \restore_error_handler(); + if (\ob_get_level() > 0) { + \ob_end_clean(); + } + + throw $_e; + } + + // Won't be needing this anymore + \restore_error_handler(); + + // Flush stdout (write to shell output, plus save to magic variable) + \ob_end_flush(); + + // Save execution scope variables for next time + $__psysh__->setScopeVariables(\get_defined_vars()); + + return $_; + }); + } + + /** + * Set the closure instance. + * + * @param Shell $psysh + * @param \Closure $closure + */ + protected function setClosure(Shell $shell, \Closure $closure) + { + if (self::shouldBindClosure()) { + $that = $shell->getBoundObject(); + if (\is_object($that)) { + $closure = $closure->bindTo($that, \get_class($that)); + } else { + $closure = $closure->bindTo(null, $shell->getBoundClass()); + } + } + + $this->closure = $closure; + } + + /** + * Go go gadget closure. + * + * @return mixed + */ + public function execute() + { + $closure = $this->closure; + + return $closure(); + } + + /** + * Decide whether to bind the execution closure. + * + * @return bool + */ + protected static function shouldBindClosure() + { + // skip binding on HHVM < 3.5.0 + // see https://github.com/facebook/hhvm/issues/1203 + if (\defined('HHVM_VERSION')) { + return \version_compare(HHVM_VERSION, '3.5.0', '>='); + } + + return true; + } +} diff --git a/app/vendor/psy/psysh/src/ExecutionLoop.php b/app/vendor/psy/psysh/src/ExecutionLoop.php new file mode 100644 index 000000000..2e4307cb7 --- /dev/null +++ b/app/vendor/psy/psysh/src/ExecutionLoop.php @@ -0,0 +1,67 @@ +loadIncludes($shell); + + $closure = new ExecutionLoopClosure($shell); + $closure->execute(); + } + + /** + * Load user-defined includes. + * + * @param Shell $shell + */ + protected function loadIncludes(Shell $shell) + { + // Load user-defined includes + $load = function (Shell $__psysh__) { + \set_error_handler([$__psysh__, 'handleError']); + foreach ($__psysh__->getIncludes() as $__psysh_include__) { + try { + include $__psysh_include__; + } catch (\Error $_e) { + $__psysh__->writeException(ErrorException::fromError($_e)); + } catch (\Exception $_e) { + $__psysh__->writeException($_e); + } + } + \restore_error_handler(); + unset($__psysh_include__); + + // Override any new local variables with pre-defined scope variables + \extract($__psysh__->getScopeVariables(false)); + + // ... then add the whole mess of variables back. + $__psysh__->setScopeVariables(\get_defined_vars()); + }; + + $load($shell); + } +} diff --git a/app/vendor/psy/psysh/src/ExecutionLoop/AbstractListener.php b/app/vendor/psy/psysh/src/ExecutionLoop/AbstractListener.php new file mode 100644 index 000000000..3617fa243 --- /dev/null +++ b/app/vendor/psy/psysh/src/ExecutionLoop/AbstractListener.php @@ -0,0 +1,62 @@ + 0) { + // This is the main thread. We'll just wait for a while. + + // We won't be needing this one. + \fclose($up); + + // Wait for a return value from the loop process. + $read = [$down]; + $write = null; + $except = null; + + do { + $n = @\stream_select($read, $write, $except, null); + + if ($n === 0) { + throw new \RuntimeException('Process timed out waiting for execution loop'); + } + + if ($n === false) { + $err = \error_get_last(); + if (!isset($err['message']) || \stripos($err['message'], 'interrupted system call') === false) { + $msg = $err['message'] ? + \sprintf('Error waiting for execution loop: %s', $err['message']) : + 'Error waiting for execution loop'; + throw new \RuntimeException($msg); + } + } + } while ($n < 1); + + $content = \stream_get_contents($down); + \fclose($down); + + if ($content) { + $shell->setScopeVariables(@\unserialize($content)); + } + + throw new BreakException('Exiting main thread'); + } + + // This is the child process. It's going to do all the work. + if (\function_exists('setproctitle')) { + setproctitle('psysh (loop)'); + } + + // We won't be needing this one. + \fclose($down); + + // Save this; we'll need to close it in `afterRun` + $this->up = $up; + } + + /** + * Create a savegame at the start of each loop iteration. + * + * @param Shell $shell + */ + public function beforeLoop(Shell $shell) + { + $this->createSavegame(); + } + + /** + * Clean up old savegames at the end of each loop iteration. + * + * @param Shell $shell + */ + public function afterLoop(Shell $shell) + { + // if there's an old savegame hanging around, let's kill it. + if (isset($this->savegame)) { + \posix_kill($this->savegame, SIGKILL); + \pcntl_signal_dispatch(); + } + } + + /** + * After the REPL session ends, send the scope variables back up to the main + * thread (if this is a child thread). + * + * @param Shell $shell + */ + public function afterRun(Shell $shell) + { + // We're a child thread. Send the scope variables back up to the main thread. + if (isset($this->up)) { + \fwrite($this->up, $this->serializeReturn($shell->getScopeVariables(false))); + \fclose($this->up); + + \posix_kill(\posix_getpid(), SIGKILL); + } + } + + /** + * Create a savegame fork. + * + * The savegame contains the current execution state, and can be resumed in + * the event that the worker dies unexpectedly (for example, by encountering + * a PHP fatal error). + */ + private function createSavegame() + { + // the current process will become the savegame + $this->savegame = \posix_getpid(); + + $pid = \pcntl_fork(); + if ($pid < 0) { + throw new \RuntimeException('Unable to create savegame fork'); + } elseif ($pid > 0) { + // we're the savegame now... let's wait and see what happens + \pcntl_waitpid($pid, $status); + + // worker exited cleanly, let's bail + if (!\pcntl_wexitstatus($status)) { + \posix_kill(\posix_getpid(), SIGKILL); + } + + // worker didn't exit cleanly, we'll need to have another go + $this->createSavegame(); + } + } + + /** + * Serialize all serializable return values. + * + * A naïve serialization will run into issues if there is a Closure or + * SimpleXMLElement (among other things) in scope when exiting the execution + * loop. We'll just ignore these unserializable classes, and serialize what + * we can. + * + * @param array $return + * + * @return string + */ + private function serializeReturn(array $return) + { + $serializable = []; + + foreach ($return as $key => $value) { + // No need to return magic variables + if (Context::isSpecialVariableName($key)) { + continue; + } + + // Resources and Closures don't error, but they don't serialize well either. + if (\is_resource($value) || $value instanceof \Closure) { + continue; + } + + try { + @\serialize($value); + $serializable[$key] = $value; + } catch (\Throwable $e) { + // we'll just ignore this one... + } catch (\Exception $e) { + // and this one too... + // @todo remove this once we don't support PHP 5.x anymore :) + } + } + + return @\serialize($serializable); + } +} diff --git a/app/vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php b/app/vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php new file mode 100644 index 000000000..d80480b0a --- /dev/null +++ b/app/vendor/psy/psysh/src/ExecutionLoop/RunkitReloader.php @@ -0,0 +1,135 @@ +parser = $parserFactory->createParser(); + } + + /** + * Reload code on input. + * + * @param Shell $shell + * @param string $input + */ + public function onInput(Shell $shell, $input) + { + $this->reload($shell); + } + + /** + * Look through included files and update anything with a new timestamp. + * + * @param Shell $shell + */ + private function reload(Shell $shell) + { + \clearstatcache(); + $modified = []; + + foreach (\get_included_files() as $file) { + $timestamp = \filemtime($file); + + if (!isset($this->timestamps[$file])) { + $this->timestamps[$file] = $timestamp; + continue; + } + + if ($this->timestamps[$file] === $timestamp) { + continue; + } + + if (!$this->lintFile($file)) { + $msg = \sprintf('Modified file "%s" could not be reloaded', $file); + $shell->writeException(new ParseErrorException($msg)); + continue; + } + + $modified[] = $file; + $this->timestamps[$file] = $timestamp; + } + + // switch (count($modified)) { + // case 0: + // return; + + // case 1: + // printf("Reloading modified file: \"%s\"\n", str_replace(getcwd(), '.', $file)); + // break; + + // default: + // printf("Reloading %d modified files\n", count($modified)); + // break; + // } + + foreach ($modified as $file) { + runkit_import($file, ( + RUNKIT_IMPORT_FUNCTIONS | + RUNKIT_IMPORT_CLASSES | + RUNKIT_IMPORT_CLASS_METHODS | + RUNKIT_IMPORT_CLASS_CONSTS | + RUNKIT_IMPORT_CLASS_PROPS | + RUNKIT_IMPORT_OVERRIDE + )); + } + } + + /** + * Should this file be re-imported? + * + * Use PHP-Parser to ensure that the file is valid PHP. + * + * @param string $file + * + * @return bool + */ + private function lintFile($file) + { + // first try to parse it + try { + $this->parser->parse(\file_get_contents($file)); + } catch (\Exception $e) { + return false; + } + + return true; + } +} diff --git a/app/vendor/psy/psysh/src/ExecutionLoopClosure.php b/app/vendor/psy/psysh/src/ExecutionLoopClosure.php new file mode 100644 index 000000000..94d3ce2e7 --- /dev/null +++ b/app/vendor/psy/psysh/src/ExecutionLoopClosure.php @@ -0,0 +1,102 @@ +setClosure($__psysh__, function () use ($__psysh__) { + // Restore execution scope variables + \extract($__psysh__->getScopeVariables(false)); + + do { + $__psysh__->beforeLoop(); + + try { + $__psysh__->getInput(); + + try { + // Pull in any new execution scope variables + \extract($__psysh__->getScopeVariablesDiff(\get_defined_vars())); + + // Buffer stdout; we'll need it later + \ob_start([$__psysh__, 'writeStdout'], 1); + + // Convert all errors to exceptions + \set_error_handler([$__psysh__, 'handleError']); + + // Evaluate the current code buffer + $_ = eval($__psysh__->onExecute($__psysh__->flushCode() ?: ExecutionClosure::NOOP_INPUT)); + } catch (\Throwable $_e) { + // Clean up on our way out. + \restore_error_handler(); + if (\ob_get_level() > 0) { + \ob_end_clean(); + } + + throw $_e; + } catch (\Exception $_e) { + // Clean up on our way out. + \restore_error_handler(); + if (\ob_get_level() > 0) { + \ob_end_clean(); + } + + throw $_e; + } + + // Won't be needing this anymore + \restore_error_handler(); + + // Flush stdout (write to shell output, plus save to magic variable) + \ob_end_flush(); + + // Save execution scope variables for next time + $__psysh__->setScopeVariables(\get_defined_vars()); + + $__psysh__->writeReturnValue($_); + } catch (BreakException $_e) { + $__psysh__->writeException($_e); + + return; + } catch (ThrowUpException $_e) { + $__psysh__->writeException($_e); + + throw $_e; + } catch (\TypeError $_e) { + $__psysh__->writeException(TypeErrorException::fromTypeError($_e)); + } catch (\Error $_e) { + $__psysh__->writeException(ErrorException::fromError($_e)); + } catch (\Exception $_e) { + $__psysh__->writeException($_e); + } + + $__psysh__->afterLoop(); + } while (true); + }); + } +} diff --git a/app/vendor/psy/psysh/src/Psy/Formatter/CodeFormatter.php b/app/vendor/psy/psysh/src/Formatter/CodeFormatter.php similarity index 76% rename from app/vendor/psy/psysh/src/Psy/Formatter/CodeFormatter.php rename to app/vendor/psy/psysh/src/Formatter/CodeFormatter.php index 45ad49195..2ac37cc9d 100644 --- a/app/vendor/psy/psysh/src/Psy/Formatter/CodeFormatter.php +++ b/app/vendor/psy/psysh/src/Formatter/CodeFormatter.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -32,21 +32,17 @@ class CodeFormatter implements Formatter public static function format(\Reflector $reflector, $colorMode = null) { if (!self::isReflectable($reflector)) { - throw new RuntimeException('Source code unavailable.'); + throw new RuntimeException('Source code unavailable'); } $colorMode = $colorMode ?: Configuration::COLOR_MODE_AUTO; - if ($reflector instanceof \ReflectionGenerator) { - $reflector = $reflector->getFunction(); - } - if ($fileName = $reflector->getFileName()) { - if (!is_file($fileName)) { - throw new RuntimeException('Source code unavailable.'); + if (!\is_file($fileName)) { + throw new RuntimeException('Source code unavailable'); } - $file = file_get_contents($fileName); + $file = \file_get_contents($fileName); $start = $reflector->getStartLine(); $end = $reflector->getEndLine() - $start; @@ -56,7 +52,7 @@ public static function format(\Reflector $reflector, $colorMode = null) return $highlighter->getCodeSnippet($file, $start, 0, $end); } else { - throw new RuntimeException('Source code unavailable.'); + throw new RuntimeException('Source code unavailable'); } } @@ -70,7 +66,6 @@ public static function format(\Reflector $reflector, $colorMode = null) private static function isReflectable(\Reflector $reflector) { return $reflector instanceof \ReflectionClass || - $reflector instanceof \ReflectionFunctionAbstract || - $reflector instanceof \ReflectionGenerator; + $reflector instanceof \ReflectionFunctionAbstract; } } diff --git a/app/vendor/psy/psysh/src/Psy/Formatter/DocblockFormatter.php b/app/vendor/psy/psysh/src/Formatter/DocblockFormatter.php similarity index 69% rename from app/vendor/psy/psysh/src/Psy/Formatter/DocblockFormatter.php rename to app/vendor/psy/psysh/src/Formatter/DocblockFormatter.php index c1e8af9c1..39ea60e54 100644 --- a/app/vendor/psy/psysh/src/Psy/Formatter/DocblockFormatter.php +++ b/app/vendor/psy/psysh/src/Formatter/DocblockFormatter.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,10 +19,10 @@ */ class DocblockFormatter implements Formatter { - private static $vectorParamTemplates = array( + private static $vectorParamTemplates = [ 'type' => 'info', 'var' => 'strong', - ); + ]; /** * Format a docblock. @@ -34,7 +34,7 @@ class DocblockFormatter implements Formatter public static function format(\Reflector $reflector) { $docblock = new Docblock($reflector); - $chunks = array(); + $chunks = []; if (!empty($docblock->desc)) { $chunks[] = 'Description:'; @@ -45,20 +45,20 @@ public static function format(\Reflector $reflector) if (!empty($docblock->tags)) { foreach ($docblock::$vectors as $name => $vector) { if (isset($docblock->tags[$name])) { - $chunks[] = sprintf('%s:', self::inflect($name)); + $chunks[] = \sprintf('%s:', self::inflect($name)); $chunks[] = self::formatVector($vector, $docblock->tags[$name]); $chunks[] = ''; } } - $tags = self::formatTags(array_keys($docblock::$vectors), $docblock->tags); + $tags = self::formatTags(\array_keys($docblock::$vectors), $docblock->tags); if (!empty($tags)) { $chunks[] = $tags; $chunks[] = ''; } } - return rtrim(implode("\n", $chunks)); + return \rtrim(\implode("\n", $chunks)); } /** @@ -73,12 +73,12 @@ public static function format(\Reflector $reflector) */ private static function formatVector(array $vector, array $lines) { - $template = array(' '); + $template = [' ']; foreach ($vector as $type) { $max = 0; foreach ($lines as $line) { $chunk = $line[$type]; - $cur = empty($chunk) ? 0 : strlen($chunk) + 1; + $cur = empty($chunk) ? 0 : \strlen($chunk) + 1; if ($cur > $max) { $max = $cur; } @@ -86,12 +86,12 @@ private static function formatVector(array $vector, array $lines) $template[] = self::getVectorParamTemplate($type, $max); } - $template = implode(' ', $template); + $template = \implode(' ', $template); - return implode("\n", array_map(function ($line) use ($template) { - $escaped = array_map(array('Symfony\Component\Console\Formatter\OutputFormatter', 'escape'), $line); + return \implode("\n", \array_map(function ($line) use ($template) { + $escaped = \array_map(['Symfony\Component\Console\Formatter\OutputFormatter', 'escape'], $line); - return rtrim(vsprintf($template, $escaped)); + return \rtrim(\vsprintf($template, $escaped)); }, $lines)); } @@ -105,21 +105,21 @@ private static function formatVector(array $vector, array $lines) */ private static function formatTags(array $skip, array $tags) { - $chunks = array(); + $chunks = []; foreach ($tags as $name => $values) { - if (in_array($name, $skip)) { + if (\in_array($name, $skip)) { continue; } foreach ($values as $value) { - $chunks[] = sprintf('%s%s %s', self::inflect($name), empty($value) ? '' : ':', OutputFormatter::escape($value)); + $chunks[] = \sprintf('%s%s %s', self::inflect($name), empty($value) ? '' : ':', OutputFormatter::escape($value)); } $chunks[] = ''; } - return implode("\n", $chunks); + return \implode("\n", $chunks); } /** @@ -133,10 +133,10 @@ private static function formatTags(array $skip, array $tags) private static function getVectorParamTemplate($type, $max) { if (!isset(self::$vectorParamTemplates[$type])) { - return sprintf('%%-%ds', $max); + return \sprintf('%%-%ds', $max); } - return sprintf('<%s>%%-%ds', self::$vectorParamTemplates[$type], $max, self::$vectorParamTemplates[$type]); + return \sprintf('<%s>%%-%ds', self::$vectorParamTemplates[$type], $max, self::$vectorParamTemplates[$type]); } /** @@ -149,7 +149,7 @@ private static function getVectorParamTemplate($type, $max) */ private static function indent($text, $indent = ' ') { - return $indent . str_replace("\n", "\n" . $indent, $text); + return $indent . \str_replace("\n", "\n" . $indent, $text); } /** @@ -161,8 +161,8 @@ private static function indent($text, $indent = ' ') */ private static function inflect($text) { - $words = trim(preg_replace('/[\s_-]+/', ' ', preg_replace('/([a-z])([A-Z])/', '$1 $2', $text))); + $words = \trim(\preg_replace('/[\s_-]+/', ' ', \preg_replace('/([a-z])([A-Z])/', '$1 $2', $text))); - return implode(' ', array_map('ucfirst', explode(' ', $words))); + return \implode(' ', \array_map('ucfirst', \explode(' ', $words))); } } diff --git a/app/vendor/psy/psysh/src/Psy/Formatter/Formatter.php b/app/vendor/psy/psysh/src/Formatter/Formatter.php similarity index 92% rename from app/vendor/psy/psysh/src/Psy/Formatter/Formatter.php rename to app/vendor/psy/psysh/src/Formatter/Formatter.php index fe11bce04..08a8e4c16 100644 --- a/app/vendor/psy/psysh/src/Psy/Formatter/Formatter.php +++ b/app/vendor/psy/psysh/src/Formatter/Formatter.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Formatter/SignatureFormatter.php b/app/vendor/psy/psysh/src/Formatter/SignatureFormatter.php similarity index 66% rename from app/vendor/psy/psysh/src/Psy/Formatter/SignatureFormatter.php rename to app/vendor/psy/psysh/src/Formatter/SignatureFormatter.php index b3ef2eac7..ec8725d9f 100644 --- a/app/vendor/psy/psysh/src/Psy/Formatter/SignatureFormatter.php +++ b/app/vendor/psy/psysh/src/Formatter/SignatureFormatter.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,8 @@ namespace Psy\Formatter; -use Psy\Reflection\ReflectionConstant; +use Psy\Reflection\ReflectionClassConstant; +use Psy\Reflection\ReflectionConstant_; use Psy\Reflection\ReflectionLanguageConstruct; use Psy\Util\Json; use Symfony\Component\Console\Formatter\OutputFormatter; @@ -41,8 +42,9 @@ public static function format(\Reflector $reflector) case $reflector instanceof \ReflectionClass: return self::formatClass($reflector); - case $reflector instanceof ReflectionConstant: - return self::formatConstant($reflector); + case $reflector instanceof ReflectionClassConstant: + case $reflector instanceof \ReflectionClassConstant: + return self::formatClassConstant($reflector); case $reflector instanceof \ReflectionMethod: return self::formatMethod($reflector); @@ -50,8 +52,11 @@ public static function format(\Reflector $reflector) case $reflector instanceof \ReflectionProperty: return self::formatProperty($reflector); + case $reflector instanceof ReflectionConstant_: + return self::formatConstant($reflector); + default: - throw new \InvalidArgumentException('Unexpected Reflector class: ' . get_class($reflector)); + throw new \InvalidArgumentException('Unexpected Reflector class: ' . \get_class($reflector)); } } @@ -70,16 +75,22 @@ public static function formatName(\Reflector $reflector) /** * Print the method, property or class modifiers. * - * Technically this should be a trait. Can't wait for 5.4 :) - * * @param \Reflector $reflector * * @return string Formatted modifiers */ private static function formatModifiers(\Reflector $reflector) { - return implode(' ', array_map(function ($modifier) { - return sprintf('%s', $modifier); + if ($reflector instanceof \ReflectionClass && $reflector->isTrait()) { + // For some reason, PHP 5.x returns `abstract public` modifiers for + // traits. Let's just ignore that business entirely. + if (\version_compare(PHP_VERSION, '7.0.0', '<')) { + return []; + } + } + + return \implode(' ', \array_map(function ($modifier) { + return \sprintf('%s', $modifier); }, \Reflection::getModifierNames($reflector->getModifiers()))); } @@ -92,51 +103,51 @@ private static function formatModifiers(\Reflector $reflector) */ private static function formatClass(\ReflectionClass $reflector) { - $chunks = array(); + $chunks = []; if ($modifiers = self::formatModifiers($reflector)) { $chunks[] = $modifiers; } - if (version_compare(PHP_VERSION, '5.4', '>=') && $reflector->isTrait()) { + if ($reflector->isTrait()) { $chunks[] = 'trait'; } else { $chunks[] = $reflector->isInterface() ? 'interface' : 'class'; } - $chunks[] = sprintf('%s', self::formatName($reflector)); + $chunks[] = \sprintf('%s', self::formatName($reflector)); if ($parent = $reflector->getParentClass()) { $chunks[] = 'extends'; - $chunks[] = sprintf('%s', $parent->getName()); + $chunks[] = \sprintf('%s', $parent->getName()); } $interfaces = $reflector->getInterfaceNames(); if (!empty($interfaces)) { - sort($interfaces); + \sort($interfaces); $chunks[] = 'implements'; - $chunks[] = implode(', ', array_map(function ($name) { - return sprintf('%s', $name); + $chunks[] = \implode(', ', \array_map(function ($name) { + return \sprintf('%s', $name); }, $interfaces)); } - return implode(' ', $chunks); + return \implode(' ', $chunks); } /** * Format a constant signature. * - * @param ReflectionConstant $reflector + * @param ReflectionClassConstant|\ReflectionClassConstant $reflector * * @return string Formatted signature */ - private static function formatConstant(ReflectionConstant $reflector) + private static function formatClassConstant($reflector) { $value = $reflector->getValue(); $style = self::getTypeStyle($value); - return sprintf( + return \sprintf( 'const %s = <%s>%s', self::formatName($reflector), $style, @@ -145,6 +156,27 @@ private static function formatConstant(ReflectionConstant $reflector) ); } + /** + * Format a constant signature. + * + * @param ReflectionConstant_ $reflector + * + * @return string Formatted signature + */ + private static function formatConstant($reflector) + { + $value = $reflector->getValue(); + $style = self::getTypeStyle($value); + + return \sprintf( + 'define(%s, <%s>%s)', + OutputFormatter::escape(Json::encode($reflector->getName())), + $style, + OutputFormatter::escape(Json::encode($value)), + $style + ); + } + /** * Helper for getting output style for a given value's type. * @@ -154,14 +186,14 @@ private static function formatConstant(ReflectionConstant $reflector) */ private static function getTypeStyle($value) { - if (is_int($value) || is_float($value)) { + if (\is_int($value) || \is_float($value)) { return 'number'; - } elseif (is_string($value)) { + } elseif (\is_string($value)) { return 'string'; - } elseif (is_bool($value) || is_null($value)) { + } elseif (\is_bool($value) || \is_null($value)) { return 'bool'; } else { - return 'strong'; + return 'strong'; // @codeCoverageIgnore } } @@ -174,7 +206,7 @@ private static function getTypeStyle($value) */ private static function formatProperty(\ReflectionProperty $reflector) { - return sprintf( + return \sprintf( '%s $%s', self::formatModifiers($reflector), $reflector->getName() @@ -190,11 +222,11 @@ private static function formatProperty(\ReflectionProperty $reflector) */ private static function formatFunction(\ReflectionFunctionAbstract $reflector) { - return sprintf( + return \sprintf( 'function %s%s(%s)', $reflector->returnsReference() ? '&' : '', self::formatName($reflector), - implode(', ', self::formatFunctionParams($reflector)) + \implode(', ', self::formatFunctionParams($reflector)) ); } @@ -207,7 +239,7 @@ private static function formatFunction(\ReflectionFunctionAbstract $reflector) */ private static function formatMethod(\ReflectionMethod $reflector) { - return sprintf( + return \sprintf( '%s %s', self::formatModifiers($reflector), self::formatFunction($reflector) @@ -219,18 +251,18 @@ private static function formatMethod(\ReflectionMethod $reflector) * * @param \ReflectionFunctionAbstract $reflector * - * @return string + * @return array */ private static function formatFunctionParams(\ReflectionFunctionAbstract $reflector) { - $params = array(); + $params = []; foreach ($reflector->getParameters() as $param) { $hint = ''; try { if ($param->isArray()) { $hint = 'array '; } elseif ($class = $param->getClass()) { - $hint = sprintf('%s ', $class->getName()); + $hint = \sprintf('%s ', $class->getName()); } } catch (\Exception $e) { // sometimes we just don't know... @@ -238,11 +270,14 @@ private static function formatFunctionParams(\ReflectionFunctionAbstract $reflec // come to think of it, the only time I've seen this is with the intl extension. // Hax: we'll try to extract it :P - $chunks = explode('$' . $param->getName(), (string) $param); - $chunks = explode(' ', trim($chunks[0])); - $guess = end($chunks); - $hint = sprintf('%s ', $guess); + // @codeCoverageIgnoreStart + $chunks = \explode('$' . $param->getName(), (string) $param); + $chunks = \explode(' ', \trim($chunks[0])); + $guess = \end($chunks); + + $hint = \sprintf('%s ', $guess); + // @codeCoverageIgnoreEnd } if ($param->isOptional()) { @@ -252,14 +287,14 @@ private static function formatFunctionParams(\ReflectionFunctionAbstract $reflec } else { $value = $param->getDefaultValue(); $typeStyle = self::getTypeStyle($value); - $value = is_array($value) ? 'array()' : is_null($value) ? 'null' : var_export($value, true); + $value = \is_array($value) ? 'array()' : \is_null($value) ? 'null' : \var_export($value, true); } - $default = sprintf(' = <%s>%s', $typeStyle, OutputFormatter::escape($value), $typeStyle); + $default = \sprintf(' = <%s>%s', $typeStyle, OutputFormatter::escape($value), $typeStyle); } else { $default = ''; } - $params[] = sprintf( + $params[] = \sprintf( '%s%s$%s%s', $param->isPassedByReference() ? '&' : '', $hint, diff --git a/app/vendor/psy/psysh/src/Psy/Input/CodeArgument.php b/app/vendor/psy/psysh/src/Input/CodeArgument.php similarity index 96% rename from app/vendor/psy/psysh/src/Psy/Input/CodeArgument.php rename to app/vendor/psy/psysh/src/Input/CodeArgument.php index 4e50754e4..cfeb9e16d 100644 --- a/app/vendor/psy/psysh/src/Psy/Input/CodeArgument.php +++ b/app/vendor/psy/psysh/src/Input/CodeArgument.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -42,7 +42,7 @@ class CodeArgument extends InputArgument public function __construct($name, $mode = null, $description = '', $default = null) { if ($mode & InputArgument::IS_ARRAY) { - throw new \InvalidArgumentException('Argument mode IS_ARRAY is not valid.'); + throw new \InvalidArgumentException('Argument mode IS_ARRAY is not valid'); } parent::__construct($name, $mode, $description, $default); diff --git a/app/vendor/psy/psysh/src/Psy/Input/FilterOptions.php b/app/vendor/psy/psysh/src/Input/FilterOptions.php similarity index 80% rename from app/vendor/psy/psysh/src/Psy/Input/FilterOptions.php rename to app/vendor/psy/psysh/src/Input/FilterOptions.php index 46017d222..d77a04fb7 100644 --- a/app/vendor/psy/psysh/src/Psy/Input/FilterOptions.php +++ b/app/vendor/psy/psysh/src/Input/FilterOptions.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,6 +11,7 @@ namespace Psy\Input; +use Psy\Exception\ErrorException; use Psy\Exception\RuntimeException; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -32,11 +33,11 @@ class FilterOptions */ public static function getOptions() { - return array( + return [ new InputOption('grep', 'G', InputOption::VALUE_REQUIRED, 'Limit to items matching the given pattern (string or regex).'), new InputOption('insensitive', 'i', InputOption::VALUE_NONE, 'Case-insensitive search (requires --grep).'), new InputOption('invert', 'v', InputOption::VALUE_NONE, 'Inverted search (requires --grep).'), - ); + ]; } /** @@ -55,7 +56,7 @@ public function bind(InputInterface $input) } if (!$this->stringIsRegex($pattern)) { - $pattern = '/' . preg_quote($pattern, '/') . '/'; + $pattern = '/' . \preg_quote($pattern, '/') . '/'; } if ($insensitive = $input->getOption('insensitive')) { @@ -90,7 +91,7 @@ public function hasFilter() */ public function match($string, array &$matches = null) { - return $this->filter === false || (preg_match($this->pattern, $string, $matches) xor $this->invert); + return $this->filter === false || (\preg_match($this->pattern, $string, $matches) xor $this->invert); } /** @@ -103,7 +104,7 @@ public function match($string, array &$matches = null) private function validateInput(InputInterface $input) { if (!$input->getOption('grep')) { - foreach (array('invert', 'insensitive') as $option) { + foreach (['invert', 'insensitive'] as $option) { if ($input->getOption($option)) { throw new RuntimeException('--' . $option . ' does not make sense without --grep'); } @@ -120,7 +121,7 @@ private function validateInput(InputInterface $input) */ private function stringIsRegex($string) { - return substr($string, 0, 1) === '/' && substr($string, -1) === '/' && strlen($string) >= 3; + return \substr($string, 0, 1) === '/' && \substr($string, -1) === '/' && \strlen($string) >= 3; } /** @@ -132,12 +133,13 @@ private function stringIsRegex($string) */ private function validateRegex($pattern) { - set_error_handler(array('Psy\Exception\ErrorException', 'throwException')); + \set_error_handler(['Psy\Exception\ErrorException', 'throwException']); try { - preg_match($pattern, ''); + \preg_match($pattern, ''); } catch (ErrorException $e) { - throw new RuntimeException(str_replace('preg_match(): ', 'Invalid regular expression: ', $e->getRawMessage())); + \restore_error_handler(); + throw new RuntimeException(\str_replace('preg_match(): ', 'Invalid regular expression: ', $e->getRawMessage())); } - restore_error_handler(); + \restore_error_handler(); } } diff --git a/app/vendor/psy/psysh/src/Psy/Input/ShellInput.php b/app/vendor/psy/psysh/src/Input/ShellInput.php similarity index 69% rename from app/vendor/psy/psysh/src/Psy/Input/ShellInput.php rename to app/vendor/psy/psysh/src/Input/ShellInput.php index 68a4252a2..8675f4d12 100644 --- a/app/vendor/psy/psysh/src/Psy/Input/ShellInput.php +++ b/app/vendor/psy/psysh/src/Input/ShellInput.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -51,10 +51,10 @@ public function bind(InputDefinition $definition) if ($definition->getArgumentCount() > 0) { $args = $definition->getArguments(); - $lastArg = array_pop($args); + $lastArg = \array_pop($args); foreach ($args as $arg) { if ($arg instanceof CodeArgument) { - $msg = sprintf('Unexpected CodeArgument before the final position: %s', $arg->getName()); + $msg = \sprintf('Unexpected CodeArgument before the final position: %s', $arg->getName()); throw new \InvalidArgumentException($msg); } } @@ -83,32 +83,34 @@ public function bind(InputDefinition $definition) */ private function tokenize($input) { - $tokens = array(); - $length = strlen($input); + $tokens = []; + $length = \strlen($input); $cursor = 0; while ($cursor < $length) { - if (preg_match('/\s+/A', $input, $match, null, $cursor)) { - } elseif (preg_match('/([^="\'\s]+?)(=?)(' . StringInput::REGEX_QUOTED_STRING . '+)/A', $input, $match, null, $cursor)) { - $tokens[] = array( - $match[1] . $match[2] . stripcslashes(str_replace(array('"\'', '\'"', '\'\'', '""'), '', substr($match[3], 1, strlen($match[3]) - 2))), - substr($input, $cursor), - ); - } elseif (preg_match('/' . StringInput::REGEX_QUOTED_STRING . '/A', $input, $match, null, $cursor)) { - $tokens[] = array( - stripcslashes(substr($match[0], 1, strlen($match[0]) - 2)), - substr($input, $cursor), - ); - } elseif (preg_match('/' . StringInput::REGEX_STRING . '/A', $input, $match, null, $cursor)) { - $tokens[] = array( - stripcslashes($match[1]), - substr($input, $cursor), - ); + if (\preg_match('/\s+/A', $input, $match, null, $cursor)) { + } elseif (\preg_match('/([^="\'\s]+?)(=?)(' . StringInput::REGEX_QUOTED_STRING . '+)/A', $input, $match, null, $cursor)) { + $tokens[] = [ + $match[1] . $match[2] . \stripcslashes(\str_replace(['"\'', '\'"', '\'\'', '""'], '', \substr($match[3], 1, \strlen($match[3]) - 2))), + \stripcslashes(\substr($input, $cursor)), + ]; + } elseif (\preg_match('/' . StringInput::REGEX_QUOTED_STRING . '/A', $input, $match, null, $cursor)) { + $tokens[] = [ + \stripcslashes(\substr($match[0], 1, \strlen($match[0]) - 2)), + \stripcslashes(\substr($input, $cursor)), + ]; + } elseif (\preg_match('/' . StringInput::REGEX_STRING . '/A', $input, $match, null, $cursor)) { + $tokens[] = [ + \stripcslashes($match[1]), + \stripcslashes(\substr($input, $cursor)), + ]; } else { // should never happen - throw new \InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10))); + // @codeCoverageIgnoreStart + throw new \InvalidArgumentException(\sprintf('Unable to parse input near "... %s ..."', \substr($input, $cursor, 10))); + // @codeCoverageIgnoreEnd } - $cursor += strlen($match[0]); + $cursor += \strlen($match[0]); } return $tokens; @@ -121,7 +123,7 @@ protected function parse() { $parseOptions = true; $this->parsed = $this->tokenPairs; - while (null !== $tokenPair = array_shift($this->parsed)) { + while (null !== $tokenPair = \array_shift($this->parsed)) { // token is what you'd expect. rest is the remainder of the input // string, including token, and will be used if this is a code arg. list($token, $rest) = $tokenPair; @@ -130,7 +132,7 @@ protected function parse() $this->parseShellArgument($token, $rest); } elseif ($parseOptions && '--' === $token) { $parseOptions = false; - } elseif ($parseOptions && 0 === strpos($token, '--')) { + } elseif ($parseOptions && 0 === \strpos($token, '--')) { $this->parseLongOption($token); } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) { $this->parseShortOption($token); @@ -150,7 +152,7 @@ protected function parse() */ private function parseShellArgument($token, $rest) { - $c = count($this->arguments); + $c = \count($this->arguments); // if input is expecting another argument, add it if ($this->definition->hasArgument($c)) { @@ -159,15 +161,19 @@ private function parseShellArgument($token, $rest) if ($arg instanceof CodeArgument) { // When we find a code argument, we're done parsing. Add the // remaining input to the current argument and call it a day. - $this->parsed = array(); + $this->parsed = []; $this->arguments[$arg->getName()] = $rest; } else { - $this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token; + $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token; } return; } + // (copypasta) + // + // @codeCoverageIgnoreStart + // if last argument isArray(), append token to last argument if ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) { $arg = $this->definition->getArgument($c - 1); @@ -178,14 +184,16 @@ private function parseShellArgument($token, $rest) // unexpected argument $all = $this->definition->getArguments(); - if (count($all)) { - throw new \RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all)))); + if (\count($all)) { + throw new \RuntimeException(\sprintf('Too many arguments, expected arguments "%s".', \implode('" "', \array_keys($all)))); } - throw new \RuntimeException(sprintf('No arguments expected, got "%s".', $token)); + throw new \RuntimeException(\sprintf('No arguments expected, got "%s".', $token)); + // @codeCoverageIgnoreEnd } // Everything below this is copypasta from ArgvInput private methods + // @codeCoverageIgnoreStart /** * Parses a short option. @@ -194,12 +202,12 @@ private function parseShellArgument($token, $rest) */ private function parseShortOption($token) { - $name = substr($token, 1); + $name = \substr($token, 1); - if (strlen($name) > 1) { + if (\strlen($name) > 1) { if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) { // an option with a value (with no space) - $this->addShortOption($name[0], substr($name, 1)); + $this->addShortOption($name[0], \substr($name, 1)); } else { $this->parseShortOptionSet($name); } @@ -217,15 +225,15 @@ private function parseShortOption($token) */ private function parseShortOptionSet($name) { - $len = strlen($name); + $len = \strlen($name); for ($i = 0; $i < $len; $i++) { if (!$this->definition->hasShortcut($name[$i])) { - throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i])); + throw new \RuntimeException(\sprintf('The "-%s" option does not exist.', $name[$i])); } $option = $this->definition->getOptionForShortcut($name[$i]); if ($option->acceptValue()) { - $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1)); + $this->addLongOption($option->getName(), $i === $len - 1 ? null : \substr($name, $i + 1)); break; } else { @@ -241,18 +249,18 @@ private function parseShortOptionSet($name) */ private function parseLongOption($token) { - $name = substr($token, 2); + $name = \substr($token, 2); - if (false !== $pos = strpos($name, '=')) { - if (0 === strlen($value = substr($name, $pos + 1))) { + if (false !== $pos = \strpos($name, '=')) { + if (0 === \strlen($value = \substr($name, $pos + 1))) { // if no value after "=" then substr() returns "" since php7 only, false before // see http://php.net/manual/fr/migration70.incompatible.php#119151 if (PHP_VERSION_ID < 70000 && false === $value) { $value = ''; } - array_unshift($this->parsed, array($value, null)); + \array_unshift($this->parsed, [$value, null]); } - $this->addLongOption(substr($name, 0, $pos), $value); + $this->addLongOption(\substr($name, 0, $pos), $value); } else { $this->addLongOption($name, null); } @@ -269,7 +277,7 @@ private function parseLongOption($token) private function addShortOption($shortcut, $value) { if (!$this->definition->hasShortcut($shortcut)) { - throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut)); + throw new \RuntimeException(\sprintf('The "-%s" option does not exist.', $shortcut)); } $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value); @@ -286,30 +294,30 @@ private function addShortOption($shortcut, $value) private function addLongOption($name, $value) { if (!$this->definition->hasOption($name)) { - throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name)); + throw new \RuntimeException(\sprintf('The "--%s" option does not exist.', $name)); } $option = $this->definition->getOption($name); if (null !== $value && !$option->acceptValue()) { - throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name)); + throw new \RuntimeException(\sprintf('The "--%s" option does not accept a value.', $name)); } - if (in_array($value, array('', null), true) && $option->acceptValue() && count($this->parsed)) { + if (\in_array($value, ['', null], true) && $option->acceptValue() && \count($this->parsed)) { // if option accepts an optional or mandatory argument // let's see if there is one provided - $next = array_shift($this->parsed); + $next = \array_shift($this->parsed); $nextToken = $next[0]; - if ((isset($nextToken[0]) && '-' !== $nextToken[0]) || in_array($nextToken, array('', null), true)) { + if ((isset($nextToken[0]) && '-' !== $nextToken[0]) || \in_array($nextToken, ['', null], true)) { $value = $nextToken; } else { - array_unshift($this->parsed, $next); + \array_unshift($this->parsed, $next); } } if (null === $value) { if ($option->isValueRequired()) { - throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name)); + throw new \RuntimeException(\sprintf('The "--%s" option requires a value.', $name)); } if (!$option->isArray() && !$option->isValueOptional()) { @@ -323,4 +331,6 @@ private function addLongOption($name, $value) $this->options[$name] = $value; } } + + // @codeCoverageIgnoreEnd } diff --git a/app/vendor/psy/psysh/src/Psy/Input/SilentInput.php b/app/vendor/psy/psysh/src/Input/SilentInput.php similarity index 96% rename from app/vendor/psy/psysh/src/Psy/Input/SilentInput.php rename to app/vendor/psy/psysh/src/Input/SilentInput.php index 0da750d69..c6f234ba9 100644 --- a/app/vendor/psy/psysh/src/Psy/Input/SilentInput.php +++ b/app/vendor/psy/psysh/src/Input/SilentInput.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Output/OutputPager.php b/app/vendor/psy/psysh/src/Output/OutputPager.php similarity index 94% rename from app/vendor/psy/psysh/src/Psy/Output/OutputPager.php rename to app/vendor/psy/psysh/src/Output/OutputPager.php index 03f049f61..a2f12aead 100644 --- a/app/vendor/psy/psysh/src/Psy/Output/OutputPager.php +++ b/app/vendor/psy/psysh/src/Output/OutputPager.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Output/PassthruPager.php b/app/vendor/psy/psysh/src/Output/PassthruPager.php similarity index 96% rename from app/vendor/psy/psysh/src/Psy/Output/PassthruPager.php rename to app/vendor/psy/psysh/src/Output/PassthruPager.php index 5bcbf7968..2dcb74398 100644 --- a/app/vendor/psy/psysh/src/Psy/Output/PassthruPager.php +++ b/app/vendor/psy/psysh/src/Output/PassthruPager.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Output/ProcOutputPager.php b/app/vendor/psy/psysh/src/Output/ProcOutputPager.php similarity index 82% rename from app/vendor/psy/psysh/src/Psy/Output/ProcOutputPager.php rename to app/vendor/psy/psysh/src/Output/ProcOutputPager.php index bb41c6cc9..a047b1c3f 100644 --- a/app/vendor/psy/psysh/src/Psy/Output/ProcOutputPager.php +++ b/app/vendor/psy/psysh/src/Output/ProcOutputPager.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -51,14 +51,14 @@ public function __construct(StreamOutput $output, $cmd = 'less -R -S -F -X') public function doWrite($message, $newline) { $pipe = $this->getPipe(); - if (false === @fwrite($pipe, $message . ($newline ? PHP_EOL : ''))) { + if (false === @\fwrite($pipe, $message . ($newline ? PHP_EOL : ''))) { // @codeCoverageIgnoreStart // should never happen - throw new \RuntimeException('Unable to write output.'); + throw new \RuntimeException('Unable to write output'); // @codeCoverageIgnoreEnd } - fflush($pipe); + \fflush($pipe); } /** @@ -67,11 +67,11 @@ public function doWrite($message, $newline) public function close() { if (isset($this->pipe)) { - fclose($this->pipe); + \fclose($this->pipe); } if (isset($this->proc)) { - $exit = proc_close($this->proc); + $exit = \proc_close($this->proc); if ($exit !== 0) { throw new \RuntimeException('Error closing output stream'); } @@ -88,10 +88,10 @@ public function close() private function getPipe() { if (!isset($this->pipe) || !isset($this->proc)) { - $desc = array(array('pipe', 'r'), $this->stream, fopen('php://stderr', 'w')); - $this->proc = proc_open($this->cmd, $desc, $pipes); + $desc = [['pipe', 'r'], $this->stream, \fopen('php://stderr', 'w')]; + $this->proc = \proc_open($this->cmd, $desc, $pipes); - if (!is_resource($this->proc)) { + if (!\is_resource($this->proc)) { throw new \RuntimeException('Error opening output stream'); } diff --git a/app/vendor/psy/psysh/src/Psy/Output/ShellOutput.php b/app/vendor/psy/psysh/src/Output/ShellOutput.php similarity index 90% rename from app/vendor/psy/psysh/src/Psy/Output/ShellOutput.php rename to app/vendor/psy/psysh/src/Output/ShellOutput.php index f390db132..5881a5c20 100644 --- a/app/vendor/psy/psysh/src/Psy/Output/ShellOutput.php +++ b/app/vendor/psy/psysh/src/Output/ShellOutput.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -41,7 +41,7 @@ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = nu if ($pager === null) { $this->pager = new PassthruPager($this); - } elseif (is_string($pager)) { + } elseif (\is_string($pager)) { $this->pager = new ProcOutputPager($this, $pager); } elseif ($pager instanceof OutputPager) { $this->pager = $pager; @@ -65,17 +65,17 @@ public function __construct($verbosity = self::VERBOSITY_NORMAL, $decorated = nu */ public function page($messages, $type = 0) { - if (is_string($messages)) { + if (\is_string($messages)) { $messages = (array) $messages; } - if (!is_array($messages) && !is_callable($messages)) { - throw new \InvalidArgumentException('Paged output requires a string, array or callback.'); + if (!\is_array($messages) && !\is_callable($messages)) { + throw new \InvalidArgumentException('Paged output requires a string, array or callback'); } $this->startPaging(); - if (is_callable($messages)) { + if (\is_callable($messages)) { $messages($this); } else { $this->write($messages, true, $type); @@ -122,15 +122,15 @@ public function write($messages, $newline = false, $type = 0) $messages = (array) $messages; if ($type & self::NUMBER_LINES) { - $pad = strlen((string) count($messages)); + $pad = \strlen((string) \count($messages)); $template = $this->isDecorated() ? ": %s" : "%{$pad}s: %s"; if ($type & self::OUTPUT_RAW) { - $messages = array_map(array('Symfony\Component\Console\Formatter\OutputFormatter', 'escape'), $messages); + $messages = \array_map(['Symfony\Component\Console\Formatter\OutputFormatter', 'escape'], $messages); } foreach ($messages as $i => $line) { - $messages[$i] = sprintf($template, $i, $line); + $messages[$i] = \sprintf($template, $i, $line); } // clean this up for super. @@ -175,20 +175,20 @@ private function initFormatters() $formatter = $this->getFormatter(); $formatter->setStyle('warning', new OutputFormatterStyle('black', 'yellow')); - $formatter->setStyle('error', new OutputFormatterStyle('black', 'red', array('bold'))); + $formatter->setStyle('error', new OutputFormatterStyle('black', 'red', ['bold'])); $formatter->setStyle('aside', new OutputFormatterStyle('blue')); - $formatter->setStyle('strong', new OutputFormatterStyle(null, null, array('bold'))); + $formatter->setStyle('strong', new OutputFormatterStyle(null, null, ['bold'])); $formatter->setStyle('return', new OutputFormatterStyle('cyan')); $formatter->setStyle('urgent', new OutputFormatterStyle('red')); $formatter->setStyle('hidden', new OutputFormatterStyle('black')); // Visibility - $formatter->setStyle('public', new OutputFormatterStyle(null, null, array('bold'))); + $formatter->setStyle('public', new OutputFormatterStyle(null, null, ['bold'])); $formatter->setStyle('protected', new OutputFormatterStyle('yellow')); $formatter->setStyle('private', new OutputFormatterStyle('red')); - $formatter->setStyle('global', new OutputFormatterStyle('cyan', null, array('bold'))); + $formatter->setStyle('global', new OutputFormatterStyle('cyan', null, ['bold'])); $formatter->setStyle('const', new OutputFormatterStyle('cyan')); - $formatter->setStyle('class', new OutputFormatterStyle('blue', null, array('underscore'))); + $formatter->setStyle('class', new OutputFormatterStyle('blue', null, ['underscore'])); $formatter->setStyle('function', new OutputFormatterStyle(null)); $formatter->setStyle('default', new OutputFormatterStyle(null)); diff --git a/app/vendor/psy/psysh/src/Psy/ParserFactory.php b/app/vendor/psy/psysh/src/ParserFactory.php similarity index 81% rename from app/vendor/psy/psysh/src/Psy/ParserFactory.php rename to app/vendor/psy/psysh/src/ParserFactory.php index 83f15398b..263da2022 100644 --- a/app/vendor/psy/psysh/src/Psy/ParserFactory.php +++ b/app/vendor/psy/psysh/src/ParserFactory.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -32,7 +32,7 @@ class ParserFactory */ public static function getPossibleKinds() { - return array('ONLY_PHP5', 'ONLY_PHP7', 'PREFER_PHP5', 'PREFER_PHP7'); + return ['ONLY_PHP5', 'ONLY_PHP7', 'PREFER_PHP5', 'PREFER_PHP7']; } /** @@ -44,7 +44,7 @@ public static function getPossibleKinds() */ public function hasKindsSupport() { - return class_exists('PhpParser\ParserFactory'); + return \class_exists('PhpParser\ParserFactory'); } /** @@ -55,7 +55,7 @@ public function hasKindsSupport() public function getDefaultKind() { if ($this->hasKindsSupport()) { - return version_compare(PHP_VERSION, '7.0', '>=') ? static::ONLY_PHP7 : static::ONLY_PHP5; + return \version_compare(PHP_VERSION, '7.0', '>=') ? static::ONLY_PHP7 : static::ONLY_PHP5; } } @@ -73,11 +73,11 @@ public function createParser($kind = null) $kind = $kind ?: $this->getDefaultKind(); - if (!in_array($kind, static::getPossibleKinds())) { + if (!\in_array($kind, static::getPossibleKinds())) { throw new \InvalidArgumentException('Unknown parser kind'); } - $parser = $originalFactory->create(constant('PhpParser\ParserFactory::' . $kind)); + $parser = $originalFactory->create(\constant('PhpParser\ParserFactory::' . $kind)); } else { if ($kind !== null) { throw new \InvalidArgumentException('Install PHP Parser v2.x to specify parser kind'); diff --git a/app/vendor/psy/psysh/src/Psy/Autoloader.php b/app/vendor/psy/psysh/src/Psy/Autoloader.php deleted file mode 100644 index df2e45b4a..000000000 --- a/app/vendor/psy/psysh/src/Psy/Autoloader.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -class StaticConstructorPass extends CodeCleanerPass -{ - private $isPHP533; - private $namespace; - - public function __construct() - { - $this->isPHP533 = version_compare(PHP_VERSION, '5.3.3', '>='); - } - - public function beforeTraverse(array $nodes) - { - $this->namespace = array(); - } - - /** - * Validate that the old-style constructor function is not static. - * - * @throws FatalErrorException if the old-style constructor function is static - * - * @param Node $node - */ - public function enterNode(Node $node) - { - if ($node instanceof Namespace_) { - $this->namespace = isset($node->name) ? $node->name->parts : array(); - } elseif ($node instanceof Class_) { - // Bail early if this is PHP 5.3.3 and we have a namespaced class - if (!empty($this->namespace) && $this->isPHP533) { - return; - } - - $constructor = null; - foreach ($node->stmts as $stmt) { - if ($stmt instanceof ClassMethod) { - // Bail early if we find a new-style constructor - if ('__construct' === strtolower($stmt->name)) { - return; - } - - // We found a possible old-style constructor - // (unless there is also a __construct method) - if (strtolower($node->name) === strtolower($stmt->name)) { - $constructor = $stmt; - } - } - } - - if ($constructor && $constructor->isStatic()) { - $msg = sprintf( - 'Constructor %s::%s() cannot be static', - implode('\\', array_merge($this->namespace, (array) $node->name)), - $constructor->name - ); - throw new FatalErrorException($msg, 0, E_ERROR, null, $node->getLine()); - } - } - } -} diff --git a/app/vendor/psy/psysh/src/Psy/Command/ThrowUpCommand.php b/app/vendor/psy/psysh/src/Psy/Command/ThrowUpCommand.php deleted file mode 100644 index 34bf425f6..000000000 --- a/app/vendor/psy/psysh/src/Psy/Command/ThrowUpCommand.php +++ /dev/null @@ -1,87 +0,0 @@ -context = $context; - } - - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('throw-up') - ->setDefinition(array( - new InputArgument('exception', InputArgument::OPTIONAL, 'Exception to throw'), - )) - ->setDescription('Throw an exception out of the Psy Shell.') - ->setHelp( - <<<'HELP' -Throws an exception out of the current the Psy Shell instance. - -By default it throws the most recent exception. - -e.g. ->>> throw-up ->>> throw-up $e -HELP - ); - } - - /** - * {@inheritdoc} - * - * @throws InvalidArgumentException if there is no exception to throw - * @throws ThrowUpException because what else do you expect it to do? - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - if ($name = $input->getArgument('exception')) { - $orig = $this->context->get(preg_replace('/^\$/', '', $name)); - } else { - $orig = $this->context->getLastException(); - } - - if (!$orig instanceof \Exception) { - throw new \InvalidArgumentException('throw-up can only throw Exceptions'); - } - - throw new ThrowUpException($orig); - } -} diff --git a/app/vendor/psy/psysh/src/Psy/Compiler.php b/app/vendor/psy/psysh/src/Psy/Compiler.php deleted file mode 100644 index 4ec7bf6b2..000000000 --- a/app/vendor/psy/psysh/src/Psy/Compiler.php +++ /dev/null @@ -1,163 +0,0 @@ -version = Shell::VERSION; - - $phar = new \Phar($pharFile, 0, 'psysh.phar'); - $phar->setSignatureAlgorithm(\Phar::SHA1); - - $phar->startBuffering(); - - $finder = Finder::create() - ->files() - ->ignoreVCS(true) - ->name('*.php') - ->notName('Compiler.php') - ->notName('Autoloader.php') - ->in(__DIR__ . '/..'); - - foreach ($finder as $file) { - $this->addFile($phar, $file); - } - - $finder = Finder::create() - ->files() - ->ignoreVCS(true) - ->name('*.php') - ->exclude('Tests') - ->exclude('tests') - ->exclude('Test') - ->exclude('test') - ->in(__DIR__ . '/../../build-vendor'); - - foreach ($finder as $file) { - $this->addFile($phar, $file); - } - - // Stubs - $phar->setStub($this->getStub()); - - $phar->stopBuffering(); - - unset($phar); - } - - /** - * Add a file to the psysh Phar. - * - * @param \Phar $phar - * @param \SplFileInfo $file - * @param bool $strip (default: true) - */ - private function addFile($phar, $file, $strip = true) - { - $path = str_replace(dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR, '', $file->getRealPath()); - - $content = file_get_contents($file); - if ($strip) { - $content = $this->stripWhitespace($content); - } elseif ('LICENSE' === basename($file)) { - $content = "\n" . $content . "\n"; - } - - $phar->addFromString($path, $content); - } - - /** - * Removes whitespace from a PHP source string while preserving line numbers. - * - * @param string $source A PHP string - * - * @return string The PHP string with the whitespace removed - */ - private function stripWhitespace($source) - { - if (!function_exists('token_get_all')) { - return $source; - } - - $output = ''; - foreach (token_get_all($source) as $token) { - if (is_string($token)) { - $output .= $token; - } elseif (in_array($token[0], array(T_COMMENT, T_DOC_COMMENT))) { - $output .= str_repeat("\n", substr_count($token[1], "\n")); - } elseif (T_WHITESPACE === $token[0]) { - // reduce wide spaces - $whitespace = preg_replace('{[ \t]+}', ' ', $token[1]); - // normalize newlines to \n - $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace); - // trim leading spaces - $whitespace = preg_replace('{\n +}', "\n", $whitespace); - $output .= $whitespace; - } else { - $output .= $token[1]; - } - } - - return $output; - } - - private static function getStubLicense() - { - $license = file_get_contents(__DIR__ . '/../../LICENSE'); - $license = str_replace('The MIT License (MIT)', '', $license); - $license = str_replace("\n", "\n * ", trim($license)); - - return $license; - } - - const STUB_AUTOLOAD = <<<'EOS' - Phar::mapPhar('psysh.phar'); - require 'phar://psysh.phar/build-vendor/autoload.php'; -EOS; - - /** - * Get a Phar stub for psysh. - * - * This is basically the psysh bin, with the autoload require statements swapped out. - * - * @return string - */ - private function getStub() - { - $content = file_get_contents(__DIR__ . '/../../bin/psysh'); - if (version_compare(PHP_VERSION, '5.4', '<')) { - $content = str_replace('#!/usr/bin/env php', '#!/usr/bin/env php -d detect_unicode=Off', $content); - } - $content = preg_replace('{/\* <<<.*?>>> \*/}sm', self::STUB_AUTOLOAD, $content); - $content = preg_replace('/\\(c\\) .*?with this source code./sm', self::getStubLicense(), $content); - - $content .= '__HALT_COMPILER();'; - - return $content; - } -} diff --git a/app/vendor/psy/psysh/src/Psy/ExecutionLoop/ForkingLoop.php b/app/vendor/psy/psysh/src/Psy/ExecutionLoop/ForkingLoop.php deleted file mode 100644 index f37eeae19..000000000 --- a/app/vendor/psy/psysh/src/Psy/ExecutionLoop/ForkingLoop.php +++ /dev/null @@ -1,177 +0,0 @@ - 0) { - // This is the main thread. We'll just wait for a while. - - // We won't be needing this one. - fclose($up); - - // Wait for a return value from the loop process. - $read = array($down); - $write = null; - $except = null; - if (stream_select($read, $write, $except, null) === false) { - throw new \RuntimeException('Error waiting for execution loop.'); - } - - $content = stream_get_contents($down); - fclose($down); - - if ($content) { - $shell->setScopeVariables(@unserialize($content)); - } - - return; - } - - // This is the child process. It's going to do all the work. - if (function_exists('setproctitle')) { - setproctitle('psysh (loop)'); - } - - // We won't be needing this one. - fclose($down); - - // Let's do some processing. - parent::run($shell); - - // Send the scope variables back up to the main thread - fwrite($up, $this->serializeReturn($shell->getScopeVariables(false))); - fclose($up); - - posix_kill(posix_getpid(), SIGKILL); - } - - /** - * Create a savegame at the start of each loop iteration. - */ - public function beforeLoop() - { - $this->createSavegame(); - } - - /** - * Clean up old savegames at the end of each loop iteration. - */ - public function afterLoop() - { - // if there's an old savegame hanging around, let's kill it. - if (isset($this->savegame)) { - posix_kill($this->savegame, SIGKILL); - pcntl_signal_dispatch(); - } - } - - /** - * Create a savegame fork. - * - * The savegame contains the current execution state, and can be resumed in - * the event that the worker dies unexpectedly (for example, by encountering - * a PHP fatal error). - */ - private function createSavegame() - { - // the current process will become the savegame - $this->savegame = posix_getpid(); - - $pid = pcntl_fork(); - if ($pid < 0) { - throw new \RuntimeException('Unable to create savegame fork.'); - } elseif ($pid > 0) { - // we're the savegame now... let's wait and see what happens - pcntl_waitpid($pid, $status); - - // worker exited cleanly, let's bail - if (!pcntl_wexitstatus($status)) { - posix_kill(posix_getpid(), SIGKILL); - } - - // worker didn't exit cleanly, we'll need to have another go - $this->createSavegame(); - } - } - - /** - * Serialize all serializable return values. - * - * A naïve serialization will run into issues if there is a Closure or - * SimpleXMLElement (among other things) in scope when exiting the execution - * loop. We'll just ignore these unserializable classes, and serialize what - * we can. - * - * @param array $return - * - * @return string - */ - private function serializeReturn(array $return) - { - $serializable = array(); - - foreach ($return as $key => $value) { - // No need to return magic variables - if (Context::isSpecialVariableName($key)) { - continue; - } - - // Resources and Closures don't error, but they don't serialize well either. - if (is_resource($value) || $value instanceof \Closure) { - continue; - } - - try { - @serialize($value); - $serializable[$key] = $value; - } catch (\Exception $e) { - // we'll just ignore this one... - } catch (\Throwable $e) { - // and this one too... - } - } - - return @serialize($serializable); - } -} diff --git a/app/vendor/psy/psysh/src/Psy/ExecutionLoop/Loop.php b/app/vendor/psy/psysh/src/Psy/ExecutionLoop/Loop.php deleted file mode 100644 index 79c310954..000000000 --- a/app/vendor/psy/psysh/src/Psy/ExecutionLoop/Loop.php +++ /dev/null @@ -1,186 +0,0 @@ -getIncludes() as $__psysh_include__) { - include $__psysh_include__; - } - } catch (\Exception $_e) { - $__psysh__->writeException($_e); - } - restore_error_handler(); - unset($__psysh_include__); - - extract($__psysh__->getScopeVariables(false)); - - do { - $__psysh__->beforeLoop(); - $__psysh__->setScopeVariables(get_defined_vars()); - - try { - // read a line, see if we should eval - $__psysh__->getInput(); - - // evaluate the current code buffer - ob_start( - array($__psysh__, 'writeStdout'), - version_compare(PHP_VERSION, '5.4', '>=') ? 1 : 2 - ); - - // Let PsySH inject some magic variables back into the - // shell scope... things like $__class, and $__file set by - // reflection commands - extract($__psysh__->getSpecialScopeVariables(false)); - - // And unset any magic variables which are no longer needed - foreach ($__psysh__->getUnusedCommandScopeVariableNames() as $__psysh_var_name__) { - unset($$__psysh_var_name__, $__psysh_var_name__); - } - - set_error_handler(array($__psysh__, 'handleError')); - $_ = eval($__psysh__->flushCode() ?: Loop::NOOP_INPUT); - restore_error_handler(); - - ob_end_flush(); - - $__psysh__->writeReturnValue($_); - } catch (BreakException $_e) { - restore_error_handler(); - if (ob_get_level() > 0) { - ob_end_clean(); - } - $__psysh__->writeException($_e); - - return; - } catch (ThrowUpException $_e) { - restore_error_handler(); - if (ob_get_level() > 0) { - ob_end_clean(); - } - $__psysh__->writeException($_e); - - throw $_e; - } catch (\TypeError $_e) { - restore_error_handler(); - if (ob_get_level() > 0) { - ob_end_clean(); - } - $__psysh__->writeException(TypeErrorException::fromTypeError($_e)); - } catch (\Error $_e) { - restore_error_handler(); - if (ob_get_level() > 0) { - ob_end_clean(); - } - $__psysh__->writeException(ErrorException::fromError($_e)); - } catch (\Exception $_e) { - restore_error_handler(); - if (ob_get_level() > 0) { - ob_end_clean(); - } - $__psysh__->writeException($_e); - } - - $__psysh__->afterLoop(); - } while (true); - }; - - // bind the closure to $this from the shell scope variables... - if (self::bindLoop()) { - $that = $shell->getBoundObject(); - if (is_object($that)) { - $loop = $loop->bindTo($that, get_class($that)); - } else { - $loop = $loop->bindTo(null, null); - } - } - - $loop($shell); - } - - /** - * A beforeLoop callback. - * - * This is executed at the start of each loop iteration. In the default - * (non-forking) loop implementation, this is a no-op. - */ - public function beforeLoop() - { - // no-op - } - - /** - * A afterLoop callback. - * - * This is executed at the end of each loop iteration. In the default - * (non-forking) loop implementation, this is a no-op. - */ - public function afterLoop() - { - // no-op - } - - /** - * Decide whether to bind the execution loop. - * - * @return bool - */ - protected static function bindLoop() - { - // skip binding on HHVM <= 3.5.0 - // see https://github.com/facebook/hhvm/issues/1203 - if (defined('HHVM_VERSION')) { - return version_compare(HHVM_VERSION, '3.5.0', '>='); - } - - return version_compare(PHP_VERSION, '5.4', '>='); - } -} diff --git a/app/vendor/psy/psysh/src/Psy/Readline/GNUReadline.php b/app/vendor/psy/psysh/src/Readline/GNUReadline.php similarity index 78% rename from app/vendor/psy/psysh/src/Psy/Readline/GNUReadline.php rename to app/vendor/psy/psysh/src/Readline/GNUReadline.php index 859b4228d..1cec3c63a 100644 --- a/app/vendor/psy/psysh/src/Psy/Readline/GNUReadline.php +++ b/app/vendor/psy/psysh/src/Readline/GNUReadline.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -36,7 +36,7 @@ class GNUReadline implements Readline */ public static function isSupported() { - return function_exists('readline_list_history'); + return \function_exists('readline_list_history'); } /** @@ -58,7 +58,7 @@ public function __construct($historyFile = null, $historySize = 0, $eraseDups = */ public function addHistory($line) { - if ($res = readline_add_history($line)) { + if ($res = \readline_add_history($line)) { $this->writeHistory(); } @@ -70,7 +70,7 @@ public function addHistory($line) */ public function clearHistory() { - if ($res = readline_clear_history()) { + if ($res = \readline_clear_history()) { $this->writeHistory(); } @@ -96,12 +96,12 @@ public function readHistory() // // https://github.com/php/php-src/blob/423a057023ef3c00d2ffc16a6b43ba01d0f71796/NEWS#L19-L21 // - if (version_compare(PHP_VERSION, '5.6.7', '>=') || !ini_get('open_basedir')) { - readline_read_history(); + if (\version_compare(PHP_VERSION, '5.6.7', '>=') || !\ini_get('open_basedir')) { + \readline_read_history(); } - readline_clear_history(); + \readline_clear_history(); - return readline_read_history($this->historyFile); + return \readline_read_history($this->historyFile); } /** @@ -109,7 +109,7 @@ public function readHistory() */ public function readline($prompt = null) { - return readline($prompt); + return \readline($prompt); } /** @@ -117,7 +117,7 @@ public function readline($prompt = null) */ public function redisplay() { - readline_redisplay(); + \readline_redisplay(); } /** @@ -128,7 +128,7 @@ public function writeHistory() // We have to write history first, since it is used // by Libedit to list history if ($this->historyFile !== false) { - $res = readline_write_history($this->historyFile); + $res = \readline_write_history($this->historyFile); } else { $res = true; } @@ -144,25 +144,25 @@ public function writeHistory() if ($this->eraseDups) { // flip-flip technique: removes duplicates, latest entries win. - $hist = array_flip(array_flip($hist)); + $hist = \array_flip(\array_flip($hist)); // sort on keys to get the order back - ksort($hist); + \ksort($hist); } if ($this->historySize > 0) { - $histsize = count($hist); + $histsize = \count($hist); if ($histsize > $this->historySize) { - $hist = array_slice($hist, $histsize - $this->historySize); + $hist = \array_slice($hist, $histsize - $this->historySize); } } - readline_clear_history(); + \readline_clear_history(); foreach ($hist as $line) { - readline_add_history($line); + \readline_add_history($line); } if ($this->historyFile !== false) { - return readline_write_history($this->historyFile); + return \readline_write_history($this->historyFile); } return true; diff --git a/app/vendor/psy/psysh/src/Psy/Readline/HoaConsole.php b/app/vendor/psy/psysh/src/Readline/HoaConsole.php similarity index 93% rename from app/vendor/psy/psysh/src/Psy/Readline/HoaConsole.php rename to app/vendor/psy/psysh/src/Readline/HoaConsole.php index 1ef7ac999..a49b59285 100644 --- a/app/vendor/psy/psysh/src/Psy/Readline/HoaConsole.php +++ b/app/vendor/psy/psysh/src/Readline/HoaConsole.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -27,7 +27,7 @@ class HoaConsole implements Readline */ public static function isSupported() { - return class_exists('\Hoa\Console\Console', true); + return \class_exists('\Hoa\Console\Console', true); } public function __construct() @@ -61,7 +61,7 @@ public function clearHistory() public function listHistory() { $i = 0; - $list = array(); + $list = []; while (($item = $this->hoaReadline->getHistory($i++)) !== null) { $list[] = $item; } diff --git a/app/vendor/psy/psysh/src/Psy/Readline/Libedit.php b/app/vendor/psy/psysh/src/Readline/Libedit.php similarity index 75% rename from app/vendor/psy/psysh/src/Psy/Readline/Libedit.php rename to app/vendor/psy/psysh/src/Readline/Libedit.php index 43b31a87f..d1dc002fd 100644 --- a/app/vendor/psy/psysh/src/Psy/Readline/Libedit.php +++ b/app/vendor/psy/psysh/src/Readline/Libedit.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -29,7 +29,7 @@ class Libedit extends GNUReadline */ public static function isSupported() { - return function_exists('readline') && !function_exists('readline_list_history'); + return \function_exists('readline') && !\function_exists('readline_list_history'); } /** @@ -37,23 +37,23 @@ public static function isSupported() */ public function listHistory() { - $history = file_get_contents($this->historyFile); + $history = \file_get_contents($this->historyFile); if (!$history) { - return array(); + return []; } // libedit doesn't seem to support non-unix line separators. - $history = explode("\n", $history); + $history = \explode("\n", $history); // shift the history signature, ensure it's valid - if (array_shift($history) !== '_HiStOrY_V2_') { - return array(); + if (\array_shift($history) !== '_HiStOrY_V2_') { + return []; } // decode the line - $history = array_map(array($this, 'parseHistoryLine'), $history); + $history = \array_map([$this, 'parseHistoryLine'], $history); // filter empty lines & comments - return array_values(array_filter($history)); + return \array_values(\array_filter($history)); } /** @@ -74,8 +74,8 @@ protected function parseHistoryLine($line) } // if "\0" is found in an entry, then // everything from it until the end of line is a comment. - if (($pos = strpos($line, "\0")) !== false) { - $line = substr($line, 0, $pos); + if (($pos = \strpos($line, "\0")) !== false) { + $line = \substr($line, 0, $pos); } return ($line !== '') ? Str::unvis($line) : null; diff --git a/app/vendor/psy/psysh/src/Psy/Readline/Readline.php b/app/vendor/psy/psysh/src/Readline/Readline.php similarity index 97% rename from app/vendor/psy/psysh/src/Psy/Readline/Readline.php rename to app/vendor/psy/psysh/src/Readline/Readline.php index 487ac81ff..6d0cb6e6b 100644 --- a/app/vendor/psy/psysh/src/Psy/Readline/Readline.php +++ b/app/vendor/psy/psysh/src/Readline/Readline.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/Readline/Transient.php b/app/vendor/psy/psysh/src/Readline/Transient.php similarity index 81% rename from app/vendor/psy/psysh/src/Psy/Readline/Transient.php rename to app/vendor/psy/psysh/src/Readline/Transient.php index 102eaf786..e238fdf49 100644 --- a/app/vendor/psy/psysh/src/Psy/Readline/Transient.php +++ b/app/vendor/psy/psysh/src/Readline/Transient.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,6 +21,7 @@ class Transient implements Readline private $history; private $historySize; private $eraseDups; + private $stdin; /** * Transient Readline is always supported. @@ -38,7 +39,7 @@ public static function isSupported() public function __construct($historyFile = null, $historySize = 0, $eraseDups = false) { // don't do anything with the history file... - $this->history = array(); + $this->history = []; $this->historySize = $historySize; $this->eraseDups = $eraseDups; } @@ -49,7 +50,7 @@ public function __construct($historyFile = null, $historySize = 0, $eraseDups = public function addHistory($line) { if ($this->eraseDups) { - if (($key = array_search($line, $this->history)) !== false) { + if (($key = \array_search($line, $this->history)) !== false) { unset($this->history[$key]); } } @@ -57,13 +58,13 @@ public function addHistory($line) $this->history[] = $line; if ($this->historySize > 0) { - $histsize = count($this->history); + $histsize = \count($this->history); if ($histsize > $this->historySize) { - $this->history = array_slice($this->history, $histsize - $this->historySize); + $this->history = \array_slice($this->history, $histsize - $this->historySize); } } - $this->history = array_values($this->history); + $this->history = \array_values($this->history); return true; } @@ -73,7 +74,7 @@ public function addHistory($line) */ public function clearHistory() { - $this->history = array(); + $this->history = []; return true; } @@ -105,7 +106,7 @@ public function readline($prompt = null) { echo $prompt; - return rtrim(fgets($this->getStdin(), 1024)); + return \rtrim(\fgets($this->getStdin(), 1024)); } /** @@ -134,10 +135,10 @@ public function writeHistory() private function getStdin() { if (!isset($this->stdin)) { - $this->stdin = fopen('php://stdin', 'r'); + $this->stdin = \fopen('php://stdin', 'r'); } - if (feof($this->stdin)) { + if (\feof($this->stdin)) { throw new BreakException('Ctrl+D'); } diff --git a/app/vendor/psy/psysh/src/Psy/Reflection/ReflectionConstant.php b/app/vendor/psy/psysh/src/Reflection/ReflectionClassConstant.php similarity index 51% rename from app/vendor/psy/psysh/src/Psy/Reflection/ReflectionConstant.php rename to app/vendor/psy/psysh/src/Reflection/ReflectionClassConstant.php index 4aa216130..019ad21da 100644 --- a/app/vendor/psy/psysh/src/Psy/Reflection/ReflectionConstant.php +++ b/app/vendor/psy/psysh/src/Reflection/ReflectionClassConstant.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,21 +12,21 @@ namespace Psy\Reflection; /** - * Somehow the standard reflection library doesn't include constants. + * Somehow the standard reflection library didn't include class constants until 7.1. * - * ReflectionConstant corrects that omission. + * ReflectionClassConstant corrects that omission. */ -class ReflectionConstant implements \Reflector +class ReflectionClassConstant implements \Reflector { - private $class; - private $name; + public $class; + public $name; private $value; /** - * Construct a ReflectionConstant object. + * Construct a ReflectionClassConstant object. * - * @param mixed $class - * @param string $name + * @param string|object $class + * @param string $name */ public function __construct($class, $name) { @@ -38,17 +38,40 @@ public function __construct($class, $name) $this->name = $name; $constants = $class->getConstants(); - if (!array_key_exists($name, $constants)) { + if (!\array_key_exists($name, $constants)) { throw new \InvalidArgumentException('Unknown constant: ' . $name); } $this->value = $constants[$name]; } + /** + * Exports a reflection. + * + * @param string|object $class + * @param string $name + * @param bool $return pass true to return the export, as opposed to emitting it + * + * @return null|string + */ + public static function export($class, $name, $return = false) + { + $refl = new self($class, $name); + $value = $refl->getValue(); + + $str = \sprintf('Constant [ public %s %s ] { %s }', \gettype($value), $refl->getName(), $value); + + if ($return) { + return $str; + } + + echo $str . "\n"; + } + /** * Gets the declaring class. * - * @return string + * @return \ReflectionClass */ public function getDeclaringClass() { @@ -67,6 +90,30 @@ public function getDeclaringClass() return $class; } + /** + * Get the constant's docblock. + * + * @return false + */ + public function getDocComment() + { + return false; + } + + /** + * Gets the class constant modifiers. + * + * Since this is only used for PHP < 7.1, we can just return "public". All + * the fancier modifiers are only available on PHP versions which have their + * own ReflectionClassConstant class :) + * + * @return int + */ + public function getModifiers() + { + return \ReflectionMethod::IS_PUBLIC; + } + /** * Gets the constant name. * @@ -87,6 +134,46 @@ public function getValue() return $this->value; } + /** + * Checks if class constant is private. + * + * @return bool false + */ + public function isPrivate() + { + return false; + } + + /** + * Checks if class constant is protected. + * + * @return bool false + */ + public function isProtected() + { + return false; + } + + /** + * Checks if class constant is public. + * + * @return bool true + */ + public function isPublic() + { + return true; + } + + /** + * To string. + * + * @return string + */ + public function __toString() + { + return $this->getName(); + } + /** * Gets the constant's file name. * @@ -120,32 +207,22 @@ public function getEndLine() } /** - * Get the constant's docblock. + * Get a ReflectionClassConstant instance. * - * @return false - */ - public function getDocComment() - { - return false; - } - - /** - * Export the constant? I don't think this is possible. + * In PHP >= 7.1, this will return a \ReflectionClassConstant from the + * standard reflection library. For older PHP, it will return this polyfill. * - * @throws \RuntimeException - */ - public static function export() - { - throw new \RuntimeException('Not yet implemented because it\'s unclear what I should do here :)'); - } - - /** - * To string. + * @param string|object $class + * @param string $name * - * @return string + * @return ReflectionClassConstant|\ReflectionClassConstant */ - public function __toString() + public static function create($class, $name) { - return $this->getName(); + if (\class_exists('\\ReflectionClassConstant')) { + return new \ReflectionClassConstant($class, $name); + } + + return new self($class, $name); } } diff --git a/app/vendor/psy/psysh/src/Reflection/ReflectionConstant.php b/app/vendor/psy/psysh/src/Reflection/ReflectionConstant.php new file mode 100644 index 000000000..a813fc573 --- /dev/null +++ b/app/vendor/psy/psysh/src/Reflection/ReflectionConstant.php @@ -0,0 +1,30 @@ +name = $name; + + if (!\defined($name) && !self::isMagicConstant($name)) { + throw new \InvalidArgumentException('Unknown constant: ' . $name); + } + + if (!self::isMagicConstant($name)) { + $this->value = @\constant($name); + } + } + + /** + * Exports a reflection. + * + * @param string $name + * @param bool $return pass true to return the export, as opposed to emitting it + * + * @return null|string + */ + public static function export($name, $return = false) + { + $refl = new self($name); + $value = $refl->getValue(); + + $str = \sprintf('Constant [ %s %s ] { %s }', \gettype($value), $refl->getName(), $value); + + if ($return) { + return $str; + } + + echo $str . "\n"; + } + + public static function isMagicConstant($name) + { + return \in_array($name, self::$magicConstants); + } + + /** + * Get the constant's docblock. + * + * @return false + */ + public function getDocComment() + { + return false; + } + + /** + * Gets the constant name. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Gets the namespace name. + * + * Returns '' when the constant is not namespaced. + * + * @return string + */ + public function getNamespaceName() + { + if (!$this->inNamespace()) { + return ''; + } + + return \preg_replace('/\\\\[^\\\\]+$/', '', $this->name); + } + + /** + * Gets the value of the constant. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Checks if this constant is defined in a namespace. + * + * @return bool + */ + public function inNamespace() + { + return \strpos($this->name, '\\') !== false; + } + + /** + * To string. + * + * @return string + */ + public function __toString() + { + return $this->getName(); + } + + /** + * Gets the constant's file name. + * + * Currently returns null, because if it returns a file name the signature + * formatter will barf. + */ + public function getFileName() + { + return; + // return $this->class->getFileName(); + } + + /** + * Get the code start line. + * + * @throws \RuntimeException + */ + public function getStartLine() + { + throw new \RuntimeException('Not yet implemented because it\'s unclear what I should do here :)'); + } + + /** + * Get the code end line. + * + * @throws \RuntimeException + */ + public function getEndLine() + { + return $this->getStartLine(); + } +} diff --git a/app/vendor/psy/psysh/src/Psy/Reflection/ReflectionLanguageConstruct.php b/app/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstruct.php similarity index 65% rename from app/vendor/psy/psysh/src/Psy/Reflection/ReflectionLanguageConstruct.php rename to app/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstruct.php index defa684b1..9b8eefc17 100644 --- a/app/vendor/psy/psysh/src/Psy/Reflection/ReflectionLanguageConstruct.php +++ b/app/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstruct.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,62 +21,62 @@ class ReflectionLanguageConstruct extends \ReflectionFunctionAbstract /** * Language construct parameter definitions. */ - private static $languageConstructs = array( - 'isset' => array( - 'var' => array(), - '...' => array( + private static $languageConstructs = [ + 'isset' => [ + 'var' => [], + '...' => [ 'isOptional' => true, 'defaultValue' => null, - ), - ), + ], + ], - 'unset' => array( - 'var' => array(), - '...' => array( + 'unset' => [ + 'var' => [], + '...' => [ 'isOptional' => true, 'defaultValue' => null, - ), - ), + ], + ], - 'empty' => array( - 'var' => array(), - ), + 'empty' => [ + 'var' => [], + ], - 'echo' => array( - 'arg1' => array(), - '...' => array( + 'echo' => [ + 'arg1' => [], + '...' => [ 'isOptional' => true, 'defaultValue' => null, - ), - ), + ], + ], - 'print' => array( - 'arg' => array(), - ), + 'print' => [ + 'arg' => [], + ], - 'die' => array( - 'status' => array( + 'die' => [ + 'status' => [ 'isOptional' => true, 'defaultValue' => 0, - ), - ), + ], + ], - 'exit' => array( - 'status' => array( + 'exit' => [ + 'status' => [ 'isOptional' => true, 'defaultValue' => 0, - ), - ), - ); + ], + ], + ]; /** * Construct a ReflectionLanguageConstruct object. * - * @param string $name + * @param string $keyword */ public function __construct($keyword) { - if (self::isLanguageConstruct($keyword)) { + if (!self::isLanguageConstruct($keyword)) { throw new \InvalidArgumentException('Unknown language construct: ' . $keyword); } @@ -116,18 +116,30 @@ public function returnsReference() /** * Get language construct params. * - * @return + * @return array */ public function getParameters() { - $params = array(); + $params = []; foreach (self::$languageConstructs[$this->keyword] as $parameter => $opts) { - array_push($params, new ReflectionLanguageConstructParameter($this->keyword, $parameter, $opts)); + \array_push($params, new ReflectionLanguageConstructParameter($this->keyword, $parameter, $opts)); } return $params; } + /** + * Gets the file name from a language construct. + * + * (Hint: it always returns false) + * + * @return bool false + */ + public function getFileName() + { + return false; + } + /** * To string. * @@ -141,12 +153,12 @@ public function __toString() /** * Check whether keyword is a (known) language construct. * - * @param $keyword + * @param string $keyword * * @return bool */ public static function isLanguageConstruct($keyword) { - return array_key_exists($keyword, self::$languageConstructs); + return \array_key_exists($keyword, self::$languageConstructs); } } diff --git a/app/vendor/psy/psysh/src/Psy/Reflection/ReflectionLanguageConstructParameter.php b/app/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstructParameter.php similarity index 82% rename from app/vendor/psy/psysh/src/Psy/Reflection/ReflectionLanguageConstructParameter.php rename to app/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstructParameter.php index 7d1b0dbdb..9161aa78b 100644 --- a/app/vendor/psy/psysh/src/Psy/Reflection/ReflectionLanguageConstructParameter.php +++ b/app/vendor/psy/psysh/src/Reflection/ReflectionLanguageConstructParameter.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -44,7 +44,7 @@ public function getClass() */ public function isArray() { - return array_key_exists('isArray', $this->opts) && $this->opts['isArray']; + return \array_key_exists('isArray', $this->opts) && $this->opts['isArray']; } /** @@ -76,7 +76,7 @@ public function getName() */ public function isOptional() { - return array_key_exists('isOptional', $this->opts) && $this->opts['isOptional']; + return \array_key_exists('isOptional', $this->opts) && $this->opts['isOptional']; } /** @@ -86,7 +86,7 @@ public function isOptional() */ public function isDefaultValueAvailable() { - return array_key_exists('defaultValue', $this->opts); + return \array_key_exists('defaultValue', $this->opts); } /** @@ -98,6 +98,6 @@ public function isDefaultValueAvailable() */ public function isPassedByReference() { - return array_key_exists('isPassedByReference', $this->opts) && $this->opts['isPassedByReference']; + return \array_key_exists('isPassedByReference', $this->opts) && $this->opts['isPassedByReference']; } } diff --git a/app/vendor/psy/psysh/src/Psy/Shell.php b/app/vendor/psy/psysh/src/Shell.php similarity index 62% rename from app/vendor/psy/psysh/src/Psy/Shell.php rename to app/vendor/psy/psysh/src/Shell.php index e002bee11..5d3517f23 100644 --- a/app/vendor/psy/psysh/src/Psy/Shell.php +++ b/app/vendor/psy/psysh/src/Shell.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -16,6 +16,9 @@ use Psy\Exception\ErrorException; use Psy\Exception\Exception as PsyException; use Psy\Exception\ThrowUpException; +use Psy\Exception\TypeErrorException; +use Psy\ExecutionLoop\ProcessForker; +use Psy\ExecutionLoop\RunkitReloader; use Psy\Input\ShellInput; use Psy\Input\SilentInput; use Psy\Output\ShellOutput; @@ -44,7 +47,7 @@ */ class Shell extends Application { - const VERSION = 'v0.8.17'; + const VERSION = 'v0.9.8'; const PROMPT = '>>> '; const BUFF_PROMPT = '... '; @@ -59,14 +62,17 @@ class Shell extends Application private $code; private $codeBuffer; private $codeBufferOpen; + private $codeStack; + private $stdoutBuffer; private $context; private $includes; private $loop; private $outputWantsNewline = false; - private $completion; - private $tabCompletionMatchers = array(); - private $stdoutBuffer; private $prompt; + private $loopListeners; + private $autoCompleter; + private $matchers = []; + private $commandsMatcher; /** * Create a new Psy Shell. @@ -75,14 +81,16 @@ class Shell extends Application */ public function __construct(Configuration $config = null) { - $this->config = $config ?: new Configuration(); - $this->cleaner = $this->config->getCodeCleaner(); - $this->loop = $this->config->getLoop(); - $this->context = new Context(); - $this->includes = array(); - $this->readline = $this->config->getReadline(); - $this->inputBuffer = array(); - $this->stdoutBuffer = ''; + $this->config = $config ?: new Configuration(); + $this->cleaner = $this->config->getCodeCleaner(); + $this->loop = new ExecutionLoop(); + $this->context = new Context(); + $this->includes = []; + $this->readline = $this->config->getReadline(); + $this->inputBuffer = []; + $this->codeStack = []; + $this->stdoutBuffer = ''; + $this->loopListeners = $this->getDefaultLoopListeners(); parent::__construct('Psy Shell', self::VERSION); @@ -101,7 +109,7 @@ public function __construct(Configuration $config = null) public static function isIncluded(array $trace) { return isset($trace[0]['function']) && - in_array($trace[0]['function'], array('require', 'include', 'require_once', 'include_once')); + \in_array($trace[0]['function'], ['require', 'include', 'require_once', 'include_once']); } /** @@ -110,14 +118,14 @@ public static function isIncluded(array $trace) * @see Psy\debug * @deprecated will be removed in 1.0. Use \Psy\debug instead * - * @param array $vars Scope variables from the calling context (default: array()) - * @param object $boundObject Bound object ($this) value for the shell + * @param array $vars Scope variables from the calling context (default: array()) + * @param object|string $bindTo Bound object ($this) or class (self) value for the shell * * @return array Scope variables from the debugger session */ - public static function debug(array $vars = array(), $boundObject = null) + public static function debug(array $vars = [], $bindTo = null) { - return \Psy\debug($vars, $boundObject); + return \Psy\debug($vars, $bindTo); } /** @@ -139,6 +147,10 @@ public function add(BaseCommand $command) if ($ret instanceof PresenterAware) { $ret->setPresenter($this->config->getPresenter()); } + + if (isset($this->commandsMatcher)) { + $this->commandsMatcher->setCommands($this->all()); + } } return $ret; @@ -151,10 +163,10 @@ public function add(BaseCommand $command) */ protected function getDefaultInputDefinition() { - return new InputDefinition(array( + return new InputDefinition([ new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'), new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message.'), - )); + ]); } /** @@ -170,7 +182,7 @@ protected function getDefaultCommands() $hist = new Command\HistoryCommand(); $hist->setReadline($this->readline); - return array( + return [ new Command\HelpCommand(), new Command\ListCommand(), new Command\DumpCommand(), @@ -179,6 +191,7 @@ protected function getDefaultCommands() new Command\WtfCommand($this->config->colorMode()), new Command\WhereamiCommand($this->config->colorMode()), new Command\ThrowUpCommand(), + new Command\TimeitCommand(), new Command\TraceCommand(), new Command\BufferCommand(), new Command\ClearCommand(), @@ -187,41 +200,85 @@ protected function getDefaultCommands() $sudo, $hist, new Command\ExitCommand(), - ); + ]; } /** * @return array */ + protected function getDefaultMatchers() + { + // Store the Commands Matcher for later. If more commands are added, + // we'll update the Commands Matcher too. + $this->commandsMatcher = new Matcher\CommandsMatcher($this->all()); + + return [ + $this->commandsMatcher, + new Matcher\KeywordsMatcher(), + new Matcher\VariablesMatcher(), + new Matcher\ConstantsMatcher(), + new Matcher\FunctionsMatcher(), + new Matcher\ClassNamesMatcher(), + new Matcher\ClassMethodsMatcher(), + new Matcher\ClassAttributesMatcher(), + new Matcher\ObjectMethodsMatcher(), + new Matcher\ObjectAttributesMatcher(), + new Matcher\ClassMethodDefaultParametersMatcher(), + new Matcher\ObjectMethodDefaultParametersMatcher(), + new Matcher\FunctionDefaultParametersMatcher(), + ]; + } + + /** + * @deprecated Nothing should use this anymore + */ protected function getTabCompletionMatchers() { - if (empty($this->tabCompletionMatchers)) { - $this->tabCompletionMatchers = array( - new Matcher\CommandsMatcher($this->all()), - new Matcher\KeywordsMatcher(), - new Matcher\VariablesMatcher(), - new Matcher\ConstantsMatcher(), - new Matcher\FunctionsMatcher(), - new Matcher\ClassNamesMatcher(), - new Matcher\ClassMethodsMatcher(), - new Matcher\ClassAttributesMatcher(), - new Matcher\ObjectMethodsMatcher(), - new Matcher\ObjectAttributesMatcher(), - new Matcher\ClassMethodDefaultParametersMatcher(), - new Matcher\ObjectMethodDefaultParametersMatcher(), - new Matcher\FunctionDefaultParametersMatcher(), - ); + @\trigger_error('getTabCompletionMatchers is no longer used', E_USER_DEPRECATED); + } + + /** + * Gets the default command loop listeners. + * + * @return array An array of Execution Loop Listener instances + */ + protected function getDefaultLoopListeners() + { + $listeners = []; + + if (ProcessForker::isSupported() && $this->config->usePcntl()) { + $listeners[] = new ProcessForker(); + } + + if (RunkitReloader::isSupported()) { + $listeners[] = new RunkitReloader(); } - return $this->tabCompletionMatchers; + return $listeners; + } + + /** + * Add tab completion matchers. + * + * @param array $matchers + */ + public function addMatchers(array $matchers) + { + $this->matchers = \array_merge($this->matchers, $matchers); + + if (isset($this->autoCompleter)) { + $this->addMatchersToAutoCompleter($matchers); + } } /** + * @deprecated Call `addMatchers` instead + * * @param array $matchers */ public function addTabCompletionMatchers(array $matchers) { - $this->tabCompletionMatchers = array_merge($matchers, $this->getTabCompletionMatchers()); + $this->addMatchers($matchers); } /** @@ -247,7 +304,7 @@ public function run(InputInterface $input = null, OutputInterface $output = null $this->initializeTabCompletion(); if ($input === null && !isset($_SERVER['argv'])) { - $input = new ArgvInput(array()); + $input = new ArgvInput([]); } if ($output === null) { @@ -259,6 +316,8 @@ public function run(InputInterface $input = null, OutputInterface $output = null } catch (\Exception $e) { $this->writeException($e); } + + return 1; } /** @@ -282,18 +341,19 @@ public function doRun(InputInterface $input, OutputInterface $output) $this->readline->readHistory(); - // if ($this->config->useReadline()) { - // readline_completion_function(array($this, 'autocomplete')); - // } - $this->output->writeln($this->getHeader()); $this->writeVersionInfo(); $this->writeStartupMessage(); try { + $this->beforeRun(); $this->loop->run($this); + $this->afterRun(); } catch (ThrowUpException $e) { throw $e->getPrevious(); + } catch (BreakException $e) { + // The ProcessForker throws a BreakException to finish the main thread. + return; } } @@ -332,12 +392,15 @@ public function getInput() } // handle empty input - if (trim($input) === '') { + if (\trim($input) === '' && !$this->codeBufferOpen) { continue; } - if ($this->hasCommand($input)) { - $this->readline->addHistory($input); + $input = $this->onInput($input); + + // If the input isn't in an open string or comment, check for commands to run. + if ($this->hasCommand($input) && !$this->inputInOpenStringOrComment($input)) { + $this->addHistory($input); $this->runCommand($input); continue; @@ -348,23 +411,101 @@ public function getInput() } /** - * Pass the beforeLoop callback through to the Loop instance. + * Check whether the code buffer (plus current input) is in an open string or comment. * - * @see Loop::beforeLoop + * @param string $input current line of input + * + * @return bool true if the input is in an open string or comment + */ + private function inputInOpenStringOrComment($input) + { + if (!$this->hasCode()) { + return; + } + + $code = $this->codeBuffer; + \array_push($code, $input); + $tokens = @\token_get_all('loopListeners as $listener) { + $listener->beforeRun($this); + } + } + + /** + * Run execution loop listeners at the start of each loop. */ public function beforeLoop() { - $this->loop->beforeLoop(); + foreach ($this->loopListeners as $listener) { + $listener->beforeLoop($this); + } + } + + /** + * Run execution loop listeners on user input. + * + * @param string $input + * + * @return string + */ + public function onInput($input) + { + foreach ($this->loopListeners as $listeners) { + if (($return = $listeners->onInput($this, $input)) !== null) { + $input = $return; + } + } + + return $input; } /** - * Pass the afterLoop callback through to the Loop instance. + * Run execution loop listeners on code to be executed. + * + * @param string $code * - * @see Loop::afterLoop + * @return string + */ + public function onExecute($code) + { + foreach ($this->loopListeners as $listener) { + if (($return = $listener->onExecute($this, $code)) !== null) { + $code = $return; + } + } + + return $code; + } + + /** + * Run execution loop listeners after each loop. */ public function afterLoop() { - $this->loop->afterLoop(); + foreach ($this->loopListeners as $listener) { + $listener->afterLoop($this); + } + } + + /** + * Run execution loop listers after the shell session. + */ + protected function afterRun() + { + foreach ($this->loopListeners as $listener) { + $listener->afterRun($this); + } } /** @@ -417,6 +558,30 @@ public function getSpecialScopeVariables($includeBoundObject = true) return $vars; } + /** + * Return the set of variables currently in scope which differ from the + * values passed as $currentVars. + * + * This is used inside the Execution Loop Closure to pick up scope variable + * changes made by commands while the loop is running. + * + * @param array $currentVars + * + * @return array Associative array of scope variables which differ from $currentVars + */ + public function getScopeVariablesDiff(array $currentVars) + { + $newVars = []; + + foreach ($this->getScopeVariables(false) as $key => $value) { + if (!array_key_exists($key, $currentVars) || $currentVars[$key] !== $value) { + $newVars[$key] = $value; + } + } + + return $newVars; + } + /** * Get the set of unused command-scope variable names. * @@ -434,7 +599,7 @@ public function getUnusedCommandScopeVariableNames() */ public function getScopeVariableNames() { - return array_keys($this->context->getAll()); + return \array_keys($this->context->getAll()); } /** @@ -469,12 +634,32 @@ public function getBoundObject() return $this->context->getBoundObject(); } + /** + * Set the bound class (self) for the interactive shell. + * + * @param string|null $boundClass + */ + public function setBoundClass($boundClass) + { + $this->context->setBoundClass($boundClass); + } + + /** + * Get the bound class (self) for the interactive shell. + * + * @return string|null + */ + public function getBoundClass() + { + return $this->context->getBoundClass(); + } + /** * Add includes, to be parsed and executed before running the interactive shell. * * @param array $includes */ - public function setIncludes(array $includes = array()) + public function setIncludes(array $includes = []) { $this->includes = $includes; } @@ -486,7 +671,7 @@ public function setIncludes(array $includes = array()) */ public function getIncludes() { - return array_merge($this->config->getDefaultIncludes(), $this->includes); + return \array_merge($this->config->getDefaultIncludes(), $this->includes); } /** @@ -515,19 +700,20 @@ protected function hasValidCode() * Add code to the code buffer. * * @param string $code + * @param bool $silent */ - public function addCode($code) + public function addCode($code, $silent = false) { try { // Code lines ending in \ keep the buffer open - if (substr(rtrim($code), -1) === '\\') { + if (\substr(\rtrim($code), -1) === '\\') { $this->codeBufferOpen = true; - $code = substr(rtrim($code), 0, -1); + $code = \substr(\rtrim($code), 0, -1); } else { $this->codeBufferOpen = false; } - $this->codeBuffer[] = $code; + $this->codeBuffer[] = $silent ? new SilentInput($code) : $code; $this->code = $this->cleaner->clean($this->codeBuffer, $this->config->requireSemicolons()); } catch (\Exception $e) { // Add failed code blocks to the readline history. @@ -537,6 +723,44 @@ public function addCode($code) } } + /** + * Set the code buffer. + * + * This is mostly used by `Shell::execute`. Any existing code in the input + * buffer is pushed onto a stack and will come back after this new code is + * executed. + * + * @throws \InvalidArgumentException if $code isn't a complete statement + * + * @param string $code + * @param bool $silent + */ + private function setCode($code, $silent = false) + { + if ($this->hasCode()) { + $this->codeStack[] = [$this->codeBuffer, $this->codeBufferOpen, $this->code]; + } + + $this->resetCodeBuffer(); + try { + $this->addCode($code, $silent); + } catch (\Throwable $e) { + $this->popCodeStack(); + + throw $e; + } catch (\Exception $e) { + $this->popCodeStack(); + + throw $e; + } + + if (!$this->hasValidCode()) { + $this->popCodeStack(); + + throw new \InvalidArgumentException('Unexpected end of input'); + } + } + /** * Get the current code buffer. * @@ -566,9 +790,9 @@ protected function runCommand($input) throw new \InvalidArgumentException('Command not found: ' . $input); } - $input = new ShellInput(str_replace('\\', '\\\\', rtrim($input, " \t\n\r\0\x0B;"))); + $input = new ShellInput(\str_replace('\\', '\\\\', \rtrim($input, " \t\n\r\0\x0B;"))); - if ($input->hasParameterOption(array('--help', '-h'))) { + if ($input->hasParameterOption(['--help', '-h'])) { $helpCommand = $this->get('help'); $helpCommand->setCommand($command); @@ -586,7 +810,7 @@ protected function runCommand($input) */ public function resetCodeBuffer() { - $this->codeBuffer = array(); + $this->codeBuffer = []; $this->code = false; } @@ -618,26 +842,64 @@ public function flushCode() if ($this->hasValidCode()) { $this->addCodeBufferToHistory(); $code = $this->code; - $this->resetCodeBuffer(); + $this->popCodeStack(); return $code; } } + /** + * Reset the code buffer and restore any code pushed during `execute` calls. + */ + private function popCodeStack() + { + $this->resetCodeBuffer(); + + if (empty($this->codeStack)) { + return; + } + + list($codeBuffer, $codeBufferOpen, $code) = \array_pop($this->codeStack); + + $this->codeBuffer = $codeBuffer; + $this->codeBufferOpen = $codeBufferOpen; + $this->code = $code; + } + + /** + * (Possibly) add a line to the readline history. + * + * Like Bash, if the line starts with a space character, it will be omitted + * from history. Note that an entire block multi-line code input will be + * omitted iff the first line begins with a space. + * + * Additionally, if a line is "silent", i.e. it was initially added with the + * silent flag, it will also be omitted. + * + * @param string|SilentInput $line + */ + private function addHistory($line) + { + if ($line instanceof SilentInput) { + return; + } + + // Skip empty lines and lines starting with a space + if (\trim($line) !== '' && \substr($line, 0, 1) !== ' ') { + $this->readline->addHistory($line); + } + } + /** * Filter silent input from code buffer, write the rest to readline history. */ private function addCodeBufferToHistory() { - $codeBuffer = array_filter($this->codeBuffer, function ($line) { + $codeBuffer = \array_filter($this->codeBuffer, function ($line) { return !$line instanceof SilentInput; }); - $code = implode("\n", $codeBuffer); - - if (trim($code) !== '') { - $this->readline->addHistory($code); - } + $this->addHistory(\implode("\n", $codeBuffer)); } /** @@ -650,7 +912,7 @@ private function addCodeBufferToHistory() public function getNamespace() { if ($namespace = $this->cleaner->getNamespace()) { - return implode('\\', $namespace); + return \implode('\\', $namespace); } } @@ -664,15 +926,12 @@ public function getNamespace() */ public function writeStdout($out, $phase = PHP_OUTPUT_HANDLER_END) { - $isCleaning = false; - if (version_compare(PHP_VERSION, '5.4', '>=')) { - $isCleaning = $phase & PHP_OUTPUT_HANDLER_CLEAN; - } + $isCleaning = $phase & PHP_OUTPUT_HANDLER_CLEAN; // Incremental flush if ($out !== '' && !$isCleaning) { $this->output->write($out, false, ShellOutput::OUTPUT_RAW); - $this->outputWantsNewline = (substr($out, -1) !== "\n"); + $this->outputWantsNewline = (\substr($out, -1) !== "\n"); $this->stdoutBuffer .= $out; } @@ -680,7 +939,7 @@ public function writeStdout($out, $phase = PHP_OUTPUT_HANDLER_END) if ($phase & PHP_OUTPUT_HANDLER_END) { // Write an extra newline if stdout didn't end with one if ($this->outputWantsNewline) { - $this->output->writeln(sprintf('', $this->config->useUnicode() ? '⏎' : '\\n')); + $this->output->writeln(\sprintf('', $this->config->useUnicode() ? '⏎' : '\\n')); $this->outputWantsNewline = false; } @@ -710,9 +969,9 @@ public function writeReturnValue($ret) $this->context->setReturnValue($ret); $ret = $this->presentValue($ret); - $indent = str_repeat(' ', strlen(static::RETVAL)); + $indent = \str_repeat(' ', \strlen(static::RETVAL)); - $this->output->writeln(static::RETVAL . str_replace(PHP_EOL, PHP_EOL . $indent, $ret)); + $this->output->writeln(static::RETVAL . \str_replace(PHP_EOL, PHP_EOL . $indent, $ret)); } /** @@ -723,8 +982,7 @@ public function writeReturnValue($ret) * * Stores $e as the last Exception in the Shell Context. * - * @param \Exception $e An exception instance - * @param OutputInterface $output An OutputInterface instance + * @param \Exception $e An exception instance */ public function writeException(\Exception $e) { @@ -747,15 +1005,23 @@ public function formatException(\Exception $e) $message = $e->getMessage(); if (!$e instanceof PsyException) { if ($message === '') { - $message = get_class($e); + $message = \get_class($e); } else { - $message = sprintf('%s with message \'%s\'', get_class($e), $message); + $message = \sprintf('%s with message \'%s\'', \get_class($e), $message); } } + $message = \preg_replace( + "#(\\w:)?(/\\w+)*/src/Execution(?:Loop)?Closure.php\(\d+\) : eval\(\)'d code#", + "eval()'d code", + \str_replace('\\', '/', $message) + ); + + $message = \str_replace(" in eval()'d code", ' in Psy Shell code', $message); + $severity = ($e instanceof \ErrorException) ? $this->getSeverity($e) : 'error'; - return sprintf('<%s>%s', $severity, OutputFormatter::escape($message), $severity); + return \sprintf('<%s>%s', $severity, OutputFormatter::escape($message), $severity); } /** @@ -768,7 +1034,7 @@ public function formatException(\Exception $e) protected function getSeverity(\ErrorException $e) { $severity = $e->getSeverity(); - if ($severity & error_reporting()) { + if ($severity & \error_reporting()) { switch ($severity) { case E_WARNING: case E_NOTICE: @@ -788,6 +1054,34 @@ protected function getSeverity(\ErrorException $e) } } + /** + * Execute code in the shell execution context. + * + * @param string $code + * @param bool $throwExceptions + * + * @return mixed + */ + public function execute($code, $throwExceptions = false) + { + $this->setCode($code, true); + $closure = new ExecutionClosure($this); + + if ($throwExceptions) { + return $closure->execute(); + } + + try { + return $closure->execute(); + } catch (\TypeError $_e) { + $this->writeException(TypeErrorException::fromTypeError($_e)); + } catch (\Error $_e) { + $this->writeException(ErrorException::fromError($_e)); + } catch (\Exception $_e) { + $this->writeException($_e); + } + } + /** * Helper for throwing an ErrorException. * @@ -816,7 +1110,7 @@ protected function getSeverity(\ErrorException $e) */ public function handleError($errno, $errstr, $errfile, $errline) { - if ($errno & error_reporting()) { + if ($errno & \error_reporting()) { ErrorException::throwException($errno, $errstr, $errfile, $errline); } elseif ($errno & $this->config->errorLoggingLevel()) { // log it and continue... @@ -862,9 +1156,8 @@ protected function getCommand($input) */ protected function hasCommand($input) { - $input = new StringInput($input); - if ($name = $input->getFirstArgument()) { - return $this->has($name); + if (\preg_match('/([^\s]+?)(?:\s|$)/A', \ltrim($input), $match)) { + return $this->has($match[1]); } return false; @@ -898,22 +1191,22 @@ protected function getPrompt() protected function readline() { if (!empty($this->inputBuffer)) { - $line = array_shift($this->inputBuffer); + $line = \array_shift($this->inputBuffer); if (!$line instanceof SilentInput) { - $this->output->writeln(sprintf('', static::REPLAY, OutputFormatter::escape($line))); + $this->output->writeln(\sprintf('', static::REPLAY, OutputFormatter::escape($line))); } return $line; } if ($bracketedPaste = $this->config->useBracketedPaste()) { - printf("\e[?2004h"); // Enable bracketed paste + \printf("\e[?2004h"); // Enable bracketed paste } $line = $this->readline->readline($this->getPrompt()); if ($bracketedPaste) { - printf("\e[?2004l"); // ... and disable it again + \printf("\e[?2004l"); // ... and disable it again } return $line; @@ -926,7 +1219,7 @@ protected function readline() */ protected function getHeader() { - return sprintf('', $this->getVersion()); + return \sprintf('', $this->getVersion()); } /** @@ -938,7 +1231,7 @@ public function getVersion() { $separator = $this->config->useUnicode() ? '—' : '-'; - return sprintf('Psy Shell %s (PHP %s %s %s)', self::VERSION, phpversion(), $separator, php_sapi_name()); + return \sprintf('Psy Shell %s (PHP %s %s %s)', self::VERSION, PHP_VERSION, $separator, PHP_SAPI); } /** @@ -952,28 +1245,11 @@ public function getManualDb() } /** - * Autocomplete variable names. - * - * This is used by `readline` for tab completion. - * - * @param string $text - * - * @return mixed Array possible completions for the given input, if any + * @deprecated Tab completion is provided by the AutoCompleter service */ protected function autocomplete($text) { - $info = readline_info(); - // $line = substr($info['line_buffer'], 0, $info['end']); - - // Check whether there's a command for this - // $words = explode(' ', $line); - // $firstWord = reset($words); - - // check whether this is a variable... - $firstChar = substr($info['line_buffer'], max(0, $info['end'] - strlen($text) - 1), 1); - if ($firstChar === '$') { - return $this->getScopeVariableNames(); - } + @\trigger_error('Tab completion is provided by the AutoCompleter service', E_USER_DEPRECATED); } /** @@ -984,17 +1260,32 @@ protected function autocomplete($text) */ protected function initializeTabCompletion() { - // auto completer needs shell to be linked to configuration because of the context aware matchers - if ($this->config->getTabCompletion()) { - $this->completion = $this->config->getAutoCompleter(); - $this->addTabCompletionMatchers($this->config->getTabCompletionMatchers()); - foreach ($this->getTabCompletionMatchers() as $matcher) { - if ($matcher instanceof ContextAware) { - $matcher->setContext($this->context); - } - $this->completion->addMatcher($matcher); + if (!$this->config->useTabCompletion()) { + return; + } + + $this->autoCompleter = $this->config->getAutoCompleter(); + + // auto completer needs shell to be linked to configuration because of + // the context aware matchers + $this->addMatchersToAutoCompleter($this->getDefaultMatchers()); + $this->addMatchersToAutoCompleter($this->matchers); + + $this->autoCompleter->activate(); + } + + /** + * Add matchers to the auto completer, setting context if needed. + * + * @param array $matchers + */ + private function addMatchersToAutoCompleter(array $matchers) + { + foreach ($matchers as $matcher) { + if ($matcher instanceof ContextAware) { + $matcher->setContext($this->context); } - $this->completion->activate(); + $this->autoCompleter->addMatcher($matcher); } } @@ -1013,7 +1304,7 @@ protected function writeVersionInfo() try { $client = $this->config->getChecker(); if (!$client->isLatest()) { - $this->output->writeln(sprintf('New version is available (current: %s, latest: %s)', self::VERSION, $client->getLatest())); + $this->output->writeln(\sprintf('New version is available (current: %s, latest: %s)', self::VERSION, $client->getLatest())); } } catch (\InvalidArgumentException $e) { $this->output->writeln($e->getMessage()); diff --git a/app/vendor/psy/psysh/src/Psy/Sudo.php b/app/vendor/psy/psysh/src/Sudo.php similarity index 93% rename from app/vendor/psy/psysh/src/Psy/Sudo.php rename to app/vendor/psy/psysh/src/Sudo.php index 2ba55728e..be354bef9 100644 --- a/app/vendor/psy/psysh/src/Psy/Sudo.php +++ b/app/vendor/psy/psysh/src/Sudo.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -64,9 +64,9 @@ public static function assignProperty($object, $property, $value) */ public static function callMethod($object, $method, $args = null) { - $args = func_get_args(); - $object = array_shift($args); - $method = array_shift($args); + $args = \func_get_args(); + $object = \array_shift($args); + $method = \array_shift($args); $refl = new \ReflectionObject($object); $reflMethod = $refl->getMethod($method); @@ -122,9 +122,9 @@ public static function assignStaticProperty($class, $property, $value) */ public static function callStatic($class, $method, $args = null) { - $args = func_get_args(); - $class = array_shift($args); - $method = array_shift($args); + $args = \func_get_args(); + $class = \array_shift($args); + $method = \array_shift($args); $refl = new \ReflectionClass($class); $reflMethod = $refl->getMethod($method); diff --git a/app/vendor/psy/psysh/src/Psy/Sudo/SudoVisitor.php b/app/vendor/psy/psysh/src/Sudo/SudoVisitor.php similarity index 57% rename from app/vendor/psy/psysh/src/Psy/Sudo/SudoVisitor.php rename to app/vendor/psy/psysh/src/Sudo/SudoVisitor.php index 77ed7e026..2b78a423e 100644 --- a/app/vendor/psy/psysh/src/Psy/Sudo/SudoVisitor.php +++ b/app/vendor/psy/psysh/src/Sudo/SudoVisitor.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -19,6 +19,8 @@ use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\StaticPropertyFetch; +use PhpParser\Node\Identifier; +use PhpParser\Node\Name; use PhpParser\Node\Name\FullyQualified as FullyQualifiedName; use PhpParser\Node\Scalar\String_; use PhpParser\NodeVisitorAbstract; @@ -47,60 +49,67 @@ class SudoVisitor extends NodeVisitorAbstract public function enterNode(Node $node) { if ($node instanceof PropertyFetch) { - $args = array( + $name = $node->name instanceof Identifier ? $node->name->toString() : $node->name; + $args = [ $node->var, - is_string($node->name) ? new String_($node->name) : $node->name, - ); + \is_string($name) ? new String_($name) : $name, + ]; return $this->prepareCall(self::PROPERTY_FETCH, $args); } elseif ($node instanceof Assign && $node->var instanceof PropertyFetch) { $target = $node->var; - $args = array( + $name = $target->name instanceof Identifier ? $target->name->toString() : $target->name; + $args = [ $target->var, - is_string($target->name) ? new String_($target->name) : $target->name, + \is_string($name) ? new String_($name) : $name, $node->expr, - ); + ]; return $this->prepareCall(self::PROPERTY_ASSIGN, $args); } elseif ($node instanceof MethodCall) { + $name = $node->name instanceof Identifier ? $node->name->toString() : $node->name; $args = $node->args; - array_unshift($args, new Arg(is_string($node->name) ? new String_($node->name) : $node->name)); - array_unshift($args, new Arg($node->var)); + \array_unshift($args, new Arg(\is_string($name) ? new String_($name) : $name)); + \array_unshift($args, new Arg($node->var)); // not using prepareCall because the $node->args we started with are already Arg instances return new StaticCall(new FullyQualifiedName(self::SUDO_CLASS), self::METHOD_CALL, $args); } elseif ($node instanceof StaticPropertyFetch) { - $class = $node->class instanceof Name ? (string) $node->class : $node->class; - $args = array( - is_string($class) ? new String_($class) : $class, - is_string($node->name) ? new String_($node->name) : $node->name, - ); + $class = $node->class instanceof Name ? $node->class->toString() : $node->class; + $name = $node->name instanceof Identifier ? $node->name->toString() : $node->name; + $args = [ + \is_string($class) ? new String_($class) : $class, + \is_string($name) ? new String_($name) : $name, + ]; return $this->prepareCall(self::STATIC_PROPERTY_FETCH, $args); } elseif ($node instanceof Assign && $node->var instanceof StaticPropertyFetch) { $target = $node->var; - $class = $target->class instanceof Name ? (string) $target->class : $target->class; - $args = array( - is_string($class) ? new String_($class) : $class, - is_string($target->name) ? new String_($target->name) : $target->name, + $class = $target->class instanceof Name ? $target->class->toString() : $target->class; + $name = $target->name instanceof Identifier ? $target->name->toString() : $target->name; + $args = [ + \is_string($class) ? new String_($class) : $class, + \is_string($name) ? new String_($name) : $name, $node->expr, - ); + ]; return $this->prepareCall(self::STATIC_PROPERTY_ASSIGN, $args); } elseif ($node instanceof StaticCall) { $args = $node->args; - $class = $node->class instanceof Name ? (string) $node->class : $node->class; - array_unshift($args, new Arg(is_string($node->name) ? new String_($node->name) : $node->name)); - array_unshift($args, new Arg(is_string($class) ? new String_($class) : $class)); + $class = $node->class instanceof Name ? $node->class->toString() : $node->class; + $name = $node->name instanceof Identifier ? $node->name->toString() : $node->name; + \array_unshift($args, new Arg(\is_string($name) ? new String_($name) : $name)); + \array_unshift($args, new Arg(\is_string($class) ? new String_($class) : $class)); // not using prepareCall because the $node->args we started with are already Arg instances return new StaticCall(new FullyQualifiedName(self::SUDO_CLASS), self::STATIC_CALL, $args); } elseif ($node instanceof ClassConstFetch) { - $class = $node->class instanceof Name ? (string) $node->class : $node->class; - $args = array( - is_string($class) ? new String_($class) : $class, - is_string($node->name) ? new String_($node->name) : $node->name, - ); + $class = $node->class instanceof Name ? $node->class->toString() : $node->class; + $name = $node->name instanceof Identifier ? $node->name->toString() : $node->name; + $args = [ + \is_string($class) ? new String_($class) : $class, + \is_string($name) ? new String_($name) : $name, + ]; return $this->prepareCall(self::CLASS_CONST_FETCH, $args); } @@ -108,7 +117,7 @@ public function enterNode(Node $node) private function prepareCall($method, $args) { - return new StaticCall(new FullyQualifiedName(self::SUDO_CLASS), $method, array_map(function ($arg) { + return new StaticCall(new FullyQualifiedName(self::SUDO_CLASS), $method, \array_map(function ($arg) { return new Arg($arg); }, $args)); } diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/AutoCompleter.php b/app/vendor/psy/psysh/src/TabCompletion/AutoCompleter.php similarity index 70% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/AutoCompleter.php rename to app/vendor/psy/psysh/src/TabCompletion/AutoCompleter.php index 86cd1663d..0751aa78b 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/AutoCompleter.php +++ b/app/vendor/psy/psysh/src/TabCompletion/AutoCompleter.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -38,7 +38,7 @@ public function addMatcher(AbstractMatcher $matcher) */ public function activate() { - readline_completion_function(array(&$this, 'callback')); + \readline_completion_function([&$this, 'callback']); } /** @@ -50,35 +50,35 @@ public function activate() * * @return array */ - public function processCallback($input, $index, $info = array()) + public function processCallback($input, $index, $info = []) { // Some (Windows?) systems provide incomplete `readline_info`, so let's // try to work around it. $line = $info['line_buffer']; if (isset($info['end'])) { - $line = substr($line, 0, $info['end']); + $line = \substr($line, 0, $info['end']); } if ($line === '' && $input !== '') { $line = $input; } - $tokens = token_get_all('matchers as $matcher) { if ($matcher->hasMatched($tokens)) { - $matches = array_merge($matcher->getMatches($tokens), $matches); + $matches = \array_merge($matcher->getMatches($tokens), $matches); } } - $matches = array_unique($matches); + $matches = \array_unique($matches); - return !empty($matches) ? $matches : array(''); + return !empty($matches) ? $matches : ['']; } /** @@ -86,14 +86,14 @@ public function processCallback($input, $index, $info = array()) * * @see processCallback * - * @param $input - * @param $index + * @param string $input + * @param int $index * * @return array */ public function callback($input, $index) { - return $this->processCallback($input, $index, readline_info()); + return $this->processCallback($input, $index, \readline_info()); } /** @@ -103,10 +103,8 @@ public function __destruct() { // PHP didn't implement the whole readline API when they first switched // to libedit. And they still haven't. - // - // So this is a thing to make PsySH work on 5.3.x: - if (function_exists('readline_callback_handler_remove')) { - readline_callback_handler_remove(); + if (\function_exists('readline_callback_handler_remove')) { + \readline_callback_handler_remove(); } } } diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractContextAwareMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php similarity index 94% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractContextAwareMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php index ad4d74ff2..91816b202 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractContextAwareMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractContextAwareMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -44,7 +44,7 @@ public function setContext(Context $context) /** * Get a Context variable by name. * - * @param $var Variable name + * @param string $var Variable name * * @return mixed */ diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php similarity index 76% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php index 3d7b4214b..c44af36ad 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractDefaultParametersMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,11 +20,11 @@ abstract class AbstractDefaultParametersMatcher extends AbstractContextAwareMatc */ public function getDefaultParameterCompletion(array $reflectionParameters) { - $parametersProcessed = array(); + $parametersProcessed = []; foreach ($reflectionParameters as $parameter) { if (!$parameter->isDefaultValueAvailable()) { - return array(); + return []; } $defaultValue = $this->valueToShortString($parameter->getDefaultValue()); @@ -33,10 +33,10 @@ public function getDefaultParameterCompletion(array $reflectionParameters) } if (empty($parametersProcessed)) { - return array(); + return []; } - return array(implode(', ', $parametersProcessed) . ')'); + return [\implode(', ', $parametersProcessed) . ')']; } /** @@ -50,17 +50,17 @@ public function getDefaultParameterCompletion(array $reflectionParameters) */ private function valueToShortString($value) { - if (!is_array($value)) { - return json_encode($value); + if (!\is_array($value)) { + return \json_encode($value); } - $chunks = array(); - $chunksSequential = array(); + $chunks = []; + $chunksSequential = []; $allSequential = true; foreach ($value as $key => $item) { - $allSequential = $allSequential && is_numeric($key) && $key === count($chunksSequential); + $allSequential = $allSequential && \is_numeric($key) && $key === \count($chunksSequential); $keyString = $this->valueToShortString($key); $itemString = $this->valueToShortString($item); @@ -71,6 +71,6 @@ private function valueToShortString($value) $chunksToImplode = $allSequential ? $chunksSequential : $chunks; - return '[' . implode(', ', $chunksToImplode) . ']'; + return '[' . \implode(', ', $chunksToImplode) . ']'; } } diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractMatcher.php similarity index 82% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractMatcher.php index 016c32190..63b715473 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/AbstractMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/AbstractMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -64,7 +64,7 @@ public function hasMatched(array $tokens) protected function getInput(array $tokens) { $var = ''; - $firstToken = array_pop($tokens); + $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { $var = $firstToken[1]; } @@ -83,9 +83,13 @@ protected function getNamespaceAndClass($tokens) { $class = ''; while (self::hasToken( - array(self::T_NS_SEPARATOR, self::T_STRING), - $token = array_pop($tokens) + [self::T_NS_SEPARATOR, self::T_STRING], + $token = \array_pop($tokens) )) { + if (self::needCompleteClass($token)) { + continue; + } + $class = $token[1] . $class; } @@ -100,7 +104,7 @@ protected function getNamespaceAndClass($tokens) * * @return array The matches resulting from the query */ - abstract public function getMatches(array $tokens, array $info = array()); + abstract public function getMatches(array $tokens, array $info = []); /** * Check whether $word starts with $prefix. @@ -112,7 +116,7 @@ abstract public function getMatches(array $tokens, array $info = array()); */ public static function startsWith($prefix, $word) { - return preg_match(sprintf('#^%s#', $prefix), $word); + return \preg_match(\sprintf('#^%s#', $prefix), $word); } /** @@ -125,13 +129,13 @@ public static function startsWith($prefix, $word) */ public static function hasSyntax($token, $syntax = self::VAR_SYNTAX) { - if (!is_array($token)) { + if (!\is_array($token)) { return false; } - $regexp = sprintf('#%s#', $syntax); + $regexp = \sprintf('#%s#', $syntax); - return (bool) preg_match($regexp, $token[1]); + return (bool) \preg_match($regexp, $token[1]); } /** @@ -144,11 +148,11 @@ public static function hasSyntax($token, $syntax = self::VAR_SYNTAX) */ public static function tokenIs($token, $which) { - if (!is_array($token)) { + if (!\is_array($token)) { return false; } - return token_name($token[0]) === $which; + return \token_name($token[0]) === $which; } /** @@ -160,11 +164,16 @@ public static function tokenIs($token, $which) */ public static function isOperator($token) { - if (!is_string($token)) { + if (!\is_string($token)) { return false; } - return strpos(self::MISC_OPERATORS, $token) !== false; + return \strpos(self::MISC_OPERATORS, $token) !== false; + } + + public static function needCompleteClass($token) + { + return \in_array($token[1], ['doc', 'ls', 'show']); } /** @@ -177,10 +186,10 @@ public static function isOperator($token) */ public static function hasToken(array $coll, $token) { - if (!is_array($token)) { + if (!\is_array($token)) { return false; } - return in_array(token_name($token[0]), $coll); + return \in_array(\token_name($token[0]), $coll); } } diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassAttributesMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php similarity index 70% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassAttributesMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php index 2635b10db..8e976b0a2 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassAttributesMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassAttributesMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,14 +24,14 @@ class ClassAttributesMatcher extends AbstractMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $input = $this->getInput($tokens); - $firstToken = array_pop($tokens); + $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the nekudotayim operator - array_pop($tokens); + \array_pop($tokens); } $class = $this->getNamespaceAndClass($tokens); @@ -39,24 +39,27 @@ public function getMatches(array $tokens, array $info = array()) try { $reflection = new \ReflectionClass($class); } catch (\ReflectionException $re) { - return array(); + return []; } - $vars = array_merge( - array_map( + $vars = \array_merge( + \array_map( function ($var) { return '$' . $var; }, - array_keys($reflection->getStaticProperties()) + \array_keys($reflection->getStaticProperties()) ), - array_keys($reflection->getConstants()) + \array_keys($reflection->getConstants()) ); - return array_map( + return \array_map( function ($name) use ($class) { - return $class . '::' . $name; + $chunks = \explode('\\', $class); + $className = \array_pop($chunks); + + return $className . '::' . $name; }, - array_filter( + \array_filter( $vars, function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var); @@ -70,8 +73,8 @@ function ($var) use ($input) { */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($prevToken, self::T_DOUBLE_COLON) && self::tokenIs($token, self::T_STRING): diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php similarity index 74% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php index 9b97e8b20..3a269a353 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodDefaultParametersMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,11 +13,11 @@ class ClassMethodDefaultParametersMatcher extends AbstractDefaultParametersMatcher { - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { - $openBracket = array_pop($tokens); - $functionName = array_pop($tokens); - $methodOperator = array_pop($tokens); + $openBracket = \array_pop($tokens); + $functionName = \array_pop($tokens); + $methodOperator = \array_pop($tokens); $class = $this->getNamespaceAndClass($tokens); @@ -25,7 +25,7 @@ public function getMatches(array $tokens, array $info = array()) $reflection = new \ReflectionClass($class); } catch (\ReflectionException $e) { // In this case the class apparently does not exist, so we can do nothing - return array(); + return []; } $methods = $reflection->getMethods(\ReflectionMethod::IS_STATIC); @@ -36,24 +36,24 @@ public function getMatches(array $tokens, array $info = array()) } } - return array(); + return []; } public function hasMatched(array $tokens) { - $openBracket = array_pop($tokens); + $openBracket = \array_pop($tokens); if ($openBracket !== '(') { return false; } - $functionName = array_pop($tokens); + $functionName = \array_pop($tokens); if (!self::tokenIs($functionName, self::T_STRING)) { return false; } - $operator = array_pop($tokens); + $operator = \array_pop($tokens); if (!self::tokenIs($operator, self::T_DOUBLE_COLON)) { return false; diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassMethodsMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php similarity index 64% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassMethodsMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php index fa734fde9..d278c18bf 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassMethodsMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassMethodsMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,14 +24,14 @@ class ClassMethodsMatcher extends AbstractMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $input = $this->getInput($tokens); - $firstToken = array_pop($tokens); + $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the nekudotayim operator - array_pop($tokens); + \array_pop($tokens); } $class = $this->getNamespaceAndClass($tokens); @@ -39,19 +39,27 @@ public function getMatches(array $tokens, array $info = array()) try { $reflection = new \ReflectionClass($class); } catch (\ReflectionException $re) { - return array(); + return []; } - $methods = $reflection->getMethods(\ReflectionMethod::IS_STATIC); - $methods = array_map(function (\ReflectionMethod $method) { + if (self::needCompleteClass($tokens[1])) { + $methods = $reflection->getMethods(); + } else { + $methods = $reflection->getMethods(\ReflectionMethod::IS_STATIC); + } + + $methods = \array_map(function (\ReflectionMethod $method) { return $method->getName(); }, $methods); - return array_map( + return \array_map( function ($name) use ($class) { - return $class . '::' . $name; + $chunks = \explode('\\', $class); + $className = \array_pop($chunks); + + return $className . '::' . $name; }, - array_filter($methods, function ($method) use ($input) { + \array_filter($methods, function ($method) use ($input) { return AbstractMatcher::startsWith($input, $method); }) ); @@ -62,8 +70,8 @@ function ($name) use ($class) { */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($prevToken, self::T_DOUBLE_COLON) && self::tokenIs($token, self::T_STRING): diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassNamesMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php similarity index 52% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassNamesMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php index aa6be0c65..844b3d2ae 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ClassNamesMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ClassNamesMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,24 +23,24 @@ class ClassNamesMatcher extends AbstractMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $class = $this->getNamespaceAndClass($tokens); - if (strlen($class) > 0 && $class[0] === '\\') { - $class = substr($class, 1, strlen($class)); + if (\strlen($class) > 0 && $class[0] === '\\') { + $class = \substr($class, 1, \strlen($class)); } - $quotedClass = preg_quote($class); + $quotedClass = \preg_quote($class); - return array_map( + return \array_map( function ($className) use ($class) { // get the number of namespace separators - $nsPos = substr_count($class, '\\'); - $pieces = explode('\\', $className); + $nsPos = \substr_count($class, '\\'); + $pieces = \explode('\\', $className); //$methods = Mirror::get($class); - return implode('\\', array_slice($pieces, $nsPos, count($pieces))); + return \implode('\\', \array_slice($pieces, $nsPos, \count($pieces))); }, - array_filter( - get_declared_classes(), + \array_filter( + \get_declared_classes(), function ($className) use ($quotedClass) { return AbstractMatcher::startsWith($quotedClass, $className); } @@ -53,21 +53,21 @@ function ($className) use ($quotedClass) { */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); - $blacklistedTokens = array( + $blacklistedTokens = [ self::T_INCLUDE, self::T_INCLUDE_ONCE, self::T_REQUIRE, self::T_REQUIRE_ONCE, - ); + ]; switch (true) { - case self::hasToken(array($blacklistedTokens), $token): - case self::hasToken(array($blacklistedTokens), $prevToken): - case is_string($token) && $token === '$': + case self::hasToken([$blacklistedTokens], $token): + case self::hasToken([$blacklistedTokens], $prevToken): + case \is_string($token) && $token === '$': return false; - case self::hasToken(array(self::T_NEW, self::T_OPEN_TAG, self::T_NS_SEPARATOR), $prevToken): - case self::hasToken(array(self::T_NEW, self::T_OPEN_TAG, self::T_NS_SEPARATOR), $token): - case self::hasToken(array(self::T_OPEN_TAG, self::T_VARIABLE), $token): + case self::hasToken([self::T_NEW, self::T_OPEN_TAG, self::T_NS_SEPARATOR, self::T_STRING], $prevToken): + case self::hasToken([self::T_NEW, self::T_OPEN_TAG, self::T_NS_SEPARATOR], $token): + case self::hasToken([self::T_OPEN_TAG, self::T_VARIABLE], $token): case self::isOperator($token): return true; } diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/CommandsMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php similarity index 79% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/CommandsMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php index 330d4dbf6..e3d8423a6 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/CommandsMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/CommandsMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,7 +24,7 @@ class CommandsMatcher extends AbstractMatcher { /** @var string[] */ - protected $commands = array(); + protected $commands = []; /** * CommandsMatcher constructor. @@ -43,10 +43,10 @@ public function __construct(array $commands) */ public function setCommands(array $commands) { - $names = array(); + $names = []; foreach ($commands as $command) { - $names = array_merge(array($command->getName()), $names); - $names = array_merge($command->getAliases(), $names); + $names = \array_merge([$command->getName()], $names); + $names = \array_merge($command->getAliases(), $names); } $this->commands = $names; } @@ -60,7 +60,7 @@ public function setCommands(array $commands) */ protected function isCommand($name) { - return in_array($name, $this->commands); + return \in_array($name, $this->commands); } /** @@ -84,11 +84,11 @@ protected function matchCommand($name) /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $input = $this->getInput($tokens); - return array_filter($this->commands, function ($command) use ($input) { + return \array_filter($this->commands, function ($command) use ($input) { return AbstractMatcher::startsWith($input, $command); }); } @@ -98,8 +98,8 @@ public function getMatches(array $tokens, array $info = array()) */ public function hasMatched(array $tokens) { - /* $openTag */ array_shift($tokens); - $command = array_shift($tokens); + /* $openTag */ \array_shift($tokens); + $command = \array_shift($tokens); switch (true) { case self::tokenIs($command, self::T_STRING) && diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ConstantsMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php similarity index 72% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ConstantsMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php index 885941e5c..71be18f58 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ConstantsMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ConstantsMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,11 +23,11 @@ class ConstantsMatcher extends AbstractMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $const = $this->getInput($tokens); - return array_filter(array_keys(get_defined_constants()), function ($constant) use ($const) { + return \array_filter(\array_keys(\get_defined_constants()), function ($constant) use ($const) { return AbstractMatcher::startsWith($const, $constant); }); } @@ -37,14 +37,14 @@ public function getMatches(array $tokens, array $info = array()) */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($prevToken, self::T_NEW): case self::tokenIs($prevToken, self::T_NS_SEPARATOR): return false; - case self::hasToken(array(self::T_OPEN_TAG, self::T_STRING), $token): + case self::hasToken([self::T_OPEN_TAG, self::T_STRING], $token): case self::isOperator($token): return true; } diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php similarity index 70% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php index 47be34b6a..66d9ea1dc 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionDefaultParametersMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,16 +13,16 @@ class FunctionDefaultParametersMatcher extends AbstractDefaultParametersMatcher { - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { - array_pop($tokens); // open bracket + \array_pop($tokens); // open bracket - $functionName = array_pop($tokens); + $functionName = \array_pop($tokens); try { $reflection = new \ReflectionFunction($functionName[1]); } catch (\ReflectionException $e) { - return array(); + return []; } $parameters = $reflection->getParameters(); @@ -32,19 +32,19 @@ public function getMatches(array $tokens, array $info = array()) public function hasMatched(array $tokens) { - $openBracket = array_pop($tokens); + $openBracket = \array_pop($tokens); if ($openBracket !== '(') { return false; } - $functionName = array_pop($tokens); + $functionName = \array_pop($tokens); if (!self::tokenIs($functionName, self::T_STRING)) { return false; } - if (!function_exists($functionName[1])) { + if (!\function_exists($functionName[1])) { return false; } diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/FunctionsMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php similarity index 66% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/FunctionsMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php index aa37f8835..3aa12a1f0 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/FunctionsMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/FunctionsMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,14 +23,14 @@ class FunctionsMatcher extends AbstractMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $func = $this->getInput($tokens); - $functions = get_defined_functions(); - $allFunctions = array_merge($functions['user'], $functions['internal']); + $functions = \get_defined_functions(); + $allFunctions = \array_merge($functions['user'], $functions['internal']); - return array_filter($allFunctions, function ($function) use ($func) { + return \array_filter($allFunctions, function ($function) use ($func) { return AbstractMatcher::startsWith($func, $function); }); } @@ -40,13 +40,13 @@ public function getMatches(array $tokens, array $info = array()) */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($prevToken, self::T_NEW): return false; - case self::hasToken(array(self::T_OPEN_TAG, self::T_STRING), $token): + case self::hasToken([self::T_OPEN_TAG, self::T_STRING], $token): case self::isOperator($token): return true; } diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/KeywordsMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php similarity index 72% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/KeywordsMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php index 329271cf6..9d0deeeea 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/KeywordsMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/KeywordsMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,14 +20,14 @@ */ class KeywordsMatcher extends AbstractMatcher { - protected $keywords = array( + protected $keywords = [ 'array', 'clone', 'declare', 'die', 'echo', 'empty', 'eval', 'exit', 'include', 'include_once', 'isset', 'list', 'print', 'require', 'require_once', 'unset', - ); + ]; - protected $mandatoryStartKeywords = array( + protected $mandatoryStartKeywords = [ 'die', 'echo', 'print', 'unset', - ); + ]; /** * Get all (completable) PHP keywords. @@ -48,17 +48,17 @@ public function getKeywords() */ public function isKeyword($keyword) { - return in_array($keyword, $this->keywords); + return \in_array($keyword, $this->keywords); } /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $input = $this->getInput($tokens); - return array_filter($this->keywords, function ($keyword) use ($input) { + return \array_filter($this->keywords, function ($keyword) use ($input) { return AbstractMatcher::startsWith($input, $keyword); }); } @@ -68,13 +68,13 @@ public function getMatches(array $tokens, array $info = array()) */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { - case self::hasToken(array(self::T_OPEN_TAG, self::T_VARIABLE), $token): + case self::hasToken([self::T_OPEN_TAG, self::T_VARIABLE], $token): // case is_string($token) && $token === '$': - case self::hasToken(array(self::T_OPEN_TAG, self::T_VARIABLE), $prevToken) && + case self::hasToken([self::T_OPEN_TAG, self::T_VARIABLE], $prevToken) && self::tokenIs($token, self::T_STRING): case self::isOperator($token): return true; diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/MongoClientMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php similarity index 74% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/MongoClientMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php index d08442e70..fb51bf7d2 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/MongoClientMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/MongoClientMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,27 +23,27 @@ class MongoClientMatcher extends AbstractContextAwareMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $input = $this->getInput($tokens); - $firstToken = array_pop($tokens); + $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the object operator - array_pop($tokens); + \array_pop($tokens); } - $objectToken = array_pop($tokens); - $objectName = str_replace('$', '', $objectToken[1]); + $objectToken = \array_pop($tokens); + $objectName = \str_replace('$', '', $objectToken[1]); $object = $this->getVariable($objectName); if (!$object instanceof \MongoClient) { - return array(); + return []; } $list = $object->listDBs(); - return array_filter( - array_map(function ($info) { + return \array_filter( + \array_map(function ($info) { return $info['name']; }, $list['databases']), function ($var) use ($input) { @@ -57,8 +57,8 @@ function ($var) use ($input) { */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($token, self::T_OBJECT_OPERATOR): diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/MongoDatabaseMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php similarity index 75% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/MongoDatabaseMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php index 8494067bf..fb1b9bbfb 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/MongoDatabaseMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/MongoDatabaseMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,24 +23,24 @@ class MongoDatabaseMatcher extends AbstractContextAwareMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $input = $this->getInput($tokens); - $firstToken = array_pop($tokens); + $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the object operator - array_pop($tokens); + \array_pop($tokens); } - $objectToken = array_pop($tokens); - $objectName = str_replace('$', '', $objectToken[1]); + $objectToken = \array_pop($tokens); + $objectName = \str_replace('$', '', $objectToken[1]); $object = $this->getVariable($objectName); if (!$object instanceof \MongoDB) { - return array(); + return []; } - return array_filter( + return \array_filter( $object->getCollectionNames(), function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var); @@ -53,8 +53,8 @@ function ($var) use ($input) { */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($token, self::T_OBJECT_OPERATOR): diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectAttributesMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php similarity index 68% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectAttributesMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php index 668f3685d..ff44f5ac1 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectAttributesMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectAttributesMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,33 +26,33 @@ class ObjectAttributesMatcher extends AbstractContextAwareMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $input = $this->getInput($tokens); - $firstToken = array_pop($tokens); + $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the object operator - array_pop($tokens); + \array_pop($tokens); } - $objectToken = array_pop($tokens); - if (!is_array($objectToken)) { - return array(); + $objectToken = \array_pop($tokens); + if (!\is_array($objectToken)) { + return []; } - $objectName = str_replace('$', '', $objectToken[1]); + $objectName = \str_replace('$', '', $objectToken[1]); try { $object = $this->getVariable($objectName); } catch (InvalidArgumentException $e) { - return array(); + return []; } - if (!is_object($object)) { - return array(); + if (!\is_object($object)) { + return []; } - return array_filter( - array_keys(get_class_vars(get_class($object))), + return \array_filter( + \array_keys(\get_class_vars(\get_class($object))), function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var); } @@ -64,8 +64,8 @@ function ($var) use ($input) { */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($token, self::T_OBJECT_OPERATOR): diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php similarity index 62% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php index 69873a0f5..16fa0189f 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodDefaultParametersMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,26 +13,26 @@ class ObjectMethodDefaultParametersMatcher extends AbstractDefaultParametersMatcher { - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { - $openBracket = array_pop($tokens); - $functionName = array_pop($tokens); - $methodOperator = array_pop($tokens); + $openBracket = \array_pop($tokens); + $functionName = \array_pop($tokens); + $methodOperator = \array_pop($tokens); - $objectToken = array_pop($tokens); - if (!is_array($objectToken)) { - return array(); + $objectToken = \array_pop($tokens); + if (!\is_array($objectToken)) { + return []; } - $objectName = str_replace('$', '', $objectToken[1]); + $objectName = \str_replace('$', '', $objectToken[1]); try { $object = $this->getVariable($objectName); $reflection = new \ReflectionObject($object); - } catch (InvalidArgumentException $e) { - return array(); + } catch (\InvalidArgumentException $e) { + return []; } catch (\ReflectionException $e) { - return array(); + return []; } $methods = $reflection->getMethods(); @@ -43,24 +43,24 @@ public function getMatches(array $tokens, array $info = array()) } } - return array(); + return []; } public function hasMatched(array $tokens) { - $openBracket = array_pop($tokens); + $openBracket = \array_pop($tokens); if ($openBracket !== '(') { return false; } - $functionName = array_pop($tokens); + $functionName = \array_pop($tokens); if (!self::tokenIs($functionName, self::T_STRING)) { return false; } - $operator = array_pop($tokens); + $operator = \array_pop($tokens); if (!self::tokenIs($operator, self::T_OBJECT_OPERATOR)) { return false; diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectMethodsMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php similarity index 71% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectMethodsMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php index dfb1d305f..23c751c7b 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/ObjectMethodsMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/ObjectMethodsMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,33 +26,33 @@ class ObjectMethodsMatcher extends AbstractContextAwareMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { $input = $this->getInput($tokens); - $firstToken = array_pop($tokens); + $firstToken = \array_pop($tokens); if (self::tokenIs($firstToken, self::T_STRING)) { // second token is the object operator - array_pop($tokens); + \array_pop($tokens); } - $objectToken = array_pop($tokens); - if (!is_array($objectToken)) { - return array(); + $objectToken = \array_pop($tokens); + if (!\is_array($objectToken)) { + return []; } - $objectName = str_replace('$', '', $objectToken[1]); + $objectName = \str_replace('$', '', $objectToken[1]); try { $object = $this->getVariable($objectName); } catch (InvalidArgumentException $e) { - return array(); + return []; } - if (!is_object($object)) { - return array(); + if (!\is_object($object)) { + return []; } - return array_filter( - get_class_methods($object), + return \array_filter( + \get_class_methods($object), function ($var) use ($input) { return AbstractMatcher::startsWith($input, $var) && // also check that we do not suggest invoking a super method(__construct, __wakeup, …) @@ -66,8 +66,8 @@ function ($var) use ($input) { */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); - $prevToken = array_pop($tokens); + $token = \array_pop($tokens); + $prevToken = \array_pop($tokens); switch (true) { case self::tokenIs($token, self::T_OBJECT_OPERATOR): diff --git a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/VariablesMatcher.php b/app/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php similarity index 65% rename from app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/VariablesMatcher.php rename to app/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php index ee3b27cd5..a142b7b2e 100644 --- a/app/vendor/psy/psysh/src/Psy/TabCompletion/Matcher/VariablesMatcher.php +++ b/app/vendor/psy/psysh/src/TabCompletion/Matcher/VariablesMatcher.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,11 +23,11 @@ class VariablesMatcher extends AbstractContextAwareMatcher /** * {@inheritdoc} */ - public function getMatches(array $tokens, array $info = array()) + public function getMatches(array $tokens, array $info = []) { - $var = str_replace('$', '', $this->getInput($tokens)); + $var = \str_replace('$', '', $this->getInput($tokens)); - return array_filter(array_keys($this->getVariables()), function ($variable) use ($var) { + return \array_filter(\array_keys($this->getVariables()), function ($variable) use ($var) { return AbstractMatcher::startsWith($var, $variable); }); } @@ -37,11 +37,11 @@ public function getMatches(array $tokens, array $info = array()) */ public function hasMatched(array $tokens) { - $token = array_pop($tokens); + $token = \array_pop($tokens); switch (true) { - case self::hasToken(array(self::T_OPEN_TAG, self::T_VARIABLE), $token): - case is_string($token) && $token === '$': + case self::hasToken([self::T_OPEN_TAG, self::T_VARIABLE], $token): + case \is_string($token) && $token === '$': case self::isOperator($token): return true; } diff --git a/app/vendor/psy/psysh/src/Psy/Util/Docblock.php b/app/vendor/psy/psysh/src/Util/Docblock.php similarity index 75% rename from app/vendor/psy/psysh/src/Psy/Util/Docblock.php rename to app/vendor/psy/psysh/src/Util/Docblock.php index 381c2b208..750210baa 100644 --- a/app/vendor/psy/psysh/src/Psy/Util/Docblock.php +++ b/app/vendor/psy/psysh/src/Util/Docblock.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -30,11 +30,11 @@ class Docblock * * @var array */ - public static $vectors = array( - 'throws' => array('type', 'desc'), - 'param' => array('type', 'var', 'desc'), - 'return' => array('type', 'desc'), - ); + public static $vectors = [ + 'throws' => ['type', 'desc'], + 'param' => ['type', 'var', 'desc'], + 'return' => ['type', 'desc'], + ]; protected $reflector; @@ -85,7 +85,7 @@ public function __construct(\Reflector $reflector) protected function setComment($comment) { $this->desc = ''; - $this->tags = array(); + $this->tags = []; $this->comment = $comment; $this->parseComment($comment); @@ -101,18 +101,18 @@ protected function setComment($comment) protected static function prefixLength(array $lines) { // find only lines with interesting things - $lines = array_filter($lines, function ($line) { - return substr($line, strspn($line, "* \t\n\r\0\x0B")); + $lines = \array_filter($lines, function ($line) { + return \substr($line, \strspn($line, "* \t\n\r\0\x0B")); }); // if we sort the lines, we only have to compare two items - sort($lines); + \sort($lines); - $first = reset($lines); - $last = end($lines); + $first = \reset($lines); + $last = \end($lines); // find the longest common substring - $count = min(strlen($first), strlen($last)); + $count = \min(\strlen($first), \strlen($last)); for ($i = 0; $i < $count; $i++) { if ($first[$i] !== $last[$i]) { return $i; @@ -130,57 +130,57 @@ protected static function prefixLength(array $lines) protected function parseComment($comment) { // Strip the opening and closing tags of the docblock - $comment = substr($comment, 3, -2); + $comment = \substr($comment, 3, -2); // Split into arrays of lines - $comment = array_filter(preg_split('/\r?\n\r?/', $comment)); + $comment = \array_filter(\preg_split('/\r?\n\r?/', $comment)); // Trim asterisks and whitespace from the beginning and whitespace from the end of lines $prefixLength = self::prefixLength($comment); - $comment = array_map(function ($line) use ($prefixLength) { - return rtrim(substr($line, $prefixLength)); + $comment = \array_map(function ($line) use ($prefixLength) { + return \rtrim(\substr($line, $prefixLength)); }, $comment); // Group the lines together by @tags - $blocks = array(); + $blocks = []; $b = -1; foreach ($comment as $line) { if (self::isTagged($line)) { $b++; - $blocks[] = array(); + $blocks[] = []; } elseif ($b === -1) { $b = 0; - $blocks[] = array(); + $blocks[] = []; } $blocks[$b][] = $line; } // Parse the blocks foreach ($blocks as $block => $body) { - $body = trim(implode("\n", $body)); + $body = \trim(\implode("\n", $body)); if ($block === 0 && !self::isTagged($body)) { // This is the description block $this->desc = $body; } else { // This block is tagged - $tag = substr(self::strTag($body), 1); - $body = ltrim(substr($body, strlen($tag) + 2)); + $tag = \substr(self::strTag($body), 1); + $body = \ltrim(\substr($body, \strlen($tag) + 2)); if (isset(self::$vectors[$tag])) { // The tagged block is a vector - $count = count(self::$vectors[$tag]); + $count = \count(self::$vectors[$tag]); if ($body) { - $parts = preg_split('/\s+/', $body, $count); + $parts = \preg_split('/\s+/', $body, $count); } else { - $parts = array(); + $parts = []; } // Default the trailing values - $parts = array_pad($parts, $count, null); + $parts = \array_pad($parts, $count, null); // Store as a mapped array - $this->tags[$tag][] = array_combine(self::$vectors[$tag], $parts); + $this->tags[$tag][] = \array_combine(self::$vectors[$tag], $parts); } else { // The tagged block is only text $this->tags[$tag][] = $body; @@ -198,7 +198,7 @@ protected function parseComment($comment) */ public function hasTag($tag) { - return is_array($this->tags) && array_key_exists($tag, $this->tags); + return \is_array($this->tags) && \array_key_exists($tag, $this->tags); } /** @@ -222,7 +222,7 @@ public function tag($tag) */ public static function isTagged($str) { - return isset($str[1]) && $str[0] === '@' && ctype_alpha($str[1]); + return isset($str[1]) && $str[0] === '@' && !\preg_match('/[^A-Za-z]/', $str[1]); } /** @@ -234,7 +234,7 @@ public static function isTagged($str) */ public static function strTag($str) { - if (preg_match('/^@[a-z0-9_]+/', $str, $matches)) { + if (\preg_match('/^@[a-z0-9_]+/', $str, $matches)) { return $matches[0]; } } diff --git a/app/vendor/psy/psysh/src/Psy/Util/Json.php b/app/vendor/psy/psysh/src/Util/Json.php similarity index 70% rename from app/vendor/psy/psysh/src/Psy/Util/Json.php rename to app/vendor/psy/psysh/src/Util/Json.php index 352e8456b..471f10e7d 100644 --- a/app/vendor/psy/psysh/src/Psy/Util/Json.php +++ b/app/vendor/psy/psysh/src/Util/Json.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,10 +26,8 @@ class Json */ public static function encode($val, $opt = 0) { - if (version_compare(PHP_VERSION, '5.4', '>=')) { - $opt |= JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; - } + $opt |= JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; - return json_encode($val, $opt); + return \json_encode($val, $opt); } } diff --git a/app/vendor/psy/psysh/src/Psy/Util/Mirror.php b/app/vendor/psy/psysh/src/Util/Mirror.php similarity index 76% rename from app/vendor/psy/psysh/src/Psy/Util/Mirror.php rename to app/vendor/psy/psysh/src/Util/Mirror.php index 4a3b061e4..09c0b5b9a 100644 --- a/app/vendor/psy/psysh/src/Psy/Util/Mirror.php +++ b/app/vendor/psy/psysh/src/Util/Mirror.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,7 +12,8 @@ namespace Psy\Util; use Psy\Exception\RuntimeException; -use Psy\Reflection\ReflectionConstant; +use Psy\Reflection\ReflectionClassConstant; +use Psy\Reflection\ReflectionConstant_; /** * A utility class for getting Reflectors. @@ -39,12 +40,16 @@ class Mirror * @param string $member Optional: property, constant or method name (default: null) * @param int $filter (default: CONSTANT | METHOD | PROPERTY | STATIC_PROPERTY) * - * @return Reflector + * @return \Reflector */ public static function get($value, $member = null, $filter = 15) { - if ($member === null && is_string($value) && function_exists($value)) { - return new \ReflectionFunction($value); + if ($member === null && \is_string($value)) { + if (\function_exists($value)) { + return new \ReflectionFunction($value); + } elseif (\defined($value) || ReflectionConstant_::isMagicConstant($value)) { + return new ReflectionConstant_($value); + } } $class = self::getClass($value); @@ -52,7 +57,7 @@ public static function get($value, $member = null, $filter = 15) if ($member === null) { return $class; } elseif ($filter & self::CONSTANT && $class->hasConstant($member)) { - return new ReflectionConstant($class, $member); + return ReflectionClassConstant::create($value, $member); } elseif ($filter & self::METHOD && $class->hasMethod($member)) { return $class->getMethod($member); } elseif ($filter & self::PROPERTY && $class->hasProperty($member)) { @@ -60,10 +65,10 @@ public static function get($value, $member = null, $filter = 15) } elseif ($filter & self::STATIC_PROPERTY && $class->hasProperty($member) && $class->getProperty($member)->isStatic()) { return $class->getProperty($member); } else { - throw new RuntimeException(sprintf( + throw new RuntimeException(\sprintf( 'Unknown member %s on class %s', $member, - is_object($value) ? get_class($value) : $value + \is_object($value) ? \get_class($value) : $value )); } } @@ -79,13 +84,13 @@ public static function get($value, $member = null, $filter = 15) */ private static function getClass($value) { - if (is_object($value)) { + if (\is_object($value)) { return new \ReflectionObject($value); } - if (!is_string($value)) { + if (!\is_string($value)) { throw new \InvalidArgumentException('Mirror expects an object or class'); - } elseif (!class_exists($value) && !interface_exists($value) && !(function_exists('trait_exists') && trait_exists($value))) { + } elseif (!\class_exists($value) && !\interface_exists($value) && !\trait_exists($value)) { throw new \InvalidArgumentException('Unknown class or function: ' . $value); } diff --git a/app/vendor/psy/psysh/src/Psy/Util/Str.php b/app/vendor/psy/psysh/src/Util/Str.php similarity index 86% rename from app/vendor/psy/psysh/src/Psy/Util/Str.php rename to app/vendor/psy/psysh/src/Util/Str.php index e3a34cb78..47d523996 100644 --- a/app/vendor/psy/psysh/src/Psy/Util/Str.php +++ b/app/vendor/psy/psysh/src/Util/Str.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -61,9 +61,9 @@ class Str */ public static function unvis($input) { - $output = preg_replace_callback(self::UNVIS_RX, 'self::unvisReplace', $input); + $output = \preg_replace_callback(self::UNVIS_RX, 'self::unvisReplace', $input); // other escapes & octal are handled by stripcslashes - return stripcslashes($output); + return \stripcslashes($output); } /** @@ -88,27 +88,27 @@ protected static function unvisReplace($match) $chr = $match[3]; // unvis S_META1 $cp = 0200; - $cp |= ord($chr); + $cp |= \ord($chr); - return chr($cp); + return \chr($cp); } // \M^(.) if (isset($match[4]) && $match[4] !== '') { $chr = $match[4]; // unvis S_META | S_CTRL $cp = 0200; - $cp |= ($chr === '?') ? 0177 : ord($chr) & 037; + $cp |= ($chr === '?') ? 0177 : \ord($chr) & 037; - return chr($cp); + return \chr($cp); } // \^(.) if (isset($match[5]) && $match[5] !== '') { $chr = $match[5]; // unvis S_CTRL $cp = 0; - $cp |= ($chr === '?') ? 0177 : ord($chr) & 037; + $cp |= ($chr === '?') ? 0177 : \ord($chr) & 037; - return chr($cp); + return \chr($cp); } } } diff --git a/app/vendor/psy/psysh/src/Psy/VarDumper/Cloner.php b/app/vendor/psy/psysh/src/VarDumper/Cloner.php similarity index 84% rename from app/vendor/psy/psysh/src/Psy/VarDumper/Cloner.php rename to app/vendor/psy/psysh/src/VarDumper/Cloner.php index 4685007b3..eb6c65e19 100644 --- a/app/vendor/psy/psysh/src/Psy/VarDumper/Cloner.php +++ b/app/vendor/psy/psysh/src/VarDumper/Cloner.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -37,6 +37,6 @@ public function cloneVar($var, $filter = 0) */ protected function castResource(Stub $stub, $isNested) { - return Caster::EXCLUDE_VERBOSE & $this->filter ? array() : parent::castResource($stub, $isNested); + return Caster::EXCLUDE_VERBOSE & $this->filter ? [] : parent::castResource($stub, $isNested); } } diff --git a/app/vendor/psy/psysh/src/Psy/VarDumper/Dumper.php b/app/vendor/psy/psysh/src/VarDumper/Dumper.php similarity index 85% rename from app/vendor/psy/psysh/src/Psy/VarDumper/Dumper.php rename to app/vendor/psy/psysh/src/VarDumper/Dumper.php index 42c8832cd..cc13b265a 100644 --- a/app/vendor/psy/psysh/src/Psy/VarDumper/Dumper.php +++ b/app/vendor/psy/psysh/src/VarDumper/Dumper.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -25,7 +25,7 @@ class Dumper extends CliDumper protected static $onlyControlCharsRx = '/^[\x00-\x1F\x7F]+$/'; protected static $controlCharsRx = '/([\x00-\x1F\x7F]+)/'; - protected static $controlCharsMap = array( + protected static $controlCharsMap = [ "\0" => '\0', "\t" => '\t', "\n" => '\n', @@ -33,7 +33,7 @@ class Dumper extends CliDumper "\f" => '\f', "\r" => '\r', "\033" => '\e', - ); + ]; public function __construct(OutputFormatter $formatter, $forceArrayIndexes = false) { @@ -64,23 +64,23 @@ protected function dumpKey(Cursor $cursor) } } - protected function style($style, $value, $attr = array()) + protected function style($style, $value, $attr = []) { if ('ref' === $style) { - $value = strtr($value, '@', '#'); + $value = \strtr($value, '@', '#'); } $styled = ''; $map = self::$controlCharsMap; $cchr = $this->styles['cchr']; - $chunks = preg_split(self::$controlCharsRx, $value, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); + $chunks = \preg_split(self::$controlCharsRx, $value, null, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); foreach ($chunks as $chunk) { - if (preg_match(self::$onlyControlCharsRx, $chunk)) { + if (\preg_match(self::$onlyControlCharsRx, $chunk)) { $chars = ''; $i = 0; do { - $chars .= isset($map[$chunk[$i]]) ? $map[$chunk[$i]] : sprintf('\x%02X', ord($chunk[$i])); + $chars .= isset($map[$chunk[$i]]) ? $map[$chunk[$i]] : \sprintf('\x%02X', \ord($chunk[$i])); } while (isset($chunk[++$i])); $chars = $this->formatter->escape($chars); diff --git a/app/vendor/psy/psysh/src/Psy/VarDumper/Presenter.php b/app/vendor/psy/psysh/src/VarDumper/Presenter.php similarity index 85% rename from app/vendor/psy/psysh/src/Psy/VarDumper/Presenter.php rename to app/vendor/psy/psysh/src/VarDumper/Presenter.php index b48ca9ddd..4f821e0cd 100644 --- a/app/vendor/psy/psysh/src/Psy/VarDumper/Presenter.php +++ b/app/vendor/psy/psysh/src/VarDumper/Presenter.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,14 +24,14 @@ class Presenter private $cloner; private $dumper; - private $exceptionsImportants = array( + private $exceptionsImportants = [ "\0*\0message", "\0*\0code", "\0*\0file", "\0*\0line", "\0Exception\0previous", - ); - private $styles = array( + ]; + private $styles = [ 'num' => 'number', 'const' => 'const', 'str' => 'string', @@ -44,22 +44,22 @@ class Presenter 'meta' => 'comment', 'key' => 'comment', 'index' => 'number', - ); + ]; public function __construct(OutputFormatter $formatter, $forceArrayIndexes = false) { // Work around https://github.com/symfony/symfony/issues/23572 - $oldLocale = setlocale(LC_NUMERIC, 0); - setlocale(LC_NUMERIC, 'C'); + $oldLocale = \setlocale(LC_NUMERIC, 0); + \setlocale(LC_NUMERIC, 'C'); $this->dumper = new Dumper($formatter, $forceArrayIndexes); $this->dumper->setStyles($this->styles); // Now put the locale back - setlocale(LC_NUMERIC, $oldLocale); + \setlocale(LC_NUMERIC, $oldLocale); $this->cloner = new Cloner(); - $this->cloner->addCasters(array('*' => function ($obj, array $a, Stub $stub, $isNested, $filter = 0) { + $this->cloner->addCasters(['*' => function ($obj, array $a, Stub $stub, $isNested, $filter = 0) { if ($filter || $isNested) { if ($obj instanceof \Exception) { $a = Caster::filter($a, Caster::EXCLUDE_NOT_IMPORTANT | Caster::EXCLUDE_EMPTY, $this->exceptionsImportants); @@ -69,7 +69,7 @@ public function __construct(OutputFormatter $formatter, $forceArrayIndexes = fal } return $a; - })); + }]); } /** @@ -116,8 +116,8 @@ public function present($value, $depth = null, $options = 0) } // Work around https://github.com/symfony/symfony/issues/23572 - $oldLocale = setlocale(LC_NUMERIC, 0); - setlocale(LC_NUMERIC, 'C'); + $oldLocale = \setlocale(LC_NUMERIC, 0); + \setlocale(LC_NUMERIC, 'C'); $output = ''; $this->dumper->dump($data, function ($line, $depth) use (&$output) { @@ -125,12 +125,12 @@ public function present($value, $depth = null, $options = 0) if ('' !== $output) { $output .= PHP_EOL; } - $output .= str_repeat(' ', $depth) . $line; + $output .= \str_repeat(' ', $depth) . $line; } }); // Now put the locale back - setlocale(LC_NUMERIC, $oldLocale); + \setlocale(LC_NUMERIC, $oldLocale); return OutputFormatter::escape($output); } diff --git a/app/vendor/psy/psysh/src/Psy/VarDumper/PresenterAware.php b/app/vendor/psy/psysh/src/VarDumper/PresenterAware.php similarity index 93% rename from app/vendor/psy/psysh/src/Psy/VarDumper/PresenterAware.php rename to app/vendor/psy/psysh/src/VarDumper/PresenterAware.php index 8406b8aea..1645c604e 100644 --- a/app/vendor/psy/psysh/src/Psy/VarDumper/PresenterAware.php +++ b/app/vendor/psy/psysh/src/VarDumper/PresenterAware.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/VersionUpdater/Checker.php b/app/vendor/psy/psysh/src/VersionUpdater/Checker.php similarity index 94% rename from app/vendor/psy/psysh/src/Psy/VersionUpdater/Checker.php rename to app/vendor/psy/psysh/src/VersionUpdater/Checker.php index 97763dbdd..c4044870d 100644 --- a/app/vendor/psy/psysh/src/Psy/VersionUpdater/Checker.php +++ b/app/vendor/psy/psysh/src/VersionUpdater/Checker.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/VersionUpdater/GitHubChecker.php b/app/vendor/psy/psysh/src/VersionUpdater/GitHubChecker.php similarity index 80% rename from app/vendor/psy/psysh/src/Psy/VersionUpdater/GitHubChecker.php rename to app/vendor/psy/psysh/src/VersionUpdater/GitHubChecker.php index 5ac6969dd..40cfc2e2f 100644 --- a/app/vendor/psy/psysh/src/Psy/VersionUpdater/GitHubChecker.php +++ b/app/vendor/psy/psysh/src/VersionUpdater/GitHubChecker.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,7 +24,7 @@ class GitHubChecker implements Checker */ public function isLatest() { - return version_compare(Shell::VERSION, $this->getLatest(), '>='); + return \version_compare(Shell::VERSION, $this->getLatest(), '>='); } /** @@ -68,22 +68,22 @@ private function getVersionFromTag() */ public function fetchLatestRelease() { - $context = stream_context_create(array( - 'http' => array( + $context = \stream_context_create([ + 'http' => [ 'user_agent' => 'PsySH/' . Shell::VERSION, 'timeout' => 3, - ), - )); + ], + ]); - set_error_handler(function () { + \set_error_handler(function () { // Just ignore all errors with this. The checker will throw an exception // if it doesn't work :) }); - $result = @file_get_contents(self::URL, false, $context); + $result = @\file_get_contents(self::URL, false, $context); - restore_error_handler(); + \restore_error_handler(); - return json_decode($result); + return \json_decode($result); } } diff --git a/app/vendor/psy/psysh/src/Psy/VersionUpdater/IntervalChecker.php b/app/vendor/psy/psysh/src/VersionUpdater/IntervalChecker.php similarity index 84% rename from app/vendor/psy/psysh/src/Psy/VersionUpdater/IntervalChecker.php rename to app/vendor/psy/psysh/src/VersionUpdater/IntervalChecker.php index 968a28577..7e0da4327 100644 --- a/app/vendor/psy/psysh/src/Psy/VersionUpdater/IntervalChecker.php +++ b/app/vendor/psy/psysh/src/VersionUpdater/IntervalChecker.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,8 +11,6 @@ namespace Psy\VersionUpdater; -use Psy\Shell; - class IntervalChecker extends GitHubChecker { private $cacheFile; @@ -27,7 +25,7 @@ public function __construct($cacheFile, $interval) public function fetchLatestRelease() { // Read the cached file - $cached = json_decode(@file_get_contents($this->cacheFile, false)); + $cached = \json_decode(@\file_get_contents($this->cacheFile, false)); if ($cached && isset($cached->last_check) && isset($cached->release)) { $now = new \DateTime(); $lastCheck = new \DateTime($cached->last_check); @@ -59,11 +57,11 @@ private function getDateInterval() private function updateCache($release) { - $data = array( - 'last_check' => date(DATE_ATOM), + $data = [ + 'last_check' => \date(DATE_ATOM), 'release' => $release, - ); + ]; - file_put_contents($this->cacheFile, json_encode($data)); + \file_put_contents($this->cacheFile, \json_encode($data)); } } diff --git a/app/vendor/psy/psysh/src/Psy/VersionUpdater/NoopChecker.php b/app/vendor/psy/psysh/src/VersionUpdater/NoopChecker.php similarity index 94% rename from app/vendor/psy/psysh/src/Psy/VersionUpdater/NoopChecker.php rename to app/vendor/psy/psysh/src/VersionUpdater/NoopChecker.php index 5edbe00db..c5c9bcb4e 100644 --- a/app/vendor/psy/psysh/src/Psy/VersionUpdater/NoopChecker.php +++ b/app/vendor/psy/psysh/src/VersionUpdater/NoopChecker.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/src/Psy/functions.php b/app/vendor/psy/psysh/src/functions.php similarity index 72% rename from app/vendor/psy/psysh/src/Psy/functions.php rename to app/vendor/psy/psysh/src/functions.php index dc77e121b..4e875bbab 100644 --- a/app/vendor/psy/psysh/src/Psy/functions.php +++ b/app/vendor/psy/psysh/src/functions.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -18,7 +18,7 @@ use Symfony\Component\Console\Input\InputOption; use XdgBaseDir\Xdg; -if (!function_exists('Psy\sh')) { +if (!\function_exists('Psy\sh')) { /** * Command to return the eval-able code to startup PsySH. * @@ -28,11 +28,11 @@ */ function sh() { - return 'extract(\Psy\debug(get_defined_vars(), isset($this) ? $this : null));'; + return 'extract(\Psy\debug(get_defined_vars(), isset($this) ? $this : @get_called_class()));'; } } -if (!function_exists('Psy\debug')) { +if (!\function_exists('Psy\debug')) { /** * Invoke a Psy Shell from the current context. * @@ -50,9 +50,9 @@ function sh() * var_dump($item); // will be whatever you set $item to in Psy Shell * } * - * Optionally, supply an object as the `$boundObject` parameter. This - * determines the value `$this` will have in the shell, and sets up class - * scope so that private and protected members are accessible: + * Optionally, supply an object as the `$bindTo` parameter. This determines + * the value `$this` will have in the shell, and sets up class scope so that + * private and protected members are accessible: * * class Foo { * function bar() { @@ -60,14 +60,22 @@ function sh() * } * } * - * This only really works in PHP 5.4+ and HHVM 3.5+, so upgrade already. + * For the static equivalent, pass a class name as the `$bindTo` parameter. + * This makes `self` work in the shell, and sets up static scope so that + * private and protected static members are accessible: * - * @param array $vars Scope variables from the calling context (default: array()) - * @param object $boundObject Bound object ($this) value for the shell + * class Foo { + * static function bar() { + * \Psy\debug(get_defined_vars(), get_called_class()); + * } + * } + * + * @param array $vars Scope variables from the calling context (default: array()) + * @param object|string $bindTo Bound object ($this) or class (self) value for the shell * * @return array Scope variables from the debugger session */ - function debug(array $vars = array(), $boundObject = null) + function debug(array $vars = [], $bindTo = null) { echo PHP_EOL; @@ -81,8 +89,10 @@ function debug(array $vars = array(), $boundObject = null) $sh->addInput('whereami -n2', true); } - if ($boundObject !== null) { - $sh->setBoundObject($boundObject); + if (\is_string($bindTo)) { + $sh->setBoundClass($bindTo); + } elseif ($bindTo !== null) { + $sh->setBoundObject($bindTo); } $sh->run(); @@ -91,7 +101,7 @@ function debug(array $vars = array(), $boundObject = null) } } -if (!function_exists('Psy\info')) { +if (!\function_exists('Psy\info')) { /** * Get a bunch of debugging info about the current PsySH environment and * configuration. @@ -113,12 +123,12 @@ function info(Configuration $config = null) } $xdg = new Xdg(); - $home = rtrim(str_replace('\\', '/', $xdg->getHomeDir()), '/'); - $homePattern = '#^' . preg_quote($home, '#') . '/#'; + $home = \rtrim(\str_replace('\\', '/', $xdg->getHomeDir()), '/'); + $homePattern = '#^' . \preg_quote($home, '#') . '/#'; $prettyPath = function ($path) use ($homePattern) { - if (is_string($path)) { - return preg_replace($homePattern, '~/', $path); + if (\is_string($path)) { + return \preg_replace($homePattern, '~/', $path); } else { return $path; } @@ -126,21 +136,22 @@ function info(Configuration $config = null) $config = $lastConfig ?: new Configuration(); - $core = array( + $core = [ 'PsySH version' => Shell::VERSION, 'PHP version' => PHP_VERSION, + 'OS' => PHP_OS, 'default includes' => $config->getDefaultIncludes(), 'require semicolons' => $config->requireSemicolons(), 'error logging level' => $config->errorLoggingLevel(), - 'config file' => array( + 'config file' => [ 'default config file' => $prettyPath($config->getConfigFile()), 'local config file' => $prettyPath($config->getLocalConfigFile()), - 'PSYSH_CONFIG env' => $prettyPath(getenv('PSYSH_CONFIG')), - ), + 'PSYSH_CONFIG env' => $prettyPath(\getenv('PSYSH_CONFIG')), + ], // 'config dir' => $config->getConfigDir(), // 'data dir' => $config->getDataDir(), // 'runtime dir' => $config->getRuntimeDir(), - ); + ]; // Use an explicit, fresh update check here, rather than relying on whatever is in $config. $checker = new GitHubChecker(); @@ -152,21 +163,21 @@ function info(Configuration $config = null) } catch (\Exception $e) { } - $updates = array( + $updates = [ 'update available' => $updateAvailable, 'latest release version' => $latest, 'update check interval' => $config->getUpdateCheck(), 'update cache file' => $prettyPath($config->getUpdateCheckCacheFile()), - ); + ]; if ($config->hasReadline()) { - $info = readline_info(); + $info = \readline_info(); - $readline = array( + $readline = [ 'readline available' => true, 'readline enabled' => $config->useReadline(), - 'readline service' => get_class($config->getReadline()), - ); + 'readline service' => \get_class($config->getReadline()), + ]; if (isset($info['library_version'])) { $readline['readline library'] = $info['library_version']; @@ -176,31 +187,31 @@ function info(Configuration $config = null) $readline['readline name'] = $info['readline_name']; } } else { - $readline = array( + $readline = [ 'readline available' => false, - ); + ]; } - $pcntl = array( - 'pcntl available' => function_exists('pcntl_signal'), - 'posix available' => function_exists('posix_getpid'), - ); + $pcntl = [ + 'pcntl available' => \function_exists('pcntl_signal'), + 'posix available' => \function_exists('posix_getpid'), + ]; - $disabledFuncs = array_map('trim', explode(',', ini_get('disable_functions'))); - if (in_array('pcntl_signal', $disabledFuncs) || in_array('pcntl_fork', $disabledFuncs)) { + $disabledFuncs = \array_map('trim', \explode(',', \ini_get('disable_functions'))); + if (\in_array('pcntl_signal', $disabledFuncs) || \in_array('pcntl_fork', $disabledFuncs)) { $pcntl['pcntl disabled'] = true; } - $history = array( + $history = [ 'history file' => $prettyPath($config->getHistoryFile()), 'history size' => $config->getHistorySize(), 'erase duplicates' => $config->getEraseDuplicates(), - ); + ]; - $docs = array( + $docs = [ 'manual db file' => $prettyPath($config->getManualDbFile()), 'sqlite available' => true, - ); + ]; try { if ($db = $config->getManualDb()) { @@ -215,7 +226,7 @@ function info(Configuration $config = null) $val = $d->format(\DateTime::RFC2822); break; } - $key = 'db ' . str_replace('_', ' ', $key); + $key = 'db ' . \str_replace('_', ' ', $key); $docs[$key] = $val; } } else { @@ -230,21 +241,31 @@ function info(Configuration $config = null) } } - $autocomplete = array( - 'tab completion enabled' => $config->getTabCompletion(), - 'custom matchers' => array_map('get_class', $config->getTabCompletionMatchers()), + $autocomplete = [ + 'tab completion enabled' => $config->useTabCompletion(), + 'custom matchers' => \array_map('get_class', $config->getTabCompletionMatchers()), 'bracketed paste' => $config->useBracketedPaste(), - ); + ]; + + // Shenanigans, but totally justified. + if ($shell = Sudo::fetchProperty($config, 'shell')) { + $core['loop listeners'] = \array_map('get_class', Sudo::fetchProperty($shell, 'loopListeners')); + $core['commands'] = \array_map('get_class', $shell->all()); + + $autocomplete['custom matchers'] = \array_map('get_class', Sudo::fetchProperty($shell, 'matchers')); + } + + // @todo Show Presenter / custom casters. - return array_merge($core, compact('updates', 'pcntl', 'readline', 'history', 'docs', 'autocomplete')); + return \array_merge($core, \compact('updates', 'pcntl', 'readline', 'history', 'docs', 'autocomplete')); } } -if (!function_exists('Psy\bin')) { +if (!\function_exists('Psy\bin')) { /** * `psysh` command line executable. * - * @return Closure + * @return \Closure */ function bin() { @@ -253,7 +274,7 @@ function bin() $input = new ArgvInput(); try { - $input->bind(new InputDefinition(array( + $input->bind(new InputDefinition([ new InputOption('help', 'h', InputOption::VALUE_NONE), new InputOption('config', 'c', InputOption::VALUE_REQUIRED), new InputOption('version', 'v', InputOption::VALUE_NONE), @@ -262,12 +283,12 @@ function bin() new InputOption('no-color', null, InputOption::VALUE_NONE), new InputArgument('include', InputArgument::IS_ARRAY), - ))); + ])); } catch (\RuntimeException $e) { $usageException = $e; } - $config = array(); + $config = []; // Handle --config if ($configFile = $input->getOption('config')) { @@ -276,7 +297,7 @@ function bin() // Handle --color and --no-color if ($input->getOption('color') && $input->getOption('no-color')) { - $usageException = new \RuntimeException('Using both "--color" and "--no-color" options is invalid.'); + $usageException = new \RuntimeException('Using both "--color" and "--no-color" options is invalid'); } elseif ($input->getOption('color')) { $config['colorMode'] = Configuration::COLOR_MODE_FORCED; } elseif ($input->getOption('no-color')) { @@ -292,7 +313,7 @@ function bin() } $version = $shell->getVersion(); - $name = basename(reset($_SERVER['argv'])); + $name = \basename(\reset($_SERVER['argv'])); echo <<run(); - } catch (Exception $e) { + } catch (\Exception $e) { echo $e->getMessage() . PHP_EOL; // @todo this triggers the "exited unexpectedly" logic in the diff --git a/app/vendor/psy/psysh/test/ClassWithSecrets.php b/app/vendor/psy/psysh/test/ClassWithSecrets.php new file mode 100644 index 000000000..adf27e3fd --- /dev/null +++ b/app/vendor/psy/psysh/test/ClassWithSecrets.php @@ -0,0 +1,37 @@ +setPass(new AbstractClassPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $this->parseAndTraverse($code); + } + + public function invalidStatements() + { + return [ + ['class A { abstract function a(); }'], + ['abstract class B { abstract function b() {} }'], + ['abstract class B { abstract function b() { echo "yep"; } }'], + ]; + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + return [ + ['abstract class C { function c() {} }'], + ['abstract class D { abstract function d(); }'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AssignThisVariablePassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/AssignThisVariablePassTest.php similarity index 52% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AssignThisVariablePassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/AssignThisVariablePassTest.php index 1a975f4bc..1ff15c571 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AssignThisVariablePassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/AssignThisVariablePassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,16 +11,13 @@ namespace Psy\Test\CodeCleaner; -use PhpParser\NodeTraverser; use Psy\CodeCleaner\AssignThisVariablePass; class AssignThisVariablePassTest extends CodeCleanerTestCase { public function setUp() { - $this->pass = new AssignThisVariablePass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); + $this->setPass(new AssignThisVariablePass()); } /** @@ -29,16 +26,15 @@ public function setUp() */ public function testProcessStatementFails($code) { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); + $this->parseAndTraverse($code); } public function invalidStatements() { - return array( - array('$this = 3'), - array('strtolower($this = "this")'), - ); + return [ + ['$this = 3'], + ['strtolower($this = "this")'], + ]; } /** @@ -46,20 +42,17 @@ public function invalidStatements() */ public function testProcessStatementPasses($code) { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? + $this->parseAndTraverse($code); $this->assertTrue(true); } public function validStatements() { - return array( - array('$this'), - array('$a = $this'), - array('$a = "this"; $$a = 3'), - array('$$this = "b"'), - ); + return [ + ['$this'], + ['$a = $this'], + ['$a = "this"; $$a = 3'], + ['$$this = "b"'], + ]; } } diff --git a/app/vendor/psy/psysh/test/CodeCleaner/CallTimePassByReferencePassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/CallTimePassByReferencePassTest.php new file mode 100644 index 000000000..cd321b5de --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/CallTimePassByReferencePassTest.php @@ -0,0 +1,59 @@ +setPass(new CallTimePassByReferencePass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $this->parseAndTraverse($code); + } + + public function invalidStatements() + { + return [ + ['f(&$arg)'], + ['$object->method($first, &$arg)'], + ['$closure($first, &$arg, $last)'], + ['A::b(&$arg)'], + ]; + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + return [ + ['array(&$var)'], + ['$a = &$b'], + ['f(array(&$b))'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/CodeCleaner/CalledClassPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/CalledClassPassTest.php new file mode 100644 index 000000000..c80f257ac --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/CalledClassPassTest.php @@ -0,0 +1,90 @@ +setPass(new CalledClassPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\ErrorException + */ + public function testProcessStatementFails($code) + { + $this->parseAndTraverse($code); + } + + public function invalidStatements() + { + return [ + ['get_class()'], + ['get_class(null)'], + ['get_called_class()'], + ['get_called_class(null)'], + ['function foo() { return get_class(); }'], + ['function foo() { return get_class(null); }'], + ['function foo() { return get_called_class(); }'], + ['function foo() { return get_called_class(null); }'], + ]; + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + return [ + ['get_class($foo)'], + ['get_class(bar())'], + ['get_called_class($foo)'], + ['get_called_class(bar())'], + ['function foo($bar) { return get_class($bar); }'], + ['function foo($bar) { return get_called_class($bar); }'], + ['class Foo { function bar() { return get_class(); } }'], + ['class Foo { function bar() { return get_class(null); } }'], + ['class Foo { function bar() { return get_called_class(); } }'], + ['class Foo { function bar() { return get_called_class(null); } }'], + ['$foo = function () {}; $foo()'], + ]; + } + + /** + * @dataProvider validTraitStatements + */ + public function testProcessTraitStatementPasses($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validTraitStatements() + { + return [ + ['trait Foo { function bar() { return get_class(); } }'], + ['trait Foo { function bar() { return get_class(null); } }'], + ['trait Foo { function bar() { return get_called_class(); } }'], + ['trait Foo { function bar() { return get_called_class(null); } }'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/CodeCleaner/CodeCleanerTestCase.php b/app/vendor/psy/psysh/test/CodeCleaner/CodeCleanerTestCase.php new file mode 100644 index 000000000..6962c1141 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/CodeCleanerTestCase.php @@ -0,0 +1,41 @@ +pass = null; + parent::tearDown(); + } + + protected function setPass(CodeCleanerPass $pass) + { + $this->pass = $pass; + if (!isset($this->traverser)) { + $this->traverser = new NodeTraverser(); + } + $this->traverser->addVisitor($this->pass); + } + + protected function parseAndTraverse($code, $prefix = 'traverse($this->parse($code, $prefix)); + } +} diff --git a/app/vendor/psy/psysh/test/CodeCleaner/ExitPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/ExitPassTest.php new file mode 100644 index 000000000..b22766c76 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/ExitPassTest.php @@ -0,0 +1,59 @@ +setPass(new ExitPass()); + } + + /** + * @dataProvider dataProviderExitStatement + */ + public function testExitStatement($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + /** + * Data provider for testExitStatement. + * + * @return array + */ + public function dataProviderExitStatement() + { + return [ + ['exit;', "{$this->expectedExceptionString};"], + ['exit();', "{$this->expectedExceptionString};"], + ['die;', "{$this->expectedExceptionString};"], + ['exit(die(die));', "{$this->expectedExceptionString};"], + ['if (true) { exit; }', "if (true) {\n {$this->expectedExceptionString};\n}"], + ['if (false) { exit; }', "if (false) {\n {$this->expectedExceptionString};\n}"], + ['1 and exit();', "1 and {$this->expectedExceptionString};"], + ['foo() or die', "foo() or {$this->expectedExceptionString};"], + ['exit and 1;', "{$this->expectedExceptionString} and 1;"], + ['if (exit) { echo $wat; }', "if ({$this->expectedExceptionString}) {\n echo \$wat;\n}"], + ['exit or die;', "{$this->expectedExceptionString} or {$this->expectedExceptionString};"], + ['switch (die) { }', "switch ({$this->expectedExceptionString}) {\n}"], + ['for ($i = 1; $i < 10; die) {}', "for (\$i = 1; \$i < 10; {$this->expectedExceptionString}) {\n}"], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FinalClassPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/FinalClassPassTest.php similarity index 51% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FinalClassPassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/FinalClassPassTest.php index 02b892d42..1808d11fb 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FinalClassPassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/FinalClassPassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,16 +11,13 @@ namespace Psy\Test\CodeCleaner; -use PhpParser\NodeTraverser; use Psy\CodeCleaner\FinalClassPass; class FinalClassPassTest extends CodeCleanerTestCase { public function setUp() { - $this->pass = new FinalClassPass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); + $this->setPass(new FinalClassPass()); } /** @@ -29,24 +26,23 @@ public function setUp() */ public function testProcessStatementFails($code) { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); + $this->parseAndTraverse($code); } public function invalidStatements() { - $stmts = array( - array('final class A {} class B extends A {}'), - array('class A {} final class B extends A {} class C extends B {}'), + $data = [ + ['final class A {} class B extends A {}'], + ['class A {} final class B extends A {} class C extends B {}'], // array('namespace A { final class B {} } namespace C { class D extends \\A\\B {} }'), - ); + ]; - if (!defined('HHVM_VERSION')) { + if (!\defined('HHVM_VERSION')) { // For some reason Closure isn't final in HHVM? - $stmts[] = array('class A extends \\Closure {}'); + $data[] = ['class A extends \\Closure {}']; } - return $stmts; + return $data; } /** @@ -54,19 +50,16 @@ public function invalidStatements() */ public function testProcessStatementPasses($code) { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? + $this->parseAndTraverse($code); $this->assertTrue(true); } public function validStatements() { - return array( - array('class A extends \\stdClass {}'), - array('final class A extends \\stdClass {}'), - array('class A {} class B extends A {}'), - ); + return [ + ['class A extends \\stdClass {}'], + ['final class A extends \\stdClass {}'], + ['class A {} class B extends A {}'], + ]; } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithCallStatic.php b/app/vendor/psy/psysh/test/CodeCleaner/Fixtures/ClassWithCallStatic.php similarity index 91% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithCallStatic.php rename to app/vendor/psy/psysh/test/CodeCleaner/Fixtures/ClassWithCallStatic.php index f576ebf66..0c674c0ed 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithCallStatic.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/Fixtures/ClassWithCallStatic.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithStatic.php b/app/vendor/psy/psysh/test/CodeCleaner/Fixtures/ClassWithStatic.php similarity index 91% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithStatic.php rename to app/vendor/psy/psysh/test/CodeCleaner/Fixtures/ClassWithStatic.php index 9686392ac..64c64c76c 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/Fixtures/ClassWithStatic.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/Fixtures/ClassWithStatic.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/test/CodeCleaner/Fixtures/TraitWithStatic.php b/app/vendor/psy/psysh/test/CodeCleaner/Fixtures/TraitWithStatic.php new file mode 100644 index 000000000..132dc061c --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/Fixtures/TraitWithStatic.php @@ -0,0 +1,20 @@ +pass = new FunctionContextPass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); + $this->setPass(new FunctionContextPass()); } /** @@ -28,19 +25,16 @@ public function setUp() */ public function testProcessStatementPasses($code) { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? + $this->parseAndTraverse($code); $this->assertTrue(true); } public function validStatements() { - return array( - array('function foo() { yield; }'), - array('if (function(){ yield; })'), - ); + return [ + ['function foo() { yield; }'], + ['if (function(){ yield; })'], + ]; } /** @@ -49,19 +43,14 @@ public function validStatements() */ public function testInvalidYield($code) { - if (version_compare(PHP_VERSION, '5.4', '<')) { - $this->markTestSkipped(); - } - - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); + $this->parseAndTraverse($code); } public function invalidYieldStatements() { - return array( - array('yield'), - array('if (yield)'), - ); + return [ + ['yield'], + ['if (yield)'], + ]; } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FunctionReturnInWriteContextPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/FunctionReturnInWriteContextPassTest.php similarity index 67% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FunctionReturnInWriteContextPassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/FunctionReturnInWriteContextPassTest.php index 040349514..85f6a04c0 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/FunctionReturnInWriteContextPassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/FunctionReturnInWriteContextPassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,6 @@ namespace Psy\Test\CodeCleaner; -use PhpParser\NodeTraverser; use Psy\CodeCleaner\FunctionReturnInWriteContextPass; use Psy\Exception\FatalErrorException; @@ -19,9 +18,7 @@ class FunctionReturnInWriteContextPassTest extends CodeCleanerTestCase { public function setUp() { - $this->pass = new FunctionReturnInWriteContextPass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); + $this->setPass(new FunctionReturnInWriteContextPass()); } /** @@ -31,20 +28,19 @@ public function setUp() */ public function testProcessStatementFails($code) { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); + $this->parseAndTraverse($code); } public function invalidStatements() { - return array( - array('f(&g())'), - array('array(& $object->method())'), - array('$a->method(& $closure())'), - array('array(& A::b())'), - array('f() = 5'), - array('unset(h())'), - ); + return [ + ['f(&g())'], + ['array(& $object->method())'], + ['$a->method(& $closure())'], + ['array(& A::b())'], + ['f() = 5'], + ['unset(h())'], + ]; } public function testIsset() @@ -53,7 +49,7 @@ public function testIsset() $this->traverser->traverse($this->parse('isset(strtolower("A"))')); $this->fail(); } catch (FatalErrorException $e) { - if (version_compare(PHP_VERSION, '5.5', '>=')) { + if (\version_compare(PHP_VERSION, '5.5', '>=')) { $this->assertContains( 'Cannot use isset() on the result of a function call (you can use "null !== func()" instead)', $e->getMessage() @@ -70,10 +66,26 @@ public function testIsset() */ public function testEmpty() { - if (version_compare(PHP_VERSION, '5.5', '>=')) { + if (\version_compare(PHP_VERSION, '5.5', '>=')) { $this->markTestSkipped(); } $this->traverser->traverse($this->parse('empty(strtolower("A"))')); } + + /** + * @dataProvider validStatements + */ + public function testValidStatements($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + return [ + ['isset($foo)'], + ]; + } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ImplicitReturnPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/ImplicitReturnPassTest.php similarity index 64% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ImplicitReturnPassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/ImplicitReturnPassTest.php index b9912c390..1c28b4a85 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ImplicitReturnPassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/ImplicitReturnPassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -30,11 +30,19 @@ public function testProcess($from, $to) public function implicitReturns() { - $values = array( - array('4', 'return 4;'), - array('foo()', 'return foo();'), - array('return 1', 'return 1;'), - ); + $data = [ + ['4', 'return 4;'], + ['foo()', 'return foo();'], + ['return 1', 'return 1;'], + ['', 'return new \Psy\CodeCleaner\NoReturnValue();'], + ]; + + $from = 'echo "foo";'; + $to = <<<'EOS' +echo "foo"; +return new \Psy\CodeCleaner\NoReturnValue(); +EOS; + $data[] = [$from, $to]; $from = 'if (true) { 1; } elseif (true) { 2; } else { 3; }'; $to = <<<'EOS' @@ -47,7 +55,7 @@ public function implicitReturns() } return new \Psy\CodeCleaner\NoReturnValue(); EOS; - $values[] = array($from, $to); + $data[] = [$from, $to]; $from = 'class A {}'; $to = <<<'EOS' @@ -56,7 +64,7 @@ class A } return new \Psy\CodeCleaner\NoReturnValue(); EOS; - $values[] = array($from, $to); + $data[] = [$from, $to]; $from = <<<'EOS' switch (false) { @@ -83,14 +91,22 @@ class A } return new \Psy\CodeCleaner\NoReturnValue(); EOS; - $values[] = array($from, $to); + $data[] = [$from, $to]; + + $from = <<<'EOS' +namespace Foo { + 1 + 1; +} +EOS; + $to = <<<'EOS' +namespace Foo; + +return 1 + 1; +EOS; + $data[] = [$from, $to]; - if (version_compare(PHP_VERSION, '5.4', '<')) { - $values[] = array('exit()', 'die;'); - } else { - $values[] = array('exit()', 'exit;'); - } + $data[] = ['exit()', 'exit;']; - return $values; + return $data; } } diff --git a/app/vendor/psy/psysh/test/CodeCleaner/InstanceOfPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/InstanceOfPassTest.php new file mode 100644 index 000000000..b8c63313e --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/InstanceOfPassTest.php @@ -0,0 +1,72 @@ +setPass(new InstanceOfPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessInvalidStatement($code) + { + $this->parseAndTraverse($code); + } + + public function invalidStatements() + { + return [ + ['null instanceof stdClass'], + ['true instanceof stdClass'], + ['9 instanceof stdClass'], + ['1.0 instanceof stdClass'], + ['"foo" instanceof stdClass'], + ['__DIR__ instanceof stdClass'], + ['PHP_SAPI instanceof stdClass'], + ['1+1 instanceof stdClass'], + ['true && false instanceof stdClass'], + ['"a"."b" instanceof stdClass'], + ['!5 instanceof stdClass'], + ]; + } + + /** + * @dataProvider validStatements + */ + public function testProcessValidStatement($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + $data = [ + ['$a instanceof stdClass'], + ['strtolower("foo") instanceof stdClass'], + ['array(1) instanceof stdClass'], + ['(string) "foo" instanceof stdClass'], + ['(1+1) instanceof stdClass'], + ['"foo ${foo} $bar" instanceof stdClass'], + ['DateTime::ISO8601 instanceof stdClass'], + ]; + + return $data; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LeavePsyshAlonePassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/LeavePsyshAlonePassTest.php similarity index 59% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LeavePsyshAlonePassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/LeavePsyshAlonePassTest.php index 10fce3e26..9df633e89 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LeavePsyshAlonePassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/LeavePsyshAlonePassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,8 +24,6 @@ public function testPassesInlineHtmlThroughJustFine() { $inline = $this->parse('not php at all!', ''); $this->traverse($inline); - - // @todo a better thing to assert here? $this->assertTrue(true); } @@ -34,23 +32,20 @@ public function testPassesInlineHtmlThroughJustFine() */ public function testProcessStatementPasses($code) { - $stmts = $this->parse($code); - $this->traverse($stmts); - - // @todo a better thing to assert here? + $this->parseAndTraverse($code); $this->assertTrue(true); } public function validStatements() { - return array( - array('array_merge()'), - array('__psysh__()'), - array('$this'), - array('$psysh'), - array('$__psysh'), - array('$banana'), - ); + return [ + ['array_merge()'], + ['__psysh__()'], + ['$this'], + ['$psysh'], + ['$__psysh'], + ['$banana'], + ]; } /** @@ -59,17 +54,16 @@ public function validStatements() */ public function testProcessStatementFails($code) { - $stmts = $this->parse($code); - $this->traverse($stmts); + $this->parseAndTraverse($code); } public function invalidStatements() { - return array( - array('$__psysh__'), - array('var_dump($__psysh__)'), - array('$__psysh__ = "your mom"'), - array('$__psysh__->fakeFunctionCall()'), - ); + return [ + ['$__psysh__'], + ['var_dump($__psysh__)'], + ['$__psysh__ = "your mom"'], + ['$__psysh__->fakeFunctionCall()'], + ]; } } diff --git a/app/vendor/psy/psysh/test/CodeCleaner/LegacyEmptyPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/LegacyEmptyPassTest.php new file mode 100644 index 000000000..5c4c7b059 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/LegacyEmptyPassTest.php @@ -0,0 +1,76 @@ +setPass(new LegacyEmptyPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\ParseErrorException + */ + public function testProcessInvalidStatement($code) + { + $this->parseAndTraverse($code); + } + + public function invalidStatements() + { + if (\version_compare(PHP_VERSION, '5.5', '>=')) { + return [ + ['empty()'], + ]; + } + + return [ + ['empty()'], + ['empty(null)'], + ['empty(PHP_EOL)'], + ['empty("wat")'], + ['empty(1.1)'], + ['empty(Foo::$bar)'], + ]; + } + + /** + * @dataProvider validStatements + */ + public function testProcessValidStatement($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + if (\version_compare(PHP_VERSION, '5.5', '<')) { + return [ + ['empty($foo)'], + ]; + } + + return [ + ['empty($foo)'], + ['empty(null)'], + ['empty(PHP_EOL)'], + ['empty("wat")'], + ['empty(1.1)'], + ['empty(Foo::$bar)'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/CodeCleaner/ListPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/ListPassTest.php new file mode 100644 index 000000000..7481f7c39 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/ListPassTest.php @@ -0,0 +1,109 @@ +setPass(new ListPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\ParseErrorException + */ + public function testProcessInvalidStatement($code, $expectedMessage) + { + if (\method_exists($this, 'setExpectedException')) { + $this->setExpectedException('Psy\Exception\ParseErrorException', $expectedMessage); + } else { + $this->expectExceptionMessage($expectedMessage); + } + + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + } + + public function invalidStatements() + { + // Not typo. It is ambiguous whether "Syntax" or "syntax". + $errorShortListAssign = "yntax error, unexpected '='"; + $errorEmptyList = 'Cannot use empty list'; + $errorAssocListAssign = 'Syntax error, unexpected T_CONSTANT_ENCAPSED_STRING, expecting \',\' or \')\''; + $errorNonVariableAssign = 'Assignments can only happen to writable values'; + $errorPhpParserSyntax = 'PHP Parse error: Syntax error, unexpected'; + + $invalidExpr = [ + ['list() = array()', $errorEmptyList], + ['list("a") = array(1)', $errorPhpParserSyntax], + ]; + + if (\version_compare(PHP_VERSION, '7.1', '<')) { + return \array_merge($invalidExpr, [ + ['list("a" => _) = array("a" => 1)', $errorPhpParserSyntax], + ['[] = []', $errorShortListAssign], + ['[$a] = [1]', $errorShortListAssign], + ['list("a" => $a) = array("a" => 1)', $errorAssocListAssign], + ['[$a[0], $a[1]] = [1, 2]', $errorShortListAssign], + ['[$a->b, $a->c] = [1, 2]', $errorShortListAssign], + ]); + } + + return \array_merge($invalidExpr, [ + ['list("a" => _) = array("a" => 1)', $errorPhpParserSyntax], + ['["a"] = [1]', $errorNonVariableAssign], + ['[] = []', $errorEmptyList], + ['[,] = [1,2]', $errorEmptyList], + ['[,,] = [1,2,3]', $errorEmptyList], + ]); + } + + /** + * @dataProvider validStatements + */ + public function testProcessValidStatement($code) + { + $stmts = $this->parse($code); + $this->traverser->traverse($stmts); + $this->assertTrue(true); + } + + public function validStatements() + { + $validExpr = [ + ['list($a) = array(1)'], + ['list($x, $y) = array(1, 2)'], + ]; + + if (\version_compare(PHP_VERSION, '7.1', '>=')) { + return \array_merge($validExpr, [ + ['[$a] = array(1)'], + ['list($b) = [2]'], + ['[$x, $y] = array(1, 2)'], + ['[$a] = [1]'], + ['[$x, $y] = [1, 2]'], + ['["_" => $v] = ["_" => 1]'], + ['[$a,] = [1,2,3]'], + ['[,$b] = [1,2,3]'], + ['[$a,,$c] = [1,2,3]'], + ['[$a,,,] = [1,2,3]'], + ['[$a[0], $a[1]] = [1, 2]'], + ['[$a->b, $a->c] = [1, 2]'], + ]); + } + + return $validExpr; + } +} diff --git a/app/vendor/psy/psysh/test/CodeCleaner/LoopContextPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/LoopContextPassTest.php new file mode 100644 index 000000000..3b3630683 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/LoopContextPassTest.php @@ -0,0 +1,108 @@ +setPass(new LoopContextPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $this->parseAndTraverse($code); + } + + public function invalidStatements() + { + return [ + ['continue'], + ['break'], + ['if (true) { continue; }'], + ['if (true) { break; }'], + ['if (false) { continue; }'], + ['if (false) { break; }'], + ['function foo() { break; }'], + ['function foo() { continue; }'], + + // actually enforce break/continue depth argument + ['do { break 2; } while (true)'], + ['do { continue 2; } while (true)'], + ['for ($a; $b; $c) { break 2; }'], + ['for ($a; $b; $c) { continue 2; }'], + ['foreach ($a as $b) { break 2; }'], + ['foreach ($a as $b) { continue 2; }'], + ['switch (true) { default: break 2; }'], + ['switch (true) { default: continue 2; }'], + ['while (true) { break 2; }'], + ['while (true) { continue 2; }'], + + // In PHP 5.4+, only positive literal integers are allowed + ['while (true) { break $n; }'], + ['while (true) { continue $n; }'], + ['while (true) { break N; }'], + ['while (true) { continue N; }'], + ['while (true) { break 0; }'], + ['while (true) { continue 0; }'], + ['while (true) { break -1; }'], + ['while (true) { continue -1; }'], + ['while (true) { break 1.0; }'], + ['while (true) { continue 1.0; }'], + ['while (true) { break 2.0; }'], + ['while (true) { continue 2.0; }'], + + // and once with nested loops, just for good measure + ['while (true) { while (true) { break 3; } }'], + ['while (true) { while (true) { continue 3; } }'], + ]; + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + return [ + ['do { break; } while (true)'], + ['do { continue; } while (true)'], + ['for ($a; $b; $c) { break; }'], + ['for ($a; $b; $c) { continue; }'], + ['foreach ($a as $b) { break; }'], + ['foreach ($a as $b) { continue; }'], + ['switch (true) { default: break; }'], + ['switch (true) { default: continue; }'], + ['while (true) { break; }'], + ['while (true) { continue; }'], + + // `break 1` is redundant, but not invalid + ['while (true) { break 1; }'], + ['while (true) { continue 1; }'], + + // and once with nested loops just for good measure + ['while (true) { while (true) { break 2; } }'], + ['while (true) { while (true) { continue 2; } }'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/MagicConstantsPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/MagicConstantsPassTest.php similarity index 75% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/MagicConstantsPassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/MagicConstantsPassTest.php index 1f78e12d2..321ac6ff3 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/MagicConstantsPassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/MagicConstantsPassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -30,10 +30,10 @@ public function testProcess($from, $to) public function magicConstants() { - return array( - array('__DIR__;', 'getcwd();'), - array('__FILE__;', "'';"), - array('___FILE___;', '___FILE___;'), - ); + return [ + ['__DIR__;', 'getcwd();'], + ['__FILE__;', "'';"], + ['___FILE___;', '___FILE___;'], + ]; } } diff --git a/app/vendor/psy/psysh/test/CodeCleaner/NamespacePassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/NamespacePassTest.php new file mode 100644 index 000000000..e8f013961 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/NamespacePassTest.php @@ -0,0 +1,59 @@ +cleaner = new CodeCleaner(); + $this->setPass(new NamespacePass($this->cleaner)); + } + + public function testProcess() + { + $this->parseAndTraverse(''); + $this->assertNull($this->cleaner->getNamespace()); + + $this->parseAndTraverse('array_merge()'); + $this->assertNull($this->cleaner->getNamespace()); + + // A non-block namespace statement should set the current namespace. + $this->parseAndTraverse('namespace Alpha'); + $this->assertSame(['Alpha'], $this->cleaner->getNamespace()); + + // A new non-block namespace statement should override the current namespace. + $this->parseAndTraverse('namespace Beta; class B {}'); + $this->assertSame(['Beta'], $this->cleaner->getNamespace()); + + // A new block namespace clears out the current namespace... + $this->parseAndTraverse('namespace Gamma { array_merge(); }'); + + if (\defined('PhpParser\\Node\\Stmt\\Namespace_::KIND_SEMICOLON')) { + $this->assertNull($this->cleaner->getNamespace()); + } else { + // But not for PHP-Parser < v3.1.2 :( + $this->assertSame(['Gamma'], $this->cleaner->getNamespace()); + } + + $this->parseAndTraverse('namespace Delta'); + + // A null namespace clears out the current namespace. + $this->parseAndTraverse('namespace { array_merge(); }'); + $this->assertNull($this->cleaner->getNamespace()); + } +} diff --git a/app/vendor/psy/psysh/test/CodeCleaner/NoReturnValueTest.php b/app/vendor/psy/psysh/test/CodeCleaner/NoReturnValueTest.php new file mode 100644 index 000000000..11e9d013f --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/NoReturnValueTest.php @@ -0,0 +1,32 @@ +assertSame( + $this->prettyPrint($this->parse('new \\Psy\CodeCleaner\\NoReturnValue()')), + $this->prettyPrint([$stmt]) + ); + } +} diff --git a/app/vendor/psy/psysh/test/CodeCleaner/PassableByReferencePassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/PassableByReferencePassTest.php new file mode 100644 index 000000000..a73ad471f --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/PassableByReferencePassTest.php @@ -0,0 +1,104 @@ +setPass(new PassableByReferencePass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessStatementFails($code) + { + $this->parseAndTraverse($code); + } + + public function invalidStatements() + { + return [ + ['array_pop(array())'], + ['array_pop(array($foo))'], + ['array_shift(array())'], + ]; + } + + /** + * @dataProvider validStatements + */ + public function testProcessStatementPasses($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + return [ + ['array_pop(json_decode("[]"))'], + ['array_pop($foo)'], + ['array_pop($foo->bar)'], + ['array_pop($foo::baz)'], + ['array_pop(Foo::qux)'], + ]; + } + + /** + * @dataProvider validArrayMultisort + */ + public function testArrayMultisort($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validArrayMultisort() + { + return [ + ['array_multisort($a)'], + ['array_multisort($a, $b)'], + ['array_multisort($a, SORT_NATURAL, $b)'], + ['array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, $b)'], + ['array_multisort($a, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE, $b)'], + ['array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, SORT_ASC, $b)'], + ['array_multisort($a, $b, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE)'], + ['array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, $b, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE)'], + ['array_multisort($a, 1, $b)'], + ['array_multisort($a, 1 + 2, $b)'], + ['array_multisort($a, getMultisortFlags(), $b)'], + ]; + } + + /** + * @dataProvider invalidArrayMultisort + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testInvalidArrayMultisort($code) + { + $this->parseAndTraverse($code); + } + + public function invalidArrayMultisort() + { + return [ + ['array_multisort(1)'], + ['array_multisort(array(1, 2, 3))'], + ['array_multisort($a, SORT_NATURAL, SORT_ASC, SORT_NATURAL, $b)'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/CodeCleaner/RequirePassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/RequirePassTest.php new file mode 100644 index 000000000..6640e639b --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/RequirePassTest.php @@ -0,0 +1,93 @@ +setPass(new RequirePass()); + } + + /** + * @dataProvider exitStatements + */ + public function testExitStatement($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function exitStatements() + { + $resolve = '\\Psy\\CodeCleaner\\RequirePass::resolve'; + + return [ + // The basics + ['require "a"', "require $resolve(\"a\", 1);"], + ['require "b.php"', "require $resolve(\"b.php\", 1);"], + ['require_once "c"', "require_once $resolve(\"c\", 1);"], + ['require_once "d.php"', "require_once $resolve(\"d.php\", 1);"], + + // Ensure that line numbers work correctly + ["null;\nrequire \"e.php\"", "null;\nrequire $resolve(\"e.php\", 2);"], + ["null;\nrequire_once \"f.php\"", "null;\nrequire_once $resolve(\"f.php\", 2);"], + + // Things with expressions + ['require $foo', "require $resolve(\$foo, 1);"], + ['require_once $foo', "require_once $resolve(\$foo, 1);"], + ['require ($bar = "g.php")', "require $resolve(\$bar = \"g.php\", 1);"], + ['require_once ($bar = "h.php")', "require_once $resolve(\$bar = \"h.php\", 1);"], + ['$bar = require ($baz = "i.php")', "\$bar = (require $resolve(\$baz = \"i.php\", 1));"], + ['$bar = require_once ($baz = "j.php")', "\$bar = (require_once $resolve(\$baz = \"j.php\", 1));"], + ]; + } + + /** + * @expectedException \Psy\Exception\FatalErrorException + * @expectedExceptionMessage Failed opening required 'not a file name' in eval()'d code on line 2 + */ + public function testResolve() + { + RequirePass::resolve('not a file name', 2); + } + + /** + * @dataProvider emptyWarnings + * + * @expectedException \Psy\Exception\ErrorException + * @expectedExceptionMessage Filename cannot be empty on line 1 + */ + public function testResolveEmptyWarnings($file) + { + if (!E_WARNING & \error_reporting()) { + $this->markTestSkipped(); + } + + RequirePass::resolve($file, 1); + } + + public function emptyWarnings() + { + return [ + [null], + [false], + [''], + ]; + } + + public function testResolveWorks() + { + $this->assertEquals(__FILE__, RequirePass::resolve(__FILE__, 3)); + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StrictTypesPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/StrictTypesPassTest.php similarity index 70% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StrictTypesPassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/StrictTypesPassTest.php index 8458fc01b..54186190d 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StrictTypesPassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/StrictTypesPassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -17,7 +17,7 @@ class StrictTypesPassTest extends CodeCleanerTestCase { public function setUp() { - if (version_compare(PHP_VERSION, '7.0', '<')) { + if (\version_compare(PHP_VERSION, '7.0', '<')) { $this->markTestSkipped(); } @@ -36,18 +36,17 @@ public function testProcess() * @dataProvider invalidDeclarations * @expectedException \Psy\Exception\FatalErrorException */ - public function testInvalidDeclarations($declaration) + public function testInvalidDeclarations($code) { - $stmts = $this->parse($declaration); - $this->traverser->traverse($stmts); + $this->parseAndTraverse($code); } public function invalidDeclarations() { - return array( - array('declare(strict_types=-1)'), - array('declare(strict_types=2)'), - array('declare(strict_types="foo")'), - ); + return [ + ['declare(strict_types=-1)'], + ['declare(strict_types=2)'], + ['declare(strict_types="foo")'], + ]; } } diff --git a/app/vendor/psy/psysh/test/CodeCleaner/UseStatementPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/UseStatementPassTest.php new file mode 100644 index 000000000..4d5ac3420 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/UseStatementPassTest.php @@ -0,0 +1,102 @@ +setPass(new UseStatementPass()); + } + + /** + * @dataProvider useStatements + */ + public function testProcess($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function useStatements() + { + return [ + [ + "use StdClass as NotSoStd;\n\$std = new NotSoStd();", + '$std = new \\StdClass();', + ], + [ + "namespace Foo;\n\nuse StdClass as S;\n\$std = new S();", + "namespace Foo;\n\n\$std = new \\StdClass();", + ], + [ + "namespace Foo;\n\nuse \\StdClass as S;\n\$std = new S();", + "namespace Foo;\n\n\$std = new \\StdClass();", + ], + [ + "use Foo\\Bar as fb;\n\$baz = new fb\\Baz();", + '$baz = new \\Foo\\Bar\\Baz();', + ], + [ + "use Foo\\Bar;\n\$baz = new Bar\\Baz();", + '$baz = new \\Foo\\Bar\\Baz();', + ], + [ + "namespace Foo;\nuse Bar;\n\$baz = new Bar\\Baz();", + "namespace Foo;\n\n\$baz = new \\Bar\\Baz();", + ], + [ + "namespace Foo;\n\nuse \\StdClass as S;\n\$std = new S();\nnamespace Foo;\n\n\$std = new S();", + "namespace Foo;\n\n\$std = new \\StdClass();\nnamespace Foo;\n\n\$std = new \\StdClass();", + ], + [ + "namespace Foo;\n\nuse \\StdClass as S;\n\$std = new S();\nnamespace Bar;\n\n\$std = new S();", + "namespace Foo;\n\n\$std = new \\StdClass();\nnamespace Bar;\n\n\$std = new S();", + ], + [ + "use Foo\\Bar as fb, Qux as Q;\n\$baz = new fb\\Baz();\n\$qux = new Q();", + "\$baz = new \\Foo\\Bar\\Baz();\n\$qux = new \\Qux();", + ], + ]; + } + + /** + * @dataProvider groupUseStatements + */ + public function testGroupUseProcess($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function groupUseStatements() + { + if (\version_compare(PHP_VERSION, '7.0', '<')) { + $this->markTestSkipped(); + } + + return [ + [ + "use Foo\\{Bar, Baz, Qux as Q};\n\$bar = new Bar();\n\$baz = new Baz();\n\$qux = new Q();", + "\$bar = new \\Foo\\Bar();\n\$baz = new \\Foo\\Baz();\n\$qux = new \\Foo\\Qux();", + ], + [ + "use X\\{Foo, Bar as B};\n\$foo = new Foo();\n\$baz = new B\\Baz();", + "\$foo = new \\X\\Foo();\n\$baz = new \\X\\Bar\\Baz();", + ], + [ + "use X\\{Foo, Bar as B};\n\$foo = new Foo();\n\$bar = new Bar();\n\$baz = new B\\Baz();", + "\$foo = new \\X\\Foo();\n\$bar = new Bar();\n\$baz = new \\X\\Bar\\Baz();", + ], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidClassNamePassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/ValidClassNamePassTest.php similarity index 63% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidClassNamePassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/ValidClassNamePassTest.php index 6be71072c..2d9ed60b5 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidClassNamePassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/ValidClassNamePassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,7 +12,6 @@ namespace Psy\Test\CodeCleaner; use Psy\CodeCleaner\ValidClassNamePass; -use Psy\Exception\Exception; class ValidClassNamePassTest extends CodeCleanerTestCase { @@ -23,103 +22,95 @@ public function setUp() /** * @dataProvider getInvalid + * @expectedException \Psy\Exception\FatalErrorException */ - public function testProcessInvalid($code, $php54 = false) + public function testProcessInvalid($code) { - try { - $stmts = $this->parse($code); - $this->traverse($stmts); - $this->fail(); - } catch (Exception $e) { - if ($php54 && version_compare(PHP_VERSION, '5.4', '<')) { - $this->assertInstanceOf('Psy\Exception\ParseErrorException', $e); - } else { - $this->assertInstanceOf('Psy\Exception\FatalErrorException', $e); - } - } + $this->parseAndTraverse($code); } public function getInvalid() { // class declarations - return array( + return [ // core class - array('class stdClass {}'), + ['class stdClass {}'], // capitalization - array('class stdClass {}'), + ['class stdClass {}'], // collisions with interfaces and traits - array('interface stdClass {}'), - array('trait stdClass {}', true), + ['interface stdClass {}'], + ['trait stdClass {}'], // collisions inside the same code snippet - array(' + [' class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} - ', true), - array(' + '], + [' trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} - ', true), - array(' + '], + [' trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} - ', true), - array(' + '], + [' interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} trait Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} - ', true), - array(' + '], + [' interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} interface Psy_Test_CodeCleaner_ValidClassNamePass_Alpha {} - '), + '], // namespaced collisions - array(' + [' namespace Psy\\Test\\CodeCleaner { class ValidClassNamePassTest {} } - '), - array(' + '], + [' namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { class Beta {} } namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { class Beta {} } - '), + '], // extends and implements - array('class ValidClassNamePassTest extends NotAClass {}'), - array('class ValidClassNamePassTest extends ArrayAccess {}'), - array('class ValidClassNamePassTest implements stdClass {}'), - array('class ValidClassNamePassTest implements ArrayAccess, stdClass {}'), - array('interface ValidClassNamePassTest extends stdClass {}'), - array('interface ValidClassNamePassTest extends ArrayAccess, stdClass {}'), + ['class ValidClassNamePassTest extends NotAClass {}'], + ['class ValidClassNamePassTest extends ArrayAccess {}'], + ['class ValidClassNamePassTest implements stdClass {}'], + ['class ValidClassNamePassTest implements ArrayAccess, stdClass {}'], + ['interface ValidClassNamePassTest extends stdClass {}'], + ['interface ValidClassNamePassTest extends ArrayAccess, stdClass {}'], // class instantiations - array('new Psy_Test_CodeCleaner_ValidClassNamePass_Gamma();'), - array(' + ['new Psy_Test_CodeCleaner_ValidClassNamePass_Gamma();'], + [' namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { new Psy_Test_CodeCleaner_ValidClassNamePass_Delta(); } - '), + '], // class constant fetch - array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::FOO'), + ['Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::FOO'], // static call - array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::foo()'), - array('Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::$foo()'), - ); + ['Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::foo()'], + ['Psy\\Test\\CodeCleaner\\ValidClassNamePass\\NotAClass::$foo()'], + ['Psy\\Test\\CodeCleaner\\ValidClassNamePassTest::notAMethod()'], + ]; } /** @@ -127,151 +118,149 @@ class Beta {} */ public function testProcessValid($code) { - $stmts = $this->parse($code); - $this->traverse($stmts); - - // @todo a better thing to assert here? + $this->parseAndTraverse($code); $this->assertTrue(true); } public function getValid() { - $valid = array( + $valid = [ // class declarations - array('class Psy_Test_CodeCleaner_ValidClassNamePass_Epsilon {}'), - array('namespace Psy\Test\CodeCleaner\ValidClassNamePass; class Zeta {}'), - array(' + ['class Psy_Test_CodeCleaner_ValidClassNamePass_Epsilon {}'], + ['namespace Psy\Test\CodeCleaner\ValidClassNamePass; class Zeta {}'], + [' namespace { class Psy_Test_CodeCleaner_ValidClassNamePass_Eta {}; } namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { class Psy_Test_CodeCleaner_ValidClassNamePass_Eta {} } - '), - array('namespace Psy\Test\CodeCleaner\ValidClassNamePass { class stdClass {} }'), + '], + ['namespace Psy\Test\CodeCleaner\ValidClassNamePass { class stdClass {} }'], // class instantiations - array('new stdClass();'), - array('new stdClass();'), - array(' + ['new stdClass();'], + ['new stdClass();'], + [' namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { class Theta {} } namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { new Theta(); } - '), - array(' + '], + [' namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { class Iota {} new Iota(); } - '), - array(' + '], + [' namespace Psy\\Test\\CodeCleaner\\ValidClassNamePass { class Kappa {} } namespace { new \\Psy\\Test\\CodeCleaner\\ValidClassNamePass\\Kappa(); } - '), + '], // Class constant fetch (ValidConstantPassTest validates the actual constant) - array('class A {} A::FOO'), - array('$a = new DateTime; $a::ATOM'), - array('interface A { const B = 1; } A::B'), + ['class A {} A::FOO'], + ['$a = new DateTime; $a::ATOM'], + ['interface A { const B = 1; } A::B'], // static call - array('DateTime::createFromFormat()'), - array('DateTime::$someMethod()'), - array('Psy\Test\CodeCleaner\Fixtures\ClassWithStatic::doStuff()'), - array('Psy\Test\CodeCleaner\Fixtures\ClassWithCallStatic::doStuff()'), + ['DateTime::createFromFormat()'], + ['DateTime::$someMethod()'], + ['Psy\Test\CodeCleaner\Fixtures\ClassWithStatic::doStuff()'], + ['Psy\Test\CodeCleaner\Fixtures\ClassWithCallStatic::doStuff()'], + ['Psy\Test\CodeCleaner\Fixtures\TraitWithStatic::doStuff()'], // Allow `self` and `static` as class names. - array(' + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function getInstance() { return new self(); } } - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function getInstance() { return new SELF(); } } - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function getInstance() { return new self; } } - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function getInstance() { return new static(); } } - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function getInstance() { return new Static(); } } - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function getInstance() { return new static; } } - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function foo() { return parent::bar(); } } - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function foo() { return self::bar(); } } - '), - array(' + '], + [' class Psy_Test_CodeCleaner_ValidClassNamePass_ClassWithStatic { public static function foo() { return static::bar(); } } - '), + '], - array('class A { static function b() { return new A; } }'), - array(' + ['class A { static function b() { return new A; } }'], + [' class A { const B = 123; function c() { return A::B; } } - '), - array('class A {} class B { function c() { return new A; } }'), + '], + ['class A {} class B { function c() { return new A; } }'], // recursion - array('class A { function a() { A::a(); } }'), + ['class A { function a() { A::a(); } }'], // conditionally defined classes - array(' + [' class A {} if (false) { class A {} } - '), - array(' + '], + [' class A {} if (true) { class A {} @@ -280,9 +269,9 @@ class A {} } else { class A {} } - '), + '], // ewww - array(' + [' class A {} if (true): class A {} @@ -291,16 +280,16 @@ class A {} else: class A {} endif; - '), - array(' + '], + [' class A {} while (false) { class A {} } - '), - array(' + '], + [' class A {} do { class A {} } while (false); - '), - array(' + '], + [' class A {} switch (1) { case 0: @@ -313,22 +302,22 @@ class A {} class A {} break; } - '), - ); + '], + ]; // Ugh. There's gotta be a better way to test for this. - if (class_exists('PhpParser\ParserFactory')) { + if (\class_exists('PhpParser\ParserFactory')) { // PHP 7.0 anonymous classes, only supported by PHP Parser v2.x - $valid[] = array('$obj = new class() {}'); + $valid[] = ['$obj = new class() {}']; } - if (version_compare(PHP_VERSION, '5.5', '>=')) { - $valid[] = array('interface A {} A::class'); - $valid[] = array('interface A {} A::CLASS'); - $valid[] = array('class A {} A::class'); - $valid[] = array('class A {} A::CLASS'); - $valid[] = array('A::class'); - $valid[] = array('A::CLASS'); + if (\version_compare(PHP_VERSION, '5.5', '>=')) { + $valid[] = ['interface A {} A::class']; + $valid[] = ['interface A {} A::CLASS']; + $valid[] = ['class A {} A::class']; + $valid[] = ['class A {} A::CLASS']; + $valid[] = ['A::class']; + $valid[] = ['A::CLASS']; } return $valid; diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidConstantPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/ValidConstantPassTest.php similarity index 58% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidConstantPassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/ValidConstantPassTest.php index c06139c73..a6c52e041 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidConstantPassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/ValidConstantPassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,19 +26,18 @@ public function setUp() */ public function testProcessInvalidConstantReferences($code) { - $stmts = $this->parse($code); - $this->traverse($stmts); + $this->parseAndTraverse($code); } public function getInvalidReferences() { - return array( - array('Foo\BAR'), + return [ + ['Foo\BAR'], // class constant fetch - array('Psy\Test\CodeCleaner\ValidConstantPassTest::FOO'), - array('DateTime::BACON'), - ); + ['Psy\Test\CodeCleaner\ValidConstantPassTest::FOO'], + ['DateTime::BACON'], + ]; } /** @@ -46,24 +45,21 @@ public function getInvalidReferences() */ public function testProcessValidConstantReferences($code) { - $stmts = $this->parse($code); - $this->traverse($stmts); - - // @todo a better thing to assert here? + $this->parseAndTraverse($code); $this->assertTrue(true); } public function getValidReferences() { - return array( - array('PHP_EOL'), + return [ + ['PHP_EOL'], // class constant fetch - array('NotAClass::FOO'), - array('DateTime::ATOM'), - array('$a = new DateTime; $a::ATOM'), - array('DateTime::class'), - array('$a = new DateTime; $a::class'), - ); + ['NotAClass::FOO'], + ['DateTime::ATOM'], + ['$a = new DateTime; $a::ATOM'], + ['DateTime::class'], + ['$a = new DateTime; $a::class'], + ]; } } diff --git a/app/vendor/psy/psysh/test/CodeCleaner/ValidConstructorPassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/ValidConstructorPassTest.php new file mode 100644 index 000000000..4f7e40c44 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleaner/ValidConstructorPassTest.php @@ -0,0 +1,93 @@ +setPass(new ValidConstructorPass()); + } + + /** + * @dataProvider invalidStatements + * @expectedException \Psy\Exception\FatalErrorException + */ + public function testProcessInvalidStatement($code) + { + $this->parseAndTraverse($code); + } + + /** + * @dataProvider invalidParserStatements + * @expectedException \Psy\Exception\ParseErrorException + */ + public function testProcessInvalidStatementCatchedByParser($code) + { + $this->parseAndTraverse($code); + } + + public function invalidStatements() + { + $data = [ + ['class A { public static function A() {}}'], + ['class A { public static function a() {}}'], + ['class A { private static function A() {}}'], + ['class A { private static function a() {}}'], + ]; + + if (\version_compare(PHP_VERSION, '7.0', '>=')) { + $data[] = ['class A { public function A(): ?array {}}']; + $data[] = ['class A { public function a(): ?array {}}']; + } + + return $data; + } + + public function invalidParserStatements() + { + return [ + ['class A { public static function __construct() {}}'], + ['class A { private static function __construct() {}}'], + ['class A { private static function __construct() {} public function A() {}}'], + ['namespace B; class A { private static function __construct() {}}'], + ]; + } + + /** + * @dataProvider validStatements + */ + public function testProcessValidStatement($code) + { + $this->parseAndTraverse($code); + $this->assertTrue(true); + } + + public function validStatements() + { + $data = [ + ['class A { public static function A() {} public function __construct() {}}'], + ['class A { private function __construct() {} public static function A() {}}'], + ['namespace B; class A { private static function A() {}}'], + ]; + + if (\version_compare(PHP_VERSION, '7.0', '>=')) { + $data[] = ['class A { public static function A() {} public function __construct() {}}']; + $data[] = ['class A { private function __construct() {} public static function A(): ?array {}}']; + $data[] = ['namespace B; class A { private static function A(): ?array {}}']; + } + + return $data; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidFunctionNamePassTest.php b/app/vendor/psy/psysh/test/CodeCleaner/ValidFunctionNamePassTest.php similarity index 76% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidFunctionNamePassTest.php rename to app/vendor/psy/psysh/test/CodeCleaner/ValidFunctionNamePassTest.php index 79b51cf24..70a17315d 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ValidFunctionNamePassTest.php +++ b/app/vendor/psy/psysh/test/CodeCleaner/ValidFunctionNamePassTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -26,40 +26,39 @@ public function setUp() */ public function testProcessInvalidFunctionCallsAndDeclarations($code) { - $stmts = $this->parse($code); - $this->traverse($stmts); + $this->parseAndTraverse($code); } public function getInvalidFunctions() { - return array( + return [ // function declarations - array('function array_merge() {}'), - array('function Array_Merge() {}'), - array(' + ['function array_merge() {}'], + ['function Array_Merge() {}'], + [' function psy_test_codecleaner_validfunctionnamepass_alpha() {} function psy_test_codecleaner_validfunctionnamepass_alpha() {} - '), - array(' + '], + [' namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { function beta() {} } namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { function beta() {} } - '), + '], // function calls - array('psy_test_codecleaner_validfunctionnamepass_gamma()'), - array(' + ['psy_test_codecleaner_validfunctionnamepass_gamma()'], + [' namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { delta(); } - '), + '], // recursion - array('function a() { a(); } function a() {}'), - ); + ['function a() { a(); } function a() {}'], + ]; } /** @@ -67,76 +66,73 @@ function beta() {} */ public function testProcessValidFunctionCallsAndDeclarations($code) { - $stmts = $this->parse($code); - $this->traverse($stmts); - - // @todo a better thing to assert here? + $this->parseAndTraverse($code); $this->assertTrue(true); } public function getValidFunctions() { - return array( - array('function psy_test_codecleaner_validfunctionnamepass_epsilon() {}'), - array(' + return [ + ['function psy_test_codecleaner_validfunctionnamepass_epsilon() {}'], + [' namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { function zeta() {} } - '), - array(' + '], + [' namespace { function psy_test_codecleaner_validfunctionnamepass_eta() {} } namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { function psy_test_codecleaner_validfunctionnamepass_eta() {} } - '), - array(' + '], + [' namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { function psy_test_codecleaner_validfunctionnamepass_eta() {} } namespace { function psy_test_codecleaner_validfunctionnamepass_eta() {} } - '), - array(' + '], + [' namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { function array_merge() {} } - '), + '], // function calls - array('array_merge();'), - array(' + ['array_merge();'], + [' namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { function theta() {} } namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { theta(); } - '), + '], // closures - array('$test = function(){};$test()'), - array(' + ['$test = function(){};$test()'], + [' namespace Psy\\Test\\CodeCleaner\\ValidFunctionNamePass { function theta() {} } namespace { Psy\\Test\\CodeCleaner\\ValidFunctionNamePass\\theta(); } - '), + '], // recursion - array('function a() { a(); }'), + ['function a() { a(); }'], // conditionally defined functions - array(' + [' function a() {} if (false) { function a() {} } - '), - array(' + '], + [' function a() {} if (true) { function a() {} @@ -145,9 +141,9 @@ function a() {} } else { function a() {} } - '), + '], // ewww - array(' + [' function a() {} if (true): function a() {} @@ -156,16 +152,16 @@ function a() {} else: function a() {} endif; - '), - array(' + '], + [' function a() {} while (false) { function a() {} } - '), - array(' + '], + [' function a() {} do { function a() {} } while (false); - '), - array(' + '], + [' function a() {} switch (1) { case 0: @@ -178,7 +174,7 @@ function a() {} function a() {} break; } - '), - ); + '], + ]; } } diff --git a/app/vendor/psy/psysh/test/CodeCleanerTest.php b/app/vendor/psy/psysh/test/CodeCleanerTest.php new file mode 100644 index 000000000..2195a4ff8 --- /dev/null +++ b/app/vendor/psy/psysh/test/CodeCleanerTest.php @@ -0,0 +1,131 @@ +assertSame($expected, $cc->clean($lines, $requireSemicolons)); + } + + public function semicolonCodeProvider() + { + return [ + [['true'], false, 'return true;'], + [['true;'], false, 'return true;'], + [['true;'], true, 'return true;'], + [['true'], true, false], + + [['echo "foo";', 'true'], true, false], + + [['echo "foo";', 'true'], false, "echo \"foo\";\nreturn true;"], + ]; + } + + /** + * @dataProvider unclosedStatementsProvider + */ + public function testUnclosedStatements(array $lines, $isUnclosed) + { + $cc = new CodeCleaner(); + $res = $cc->clean($lines); + + if ($isUnclosed) { + $this->assertFalse($res); + } else { + $this->assertNotFalse($res); + } + } + + public function unclosedStatementsProvider() + { + return [ + [['echo "'], true], + [['echo \''], true], + [['if (1) {'], true], + + [['echo "foo",'], true], + + [['echo ""'], false], + [["echo ''"], false], + [['if (1) {}'], false], + + [['// closed comment'], false], + [['function foo() { /**'], true], + + [['var_dump(1, 2,'], true], + [['var_dump(1, 2,', '3)'], false], + ]; + } + + /** + * @dataProvider moreUnclosedStatementsProvider + */ + public function testMoreUnclosedStatements(array $lines) + { + if (\defined('HHVM_VERSION')) { + $this->markTestSkipped('HHVM not supported.'); + } + + $cc = new CodeCleaner(); + $res = $cc->clean($lines); + + $this->assertFalse($res); + } + + public function moreUnclosedStatementsProvider() + { + return [ + [["\$content = <<clean([$code]); + } + + public function invalidStatementsProvider() + { + // n.b. We used to check that `var_dump(1,2,)` failed, but PHP Parser + // 4.x backported trailing comma function calls from PHP 7.3 for free! + // so we're not going to spend too much time worrying about it :) + + return [ + ['function "what'], + ["function 'what"], + ['echo }'], + ['echo {'], + ['if (1) }'], + ['echo """'], + ["echo '''"], + ['$foo "bar'], + ['$foo \'bar'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Command/ExitCommandTest.php b/app/vendor/psy/psysh/test/Command/ExitCommandTest.php new file mode 100644 index 000000000..45626be2c --- /dev/null +++ b/app/vendor/psy/psysh/test/Command/ExitCommandTest.php @@ -0,0 +1,29 @@ +execute([]); + } +} diff --git a/app/vendor/psy/psysh/test/Command/ThrowUpCommandTest.php b/app/vendor/psy/psysh/test/Command/ThrowUpCommandTest.php new file mode 100644 index 000000000..511c5809c --- /dev/null +++ b/app/vendor/psy/psysh/test/Command/ThrowUpCommandTest.php @@ -0,0 +1,89 @@ +getMockBuilder('Psy\\Shell') + ->setMethods(['hasCode', 'addCode']) + ->getMock(); + + $shell->expects($this->once())->method('hasCode')->willReturn($hasCode); + $shell->expects($this->once()) + ->method('addCode') + ->with($this->equalTo($expect), $this->equalTo($addSilent)); + + $command = new ThrowUpCommand(); + $command->setApplication($shell); + $tester = new CommandTester($command); + $tester->execute($args); + $this->assertEquals('', $tester->getDisplay()); + } + + public function executeThis() + { + $throw = 'throw \Psy\Exception\ThrowUpException::fromThrowable'; + + return [ + [[], false, $throw . '($_e);'], + + [['exception' => '$ex'], false, $throw . '($ex);'], + [['exception' => 'getException()'], false, $throw . '(getException());'], + [['exception' => 'new \\Exception("WAT")'], false, $throw . '(new \\Exception("WAT"));'], + + [['exception' => '\'some string\''], false, $throw . '(new \\Exception(\'some string\'));'], + [['exception' => '"WHEEEEEEE!"'], false, $throw . '(new \\Exception("WHEEEEEEE!"));'], + + // Everything should work with or without semicolons. + [['exception' => '$ex;'], false, $throw . '($ex);'], + [['exception' => '"WHEEEEEEE!";'], false, $throw . '(new \\Exception("WHEEEEEEE!"));'], + + // Don't add as silent code if we've already got code. + [[], true, $throw . '($_e);', false], + [['exception' => 'getException()'], true, $throw . '(getException());', false], + [['exception' => '\'some string\''], true, $throw . '(new \\Exception(\'some string\'));', false], + ]; + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage No idea how to throw this + */ + public function testMultipleArgsThrowsException() + { + $command = new ThrowUpCommand(); + $command->setApplication(new Shell()); + $tester = new CommandTester($command); + $tester->execute(['exception' => 'foo(); bar()']); + } + + /** + * @expectedException \PhpParser\Error + * @expectedExceptionMessage Syntax error, unexpected ')' on line 1 + */ + public function testParseErrorThrowsException() + { + $command = new ThrowUpCommand(); + $command->setApplication(new Shell()); + $tester = new CommandTester($command); + $tester->execute(['exception' => 'foo)']); + } +} diff --git a/app/vendor/psy/psysh/test/Command/TimeitCommand/TimeitVisitorTest.php b/app/vendor/psy/psysh/test/Command/TimeitCommand/TimeitVisitorTest.php new file mode 100644 index 000000000..1f317350e --- /dev/null +++ b/app/vendor/psy/psysh/test/Command/TimeitCommand/TimeitVisitorTest.php @@ -0,0 +1,52 @@ +traverser = new NodeTraverser(); + $this->traverser->addVisitor(new TimeitVisitor()); + } + + /** + * @dataProvider codez + */ + public function testProcess($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function codez() + { + $start = '\Psy\Command\TimeitCommand::markStart'; + $end = '\Psy\Command\TimeitCommand::markEnd'; + $noReturn = 'new \Psy\CodeCleaner\NoReturnValue()'; + + return [ + ['', "$end($start());"], // heh + ['a()', "$start(); $end(a());"], + ['$b()', "$start(); $end(\$b());"], + ['$c->d()', "$start(); $end(\$c->d());"], + ['e(); f()', "$start(); e(); $end(f());"], + ['function g() { return 1; }', "$start(); function g() {return 1;} $end($noReturn);"], + ['return 1', "$start(); return $end(1);"], + ['return 1; 2', "$start(); return $end(1); $end(2);"], + ['return 1; function h() {}', "$start(); return $end(1); function h() {} $end($noReturn);"], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/ConfigurationTest.php b/app/vendor/psy/psysh/test/ConfigurationTest.php similarity index 60% rename from app/vendor/psy/psysh/test/Psy/Test/ConfigurationTest.php rename to app/vendor/psy/psysh/test/ConfigurationTest.php index e4d9936d5..b7b6c0c01 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/ConfigurationTest.php +++ b/app/vendor/psy/psysh/test/ConfigurationTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -13,7 +13,6 @@ use Psy\CodeCleaner; use Psy\Configuration; -use Psy\ExecutionLoop\Loop; use Psy\Output\PassthruPager; use Psy\VersionUpdater\GitHubChecker; use Symfony\Component\Console\Output\ConsoleOutput; @@ -22,19 +21,19 @@ class ConfigurationTest extends \PHPUnit\Framework\TestCase { private function getConfig($configFile = null) { - return new Configuration(array( - 'configFile' => $configFile ?: __DIR__ . '/../../fixtures/empty.php', - )); + return new Configuration([ + 'configFile' => $configFile ?: __DIR__ . '/fixtures/empty.php', + ]); } public function testDefaults() { $config = $this->getConfig(); - $this->assertEquals(function_exists('readline'), $config->hasReadline()); - $this->assertEquals(function_exists('readline'), $config->useReadline()); - $this->assertEquals(function_exists('pcntl_signal'), $config->hasPcntl()); - $this->assertEquals(function_exists('pcntl_signal'), $config->usePcntl()); + $this->assertSame(\function_exists('readline'), $config->hasReadline()); + $this->assertSame(\function_exists('readline'), $config->useReadline()); + $this->assertSame(\function_exists('pcntl_signal'), $config->hasPcntl()); + $this->assertSame(\function_exists('pcntl_signal'), $config->usePcntl()); $this->assertFalse($config->requireSemicolons()); $this->assertSame(Configuration::COLOR_MODE_AUTO, $config->colorMode()); $this->assertNull($config->getStartupMessage()); @@ -46,11 +45,11 @@ public function testGettersAndSetters() $this->assertNull($config->getDataDir()); $config->setDataDir('wheee'); - $this->assertEquals('wheee', $config->getDataDir()); + $this->assertSame('wheee', $config->getDataDir()); $this->assertNull($config->getConfigDir()); $config->setConfigDir('wheee'); - $this->assertEquals('wheee', $config->getConfigDir()); + $this->assertSame('wheee', $config->getConfigDir()); } /** @@ -58,41 +57,41 @@ public function testGettersAndSetters() */ public function testFilesAndDirectories($home, $configFile, $historyFile, $manualDbFile) { - $oldHome = getenv('HOME'); - putenv("HOME=$home"); + $oldHome = \getenv('HOME'); + \putenv("HOME=$home"); $config = new Configuration(); - $this->assertEquals(realpath($configFile), realpath($config->getConfigFile())); - $this->assertEquals(realpath($historyFile), realpath($config->getHistoryFile())); - $this->assertEquals(realpath($manualDbFile), realpath($config->getManualDbFile())); + $this->assertSame(\realpath($configFile), \realpath($config->getConfigFile())); + $this->assertSame(\realpath($historyFile), \realpath($config->getHistoryFile())); + $this->assertSame(\realpath($manualDbFile), \realpath($config->getManualDbFile())); - putenv("HOME=$oldHome"); + \putenv("HOME=$oldHome"); } public function directories() { - $base = realpath(__DIR__ . '/../../fixtures'); + $base = \realpath(__DIR__ . '/fixtures'); - return array( - array( + return [ + [ $base . '/default', $base . '/default/.config/psysh/config.php', $base . '/default/.config/psysh/psysh_history', $base . '/default/.local/share/psysh/php_manual.sqlite', - ), - array( + ], + [ $base . '/legacy', $base . '/legacy/.psysh/rc.php', $base . '/legacy/.psysh/history', $base . '/legacy/.psysh/php_manual.sqlite', - ), - array( + ], + [ $base . '/mixed', $base . '/mixed/.psysh/config.php', $base . '/mixed/.psysh/psysh_history', null, - ), - ); + ], + ]; } public function testLoadConfig() @@ -100,64 +99,61 @@ public function testLoadConfig() $config = $this->getConfig(); $cleaner = new CodeCleaner(); $pager = new PassthruPager(new ConsoleOutput()); - $loop = new Loop($config); - $config->loadConfig(array( + $config->loadConfig([ 'useReadline' => false, 'usePcntl' => false, 'codeCleaner' => $cleaner, 'pager' => $pager, - 'loop' => $loop, 'requireSemicolons' => true, 'errorLoggingLevel' => E_ERROR | E_WARNING, 'colorMode' => Configuration::COLOR_MODE_FORCED, 'startupMessage' => 'Psysh is awesome!', - )); + ]); $this->assertFalse($config->useReadline()); $this->assertFalse($config->usePcntl()); $this->assertSame($cleaner, $config->getCodeCleaner()); $this->assertSame($pager, $config->getPager()); - $this->assertSame($loop, $config->getLoop()); $this->assertTrue($config->requireSemicolons()); - $this->assertEquals(E_ERROR | E_WARNING, $config->errorLoggingLevel()); + $this->assertSame(E_ERROR | E_WARNING, $config->errorLoggingLevel()); $this->assertSame(Configuration::COLOR_MODE_FORCED, $config->colorMode()); $this->assertSame('Psysh is awesome!', $config->getStartupMessage()); } public function testLoadConfigFile() { - $config = $this->getConfig(__DIR__ . '/../../fixtures/config.php'); + $config = $this->getConfig(__DIR__ . '/fixtures/config.php'); - $runtimeDir = $this->joinPath(realpath(sys_get_temp_dir()), 'psysh_test', 'withconfig', 'temp'); + $runtimeDir = $this->joinPath(\realpath(\sys_get_temp_dir()), 'psysh_test', 'withconfig', 'temp'); - $this->assertStringStartsWith($runtimeDir, realpath($config->getTempFile('foo', 123))); - $this->assertStringStartsWith($runtimeDir, realpath(dirname($config->getPipe('pipe', 123)))); - $this->assertStringStartsWith($runtimeDir, realpath($config->getRuntimeDir())); + $this->assertStringStartsWith($runtimeDir, \realpath($config->getTempFile('foo', 123))); + $this->assertStringStartsWith($runtimeDir, \realpath(\dirname($config->getPipe('pipe', 123)))); + $this->assertStringStartsWith($runtimeDir, \realpath($config->getRuntimeDir())); - $this->assertEquals(function_exists('readline'), $config->useReadline()); + $this->assertSame(\function_exists('readline'), $config->useReadline()); $this->assertFalse($config->usePcntl()); - $this->assertEquals(E_ALL & ~E_NOTICE, $config->errorLoggingLevel()); + $this->assertSame(E_ALL & ~E_NOTICE, $config->errorLoggingLevel()); } public function testLoadLocalConfigFile() { - $oldPwd = getcwd(); - chdir(realpath(__DIR__ . '/../../fixtures/project/')); + $oldPwd = \getcwd(); + \chdir(\realpath(__DIR__ . '/fixtures/project/')); $config = new Configuration(); // When no configuration file is specified local project config is merged - $this->assertFalse($config->useReadline()); - $this->assertTrue($config->usePcntl()); + $this->assertTrue($config->requireSemicolons()); + $this->assertFalse($config->useUnicode()); - $config = new Configuration(array('configFile' => __DIR__ . '/../../fixtures/config.php')); + $config = new Configuration(['configFile' => __DIR__ . '/fixtures/config.php']); // Defining a configuration file skips loading local project config - $this->assertTrue($config->useReadline()); - $this->assertFalse($config->usePcntl()); + $this->assertFalse($config->requireSemicolons()); + $this->assertTrue($config->useUnicode()); - chdir($oldPwd); + \chdir($oldPwd); } /** @@ -165,24 +161,24 @@ public function testLoadLocalConfigFile() */ public function testBaseDirConfigIsDeprecated() { - $config = new Configuration(array('baseDir' => 'fake')); + $config = new Configuration(['baseDir' => 'fake']); } private function joinPath() { - return implode(DIRECTORY_SEPARATOR, func_get_args()); + return \implode(DIRECTORY_SEPARATOR, \func_get_args()); } public function testConfigIncludes() { - $config = new Configuration(array( - 'defaultIncludes' => array('/file.php'), - 'configFile' => __DIR__ . '/../../fixtures/empty.php', - )); + $config = new Configuration([ + 'defaultIncludes' => ['/file.php'], + 'configFile' => __DIR__ . '/fixtures/empty.php', + ]); $includes = $config->getDefaultIncludes(); $this->assertCount(1, $includes); - $this->assertEquals('/file.php', $includes[0]); + $this->assertSame('/file.php', $includes[0]); } public function testGetOutput() @@ -190,25 +186,25 @@ public function testGetOutput() $config = $this->getConfig(); $output = $config->getOutput(); - $this->assertInstanceOf('\Psy\Output\ShellOutput', $output); + $this->assertInstanceOf('Psy\Output\ShellOutput', $output); } public function getOutputDecoratedProvider() { - return array( - 'auto' => array( + return [ + 'auto' => [ null, Configuration::COLOR_MODE_AUTO, - ), - 'forced' => array( + ], + 'forced' => [ true, Configuration::COLOR_MODE_FORCED, - ), - 'disabled' => array( + ], + 'disabled' => [ false, Configuration::COLOR_MODE_DISABLED, - ), - ); + ], + ]; } /** @dataProvider getOutputDecoratedProvider */ @@ -222,11 +218,11 @@ public function testGetOutputDecorated($expectation, $colorMode) public function setColorModeValidProvider() { - return array( - 'auto' => array(Configuration::COLOR_MODE_AUTO), - 'forced' => array(Configuration::COLOR_MODE_FORCED), - 'disabled' => array(Configuration::COLOR_MODE_DISABLED), - ); + return [ + 'auto' => [Configuration::COLOR_MODE_AUTO], + 'forced' => [Configuration::COLOR_MODE_FORCED], + 'disabled' => [Configuration::COLOR_MODE_DISABLED], + ]; } /** @dataProvider setColorModeValidProvider */ @@ -235,7 +231,7 @@ public function testSetColorModeValid($colorMode) $config = $this->getConfig(); $config->setColorMode($colorMode); - $this->assertEquals($colorMode, $config->colorMode()); + $this->assertSame($colorMode, $config->colorMode()); } /** diff --git a/app/vendor/psy/psysh/test/Psy/Test/ConsoleColorFactoryTest.php b/app/vendor/psy/psysh/test/ConsoleColorFactoryTest.php similarity index 84% rename from app/vendor/psy/psysh/test/Psy/Test/ConsoleColorFactoryTest.php rename to app/vendor/psy/psysh/test/ConsoleColorFactoryTest.php index 3da13c7b7..d58a48d36 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/ConsoleColorFactoryTest.php +++ b/app/vendor/psy/psysh/test/ConsoleColorFactoryTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -24,7 +24,7 @@ public function testGetConsoleColorAuto() $themes = $colors->getThemes(); $this->assertFalse($colors->isStyleForced()); - $this->assertEquals(array('blue'), $themes['line_number']); + $this->assertSame(['blue'], $themes['line_number']); } public function testGetConsoleColorForced() @@ -35,7 +35,7 @@ public function testGetConsoleColorForced() $themes = $colors->getThemes(); $this->assertTrue($colors->isStyleForced()); - $this->assertEquals(array('blue'), $themes['line_number']); + $this->assertSame(['blue'], $themes['line_number']); } public function testGetConsoleColorDisabled() @@ -46,6 +46,6 @@ public function testGetConsoleColorDisabled() $themes = $colors->getThemes(); $this->assertFalse($colors->isStyleForced()); - $this->assertEquals(array('none'), $themes['line_number']); + $this->assertSame(['none'], $themes['line_number']); } } diff --git a/app/vendor/psy/psysh/test/ContextTest.php b/app/vendor/psy/psysh/test/ContextTest.php new file mode 100644 index 000000000..d19370367 --- /dev/null +++ b/app/vendor/psy/psysh/test/ContextTest.php @@ -0,0 +1,325 @@ +assertTrue(true); + } + + public function testGetAll() + { + $this->assertTrue(true); + } + + public function testGetSpecialVariables() + { + $context = new Context(); + + $this->assertNull($context->get('_')); + $this->assertNull($context->getReturnValue()); + + $this->assertEquals(['_' => null], $context->getAll()); + + $e = new \Exception('eeeeeee'); + $obj = new \StdClass(); + $context->setLastException($e); + $context->setLastStdout('out'); + $context->setBoundObject($obj); + + $context->setCommandScopeVariables([ + '__function' => 'function', + '__method' => 'method', + '__class' => 'class', + '__namespace' => 'namespace', + '__file' => 'file', + '__line' => 'line', + '__dir' => 'dir', + ]); + + $expected = [ + '_' => null, + '_e' => $e, + '__out' => 'out', + 'this' => $obj, + '__function' => 'function', + '__method' => 'method', + '__class' => 'class', + '__namespace' => 'namespace', + '__file' => 'file', + '__line' => 'line', + '__dir' => 'dir', + ]; + + $this->assertEquals($expected, $context->getAll()); + } + + public function testSetAll() + { + $context = new Context(); + + $baz = new \StdClass(); + $vars = [ + 'foo' => 'Foo', + 'bar' => 123, + 'baz' => $baz, + + '_' => 'fail', + '_e' => 'fail', + '__out' => 'fail', + 'this' => 'fail', + '__psysh__' => 'fail', + + '__function' => 'fail', + '__method' => 'fail', + '__class' => 'fail', + '__namespace' => 'fail', + '__file' => 'fail', + '__line' => 'fail', + '__dir' => 'fail', + ]; + + $context->setAll($vars); + + $this->assertEquals('Foo', $context->get('foo')); + $this->assertEquals(123, $context->get('bar')); + $this->assertSame($baz, $context->get('baz')); + + $this->assertEquals(['foo' => 'Foo', 'bar' => 123, 'baz' => $baz, '_' => null], $context->getAll()); + } + + /** + * @dataProvider specialNames + * @expectedException \InvalidArgumentException + * @expectedExceptionMessageRegEx /Unknown variable: \$\w+/ + */ + public function testSetAllDoesNotSetSpecial($name) + { + $context = new Context(); + $context->setAll([$name => 'fail']); + $context->get($name); + } + + public function specialNames() + { + return [ + ['_e'], + ['__out'], + ['this'], + ['__psysh__'], + ['__function'], + ['__method'], + ['__class'], + ['__namespace'], + ['__file'], + ['__line'], + ['__dir'], + ]; + } + + public function testReturnValue() + { + $context = new Context(); + $this->assertNull($context->getReturnValue()); + + $val = 'some string'; + $context->setReturnValue($val); + $this->assertEquals($val, $context->getReturnValue()); + $this->assertEquals($val, $context->get('_')); + + $obj = new \StdClass(); + $context->setReturnValue($obj); + $this->assertSame($obj, $context->getReturnValue()); + $this->assertSame($obj, $context->get('_')); + + $context->setReturnValue(null); + $this->assertNull($context->getReturnValue()); + } + + public function testLastException() + { + $context = new Context(); + $e = new \Exception('wat'); + $context->setLastException($e); + $this->assertSame($e, $context->getLastException()); + $this->assertSame($e, $context->get('_e')); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage No most-recent exception + */ + public function testLastExceptionThrowsSometimes() + { + $context = new Context(); + $context->getLastException(); + } + + public function testLastStdout() + { + $context = new Context(); + $context->setLastStdout('ouuuuut'); + $this->assertEquals('ouuuuut', $context->getLastStdout()); + $this->assertEquals('ouuuuut', $context->get('__out')); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage No most-recent output + */ + public function testLastStdoutThrowsSometimes() + { + $context = new Context(); + $context->getLastStdout(); + } + + public function testBoundObject() + { + $context = new Context(); + $this->assertNull($context->getBoundObject()); + + $obj = new \StdClass(); + $context->setBoundObject($obj); + $this->assertSame($obj, $context->getBoundObject()); + $this->assertSame($obj, $context->get('this')); + + $context->setBoundObject(null); + $this->assertNull($context->getBoundObject()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Unknown variable: $this + */ + public function testBoundObjectThrowsSometimes() + { + $context = new Context(); + $context->get('this'); + } + + public function testBoundClass() + { + $context = new Context(); + $this->assertNull($context->getBoundClass()); + + $context->setBoundClass(''); + $this->assertNull($context->getBoundClass()); + + $context->setBoundClass('Psy\Shell'); + $this->assertEquals('Psy\Shell', $context->getBoundClass()); + + $context->setBoundObject(new \StdClass()); + $this->assertNotNull($context->getBoundObject()); + $this->assertNull($context->getBoundClass()); + + $context->setBoundClass('Psy\Shell'); + $this->assertEquals('Psy\Shell', $context->getBoundClass()); + $this->assertNull($context->getBoundObject()); + + $context->setBoundClass(null); + $this->assertNull($context->getBoundClass()); + $this->assertNull($context->getBoundObject()); + } + + public function testCommandScopeVariables() + { + $__function = 'donkey'; + $__method = 'diddy'; + $__class = 'cranky'; + $__namespace = 'funky'; + $__file = 'candy'; + $__line = 'dixie'; + $__dir = 'wrinkly'; + + $vars = \compact('__function', '__method', '__class', '__namespace', '__file', '__line', '__dir'); + + $context = new Context(); + $context->setCommandScopeVariables($vars); + + $this->assertEquals($vars, $context->getCommandScopeVariables()); + + $this->assertEquals($__function, $context->get('__function')); + $this->assertEquals($__method, $context->get('__method')); + $this->assertEquals($__class, $context->get('__class')); + $this->assertEquals($__namespace, $context->get('__namespace')); + $this->assertEquals($__file, $context->get('__file')); + $this->assertEquals($__line, $context->get('__line')); + $this->assertEquals($__dir, $context->get('__dir')); + + $someVars = \compact('__function', '__namespace', '__file', '__line', '__dir'); + $context->setCommandScopeVariables($someVars); + } + + public function testGetUnusedCommandScopeVariableNames() + { + $context = new Context(); + + $this->assertEquals( + ['__function', '__method', '__class', '__namespace', '__file', '__line', '__dir'], + $context->getUnusedCommandScopeVariableNames() + ); + + $context->setCommandScopeVariables([ + '__function' => 'foo', + '__namespace' => 'bar', + '__file' => 'baz', + '__line' => 123, + '__dir' => 'qux', + ]); + + $this->assertEquals( + ['__method', '__class'], + \array_values($context->getUnusedCommandScopeVariableNames()) + ); + } + + /** + * @dataProvider specialAndNotSpecialVariableNames + */ + public function testIsSpecialVariableName($name, $isSpecial) + { + $context = new Context(); + + if ($isSpecial) { + $this->assertTrue($context->isSpecialVariableName($name)); + } else { + $this->assertFalse($context->isSpecialVariableName($name)); + } + } + + public function specialAndNotSpecialVariableNames() + { + return [ + ['foo', false], + ['psysh', false], + ['__psysh', false], + + ['_', true], + ['_e', true], + ['__out', true], + ['this', true], + ['__psysh__', true], + + ['__function', true], + ['__method', true], + ['__class', true], + ['__namespace', true], + ['__file', true], + ['__line', true], + ['__dir', true], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/Exception/BreakExceptionTest.php b/app/vendor/psy/psysh/test/Exception/BreakExceptionTest.php similarity index 56% rename from app/vendor/psy/psysh/test/Psy/Test/Exception/BreakExceptionTest.php rename to app/vendor/psy/psysh/test/Exception/BreakExceptionTest.php index fb0949853..ae39fb1f4 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Exception/BreakExceptionTest.php +++ b/app/vendor/psy/psysh/test/Exception/BreakExceptionTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,7 +12,6 @@ namespace Psy\Test\Exception; use Psy\Exception\BreakException; -use Psy\Exception\Exception; class BreakExceptionTest extends \PHPUnit\Framework\TestCase { @@ -20,8 +19,8 @@ public function testInstance() { $e = new BreakException(); - $this->assertTrue($e instanceof Exception); - $this->assertTrue($e instanceof BreakException); + $this->assertInstanceOf('Psy\Exception\Exception', $e); + $this->assertInstanceOf('Psy\Exception\BreakException', $e); } public function testMessage() @@ -29,6 +28,15 @@ public function testMessage() $e = new BreakException('foo'); $this->assertContains('foo', $e->getMessage()); - $this->assertEquals('foo', $e->getRawMessage()); + $this->assertSame('foo', $e->getRawMessage()); + } + + /** + * @expectedException \Psy\Exception\BreakException + * @expectedExceptionMessage Goodbye + */ + public function testExitShell() + { + BreakException::exitShell(); } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/Exception/ErrorExceptionTest.php b/app/vendor/psy/psysh/test/Exception/ErrorExceptionTest.php similarity index 55% rename from app/vendor/psy/psysh/test/Psy/Test/Exception/ErrorExceptionTest.php rename to app/vendor/psy/psysh/test/Exception/ErrorExceptionTest.php index 4bc7f555a..ef9fb9ab4 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Exception/ErrorExceptionTest.php +++ b/app/vendor/psy/psysh/test/Exception/ErrorExceptionTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -12,7 +12,6 @@ namespace Psy\Test\Exception; use Psy\Exception\ErrorException; -use Psy\Exception\Exception; class ErrorExceptionTest extends \PHPUnit\Framework\TestCase { @@ -20,9 +19,9 @@ public function testInstance() { $e = new ErrorException(); - $this->assertTrue($e instanceof Exception); - $this->assertTrue($e instanceof \ErrorException); - $this->assertTrue($e instanceof ErrorException); + $this->assertInstanceOf('Psy\Exception\Exception', $e); + $this->assertInstanceOf('ErrorException', $e); + $this->assertInstanceOf('Psy\Exception\ErrorException', $e); } public function testMessage() @@ -30,7 +29,7 @@ public function testMessage() $e = new ErrorException('foo'); $this->assertContains('foo', $e->getMessage()); - $this->assertEquals('foo', $e->getRawMessage()); + $this->assertSame('foo', $e->getRawMessage()); } /** @@ -59,14 +58,17 @@ public function testThrowException($level, $type) public function getLevels() { - return array( - array(E_WARNING, 'Warning'), - array(E_CORE_WARNING, 'Warning'), - array(E_COMPILE_WARNING, 'Warning'), - array(E_USER_WARNING, 'Warning'), - array(E_STRICT, 'Strict error'), - array(0, 'Error'), - ); + return [ + [E_WARNING, 'Warning'], + [E_CORE_WARNING, 'Warning'], + [E_COMPILE_WARNING, 'Warning'], + [E_USER_WARNING, 'Warning'], + [E_STRICT, 'Strict error'], + [E_DEPRECATED, 'Deprecated'], + [E_USER_DEPRECATED, 'Deprecated'], + [E_RECOVERABLE_ERROR, 'Recoverable fatal error'], + [0, 'Error'], + ]; } /** @@ -74,35 +76,50 @@ public function getLevels() */ public function testThrowExceptionAsErrorHandler($level, $type) { - set_error_handler(array('Psy\Exception\ErrorException', 'throwException')); + \set_error_handler(['Psy\Exception\ErrorException', 'throwException']); try { - trigger_error('{whot}', $level); + \trigger_error('{whot}', $level); } catch (ErrorException $e) { $this->assertContains('PHP ' . $type, $e->getMessage()); $this->assertContains('{whot}', $e->getMessage()); } - restore_error_handler(); + \restore_error_handler(); } public function getUserLevels() { - return array( - array(E_USER_ERROR, 'Error'), - array(E_USER_WARNING, 'Warning'), - array(E_USER_NOTICE, 'Notice'), - array(E_USER_DEPRECATED, 'Deprecated'), - ); + return [ + [E_USER_ERROR, 'Error'], + [E_USER_WARNING, 'Warning'], + [E_USER_NOTICE, 'Notice'], + [E_USER_DEPRECATED, 'Deprecated'], + ]; } public function testIgnoreExecutionLoopFilename() { - $e = new ErrorException('{{message}}', 0, 1, '/fake/path/to/Psy/ExecutionLoop/Loop.php'); + $e = new ErrorException('{{message}}', 0, 1, '/fake/path/to/Psy/ExecutionLoop.php'); $this->assertEmpty($e->getFile()); - $e = new ErrorException('{{message}}', 0, 1, 'c:\fake\path\to\Psy\ExecutionLoop\Loop.php'); + $e = new ErrorException('{{message}}', 0, 1, 'c:\fake\path\to\Psy\ExecutionLoop.php'); $this->assertEmpty($e->getFile()); $e = new ErrorException('{{message}}', 0, 1, '/fake/path/to/Psy/File.php'); $this->assertNotEmpty($e->getFile()); } + + public function testFromError() + { + if (\version_compare(PHP_VERSION, '7.0.0', '<')) { + $this->markTestSkipped(); + } + + $error = new \Error('{{message}}', 0); + $exception = ErrorException::fromError($error); + + $this->assertContains('PHP Error: {{message}}', $exception->getMessage()); + $this->assertEquals(0, $exception->getCode()); + $this->assertEquals($error->getFile(), $exception->getFile()); + $this->assertSame($exception->getPrevious(), $error); + } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/Exception/FatalErrorExceptionTest.php b/app/vendor/psy/psysh/test/Exception/FatalErrorExceptionTest.php similarity index 64% rename from app/vendor/psy/psysh/test/Psy/Test/Exception/FatalErrorExceptionTest.php rename to app/vendor/psy/psysh/test/Exception/FatalErrorExceptionTest.php index 9ff66b954..36c7dd8c1 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Exception/FatalErrorExceptionTest.php +++ b/app/vendor/psy/psysh/test/Exception/FatalErrorExceptionTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,6 @@ namespace Psy\Test\Exception; -use Psy\Exception\Exception; use Psy\Exception\FatalErrorException; class FatalErrorExceptionTest extends \PHPUnit\Framework\TestCase @@ -20,16 +19,16 @@ public function testInstance() { $e = new FatalErrorException(); - $this->assertTrue($e instanceof Exception); - $this->assertTrue($e instanceof \ErrorException); - $this->assertTrue($e instanceof FatalErrorException); + $this->assertInstanceOf('Psy\Exception\Exception', $e); + $this->assertInstanceOf('ErrorException', $e); + $this->assertInstanceOf('Psy\Exception\FatalErrorException', $e); } public function testMessage() { $e = new FatalErrorException('{msg}', 0, 0, '{filename}', 13); - $this->assertEquals('{msg}', $e->getRawMessage()); + $this->assertSame('{msg}', $e->getRawMessage()); $this->assertContains('{msg}', $e->getMessage()); $this->assertContains('{filename}', $e->getMessage()); $this->assertContains('line 13', $e->getMessage()); @@ -39,8 +38,14 @@ public function testMessageWithNoFilename() { $e = new FatalErrorException('{msg}'); - $this->assertEquals('{msg}', $e->getRawMessage()); + $this->assertSame('{msg}', $e->getRawMessage()); $this->assertContains('{msg}', $e->getMessage()); $this->assertContains('eval()\'d code', $e->getMessage()); } + + public function testNegativeOneLineNumberIgnored() + { + $e = new FatalErrorException('{msg}', 0, 1, null, -1); + $this->assertEquals(0, $e->getLine()); + } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/Exception/ParseErrorExceptionTest.php b/app/vendor/psy/psysh/test/Exception/ParseErrorExceptionTest.php similarity index 79% rename from app/vendor/psy/psysh/test/Psy/Test/Exception/ParseErrorExceptionTest.php rename to app/vendor/psy/psysh/test/Exception/ParseErrorExceptionTest.php index 9fa9750da..446b9389c 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Exception/ParseErrorExceptionTest.php +++ b/app/vendor/psy/psysh/test/Exception/ParseErrorExceptionTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,6 @@ namespace Psy\Test\Exception; -use Psy\Exception\Exception; use Psy\Exception\ParseErrorException; class ParseErrorExceptionTest extends \PHPUnit\Framework\TestCase @@ -20,9 +19,9 @@ public function testInstance() { $e = new ParseErrorException(); - $this->assertTrue($e instanceof Exception); - $this->assertTrue($e instanceof \PhpParser\Error); - $this->assertTrue($e instanceof ParseErrorException); + $this->assertInstanceOf('Psy\Exception\Exception', $e); + $this->assertInstanceOf('PhpParser\Error', $e); + $this->assertInstanceOf('Psy\Exception\ParseErrorException', $e); } public function testMessage() diff --git a/app/vendor/psy/psysh/test/Psy/Test/Exception/RuntimeExceptionTest.php b/app/vendor/psy/psysh/test/Exception/RuntimeExceptionTest.php similarity index 56% rename from app/vendor/psy/psysh/test/Psy/Test/Exception/RuntimeExceptionTest.php rename to app/vendor/psy/psysh/test/Exception/RuntimeExceptionTest.php index 8eca13487..1121ea4e5 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Exception/RuntimeExceptionTest.php +++ b/app/vendor/psy/psysh/test/Exception/RuntimeExceptionTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,6 @@ namespace Psy\Test\Exception; -use Psy\Exception\Exception; use Psy\Exception\RuntimeException; class RuntimeExceptionTest extends \PHPUnit\Framework\TestCase @@ -21,11 +20,11 @@ public function testException() $msg = 'bananas'; $e = new RuntimeException($msg); - $this->assertTrue($e instanceof Exception); - $this->assertTrue($e instanceof \RuntimeException); - $this->assertTrue($e instanceof RuntimeException); + $this->assertInstanceOf('Psy\Exception\Exception', $e); + $this->assertInstanceOf('RuntimeException', $e); + $this->assertInstanceOf('Psy\Exception\RuntimeException', $e); - $this->assertEquals($msg, $e->getMessage()); - $this->assertEquals($msg, $e->getRawMessage()); + $this->assertSame($msg, $e->getMessage()); + $this->assertSame($msg, $e->getRawMessage()); } } diff --git a/app/vendor/psy/psysh/test/Exception/ThrowUpExceptionTest.php b/app/vendor/psy/psysh/test/Exception/ThrowUpExceptionTest.php new file mode 100644 index 000000000..09c337324 --- /dev/null +++ b/app/vendor/psy/psysh/test/Exception/ThrowUpExceptionTest.php @@ -0,0 +1,66 @@ +assertInstanceOf('Psy\Exception\Exception', $e); + $this->assertInstanceOf('Psy\Exception\ThrowUpException', $e); + + $this->assertEquals("Throwing Exception with message '{{message}}'", $e->getMessage()); + $this->assertEquals('{{message}}', $e->getRawMessage()); + $this->assertEquals(123, $e->getCode()); + $this->assertSame($previous, $e->getPrevious()); + } + + public function testFromThrowable() + { + $previous = new \Exception('{{message}}'); + $e = ThrowUpException::fromThrowable($previous); + + $this->assertInstanceOf('Psy\Exception\ThrowUpException', $e); + $this->assertSame($previous, $e->getPrevious()); + } + + public function testFromThrowableWithError() + { + if (\version_compare(PHP_VERSION, '7.0.0', '<')) { + $this->markTestSkipped(); + } + + $previous = new \Error('{{message}}'); + $e = ThrowUpException::fromThrowable($previous); + + $this->assertInstanceOf('Psy\Exception\ThrowUpException', $e); + $this->assertInstanceOf('Psy\Exception\ErrorException', $e->getPrevious()); + + $this->assertNotSame($previous, $e->getPrevious()); + $this->assertSame($previous, $e->getPrevious()->getPrevious()); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage throw-up can only throw Exceptions and Errors + */ + public function testFromThrowableThrowsError() + { + $notThrowable = new \StdClass(); + ThrowUpException::fromThrowable($notThrowable); + } +} diff --git a/app/vendor/psy/psysh/test/Exception/TypeErrorExceptionTest.php b/app/vendor/psy/psysh/test/Exception/TypeErrorExceptionTest.php new file mode 100644 index 000000000..01f251bb8 --- /dev/null +++ b/app/vendor/psy/psysh/test/Exception/TypeErrorExceptionTest.php @@ -0,0 +1,52 @@ +assertInstanceOf('Psy\Exception\Exception', $e); + $this->assertInstanceOf('Psy\Exception\TypeErrorException', $e); + + $this->assertEquals('TypeError: {{message}}', $e->getMessage()); + $this->assertEquals('{{message}}', $e->getRawMessage()); + $this->assertEquals(13, $e->getCode()); + } + + public function testStripsEvalFromMessage() + { + $message = 'Something or other, called in line 10: eval()\'d code'; + $e = new TypeErrorException($message); + $this->assertEquals($message, $e->getRawMessage()); + $this->assertEquals('TypeError: Something or other', $e->getMessage()); + } + + public function testFromTypeError() + { + if (\version_compare(PHP_VERSION, '7.0.0', '<')) { + $this->markTestSkipped(); + } + + $previous = new \TypeError('{{message}}', 13); + $e = TypeErrorException::fromTypeError($previous); + + $this->assertInstanceOf('Psy\Exception\TypeErrorException', $e); + $this->assertEquals('TypeError: {{message}}', $e->getMessage()); + $this->assertEquals('{{message}}', $e->getRawMessage()); + $this->assertEquals(13, $e->getCode()); + } +} diff --git a/app/vendor/psy/psysh/test/FakeShell.php b/app/vendor/psy/psysh/test/FakeShell.php new file mode 100644 index 000000000..9f6fa97fc --- /dev/null +++ b/app/vendor/psy/psysh/test/FakeShell.php @@ -0,0 +1,29 @@ +matchers = $matchers; + } +} diff --git a/app/vendor/psy/psysh/test/Formatter/CodeFormatterTest.php b/app/vendor/psy/psysh/test/Formatter/CodeFormatterTest.php new file mode 100644 index 000000000..87f56dfd7 --- /dev/null +++ b/app/vendor/psy/psysh/test/Formatter/CodeFormatterTest.php @@ -0,0 +1,129 @@ +assertEquals($expected, self::trimLines($formattedWithoutColors)); + $this->assertNotEquals($expected, self::trimLines($formatted)); + } + + public function reflectors() + { + $expectClass = <<<'EOS' + > 14| class SomeClass + 15| { + 16| const SOME_CONST = 'some const'; + 17| private $someProp = 'some prop'; + 18| + 19| public function someMethod($someParam) + 20| { + 21| return 'some method'; + 22| } + 23| + 24| public static function someClosure() + 25| { + 26| return function () { + 27| return 'some closure'; + 28| }; + 29| } + 30| } +EOS; + + $expectMethod = <<<'EOS' + > 19| public function someMethod($someParam) + 20| { + 21| return 'some method'; + 22| } +EOS; + + $expectClosure = <<<'EOS' + > 26| return function () { + 27| return 'some closure'; + 28| }; +EOS; + + return [ + [new \ReflectionClass('Psy\Test\Formatter\Fixtures\SomeClass'), $expectClass], + [new \ReflectionObject(new SomeClass()), $expectClass], + [new \ReflectionMethod('Psy\Test\Formatter\Fixtures\SomeClass', 'someMethod'), $expectMethod], + [new \ReflectionFunction(SomeClass::someClosure()), $expectClosure], + ]; + } + + /** + * @dataProvider invalidReflectors + * @expectedException \Psy\Exception\RuntimeException + */ + public function testCodeFormatterThrowsExceptionForReflectorsItDoesntUnderstand($reflector) + { + CodeFormatter::format($reflector); + } + + public function invalidReflectors() + { + $reflectors = [ + [new \ReflectionExtension('json')], + [new \ReflectionParameter(['Psy\Test\Formatter\Fixtures\SomeClass', 'someMethod'], 'someParam')], + [new \ReflectionProperty('Psy\Test\Formatter\Fixtures\SomeClass', 'someProp')], + ]; + + if (\version_compare(PHP_VERSION, '7.1.0', '>=')) { + $reflectors[] = [new \ReflectionClassConstant('Psy\Test\Formatter\Fixtures\SomeClass', 'SOME_CONST')]; + } + + return $reflectors; + } + + /** + * @dataProvider filenames + * @expectedException \Psy\Exception\RuntimeException + */ + public function testCodeFormatterThrowsExceptionForMissingFile($filename) + { + $reflector = $this->getMockBuilder('ReflectionClass') + ->disableOriginalConstructor() + ->getMock(); + + $reflector + ->expects($this->once()) + ->method('getFileName') + ->will($this->returnValue($filename)); + + CodeFormatter::format($reflector); + } + + public function filenames() + { + if (\defined('HHVM_VERSION')) { + $this->markTestSkipped('We have issues with PHPUnit mocks on HHVM.'); + } + + return [[null], ['not a file']]; + } + + private static function trimLines($code) + { + return \rtrim(\implode("\n", \array_map('rtrim', \explode("\n", $code)))); + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/Formatter/DocblockFormatterTest.php b/app/vendor/psy/psysh/test/Formatter/DocblockFormatterTest.php similarity index 96% rename from app/vendor/psy/psysh/test/Psy/Test/Formatter/DocblockFormatterTest.php rename to app/vendor/psy/psysh/test/Formatter/DocblockFormatterTest.php index fa742b088..134c76d02 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Formatter/DocblockFormatterTest.php +++ b/app/vendor/psy/psysh/test/Formatter/DocblockFormatterTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -55,7 +55,7 @@ public function testFormat() Author: Justin Hileman \ EOS; - $this->assertEquals( + $this->assertSame( $expected, DocblockFormatter::format(new \ReflectionMethod($this, 'methodWithDocblock')) ); diff --git a/app/vendor/psy/psysh/test/Formatter/Fixtures/BoringTrait.php b/app/vendor/psy/psysh/test/Formatter/Fixtures/BoringTrait.php new file mode 100644 index 000000000..9f13ab932 --- /dev/null +++ b/app/vendor/psy/psysh/test/Formatter/Fixtures/BoringTrait.php @@ -0,0 +1,20 @@ +assertEquals($expected, strip_tags(SignatureFormatter::format($reflector))); + $this->assertSame($expected, \strip_tags(SignatureFormatter::format($reflector))); } public function signatureReflectors() { - return array( - array( + return [ + [ new \ReflectionFunction('implode'), - defined('HHVM_VERSION') ? 'function implode($arg1, $arg2 = null)' : 'function implode($glue, $pieces)', - ), - array( - new ReflectionConstant($this, 'FOO'), + \defined('HHVM_VERSION') ? 'function implode($arg1, $arg2 = null)' : 'function implode($glue, $pieces)', + ], + [ + ReflectionClassConstant::create($this, 'FOO'), 'const FOO = "foo value"', - ), - array( + ], + [ new \ReflectionMethod($this, 'someFakeMethod'), 'private function someFakeMethod(array $one, $two = \'TWO\', Reflector $three = null)', - ), - array( + ], + [ new \ReflectionProperty($this, 'bar'), 'private static $bar', - ), - array( + ], + [ new \ReflectionClass('Psy\CodeCleaner\CodeCleanerPass'), 'abstract class Psy\CodeCleaner\CodeCleanerPass ' . 'extends PhpParser\NodeVisitorAbstract ' . 'implements PhpParser\NodeVisitor', - ), - ); + ], + [ + new \ReflectionFunction('array_chunk'), + 'function array_chunk($arg, $size, $preserve_keys = unknown)', + ], + [ + new \ReflectionClass('Psy\Test\Formatter\Fixtures\BoringTrait'), + 'trait Psy\Test\Formatter\Fixtures\BoringTrait', + ], + [ + new \ReflectionMethod('Psy\Test\Formatter\Fixtures\BoringTrait', 'boringMethod'), + 'public function boringMethod($one = 1)', + ], + [ + new ReflectionConstant_('E_ERROR'), + 'define("E_ERROR", 1)', + ], + [ + new ReflectionConstant_('PHP_VERSION'), + 'define("PHP_VERSION", "' . PHP_VERSION . '")', + ], + [ + new ReflectionConstant_('__LINE__'), + 'define("__LINE__", null)', // @todo show this as `unknown` in red or something? + ], + ]; } /** diff --git a/app/vendor/psy/psysh/test/Psy/Test/Input/CodeArgumentTest.php b/app/vendor/psy/psysh/test/Input/CodeArgumentTest.php similarity index 67% rename from app/vendor/psy/psysh/test/Psy/Test/Input/CodeArgumentTest.php rename to app/vendor/psy/psysh/test/Input/CodeArgumentTest.php index 4329a032b..c39615208 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Input/CodeArgumentTest.php +++ b/app/vendor/psy/psysh/test/Input/CodeArgumentTest.php @@ -3,13 +3,13 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace Psy\Tests\Input; +namespace Psy\Test\Input; use Psy\Input\CodeArgument; use Symfony\Component\Console\Input\InputArgument; @@ -27,11 +27,11 @@ public function testInvalidModes($mode) public function getInvalidModes() { - return array( - array(InputArgument::IS_ARRAY), - array(InputArgument::IS_ARRAY | InputArgument::REQUIRED), - array(InputArgument::IS_ARRAY | InputArgument::OPTIONAL), - ); + return [ + [InputArgument::IS_ARRAY], + [InputArgument::IS_ARRAY | InputArgument::REQUIRED], + [InputArgument::IS_ARRAY | InputArgument::OPTIONAL], + ]; } /** @@ -44,9 +44,9 @@ public function testValidModes($mode) public function getValidModes() { - return array( - array(InputArgument::REQUIRED), - array(InputArgument::OPTIONAL), - ); + return [ + [InputArgument::REQUIRED], + [InputArgument::OPTIONAL], + ]; } } diff --git a/app/vendor/psy/psysh/test/Input/FilterOptionsTest.php b/app/vendor/psy/psysh/test/Input/FilterOptionsTest.php new file mode 100644 index 000000000..7ed8919bd --- /dev/null +++ b/app/vendor/psy/psysh/test/Input/FilterOptionsTest.php @@ -0,0 +1,105 @@ +assertCount(3, $opts); + } + + /** + * @dataProvider validInputs + */ + public function testBindValidInput($input, $hasFilter = true) + { + $input = $this->getInput($input); + $filterOptions = new FilterOptions(); + $filterOptions->bind($input); + + $this->assertEquals($hasFilter, $filterOptions->hasFilter()); + } + + public function validInputs() + { + return [ + ['--grep="bar"'], + ['--grep="bar" --invert'], + ['--grep="bar" --insensitive'], + ['--grep="bar" --invert --insensitive'], + ['', false], + ]; + } + + /** + * @dataProvider invalidInputs + * @expectedException \Psy\Exception\RuntimeException + */ + public function testBindInvalidInput($input) + { + $input = $this->getInput($input); + $filterOptions = new FilterOptions(); + $filterOptions->bind($input); + } + + public function invalidInputs() + { + return [ + ['--invert'], + ['--insensitive'], + ['--invert --insensitive'], + + // invalid because regex + ['--grep /*/'], + ]; + } + + /** + * @dataProvider matchData + */ + public function testMatch($input, $str, $matches) + { + $input = $this->getInput($input); + $filterOptions = new FilterOptions(); + $filterOptions->bind($input); + + $this->assertEquals($matches, $filterOptions->match($str)); + } + + public function matchData() + { + return [ + ['', 'whatever', true], + ['--grep FOO', 'foo', false], + ['--grep foo', 'foo', true], + ['--grep foo', 'food', true], + ['--grep oo', 'Food', true], + ['--grep oo -i', 'FOOD', true], + ['--grep foo -v', 'food', false], + ['--grep foo -v', 'whatever', true], + ]; + } + + private function getInput($input) + { + $input = new StringInput($input); + $input->bind(new InputDefinition(FilterOptions::getOptions())); + + return $input; + } +} diff --git a/app/vendor/psy/psysh/test/Input/ShellInputTest.php b/app/vendor/psy/psysh/test/Input/ShellInputTest.php new file mode 100644 index 000000000..f19d12618 --- /dev/null +++ b/app/vendor/psy/psysh/test/Input/ShellInputTest.php @@ -0,0 +1,254 @@ +bind($definition); + } + + public function testInputOptionWithGivenString() + { + $definition = new InputDefinition([ + new InputOption('foo', null, InputOption::VALUE_REQUIRED), + new CodeArgument('code', null, CodeArgument::REQUIRED), + ]); + + $input = new ShellInput('--foo=bar echo "baz\\\\n";'); + $input->bind($definition); + $this->assertSame('bar', $input->getOption('foo')); + $this->assertSame('echo "baz\n";', $input->getArgument('code')); + } + + public function testInputOptionWithoutCodeArguments() + { + $definition = new InputDefinition([ + new InputOption('foo', null, InputOption::VALUE_REQUIRED), + new InputOption('qux', 'q', InputOption::VALUE_REQUIRED), + new InputArgument('bar', null, InputArgument::REQUIRED), + new InputArgument('baz', null, InputArgument::REQUIRED), + ]); + + $input = new ShellInput('--foo=foo -q qux bar "baz\\\\n"'); + $input->bind($definition); + $this->assertSame('foo', $input->getOption('foo')); + $this->assertSame('qux', $input->getOption('qux')); + $this->assertSame('bar', $input->getArgument('bar')); + $this->assertSame('baz\\n', $input->getArgument('baz')); + } + + public function testInputWithDashDash() + { + $definition = new InputDefinition([ + new InputOption('foo', null, InputOption::VALUE_REQUIRED), + new CodeArgument('code', null, CodeArgument::REQUIRED), + ]); + + $input = new ShellInput('-- echo --foo::$bar'); + $input->bind($definition); + $this->assertNull($input->getOption('foo')); + $this->assertSame('echo --foo::$bar', $input->getArgument('code')); + } + + public function testInputWithEmptyString() + { + $definition = new InputDefinition([ + new InputOption('foo', null, InputOption::VALUE_REQUIRED), + new CodeArgument('code', null, CodeArgument::REQUIRED), + ]); + + $input = new ShellInput('"" --foo bar'); + $input->bind($definition); + $this->assertSame('"" --foo bar', $input->getArgument('code')); + } + + /** + * @dataProvider getTokenizeData + */ + public function testTokenize($input, $tokens, $message) + { + $input = new ShellInput($input); + $r = new \ReflectionClass('Psy\Input\ShellInput'); + $p = $r->getProperty('tokenPairs'); + $p->setAccessible(true); + $this->assertSame($tokens, $p->getValue($input), $message); + } + + public function getTokenizeData() + { + // Test all the cases from StringInput test, ensuring they have an appropriate $rest token. + return [ + [ + '', + [], + '->tokenize() parses an empty string', + ], + [ + 'foo', + [['foo', 'foo']], + '->tokenize() parses arguments', + ], + [ + ' foo bar ', + [['foo', 'foo bar '], ['bar', 'bar ']], + '->tokenize() ignores whitespaces between arguments', + ], + [ + '"quoted"', + [['quoted', '"quoted"']], + '->tokenize() parses quoted arguments', + ], + [ + "'quoted'", + [['quoted', "'quoted'"]], + '->tokenize() parses quoted arguments', + ], + [ + "'a\rb\nc\td'", + [["a\rb\nc\td", "'a\rb\nc\td'"]], + '->tokenize() parses whitespace chars in strings', + ], + [ + "'a'\r'b'\n'c'\t'd'", + [ + ['a', "'a'\r'b'\n'c'\t'd'"], + ['b', "'b'\n'c'\t'd'"], + ['c', "'c'\t'd'"], + ['d', "'d'"], + ], + '->tokenize() parses whitespace chars between args as spaces', + ], + + /* + * These don't play nice with unescaping input, but the end result + * is correct, so disable the tests for now. + * + * @todo Sort this out and re-enable these test cases. + */ + // [ + // '\"quoted\"', + // [['"quoted"', '\"quoted\"']], + // '->tokenize() parses escaped-quoted arguments', + // ], + // [ + // "\'quoted\'", + // [['\'quoted\'', "\'quoted\'"]], + // '->tokenize() parses escaped-quoted arguments', + // ], + + [ + '-a', + [['-a', '-a']], + '->tokenize() parses short options', + ], + [ + '-azc', + [['-azc', '-azc']], + '->tokenize() parses aggregated short options', + ], + [ + '-awithavalue', + [['-awithavalue', '-awithavalue']], + '->tokenize() parses short options with a value', + ], + [ + '-a"foo bar"', + [['-afoo bar', '-a"foo bar"']], + '->tokenize() parses short options with a value', + ], + [ + '-a"foo bar""foo bar"', + [['-afoo barfoo bar', '-a"foo bar""foo bar"']], + '->tokenize() parses short options with a value', + ], + [ + '-a\'foo bar\'', + [['-afoo bar', '-a\'foo bar\'']], + '->tokenize() parses short options with a value', + ], + [ + '-a\'foo bar\'\'foo bar\'', + [['-afoo barfoo bar', '-a\'foo bar\'\'foo bar\'']], + '->tokenize() parses short options with a value', + ], + [ + '-a\'foo bar\'"foo bar"', + [['-afoo barfoo bar', '-a\'foo bar\'"foo bar"']], + '->tokenize() parses short options with a value', + ], + [ + '--long-option', + [['--long-option', '--long-option']], + '->tokenize() parses long options', + ], + [ + '--long-option=foo', + [['--long-option=foo', '--long-option=foo']], + '->tokenize() parses long options with a value', + ], + [ + '--long-option="foo bar"', + [['--long-option=foo bar', '--long-option="foo bar"']], + '->tokenize() parses long options with a value', + ], + [ + '--long-option="foo bar""another"', + [['--long-option=foo baranother', '--long-option="foo bar""another"']], + '->tokenize() parses long options with a value', + ], + [ + '--long-option=\'foo bar\'', + [['--long-option=foo bar', '--long-option=\'foo bar\'']], + '->tokenize() parses long options with a value', + ], + [ + "--long-option='foo bar''another'", + [['--long-option=foo baranother', "--long-option='foo bar''another'"]], + '->tokenize() parses long options with a value', + ], + [ + "--long-option='foo bar'\"another\"", + [['--long-option=foo baranother', "--long-option='foo bar'\"another\""]], + '->tokenize() parses long options with a value', + ], + [ + 'foo -a -ffoo --long bar', + [ + ['foo', 'foo -a -ffoo --long bar'], + ['-a', '-a -ffoo --long bar'], + ['-ffoo', '-ffoo --long bar'], + ['--long', '--long bar'], + ['bar', 'bar'], + ], + '->tokenize() parses when several arguments and options', + ], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CodeCleanerTestCase.php b/app/vendor/psy/psysh/test/ParserTestCase.php similarity index 76% rename from app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CodeCleanerTestCase.php rename to app/vendor/psy/psysh/test/ParserTestCase.php index d1a302795..a0740b663 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CodeCleanerTestCase.php +++ b/app/vendor/psy/psysh/test/ParserTestCase.php @@ -3,34 +3,29 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -namespace Psy\Test\CodeCleaner; +namespace Psy\Test; -use PhpParser\NodeTraverser; use PhpParser\PrettyPrinter\Standard as Printer; -use Psy\CodeCleaner\CodeCleanerPass; use Psy\Exception\ParseErrorException; use Psy\ParserFactory; -class CodeCleanerTestCase extends \PHPUnit\Framework\TestCase +class ParserTestCase extends \PHPUnit\Framework\TestCase { - protected $pass; protected $traverser; private $parser; private $printer; - protected function setPass(CodeCleanerPass $pass) + public function tearDown() { - $this->pass = $pass; - if (!isset($this->traverser)) { - $this->traverser = new NodeTraverser(); - } - $this->traverser->addVisitor($this->pass); + $this->traverser = null; + $this->parser = null; + $this->printer = null; } protected function parse($code, $prefix = 'traverser)) { + throw new \RuntimeException('Test cases must provide a traverser'); + } + return $this->traverser->traverse($stmts); } @@ -66,7 +65,8 @@ protected function assertProcessesAs($from, $to) { $stmts = $this->parse($from); $stmts = $this->traverse($stmts); - $this->assertEquals($to, $this->prettyPrint($stmts)); + $toStmts = $this->parse($to); + $this->assertSame($this->prettyPrint($toStmts), $this->prettyPrint($stmts)); } private function getParser() @@ -92,6 +92,6 @@ private function parseErrorIsEOF(\PhpParser\Error $e) { $msg = $e->getRawMessage(); - return ($msg === 'Unexpected token EOF') || (strpos($msg, 'Syntax error, unexpected EOF') !== false); + return ($msg === 'Unexpected token EOF') || (\strpos($msg, 'Syntax error, unexpected EOF') !== false); } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/AutoloaderTest.php b/app/vendor/psy/psysh/test/Psy/Test/AutoloaderTest.php deleted file mode 100644 index fdd6d5f8c..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/AutoloaderTest.php +++ /dev/null @@ -1,23 +0,0 @@ -assertTrue(spl_autoload_unregister(array('Psy\Autoloader', 'autoload'))); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AbstractClassPassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AbstractClassPassTest.php deleted file mode 100644 index 21d4f0858..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/AbstractClassPassTest.php +++ /dev/null @@ -1,64 +0,0 @@ -pass = new AbstractClassPass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); - } - - /** - * @dataProvider invalidStatements - * @expectedException \Psy\Exception\FatalErrorException - */ - public function testProcessStatementFails($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidStatements() - { - return array( - array('class A { abstract function a(); }'), - array('abstract class B { abstract function b() {} }'), - array('abstract class B { abstract function b() { echo "yep"; } }'), - ); - } - - /** - * @dataProvider validStatements - */ - public function testProcessStatementPasses($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validStatements() - { - return array( - array('abstract class C { function c() {} }'), - array('abstract class D { abstract function d(); }'), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CallTimePassByReferencePassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CallTimePassByReferencePassTest.php deleted file mode 100644 index ff2527946..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CallTimePassByReferencePassTest.php +++ /dev/null @@ -1,76 +0,0 @@ -pass = new CallTimePassByReferencePass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); - } - - /** - * @dataProvider invalidStatements - * @expectedException \Psy\Exception\FatalErrorException - */ - public function testProcessStatementFails($code) - { - if (version_compare(PHP_VERSION, '5.4', '<')) { - $this->markTestSkipped(); - } - - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidStatements() - { - return array( - array('f(&$arg)'), - array('$object->method($first, &$arg)'), - array('$closure($first, &$arg, $last)'), - array('A::b(&$arg)'), - ); - } - - /** - * @dataProvider validStatements - */ - public function testProcessStatementPasses($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validStatements() - { - $data = array( - array('array(&$var)'), - array('$a = &$b'), - array('f(array(&$b))'), - ); - - if (version_compare(PHP_VERSION, '5.4', '<')) { - $data = array_merge($data, $this->invalidStatements()); - } - - return $data; - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CalledClassPassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CalledClassPassTest.php deleted file mode 100644 index a581d7f33..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/CalledClassPassTest.php +++ /dev/null @@ -1,104 +0,0 @@ -pass = new CalledClassPass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); - } - - /** - * @dataProvider invalidStatements - * @expectedException \Psy\Exception\ErrorException - */ - public function testProcessStatementFails($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidStatements() - { - return array( - array('get_class()'), - array('get_class(null)'), - array('get_called_class()'), - array('get_called_class(null)'), - array('function foo() { return get_class(); }'), - array('function foo() { return get_class(null); }'), - array('function foo() { return get_called_class(); }'), - array('function foo() { return get_called_class(null); }'), - ); - } - - /** - * @dataProvider validStatements - */ - public function testProcessStatementPasses($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validStatements() - { - return array( - array('get_class($foo)'), - array('get_class(bar())'), - array('get_called_class($foo)'), - array('get_called_class(bar())'), - array('function foo($bar) { return get_class($bar); }'), - array('function foo($bar) { return get_called_class($bar); }'), - array('class Foo { function bar() { return get_class(); } }'), - array('class Foo { function bar() { return get_class(null); } }'), - array('class Foo { function bar() { return get_called_class(); } }'), - array('class Foo { function bar() { return get_called_class(null); } }'), - array('$foo = function () {}; $foo()'), - ); - } - - /** - * @dataProvider validTraitStatements - */ - public function testProcessTraitStatementPasses($code) - { - if (version_compare(PHP_VERSION, '5.4', '<')) { - $this->markTestSkipped(); - } - - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validTraitStatements() - { - return array( - array('trait Foo { function bar() { return get_class(); } }'), - array('trait Foo { function bar() { return get_class(null); } }'), - array('trait Foo { function bar() { return get_called_class(); } }'), - array('trait Foo { function bar() { return get_called_class(null); } }'), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ExitPassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ExitPassTest.php deleted file mode 100644 index 43b55546b..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/ExitPassTest.php +++ /dev/null @@ -1,59 +0,0 @@ -setPass(new ExitPass()); - } - - /** - * @dataProvider dataProviderExitStatement - */ - public function testExitStatement($from, $to) - { - $this->assertProcessesAs($from, $to); - } - - /** - * Data provider for testExitStatement. - * - * @return array - */ - public function dataProviderExitStatement() - { - return array( - array('exit;', "{$this->expectedExceptionString};"), - array('exit();', "{$this->expectedExceptionString};"), - array('die;', "{$this->expectedExceptionString};"), - array('exit(die(die));', "{$this->expectedExceptionString};"), - array('if (true) { exit; }', "if (true) {\n {$this->expectedExceptionString};\n}"), - array('if (false) { exit; }', "if (false) {\n {$this->expectedExceptionString};\n}"), - array('1 and exit();', "1 and {$this->expectedExceptionString};"), - array('foo() or die', "foo() or {$this->expectedExceptionString};"), - array('exit and 1;', "{$this->expectedExceptionString} and 1;"), - array('if (exit) { echo $wat; }', "if ({$this->expectedExceptionString}) {\n echo \$wat;\n}"), - array('exit or die;', "{$this->expectedExceptionString} or {$this->expectedExceptionString};"), - array('switch (die) { }', "switch ({$this->expectedExceptionString}) {\n}"), - array('for ($i = 1; $i < 10; die) {}', "for (\$i = 1; \$i < 10; {$this->expectedExceptionString}) {\n}"), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/InstanceOfPassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/InstanceOfPassTest.php deleted file mode 100644 index fc4a5b6a5..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/InstanceOfPassTest.php +++ /dev/null @@ -1,76 +0,0 @@ -setPass(new InstanceOfPass()); - } - - /** - * @dataProvider invalidStatements - * @expectedException \Psy\Exception\FatalErrorException - */ - public function testProcessInvalidStatement($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidStatements() - { - return array( - array('null instanceof stdClass'), - array('true instanceof stdClass'), - array('9 instanceof stdClass'), - array('1.0 instanceof stdClass'), - array('"foo" instanceof stdClass'), - array('__DIR__ instanceof stdClass'), - array('PHP_SAPI instanceof stdClass'), - array('1+1 instanceof stdClass'), - array('true && false instanceof stdClass'), - array('"a"."b" instanceof stdClass'), - array('!5 instanceof stdClass'), - ); - } - - /** - * @dataProvider validStatements - */ - public function testProcessValidStatement($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validStatements() - { - $data = array( - array('$a instanceof stdClass'), - array('strtolower("foo") instanceof stdClass'), - array('array(1) instanceof stdClass'), - array('(string) "foo" instanceof stdClass'), - array('(1+1) instanceof stdClass'), - array('"foo ${foo} $bar" instanceof stdClass'), - array('DateTime::ISO8601 instanceof stdClass'), - ); - - return $data; - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LegacyEmptyPassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LegacyEmptyPassTest.php deleted file mode 100644 index d4fbd8b70..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LegacyEmptyPassTest.php +++ /dev/null @@ -1,80 +0,0 @@ -setPass(new LegacyEmptyPass()); - } - - /** - * @dataProvider invalidStatements - * @expectedException \Psy\Exception\ParseErrorException - */ - public function testProcessInvalidStatement($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidStatements() - { - if (version_compare(PHP_VERSION, '5.5', '>=')) { - return array( - array('empty()'), - ); - } - - return array( - array('empty()'), - array('empty(null)'), - array('empty(PHP_EOL)'), - array('empty("wat")'), - array('empty(1.1)'), - array('empty(Foo::$bar)'), - ); - } - - /** - * @dataProvider validStatements - */ - public function testProcessValidStatement($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validStatements() - { - if (version_compare(PHP_VERSION, '5.5', '<')) { - return array( - array('empty($foo)'), - ); - } - - return array( - array('empty($foo)'), - array('empty(null)'), - array('empty(PHP_EOL)'), - array('empty("wat")'), - array('empty(1.1)'), - array('empty(Foo::$bar)'), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LoopContextPassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LoopContextPassTest.php deleted file mode 100644 index 7f261dfac..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/LoopContextPassTest.php +++ /dev/null @@ -1,137 +0,0 @@ -pass = new LoopContextPass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); - } - - /** - * @dataProvider invalidStatements - * @expectedException \Psy\Exception\FatalErrorException - */ - public function testProcessStatementFails($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidStatements() - { - return array( - array('continue'), - array('break'), - array('if (true) { continue; }'), - array('if (true) { break; }'), - array('if (false) { continue; }'), - array('if (false) { break; }'), - array('function foo() { break; }'), - array('function foo() { continue; }'), - - // actually enforce break/continue depth argument - array('do { break 2; } while (true)'), - array('do { continue 2; } while (true)'), - array('for ($a; $b; $c) { break 2; }'), - array('for ($a; $b; $c) { continue 2; }'), - array('foreach ($a as $b) { break 2; }'), - array('foreach ($a as $b) { continue 2; }'), - array('switch (true) { default: break 2; }'), - array('switch (true) { default: continue 2; }'), - array('while (true) { break 2; }'), - array('while (true) { continue 2; }'), - - // invalid in 5.4+ because they're floats - // ... in 5.3 because the number is too big - array('while (true) { break 2.0; }'), - array('while (true) { continue 2.0; }'), - - // and once with nested loops, just for good measure - array('while (true) { while (true) { break 3; } }'), - array('while (true) { while (true) { continue 3; } }'), - ); - } - - /** - * @dataProvider invalidPHP54Statements - * @expectedException \Psy\Exception\FatalErrorException - */ - public function testPHP54ProcessStatementFails($code) - { - if (version_compare(PHP_VERSION, '5.4.0', '<')) { - $this->markTestSkipped(); - } - - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidPHP54Statements() - { - return array( - // In PHP 5.4+, only positive literal integers are allowed - array('while (true) { break $n; }'), - array('while (true) { continue $n; }'), - array('while (true) { break N; }'), - array('while (true) { continue N; }'), - array('while (true) { break 0; }'), - array('while (true) { continue 0; }'), - array('while (true) { break -1; }'), - array('while (true) { continue -1; }'), - array('while (true) { break 1.0; }'), - array('while (true) { continue 1.0; }'), - ); - } - - /** - * @dataProvider validStatements - */ - public function testProcessStatementPasses($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validStatements() - { - return array( - array('do { break; } while (true)'), - array('do { continue; } while (true)'), - array('for ($a; $b; $c) { break; }'), - array('for ($a; $b; $c) { continue; }'), - array('foreach ($a as $b) { break; }'), - array('foreach ($a as $b) { continue; }'), - array('switch (true) { default: break; }'), - array('switch (true) { default: continue; }'), - array('while (true) { break; }'), - array('while (true) { continue; }'), - - // `break 1` is redundant, but not invalid - array('while (true) { break 1; }'), - array('while (true) { continue 1; }'), - - // and once with nested loops just for good measure - array('while (true) { while (true) { break 2; } }'), - array('while (true) { while (true) { continue 2; } }'), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/NamespacePassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/NamespacePassTest.php deleted file mode 100644 index 553a699a7..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/NamespacePassTest.php +++ /dev/null @@ -1,56 +0,0 @@ -cleaner = new CodeCleaner(); - $this->setPass(new NamespacePass($this->cleaner)); - } - - public function testProcess() - { - $this->process('array_merge()'); - $this->assertNull($this->cleaner->getNamespace()); - - // A non-block namespace statement should set the current namespace. - $this->process('namespace Alpha'); - $this->assertEquals(array('Alpha'), $this->cleaner->getNamespace()); - - // A new non-block namespace statement should override the current namespace. - $this->process('namespace Beta; class B {}'); - $this->assertEquals(array('Beta'), $this->cleaner->getNamespace()); - - // @todo Figure out if we can detect when the last namespace block is - // bracketed or unbracketed, because this should really clear the - // namespace at the end... - $this->process('namespace Gamma { array_merge(); }'); - $this->assertEquals(array('Gamma'), $this->cleaner->getNamespace()); - - // A null namespace clears out the current namespace. - $this->process('namespace { array_merge(); }'); - $this->assertNull($this->cleaner->getNamespace()); - } - - private function process($code) - { - $stmts = $this->parse($code); - $this->traverse($stmts); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/PassableByReferencePassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/PassableByReferencePassTest.php deleted file mode 100644 index 94843d996..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/PassableByReferencePassTest.php +++ /dev/null @@ -1,115 +0,0 @@ -pass = new PassableByReferencePass(); - $this->traverser = new NodeTraverser(); - $this->traverser->addVisitor($this->pass); - } - - /** - * @dataProvider invalidStatements - * @expectedException \Psy\Exception\FatalErrorException - */ - public function testProcessStatementFails($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidStatements() - { - return array( - array('array_pop(array())'), - array('array_pop(array($foo))'), - array('array_shift(array())'), - ); - } - - /** - * @dataProvider validStatements - */ - public function testProcessStatementPasses($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validStatements() - { - return array( - array('array_pop(json_decode("[]"))'), - array('array_pop($foo)'), - array('array_pop($foo->bar)'), - array('array_pop($foo::baz)'), - array('array_pop(Foo::qux)'), - ); - } - - /** - * @dataProvider validArrayMultisort - */ - public function testArrayMultisort($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validArrayMultisort() - { - return array( - array('array_multisort($a)'), - array('array_multisort($a, $b)'), - array('array_multisort($a, SORT_NATURAL, $b)'), - array('array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, $b)'), - array('array_multisort($a, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE, $b)'), - array('array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, SORT_ASC, $b)'), - array('array_multisort($a, $b, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE)'), - array('array_multisort($a, SORT_NATURAL | SORT_FLAG_CASE, $b, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE)'), - array('array_multisort($a, 1, $b)'), - array('array_multisort($a, 1 + 2, $b)'), - array('array_multisort($a, getMultisortFlags(), $b)'), - ); - } - - /** - * @dataProvider invalidArrayMultisort - * @expectedException \Psy\Exception\FatalErrorException - */ - public function testInvalidArrayMultisort($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidArrayMultisort() - { - return array( - array('array_multisort(1)'), - array('array_multisort(array(1, 2, 3))'), - array('array_multisort($a, SORT_NATURAL, SORT_ASC, SORT_NATURAL, $b)'), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/RequirePassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/RequirePassTest.php deleted file mode 100644 index c7a68f249..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/RequirePassTest.php +++ /dev/null @@ -1,95 +0,0 @@ -setPass(new RequirePass()); - } - - /** - * @dataProvider exitStatements - */ - public function testExitStatement($from, $to) - { - $this->assertProcessesAs($from, $to); - } - - public function exitStatements() - { - $resolve = '\\Psy\\CodeCleaner\\RequirePass::resolve'; - - if (version_compare(PHP_VERSION, '5.4', '<')) { - return array( - array('require $foo', "require $resolve(\$foo, 1);"), - array('$bar = require $baz', "\$bar = (require $resolve(\$baz, 1));"), - ); - } - - return array( - // The basics - array('require "a"', "require $resolve(\"a\", 1);"), - array('require "b.php"', "require $resolve(\"b.php\", 1);"), - array('require_once "c"', "require_once $resolve(\"c\", 1);"), - array('require_once "d.php"', "require_once $resolve(\"d.php\", 1);"), - - // Ensure that line numbers work correctly - array("null;\nrequire \"e.php\"", "null;\nrequire $resolve(\"e.php\", 2);"), - array("null;\nrequire_once \"f.php\"", "null;\nrequire_once $resolve(\"f.php\", 2);"), - - // Things with expressions - array('require $foo', "require $resolve(\$foo, 1);"), - array('require_once $foo', "require_once $resolve(\$foo, 1);"), - array('require ($bar = "g.php")', "require $resolve(\$bar = \"g.php\", 1);"), - array('require_once ($bar = "h.php")', "require_once $resolve(\$bar = \"h.php\", 1);"), - array('$bar = require ($baz = "i.php")', "\$bar = (require $resolve(\$baz = \"i.php\", 1));"), - array('$bar = require_once ($baz = "j.php")', "\$bar = (require_once $resolve(\$baz = \"j.php\", 1));"), - ); - } - - /** - * @expectedException \Psy\Exception\FatalErrorException - * @expectedExceptionMessage Failed opening required 'not a file name' in eval()'d code on line 2 - */ - public function testResolve() - { - RequirePass::resolve('not a file name', 2); - } - - /** - * @dataProvider emptyWarnings - * - * @expectedException \Psy\Exception\ErrorException - * @expectedExceptionMessage Filename cannot be empty on line 1 - */ - public function testResolveEmptyWarnings($file) - { - if (!E_WARNING & error_reporting()) { - $this->markTestSkipped(); - } - - RequirePass::resolve($file, 1); - } - - public function emptyWarnings() - { - return array( - array(null), - array(false), - array(''), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StaticConstructorPassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StaticConstructorPassTest.php deleted file mode 100644 index 0ba72380f..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/StaticConstructorPassTest.php +++ /dev/null @@ -1,94 +0,0 @@ -setPass(new StaticConstructorPass()); - } - - /** - * @dataProvider invalidStatements - * @expectedException \Psy\Exception\FatalErrorException - */ - public function testProcessInvalidStatement($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - /** - * @dataProvider invalidParserStatements - * @expectedException \Psy\Exception\ParseErrorException - */ - public function testProcessInvalidStatementCatchedByParser($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - } - - public function invalidStatements() - { - $statements = array( - array('class A { public static function A() {}}'), - array('class A { private static function A() {}}'), - ); - - if (version_compare(PHP_VERSION, '5.3.3', '<')) { - $statements[] = array('namespace B; class A { private static function A() {}}'); - } - - return $statements; - } - - public function invalidParserStatements() - { - $statements = array( - array('class A { public static function __construct() {}}'), - array('class A { private static function __construct() {}}'), - array('class A { private static function __construct() {} public function A() {}}'), - array('namespace B; class A { private static function __construct() {}}'), - ); - - return $statements; - } - - /** - * @dataProvider validStatements - */ - public function testProcessValidStatement($code) - { - $stmts = $this->parse($code); - $this->traverser->traverse($stmts); - - // @todo a better thing to assert here? - $this->assertTrue(true); - } - - public function validStatements() - { - $statements = array( - array('class A { public static function A() {} public function __construct() {}}'), - array('class A { private function __construct() {} public static function A() {}}'), - ); - - if (version_compare(PHP_VERSION, '5.3.3', '>=')) { - $statements[] = array('namespace B; class A { private static function A() {}}'); - } - - return $statements; - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/UseStatementPassTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/UseStatementPassTest.php deleted file mode 100644 index 9c525efef..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleaner/UseStatementPassTest.php +++ /dev/null @@ -1,52 +0,0 @@ -setPass(new UseStatementPass()); - } - - /** - * @dataProvider useStatements - */ - public function testProcess($from, $to) - { - $this->assertProcessesAs($from, $to); - } - - public function useStatements() - { - return array( - array( - "use StdClass as NotSoStd;\n\$std = new NotSoStd();", - '$std = new \\StdClass();', - ), - array( - "namespace Foo;\n\nuse StdClass as S;\n\$std = new S();", - "namespace Foo;\n\n\$std = new \\StdClass();", - ), - array( - "namespace Foo;\n\nuse \\StdClass as S;\n\$std = new S();", - "namespace Foo;\n\n\$std = new \\StdClass();", - ), - array( - "use Foo\\Bar as fb;\n\$baz = new fb\\Baz();", - '$baz = new \\Foo\\Bar\\Baz();', - ), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/CodeCleanerTest.php b/app/vendor/psy/psysh/test/Psy/Test/CodeCleanerTest.php deleted file mode 100644 index f46b6da13..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/CodeCleanerTest.php +++ /dev/null @@ -1,132 +0,0 @@ -assertEquals($expected, $cc->clean($lines, $requireSemicolons)); - } - - public function semicolonCodeProvider() - { - $values = array( - array(array('true'), false, 'return true;'), - array(array('true;'), false, 'return true;'), - array(array('true;'), true, 'return true;'), - array(array('true'), true, false), - - array(array('echo "foo";', 'true'), true, false), - ); - - if (version_compare(PHP_VERSION, '5.4', '<')) { - $values[] = array(array('echo "foo";', 'true'), false, "echo 'foo';\nreturn true;"); - } else { - $values[] = array(array('echo "foo";', 'true'), false, "echo \"foo\";\nreturn true;"); - } - - return $values; - } - - /** - * @dataProvider unclosedStatementsProvider - */ - public function testUnclosedStatements(array $lines, $isUnclosed) - { - $cc = new CodeCleaner(); - $res = $cc->clean($lines); - - if ($isUnclosed) { - $this->assertFalse($res); - } else { - $this->assertNotFalse($res); - } - } - - public function unclosedStatementsProvider() - { - return array( - array(array('echo "'), true), - array(array('echo \''), true), - array(array('if (1) {'), true), - - array(array('echo ""'), false), - array(array("echo ''"), false), - array(array('if (1) {}'), false), - - array(array('// closed comment'), false), - array(array('function foo() { /**'), true), - - array(array('var_dump(1, 2,'), true), - array(array('var_dump(1, 2,', '3)'), false), - ); - } - - /** - * @dataProvider moreUnclosedStatementsProvider - */ - public function testMoreUnclosedStatements(array $lines) - { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('HHVM not supported.'); - } - - $cc = new CodeCleaner(); - $res = $cc->clean($lines); - - $this->assertFalse($res); - } - - public function moreUnclosedStatementsProvider() - { - return array( - array(array("\$content = <<clean(array($code)); - } - - public function invalidStatementsProvider() - { - return array( - array('function "what'), - array("function 'what"), - array('echo }'), - array('echo {'), - array('if (1) }'), - array('echo """'), - array("echo '''"), - array('$foo "bar'), - array('$foo \'bar'), - array('var_dump(1,2,)'), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/Formatter/CodeFormatterTest.php b/app/vendor/psy/psysh/test/Psy/Test/Formatter/CodeFormatterTest.php deleted file mode 100644 index 7f1635e55..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/Formatter/CodeFormatterTest.php +++ /dev/null @@ -1,65 +0,0 @@ - 18| private function ignoreThisMethod($arg) - 19| { - 20| echo 'whot!'; - 21| } -EOS; - - $formatted = CodeFormatter::format(new \ReflectionMethod($this, 'ignoreThisMethod')); - $formattedWithoutColors = preg_replace('#' . chr(27) . '\[\d\d?m#', '', $formatted); - - $this->assertEquals($expected, rtrim($formattedWithoutColors)); - $this->assertNotEquals($expected, rtrim($formatted)); - } - - /** - * @dataProvider filenames - * @expectedException \Psy\Exception\RuntimeException - */ - public function testCodeFormatterThrowsException($filename) - { - $reflector = $this->getMockBuilder('ReflectionClass') - ->disableOriginalConstructor() - ->getMock(); - - $reflector - ->expects($this->once()) - ->method('getFileName') - ->will($this->returnValue($filename)); - - CodeFormatter::format($reflector); - } - - public function filenames() - { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('We have issues with PHPUnit mocks on HHVM.'); - } - - return array(array(null), array('not a file')); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/Input/ShellInputTest.php b/app/vendor/psy/psysh/test/Psy/Test/Input/ShellInputTest.php deleted file mode 100644 index 98a89779e..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/Input/ShellInputTest.php +++ /dev/null @@ -1,204 +0,0 @@ -getProperty('tokenPairs'); - $p->setAccessible(true); - $this->assertEquals($tokens, $p->getValue($input), $message); - } - - public function testInputOptionWithGivenString() - { - $definition = new InputDefinition(array( - new InputOption('foo', null, InputOption::VALUE_REQUIRED), - new CodeArgument('code', null, InputOption::VALUE_REQUIRED), - )); - - $input = new ShellInput('--foo=bar echo "baz\n";'); - $input->bind($definition); - $this->assertEquals('bar', $input->getOption('foo')); - $this->assertEquals('echo "baz\n";', $input->getArgument('code')); - } - - public function testInputOptionWithoutCodeArguments() - { - $definition = new InputDefinition(array( - new InputOption('foo', null, InputOption::VALUE_REQUIRED), - new InputArgument('bar', null, InputOption::VALUE_REQUIRED), - new InputArgument('baz', null, InputOption::VALUE_REQUIRED), - )); - - $input = new ShellInput('--foo=foo bar "baz\n"'); - $input->bind($definition); - $this->assertEquals('foo', $input->getOption('foo')); - $this->assertEquals('bar', $input->getArgument('bar')); - $this->assertEquals("baz\n", $input->getArgument('baz')); - } - - public function getTokenizeData() - { - // Test all the cases from StringInput test, ensuring they have an appropriate $rest token. - return array( - array( - '', - array(), - '->tokenize() parses an empty string', - ), - array( - 'foo', - array(array('foo', 'foo')), - '->tokenize() parses arguments', - ), - array( - ' foo bar ', - array(array('foo', 'foo bar '), array('bar', 'bar ')), - '->tokenize() ignores whitespaces between arguments', - ), - array( - '"quoted"', - array(array('quoted', '"quoted"')), - '->tokenize() parses quoted arguments', - ), - array( - "'quoted'", - array(array('quoted', "'quoted'")), - '->tokenize() parses quoted arguments', - ), - array( - "'a\rb\nc\td'", - array(array("a\rb\nc\td", "'a\rb\nc\td'")), - '->tokenize() parses whitespace chars in strings', - ), - array( - "'a'\r'b'\n'c'\t'd'", - array( - array('a', "'a'\r'b'\n'c'\t'd'"), - array('b', "'b'\n'c'\t'd'"), - array('c', "'c'\t'd'"), - array('d', "'d'"), - ), - '->tokenize() parses whitespace chars between args as spaces', - ), - array( - '\"quoted\"', - array(array('"quoted"', '\"quoted\"')), - '->tokenize() parses escaped-quoted arguments', - ), - array( - "\'quoted\'", - array(array('\'quoted\'', "\'quoted\'")), - '->tokenize() parses escaped-quoted arguments', - ), - array( - '-a', - array(array('-a', '-a')), - '->tokenize() parses short options', - ), - array( - '-azc', - array(array('-azc', '-azc')), - '->tokenize() parses aggregated short options', - ), - array( - '-awithavalue', - array(array('-awithavalue', '-awithavalue')), - '->tokenize() parses short options with a value', - ), - array( - '-a"foo bar"', - array(array('-afoo bar', '-a"foo bar"')), - '->tokenize() parses short options with a value', - ), - array( - '-a"foo bar""foo bar"', - array(array('-afoo barfoo bar', '-a"foo bar""foo bar"')), - '->tokenize() parses short options with a value', - ), - array( - '-a\'foo bar\'', - array(array('-afoo bar', '-a\'foo bar\'')), - '->tokenize() parses short options with a value', - ), - array( - '-a\'foo bar\'\'foo bar\'', - array(array('-afoo barfoo bar', '-a\'foo bar\'\'foo bar\'')), - '->tokenize() parses short options with a value', - ), - array( - '-a\'foo bar\'"foo bar"', - array(array('-afoo barfoo bar', '-a\'foo bar\'"foo bar"')), - '->tokenize() parses short options with a value', - ), - array( - '--long-option', - array(array('--long-option', '--long-option')), - '->tokenize() parses long options', - ), - array( - '--long-option=foo', - array(array('--long-option=foo', '--long-option=foo')), - '->tokenize() parses long options with a value', - ), - array( - '--long-option="foo bar"', - array(array('--long-option=foo bar', '--long-option="foo bar"')), - '->tokenize() parses long options with a value', - ), - array( - '--long-option="foo bar""another"', - array(array('--long-option=foo baranother', '--long-option="foo bar""another"')), - '->tokenize() parses long options with a value', - ), - array( - '--long-option=\'foo bar\'', - array(array('--long-option=foo bar', '--long-option=\'foo bar\'')), - '->tokenize() parses long options with a value', - ), - array( - "--long-option='foo bar''another'", - array(array('--long-option=foo baranother', "--long-option='foo bar''another'")), - '->tokenize() parses long options with a value', - ), - array( - "--long-option='foo bar'\"another\"", - array(array('--long-option=foo baranother', "--long-option='foo bar'\"another\"")), - '->tokenize() parses long options with a value', - ), - array( - 'foo -a -ffoo --long bar', - array( - array('foo', 'foo -a -ffoo --long bar'), - array('-a', '-a -ffoo --long bar'), - array('-ffoo', '-ffoo --long bar'), - array('--long', '--long bar'), - array('bar', 'bar'), - ), - '->tokenize() parses when several arguments and options', - ), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/Reflection/ReflectionConstantTest.php b/app/vendor/psy/psysh/test/Psy/Test/Reflection/ReflectionConstantTest.php deleted file mode 100644 index 60164f71a..000000000 --- a/app/vendor/psy/psysh/test/Psy/Test/Reflection/ReflectionConstantTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getDeclaringClass(); - - $this->assertTrue($class instanceof \ReflectionClass); - $this->assertEquals('Psy\Test\Reflection\ReflectionConstantTest', $class->getName()); - $this->assertEquals('CONSTANT_ONE', $refl->getName()); - $this->assertEquals('CONSTANT_ONE', (string) $refl); - $this->assertEquals('one', $refl->getValue()); - $this->assertEquals(null, $refl->getFileName()); - $this->assertFalse($refl->getDocComment()); - } - - /** - * @expectedException \InvalidArgumentException - */ - public function testUnknownConstantThrowsException() - { - new ReflectionConstant($this, 'UNKNOWN_CONSTANT'); - } - - /** - * @expectedException \RuntimeException - * @dataProvider notYetImplemented - */ - public function testNotYetImplemented($method) - { - $refl = new ReflectionConstant($this, 'CONSTANT_ONE'); - $refl->$method(); - } - - public function notYetImplemented() - { - return array( - array('getStartLine'), - array('getEndLine'), - array('export'), - ); - } -} diff --git a/app/vendor/psy/psysh/test/Psy/Test/Readline/GNUReadlineTest.php b/app/vendor/psy/psysh/test/Readline/GNUReadlineTest.php similarity index 70% rename from app/vendor/psy/psysh/test/Psy/Test/Readline/GNUReadlineTest.php rename to app/vendor/psy/psysh/test/Readline/GNUReadlineTest.php index 95a40e7c8..406377fcc 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Readline/GNUReadlineTest.php +++ b/app/vendor/psy/psysh/test/Readline/GNUReadlineTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,8 +23,8 @@ public function setUp() $this->markTestSkipped('GNUReadline not enabled'); } - $this->historyFile = tempnam(sys_get_temp_dir(), 'psysh_test_history'); - file_put_contents($this->historyFile, "_HiStOrY_V2_\n"); + $this->historyFile = \tempnam(\sys_get_temp_dir(), 'psysh_test_history'); + \file_put_contents($this->historyFile, "_HiStOrY_V2_\n"); } public function testHistory() @@ -32,11 +32,11 @@ public function testHistory() $readline = new GNUReadline($this->historyFile); $this->assertEmpty($readline->listHistory()); $readline->addHistory('foo'); - $this->assertEquals(array('foo'), $readline->listHistory()); + $this->assertSame(['foo'], $readline->listHistory()); $readline->addHistory('bar'); - $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $this->assertSame(['foo', 'bar'], $readline->listHistory()); $readline->addHistory('baz'); - $this->assertEquals(array('foo', 'bar', 'baz'), $readline->listHistory()); + $this->assertSame(['foo', 'bar', 'baz'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } @@ -50,11 +50,11 @@ public function testHistorySize() $this->assertEmpty($readline->listHistory()); $readline->addHistory('foo'); $readline->addHistory('bar'); - $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $this->assertSame(['foo', 'bar'], $readline->listHistory()); $readline->addHistory('baz'); - $this->assertEquals(array('bar', 'baz'), $readline->listHistory()); + $this->assertSame(['bar', 'baz'], $readline->listHistory()); $readline->addHistory('w00t'); - $this->assertEquals(array('baz', 'w00t'), $readline->listHistory()); + $this->assertSame(['baz', 'w00t'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } @@ -69,11 +69,11 @@ public function testHistoryEraseDups() $readline->addHistory('foo'); $readline->addHistory('bar'); $readline->addHistory('foo'); - $this->assertEquals(array('bar', 'foo'), $readline->listHistory()); + $this->assertSame(['bar', 'foo'], $readline->listHistory()); $readline->addHistory('baz'); $readline->addHistory('w00t'); $readline->addHistory('baz'); - $this->assertEquals(array('bar', 'foo', 'w00t', 'baz'), $readline->listHistory()); + $this->assertSame(['bar', 'foo', 'w00t', 'baz'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } diff --git a/app/vendor/psy/psysh/test/Psy/Test/Readline/HoaConsoleTest.php b/app/vendor/psy/psysh/test/Readline/HoaConsoleTest.php similarity index 73% rename from app/vendor/psy/psysh/test/Psy/Test/Readline/HoaConsoleTest.php rename to app/vendor/psy/psysh/test/Readline/HoaConsoleTest.php index 707837d8f..ecf444f39 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Readline/HoaConsoleTest.php +++ b/app/vendor/psy/psysh/test/Readline/HoaConsoleTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,11 +20,11 @@ public function testHistory() $readline = new HoaConsole(); $this->assertEmpty($readline->listHistory()); $readline->addHistory('foo'); - $this->assertEquals(array('foo'), $readline->listHistory()); + $this->assertSame(['foo'], $readline->listHistory()); $readline->addHistory('bar'); - $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $this->assertSame(['foo', 'bar'], $readline->listHistory()); $readline->addHistory('baz'); - $this->assertEquals(array('foo', 'bar', 'baz'), $readline->listHistory()); + $this->assertSame(['foo', 'bar', 'baz'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } diff --git a/app/vendor/psy/psysh/test/Psy/Test/Readline/LibeditTest.php b/app/vendor/psy/psysh/test/Readline/LibeditTest.php similarity index 71% rename from app/vendor/psy/psysh/test/Psy/Test/Readline/LibeditTest.php rename to app/vendor/psy/psysh/test/Readline/LibeditTest.php index fb0aaa598..2d7be2889 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Readline/LibeditTest.php +++ b/app/vendor/psy/psysh/test/Readline/LibeditTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -23,20 +23,20 @@ public function setUp() $this->markTestSkipped('Libedit not enabled'); } - $this->historyFile = tempnam(sys_get_temp_dir(), 'psysh_test_history'); - if (false === file_put_contents($this->historyFile, "_HiStOrY_V2_\n")) { + $this->historyFile = \tempnam(\sys_get_temp_dir(), 'psysh_test_history'); + if (false === \file_put_contents($this->historyFile, "_HiStOrY_V2_\n")) { $this->fail('Unable to write history file: ' . $this->historyFile); } // Calling readline_read_history before readline_clear_history // avoids segfault with PHP 5.5.7 & libedit v3.1 - readline_read_history($this->historyFile); - readline_clear_history(); + \readline_read_history($this->historyFile); + \readline_clear_history(); } public function tearDown() { - if (is_file($this->historyFile)) { - unlink($this->historyFile); + if (\is_file($this->historyFile)) { + \unlink($this->historyFile); } } @@ -45,11 +45,11 @@ public function testHistory() $readline = new Libedit($this->historyFile); $this->assertEmpty($readline->listHistory()); $readline->addHistory('foo'); - $this->assertEquals(array('foo'), $readline->listHistory()); + $this->assertSame(['foo'], $readline->listHistory()); $readline->addHistory('bar'); - $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $this->assertSame(['foo', 'bar'], $readline->listHistory()); $readline->addHistory('baz'); - $this->assertEquals(array('foo', 'bar', 'baz'), $readline->listHistory()); + $this->assertSame(['foo', 'bar', 'baz'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } @@ -63,11 +63,11 @@ public function testHistorySize() $this->assertEmpty($readline->listHistory()); $readline->addHistory('foo'); $readline->addHistory('bar'); - $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $this->assertSame(['foo', 'bar'], $readline->listHistory()); $readline->addHistory('baz'); - $this->assertEquals(array('bar', 'baz'), $readline->listHistory()); + $this->assertSame(['bar', 'baz'], $readline->listHistory()); $readline->addHistory('w00t'); - $this->assertEquals(array('baz', 'w00t'), $readline->listHistory()); + $this->assertSame(['baz', 'w00t'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } @@ -82,11 +82,11 @@ public function testHistoryEraseDups() $readline->addHistory('foo'); $readline->addHistory('bar'); $readline->addHistory('foo'); - $this->assertEquals(array('bar', 'foo'), $readline->listHistory()); + $this->assertSame(['bar', 'foo'], $readline->listHistory()); $readline->addHistory('baz'); $readline->addHistory('w00t'); $readline->addHistory('baz'); - $this->assertEquals(array('bar', 'foo', 'w00t', 'baz'), $readline->listHistory()); + $this->assertSame(['bar', 'foo', 'w00t', 'baz'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } @@ -94,15 +94,15 @@ public function testHistoryEraseDups() public function testListHistory() { $readline = new Libedit($this->historyFile); - file_put_contents( + \file_put_contents( $this->historyFile, "This is an entry\n\0This is a comment\nThis is an entry\0With a comment\n", FILE_APPEND ); - $this->assertEquals(array( + $this->assertSame([ 'This is an entry', 'This is an entry', - ), $readline->listHistory()); + ], $readline->listHistory()); $readline->clearHistory(); } @@ -113,16 +113,16 @@ public function testListHistory() public function testLinebreaksSupport() { $readline = new Libedit($this->historyFile); - file_put_contents( + \file_put_contents( $this->historyFile, "foo\rbar\nbaz\r\nw00t", FILE_APPEND ); - $this->assertEquals(array( + $this->assertSame([ "foo\rbar", "baz\r", 'w00t', - ), $readline->listHistory()); + ], $readline->listHistory()); $readline->clearHistory(); } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/Readline/TransientTest.php b/app/vendor/psy/psysh/test/Readline/TransientTest.php similarity index 74% rename from app/vendor/psy/psysh/test/Psy/Test/Readline/TransientTest.php rename to app/vendor/psy/psysh/test/Readline/TransientTest.php index 24eafbaf4..24fcba0b2 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Readline/TransientTest.php +++ b/app/vendor/psy/psysh/test/Readline/TransientTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,11 +20,11 @@ public function testHistory() $readline = new Transient(); $this->assertEmpty($readline->listHistory()); $readline->addHistory('foo'); - $this->assertEquals(array('foo'), $readline->listHistory()); + $this->assertSame(['foo'], $readline->listHistory()); $readline->addHistory('bar'); - $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $this->assertSame(['foo', 'bar'], $readline->listHistory()); $readline->addHistory('baz'); - $this->assertEquals(array('foo', 'bar', 'baz'), $readline->listHistory()); + $this->assertSame(['foo', 'bar', 'baz'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } @@ -38,11 +38,11 @@ public function testHistorySize() $this->assertEmpty($readline->listHistory()); $readline->addHistory('foo'); $readline->addHistory('bar'); - $this->assertEquals(array('foo', 'bar'), $readline->listHistory()); + $this->assertSame(['foo', 'bar'], $readline->listHistory()); $readline->addHistory('baz'); - $this->assertEquals(array('bar', 'baz'), $readline->listHistory()); + $this->assertSame(['bar', 'baz'], $readline->listHistory()); $readline->addHistory('w00t'); - $this->assertEquals(array('baz', 'w00t'), $readline->listHistory()); + $this->assertSame(['baz', 'w00t'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } @@ -57,11 +57,11 @@ public function testHistoryEraseDups() $readline->addHistory('foo'); $readline->addHistory('bar'); $readline->addHistory('foo'); - $this->assertEquals(array('bar', 'foo'), $readline->listHistory()); + $this->assertSame(['bar', 'foo'], $readline->listHistory()); $readline->addHistory('baz'); $readline->addHistory('w00t'); $readline->addHistory('baz'); - $this->assertEquals(array('bar', 'foo', 'w00t', 'baz'), $readline->listHistory()); + $this->assertSame(['bar', 'foo', 'w00t', 'baz'], $readline->listHistory()); $readline->clearHistory(); $this->assertEmpty($readline->listHistory()); } diff --git a/app/vendor/psy/psysh/test/Reflection/ReflectionClassConstantTest.php b/app/vendor/psy/psysh/test/Reflection/ReflectionClassConstantTest.php new file mode 100644 index 000000000..87d4f7520 --- /dev/null +++ b/app/vendor/psy/psysh/test/Reflection/ReflectionClassConstantTest.php @@ -0,0 +1,81 @@ +getDeclaringClass(); + + $this->assertInstanceOf('ReflectionClass', $class); + $this->assertSame('Psy\Test\Reflection\ReflectionClassConstantTest', $class->getName()); + $this->assertSame('CONSTANT_ONE', $refl->getName()); + $this->assertSame('CONSTANT_ONE', (string) $refl); + $this->assertSame('one', $refl->getValue()); + $this->assertNull($refl->getFileName()); + $this->assertFalse($refl->getDocComment()); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testUnknownConstantThrowsException() + { + new ReflectionClassConstant($this, 'UNKNOWN_CONSTANT'); + } + + public function testExport() + { + $ret = ReflectionClassConstant::export($this, 'CONSTANT_ONE', true); + $this->assertEquals($ret, 'Constant [ public string CONSTANT_ONE ] { one }'); + } + + public function testExportOutput() + { + $this->expectOutputString("Constant [ public string CONSTANT_ONE ] { one }\n"); + ReflectionClassConstant::export($this, 'CONSTANT_ONE', false); + } + + public function testModifiers() + { + $refl = new ReflectionClassConstant($this, 'CONSTANT_ONE'); + + $this->assertEquals(\ReflectionMethod::IS_PUBLIC, $refl->getModifiers()); + $this->assertFalse($refl->isPrivate()); + $this->assertFalse($refl->isProtected()); + $this->assertTrue($refl->isPublic()); + } + + /** + * @expectedException \RuntimeException + * @dataProvider notYetImplemented + */ + public function testNotYetImplemented($method) + { + $refl = new ReflectionClassConstant($this, 'CONSTANT_ONE'); + $refl->$method(); + } + + public function notYetImplemented() + { + return [ + ['getStartLine'], + ['getEndLine'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Reflection/ReflectionConstantBCTest.php b/app/vendor/psy/psysh/test/Reflection/ReflectionConstantBCTest.php new file mode 100644 index 000000000..69d279709 --- /dev/null +++ b/app/vendor/psy/psysh/test/Reflection/ReflectionConstantBCTest.php @@ -0,0 +1,26 @@ +assertInstanceOf('Psy\Reflection\ReflectionConstant', $refl); + $this->assertInstanceOf('Psy\Reflection\ReflectionClassConstant', $refl); + } +} diff --git a/app/vendor/psy/psysh/test/Reflection/ReflectionConstantTest.php b/app/vendor/psy/psysh/test/Reflection/ReflectionConstantTest.php new file mode 100644 index 000000000..02c1a8442 --- /dev/null +++ b/app/vendor/psy/psysh/test/Reflection/ReflectionConstantTest.php @@ -0,0 +1,114 @@ +assertFalse($refl->getDocComment()); + $this->assertEquals('Psy\\Test\\Reflection\\SOME_CONSTANT', $refl->getName()); + $this->assertEquals('Psy\\Test\\Reflection', $refl->getNamespaceName()); + $this->assertEquals('yep', $refl->getValue()); + $this->assertTrue($refl->inNamespace()); + $this->assertEquals('Psy\\Test\\Reflection\\SOME_CONSTANT', (string) $refl); + $this->assertNull($refl->getFileName()); + } + + public function testBuiltInConstant() + { + $refl = new ReflectionConstant_('PHP_VERSION'); + + $this->assertEquals('PHP_VERSION', $refl->getName()); + $this->assertEquals('PHP_VERSION', (string) $refl); + $this->assertEquals(PHP_VERSION, $refl->getValue()); + $this->assertFalse($refl->inNamespace()); + $this->assertSame('', $refl->getNamespaceName()); + } + + /** + * @dataProvider magicConstants + */ + public function testIsMagicConstant($name, $is) + { + $this->assertEquals($is, ReflectionConstant_::isMagicConstant($name)); + } + + public function magicConstants() + { + return [ + ['__LINE__', true], + ['__FILE__', true], + ['__DIR__', true], + ['__FUNCTION__', true], + ['__CLASS__', true], + ['__TRAIT__', true], + ['__METHOD__', true], + ['__NAMESPACE__', true], + ['__COMPILER_HALT_OFFSET__', true], + ['PHP_VERSION', false], + ['PHP_EOL', false], + ['Psy\\Test\\Reflection\\SOME_CONSTANT', false], + ['What if it isn\'t even a valid constant name?', false], + ]; + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testUnknownConstantThrowsException() + { + new ReflectionConstant_('UNKNOWN_CONSTANT'); + } + + public function testExport() + { + $ret = ReflectionConstant_::export('Psy\\Test\\Reflection\\SOME_CONSTANT', true); + $this->assertEquals($ret, 'Constant [ string Psy\\Test\\Reflection\\SOME_CONSTANT ] { yep }'); + } + + public function testExportOutput() + { + $this->expectOutputString("Constant [ string Psy\\Test\\Reflection\\SOME_CONSTANT ] { yep }\n"); + ReflectionConstant_::export('Psy\\Test\\Reflection\\SOME_CONSTANT', false); + } + + public function testGetFileName() + { + $refl = new ReflectionConstant_('Psy\\Test\\Reflection\\SOME_CONSTANT'); + $this->assertNull($refl->getFileName()); + } + + /** + * @expectedException \RuntimeException + * @dataProvider notYetImplemented + */ + public function testNotYetImplemented($method) + { + $refl = new ReflectionConstant_('Psy\\Test\\Reflection\\SOME_CONSTANT'); + $refl->$method(); + } + + public function notYetImplemented() + { + return [ + ['getStartLine'], + ['getEndLine'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Reflection/ReflectionLanguageConstructParameterTest.php b/app/vendor/psy/psysh/test/Reflection/ReflectionLanguageConstructParameterTest.php new file mode 100644 index 000000000..223432f8c --- /dev/null +++ b/app/vendor/psy/psysh/test/Reflection/ReflectionLanguageConstructParameterTest.php @@ -0,0 +1,64 @@ + false, + 'defaultValue' => null, + 'isOptional' => false, + 'isPassedByReference' => false, + ]); + + $this->assertNull($refl->getClass()); + $this->assertEquals('one', $refl->getName()); + $this->assertFalse($refl->isArray()); + $this->assertTrue($refl->isDefaultValueAvailable()); + $this->assertNull($refl->getDefaultValue()); + $this->assertFalse($refl->isOptional()); + $this->assertFalse($refl->isPassedByReference()); + + $reflTwo = new ReflectionLanguageConstructParameter($keyword, 'two', [ + 'isArray' => true, + 'isOptional' => true, + 'isPassedByReference' => true, + ]); + + $this->assertNull($refl->getClass()); + $this->assertEquals('two', $reflTwo->getName()); + $this->assertTrue($reflTwo->isArray()); + $this->assertFalse($reflTwo->isDefaultValueAvailable()); + $this->assertNull($reflTwo->getDefaultValue()); + $this->assertTrue($reflTwo->isOptional()); + $this->assertTrue($reflTwo->isPassedByReference()); + + $refl = new ReflectionLanguageConstructParameter($keyword, 'three', [ + 'defaultValue' => 3, + ]); + + $this->assertNull($refl->getClass()); + $this->assertEquals('three', $refl->getName()); + $this->assertFalse($refl->isArray()); + $this->assertTrue($refl->isDefaultValueAvailable()); + $this->assertEquals(3, $refl->getDefaultValue()); + $this->assertFalse($refl->isOptional()); + $this->assertFalse($refl->isPassedByReference()); + } +} diff --git a/app/vendor/psy/psysh/test/Reflection/ReflectionLanguageConstructTest.php b/app/vendor/psy/psysh/test/Reflection/ReflectionLanguageConstructTest.php new file mode 100644 index 000000000..872a726d6 --- /dev/null +++ b/app/vendor/psy/psysh/test/Reflection/ReflectionLanguageConstructTest.php @@ -0,0 +1,102 @@ +assertEquals($keyword, $refl->getName()); + $this->assertEquals($keyword, (string) $refl); + } + + /** + * @dataProvider languageConstructs + */ + public function testKnownLanguageConstructs($keyword) + { + $this->assertTrue(ReflectionLanguageConstruct::isLanguageConstruct($keyword)); + } + + /** + * @dataProvider languageConstructs + */ + public function testFileName($keyword) + { + $refl = new ReflectionLanguageConstruct($keyword); + $this->assertFalse($refl->getFileName()); + } + + /** + * @dataProvider languageConstructs + */ + public function testReturnsReference($keyword) + { + $refl = new ReflectionLanguageConstruct($keyword); + $this->assertFalse($refl->returnsReference()); + } + + /** + * @dataProvider languageConstructs + */ + public function testGetParameters($keyword) + { + $refl = new ReflectionLanguageConstruct($keyword); + $this->assertNotEmpty($refl->getParameters()); + } + + /** + * @dataProvider languageConstructs + * @expectedException \RuntimeException + */ + public function testExportThrows($keyword) + { + ReflectionLanguageConstruct::export($keyword); + } + + public function languageConstructs() + { + return [ + ['isset'], + ['unset'], + ['empty'], + ['echo'], + ['print'], + ['die'], + ['exit'], + ]; + } + + /** + * @dataProvider unknownLanguageConstructs + * @expectedException \InvalidArgumentException + */ + public function testUnknownLanguageConstructsThrowExceptions($keyword) + { + new ReflectionLanguageConstruct($keyword); + } + + public function unknownLanguageConstructs() + { + return [ + ['async'], + ['await'], + ['comefrom'], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/ShellTest.php b/app/vendor/psy/psysh/test/ShellTest.php similarity index 51% rename from app/vendor/psy/psysh/test/Psy/Test/ShellTest.php rename to app/vendor/psy/psysh/test/ShellTest.php index 01dddc8ee..809af021e 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/ShellTest.php +++ b/app/vendor/psy/psysh/test/ShellTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,12 +20,12 @@ class ShellTest extends \PHPUnit\Framework\TestCase { - private $streams = array(); + private $streams = []; public function tearDown() { foreach ($this->streams as $stream) { - fclose($stream); + \fclose($stream); } } @@ -39,23 +39,26 @@ public function testScopeVariables() $_e = 'ignore this'; $shell = new Shell($this->getConfig()); - $shell->setScopeVariables(compact('one', 'two', 'three', '__psysh__', '_', '_e', 'this')); + $shell->setScopeVariables(\compact('one', 'two', 'three', '__psysh__', '_', '_e', 'this')); $this->assertNotContains('__psysh__', $shell->getScopeVariableNames()); - $this->assertEquals(array('one', 'two', 'three', '_'), $shell->getScopeVariableNames()); - $this->assertEquals('banana', $shell->getScopeVariable('one')); - $this->assertEquals(123, $shell->getScopeVariable('two')); + $this->assertSame(['one', 'two', 'three', '_'], $shell->getScopeVariableNames()); + $this->assertSame('banana', $shell->getScopeVariable('one')); + $this->assertSame(123, $shell->getScopeVariable('two')); $this->assertSame($three, $shell->getScopeVariable('three')); $this->assertNull($shell->getScopeVariable('_')); - $shell->setScopeVariables(array()); - $this->assertEquals(array('_'), $shell->getScopeVariableNames()); + $diff = $shell->getScopeVariablesDiff(['one' => $one, 'two' => 'not two']); + $this->assertSame(['two' => $two, 'three' => $three, '_' => null], $diff); + + $shell->setScopeVariables([]); + $this->assertSame(['_'], $shell->getScopeVariableNames()); $shell->setBoundObject($this); - $this->assertEquals(array('_', 'this'), $shell->getScopeVariableNames()); + $this->assertSame(['_', 'this'], $shell->getScopeVariableNames()); $this->assertSame($this, $shell->getScopeVariable('this')); - $this->assertEquals(array('_' => null), $shell->getScopeVariables(false)); - $this->assertEquals(array('_' => null, 'this' => $this), $shell->getScopeVariables()); + $this->assertSame(['_' => null], $shell->getScopeVariables(false)); + $this->assertSame(['_' => null, 'this' => $this], $shell->getScopeVariables()); } /** @@ -64,44 +67,82 @@ public function testScopeVariables() public function testUnknownScopeVariablesThrowExceptions() { $shell = new Shell($this->getConfig()); - $shell->setScopeVariables(array('foo' => 'FOO', 'bar' => 1)); + $shell->setScopeVariables(['foo' => 'FOO', 'bar' => 1]); $shell->getScopeVariable('baz'); } + public function testIncludesWithScopeVariables() + { + $one = 'banana'; + $two = 123; + $three = new \StdClass(); + $__psysh__ = 'ignore this'; + $_ = 'ignore this'; + $_e = 'ignore this'; + + $config = $this->getConfig(['usePcntl' => false]); + + $shell = new Shell($config); + $shell->setScopeVariables(\compact('one', 'two', 'three', '__psysh__', '_', '_e', 'this')); + $shell->addInput('exit', true); + + // This is super slow and we shouldn't do this :( + $shell->run(null, $this->getOutput()); + + $this->assertNotContains('__psysh__', $shell->getScopeVariableNames()); + $this->assertSame(['one', 'two', 'three', '_', '_e'], $shell->getScopeVariableNames()); + $this->assertSame('banana', $shell->getScopeVariable('one')); + $this->assertSame(123, $shell->getScopeVariable('two')); + $this->assertSame($three, $shell->getScopeVariable('three')); + $this->assertNull($shell->getScopeVariable('_')); + } + public function testIncludes() { - $config = $this->getConfig(array('configFile' => __DIR__ . '/../../fixtures/empty.php')); + $config = $this->getConfig(['configFile' => __DIR__ . '/fixtures/empty.php']); $shell = new Shell($config); $this->assertEmpty($shell->getIncludes()); - $shell->setIncludes(array('foo', 'bar', 'baz')); - $this->assertEquals(array('foo', 'bar', 'baz'), $shell->getIncludes()); + $shell->setIncludes(['foo', 'bar', 'baz']); + $this->assertSame(['foo', 'bar', 'baz'], $shell->getIncludes()); } public function testIncludesConfig() { - $config = $this->getConfig(array( - 'defaultIncludes' => array('/file.php'), - 'configFile' => __DIR__ . '/../../fixtures/empty.php', - )); + $config = $this->getConfig([ + 'defaultIncludes' => ['/file.php'], + 'configFile' => __DIR__ . '/fixtures/empty.php', + ]); $shell = new Shell($config); $includes = $shell->getIncludes(); - $this->assertEquals('/file.php', $includes[0]); + $this->assertSame('/file.php', $includes[0]); } public function testAddMatchersViaConfig() { - $config = $this->getConfig(array( - 'tabCompletionMatchers' => array( - new ClassMethodsMatcher(), - ), - )); + $shell = new FakeShell(); + $matcher = new ClassMethodsMatcher(); + + $config = $this->getConfig([ + 'matchers' => [$matcher], + ]); + $config->setShell($shell); + + $this->assertSame([$matcher], $shell->matchers); + } + + public function testAddMatchersViaConfigAfterShell() + { + $shell = new FakeShell(); + $matcher = new ClassMethodsMatcher(); - $matchers = $config->getTabCompletionMatchers(); + $config = $this->getConfig([]); + $config->setShell($shell); + $config->addMatchers([$matcher]); - $this->assertTrue(array_pop($matchers) instanceof ClassMethodsMatcher); + $this->assertSame([$matcher], $shell->matchers); } public function testRenderingExceptions() @@ -122,8 +163,8 @@ public function testRenderingExceptions() $this->assertFalse($shell->hasCode()); $this->assertEmpty($shell->getCodeBuffer()); - rewind($stream); - $streamContents = stream_get_contents($stream); + \rewind($stream); + $streamContents = \stream_get_contents($stream); $this->assertContains('PHP Parse error', $streamContents); $this->assertContains('message', $streamContents); @@ -137,19 +178,19 @@ public function testHandlingErrors() $stream = $output->getStream(); $shell->setOutput($output); - $oldLevel = error_reporting(); - error_reporting($oldLevel & ~E_USER_NOTICE); + $oldLevel = \error_reporting(); + \error_reporting($oldLevel & ~E_USER_NOTICE); try { $shell->handleError(E_USER_NOTICE, 'wheee', null, 13); } catch (ErrorException $e) { - error_reporting($oldLevel); + \error_reporting($oldLevel); $this->fail('Unexpected error exception'); } - error_reporting($oldLevel); + \error_reporting($oldLevel); - rewind($stream); - $streamContents = stream_get_contents($stream); + \rewind($stream); + $streamContents = \stream_get_contents($stream); $this->assertContains('PHP Notice:', $streamContents); $this->assertContains('wheee', $streamContents); @@ -162,13 +203,13 @@ public function testHandlingErrors() public function testNotHandlingErrors() { $shell = new Shell($this->getConfig()); - $oldLevel = error_reporting(); - error_reporting($oldLevel | E_USER_NOTICE); + $oldLevel = \error_reporting(); + \error_reporting($oldLevel | E_USER_NOTICE); try { $shell->handleError(E_USER_NOTICE, 'wheee', null, 13); } catch (ErrorException $e) { - error_reporting($oldLevel); + \error_reporting($oldLevel); throw $e; } } @@ -179,8 +220,8 @@ public function testVersion() $this->assertInstanceOf('Symfony\Component\Console\Application', $shell); $this->assertContains(Shell::VERSION, $shell->getVersion()); - $this->assertContains(phpversion(), $shell->getVersion()); - $this->assertContains(php_sapi_name(), $shell->getVersion()); + $this->assertContains(PHP_VERSION, $shell->getVersion()); + $this->assertContains(PHP_SAPI, $shell->getVersion()); } public function testCodeBuffer() @@ -198,9 +239,9 @@ public function testCodeBuffer() $shell->addCode('{}'); $code = $shell->flushCode(); $this->assertFalse($shell->hasCode()); - $code = preg_replace('/\s+/', ' ', $code); + $code = \preg_replace('/\s+/', ' ', $code); $this->assertNotNull($code); - $this->assertEquals('class a { } return new \\Psy\\CodeCleaner\\NoReturnValue();', $code); + $this->assertSame('class a { } return new \\Psy\\CodeCleaner\\NoReturnValue();', $code); } public function testKeepCodeBufferOpen() @@ -218,9 +259,9 @@ public function testKeepCodeBufferOpen() $shell->addCode('+ 1'); $code = $shell->flushCode(); $this->assertFalse($shell->hasCode()); - $code = preg_replace('/\s+/', ' ', $code); + $code = \preg_replace('/\s+/', ' ', $code); $this->assertNotNull($code); - $this->assertEquals('return 1 + 1 + 1;', $code); + $this->assertSame('return 1 + 1 + 1;', $code); } /** @@ -241,7 +282,7 @@ public function testClosuresSupport() $shell->flushCode(); $code = '$test()'; $shell->addCode($code); - $this->assertEquals($shell->flushCode(), 'return $test();'); + $this->assertSame($shell->flushCode(), 'return $test();'); } public function testWriteStdout() @@ -253,10 +294,10 @@ public function testWriteStdout() $shell->writeStdout("{{stdout}}\n"); - rewind($stream); - $streamContents = stream_get_contents($stream); + \rewind($stream); + $streamContents = \stream_get_contents($stream); - $this->assertEquals('{{stdout}}' . PHP_EOL, $streamContents); + $this->assertSame('{{stdout}}' . PHP_EOL, $streamContents); } public function testWriteStdoutWithoutNewline() @@ -268,10 +309,10 @@ public function testWriteStdoutWithoutNewline() $shell->writeStdout('{{stdout}}'); - rewind($stream); - $streamContents = stream_get_contents($stream); + \rewind($stream); + $streamContents = \stream_get_contents($stream); - $this->assertEquals('{{stdout}}' . PHP_EOL, $streamContents); + $this->assertSame('{{stdout}}' . PHP_EOL, $streamContents); } /** @@ -285,16 +326,16 @@ public function testWriteReturnValue($input, $expected) $shell->setOutput($output); $shell->writeReturnValue($input); - rewind($stream); - $this->assertEquals($expected, stream_get_contents($stream)); + \rewind($stream); + $this->assertEquals($expected, \stream_get_contents($stream)); } public function getReturnValues() { - return array( - array('{{return value}}', "=> \"\033[32m{{return value}}\033[39m\"" . PHP_EOL), - array(1, "=> \033[35m1\033[39m" . PHP_EOL), - ); + return [ + ['{{return value}}', "=> \"\033[32m{{return value}}\033[39m\"" . PHP_EOL], + [1, "=> \033[35m1\033[39m" . PHP_EOL], + ]; } /** @@ -308,20 +349,75 @@ public function testWriteException($exception, $expected) $shell->setOutput($output); $shell->writeException($exception); - rewind($stream); - $this->assertEquals($expected, stream_get_contents($stream)); + \rewind($stream); + $this->assertSame($expected, \stream_get_contents($stream)); } public function getRenderedExceptions() { - return array( - array(new \Exception('{{message}}'), "Exception with message '{{message}}'" . PHP_EOL), - ); + return [ + [new \Exception('{{message}}'), "Exception with message '{{message}}'" . PHP_EOL], + ]; + } + + /** + * @dataProvider getExecuteValues + */ + public function testShellExecute($input, $expected) + { + $output = $this->getOutput(); + $stream = $output->getStream(); + $shell = new Shell($this->getConfig()); + $shell->setOutput($output); + $this->assertEquals($expected, $shell->execute($input)); + \rewind($stream); + $this->assertSame('', \stream_get_contents($stream)); + } + + public function getExecuteValues() + { + return [ + ['return 12', 12], + ['"{{return value}}"', '{{return value}}'], + ['1', '1'], + ]; + } + + /** + * @dataProvider commandsToHas + */ + public function testHasCommand($command, $has) + { + $shell = new Shell($this->getConfig()); + + // :-/ + $refl = new \ReflectionClass('Psy\\Shell'); + $method = $refl->getMethod('hasCommand'); + $method->setAccessible(true); + + $this->assertEquals($method->invokeArgs($shell, [$command]), $has); + } + + public function commandsToHas() + { + return [ + ['help', true], + ['help help', true], + ['"help"', false], + ['"help help"', false], + ['ls -al ', true], + ['ls "-al" ', true], + ['ls"-al"', false], + [' q', true], + [' q --help', true], + ['"q"', false], + ['"q",', false], + ]; } private function getOutput() { - $stream = fopen('php://memory', 'w+'); + $stream = \fopen('php://memory', 'w+'); $this->streams[] = $stream; $output = new StreamOutput($stream, StreamOutput::VERBOSITY_NORMAL, false); @@ -329,18 +425,18 @@ private function getOutput() return $output; } - private function getConfig(array $config = array()) + private function getConfig(array $config = []) { // Mebbe there's a better way than this? - $dir = tempnam(sys_get_temp_dir(), 'psysh_shell_test_'); - unlink($dir); + $dir = \tempnam(\sys_get_temp_dir(), 'psysh_shell_test_'); + \unlink($dir); - $defaults = array( + $defaults = [ 'configDir' => $dir, 'dataDir' => $dir, 'runtimeDir' => $dir, - ); + ]; - return new Configuration(array_merge($defaults, $config)); + return new Configuration(\array_merge($defaults, $config)); } } diff --git a/app/vendor/psy/psysh/test/Sudo/SudoVisitorTest.php b/app/vendor/psy/psysh/test/Sudo/SudoVisitorTest.php new file mode 100644 index 000000000..1f2042c86 --- /dev/null +++ b/app/vendor/psy/psysh/test/Sudo/SudoVisitorTest.php @@ -0,0 +1,142 @@ +traverser = new NodeTraverser(); + $this->traverser->addVisitor(new SudoVisitor()); + } + + /** + * @dataProvider propertyFetches + */ + public function testPropertyFetch($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function propertyFetches() + { + return [ + ['$a->b', "\Psy\Sudo::fetchProperty(\$a, 'b');"], + ['$a->$b', '\Psy\Sudo::fetchProperty($a, $b);'], + ["\$a->{'b'}", "\Psy\Sudo::fetchProperty(\$a, 'b');"], + ]; + } + + /** + * @dataProvider propertyAssigns + */ + public function testPropertyAssign($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function propertyAssigns() + { + return [ + ['$a->b = $c', "\Psy\Sudo::assignProperty(\$a, 'b', \$c);"], + ['$a->$b = $c', '\Psy\Sudo::assignProperty($a, $b, $c);'], + ["\$a->{'b'} = \$c", "\Psy\Sudo::assignProperty(\$a, 'b', \$c);"], + ]; + } + + /** + * @dataProvider methodCalls + */ + public function testMethodCall($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function methodCalls() + { + return [ + ['$a->b()', "\Psy\Sudo::callMethod(\$a, 'b');"], + ['$a->$b()', '\Psy\Sudo::callMethod($a, $b);'], + ["\$a->b(\$c, 'd')", "\Psy\Sudo::callMethod(\$a, 'b', \$c, 'd');"], + ["\$a->\$b(\$c, 'd')", "\Psy\Sudo::callMethod(\$a, \$b, \$c, 'd');"], + ]; + } + + /** + * @dataProvider staticPropertyFetches + */ + public function testStaticPropertyFetch($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function staticPropertyFetches() + { + return [ + ['A::$b', "\Psy\Sudo::fetchStaticProperty('A', 'b');"], + ['$a::$b', "\Psy\Sudo::fetchStaticProperty(\$a, 'b');"], + ]; + } + + /** + * @dataProvider staticPropertyAssigns + */ + public function testStaticPropertyAssign($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function staticPropertyAssigns() + { + return [ + ['A::$b = $c', "\Psy\Sudo::assignStaticProperty('A', 'b', \$c);"], + ['$a::$b = $c', "\Psy\Sudo::assignStaticProperty(\$a, 'b', \$c);"], + ]; + } + + /** + * @dataProvider staticCalls + */ + public function testStaticCall($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function staticCalls() + { + return [ + ['A::b()', "\Psy\Sudo::callStatic('A', 'b');"], + ['A::$b()', "\Psy\Sudo::callStatic('A', \$b);"], + ["A::b(\$c, 'd')", "\Psy\Sudo::callStatic('A', 'b', \$c, 'd');"], + ["A::\$b(\$c, 'd')", "\Psy\Sudo::callStatic('A', \$b, \$c, 'd');"], + ]; + } + + /** + * @dataProvider classConstFetches + */ + public function testClassConstFetch($from, $to) + { + $this->assertProcessesAs($from, $to); + } + + public function classConstFetches() + { + return [ + ['A::B', "\Psy\Sudo::fetchClassConst('A', 'B');"], + ]; + } +} diff --git a/app/vendor/psy/psysh/test/SudoTest.php b/app/vendor/psy/psysh/test/SudoTest.php new file mode 100644 index 000000000..6123db04e --- /dev/null +++ b/app/vendor/psy/psysh/test/SudoTest.php @@ -0,0 +1,80 @@ +markTestSkipped('YOLO'); + } + } + + public function testFetchProperty() + { + $obj = new ClassWithSecrets(); + $this->assertSame('private and prop', Sudo::fetchProperty($obj, 'privateProp')); + } + + public function testAssignProperty() + { + $obj = new ClassWithSecrets(); + $this->assertSame('private and prop', Sudo::fetchProperty($obj, 'privateProp')); + $this->assertSame('not so private now', Sudo::assignProperty($obj, 'privateProp', 'not so private now')); + $this->assertSame('not so private now', Sudo::fetchProperty($obj, 'privateProp')); + } + + public function testCallMethod() + { + $obj = new ClassWithSecrets(); + $this->assertSame('private and method', Sudo::callMethod($obj, 'privateMethod')); + $this->assertSame('private and method with 1', Sudo::callMethod($obj, 'privateMethod', 1)); + $this->assertSame( + 'private and method with ["foo",2]', + Sudo::callMethod($obj, 'privateMethod', ['foo', 2] + )); + } + + public function testFetchStaticProperty() + { + $obj = new ClassWithSecrets(); + $this->assertSame('private and static and prop', Sudo::fetchStaticProperty($obj, 'privateStaticProp')); + } + + public function testAssignStaticProperty() + { + $obj = new ClassWithSecrets(); + $this->assertSame('private and static and prop', Sudo::fetchStaticProperty($obj, 'privateStaticProp')); + $this->assertSame('not so private now', Sudo::assignStaticProperty($obj, 'privateStaticProp', 'not so private now')); + $this->assertSame('not so private now', Sudo::fetchStaticProperty($obj, 'privateStaticProp')); + } + + public function testCallStatic() + { + $obj = new ClassWithSecrets(); + $this->assertSame('private and static and method', Sudo::callStatic($obj, 'privateStaticMethod')); + $this->assertSame('private and static and method with 1', Sudo::callStatic($obj, 'privateStaticMethod', 1)); + $this->assertSame( + 'private and static and method with ["foo",2]', + Sudo::callStatic($obj, 'privateStaticMethod', ['foo', 2] + )); + } + + public function testFetchClassConst() + { + $obj = new ClassWithSecrets(); + $this->assertSame('private and const', Sudo::fetchClassConst($obj, 'PRIVATE_CONST')); + } +} diff --git a/app/vendor/psy/psysh/test/Psy/Test/TabCompletion/AutoCompleterTest.php b/app/vendor/psy/psysh/test/TabCompletion/AutoCompleterTest.php similarity index 59% rename from app/vendor/psy/psysh/test/Psy/Test/TabCompletion/AutoCompleterTest.php rename to app/vendor/psy/psysh/test/TabCompletion/AutoCompleterTest.php index 3f2fda901..d98d452c4 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/TabCompletion/AutoCompleterTest.php +++ b/app/vendor/psy/psysh/test/TabCompletion/AutoCompleterTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -21,21 +21,21 @@ class AutoCompleterTest extends \PHPUnit\Framework\TestCase { /** - * @param $line - * @param $mustContain - * @param $mustNotContain + * @param string $line + * @param array $mustContain + * @param array $mustNotContain * @dataProvider classesInput */ public function testClassesCompletion($line, $mustContain, $mustNotContain) { $context = new Context(); - $commands = array( + $commands = [ new ShowCommand(), new ListCommand(), - ); + ]; - $matchers = array( + $matchers = [ new Matcher\VariablesMatcher(), new Matcher\ClassNamesMatcher(), new Matcher\ConstantsMatcher(), @@ -46,7 +46,7 @@ public function testClassesCompletion($line, $mustContain, $mustNotContain) new Matcher\ClassAttributesMatcher(), new Matcher\ClassMethodsMatcher(), new Matcher\CommandsMatcher($commands), - ); + ]; $config = new Configuration(); $tabCompletion = $config->getAutoCompleter(); @@ -57,13 +57,13 @@ public function testClassesCompletion($line, $mustContain, $mustNotContain) $tabCompletion->addMatcher($matcher); } - $context->setAll(array('foo' => 12, 'bar' => new \DOMDocument())); + $context->setAll(['foo' => 12, 'bar' => new \DOMDocument()]); - $code = $tabCompletion->processCallback('', 0, array( + $code = $tabCompletion->processCallback('', 0, [ 'line_buffer' => $line, 'point' => 0, - 'end' => strlen($line), - )); + 'end' => \strlen($line), + ]); foreach ($mustContain as $mc) { $this->assertContains($mc, $code); @@ -92,54 +92,54 @@ public function testClassesCompletion($line, $mustContain, $mustNotContain) */ public function classesInput() { - return array( + return [ // input, must had, must not had - array('T_OPE', array('T_OPEN_TAG'), array()), - array('st', array('stdClass'), array()), - array('stdCla', array('stdClass'), array()), - array('new s', array('stdClass'), array()), - array( + ['T_OPE', ['T_OPEN_TAG'], []], + ['st', ['stdClass'], []], + ['stdCla', ['stdClass'], []], + ['new s', ['stdClass'], []], + [ 'new ', - array('stdClass', 'Psy\\Context', 'Psy\\Configuration'), - array('require', 'array_search', 'T_OPEN_TAG', '$foo'), - ), - array('new Psy\\C', array('Context'), array('CASE_LOWER')), - array('\s', array('stdClass'), array()), - array('array_', array('array_search', 'array_map', 'array_merge'), array()), - array('$bar->', array('load'), array()), - array('$b', array('bar'), array()), - array('6 + $b', array('bar'), array()), - array('$f', array('foo'), array()), - array('l', array('ls'), array()), - array('ls ', array(), array('ls')), - array('sho', array('show'), array()), - array('12 + clone $', array('foo'), array()), + ['stdClass', 'Psy\\Context', 'Psy\\Configuration'], + ['require', 'array_search', 'T_OPEN_TAG', '$foo'], + ], + ['new Psy\\C', ['Context'], ['CASE_LOWER']], + ['\s', ['stdClass'], []], + ['array_', ['array_search', 'array_map', 'array_merge'], []], + ['$bar->', ['load'], []], + ['$b', ['bar'], []], + ['6 + $b', ['bar'], []], + ['$f', ['foo'], []], + ['l', ['ls'], []], + ['ls ', [], ['ls']], + ['sho', ['show'], []], + ['12 + clone $', ['foo'], []], // array( // '$foo ', // array('+', 'clone'), // array('$foo', 'DOMDocument', 'array_map') // ), requires a operator matcher? - array('$', array('foo', 'bar'), array('require', 'array_search', 'T_OPEN_TAG', 'Psy')), - array( + ['$', ['foo', 'bar'], ['require', 'array_search', 'T_OPEN_TAG', 'Psy']], + [ 'Psy\\', - array('Context', 'TabCompletion\\Matcher\\AbstractMatcher'), - array('require', 'array_search'), - ), - array( + ['Context', 'TabCompletion\\Matcher\\AbstractMatcher'], + ['require', 'array_search'], + ], + [ 'Psy\Test\TabCompletion\StaticSample::CO', - array('Psy\Test\TabCompletion\StaticSample::CONSTANT_VALUE'), - array(), - ), - array( + ['StaticSample::CONSTANT_VALUE'], + [], + ], + [ 'Psy\Test\TabCompletion\StaticSample::', - array('Psy\Test\TabCompletion\StaticSample::$staticVariable'), - array(), - ), - array( + ['StaticSample::$staticVariable'], + [], + ], + [ 'Psy\Test\TabCompletion\StaticSample::', - array('Psy\Test\TabCompletion\StaticSample::staticFunction'), - array(), - ), - ); + ['StaticSample::staticFunction'], + [], + ], + ]; } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/TabCompletion/StaticSample.php b/app/vendor/psy/psysh/test/TabCompletion/StaticSample.php similarity index 93% rename from app/vendor/psy/psysh/test/Psy/Test/TabCompletion/StaticSample.php rename to app/vendor/psy/psysh/test/TabCompletion/StaticSample.php index aea0031c3..e0de2f0bb 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/TabCompletion/StaticSample.php +++ b/app/vendor/psy/psysh/test/TabCompletion/StaticSample.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/test/Psy/Test/Util/DocblockTest.php b/app/vendor/psy/psysh/test/Util/DocblockTest.php similarity index 64% rename from app/vendor/psy/psysh/test/Psy/Test/Util/DocblockTest.php rename to app/vendor/psy/psysh/test/Util/DocblockTest.php index 9ed3c0290..82e12fede 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Util/DocblockTest.php +++ b/app/vendor/psy/psysh/test/Util/DocblockTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -31,7 +31,7 @@ public function testDocblockParsing($comment, $body, $tags) $docblock = new Docblock($reflector); - $this->assertEquals($body, $docblock->desc); + $this->assertSame($body, $docblock->desc); foreach ($tags as $tag => $value) { $this->assertTrue($docblock->hasTag($tag)); @@ -41,24 +41,24 @@ public function testDocblockParsing($comment, $body, $tags) public function comments() { - if (defined('HHVM_VERSION')) { + if (\defined('HHVM_VERSION')) { $this->markTestSkipped('We have issues with PHPUnit mocks on HHVM.'); } - return array( - array('', '', array()), - array( + return [ + ['', '', []], + [ '/** * This is a docblock * * @throws \Exception with a description */', 'This is a docblock', - array( - 'throws' => array(array('type' => '\Exception', 'desc' => 'with a description')), - ), - ), - array( + [ + 'throws' => [['type' => '\Exception', 'desc' => 'with a description']], + ], + ], + [ '/** * This is a slightly longer docblock * @@ -69,18 +69,18 @@ public function comments() * @return int At least it isn\'t a string */', 'This is a slightly longer docblock', - array( - 'param' => array( - array('type' => 'int', 'desc' => 'Is a Foo', 'var' => '$foo'), - array('type' => 'string', 'desc' => 'With some sort of description', 'var' => '$bar'), - array('type' => '\ClassName', 'desc' => 'is cool too', 'var' => '$baz'), - ), - 'return' => array( - array('type' => 'int', 'desc' => 'At least it isn\'t a string'), - ), - ), - ), - array( + [ + 'param' => [ + ['type' => 'int', 'desc' => 'Is a Foo', 'var' => '$foo'], + ['type' => 'string', 'desc' => 'With some sort of description', 'var' => '$bar'], + ['type' => '\ClassName', 'desc' => 'is cool too', 'var' => '$baz'], + ], + 'return' => [ + ['type' => 'int', 'desc' => 'At least it isn\'t a string'], + ], + ], + ], + [ '/** * This is a docblock! * @@ -91,10 +91,10 @@ public function comments() * @return */', "This is a docblock!\n\nIt spans lines, too!", - array( - 'tagname' => array('plus a description'), - ), - ), - ); + [ + 'tagname' => ['plus a description'], + ], + ], + ]; } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/Util/MirrorTest.php b/app/vendor/psy/psysh/test/Util/MirrorTest.php similarity index 58% rename from app/vendor/psy/psysh/test/Psy/Test/Util/MirrorTest.php rename to app/vendor/psy/psysh/test/Util/MirrorTest.php index ab0b17263..585fffbb2 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Util/MirrorTest.php +++ b/app/vendor/psy/psysh/test/Util/MirrorTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -11,7 +11,6 @@ namespace Psy\Test\Util; -use Psy\Reflection\ReflectionConstant; use Psy\Util\Mirror; class MirrorTest extends \PHPUnit\Framework\TestCase @@ -28,28 +27,35 @@ public function aPublicMethod() public function testMirror() { $refl = Mirror::get('sort'); - $this->assertTrue($refl instanceof \ReflectionFunction); + $this->assertInstanceOf('ReflectionFunction', $refl); $refl = Mirror::get('Psy\Test\Util\MirrorTest'); - $this->assertTrue($refl instanceof \ReflectionClass); + $this->assertInstanceOf('ReflectionClass', $refl); $refl = Mirror::get($this); - $this->assertTrue($refl instanceof \ReflectionObject); + $this->assertInstanceOf('ReflectionObject', $refl); $refl = Mirror::get($this, 'FOO'); - $this->assertTrue($refl instanceof ReflectionConstant); + if (\version_compare(PHP_VERSION, '7.1.0', '>=')) { + $this->assertInstanceOf('ReflectionClassConstant', $refl); + } else { + $this->assertInstanceOf('Psy\Reflection\ReflectionClassConstant', $refl); + } + + $refl = Mirror::get('PHP_VERSION'); + $this->assertInstanceOf('Psy\Reflection\ReflectionConstant_', $refl); $refl = Mirror::get($this, 'bar'); - $this->assertTrue($refl instanceof \ReflectionProperty); + $this->assertInstanceOf('ReflectionProperty', $refl); $refl = Mirror::get($this, 'baz'); - $this->assertTrue($refl instanceof \ReflectionProperty); + $this->assertInstanceOf('ReflectionProperty', $refl); $refl = Mirror::get($this, 'aPublicMethod'); - $this->assertTrue($refl instanceof \ReflectionMethod); + $this->assertInstanceOf('ReflectionMethod', $refl); $refl = Mirror::get($this, 'baz', Mirror::STATIC_PROPERTY); - $this->assertTrue($refl instanceof \ReflectionProperty); + $this->assertInstanceOf('ReflectionProperty', $refl); } /** @@ -71,10 +77,10 @@ public function testMirrorThrowsInvalidArgumentExceptions($value) public function invalidArguments() { - return array( - array('not_a_function_or_class'), - array(array()), - array(1), - ); + return [ + ['not_a_function_or_class'], + [[]], + [1], + ]; } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/Util/StrTest.php b/app/vendor/psy/psysh/test/Util/StrTest.php similarity index 62% rename from app/vendor/psy/psysh/test/Psy/Test/Util/StrTest.php rename to app/vendor/psy/psysh/test/Util/StrTest.php index 46cdb2303..4f99a79b3 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/Util/StrTest.php +++ b/app/vendor/psy/psysh/test/Util/StrTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,12 +20,12 @@ class StrTest extends \PHPUnit\Framework\TestCase */ public function testUnvis($input, $expected) { - $this->assertEquals($expected, Str::unvis($input)); + $this->assertSame($expected, Str::unvis($input)); } public function unvisProvider() { - //return require_once(__DIR__.'/../../../fixtures/unvis_fixtures.php'); - return json_decode(file_get_contents(__DIR__ . '/../../../fixtures/unvis_fixtures.json')); + //return require_once(__DIR__.'/../fixtures/unvis_fixtures.php'); + return \json_decode(\file_get_contents(__DIR__ . '/../fixtures/unvis_fixtures.json')); } } diff --git a/app/vendor/psy/psysh/test/Psy/Test/VersionUpdater/GitHubCheckerTest.php b/app/vendor/psy/psysh/test/VersionUpdater/GitHubCheckerTest.php similarity index 55% rename from app/vendor/psy/psysh/test/Psy/Test/VersionUpdater/GitHubCheckerTest.php rename to app/vendor/psy/psysh/test/VersionUpdater/GitHubCheckerTest.php index 07eb0c6e1..7d12d47d6 100644 --- a/app/vendor/psy/psysh/test/Psy/Test/VersionUpdater/GitHubCheckerTest.php +++ b/app/vendor/psy/psysh/test/VersionUpdater/GitHubCheckerTest.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. @@ -20,12 +20,12 @@ class GitHubCheckerTest extends \PHPUnit\Framework\TestCase * @expectedException \InvalidArgumentException * @expectedExceptionMessage Unable to check for updates * - * @param $input + * @param mixed $input */ public function testExceptionInvocation($input) { $checker = $this->getMockBuilder('Psy\\VersionUpdater\\GitHubChecker') - ->setMethods(array('fetchLatestRelease')) + ->setMethods(['fetchLatestRelease']) ->getMock(); $checker->expects($this->once())->method('fetchLatestRelease')->willReturn($input); $checker->isLatest(); @@ -34,13 +34,13 @@ public function testExceptionInvocation($input) /** * @dataProvider jsonResults * - * @param $assertion - * @param $input + * @param bool $assertion + * @param mixed $input */ public function testDataSetResults($assertion, $input) { $checker = $this->getMockBuilder('Psy\\VersionUpdater\\GitHubChecker') - ->setMethods(array('fetchLatestRelease')) + ->setMethods(['fetchLatestRelease']) ->getMock(); $checker->expects($this->once())->method('fetchLatestRelease')->willReturn($input); $this->assertSame($assertion, $checker->isLatest()); @@ -51,15 +51,15 @@ public function testDataSetResults($assertion, $input) */ public function jsonResults() { - return array( - array(false, json_decode('{"tag_name":"v9.0.0"}')), - array(true, json_decode('{"tag_name":"v' . Shell::VERSION . '"}')), - array(true, json_decode('{"tag_name":"v0.0.1"}')), - array(true, json_decode('{"tag_name":"v0.4.1-alpha"}')), - array(true, json_decode('{"tag_name":"v0.4.2-beta3"}')), - array(true, json_decode('{"tag_name":"v0.0.1"}')), - array(true, json_decode('{"tag_name":""}')), - ); + return [ + [false, \json_decode('{"tag_name":"v9.0.0"}')], + [true, \json_decode('{"tag_name":"v' . Shell::VERSION . '"}')], + [true, \json_decode('{"tag_name":"v0.0.1"}')], + [true, \json_decode('{"tag_name":"v0.4.1-alpha"}')], + [true, \json_decode('{"tag_name":"v0.4.2-beta3"}')], + [true, \json_decode('{"tag_name":"v0.0.1"}')], + [true, \json_decode('{"tag_name":""}')], + ]; } /** @@ -67,16 +67,16 @@ public function jsonResults() */ public function malformedResults() { - return array( - array(null), - array(false), - array(true), - array(json_decode('{"foo":"bar"}')), - array(json_decode('{}')), - array(json_decode('[]')), - array(array()), - array(json_decode('{"tag_name":false"}')), - array(json_decode('{"tag_name":true"}')), - ); + return [ + [null], + [false], + [true], + [\json_decode('{"foo":"bar"}')], + [\json_decode('{}')], + [\json_decode('[]')], + [[]], + [\json_decode('{"tag_name":false"}')], + [\json_decode('{"tag_name":true"}')], + ]; } } diff --git a/app/vendor/psy/psysh/test/VersionUpdater/NoopCheckerTest.php b/app/vendor/psy/psysh/test/VersionUpdater/NoopCheckerTest.php new file mode 100644 index 000000000..b9ba568c7 --- /dev/null +++ b/app/vendor/psy/psysh/test/VersionUpdater/NoopCheckerTest.php @@ -0,0 +1,25 @@ +assertTrue($checker->isLatest()); + $this->assertEquals(Shell::VERSION, $checker->getLatest()); + } +} diff --git a/app/vendor/psy/psysh/test/fixtures/config.php b/app/vendor/psy/psysh/test/fixtures/config.php index 31a4ef54d..4c74b79d0 100644 --- a/app/vendor/psy/psysh/test/fixtures/config.php +++ b/app/vendor/psy/psysh/test/fixtures/config.php @@ -3,16 +3,18 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ -$config->setRuntimeDir(sys_get_temp_dir() . '/psysh_test/withconfig/temp'); +$config->setRuntimeDir(\sys_get_temp_dir() . '/psysh_test/withconfig/temp'); -return array( +return [ 'useReadline' => true, 'usePcntl' => false, + 'requireSemicolons' => false, + 'useUnicode' => true, 'errorLoggingLevel' => E_ALL & ~E_NOTICE, -); +]; diff --git a/app/vendor/psy/psysh/test/fixtures/empty.php b/app/vendor/psy/psysh/test/fixtures/empty.php index a385c6c92..ba4e5784c 100644 --- a/app/vendor/psy/psysh/test/fixtures/empty.php +++ b/app/vendor/psy/psysh/test/fixtures/empty.php @@ -3,7 +3,7 @@ /* * This file is part of Psy Shell. * - * (c) 2012-2017 Justin Hileman + * (c) 2012-2018 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/app/vendor/psy/psysh/test/fixtures/project/.psysh.php b/app/vendor/psy/psysh/test/fixtures/project/.psysh.php index a6ac121e9..8ba668c81 100644 --- a/app/vendor/psy/psysh/test/fixtures/project/.psysh.php +++ b/app/vendor/psy/psysh/test/fixtures/project/.psysh.php @@ -10,6 +10,8 @@ */ return array( - 'useReadline' => false, - 'usePcntl' => true, + 'useReadline' => false, + 'usePcntl' => true, + 'requireSemicolons' => true, + 'useUnicode' => false, ); diff --git a/app/vendor/psy/psysh/vendor-bin/box/composer.json b/app/vendor/psy/psysh/vendor-bin/box/composer.json new file mode 100644 index 000000000..a5ef20620 --- /dev/null +++ b/app/vendor/psy/psysh/vendor-bin/box/composer.json @@ -0,0 +1,7 @@ +{ + "minimum-stability": "dev", + "prefer-stable": true, + "require": { + "humbug/box": "^3.0@alpha" + } +} diff --git a/app/vendor/psy/psysh/vendor-bin/box/composer.lock b/app/vendor/psy/psysh/vendor-bin/box/composer.lock new file mode 100644 index 000000000..3c4496384 --- /dev/null +++ b/app/vendor/psy/psysh/vendor-bin/box/composer.lock @@ -0,0 +1,2524 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "d98ffe050f0ba4e81c2d1a98ca945200", + "packages": [ + { + "name": "amphp/amp", + "version": "v2.0.7", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "d561cc9736bc18dd94a2fc9cdae98b616bd92c43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/d561cc9736bc18dd94a2fc9cdae98b616bd92c43", + "reference": "d561cc9736bc18dd94a2fc9cdae98b616bd92c43", + "shasum": "" + }, + "require": { + "php": ">=7" + }, + "require-dev": { + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "phpstan/phpstan": "^0.8.5", + "phpunit/phpunit": "^6.0.9", + "react/promise": "^2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\": "lib" + }, + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "http://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "time": "2018-04-30T20:49:57+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.3.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "1b75b122e6f069e7d102eef065dc192119d99ca7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/1b75b122e6f069e7d102eef065dc192119d99ca7", + "reference": "1b75b122e6f069e7d102eef065dc192119d99ca7", + "shasum": "" + }, + "require": { + "amphp/amp": "^2" + }, + "require-dev": { + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\ByteStream\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "http://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "time": "2018-04-04T05:33:09+00:00" + }, + { + "name": "amphp/parallel", + "version": "v0.2.5", + "source": { + "type": "git", + "url": "https://github.com/amphp/parallel.git", + "reference": "732694688461936bec02c0ccf020dfee10c4f7ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parallel/zipball/732694688461936bec02c0ccf020dfee10c4f7ee", + "reference": "732694688461936bec02c0ccf020dfee10c4f7ee", + "shasum": "" + }, + "require": { + "amphp/amp": "^2", + "amphp/byte-stream": "^1.2", + "amphp/parser": "^1", + "amphp/process": "^0.2 || ^0.3", + "amphp/sync": "^1.0.1" + }, + "require-dev": { + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "phpunit/phpunit": "^6" + }, + "suggest": { + "ext-pthreads": "Required for thread contexts" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Parallel\\": "lib" + }, + "files": [ + "lib/Worker/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Parallel processing component for Amp.", + "homepage": "https://github.com/amphp/parallel", + "keywords": [ + "async", + "asynchronous", + "concurrent", + "multi-processing", + "multi-threading" + ], + "time": "2018-03-21T14:37:51+00:00" + }, + { + "name": "amphp/parallel-functions", + "version": "v0.1.2", + "source": { + "type": "git", + "url": "https://github.com/amphp/parallel-functions.git", + "reference": "999ba8a00adaf4d1fd3a7cb40bf7e565e507ff48" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parallel-functions/zipball/999ba8a00adaf4d1fd3a7cb40bf7e565e507ff48", + "reference": "999ba8a00adaf4d1fd3a7cb40bf7e565e507ff48", + "shasum": "" + }, + "require": { + "amphp/amp": "^2.0.3", + "amphp/parallel": "^0.1.8 || ^0.2", + "opis/closure": "^3.0.7", + "php": ">=7" + }, + "require-dev": { + "amphp/phpunit-util": "^1.0", + "friendsofphp/php-cs-fixer": "^2.9", + "phpunit/phpunit": "^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\ParallelFunctions\\": "src" + }, + "files": [ + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Parallel processing made simple.", + "time": "2017-12-17T18:33:29+00:00" + }, + { + "name": "amphp/parser", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/parser.git", + "reference": "f83e68f03d5b8e8e0365b8792985a7f341c57ae1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parser/zipball/f83e68f03d5b8e8e0365b8792985a7f341c57ae1", + "reference": "f83e68f03d5b8e8e0365b8792985a7f341c57ae1", + "shasum": "" + }, + "require": { + "php": ">=7" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.3", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Parser\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "A generator parser to make streaming parsers simple.", + "homepage": "https://github.com/amphp/parser", + "keywords": [ + "async", + "non-blocking", + "parser", + "stream" + ], + "time": "2017-06-06T05:29:10+00:00" + }, + { + "name": "amphp/process", + "version": "v0.3.3", + "source": { + "type": "git", + "url": "https://github.com/amphp/process.git", + "reference": "b795d20a7f6d5a0637128a02be613f520f1705fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/process/zipball/b795d20a7f6d5a0637128a02be613f520f1705fc", + "reference": "b795d20a7f6d5a0637128a02be613f520f1705fc", + "shasum": "" + }, + "require": { + "amphp/amp": "^2", + "amphp/byte-stream": "^1", + "php": ">=7" + }, + "require-dev": { + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Process\\": "lib" + }, + "files": [ + "lib/constants.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Asynchronous process manager.", + "homepage": "https://github.com/amphp/process", + "time": "2018-04-08T18:55:42+00:00" + }, + { + "name": "amphp/sync", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/sync.git", + "reference": "a1d8f244eb19e3e2a96abc4686cebc80995bbc90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/sync/zipball/a1d8f244eb19e3e2a96abc4686cebc80995bbc90", + "reference": "a1d8f244eb19e3e2a96abc4686cebc80995bbc90", + "shasum": "" + }, + "require": { + "amphp/amp": "^2" + }, + "require-dev": { + "amphp/phpunit-util": "^1", + "friendsofphp/php-cs-fixer": "^2.3", + "phpunit/phpunit": "^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Sync\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Mutex, Semaphore, and other synchronization tools for Amp.", + "homepage": "https://github.com/amphp/sync", + "keywords": [ + "async", + "asynchronous", + "mutex", + "semaphore", + "synchronization" + ], + "time": "2017-11-29T21:48:53+00:00" + }, + { + "name": "beberlei/assert", + "version": "v2.9.5", + "source": { + "type": "git", + "url": "https://github.com/beberlei/assert.git", + "reference": "c07fe163d6a3b3e4b1275981ec004397954afa89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/beberlei/assert/zipball/c07fe163d6a3b3e4b1275981ec004397954afa89", + "reference": "c07fe163d6a3b3e4b1275981ec004397954afa89", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=5.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.1.1", + "phpunit/phpunit": "^4.8.35|^5.7" + }, + "type": "library", + "autoload": { + "psr-4": { + "Assert\\": "lib/Assert" + }, + "files": [ + "lib/Assert/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de", + "role": "Lead Developer" + }, + { + "name": "Richard Quadling", + "email": "rquadling@gmail.com", + "role": "Collaborator" + } + ], + "description": "Thin assertion library for input validation in business models.", + "keywords": [ + "assert", + "assertion", + "validation" + ], + "time": "2018-04-16T11:18:27+00:00" + }, + { + "name": "composer/ca-bundle", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/composer/ca-bundle.git", + "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/d2c0a83b7533d6912e8d516756ebd34f893e9169", + "reference": "d2c0a83b7533d6912e8d516756ebd34f893e9169", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "ext-pcre": "*", + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "psr/log": "^1.0", + "symfony/process": "^2.5 || ^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\CaBundle\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.", + "keywords": [ + "cabundle", + "cacert", + "certificate", + "ssl", + "tls" + ], + "time": "2018-03-29T19:57:20+00:00" + }, + { + "name": "composer/composer", + "version": "1.6.5", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "b184a92419cc9a9c4c6a09db555a94d441cb11c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/b184a92419cc9a9c4c6a09db555a94d441cb11c9", + "reference": "b184a92419cc9a9c4c6a09db555a94d441cb11c9", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "composer/semver": "^1.0", + "composer/spdx-licenses": "^1.2", + "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0", + "seld/cli-prompt": "^1.0", + "seld/jsonlint": "^1.4", + "seld/phar-utils": "^1.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0", + "symfony/finder": "^2.7 || ^3.0 || ^4.0", + "symfony/process": "^2.7 || ^3.0 || ^4.0" + }, + "conflict": { + "symfony/console": "2.8.38" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7", + "phpunit/phpunit-mock-objects": "^2.3 || ^3.0" + }, + "suggest": { + "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", + "ext-zip": "Enabling the zip extension allows you to unzip archives", + "ext-zlib": "Allow gzip compression of HTTP requests" + }, + "bin": [ + "bin/composer" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\": "src/Composer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Composer helps you declare, manage and install dependencies of PHP projects, ensuring you have the right stack everywhere.", + "homepage": "https://getcomposer.org/", + "keywords": [ + "autoload", + "dependency", + "package" + ], + "time": "2018-05-04T09:44:59+00:00" + }, + { + "name": "composer/semver", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", + "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5 || ^5.0.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "time": "2016-08-30T16:08:34+00:00" + }, + { + "name": "composer/spdx-licenses", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/spdx-licenses.git", + "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/cb17687e9f936acd7e7245ad3890f953770dec1b", + "reference": "cb17687e9f936acd7e7245ad3890f953770dec1b", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5", + "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Spdx\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "SPDX licenses list and validation library.", + "keywords": [ + "license", + "spdx", + "validator" + ], + "time": "2018-04-30T10:33:04+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/c919dc6c62e221fc6406f861ea13433c0aa24f08", + "reference": "c919dc6c62e221fc6406f861ea13433c0aa24f08", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0", + "psr/log": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "time": "2018-04-11T15:42:36+00:00" + }, + { + "name": "doctrine/annotations", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/annotations.git", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5", + "shasum": "" + }, + "require": { + "doctrine/lexer": "1.*", + "php": "^7.1" + }, + "require-dev": { + "doctrine/cache": "1.*", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Docblock Annotations Parser", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "annotations", + "docblock", + "parser" + ], + "time": "2017-12-06T07:11:42+00:00" + }, + { + "name": "doctrine/lexer", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", + "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Doctrine\\Common\\Lexer\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "http://www.doctrine-project.org", + "keywords": [ + "lexer", + "parser" + ], + "time": "2014-09-09T13:34:57+00:00" + }, + { + "name": "herrera-io/annotations", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/kherge-abandoned/php-annotations.git", + "reference": "7d8b9a536da7f12aad8de7f28b2cb5266bde8da1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kherge-abandoned/php-annotations/zipball/7d8b9a536da7f12aad8de7f28b2cb5266bde8da1", + "reference": "7d8b9a536da7f12aad8de7f28b2cb5266bde8da1", + "shasum": "" + }, + "require": { + "doctrine/annotations": "~1.0", + "php": ">=5.3.3" + }, + "require-dev": { + "herrera-io/phpunit-test-case": "1.*", + "phpunit/phpunit": "3.7.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-0": { + "Herrera\\Annotations": "src/lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kevin Herrera", + "email": "kevin@herrera.io", + "homepage": "http://kevin.herrera.io" + } + ], + "description": "A tokenizer for Doctrine annotations.", + "homepage": "https://github.com/herrera-io/php-annotations", + "keywords": [ + "annotations", + "doctrine", + "tokenizer" + ], + "abandoned": true, + "time": "2014-02-03T17:34:08+00:00" + }, + { + "name": "humbug/box", + "version": "3.0.0-alpha.5", + "source": { + "type": "git", + "url": "https://github.com/humbug/box.git", + "reference": "26b3f481e3b375f55c0644f501b831f7c05d8058" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/humbug/box/zipball/26b3f481e3b375f55c0644f501b831f7c05d8058", + "reference": "26b3f481e3b375f55c0644f501b831f7c05d8058", + "shasum": "" + }, + "require": { + "amphp/parallel-functions": "^0.1.2", + "beberlei/assert": "^2.8", + "composer/composer": "^1.6", + "composer/xdebug-handler": "^1.1.0", + "ext-phar": "*", + "herrera-io/annotations": "~1.0", + "humbug/php-scoper": "^1.0@dev", + "justinrainbow/json-schema": "^5.2", + "nikic/iter": "^1.6", + "php": "^7.1", + "phpseclib/phpseclib": "~2.0", + "seld/jsonlint": "^1.6", + "symfony/console": "^3.4 || ^4.0", + "symfony/filesystem": "^3.4 || ^4.0", + "symfony/finder": "^3.4 || ^4.0", + "symfony/var-dumper": "^3.4 || ^4.0", + "webmozart/path-util": "^2.3" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "infection/infection": "^0.8", + "mikey179/vfsstream": "^1.1", + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-openssl": "To accelerate private key generation." + }, + "bin": [ + "bin/box" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + }, + "bamarni-bin": { + "bin-links": false + } + }, + "autoload": { + "psr-4": { + "KevinGH\\Box\\": "src" + }, + "files": [ + "src/FileSystem/file_system.php", + "src/functions.php" + ], + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Kevin Herrera", + "email": "kevin@herrera.io", + "homepage": "http://kevin.herrera.io" + }, + { + "name": "Théo Fidry", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Fast, zero config application bundler with PHARs.", + "keywords": [ + "phar" + ], + "time": "2018-05-04T22:04:10+00:00" + }, + { + "name": "humbug/php-scoper", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/humbug/php-scoper.git", + "reference": "450fe36a7457847d0cb431e7379b5df9d05992a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/humbug/php-scoper/zipball/450fe36a7457847d0cb431e7379b5df9d05992a4", + "reference": "450fe36a7457847d0cb431e7379b5df9d05992a4", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^3.0", + "ocramius/package-versions": "^1.1", + "padraic/phar-updater": "^1.0", + "php": "^7.1", + "roave/better-reflection": "^2.0", + "symfony/console": "^3.2 || ^4.0", + "symfony/filesystem": "^3.2 || ^4.0", + "symfony/finder": "^3.2 || ^4.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.1", + "phpunit/phpunit": "^6.1" + }, + "bin": [ + "bin/php-scoper" + ], + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false + }, + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Humbug\\PhpScoper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + }, + { + "name": "Théo Fidry", + "email": "theo.fidry@gmail.com" + }, + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com" + } + ], + "description": "Prefixes all PHP namespaces in a file or directory.", + "time": "2018-04-25T21:59:07+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.7", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "8560d4314577199ba51bf2032f02cd1315587c23" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/8560d4314577199ba51bf2032f02cd1315587c23", + "reference": "8560d4314577199ba51bf2032f02cd1315587c23", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "time": "2018-02-14T22:26:30+00:00" + }, + { + "name": "nikic/iter", + "version": "v1.6.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/iter.git", + "reference": "fed36b417ea93fe9b4b7cb2e2abf98d91092564c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/iter/zipball/fed36b417ea93fe9b4b7cb2e2abf98d91092564c", + "reference": "fed36b417ea93fe9b4b7cb2e2abf98d91092564c", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } + ], + "description": "Iteration primitives using generators", + "keywords": [ + "functional", + "generator", + "iterator" + ], + "time": "2017-11-10T22:56:03+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v3.1.5", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "~4.0|~5.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2018-02-28T20:30:58+00:00" + }, + { + "name": "ocramius/package-versions", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/PackageVersions.git", + "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/4489d5002c49d55576fa0ba786f42dbb009be46f", + "reference": "4489d5002c49d55576fa0ba786f42dbb009be46f", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0.0", + "php": "^7.1.0" + }, + "require-dev": { + "composer/composer": "^1.6.3", + "ext-zip": "*", + "infection/infection": "^0.7.1", + "phpunit/phpunit": "^7.0.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "time": "2018-02-05T13:05:30+00:00" + }, + { + "name": "opis/closure", + "version": "3.0.12", + "source": { + "type": "git", + "url": "https://github.com/opis/closure.git", + "reference": "507a28d15e79258d404ba76e73976ba895d0eb11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/closure/zipball/507a28d15e79258d404ba76e73976ba895d0eb11", + "reference": "507a28d15e79258d404ba76e73976ba895d0eb11", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "jeremeamia/superclosure": "^2.0", + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\Closure\\": "src/" + }, + "files": [ + "functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + } + ], + "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", + "homepage": "http://www.opis.io/closure", + "keywords": [ + "anonymous functions", + "closure", + "function", + "serializable", + "serialization", + "serialize" + ], + "time": "2018-02-23T08:08:14+00:00" + }, + { + "name": "padraic/humbug_get_contents", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/humbug/file_get_contents.git", + "reference": "dcb086060c9dd6b2f51d8f7a895500307110b7a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/humbug/file_get_contents/zipball/dcb086060c9dd6b2f51d8f7a895500307110b7a7", + "reference": "dcb086060c9dd6b2f51d8f7a895500307110b7a7", + "shasum": "" + }, + "require": { + "composer/ca-bundle": "^1.0", + "ext-openssl": "*", + "php": "^5.3 || ^7.0 || ^7.1 || ^7.2" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.1", + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^4.8 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": false + }, + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Humbug\\": "src/" + }, + "files": [ + "src/function.php", + "src/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Padraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Théo Fidry", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Secure wrapper for accessing HTTPS resources with file_get_contents for PHP 5.3+", + "homepage": "https://github.com/padraic/file_get_contents", + "keywords": [ + "download", + "file_get_contents", + "http", + "https", + "ssl", + "tls" + ], + "time": "2018-02-12T18:47:17+00:00" + }, + { + "name": "padraic/phar-updater", + "version": "v1.0.6", + "source": { + "type": "git", + "url": "https://github.com/humbug/phar-updater.git", + "reference": "d01d3b8f26e541ac9b9eeba1e18d005d852f7ff1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/humbug/phar-updater/zipball/d01d3b8f26e541ac9b9eeba1e18d005d852f7ff1", + "reference": "d01d3b8f26e541ac9b9eeba1e18d005d852f7ff1", + "shasum": "" + }, + "require": { + "padraic/humbug_get_contents": "^1.0", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Humbug\\SelfUpdate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + } + ], + "description": "A thing to make PHAR self-updating easy and secure.", + "keywords": [ + "humbug", + "phar", + "self-update", + "update" + ], + "time": "2018-03-30T12:52:15+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-30T07:14:17+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "2.0.11", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7053f06f91b3de78e143d430e55a8f7889efc08b", + "reference": "7053f06f91b3de78e143d430e55a8f7889efc08b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "sami/sami": "~2.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "time": "2018-04-15T16:55:05+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + }, + { + "name": "roave/better-reflection", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/Roave/BetterReflection.git", + "reference": "efc45b50cb52d5eeaacab15741376e981e28738b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Roave/BetterReflection/zipball/efc45b50cb52d5eeaacab15741376e981e28738b", + "reference": "efc45b50cb52d5eeaacab15741376e981e28738b", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^3.1.1", + "php": ">=7.1.0,<7.3.0", + "phpdocumentor/reflection-docblock": "^4.1.1", + "phpdocumentor/type-resolver": "^0.4.0", + "roave/signature": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.3.0" + }, + "suggest": { + "composer/composer": "Required to use the ComposerSourceLocator" + }, + "type": "library", + "autoload": { + "psr-4": { + "Roave\\BetterReflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.io/" + }, + { + "name": "James Titcumb", + "email": "james@asgrim.com", + "homepage": "https://github.com/asgrim" + }, + { + "name": "Gary Hockin", + "email": "gary@roave.com", + "homepage": "https://github.com/geeh" + }, + { + "name": "Jaroslav Hanslík", + "email": "kukulich@kukulich.cz", + "homepage": "https://github.com/kukulich" + } + ], + "description": "Better Reflection - an improved code reflection API", + "time": "2018-02-05T08:08:57+00:00" + }, + { + "name": "roave/signature", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Roave/Signature.git", + "reference": "bed4ecbdd7f312ab6bb39561ac191f520bcee386" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Roave/Signature/zipball/bed4ecbdd7f312ab6bb39561ac191f520bcee386", + "reference": "bed4ecbdd7f312ab6bb39561ac191f520bcee386", + "shasum": "" + }, + "require": { + "php": "^7.0|^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^5.6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Roave\\Signature\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Sign and verify stuff", + "time": "2017-02-17T13:53:21+00:00" + }, + { + "name": "seld/cli-prompt", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/cli-prompt.git", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\CliPrompt\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", + "keywords": [ + "cli", + "console", + "hidden", + "input", + "prompt" + ], + "time": "2017-03-18T11:32:45+00:00" + }, + { + "name": "seld/jsonlint", + "version": "1.7.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/jsonlint.git", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/d15f59a67ff805a44c50ea0516d2341740f81a38", + "reference": "d15f59a67ff805a44c50ea0516d2341740f81a38", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "bin": [ + "bin/jsonlint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Seld\\JsonLint\\": "src/Seld/JsonLint/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "JSON Linter", + "keywords": [ + "json", + "linter", + "parser", + "validator" + ], + "time": "2018-01-24T12:46:19+00:00" + }, + { + "name": "seld/phar-utils", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/phar-utils.git", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a", + "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\PharUtils\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "PHAR file format utilities, for when PHP phars you up", + "keywords": [ + "phra" + ], + "time": "2015-10-13T18:44:15+00:00" + }, + { + "name": "symfony/console", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", + "reference": "3e820bc2c520a87ca209ad8fa961c97f42e0b4ae", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/process": "<3.3" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~3.4|~4.0", + "symfony/dependency-injection": "~3.4|~4.0", + "symfony/event-dispatcher": "~3.4|~4.0", + "symfony/lock": "~3.4|~4.0", + "symfony/process": "~3.4|~4.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "time": "2018-04-30T01:23:47+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", + "reference": "5d2d655b2c72fc4d9bf7e9bf14f72a447b940f21", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "time": "2018-02-22T10:50:29+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", + "reference": "ca27c02b7a3fef4828c998c2ff9ba7aae1641c49", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "time": "2018-04-04T05:10:37+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "3296adf6a6454a050679cde90f95350ad604b171" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171", + "reference": "3296adf6a6454a050679cde90f95350ad604b171", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2018-04-26T10:06:28+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.8.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "a4576e282d782ad82397f3e4ec1df8e0f0cafb46" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/a4576e282d782ad82397f3e4ec1df8e0f0cafb46", + "reference": "a4576e282d782ad82397f3e4ec1df8e0f0cafb46", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "time": "2018-04-26T10:06:28+00:00" + }, + { + "name": "symfony/process", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25", + "reference": "d7dc1ee5dfe9f732cb1bba7310f5b99f2b7a6d25", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "time": "2018-04-03T05:24:00+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v4.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "3c34cf3f4bbac9e003d9325225e9ef1a49180a18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3c34cf3f4bbac9e003d9325225e9ef1a49180a18", + "reference": "3c34cf3f4bbac9e003d9325225e9ef1a49180a18", + "shasum": "" + }, + "require": { + "php": "^7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php72": "~1.5" + }, + "conflict": { + "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0" + }, + "require-dev": { + "ext-iconv": "*", + "twig/twig": "~1.34|~2.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony mechanism for exploring and dumping PHP variables", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "time": "2018-04-26T16:12:06+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-01-29T19:49:41+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "time": "2015-12-17T08:42:14+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "humbug/box": 15 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/app/vendor/seld/cli-prompt/.gitignore b/app/vendor/seld/cli-prompt/.gitignore deleted file mode 100644 index 42cd73d95..000000000 --- a/app/vendor/seld/cli-prompt/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/vendor/ \ No newline at end of file diff --git a/app/vendor/seld/cli-prompt/README.md b/app/vendor/seld/cli-prompt/README.md deleted file mode 100644 index d5a046a14..000000000 --- a/app/vendor/seld/cli-prompt/README.md +++ /dev/null @@ -1,61 +0,0 @@ -CLI-Prompt -========== - -While prompting for user input using `fgets()` is quite easy, sometimes you -need to prompt for sensitive information. In these cases, the characters typed -in by the user should not be directly visible, and this is quite a pain to -do in a cross-platform way. - -This tiny package fixes just that for you: - -```php - Prompts the user for input and hides what they type. If this fails for any - > reason and `$allowFallback` is set to `true` the prompt will be done using - > the usual `fgets()` and characters will be visible. - -- `Seld\CliPrompt\CliPrompt::prompt();` - - > Regular user prompt for input with characters being shown on screen. - -In both cases, the trailing newline the user enters when submitting the answer -is trimmed. - -Requirements ------------- - -PHP 5.3 and above - -License -------- - -CLI-Prompt is licensed under the MIT License - see the LICENSE file for details - -Acknowledgments ---------------- - -- This project uses hiddeninput.exe to prompt for passwords on Windows, sources - and details can be found on the [github page of the project](https://github.com/Seldaek/hidden-input). diff --git a/app/vendor/seld/cli-prompt/composer.json b/app/vendor/seld/cli-prompt/composer.json deleted file mode 100644 index e36643796..000000000 --- a/app/vendor/seld/cli-prompt/composer.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "name": "seld/cli-prompt", - "description": "Allows you to prompt for user input on the command line, and optionally hide the characters they type", - "type": "library", - "keywords": ["cli", "console", "hidden", "input", "prompt"], - "license": "MIT", - "require": { - "php": ">=5.3" - }, - "authors": [ - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "autoload": { - "psr-4": { - "Seld\\CliPrompt\\": "src/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - } -} diff --git a/app/vendor/seld/cli-prompt/res/example.php b/app/vendor/seld/cli-prompt/res/example.php deleted file mode 100644 index 5ce5b23fd..000000000 --- a/app/vendor/seld/cli-prompt/res/example.php +++ /dev/null @@ -1,15 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Seld\CliPrompt; - -class CliPrompt -{ - /** - * Prompts the user for input and shows what they type - * - * @return string - */ - public static function prompt() - { - $stdin = fopen('php://stdin', 'r'); - $answer = self::trimAnswer(fgets($stdin, 4096)); - fclose($stdin); - - return $answer; - } - - /** - * Prompts the user for input and hides what they type - * - * @param bool $allowFallback If prompting fails for any reason and this is set to true the prompt - * will be done using the regular prompt() function, otherwise a - * \RuntimeException is thrown. - * @return string - * @throws RuntimeException on failure to prompt, unless $allowFallback is true - */ - public static function hiddenPrompt($allowFallback = false) - { - // handle windows - if (defined('PHP_WINDOWS_VERSION_BUILD')) { - // fallback to hiddeninput executable - $exe = __DIR__.'\\..\\res\\hiddeninput.exe'; - - // handle code running from a phar - if ('phar:' === substr(__FILE__, 0, 5)) { - $tmpExe = sys_get_temp_dir().'/hiddeninput.exe'; - - // use stream_copy_to_stream instead of copy - // to work around https://bugs.php.net/bug.php?id=64634 - $source = fopen($exe, 'r'); - $target = fopen($tmpExe, 'w+'); - stream_copy_to_stream($source, $target); - fclose($source); - fclose($target); - unset($source, $target); - - $exe = $tmpExe; - } - - $output = shell_exec($exe); - - // clean up - if (isset($tmpExe)) { - unlink($tmpExe); - } - - if ($output !== null) { - // output a newline to be on par with the regular prompt() - echo PHP_EOL; - - return self::trimAnswer($output); - } - } - - if (file_exists('/usr/bin/env')) { - // handle other OSs with bash/zsh/ksh/csh if available to hide the answer - $test = "/usr/bin/env %s -c 'echo OK' 2> /dev/null"; - foreach (array('bash', 'zsh', 'ksh', 'csh', 'sh') as $sh) { - if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) { - $shell = $sh; - break; - } - } - - if (isset($shell)) { - $readCmd = ($shell === 'csh') ? 'set mypassword = $<' : 'read -r mypassword'; - $command = sprintf("/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \$mypassword'", $shell, $readCmd); - $output = shell_exec($command); - - if ($output !== null) { - // output a newline to be on par with the regular prompt() - echo PHP_EOL; - - return self::trimAnswer($output); - } - } - } - - // not able to hide the answer - if (!$allowFallback) { - throw new \RuntimeException('Could not prompt for input in a secure fashion, aborting'); - } - - return self::prompt(); - } - - private static function trimAnswer($str) - { - return preg_replace('{\r?\n$}D', '', $str); - } -} diff --git a/app/vendor/squizlabs/php_codesniffer/README.md b/app/vendor/squizlabs/php_codesniffer/README.md index 26e24c567..096596214 100644 --- a/app/vendor/squizlabs/php_codesniffer/README.md +++ b/app/vendor/squizlabs/php_codesniffer/README.md @@ -11,12 +11,19 @@ PHP\_CodeSniffer requires PHP version 5.4.0 or greater, although individual snif ## Installation The easiest way to get started with PHP\_CodeSniffer is to download the Phar files for each of the commands: +``` +# Download using curl +curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar +curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar - curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar - php phpcs.phar -h +# Or download using wget +wget https://squizlabs.github.io/PHP_CodeSniffer/phpcs.phar +wget https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar - curl -OL https://squizlabs.github.io/PHP_CodeSniffer/phpcbf.phar - php phpcbf.phar -h +# Then test the downloaded PHARs +php phpcs.phar -h +php phpcbf.phar -h +``` ### Composer If you use Composer, you can install PHP_CodeSniffer system-wide with the following command: @@ -75,3 +82,26 @@ Bug reports and feature requests can be submitted on the [Github Issue Tracker]( ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) for information. + +## Versioning + +PHP_CodeSniffer uses a `MAJOR.MINOR.PATCH` version number format. + +The `MAJOR` version is incremented when: +- backwards-incompatible changes are made to how the `phpcs` or `phpcbf` commands are used, or +- backwards-incompatible changes are made to the `ruleset.xml` format, or +- backwards-incompatible changes are made to the API used by sniff developers, or +- custom PHP_CodeSniffer token types are removed + +The `MINOR` version is incremented when: +- new backwards-compatible features are added to the `phpcs` and `phpcbf` commands, or +- backwards-compatible changes are made to the `ruleset.xml` format, or +- backwards-compatible changes are made to the API used by sniff developers, or +- new sniffs are added to an included standard + +> NOTE: Backwards-compatible changes to the API used by sniff develpers will allow an existing sniff to continue running without producing fatal errors but may not result in the sniff reporting the same errors as it did previously without changes being required. + +The `PATCH` version is incremented when: +- backwards-compatible bug fixes are made + +> NOTE: As PHP_CodeSniffer exists to report and fix issues, most bugs are the result of coding standard errors being incorrectly reported or coding standard errors not being reported when they should be. This means that the messages produced by PHP_CodeSniffer, and the fixes it makes, are likely to be different between PATCH versions. diff --git a/app/vendor/squizlabs/php_codesniffer/autoload.php b/app/vendor/squizlabs/php_codesniffer/autoload.php index e4d21ace0..108c80c13 100644 --- a/app/vendor/squizlabs/php_codesniffer/autoload.php +++ b/app/vendor/squizlabs/php_codesniffer/autoload.php @@ -217,6 +217,18 @@ public static function addSearchPath($path, $nsPrefix='') }//end addSearchPath() + /** + * Retrieve the namespaces and paths registered by external standards. + * + * @return array + */ + public static function getSearchPaths() + { + return self::$searchPaths; + + }//end getSearchPaths() + + /** * Gets the class name for the given file path. * diff --git a/app/vendor/squizlabs/php_codesniffer/composer.json b/app/vendor/squizlabs/php_codesniffer/composer.json index fa6270136..d13522f15 100644 --- a/app/vendor/squizlabs/php_codesniffer/composer.json +++ b/app/vendor/squizlabs/php_codesniffer/composer.json @@ -31,7 +31,7 @@ "ext-simplexml": "*" }, "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "bin": [ "bin/phpcs", diff --git a/app/vendor/squizlabs/php_codesniffer/phpcs.xml.dist b/app/vendor/squizlabs/php_codesniffer/phpcs.xml.dist index cea560f2c..2828e1b0a 100644 --- a/app/vendor/squizlabs/php_codesniffer/phpcs.xml.dist +++ b/app/vendor/squizlabs/php_codesniffer/phpcs.xml.dist @@ -4,6 +4,7 @@ autoload.php bin + scripts src tests @@ -28,6 +29,7 @@ +
@@ -47,6 +49,7 @@ + @@ -67,6 +70,13 @@ + + + + + + + @@ -103,6 +113,19 @@ + + + + + + + + + + + + + error diff --git a/app/vendor/squizlabs/php_codesniffer/phpcs.xsd b/app/vendor/squizlabs/php_codesniffer/phpcs.xsd index e2197630f..79019d0bc 100644 --- a/app/vendor/squizlabs/php_codesniffer/phpcs.xsd +++ b/app/vendor/squizlabs/php_codesniffer/phpcs.xsd @@ -75,6 +75,14 @@ + + + + + + + + @@ -83,7 +91,7 @@ - + diff --git a/app/vendor/squizlabs/php_codesniffer/scripts/build-phar.php b/app/vendor/squizlabs/php_codesniffer/scripts/build-phar.php index ee01c834d..6b2800c88 100644 --- a/app/vendor/squizlabs/php_codesniffer/scripts/build-phar.php +++ b/app/vendor/squizlabs/php_codesniffer/scripts/build-phar.php @@ -21,10 +21,10 @@ exit(1); } -$scripts = array( - 'phpcs', - 'phpcbf', - ); +$scripts = [ + 'phpcs', + 'phpcbf', +]; foreach ($scripts as $script) { echo "Building $script phar".PHP_EOL; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Config.php b/app/vendor/squizlabs/php_codesniffer/src/Config.php index 44f7149a0..3da4d7a6f 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Config.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Config.php @@ -23,7 +23,7 @@ class Config * * @var string */ - const VERSION = '3.2.2'; + const VERSION = '3.3.2'; /** * Package stability; either stable, beta or alpha. @@ -59,7 +59,7 @@ class Config * bool showSources Show sniff source codes in report output. * bool showProgress Show basic progress information while running. * bool quiet Quiet mode; disables progress and verbose output. - * bool annotations Process @codingStandard annotations. + * bool annotations Process phpcs: annotations. * int tabWidth How many spaces each tab is worth. * string encoding The encoding of the files being checked. * string[] sniffs The sniffs that should be used for checking. @@ -158,7 +158,7 @@ class Config * * @var array */ - private $overriddenDefaults = []; + private static $overriddenDefaults = []; /** * Config file data that has been loaded for the run. @@ -334,7 +334,7 @@ public function __construct(array $cliArgs=[], $dieOnUnknownArg=true) $this->restoreDefaults(); $this->setCommandLineValues($cliArgs); - if (isset($this->overriddenDefaults['standards']) === false) { + if (isset(self::$overriddenDefaults['standards']) === false) { // They did not supply a standard to use. // Look for a default ruleset in the current directory or higher. $currentDir = getcwd(); @@ -389,8 +389,8 @@ public function __construct(array $cliArgs=[], $dieOnUnknownArg=true) if (trim($fileContents) !== '') { $this->stdin = true; $this->stdinContent = $fileContents; - $this->overriddenDefaults['stdin'] = true; - $this->overriddenDefaults['stdinContent'] = true; + self::$overriddenDefaults['stdin'] = true; + self::$overriddenDefaults['stdinContent'] = true; } }//end if @@ -421,7 +421,7 @@ public function setCommandLineValues($args) if ($arg === '-') { // Asking to read from STDIN. $this->stdin = true; - $this->overriddenDefaults['stdin'] = true; + self::$overriddenDefaults['stdin'] = true; continue; } @@ -608,23 +608,23 @@ public function processShortArgument($arg, $pos) } $this->verbosity++; - $this->overriddenDefaults['verbosity'] = true; + self::$overriddenDefaults['verbosity'] = true; break; case 'l' : $this->local = true; - $this->overriddenDefaults['local'] = true; + self::$overriddenDefaults['local'] = true; break; case 's' : $this->showSources = true; - $this->overriddenDefaults['showSources'] = true; + self::$overriddenDefaults['showSources'] = true; break; case 'a' : $this->interactive = true; - $this->overriddenDefaults['interactive'] = true; + self::$overriddenDefaults['interactive'] = true; break; case 'e': $this->explain = true; - $this->overriddenDefaults['explain'] = true; + self::$overriddenDefaults['explain'] = true; break; case 'p' : if ($this->quiet === true) { @@ -633,7 +633,7 @@ public function processShortArgument($arg, $pos) } $this->showProgress = true; - $this->overriddenDefaults['showProgress'] = true; + self::$overriddenDefaults['showProgress'] = true; break; case 'q' : // Quiet mode disables a few other settings as well. @@ -641,11 +641,11 @@ public function processShortArgument($arg, $pos) $this->showProgress = false; $this->verbosity = 0; - $this->overriddenDefaults['quiet'] = true; + self::$overriddenDefaults['quiet'] = true; break; case 'm' : $this->recordErrors = false; - $this->overriddenDefaults['recordErrors'] = true; + self::$overriddenDefaults['recordErrors'] = true; break; case 'd' : $ini = explode('=', $this->cliArgs[($pos + 1)]); @@ -657,15 +657,15 @@ public function processShortArgument($arg, $pos) } break; case 'n' : - if (isset($this->overriddenDefaults['warningSeverity']) === false) { + if (isset(self::$overriddenDefaults['warningSeverity']) === false) { $this->warningSeverity = 0; - $this->overriddenDefaults['warningSeverity'] = true; + self::$overriddenDefaults['warningSeverity'] = true; } break; case 'w' : - if (isset($this->overriddenDefaults['warningSeverity']) === false) { + if (isset(self::$overriddenDefaults['warningSeverity']) === false) { $this->warningSeverity = $this->errorSeverity; - $this->overriddenDefaults['warningSeverity'] = true; + self::$overriddenDefaults['warningSeverity'] = true; } break; default: @@ -703,46 +703,46 @@ public function processLongArgument($arg, $pos) $output .= 'by Squiz (http://www.squiz.net)'.PHP_EOL; throw new DeepExitException($output, 0); case 'colors': - if (isset($this->overriddenDefaults['colors']) === true) { + if (isset(self::$overriddenDefaults['colors']) === true) { break; } $this->colors = true; - $this->overriddenDefaults['colors'] = true; + self::$overriddenDefaults['colors'] = true; break; case 'no-colors': - if (isset($this->overriddenDefaults['colors']) === true) { + if (isset(self::$overriddenDefaults['colors']) === true) { break; } $this->colors = false; - $this->overriddenDefaults['colors'] = true; + self::$overriddenDefaults['colors'] = true; break; case 'cache': - if (isset($this->overriddenDefaults['cache']) === true) { + if (isset(self::$overriddenDefaults['cache']) === true) { break; } if (defined('PHP_CODESNIFFER_IN_TESTS') === false) { $this->cache = true; - $this->overriddenDefaults['cache'] = true; + self::$overriddenDefaults['cache'] = true; } break; case 'no-cache': - if (isset($this->overriddenDefaults['cache']) === true) { + if (isset(self::$overriddenDefaults['cache']) === true) { break; } $this->cache = false; - $this->overriddenDefaults['cache'] = true; + self::$overriddenDefaults['cache'] = true; break; case 'ignore-annotations': - if (isset($this->overriddenDefaults['annotations']) === true) { + if (isset(self::$overriddenDefaults['annotations']) === true) { break; } $this->annotations = false; - $this->overriddenDefaults['annotations'] = true; + self::$overriddenDefaults['annotations'] = true; break; case 'config-set': if (isset($this->cliArgs[($pos + 1)]) === false @@ -816,10 +816,15 @@ public function processLongArgument($arg, $pos) $this->cliArgs[($pos + 1)] = ''; $this->cliArgs[($pos + 2)] = ''; self::setConfigData($key, $value, true); + if (isset(self::$overriddenDefaults['runtime-set']) === false) { + self::$overriddenDefaults['runtime-set'] = []; + } + + self::$overriddenDefaults['runtime-set'][$key] = true; break; default: if (substr($arg, 0, 7) === 'sniffs=') { - if (isset($this->overriddenDefaults['sniffs']) === true) { + if (isset(self::$overriddenDefaults['sniffs']) === true) { break; } @@ -833,9 +838,9 @@ public function processLongArgument($arg, $pos) } $this->sniffs = $sniffs; - $this->overriddenDefaults['sniffs'] = true; + self::$overriddenDefaults['sniffs'] = true; } else if (substr($arg, 0, 8) === 'exclude=') { - if (isset($this->overriddenDefaults['exclude']) === true) { + if (isset(self::$overriddenDefaults['exclude']) === true) { break; } @@ -849,20 +854,20 @@ public function processLongArgument($arg, $pos) } $this->exclude = $sniffs; - $this->overriddenDefaults['exclude'] = true; + self::$overriddenDefaults['exclude'] = true; } else if (defined('PHP_CODESNIFFER_IN_TESTS') === false && substr($arg, 0, 6) === 'cache=' ) { - if ((isset($this->overriddenDefaults['cache']) === true + if ((isset(self::$overriddenDefaults['cache']) === true && $this->cache === false) - || isset($this->overriddenDefaults['cacheFile']) === true + || isset(self::$overriddenDefaults['cacheFile']) === true ) { break; } // Turn caching on. $this->cache = true; - $this->overriddenDefaults['cache'] = true; + self::$overriddenDefaults['cache'] = true; $this->cacheFile = Util\Common::realpath(substr($arg, 6)); @@ -895,7 +900,7 @@ public function processLongArgument($arg, $pos) } }//end if - $this->overriddenDefaults['cacheFile'] = true; + self::$overriddenDefaults['cacheFile'] = true; if (is_dir($this->cacheFile) === true) { $error = 'ERROR: The specified cache file path "'.$this->cacheFile.'" is a directory'.PHP_EOL.PHP_EOL; @@ -917,7 +922,7 @@ public function processLongArgument($arg, $pos) } $this->bootstrap = array_merge($this->bootstrap, $bootstrap); - $this->overriddenDefaults['bootstrap'] = true; + self::$overriddenDefaults['bootstrap'] = true; } else if (substr($arg, 0, 10) === 'file-list=') { $fileList = substr($arg, 10); $path = Util\Common::realpath($fileList); @@ -939,7 +944,7 @@ public function processLongArgument($arg, $pos) $this->processFilePath($inputFile); } } else if (substr($arg, 0, 11) === 'stdin-path=') { - if (isset($this->overriddenDefaults['stdinPath']) === true) { + if (isset(self::$overriddenDefaults['stdinPath']) === true) { break; } @@ -950,9 +955,9 @@ public function processLongArgument($arg, $pos) $this->stdinPath = trim(substr($arg, 11)); } - $this->overriddenDefaults['stdinPath'] = true; + self::$overriddenDefaults['stdinPath'] = true; } else if (PHP_CODESNIFFER_CBF === false && substr($arg, 0, 12) === 'report-file=') { - if (isset($this->overriddenDefaults['reportFile']) === true) { + if (isset(self::$overriddenDefaults['reportFile']) === true) { break; } @@ -987,7 +992,7 @@ public function processLongArgument($arg, $pos) } }//end if - $this->overriddenDefaults['reportFile'] = true; + self::$overriddenDefaults['reportFile'] = true; if (is_dir($this->reportFile) === true) { $error = 'ERROR: The specified report file path "'.$this->reportFile.'" is a directory'.PHP_EOL.PHP_EOL; @@ -995,18 +1000,18 @@ public function processLongArgument($arg, $pos) throw new DeepExitException($error, 3); } } else if (substr($arg, 0, 13) === 'report-width=') { - if (isset($this->overriddenDefaults['reportWidth']) === true) { + if (isset(self::$overriddenDefaults['reportWidth']) === true) { break; } $this->reportWidth = substr($arg, 13); - $this->overriddenDefaults['reportWidth'] = true; + self::$overriddenDefaults['reportWidth'] = true; } else if (substr($arg, 0, 9) === 'basepath=') { - if (isset($this->overriddenDefaults['basepath']) === true) { + if (isset(self::$overriddenDefaults['basepath']) === true) { break; } - $this->overriddenDefaults['basepath'] = true; + self::$overriddenDefaults['basepath'] = true; if (substr($arg, 9) === '') { $this->basepath = null; @@ -1041,6 +1046,12 @@ public function processLongArgument($arg, $pos) $output = null; } else { $dir = dirname($output); + if (is_dir($dir) === false) { + $error = 'ERROR: The specified '.$report.' report file path "'.$output.'" points to a non-existent directory'.PHP_EOL.PHP_EOL; + $error .= $this->printShortUsage(true); + throw new DeepExitException($error, 3); + } + if ($dir === '.') { // Passed report file is a filename in the current directory. $output = getcwd().'/'.basename($output); @@ -1063,7 +1074,7 @@ public function processLongArgument($arg, $pos) $reports[$report] = $output; } else { // This is a single report. - if (isset($this->overriddenDefaults['reports']) === true) { + if (isset(self::$overriddenDefaults['reports']) === true) { break; } @@ -1074,29 +1085,29 @@ public function processLongArgument($arg, $pos) }//end if // Remove the default value so the CLI value overrides it. - if (isset($this->overriddenDefaults['reports']) === false) { + if (isset(self::$overriddenDefaults['reports']) === false) { $this->reports = $reports; } else { $this->reports = array_merge($this->reports, $reports); } - $this->overriddenDefaults['reports'] = true; + self::$overriddenDefaults['reports'] = true; } else if (substr($arg, 0, 7) === 'filter=') { - if (isset($this->overriddenDefaults['filter']) === true) { + if (isset(self::$overriddenDefaults['filter']) === true) { break; } $this->filter = substr($arg, 7); - $this->overriddenDefaults['filter'] = true; + self::$overriddenDefaults['filter'] = true; } else if (substr($arg, 0, 9) === 'standard=') { $standards = trim(substr($arg, 9)); if ($standards !== '') { $this->standards = explode(',', $standards); } - $this->overriddenDefaults['standards'] = true; + self::$overriddenDefaults['standards'] = true; } else if (substr($arg, 0, 11) === 'extensions=') { - if (isset($this->overriddenDefaults['extensions']) === true) { + if (isset(self::$overriddenDefaults['extensions']) === true) { break; } @@ -1119,47 +1130,47 @@ public function processLongArgument($arg, $pos) } $this->extensions = $newExtensions; - $this->overriddenDefaults['extensions'] = true; + self::$overriddenDefaults['extensions'] = true; } else if (substr($arg, 0, 7) === 'suffix=') { - if (isset($this->overriddenDefaults['suffix']) === true) { + if (isset(self::$overriddenDefaults['suffix']) === true) { break; } $this->suffix = substr($arg, 7); - $this->overriddenDefaults['suffix'] = true; + self::$overriddenDefaults['suffix'] = true; } else if (substr($arg, 0, 9) === 'parallel=') { - if (isset($this->overriddenDefaults['parallel']) === true) { + if (isset(self::$overriddenDefaults['parallel']) === true) { break; } $this->parallel = max((int) substr($arg, 9), 1); - $this->overriddenDefaults['parallel'] = true; + self::$overriddenDefaults['parallel'] = true; } else if (substr($arg, 0, 9) === 'severity=') { $this->errorSeverity = (int) substr($arg, 9); $this->warningSeverity = $this->errorSeverity; - if (isset($this->overriddenDefaults['errorSeverity']) === false) { - $this->overriddenDefaults['errorSeverity'] = true; + if (isset(self::$overriddenDefaults['errorSeverity']) === false) { + self::$overriddenDefaults['errorSeverity'] = true; } - if (isset($this->overriddenDefaults['warningSeverity']) === false) { - $this->overriddenDefaults['warningSeverity'] = true; + if (isset(self::$overriddenDefaults['warningSeverity']) === false) { + self::$overriddenDefaults['warningSeverity'] = true; } } else if (substr($arg, 0, 15) === 'error-severity=') { - if (isset($this->overriddenDefaults['errorSeverity']) === true) { + if (isset(self::$overriddenDefaults['errorSeverity']) === true) { break; } $this->errorSeverity = (int) substr($arg, 15); - $this->overriddenDefaults['errorSeverity'] = true; + self::$overriddenDefaults['errorSeverity'] = true; } else if (substr($arg, 0, 17) === 'warning-severity=') { - if (isset($this->overriddenDefaults['warningSeverity']) === true) { + if (isset(self::$overriddenDefaults['warningSeverity']) === true) { break; } $this->warningSeverity = (int) substr($arg, 17); - $this->overriddenDefaults['warningSeverity'] = true; + self::$overriddenDefaults['warningSeverity'] = true; } else if (substr($arg, 0, 7) === 'ignore=') { - if (isset($this->overriddenDefaults['ignored']) === true) { + if (isset(self::$overriddenDefaults['ignored']) === true) { break; } @@ -1181,30 +1192,30 @@ public function processLongArgument($arg, $pos) } $this->ignored = $ignored; - $this->overriddenDefaults['ignored'] = true; + self::$overriddenDefaults['ignored'] = true; } else if (substr($arg, 0, 10) === 'generator=' && PHP_CODESNIFFER_CBF === false ) { - if (isset($this->overriddenDefaults['generator']) === true) { + if (isset(self::$overriddenDefaults['generator']) === true) { break; } $this->generator = substr($arg, 10); - $this->overriddenDefaults['generator'] = true; + self::$overriddenDefaults['generator'] = true; } else if (substr($arg, 0, 9) === 'encoding=') { - if (isset($this->overriddenDefaults['encoding']) === true) { + if (isset(self::$overriddenDefaults['encoding']) === true) { break; } $this->encoding = strtolower(substr($arg, 9)); - $this->overriddenDefaults['encoding'] = true; + self::$overriddenDefaults['encoding'] = true; } else if (substr($arg, 0, 10) === 'tab-width=') { - if (isset($this->overriddenDefaults['tabWidth']) === true) { + if (isset(self::$overriddenDefaults['tabWidth']) === true) { break; } $this->tabWidth = (int) substr($arg, 10); - $this->overriddenDefaults['tabWidth'] = true; + self::$overriddenDefaults['tabWidth'] = true; } else { if ($this->dieOnUnknownArg === false) { $eqPos = strpos($arg, '='); @@ -1223,7 +1234,6 @@ public function processLongArgument($arg, $pos) $this->processUnknownArgument('--'.$arg, $pos); } }//end if - break; }//end switch @@ -1282,10 +1292,12 @@ public function processFilePath($path) $error .= $this->printShortUsage(true); throw new DeepExitException($error, 3); } else { + // Can't modify the files array directly because it's not a real + // class member, so need to use this little get/modify/set trick. $files = $this->files; $files[] = $file; $this->files = $files; - $this->overriddenDefaults['files'] = true; + self::$overriddenDefaults['files'] = true; } }//end processFilePath() @@ -1379,7 +1391,7 @@ public function printPHPCSUsage() echo ' --no-colors Do not use colors in output (this is the default)'.PHP_EOL; echo ' --cache Cache results between runs'.PHP_EOL; echo ' --no-cache Do not cache results between runs (this is the default)'.PHP_EOL; - echo ' --ignore-annotations Ignore all @codingStandard annotations in code comments'.PHP_EOL; + echo ' --ignore-annotations Ignore all phpcs: annotations in code comments'.PHP_EOL; echo PHP_EOL; echo ' Use a specific file for caching (uses a temporary file by default)'.PHP_EOL; echo ' A path to strip from the front of file paths inside reports'.PHP_EOL; @@ -1439,7 +1451,7 @@ public function printPHPCBFUsage() echo PHP_EOL; echo ' --help Print this help message'.PHP_EOL; echo ' --version Print version information'.PHP_EOL; - echo ' --ignore-annotations Ignore all @codingStandard annotations in code comments'.PHP_EOL; + echo ' --ignore-annotations Ignore all phpcs: annotations in code comments'.PHP_EOL; echo PHP_EOL; echo ' A path to strip from the front of file paths inside reports'.PHP_EOL; echo ' A comma separated list of files to run before processing begins'.PHP_EOL; @@ -1504,6 +1516,11 @@ public static function getExecutablePath($name) return $data; } + if ($name === "php") { + // For php, we know the executable path. There's no need to look it up. + return PHP_BINARY; + } + if (array_key_exists($name, self::$executablePaths) === true) { return self::$executablePaths[$name]; } @@ -1542,6 +1559,12 @@ public static function getExecutablePath($name) */ public static function setConfigData($key, $value, $temp=false) { + if (isset(self::$overriddenDefaults['runtime-set']) === true + && isset(self::$overriddenDefaults['runtime-set'][$key]) === true + ) { + return false; + } + if ($temp === false) { $path = ''; if (is_callable('\Phar::running') === true) { diff --git a/app/vendor/squizlabs/php_codesniffer/src/Files/File.php b/app/vendor/squizlabs/php_codesniffer/src/Files/File.php index 507936877..effc1b84c 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Files/File.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Files/File.php @@ -50,7 +50,7 @@ class File /** * If TRUE, the entire file is being ignored. * - * @var string + * @var boolean */ public $ignored = false; @@ -75,6 +75,13 @@ class File */ public $tokenizer = null; + /** + * The name of the tokenizer being used for this file. + * + * @var string + */ + public $tokenizerType = 'PHP'; + /** * Was the file loaded from cache? * @@ -239,7 +246,8 @@ public function __construct($path, Ruleset $ruleset, Config $config) $this->configCache['errorSeverity'] = $this->config->errorSeverity; $this->configCache['warningSeverity'] = $this->config->warningSeverity; $this->configCache['recordErrors'] = $this->config->recordErrors; - $this->configCache['ignorePatterns'] = $this->ruleset->getIgnorePatterns(); + $this->configCache['ignorePatterns'] = $this->ruleset->ignorePatterns; + $this->configCache['includePatterns'] = $this->ruleset->includePatterns; }//end __construct() @@ -351,9 +359,9 @@ public function process() $start = strpos($commentText, '@codingStandardsChangeSetting'); $comment = substr($commentText, ($start + 30)); $parts = explode(' ', $comment); - if ($parts >= 3) { + if (count($parts) >= 2) { $sniffParts = explode('.', $parts[0]); - if ($sniffParts >= 3) { + if (count($sniffParts) >= 3) { // If the sniff code is not known to us, it has not been registered in this run. // But don't throw an error as it could be there for a different standard to use. if (isset($this->ruleset->sniffCodes[$parts[0]]) === true) { @@ -366,7 +374,9 @@ public function process() } } }//end if - } else if (substr($commentTextLower, 0, 16) === 'phpcs:ignorefile') { + } else if (substr($commentTextLower, 0, 16) === 'phpcs:ignorefile' + || substr($commentTextLower, 0, 17) === '@phpcs:ignorefile' + ) { // Ignoring the whole file, just a little late. $this->errors = []; $this->warnings = []; @@ -374,12 +384,20 @@ public function process() $this->warningCount = 0; $this->fixableCount = 0; return; - } else if (substr($commentTextLower, 0, 9) === 'phpcs:set') { + } else if (substr($commentTextLower, 0, 9) === 'phpcs:set' + || substr($commentTextLower, 0, 10) === '@phpcs:set' + ) { + // If the @phpcs: syntax is being used, strip the @ to make + // comparisons easier. + if ($commentText[0] === '@') { + $commentText = substr($commentText, 1); + } + // Need to maintain case here, to get the correct sniff code. $parts = explode(' ', substr($commentText, 10)); - if ($parts >= 3) { + if (count($parts) >= 2) { $sniffParts = explode('.', $parts[0]); - if ($sniffParts >= 3) { + if (count($sniffParts) >= 3) { // If the sniff code is not known to us, it has not been registered in this run. // But don't throw an error as it could be there for a different standard to use. if (isset($this->ruleset->sniffCodes[$parts[0]]) === true) { @@ -816,7 +834,7 @@ public function addFixableWarning( protected function addMessage($error, $message, $line, $column, $code, $data, $severity, $fixable) { // Check if this line is ignoring all message codes. - if (isset($this->tokenizer->ignoredLines[$line]['all']) === true) { + if (isset($this->tokenizer->ignoredLines[$line]['.all']) === true) { return false; } @@ -846,12 +864,32 @@ protected function addMessage($error, $message, $line, $column, $code, $data, $s ]; }//end if - // Check if this line is ignoring this specific message. - foreach ($checkCodes as $checkCode) { - if (isset($this->tokenizer->ignoredLines[$line][$checkCode]) === true) { + if (isset($this->tokenizer->ignoredLines[$line]) === true) { + // Check if this line is ignoring this specific message. + $ignored = false; + foreach ($checkCodes as $checkCode) { + if (isset($this->tokenizer->ignoredLines[$line][$checkCode]) === true) { + $ignored = true; + break; + } + } + + // If it is ignored, make sure it's not whitelisted. + if ($ignored === true + && isset($this->tokenizer->ignoredLines[$line]['.except']) === true + ) { + foreach ($checkCodes as $checkCode) { + if (isset($this->tokenizer->ignoredLines[$line]['.except'][$checkCode]) === true) { + $ignored = false; + break; + } + } + } + + if ($ignored === true) { return false; } - } + }//end if $includeAll = true; if ($this->configCache['cache'] === false @@ -927,11 +965,21 @@ protected function addMessage($error, $message, $line, $column, $code, $data, $s // Make sure we are not ignoring this file. foreach ($checkCodes as $checkCode) { - if (isset($this->configCache['ignorePatterns'][$checkCode]) === false) { + $patterns = null; + + if (isset($this->configCache['includePatterns'][$checkCode]) === true) { + $patterns = $this->configCache['includePatterns'][$checkCode]; + $excluding = false; + } else if (isset($this->configCache['ignorePatterns'][$checkCode]) === true) { + $patterns = $this->configCache['ignorePatterns'][$checkCode]; + $excluding = true; + } + + if ($patterns === null) { continue; } - foreach ($this->configCache['ignorePatterns'][$checkCode] as $pattern => $type) { + foreach ($patterns as $pattern => $type) { // While there is support for a type of each pattern // (absolute or relative) we don't actually support it here. $replacements = [ @@ -947,7 +995,11 @@ protected function addMessage($error, $message, $line, $column, $code, $data, $s } $pattern = '`'.strtr($pattern, $replacements).'`i'; - if (preg_match($pattern, $this->path) === 1) { + $matched = preg_match($pattern, $this->path); + if (($matched === 1 && $excluding === true) + || ($matched === 0 && $excluding === false) + ) { + // This file path is being excluded, or not included. $this->ignoredCodes[$checkCode] = true; return false; } @@ -1005,7 +1057,7 @@ protected function addMessage($error, $message, $line, $column, $code, $data, $s /** - * Adds an warning to the warning stack. + * Record a metric about the file being examined. * * @param int $stackPtr The stack position where the metric was recorded. * @param string $metric The name of the metric being recorded. @@ -1214,6 +1266,8 @@ public function getDeclarationName($stackPtr) * 'pass_by_reference' => boolean, // Is the variable passed by reference? * 'variable_length' => boolean, // Is the param of variable length through use of `...` ? * 'type_hint' => string, // The type hint for the variable. + * 'type_hint_token' => integer, // The stack pointer to the type hint + * // or false if there is no type hint. * 'nullable_type' => boolean, // Is the variable using a nullable type? * ) * @@ -1247,6 +1301,7 @@ public function getMethodParameters($stackPtr) $passByReference = false; $variableLength = false; $typeHint = ''; + $typeHintToken = false; $nullableType = false; for ($i = $paramStart; $i <= $closer; $i++) { @@ -1280,8 +1335,11 @@ public function getMethodParameters($stackPtr) case T_ELLIPSIS: $variableLength = true; break; - case T_ARRAY_HINT: case T_CALLABLE: + if ($typeHintToken === false) { + $typeHintToken = $i; + } + $typeHint .= $this->tokens[$i]['content']; break; case T_SELF: @@ -1289,6 +1347,10 @@ public function getMethodParameters($stackPtr) case T_STATIC: // Self is valid, the others invalid, but were probably intended as type hints. if (isset($defaultStart) === false) { + if ($typeHintToken === false) { + $typeHintToken = $i; + } + $typeHint .= $this->tokens[$i]['content']; } break; @@ -1318,12 +1380,20 @@ public function getMethodParameters($stackPtr) } if ($defaultStart === null) { + if ($typeHintToken === false) { + $typeHintToken = $i; + } + $typeHint .= $this->tokens[$i]['content']; } break; case T_NS_SEPARATOR: // Part of a type hint or default value. if ($defaultStart === null) { + if ($typeHintToken === false) { + $typeHintToken = $i; + } + $typeHint .= $this->tokens[$i]['content']; } break; @@ -1338,7 +1408,7 @@ public function getMethodParameters($stackPtr) // If it's null, then there must be no parameters for this // method. if ($currVar === null) { - continue; + continue 2; } $vars[$paramCount] = []; @@ -1353,6 +1423,7 @@ public function getMethodParameters($stackPtr) $vars[$paramCount]['pass_by_reference'] = $passByReference; $vars[$paramCount]['variable_length'] = $variableLength; $vars[$paramCount]['type_hint'] = $typeHint; + $vars[$paramCount]['type_hint_token'] = $typeHintToken; $vars[$paramCount]['nullable_type'] = $nullableType; // Reset the vars, as we are about to process the next parameter. @@ -1361,6 +1432,7 @@ public function getMethodParameters($stackPtr) $passByReference = false; $variableLength = false; $typeHint = ''; + $typeHintToken = false; $nullableType = false; $paramCount++; @@ -1382,11 +1454,15 @@ public function getMethodParameters($stackPtr) * The format of the array is: * * array( - * 'scope' => 'public', // public protected or protected - * 'scope_specified' => true, // true is scope keyword was found. - * 'is_abstract' => false, // true if the abstract keyword was found. - * 'is_final' => false, // true if the final keyword was found. - * 'is_static' => false, // true if the static keyword was found. + * 'scope' => 'public', // public protected or protected + * 'scope_specified' => true, // true is scope keyword was found. + * 'return_type' => '', // the return type of the method. + * 'return_type_token' => integer, // The stack pointer to the start of the return type + * // or false if there is no return type. + * 'nullable_return_type' => false, // true if the return type is nullable. + * 'is_abstract' => false, // true if the abstract keyword was found. + * 'is_final' => false, // true if the final keyword was found. + * 'is_static' => false, // true if the static keyword was found. * ); * * @@ -1462,12 +1538,59 @@ public function getMethodProperties($stackPtr) }//end switch }//end for + $returnType = ''; + $returnTypeToken = false; + $nullableReturnType = false; + + if (isset($this->tokens[$stackPtr]['parenthesis_closer']) === true) { + $scopeOpener = null; + if (isset($this->tokens[$stackPtr]['scope_opener']) === true) { + $scopeOpener = $this->tokens[$stackPtr]['scope_opener']; + } + + $valid = [ + T_STRING => T_STRING, + T_CALLABLE => T_CALLABLE, + T_SELF => T_SELF, + T_PARENT => T_PARENT, + T_NS_SEPARATOR => T_NS_SEPARATOR, + ]; + + for ($i = $this->tokens[$stackPtr]['parenthesis_closer']; $i < $this->numTokens; $i++) { + if (($scopeOpener === null && $this->tokens[$i]['code'] === T_SEMICOLON) + || ($scopeOpener !== null && $i === $scopeOpener) + ) { + // End of function definition. + break; + } + + if ($this->tokens[$i]['code'] === T_NULLABLE) { + $nullableReturnType = true; + } + + if (isset($valid[$this->tokens[$i]['code']]) === true) { + if ($returnTypeToken === false) { + $returnTypeToken = $i; + } + + $returnType .= $this->tokens[$i]['content']; + } + } + }//end if + + if ($returnType !== '' && $nullableReturnType === true) { + $returnType = '?'.$returnType; + } + return [ - 'scope' => $scope, - 'scope_specified' => $scopeSpecified, - 'is_abstract' => $isAbstract, - 'is_final' => $isFinal, - 'is_static' => $isStatic, + 'scope' => $scope, + 'scope_specified' => $scopeSpecified, + 'return_type' => $returnType, + 'return_type_token' => $returnTypeToken, + 'nullable_return_type' => $nullableReturnType, + 'is_abstract' => $isAbstract, + 'is_final' => $isFinal, + 'is_static' => $isStatic, ]; }//end getMethodProperties() @@ -1481,8 +1604,9 @@ public function getMethodProperties($stackPtr) * * * array( - * 'scope' => 'public', // public protected or protected - * 'is_static' => false, // true if the static keyword was found. + * 'scope' => 'public', // public protected or protected. + * 'scope_specified' => false, // true if the scope was explicitly specified. + * 'is_static' => false, // true if the static keyword was found. * ); * * @@ -1527,22 +1651,29 @@ public function getMemberProperties($stackPtr) } $valid = [ - T_PUBLIC => T_PUBLIC, - T_PRIVATE => T_PRIVATE, - T_PROTECTED => T_PROTECTED, - T_STATIC => T_STATIC, - T_WHITESPACE => T_WHITESPACE, - T_COMMENT => T_COMMENT, - T_DOC_COMMENT => T_DOC_COMMENT, - T_VARIABLE => T_VARIABLE, - T_COMMA => T_COMMA, + T_PUBLIC => T_PUBLIC, + T_PRIVATE => T_PRIVATE, + T_PROTECTED => T_PROTECTED, + T_STATIC => T_STATIC, + T_VAR => T_VAR, ]; + $valid += Util\Tokens::$emptyTokens; + $scope = 'public'; $scopeSpecified = false; $isStatic = false; - for ($i = ($stackPtr - 1); $i > 0; $i--) { + $startOfStatement = $this->findPrevious( + [ + T_SEMICOLON, + T_OPEN_CURLY_BRACKET, + T_CLOSE_CURLY_BRACKET, + ], + ($stackPtr - 1) + ); + + for ($i = ($startOfStatement + 1); $i < $stackPtr; $i++) { if (isset($valid[$this->tokens[$i]['code']]) === false) { break; } @@ -1771,12 +1902,14 @@ public function isReference($stackPtr) * Returns the content of the tokens from the specified start position in * the token stack for the specified length. * - * @param int $start The position to start from in the token stack. - * @param int $length The length of tokens to traverse from the start pos. + * @param int $start The position to start from in the token stack. + * @param int $length The length of tokens to traverse from the start pos. + * @param int $origContent Whether the original content or the tab replaced + * content should be used. * * @return string The token contents. */ - public function getTokensAsString($start, $length) + public function getTokensAsString($start, $length, $origContent=false) { $str = ''; $end = ($start + $length); @@ -1785,7 +1918,13 @@ public function getTokensAsString($start, $length) } for ($i = $start; $i < $end; $i++) { - $str .= $this->tokens[$i]['content']; + // If tabs are being converted to spaces by the tokeniser, the + // original content should be used instead of the converted content. + if ($origContent === true && isset($this->tokens[$i]['orig_content']) === true) { + $str .= $this->tokens[$i]['orig_content']; + } else { + $str .= $this->tokens[$i]['content']; + } } return $str; @@ -2061,6 +2200,10 @@ public function findEndOfStatement($start, $ignore=null) && ($i === $this->tokens[$i]['scope_opener'] || $i === $this->tokens[$i]['scope_condition']) ) { + if ($i === $start && isset(Util\Tokens::$scopeOpeners[$this->tokens[$i]['code']]) === true) { + return $this->tokens[$i]['scope_closer']; + } + $i = $this->tokens[$i]['scope_closer']; } else if (isset($this->tokens[$i]['bracket_closer']) === true && $i === $this->tokens[$i]['bracket_opener'] @@ -2234,12 +2377,12 @@ public function findExtendedClassName($stackPtr) return false; } - if (isset($this->tokens[$stackPtr]['scope_closer']) === false) { + if (isset($this->tokens[$stackPtr]['scope_opener']) === false) { return false; } - $classCloserIndex = $this->tokens[$stackPtr]['scope_closer']; - $extendsIndex = $this->findNext(T_EXTENDS, $stackPtr, $classCloserIndex); + $classOpenerIndex = $this->tokens[$stackPtr]['scope_opener']; + $extendsIndex = $this->findNext(T_EXTENDS, $stackPtr, $classOpenerIndex); if (false === $extendsIndex) { return false; } @@ -2250,7 +2393,7 @@ public function findExtendedClassName($stackPtr) T_WHITESPACE, ]; - $end = $this->findNext($find, ($extendsIndex + 1), $classCloserIndex, true); + $end = $this->findNext($find, ($extendsIndex + 1), ($classOpenerIndex + 1), true); $name = $this->getTokensAsString(($extendsIndex + 1), ($end - $extendsIndex - 1)); $name = trim($name); diff --git a/app/vendor/squizlabs/php_codesniffer/src/Files/FileList.php b/app/vendor/squizlabs/php_codesniffer/src/Files/FileList.php index 69526c7a6..9e643de79 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Files/FileList.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Files/FileList.php @@ -167,7 +167,7 @@ private function getFilterClass() * * @return void */ - function rewind() + public function rewind() { reset($this->files); @@ -179,7 +179,7 @@ function rewind() * * @return \PHP_CodeSniffer\Files\File */ - function current() + public function current() { $path = key($this->files); if ($this->files[$path] === null) { @@ -196,7 +196,7 @@ function current() * * @return void */ - function key() + public function key() { return key($this->files); @@ -208,7 +208,7 @@ function key() * * @return void */ - function next() + public function next() { next($this->files); @@ -220,7 +220,7 @@ function next() * * @return boolean */ - function valid() + public function valid() { if (current($this->files) === false) { return false; @@ -236,7 +236,7 @@ function valid() * * @return integer */ - function count() + public function count() { return $this->numFiles; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php b/app/vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php index 0df71512f..6e086808d 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Files/LocalFile.php @@ -48,7 +48,7 @@ public function __construct($path, Ruleset $ruleset, Config $config) fclose($handle); if (strpos($firstContent, '@codingStandardsIgnoreFile') !== false - || strpos(strtolower($firstContent), 'phpcs:ignorefile') !== false + || stripos($firstContent, 'phpcs:ignorefile') !== false ) { // We are ignoring the whole file. $this->ignored = true; @@ -69,7 +69,7 @@ public function __construct($path, Ruleset $ruleset, Config $config) * * @return void */ - function reloadContent() + public function reloadContent() { $this->setContent(file_get_contents($this->path)); diff --git a/app/vendor/squizlabs/php_codesniffer/src/Filters/Filter.php b/app/vendor/squizlabs/php_codesniffer/src/Filters/Filter.php index b7a6c2aa2..04cc3919e 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Filters/Filter.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Filters/Filter.php @@ -204,9 +204,10 @@ protected function shouldIgnorePath($path) // If the ignore pattern ends with /* then it is ignoring an entire directory. if (substr($pattern, -2) === '/*') { // Need to check this pattern for dirs as well as individual file paths. - $pattern = substr($pattern, 0, -2); - $this->ignoreDirPatterns[$pattern] = $type; $this->ignoreFilePatterns[$pattern] = $type; + + $pattern = substr($pattern, 0, -2); + $this->ignoreDirPatterns[$pattern] = $type; } else { // This is a file-specific pattern, so only need to check this // for individual file paths. diff --git a/app/vendor/squizlabs/php_codesniffer/src/Generators/Generator.php b/app/vendor/squizlabs/php_codesniffer/src/Generators/Generator.php index 1f1745e30..56049768b 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Generators/Generator.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Generators/Generator.php @@ -14,7 +14,6 @@ use PHP_CodeSniffer\Ruleset; use PHP_CodeSniffer\Autoload; -use PHP_CodeSniffer\Util\Common; abstract class Generator { diff --git a/app/vendor/squizlabs/php_codesniffer/src/Reporter.php b/app/vendor/squizlabs/php_codesniffer/src/Reporter.php index b9a64c261..4667a76a9 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Reporter.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Reporter.php @@ -99,12 +99,11 @@ public function __construct(Config $config) $this->config = $config; foreach ($config->reports as $type => $output) { - $type = ucfirst($type); - if ($output === null) { $output = $config->reportFile; } + $reportClassName = ''; if (strpos($type, '.') !== false) { // This is a path to a custom report class. $filename = realpath($type); @@ -114,8 +113,32 @@ public function __construct(Config $config) } $reportClassName = Autoload::loadFile($filename); + } else if (class_exists('PHP_CodeSniffer\Reports\\'.ucfirst($type)) === true) { + // PHPCS native report. + $reportClassName = 'PHP_CodeSniffer\Reports\\'.ucfirst($type); + } else if (class_exists($type) === true) { + // FQN of a custom report. + $reportClassName = $type; } else { - $reportClassName = 'PHP_CodeSniffer\Reports\\'.$type; + // OK, so not a FQN, try and find the report using the registered namespaces. + $registeredNamespaces = Autoload::getSearchPaths(); + $trimmedType = ltrim($type, '\\'); + + foreach ($registeredNamespaces as $nsPrefix) { + if ($nsPrefix === '') { + continue; + } + + if (class_exists($nsPrefix.'\\'.$trimmedType) === true) { + $reportClassName = $nsPrefix.'\\'.$trimmedType; + break; + } + } + }//end if + + if ($reportClassName === '') { + $error = "ERROR: Class file for report \"$type\" not found".PHP_EOL; + throw new DeepExitException($error, 3); } $reportClass = new $reportClassName(); @@ -175,7 +198,6 @@ public function printReports() */ public function printReport($report) { - $report = ucfirst($report); $reportClass = $this->reports[$report]['class']; $reportFile = $this->reports[$report]['output']; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Reports/Diff.php b/app/vendor/squizlabs/php_codesniffer/src/Reports/Diff.php index 7d55cc70f..ce4b31fc0 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Reports/Diff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Reports/Diff.php @@ -10,7 +10,6 @@ namespace PHP_CodeSniffer\Reports; use PHP_CodeSniffer\Files\File; -use PHP_CodeSniffer\Util; class Diff implements Report { diff --git a/app/vendor/squizlabs/php_codesniffer/src/Reports/Full.php b/app/vendor/squizlabs/php_codesniffer/src/Reports/Full.php index 10bbbe9d7..084bc8aa5 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Reports/Full.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Reports/Full.php @@ -114,27 +114,40 @@ public function generateFileReport($report, File $phpcsFile, $showSources=false, // The maximum amount of space an error message can use. $maxErrorSpace = ($width - $paddingLength - 1); - if ($showSources === true) { - // Account for the chars used to print colors. - $maxErrorSpace += 8; - } foreach ($report['messages'] as $line => $lineErrors) { foreach ($lineErrors as $column => $colErrors) { foreach ($colErrors as $error) { - $message = $error['message']; - $message = str_replace("\n", "\n".$paddingLine2, $message); - if ($showSources === true) { - $message = "\033[1m".$message."\033[0m".' ('.$error['source'].')'; + $message = $error['message']; + $msgLines = [$message]; + if (strpos($message, "\n") !== false) { + $msgLines = explode("\n", $message); + } + + $errorMsg = ''; + $lastLine = (count($msgLines) - 1); + foreach ($msgLines as $k => $msgLine) { + if ($k === 0) { + if ($showSources === true) { + $errorMsg .= "\033[1m"; + } + } else { + $errorMsg .= PHP_EOL.$paddingLine2; + } + + if ($k === $lastLine && $showSources === true) { + $msgLine .= "\033[0m".' ('.$error['source'].')'; + } + + $errorMsg .= wordwrap( + $msgLine, + $maxErrorSpace, + PHP_EOL.$paddingLine2 + ); } // The padding that goes on the front of the line. - $padding = ($maxLineNumLength - strlen($line)); - $errorMsg = wordwrap( - $message, - $maxErrorSpace, - PHP_EOL.$paddingLine2 - ); + $padding = ($maxLineNumLength - strlen($line)); echo ' '.str_repeat(' ', $padding).$line.' | '; if ($error['type'] === 'ERROR') { diff --git a/app/vendor/squizlabs/php_codesniffer/src/Reports/Info.php b/app/vendor/squizlabs/php_codesniffer/src/Reports/Info.php index b13d9e2bb..85738a5a5 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Reports/Info.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Reports/Info.php @@ -101,30 +101,59 @@ public function generate( echo str_repeat('-', 70).PHP_EOL; foreach ($metrics as $metric => $values) { - $winner = ''; - $winnerCount = 0; - $totalCount = 0; - foreach ($values as $value => $count) { - $totalCount += $count; - if ($count > $winnerCount) { - $winner = $value; - $winnerCount = $count; - } - } + if (count($values) === 1) { + $count = reset($values); + $value = key($values); - $winPercent = round(($winnerCount / $totalCount * 100), 2); - echo "$metric: \033[4m$winner\033[0m [$winnerCount/$totalCount, $winPercent%]".PHP_EOL; + echo "$metric: \033[4m$value\033[0m [$count/$count, 100%]".PHP_EOL; + } else { + $totalCount = 0; + $valueWidth = 0; + foreach ($values as $value => $count) { + $totalCount += $count; + $valueWidth = max($valueWidth, strlen($value)); + } - asort($values); - $values = array_reverse($values, true); - foreach ($values as $value => $count) { - if ($value === $winner) { - continue; + $countWidth = strlen($totalCount); + $nrOfThousandSeps = floor($countWidth / 3); + $countWidth += $nrOfThousandSeps; + + // Account for 'total' line. + $valueWidth = max(5, $valueWidth); + + echo "$metric:".PHP_EOL; + + ksort($values, SORT_NATURAL); + arsort($values); + + $percentPrefixWidth = 0; + $percentWidth = 6; + foreach ($values as $value => $count) { + $percent = round(($count / $totalCount * 100), 2); + $percentPrefix = ''; + if ($percent === 0.00) { + $percent = 0.01; + $percentPrefix = '<'; + $percentPrefixWidth = 2; + $percentWidth = 4; + } + + printf( + "\t%-{$valueWidth}s => %{$countWidth}s (%{$percentPrefixWidth}s%{$percentWidth}.2f%%)".PHP_EOL, + $value, + number_format($count), + $percentPrefix, + $percent + ); } - $percent = round(($count / $totalCount * 100), 2); - echo "\t$value => $count ($percent%)".PHP_EOL; - } + echo "\t".str_repeat('-', ($valueWidth + $countWidth + 15)).PHP_EOL; + printf( + "\t%-{$valueWidth}s => %{$countWidth}s (100.00%%)".PHP_EOL, + 'total', + number_format($totalCount) + ); + }//end if echo PHP_EOL; }//end foreach diff --git a/app/vendor/squizlabs/php_codesniffer/src/Reports/Json.php b/app/vendor/squizlabs/php_codesniffer/src/Reports/Json.php index 3c41f8e41..8bf269209 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Reports/Json.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Reports/Json.php @@ -42,28 +42,23 @@ public function generateFileReport($report, File $phpcsFile, $showSources=false, foreach ($report['messages'] as $line => $lineErrors) { foreach ($lineErrors as $column => $colErrors) { foreach ($colErrors as $error) { - $error['message'] = str_replace('\\', '\\\\', $error['message']); - $error['message'] = str_replace('"', '\"', $error['message']); - $error['message'] = str_replace('/', '\/', $error['message']); $error['message'] = str_replace("\n", '\n', $error['message']); $error['message'] = str_replace("\r", '\r', $error['message']); $error['message'] = str_replace("\t", '\t', $error['message']); - $fixable = 'false'; + $fixable = false; if ($error['fixable'] === true) { - $fixable = 'true'; + $fixable = true; } - $messages .= '{"message":"'.$error['message'].'",'; - $messages .= '"source":"'.$error['source'].'",'; - $messages .= '"severity":'.$error['severity'].','; - $messages .= '"type":"'.$error['type'].'",'; - $messages .= '"line":'.$line.','; - $messages .= '"column":'.$column.','; - $messages .= '"fixable":'.$fixable; - $messages .= '},'; - }//end foreach - }//end foreach + $messagesObject = (object) $error; + $messagesObject->line = $line; + $messagesObject->column = $column; + $messagesObject->fixable = $fixable; + + $messages .= json_encode($messagesObject).","; + } + } }//end foreach echo rtrim($messages, ','); diff --git a/app/vendor/squizlabs/php_codesniffer/src/Reports/Junit.php b/app/vendor/squizlabs/php_codesniffer/src/Reports/Junit.php index 3461d89f3..d3ede61d4 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Reports/Junit.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Reports/Junit.php @@ -39,6 +39,7 @@ public function generateFileReport($report, File $phpcsFile, $showSources=false, $out->startElement('testsuite'); $out->writeAttribute('name', $report['filename']); + $out->writeAttribute('errors', 0); if (count($report['messages']) === 0) { $out->writeAttribute('tests', 1); @@ -120,7 +121,7 @@ public function generate( $failures = ($totalErrors + $totalWarnings); echo ''.PHP_EOL; - echo ''.PHP_EOL; + echo ''.PHP_EOL; echo $cachedData; echo ''.PHP_EOL; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Reports/Source.php b/app/vendor/squizlabs/php_codesniffer/src/Reports/Source.php index 7827d1941..ce8c3cfec 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Reports/Source.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Reports/Source.php @@ -141,13 +141,6 @@ public function generate( } else { $sources[$source]['count'] += $count; }//end if - - $fileLen = strlen($parts[0]); - $reportFiles[$parts[0]] = [ - 'errors' => $parts[1], - 'warnings' => $parts[2], - 'strlen' => $fileLen, - ]; }//end foreach if ($showSources === true) { @@ -158,8 +151,14 @@ public function generate( $width = max($width, 70); - asort($sources); - $sources = array_reverse($sources); + // Sort the data based on counts and source code. + $sourceCodes = array_keys($sources); + $counts = []; + foreach ($sources as $source => $data) { + $counts[$source] = $data['count']; + } + + array_multisort($counts, SORT_DESC, $sourceCodes, SORT_ASC, SORT_NATURAL, $sources); echo PHP_EOL."\033[1mPHP CODE SNIFFER VIOLATION SOURCE SUMMARY\033[0m".PHP_EOL; echo str_repeat('-', $width).PHP_EOL."\033[1m"; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Reports/Summary.php b/app/vendor/squizlabs/php_codesniffer/src/Reports/Summary.php index 08b69c137..8fe18e764 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Reports/Summary.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Reports/Summary.php @@ -95,6 +95,27 @@ public function generate( $maxLength = max($maxLength, $fileLen); } + uksort( + $reportFiles, + function ($keyA, $keyB) { + $pathPartsA = explode(DIRECTORY_SEPARATOR, $keyA); + $pathPartsB = explode(DIRECTORY_SEPARATOR, $keyB); + + do { + $partA = array_shift($pathPartsA); + $partB = array_shift($pathPartsB); + } while ($partA === $partB && empty($pathPartsA) === false && empty($pathPartsB) === false); + + if (empty($pathPartsA) === false && empty($pathPartsB) === true) { + return 1; + } else if (empty($pathPartsA) === true && empty($pathPartsB) === false) { + return -1; + } else { + return strcasecmp($partA, $partB); + } + } + ); + $width = min($width, ($maxLength + 21)); $width = max($width, 70); diff --git a/app/vendor/squizlabs/php_codesniffer/src/Ruleset.php b/app/vendor/squizlabs/php_codesniffer/src/Ruleset.php index 6f209d525..6e8419831 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Ruleset.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Ruleset.php @@ -390,7 +390,11 @@ public function processRuleset($rulesetPath, $depth=0) $includedSniffs = array_merge($includedSniffs, $expandedSniffs); $parts = explode('.', $rule['ref']); - if (count($parts) === 4) { + if (count($parts) === 4 + && $parts[0] !== '' + && $parts[1] !== '' + && $parts[2] !== '' + ) { $sniffCode = $parts[0].'.'.$parts[1].'.'.$parts[2]; if (isset($this->ruleset[$sniffCode]['severity']) === true && $this->ruleset[$sniffCode]['severity'] === 0 @@ -945,21 +949,43 @@ private function processRule($rule, $newSniffs, $depth=0) if (isset($prop['type']) === true && (string) $prop['type'] === 'array' ) { - $value = (string) $prop['value']; $values = []; - foreach (explode(',', $value) as $val) { - list($k, $v) = explode('=>', $val.'=>'); - if ($v !== '') { - $values[trim($k)] = trim($v); - } else { - $values[] = trim($k); + if (isset($prop->element) === true) { + $printValue = ''; + foreach ($prop->element as $element) { + if ($this->shouldProcessElement($element) === false) { + continue; + } + + $value = (string) $element['value']; + if (isset($element['key']) === true) { + $key = (string) $element['key']; + $values[$key] = $value; + $printValue .= $key.'=>'.$value.','; + } else { + $values[] = $value; + $printValue .= $value.','; + } } - } + + $printValue = rtrim($printValue, ','); + } else { + $value = (string) $prop['value']; + $printValue = $value; + foreach (explode(',', $value) as $val) { + list($k, $v) = explode('=>', $val.'=>'); + if ($v !== '') { + $values[trim($k)] = trim($v); + } else { + $values[] = trim($k); + } + } + }//end if $this->ruleset[$code]['properties'][$name] = $values; if (PHP_CODESNIFFER_VERBOSITY > 1) { echo str_repeat("\t", $depth); - echo "\t\t=> array property \"$name\" set to \"$value\""; + echo "\t\t=> array property \"$name\" set to \"$printValue\""; if ($code !== $ref) { echo " for $code"; } @@ -1241,11 +1267,30 @@ public function setSniffProperty($sniffClass, $name, $value) $value = trim($value); } + if ($value === '') { + $value = null; + } + // Special case for booleans. if ($value === 'true') { $value = true; } else if ($value === 'false') { $value = false; + } else if (substr($name, -2) === '[]') { + $name = substr($name, 0, -2); + $values = []; + if ($value !== null) { + foreach (explode(',', $value) as $val) { + list($k, $v) = explode('=>', $val.'=>'); + if ($v !== '') { + $values[trim($k)] = trim($v); + } else { + $values[] = trim($k); + } + } + } + + $value = $values; } $this->sniffs[$sniffClass]->$name = $value; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Runner.php b/app/vendor/squizlabs/php_codesniffer/src/Runner.php index 46e504875..d762ebbb5 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Runner.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Runner.php @@ -726,7 +726,7 @@ private function processChildProcs($childProcs) * * @return void */ - function printProgress($file, $numFiles, $numProcessed) + public function printProgress($file, $numFiles, $numProcessed) { if (PHP_CODESNIFFER_VERBOSITY > 0 || $this->config->showProgress === false diff --git a/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractArraySniff.php b/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractArraySniff.php index c76944a7c..6589c288d 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractArraySniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractArraySniff.php @@ -9,7 +9,6 @@ namespace PHP_CodeSniffer\Sniffs; -use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; @@ -110,10 +109,9 @@ public function process(File $phpcsFile, $stackPtr) } $checkToken = $phpcsFile->findNext(T_WHITESPACE, ($checkToken + 1), null, true); + $lastToken = $checkToken; if ($tokens[$checkToken]['code'] !== T_COMMA) { $checkToken--; - } else { - $lastToken = $checkToken; } continue; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractPatternSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractPatternSniff.php index 3ffcf53fc..c41ba77e5 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractPatternSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractPatternSniff.php @@ -10,7 +10,6 @@ namespace PHP_CodeSniffer\Sniffs; use PHP_CodeSniffer\Files\File; -use PHP_CodeSniffer\Config; use PHP_CodeSniffer\Util\Tokens; use PHP_CodeSniffer\Tokenizers\PHP; use PHP_CodeSniffer\Exceptions\RuntimeException; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractScopeSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractScopeSniff.php index 48803dfad..a47b91506 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractScopeSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractScopeSniff.php @@ -121,7 +121,10 @@ final public function register() * @param int $stackPtr The position in the stack where this * token was found. * - * @return void + * @return void|int Optionally returns a stack pointer. The sniff will not be + * called again on the current file until the returned stack + * pointer is reached. Return (count($tokens) + 1) to skip + * the rest of the file. * @see processTokenWithinScope() */ final public function process(File $phpcsFile, $stackPtr) @@ -129,17 +132,24 @@ final public function process(File $phpcsFile, $stackPtr) $tokens = $phpcsFile->getTokens(); $foundScope = false; + $skipPtrs = []; foreach ($tokens[$stackPtr]['conditions'] as $scope => $code) { if (isset($this->scopeTokens[$code]) === true) { - $this->processTokenWithinScope($phpcsFile, $stackPtr, $scope); + $skipPtrs[] = $this->processTokenWithinScope($phpcsFile, $stackPtr, $scope); $foundScope = true; } } if ($this->listenOutside === true && $foundScope === false) { - $this->processTokenOutsideScope($phpcsFile, $stackPtr); + $skipPtrs[] = $this->processTokenOutsideScope($phpcsFile, $stackPtr); } + if (empty($skipPtrs) === false) { + return min($skipPtrs); + } + + return; + }//end process() @@ -154,7 +164,10 @@ final public function process(File $phpcsFile, $stackPtr) * opened the scope that this test is * listening for. * - * @return void + * @return void|int Optionally returns a stack pointer. The sniff will not be + * called again on the current file until the returned stack + * pointer is reached. Return (count($tokens) + 1) to skip + * the rest of the file. */ abstract protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope); @@ -167,7 +180,10 @@ abstract protected function processTokenWithinScope(File $phpcsFile, $stackPtr, * @param int $stackPtr The position in the stack where this * token was found. * - * @return void + * @return void|int Optionally returns a stack pointer. The sniff will not be + * called again on the current file until the returned stack + * pointer is reached. Return (count($tokens) + 1) to skip + * the rest of the file. */ abstract protected function processTokenOutsideScope(File $phpcsFile, $stackPtr); diff --git a/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractVariableSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractVariableSniff.php index 594e3678e..48e31b279 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractVariableSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Sniffs/AbstractVariableSniff.php @@ -17,12 +17,34 @@ use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; -use PHP_CodeSniffer\Exceptions\RuntimeException; abstract class AbstractVariableSniff extends AbstractScopeSniff { + /** + * List of PHP Reserved variables. + * + * Used by various naming convention sniffs. + * + * @var array + */ + protected $phpReservedVars = [ + '_SERVER' => true, + '_GET' => true, + '_POST' => true, + '_REQUEST' => true, + '_SESSION' => true, + '_ENV' => true, + '_COOKIE' => true, + '_FILES' => true, + 'GLOBALS' => true, + 'http_response_header' => true, + 'HTTP_RAW_POST_DATA' => true, + 'php_errormsg' => true, + ]; + + /** * Constructs an AbstractVariableTest. */ @@ -49,7 +71,10 @@ public function __construct() * @param int $stackPtr The position where the token was found. * @param int $currScope The current scope opener token. * - * @return void + * @return void|int Optionally returns a stack pointer. The sniff will not be + * called again on the current file until the returned stack + * pointer is reached. Return (count($tokens) + 1) to skip + * the rest of the file. */ final protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope) { @@ -61,7 +86,7 @@ final protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $cu // Check to see if this string has a variable in it. $pattern = '|(?processVariableInString($phpcsFile, $stackPtr); + return $this->processVariableInString($phpcsFile, $stackPtr); } return; @@ -115,9 +140,9 @@ final protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $cu }//end if if ($inFunction === true) { - $this->processVariable($phpcsFile, $stackPtr); + return $this->processVariable($phpcsFile, $stackPtr); } else { - $this->processMemberVar($phpcsFile, $stackPtr); + return $this->processMemberVar($phpcsFile, $stackPtr); } }//end processTokenWithinScope() @@ -130,21 +155,24 @@ final protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $cu * token was found. * @param int $stackPtr The position where the token was found. * - * @return void + * @return void|int Optionally returns a stack pointer. The sniff will not be + * called again on the current file until the returned stack + * pointer is reached. Return (count($tokens) + 1) to skip + * the rest of the file. */ final protected function processTokenOutsideScope(File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // These variables are not member vars. if ($tokens[$stackPtr]['code'] === T_VARIABLE) { - $this->processVariable($phpcsFile, $stackPtr); + return $this->processVariable($phpcsFile, $stackPtr); } else if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING || $tokens[$stackPtr]['code'] === T_HEREDOC ) { // Check to see if this string has a variable in it. $pattern = '|(?processVariableInString($phpcsFile, $stackPtr); + return $this->processVariableInString($phpcsFile, $stackPtr); } } @@ -158,7 +186,10 @@ final protected function processTokenOutsideScope(File $phpcsFile, $stackPtr) * token was found. * @param int $stackPtr The position where the token was found. * - * @return void + * @return void|int Optionally returns a stack pointer. The sniff will not be + * called again on the current file until the returned stack + * pointer is reached. Return (count($tokens) + 1) to skip + * the rest of the file. */ abstract protected function processMemberVar(File $phpcsFile, $stackPtr); @@ -170,7 +201,10 @@ abstract protected function processMemberVar(File $phpcsFile, $stackPtr); * token was found. * @param int $stackPtr The position where the token was found. * - * @return void + * @return void|int Optionally returns a stack pointer. The sniff will not be + * called again on the current file until the returned stack + * pointer is reached. Return (count($tokens) + 1) to skip + * the rest of the file. */ abstract protected function processVariable(File $phpcsFile, $stackPtr); @@ -186,7 +220,10 @@ abstract protected function processVariable(File $phpcsFile, $stackPtr); * @param int $stackPtr The position where the double quoted * string was found. * - * @return void + * @return void|int Optionally returns a stack pointer. The sniff will not be + * called again on the current file until the returned stack + * pointer is reached. Return (count($tokens) + 1) to skip + * the rest of the file. */ abstract protected function processVariableInString(File $phpcsFile, $stackPtr); diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/Commenting/FixmeStandard.xml b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/Commenting/FixmeStandard.xml index 451e5fb61..174c6b0a8 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/Commenting/FixmeStandard.xml +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/Commenting/FixmeStandard.xml @@ -1,4 +1,4 @@ - + + true, false and null constants must always be lowercase. diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/PHP/LowerCaseTypeStandard.xml b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/PHP/LowerCaseTypeStandard.xml new file mode 100644 index 000000000..f38df3af5 --- /dev/null +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/PHP/LowerCaseTypeStandard.xml @@ -0,0 +1,38 @@ + + + + + + + + + + Int $foo) : STRING { +} + ]]> + + + + + + + + + + + (BOOL) $isValid; + ]]> + + + diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/PHP/UpperCaseConstantStandard.xml b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/PHP/UpperCaseConstantStandard.xml index 26487347b..1f337f77e 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/PHP/UpperCaseConstantStandard.xml +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/PHP/UpperCaseConstantStandard.xml @@ -1,4 +1,4 @@ - + true, false and null constants must always be uppercase. diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/WhiteSpace/ArbitraryParenthesesSpacingStandard.xml b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/WhiteSpace/ArbitraryParenthesesSpacingStandard.xml new file mode 100644 index 000000000..30e0def93 --- /dev/null +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/WhiteSpace/ArbitraryParenthesesSpacingStandard.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Arrays/ArrayIndentSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Arrays/ArrayIndentSniff.php index 563fe9183..cffea8033 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Arrays/ArrayIndentSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Arrays/ArrayIndentSniff.php @@ -10,7 +10,6 @@ namespace PHP_CodeSniffer\Standards\Generic\Sniffs\Arrays; use PHP_CodeSniffer\Sniffs\AbstractArraySniff; -use PHP_CodeSniffer\Files\File; use PHP_CodeSniffer\Util\Tokens; class ArrayIndentSniff extends AbstractArraySniff diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php index 2514a2d97..684d14d9a 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/CodeAnalysis/AssignmentInConditionSniff.php @@ -150,10 +150,15 @@ public function process(File $phpcsFile, $stackPtr) } if ($hasVariable === true) { + $errorCode = 'Found'; + if ($token['code'] === T_WHILE) { + $errorCode = 'FoundInWhileCondition'; + } + $phpcsFile->addWarning( 'Variable assignment found within a condition. Did you mean to do a comparison ?', $hasAssignment, - 'Found' + $errorCode ); } diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php index 9d42adfd2..3fe5fb7d9 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/CodeAnalysis/EmptyStatementSniff.php @@ -39,7 +39,9 @@ class EmptyStatementSniff implements Sniff public function register() { return [ + T_TRY, T_CATCH, + T_FINALLY, T_DO, T_ELSE, T_ELSEIF, @@ -47,7 +49,6 @@ public function register() T_FOREACH, T_IF, T_SWITCH, - T_TRY, T_WHILE, ]; @@ -87,7 +88,7 @@ public function process(File $phpcsFile, $stackPtr) // Get token identifier. $name = strtoupper($token['content']); $error = 'Empty %s statement detected'; - $phpcsFile->addError($error, $stackPtr, 'Detected'.$name, [$name]); + $phpcsFile->addError($error, $stackPtr, 'Detected'.ucfirst(strtolower($name)), [$name]); }//end process() diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php index 3cd78e6ff..755278c0d 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/DocCommentSniff.php @@ -49,7 +49,16 @@ public function register() */ public function process(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); + $tokens = $phpcsFile->getTokens(); + + if (isset($tokens[$stackPtr]['comment_closer']) === false + || ($tokens[$tokens[$stackPtr]['comment_closer']]['content'] === '' + && $tokens[$stackPtr]['comment_closer'] === ($phpcsFile->numTokens - 1)) + ) { + // Don't process an unfinished comment during live coding. + return; + } + $commentStart = $stackPtr; $commentEnd = $tokens[$stackPtr]['comment_closer']; @@ -110,74 +119,73 @@ public function process(File $phpcsFile, $stackPtr) if ($tokens[$short]['code'] !== T_DOC_COMMENT_STRING) { $error = 'Missing short description in doc comment'; $phpcsFile->addError($error, $stackPtr, 'MissingShort'); - return; - } + } else { + // No extra newline before short description. + if ($tokens[$short]['line'] !== ($tokens[$stackPtr]['line'] + 1)) { + $error = 'Doc comment short description must be on the first line'; + $fix = $phpcsFile->addFixableError($error, $short, 'SpacingBeforeShort'); + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + for ($i = $stackPtr; $i < $short; $i++) { + if ($tokens[$i]['line'] === $tokens[$stackPtr]['line']) { + continue; + } else if ($tokens[$i]['line'] === $tokens[$short]['line']) { + break; + } - // No extra newline before short description. - if ($tokens[$short]['line'] !== ($tokens[$stackPtr]['line'] + 1)) { - $error = 'Doc comment short description must be on the first line'; - $fix = $phpcsFile->addFixableError($error, $short, 'SpacingBeforeShort'); - if ($fix === true) { - $phpcsFile->fixer->beginChangeset(); - for ($i = $stackPtr; $i < $short; $i++) { - if ($tokens[$i]['line'] === $tokens[$stackPtr]['line']) { - continue; - } else if ($tokens[$i]['line'] === $tokens[$short]['line']) { - break; + $phpcsFile->fixer->replaceToken($i, ''); } - $phpcsFile->fixer->replaceToken($i, ''); + $phpcsFile->fixer->endChangeset(); } - - $phpcsFile->fixer->endChangeset(); } - } - // Account for the fact that a short description might cover - // multiple lines. - $shortContent = $tokens[$short]['content']; - $shortEnd = $short; - for ($i = ($short + 1); $i < $commentEnd; $i++) { - if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) { - if ($tokens[$i]['line'] === ($tokens[$shortEnd]['line'] + 1)) { - $shortContent .= $tokens[$i]['content']; - $shortEnd = $i; - } else { - break; + // Account for the fact that a short description might cover + // multiple lines. + $shortContent = $tokens[$short]['content']; + $shortEnd = $short; + for ($i = ($short + 1); $i < $commentEnd; $i++) { + if ($tokens[$i]['code'] === T_DOC_COMMENT_STRING) { + if ($tokens[$i]['line'] === ($tokens[$shortEnd]['line'] + 1)) { + $shortContent .= $tokens[$i]['content']; + $shortEnd = $i; + } else { + break; + } } } - } - if (preg_match('/^\p{Ll}/u', $shortContent) === 1) { - $error = 'Doc comment short description must start with a capital letter'; - $phpcsFile->addError($error, $short, 'ShortNotCapital'); - } + if (preg_match('/^\p{Ll}/u', $shortContent) === 1) { + $error = 'Doc comment short description must start with a capital letter'; + $phpcsFile->addError($error, $short, 'ShortNotCapital'); + } - $long = $phpcsFile->findNext($empty, ($shortEnd + 1), ($commentEnd - 1), true); - if ($long !== false && $tokens[$long]['code'] === T_DOC_COMMENT_STRING) { - if ($tokens[$long]['line'] !== ($tokens[$shortEnd]['line'] + 2)) { - $error = 'There must be exactly one blank line between descriptions in a doc comment'; - $fix = $phpcsFile->addFixableError($error, $long, 'SpacingBetween'); - if ($fix === true) { - $phpcsFile->fixer->beginChangeset(); - for ($i = ($shortEnd + 1); $i < $long; $i++) { - if ($tokens[$i]['line'] === $tokens[$shortEnd]['line']) { - continue; - } else if ($tokens[$i]['line'] === ($tokens[$long]['line'] - 1)) { - break; + $long = $phpcsFile->findNext($empty, ($shortEnd + 1), ($commentEnd - 1), true); + if ($long !== false && $tokens[$long]['code'] === T_DOC_COMMENT_STRING) { + if ($tokens[$long]['line'] !== ($tokens[$shortEnd]['line'] + 2)) { + $error = 'There must be exactly one blank line between descriptions in a doc comment'; + $fix = $phpcsFile->addFixableError($error, $long, 'SpacingBetween'); + if ($fix === true) { + $phpcsFile->fixer->beginChangeset(); + for ($i = ($shortEnd + 1); $i < $long; $i++) { + if ($tokens[$i]['line'] === $tokens[$shortEnd]['line']) { + continue; + } else if ($tokens[$i]['line'] === ($tokens[$long]['line'] - 1)) { + break; + } + + $phpcsFile->fixer->replaceToken($i, ''); } - $phpcsFile->fixer->replaceToken($i, ''); + $phpcsFile->fixer->endChangeset(); } - - $phpcsFile->fixer->endChangeset(); } - } - if (preg_match('/^\p{Ll}/u', $tokens[$long]['content']) === 1) { - $error = 'Doc comment long description must start with a capital letter'; - $phpcsFile->addError($error, $long, 'LongNotCapital'); - } + if (preg_match('/^\p{Ll}/u', $tokens[$long]['content']) === 1) { + $error = 'Doc comment long description must start with a capital letter'; + $phpcsFile->addError($error, $long, 'LongNotCapital'); + } + }//end if }//end if if (empty($tokens[$commentStart]['comment_tags']) === true) { @@ -187,7 +195,9 @@ public function process(File $phpcsFile, $stackPtr) $firstTag = $tokens[$commentStart]['comment_tags'][0]; $prev = $phpcsFile->findPrevious($empty, ($firstTag - 1), $stackPtr, true); - if ($tokens[$firstTag]['line'] !== ($tokens[$prev]['line'] + 2)) { + if ($tokens[$firstTag]['line'] !== ($tokens[$prev]['line'] + 2) + && $tokens[$prev]['code'] !== T_DOC_COMMENT_OPEN_TAG + ) { $error = 'There must be exactly one blank line before the tags in a doc comment'; $fix = $phpcsFile->addFixableError($error, $firstTag, 'SpacingBeforeTags'); if ($fix === true) { @@ -230,10 +240,8 @@ public function process(File $phpcsFile, $stackPtr) } if ($tokens[$tag]['content'] === '@param') { - if (($paramGroupid === null - && empty($tagGroups[$groupid]) === false) - || ($paramGroupid !== null - && $paramGroupid !== $groupid) + if ($paramGroupid !== null + && $paramGroupid !== $groupid ) { $error = 'Parameter tags must be grouped together in a doc comment'; $phpcsFile->addError($error, $tag, 'ParamGroup'); @@ -242,18 +250,22 @@ public function process(File $phpcsFile, $stackPtr) if ($paramGroupid === null) { $paramGroupid = $groupid; } - } else if ($groupid === $paramGroupid) { - $error = 'Tag cannot be grouped with parameter tags in a doc comment'; - $phpcsFile->addError($error, $tag, 'NonParamGroup'); }//end if $tagGroups[$groupid][] = $tag; }//end foreach - foreach ($tagGroups as $group) { + foreach ($tagGroups as $groupid => $group) { $maxLength = 0; $paddings = []; foreach ($group as $pos => $tag) { + if ($paramGroupid === $groupid + && $tokens[$tag]['content'] !== '@param' + ) { + $error = 'Tag cannot be grouped with parameter tags in a doc comment'; + $phpcsFile->addError($error, $tag, 'NonParamGroup'); + } + $tagLength = strlen($tokens[$tag]['content']); if ($tagLength > $maxLength) { $maxLength = $tagLength; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/FixmeSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/FixmeSniff.php index 59265148f..586da97b0 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/FixmeSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/FixmeSniff.php @@ -35,7 +35,7 @@ class FixmeSniff implements Sniff */ public function register() { - return Tokens::$commentTokens; + return array_diff(Tokens::$commentTokens, Tokens::$phpcsCommentTokens); }//end register() diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/TodoSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/TodoSniff.php index c1ad5e506..35a1e3c25 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/TodoSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Commenting/TodoSniff.php @@ -34,7 +34,7 @@ class TodoSniff implements Sniff */ public function register() { - return Tokens::$commentTokens; + return array_diff(Tokens::$commentTokens, Tokens::$phpcsCommentTokens); }//end register() diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php index 1708164da..2a30ef583 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/ControlStructures/InlineControlStructureSniff.php @@ -191,6 +191,12 @@ public function process(File $phpcsFile, $stackPtr) if ($type === T_TRY && $nextType === T_CATCH) { $end = $tokens[$next]['scope_closer']; } + } else if ($type === T_CLOSURE) { + // There should be a semicolon after the closing brace. + $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($end + 1), null, true); + if ($next !== false && $tokens[$next]['code'] === T_SEMICOLON) { + $end = $next; + } }//end if if ($tokens[$end]['code'] !== T_END_HEREDOC @@ -215,30 +221,34 @@ public function process(File $phpcsFile, $stackPtr) $end = $lastNonEmpty; } - $next = $phpcsFile->findNext(Tokens::$emptyTokens, ($end + 1), null, true); - - if ($next === false || $tokens[$next]['line'] !== $tokens[$end]['line']) { + $nextContent = $phpcsFile->findNext(Tokens::$emptyTokens, ($end + 1), null, true); + if ($nextContent === false || $tokens[$nextContent]['line'] !== $tokens[$end]['line']) { // Looks for completely empty statements. $next = $phpcsFile->findNext(T_WHITESPACE, ($closer + 1), ($end + 1), true); - - // Account for a comment on the end of the line. - for ($endLine = $end; $endLine < $phpcsFile->numTokens; $endLine++) { - if (isset($tokens[($endLine + 1)]) === false - || $tokens[$endLine]['line'] !== $tokens[($endLine + 1)]['line'] - ) { - break; - } - } - - if ($tokens[$endLine]['code'] !== T_COMMENT) { - $endLine = $end; - } } else { $next = ($end + 1); $endLine = $end; } if ($next !== $end) { + if ($nextContent === false || $tokens[$nextContent]['line'] !== $tokens[$end]['line']) { + // Account for a comment on the end of the line. + for ($endLine = $end; $endLine < $phpcsFile->numTokens; $endLine++) { + if (isset($tokens[($endLine + 1)]) === false + || $tokens[$endLine]['line'] !== $tokens[($endLine + 1)]['line'] + ) { + break; + } + } + + if (isset(Tokens::$commentTokens[$tokens[$endLine]['code']]) === false + && ($tokens[$endLine]['code'] !== T_WHITESPACE + || isset(Tokens::$commentTokens[$tokens[($endLine - 1)]['code']]) === false) + ) { + $endLine = $end; + } + } + if ($endLine !== $end) { $endToken = $endLine; $addedContent = ''; @@ -262,9 +272,7 @@ public function process(File $phpcsFile, $stackPtr) } else { $indent = ''; for ($first = $stackPtr; $first > 0; $first--) { - if ($first === 1 - || $tokens[($first - 1)]['line'] !== $tokens[$first]['line'] - ) { + if ($tokens[$first]['column'] === 1) { break; } } @@ -285,6 +293,24 @@ public function process(File $phpcsFile, $stackPtr) $phpcsFile->fixer->addContent($endToken, $addedContent); }//end if } else { + if ($nextContent === false || $tokens[$nextContent]['line'] !== $tokens[$end]['line']) { + // Account for a comment on the end of the line. + for ($endLine = $end; $endLine < $phpcsFile->numTokens; $endLine++) { + if (isset($tokens[($endLine + 1)]) === false + || $tokens[$endLine]['line'] !== $tokens[($endLine + 1)]['line'] + ) { + break; + } + } + + if ($tokens[$endLine]['code'] !== T_COMMENT + && ($tokens[$endLine]['code'] !== T_WHITESPACE + || $tokens[($endLine - 1)]['code'] !== T_COMMENT) + ) { + $endLine = $end; + } + } + if ($endLine !== $end) { $phpcsFile->fixer->replaceToken($end, ''); $phpcsFile->fixer->addNewlineBefore($endLine); diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php index 0da42e2f4..d896bafc9 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Files/LineLengthSniff.php @@ -15,6 +15,7 @@ use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Util\Tokens; class LineLengthSniff implements Sniff { @@ -108,6 +109,16 @@ protected function checkLineLength($phpcsFile, $tokens, $stackPtr) $stackPtr--; } + if (isset(Tokens::$phpcsCommentTokens[$tokens[$stackPtr]['code']]) === true) { + $prevNonWhiteSpace = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); + if ($tokens[$stackPtr]['line'] !== $tokens[$prevNonWhiteSpace]['line']) { + // Ignore PHPCS annotation comments if they are on a line by themselves. + return; + } + + unset($prevNonWhiteSpace); + } + $lineLength = ($tokens[$stackPtr]['column'] + $tokens[$stackPtr]['length'] - 1); // Record metrics for common line length groupings. diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Formatting/MultipleStatementAlignmentSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Formatting/MultipleStatementAlignmentSniff.php index 29c5ae4e1..4a6868323 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Formatting/MultipleStatementAlignmentSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Formatting/MultipleStatementAlignmentSniff.php @@ -96,10 +96,12 @@ public function process(File $phpcsFile, $stackPtr) * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. + * @param int $end The token where checking should end. + * If NULL, the entire file will be checked. * * @return int */ - public function checkAlignment($phpcsFile, $stackPtr) + public function checkAlignment($phpcsFile, $stackPtr, $end=null) { $tokens = $phpcsFile->getTokens(); @@ -110,18 +112,66 @@ public function checkAlignment($phpcsFile, $stackPtr) $stopped = null; $lastCode = $stackPtr; $lastSemi = null; + $arrayEnd = null; + + if ($end === null) { + $end = $phpcsFile->numTokens; + } $find = Tokens::$assignmentTokens; unset($find[T_DOUBLE_ARROW]); - for ($assign = $stackPtr; $assign < $phpcsFile->numTokens; $assign++) { + $scopes = Tokens::$scopeOpeners; + unset($scopes[T_CLOSURE]); + unset($scopes[T_ANON_CLASS]); + unset($scopes[T_OBJECT]); + + for ($assign = $stackPtr; $assign < $end; $assign++) { + if ($tokens[$assign]['level'] < $tokens[$stackPtr]['level']) { + // Statement is in a different context, so the block is over. + break; + } + + if (isset($scopes[$tokens[$assign]['code']]) === true + && isset($tokens[$assign]['scope_opener']) === true + && $tokens[$assign]['level'] === $tokens[$stackPtr]['level'] + ) { + break; + } + + if ($assign === $arrayEnd) { + $arrayEnd = null; + } + if (isset($find[$tokens[$assign]['code']]) === false) { // A blank line indicates that the assignment block has ended. - if (isset(Tokens::$emptyTokens[$tokens[$assign]['code']]) === false) { - if (($tokens[$assign]['line'] - $tokens[$lastCode]['line']) > 1) { - break; - } + if (isset(Tokens::$emptyTokens[$tokens[$assign]['code']]) === false + && ($tokens[$assign]['line'] - $tokens[$lastCode]['line']) > 1 + && $tokens[$assign]['level'] === $tokens[$stackPtr]['level'] + && $arrayEnd === null + ) { + break; + } + if ($tokens[$assign]['code'] === T_CLOSE_TAG) { + // Breaking out of PHP ends the assignment block. + break; + } + + if ($tokens[$assign]['code'] === T_OPEN_SHORT_ARRAY + && isset($tokens[$assign]['bracket_closer']) === true + ) { + $arrayEnd = $tokens[$assign]['bracket_closer']; + } + + if ($tokens[$assign]['code'] === T_ARRAY + && isset($tokens[$assign]['parenthesis_opener']) === true + && isset($tokens[$tokens[$assign]['parenthesis_opener']]['parenthesis_closer']) === true + ) { + $arrayEnd = $tokens[$tokens[$assign]['parenthesis_opener']]['parenthesis_closer']; + } + + if (isset(Tokens::$emptyTokens[$tokens[$assign]['code']]) === false) { $lastCode = $assign; if ($tokens[$assign]['code'] === T_SEMICOLON) { @@ -132,7 +182,7 @@ public function checkAlignment($phpcsFile, $stackPtr) } else { $lastSemi = $assign; } - } else { + } else if ($tokens[$assign]['level'] < $tokens[$stackPtr]['level']) { // Statement is in a different context, so the block is over. break; } @@ -147,9 +197,22 @@ public function checkAlignment($phpcsFile, $stackPtr) }//end if if ($assign !== $stackPtr) { - // Has to be nested inside the same conditions as the first assignment. - if ($tokens[$assign]['conditions'] !== $tokens[$stackPtr]['conditions']) { + if ($tokens[$assign]['level'] > $tokens[$stackPtr]['level']) { + // Has to be nested inside the same conditions as the first assignment. + // We've gone one level down, so process this new block. + $assign = $this->checkAlignment($phpcsFile, $assign); + $lastCode = $assign; + continue; + } else if ($tokens[$assign]['level'] < $tokens[$stackPtr]['level']) { + // We've gone one level up, so the block we are processing is done. break; + } else if ($arrayEnd !== null) { + // Assignments inside arrays are not part of + // the original block, so process this new block. + $assign = ($this->checkAlignment($phpcsFile, $assign, $arrayEnd) - 1); + $arrayEnd = null; + $lastCode = $assign; + continue; } // Make sure it is not assigned inside a condition (eg. IF, FOR). @@ -175,6 +238,11 @@ public function checkAlignment($phpcsFile, $stackPtr) $varEnd = $tokens[($var + 1)]['column']; $assignLen = $tokens[$assign]['length']; if ($assign !== $stackPtr) { + if ($prevAssign === null) { + // Processing an inner block but no assignments found. + break; + } + if (($varEnd + 1) > $assignments[$prevAssign]['assign_col']) { $padding = 1; $assignColumn = ($varEnd + 1); @@ -310,7 +378,7 @@ public function checkAlignment($phpcsFile, $stackPtr) if ($stopped !== null) { return $this->checkAlignment($phpcsFile, $stopped); } else { - return $assignment; + return $assign; } }//end checkAlignment() diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Formatting/SpaceAfterNotSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Formatting/SpaceAfterNotSniff.php index 0a5af940b..573aff874 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Formatting/SpaceAfterNotSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Formatting/SpaceAfterNotSniff.php @@ -11,7 +11,6 @@ use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Files\File; -use PHP_CodeSniffer\Util\Tokens; class SpaceAfterNotSniff implements Sniff { diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php index e18cf318a..33031ce2b 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php @@ -115,10 +115,19 @@ public function process(File $phpcsFile, $stackPtr) $error = 'Space found before comma in function call'; $fix = $phpcsFile->addFixableError($error, $nextSeparator, 'SpaceBeforeComma'); if ($fix === true) { - $phpcsFile->fixer->replaceToken(($nextSeparator - 1), ''); + $phpcsFile->fixer->beginChangeset(); + + if ($tokens[$prev]['line'] !== $tokens[$nextSeparator]['line']) { + $phpcsFile->fixer->addContent($prev, ','); + $phpcsFile->fixer->replaceToken($nextSeparator, ''); + } else { + $phpcsFile->fixer->replaceToken(($nextSeparator - 1), ''); + } + + $phpcsFile->fixer->endChangeset(); } - } - } + }//end if + }//end if if ($tokens[($nextSeparator + 1)]['code'] !== T_WHITESPACE) { $error = 'No space found after comma in function call'; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php index 3e4b9f936..572902e16 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceBsdAllmanSniff.php @@ -11,6 +11,7 @@ use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Util\Tokens; class OpeningFunctionBraceBsdAllmanSniff implements Sniff { @@ -80,26 +81,61 @@ public function process(File $phpcsFile, $stackPtr) } } - $functionLine = $tokens[$closeBracket]['line']; + // Find the end of the function declaration. + $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($openingBrace - 1), $closeBracket, true); + + $functionLine = $tokens[$prev]['line']; $braceLine = $tokens[$openingBrace]['line']; $lineDifference = ($braceLine - $functionLine); + $metricType = 'Function'; + if ($tokens[$stackPtr]['code'] === T_CLOSURE) { + $metricType = 'Closure'; + } + if ($lineDifference === 0) { $error = 'Opening brace should be on a new line'; $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceOnSameLine'); if ($fix === true) { + $hasTrailingAnnotation = false; + for ($nextLine = ($openingBrace + 1); $nextLine < $phpcsFile->numTokens; $nextLine++) { + if ($tokens[$openingBrace]['line'] !== $tokens[$nextLine]['line']) { + break; + } + + if (isset(Tokens::$phpcsCommentTokens[$tokens[$nextLine]['code']]) === true) { + $hasTrailingAnnotation = true; + } + } + $phpcsFile->fixer->beginChangeset(); $indent = $phpcsFile->findFirstOnLine([], $openingBrace); - if ($tokens[$indent]['code'] === T_WHITESPACE) { - $phpcsFile->fixer->addContentBefore($openingBrace, $tokens[$indent]['content']); + + if ($hasTrailingAnnotation === false || $nextLine === false) { + if ($tokens[$indent]['code'] === T_WHITESPACE) { + $phpcsFile->fixer->addContentBefore($openingBrace, $tokens[$indent]['content']); + } + + if ($tokens[($openingBrace - 1)]['code'] === T_WHITESPACE) { + $phpcsFile->fixer->replaceToken(($openingBrace - 1), ''); + } + + $phpcsFile->fixer->addNewlineBefore($openingBrace); + } else { + $phpcsFile->fixer->replaceToken($openingBrace, ''); + $phpcsFile->fixer->addNewlineBefore($nextLine); + $phpcsFile->fixer->addContentBefore($nextLine, '{'); + + if ($tokens[$indent]['code'] === T_WHITESPACE) { + $phpcsFile->fixer->addContentBefore($nextLine, $tokens[$indent]['content']); + } } - $phpcsFile->fixer->addNewlineBefore($openingBrace); $phpcsFile->fixer->endChangeset(); - } + }//end if - $phpcsFile->recordMetric($stackPtr, 'Function opening brace placement', 'same line'); + $phpcsFile->recordMetric($stackPtr, "$metricType opening brace placement", 'same line'); } else if ($lineDifference > 1) { $error = 'Opening brace should be on the line after the declaration; found %s blank line(s)'; $data = [($lineDifference - 1)]; @@ -116,7 +152,9 @@ public function process(File $phpcsFile, $stackPtr) } }//end if - $next = $phpcsFile->findNext(T_WHITESPACE, ($openingBrace + 1), null, true); + $ignore = Tokens::$phpcsCommentTokens; + $ignore[] = T_WHITESPACE; + $next = $phpcsFile->findNext($ignore, ($openingBrace + 1), null, true); if ($tokens[$next]['line'] === $tokens[$openingBrace]['line']) { if ($next === $tokens[$stackPtr]['scope_closer']) { // Ignore empty functions. @@ -167,7 +205,7 @@ public function process(File $phpcsFile, $stackPtr) } }//end if - $phpcsFile->recordMetric($stackPtr, 'Function opening brace placement', 'new line'); + $phpcsFile->recordMetric($stackPtr, "$metricType opening brace placement", 'new line'); }//end process() diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php index 1c7935c0b..d0f578a1e 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Functions/OpeningFunctionBraceKernighanRitchieSniff.php @@ -82,13 +82,21 @@ public function process(File $phpcsFile, $stackPtr) } } - $functionLine = $tokens[$closeBracket]['line']; + // Find the end of the function declaration. + $prev = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($openingBrace - 1), $closeBracket, true); + + $functionLine = $tokens[$prev]['line']; $braceLine = $tokens[$openingBrace]['line']; $lineDifference = ($braceLine - $functionLine); + $metricType = 'Function'; + if ($tokens[$stackPtr]['code'] === T_CLOSURE) { + $metricType = 'Closure'; + } + if ($lineDifference > 0) { - $phpcsFile->recordMetric($stackPtr, 'Function opening brace placement', 'new line'); + $phpcsFile->recordMetric($stackPtr, "$metricType opening brace placement", 'new line'); $error = 'Opening brace should be on the same line as the declaration'; $fix = $phpcsFile->addFixableError($error, $openingBrace, 'BraceOnNewLine'); if ($fix === true) { @@ -107,7 +115,7 @@ public function process(File $phpcsFile, $stackPtr) && $tokens[($openingBrace - 1)]['line'] === $tokens[$openingBrace]['line'] && $tokens[($openingBrace - 2)]['line'] < $tokens[$openingBrace]['line'] ) { - // Brace is preceeded by indent, so remove it to ensure we don't + // Brace is preceded by indent, so remove it to ensure we don't // leave behind more indent than is required for the first line. $phpcsFile->fixer->replaceToken(($openingBrace - 1), ''); } @@ -115,11 +123,13 @@ public function process(File $phpcsFile, $stackPtr) $phpcsFile->fixer->endChangeset(); }//end if + } else { + $phpcsFile->recordMetric($stackPtr, "$metricType opening brace placement", 'same line'); }//end if - $phpcsFile->recordMetric($stackPtr, 'Function opening brace placement', 'same line'); - - $next = $phpcsFile->findNext(T_WHITESPACE, ($openingBrace + 1), null, true); + $ignore = Tokens::$phpcsCommentTokens; + $ignore[] = T_WHITESPACE; + $next = $phpcsFile->findNext($ignore, ($openingBrace + 1), null, true); if ($tokens[$next]['line'] === $tokens[$openingBrace]['line']) { if ($next === $tokens[$stackPtr]['scope_closer'] || $tokens[$next]['code'] === T_CLOSE_TAG diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php index ab07e21e0..04634417a 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/Metrics/CyclomaticComplexitySniff.php @@ -58,8 +58,6 @@ public function register() */ public function process(File $phpcsFile, $stackPtr) { - $this->currentFile = $phpcsFile; - $tokens = $phpcsFile->getTokens(); // Ignore abstract methods. diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php index 40e3197c8..917db2069 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/CamelCapsFunctionNameSniff.php @@ -110,14 +110,14 @@ protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScop // Is this a magic method. i.e., is prefixed with "__" ? if (preg_match('|^__[^_]|', $methodName) !== 0) { $magicPart = strtolower(substr($methodName, 2)); - if (isset($this->magicMethods[$magicPart]) === false - && isset($this->methodsDoubleUnderscore[$magicPart]) === false + if (isset($this->magicMethods[$magicPart]) === true + || isset($this->methodsDoubleUnderscore[$magicPart]) === true ) { - $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; - $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData); + return; } - return; + $error = 'Method name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; + $phpcsFile->addError($error, $stackPtr, 'MethodDoubleUnderscore', $errorData); } // PHP4 constructors are allowed to break our rules. @@ -178,12 +178,12 @@ protected function processTokenOutsideScope(File $phpcsFile, $stackPtr) // Is this a magic function. i.e., it is prefixed with "__". if (preg_match('|^__[^_]|', $functionName) !== 0) { $magicPart = strtolower(substr($functionName, 2)); - if (isset($this->magicFunctions[$magicPart]) === false) { - $error = 'Function name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; - $phpcsFile->addError($error, $stackPtr, 'FunctionDoubleUnderscore', $errorData); + if (isset($this->magicFunctions[$magicPart]) === true) { + return; } - return; + $error = 'Function name "%s" is invalid; only PHP magic methods should be prefixed with a double underscore'; + $phpcsFile->addError($error, $stackPtr, 'FunctionDoubleUnderscore', $errorData); } // Ignore first underscore in functions prefixed with "_". diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php index 2fe74056f..32b940d81 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/UpperCaseConstantNameSniff.php @@ -11,6 +11,7 @@ use PHP_CodeSniffer\Sniffs\Sniff; use PHP_CodeSniffer\Files\File; +use PHP_CodeSniffer\Util\Tokens; class UpperCaseConstantNameSniff implements Sniff { @@ -23,7 +24,10 @@ class UpperCaseConstantNameSniff implements Sniff */ public function register() { - return [T_STRING]; + return [ + T_STRING, + T_CONST, + ]; }//end register() @@ -39,62 +43,22 @@ public function register() */ public function process(File $phpcsFile, $stackPtr) { - $tokens = $phpcsFile->getTokens(); - $constName = $tokens[$stackPtr]['content']; + $tokens = $phpcsFile->getTokens(); - // If this token is in a heredoc, ignore it. - if ($phpcsFile->hasCondition($stackPtr, T_START_HEREDOC) === true) { - return; - } - - // Special case for PHP 5.5 class name resolution. - if (strtolower($constName) === 'class' - && $tokens[($stackPtr - 1)]['code'] === T_DOUBLE_COLON - ) { - return; - } - - // Special case for PHPUnit. - if ($constName === 'PHPUnit_MAIN_METHOD') { - return; - } - - // If the next non-whitespace token after this token - // is not an opening parenthesis then it is not a function call. - for ($openBracket = ($stackPtr + 1); $openBracket < $phpcsFile->numTokens; $openBracket++) { - if ($tokens[$openBracket]['code'] !== T_WHITESPACE) { - break; - } - } - - if ($openBracket === $phpcsFile->numTokens) { - return; - } - - if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) { - $functionKeyword = $phpcsFile->findPrevious( - [ - T_WHITESPACE, - T_COMMA, - T_COMMENT, - T_STRING, - T_NS_SEPARATOR, - ], - ($stackPtr - 1), - null, - true - ); - - if ($tokens[$functionKeyword]['code'] !== T_CONST) { + if ($tokens[$stackPtr]['code'] === T_CONST) { + // This is a class constant. + $constant = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); + if ($constant === false) { return; } - // This is a class constant. + $constName = $tokens[$constant]['content']; + if (strtoupper($constName) !== $constName) { if (strtolower($constName) === $constName) { - $phpcsFile->recordMetric($stackPtr, 'Constant name case', 'lower'); + $phpcsFile->recordMetric($constant, 'Constant name case', 'lower'); } else { - $phpcsFile->recordMetric($stackPtr, 'Constant name case', 'mixed'); + $phpcsFile->recordMetric($constant, 'Constant name case', 'mixed'); } $error = 'Class constants must be uppercase; expected %s but found %s'; @@ -102,22 +66,19 @@ public function process(File $phpcsFile, $stackPtr) strtoupper($constName), $constName, ]; - $phpcsFile->addError($error, $stackPtr, 'ClassConstantNotUpperCase', $data); + $phpcsFile->addError($error, $constant, 'ClassConstantNotUpperCase', $data); } else { - $phpcsFile->recordMetric($stackPtr, 'Constant name case', 'upper'); + $phpcsFile->recordMetric($constant, 'Constant name case', 'upper'); } return; }//end if - if (strtolower($constName) !== 'define') { + // Only interested in define statements now. + if (strtolower($tokens[$stackPtr]['content']) !== 'define') { return; } - /* - This may be a "define" function call. - */ - // Make sure this is not a method call. $prev = $phpcsFile->findPrevious(T_WHITESPACE, ($stackPtr - 1), null, true); if ($tokens[$prev]['code'] === T_OBJECT_OPERATOR @@ -126,6 +87,13 @@ public function process(File $phpcsFile, $stackPtr) return; } + // If the next non-whitespace token after this token + // is not an opening parenthesis then it is not a function call. + $openBracket = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); + if ($openBracket === false) { + return; + } + // The next non-whitespace token must be the constant name. $constPtr = $phpcsFile->findNext(T_WHITESPACE, ($openBracket + 1), null, true); if ($tokens[$constPtr]['code'] !== T_CONSTANT_ENCAPSED_STRING) { diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/DeprecatedFunctionsSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/DeprecatedFunctionsSniff.php index b66b23d78..4ab3444a8 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/DeprecatedFunctionsSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/DeprecatedFunctionsSniff.php @@ -19,7 +19,7 @@ class DeprecatedFunctionsSniff extends ForbiddenFunctionsSniff * The value is NULL if no alternative exists. IE, the * function should just not be used. * - * @var array(string => string|null) + * @var array */ public $forbiddenFunctions = []; diff --git a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/DisallowAlternativePHPTagsSniff.php b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/DisallowAlternativePHPTagsSniff.php index be4bc1d93..178e87c85 100644 --- a/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/DisallowAlternativePHPTagsSniff.php +++ b/app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/PHP/DisallowAlternativePHPTagsSniff.php @@ -131,9 +131,8 @@ public function process(File $phpcsFile, $stackPtr) }//end if // Account for incorrect script open tags. - // The "(?:]+)?language=[\'"]?php[\'"]?(?:[^>]+)?>)`i', $content, $match) === 1 + && preg_match('`(