diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 9e5ea6a9..62c95b42 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -22,11 +22,11 @@ jobs: uses: actions/checkout@v4 - name: Install - run: npm install + run: npm ci - name: Setup Environment run: | - rm composer.lock + composer install --no-interaction --no-security-blocking npm run setup - name: Test diff --git a/composer.json b/composer.json index aa09726d..94fa07d8 100644 --- a/composer.json +++ b/composer.json @@ -19,17 +19,29 @@ "support" : { "issues": "https://github.com/WordPress/phpdoc-parser/issues" }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/dmsnell/Reflection.git" + }, + { + "type": "vcs", + "url": "git@github.com:dmsnell/ReflectionDocBlock.git", + "no-api": true + } + ], "require" : { - "php" : ">=5.4", + "php" : ">=7.4", "composer/installers" : "~1.0", - "phpdocumentor/reflection" : "~3.0", + "phpdocumentor/reflection" : "dev-fix/update-parser", + "phpdocumentor/reflection-docblock" : "dev-fix/php85-nullable-types as 2.0.5", "erusev/parsedown" : "~1.7", "scribu/lib-posts-to-posts": "dev-master@dev", "scribu/scb-framework" : "dev-master@dev", "psr/log" : "~1.0" }, "require-dev" : { - "phpunit/phpunit": "^7", + "phpunit/phpunit": "~8", "spatie/phpunit-watcher": "^1.23", "yoast/phpunit-polyfills": "^1.0" }, diff --git a/composer.lock b/composer.lock index 55aea9d6..aacae0e1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "96d200642f6aded313abd6eb270909ee", + "content-hash": "69f292856e9ab803391c7c86c3519794", "packages": [ { "name": "composer/installers", @@ -159,24 +159,24 @@ }, { "name": "erusev/parsedown", - "version": "1.7.4", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/erusev/parsedown.git", - "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3" + "reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3", - "reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/96baaad00f71ba04d76e45b4620f54d3beabd6f7", + "reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=5.3.0" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.35" + "phpunit/phpunit": "^7.5|^8.5|^9.6" }, "type": "library", "autoload": { @@ -203,38 +203,53 @@ ], "support": { "issues": "https://github.com/erusev/parsedown/issues", - "source": "https://github.com/erusev/parsedown/tree/1.7.x" + "source": "https://github.com/erusev/parsedown/tree/1.8.0" }, - "time": "2019-12-30T22:54:17+00:00" + "funding": [ + { + "url": "https://github.com/erusev", + "type": "github" + } + ], + "time": "2026-02-16T11:41:01+00:00" }, { "name": "nikic/php-parser", - "version": "v1.4.1", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51" + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", - "reference": "f78af2c9c86107aa1a34cd1dbb5bbe9eeb0d9f51", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=5.3" + "php": ">=7.4" }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "5.x-dev" } }, "autoload": { - "files": [ - "lib/bootstrap.php" - ] + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -252,28 +267,28 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/1.x" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2015-09-19T14:15:08+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { "name": "phpdocumentor/reflection", - "version": "3.0.1", + "version": "dev-fix/update-parser", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/Reflection.git", - "reference": "793bfd92d9a0fc96ae9608fb3e947c3f59fb3a0d" + "url": "https://github.com/dmsnell/Reflection.git", + "reference": "8ec058b8b96ddaebc0f21a12f9adc685b8a14cbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/793bfd92d9a0fc96ae9608fb3e947c3f59fb3a0d", - "reference": "793bfd92d9a0fc96ae9608fb3e947c3f59fb3a0d", + "url": "https://api.github.com/repos/dmsnell/Reflection/zipball/8ec058b8b96ddaebc0f21a12f9adc685b8a14cbc", + "reference": "8ec058b8b96ddaebc0f21a12f9adc685b8a14cbc", "shasum": "" }, "require": { - "nikic/php-parser": "^1.0", - "php": ">=5.3.3", - "phpdocumentor/reflection-docblock": "~2.0", + "nikic/php-parser": "^5.7", + "php": ">=7.4", + "phpdocumentor/reflection-docblock": "dev-fix/php85-nullable-types as 2.0.5", "psr/log": "~1.0" }, "require-dev": { @@ -296,7 +311,6 @@ ] } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -309,27 +323,26 @@ "static analysis" ], "support": { - "issues": "https://github.com/phpDocumentor/Reflection/issues", - "source": "https://github.com/phpDocumentor/Reflection/tree/master" + "source": "https://github.com/dmsnell/Reflection/tree/fix/update-parser" }, - "time": "2016-05-21T08:42:32+00:00" + "time": "2026-05-13T17:49:17+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "2.0.5", + "version": "dev-fix/php85-nullable-types", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" + "url": "git@github.com:dmsnell/ReflectionDocBlock.git", + "reference": "66542f768ac6b7be46f2f862f69d34cf13712ef9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", - "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "url": "https://api.github.com/repos/dmsnell/ReflectionDocBlock/zipball/66542f768ac6b7be46f2f862f69d34cf13712ef9", + "reference": "66542f768ac6b7be46f2f862f69d34cf13712ef9", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.4" }, "require-dev": { "phpunit/phpunit": "~4.0" @@ -341,6 +354,7 @@ "type": "library", "extra": { "branch-alias": { + "dev-fix/php85-nullable-types": "2.0.x-dev", "dev-master": "2.0.x-dev" } }, @@ -351,7 +365,6 @@ ] } }, - "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], @@ -361,11 +374,7 @@ "email": "mike.vanriel@naenius.com" } ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/2.x" - }, - "time": "2016-01-25T08:17:30+00:00" + "time": "2026-05-13T17:48:39+00:00" }, { "name": "psr/log", @@ -579,25 +588,25 @@ }, { "name": "clue/term-react", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/clue/reactphp-term.git", - "reference": "eb6eb063eda04a714ef89f066586a2c49588f7ca" + "reference": "00f297dc597eaee2ebf98af8f27cca5d21d60fa3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/clue/reactphp-term/zipball/eb6eb063eda04a714ef89f066586a2c49588f7ca", - "reference": "eb6eb063eda04a714ef89f066586a2c49588f7ca", + "url": "https://api.github.com/repos/clue/reactphp-term/zipball/00f297dc597eaee2ebf98af8f27cca5d21d60fa3", + "reference": "00f297dc597eaee2ebf98af8f27cca5d21d60fa3", "shasum": "" }, "require": { "php": ">=5.3", - "react/stream": "^1.0 || ^0.7" + "react/stream": "^1.2" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8", - "react/event-loop": "^1.0 || ^0.5 || ^0.4 || ^0.3" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/event-loop": "^1.2" }, "type": "library", "autoload": { @@ -636,7 +645,7 @@ ], "support": { "issues": "https://github.com/clue/reactphp-term/issues", - "source": "https://github.com/clue/reactphp-term/tree/v1.3.0" + "source": "https://github.com/clue/reactphp-term/tree/v1.4.0" }, "funding": [ { @@ -648,20 +657,20 @@ "type": "github" } ], - "time": "2020-11-06T11:50:12+00:00" + "time": "2024-01-30T10:22:09+00:00" }, { "name": "clue/utf8-react", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/clue/reactphp-utf8.git", - "reference": "8bc3f8c874cdf642c8f10f9ae93aadb8cd63da96" + "reference": "d5cd04d39cb5457aa5df830b7c4b301d2694217e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/clue/reactphp-utf8/zipball/8bc3f8c874cdf642c8f10f9ae93aadb8cd63da96", - "reference": "8bc3f8c874cdf642c8f10f9ae93aadb8cd63da96", + "url": "https://api.github.com/repos/clue/reactphp-utf8/zipball/d5cd04d39cb5457aa5df830b7c4b301d2694217e", + "reference": "d5cd04d39cb5457aa5df830b7c4b301d2694217e", "shasum": "" }, "require": { @@ -669,7 +678,7 @@ "react/stream": "^1.0 || ^0.7 || ^0.6 || ^0.5 || ^0.4 || ^0.3" }, "require-dev": { - "phpunit/phpunit": "^9.3 ||^5.7 || ^4.8", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", "react/stream": "^1.0 || ^0.7" }, "type": "library", @@ -699,7 +708,7 @@ ], "support": { "issues": "https://github.com/clue/reactphp-utf8/issues", - "source": "https://github.com/clue/reactphp-utf8/tree/v1.2.0" + "source": "https://github.com/clue/reactphp-utf8/tree/v1.3.0" }, "funding": [ { @@ -711,34 +720,34 @@ "type": "github" } ], - "time": "2020-11-06T11:48:09+00:00" + "time": "2023-12-06T14:52:17+00:00" }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.16 || ^1", "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.30 || ^5.4" }, "type": "library", "autoload": { @@ -765,7 +774,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" }, "funding": [ { @@ -781,32 +790,32 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "evenement/evenement", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/igorw/evenement.git", - "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7" + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/igorw/evenement/zipball/531bfb9d15f8aa57454f5f0285b18bec903b8fb7", - "reference": "531bfb9d15f8aa57454f5f0285b18bec903b8fb7", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", "shasum": "" }, "require": { "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9 || ^6" }, "type": "library", "autoload": { - "psr-0": { - "Evenement": "src" + "psr-4": { + "Evenement\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -826,9 +835,9 @@ ], "support": { "issues": "https://github.com/igorw/evenement/issues", - "source": "https://github.com/igorw/evenement/tree/master" + "source": "https://github.com/igorw/evenement/tree/v3.0.2" }, - "time": "2017-07-23T21:35:13+00:00" + "time": "2023-08-08T05:53:35+00:00" }, { "name": "jolicode/jolinotif", @@ -894,16 +903,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.13.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { @@ -911,11 +920,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -941,7 +951,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" }, "funding": [ { @@ -949,32 +959,34 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1006,26 +1018,32 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/master" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2018-07-08T19:23:20+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", - "version": "2.0.1", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -1057,113 +1075,46 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/master" - }, - "time": "2018-07-08T19:19:57+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.10.3", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" - }, - "time": "2020-03-05T15:02:03+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "6.1.4", + "version": "7.0.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.1", - "phpunit/php-file-iterator": "^2.0", + "php": ">=7.2", + "phpunit/php-file-iterator": "^2.0.2", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^3.0", + "phpunit/php-token-stream": "^3.1.3 || ^4.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.1 || ^4.0", + "sebastian/environment": "^4.2.2", "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "theseer/tokenizer": "^1.1.3" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^8.2.2" }, "suggest": { - "ext-xdebug": "^2.6.0" + "ext-xdebug": "^2.7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.1-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -1191,22 +1142,28 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.17" }, - "time": "2018-10-31T16:06:48+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:09:37+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5" + "reference": "69deeb8664f611f156a924154985fbd4911eb36b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", - "reference": "42c5ba5220e6904cbfe8b1a1bda7c0cfdc8c12f5", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/69deeb8664f611f156a924154985fbd4911eb36b", + "reference": "69deeb8664f611f156a924154985fbd4911eb36b", "shasum": "" }, "require": { @@ -1245,7 +1202,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.6" }, "funding": [ { @@ -1253,7 +1210,7 @@ "type": "github" } ], - "time": "2021-12-02T12:42:26+00:00" + "time": "2024-03-01T13:39:50+00:00" }, { "name": "phpunit/php-text-template", @@ -1302,16 +1259,16 @@ }, { "name": "phpunit/php-timer", - "version": "2.1.3", + "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a691211e94ff39a34811abd521c31bd5b305b0bb", + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb", "shasum": "" }, "require": { @@ -1349,7 +1306,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.4" }, "funding": [ { @@ -1357,33 +1314,33 @@ "type": "github" } ], - "time": "2020-11-30T08:20:02+00:00" + "time": "2024-03-01T13:42:41+00:00" }, { "name": "phpunit/php-token-stream", - "version": "3.1.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "9c1da83261628cb24b6a6df371b6e312b3954768" + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/9c1da83261628cb24b6a6df371b6e312b3954768", - "reference": "9c1da83261628cb24b6a6df371b6e312b3954768", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=7.1" + "php": "^7.3 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1408,7 +1365,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.3" + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" }, "funding": [ { @@ -1417,57 +1374,52 @@ } ], "abandoned": true, - "time": "2021-07-26T12:15:06+00:00" + "time": "2020-08-04T08:28:15+00:00" }, { "name": "phpunit/phpunit", - "version": "7.5.20", + "version": "8.5.52", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" + "reference": "1015741814413c156abb0f53d7db7bbd03c6e858" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1015741814413c156abb0f53d7db7bbd03c6e858", + "reference": "1015741814413c156abb0f53d7db7bbd03c6e858", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.1", + "doctrine/instantiator": "^1.5.0", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.7", - "phar-io/manifest": "^1.0.2", - "phar-io/version": "^2.0", - "php": "^7.1", - "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^6.0.7", - "phpunit/php-file-iterator": "^2.0.1", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=7.2", + "phpunit/php-code-coverage": "^7.0.17", + "phpunit/php-file-iterator": "^2.0.6", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^4.0", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0", + "phpunit/php-timer": "^2.1.4", + "sebastian/comparator": "^3.0.7", + "sebastian/diff": "^3.0.6", + "sebastian/environment": "^4.2.5", + "sebastian/exporter": "^3.1.8", + "sebastian/global-state": "^3.0.6", + "sebastian/object-enumerator": "^3.0.5", + "sebastian/resource-operations": "^2.0.3", + "sebastian/type": "^1.1.5", "sebastian/version": "^2.0.1" }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" - }, - "require-dev": { - "ext-pdo": "*" - }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage", + "phpunit/php-invoker": "To allow enforcing time limits" }, "bin": [ "phpunit" @@ -1475,7 +1427,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.5-dev" + "dev-master": "8.5-dev" } }, "autoload": { @@ -1503,9 +1455,32 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.52" }, - "time": "2020-01-08T08:45:45+00:00" + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2026-01-27T05:20:18+00:00" }, { "name": "psr/container", @@ -1557,33 +1532,31 @@ }, { "name": "react/event-loop", - "version": "v1.3.0", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/reactphp/event-loop.git", - "reference": "187fb56f46d424afb6ec4ad089269c72eec2e137" + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/187fb56f46d424afb6ec4ad089269c72eec2e137", - "reference": "187fb56f46d424afb6ec4ad089269c72eec2e137", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a", "shasum": "" }, "require": { "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" }, "suggest": { - "ext-event": "~1.0 for ExtEventLoop", - "ext-pcntl": "For signal handling support when using the StreamSelectLoop", - "ext-uv": "* for ExtUvLoop" + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" }, "type": "library", "autoload": { "psr-4": { - "React\\EventLoop\\": "src" + "React\\EventLoop\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1619,32 +1592,28 @@ ], "support": { "issues": "https://github.com/reactphp/event-loop/issues", - "source": "https://github.com/reactphp/event-loop/tree/v1.3.0" + "source": "https://github.com/reactphp/event-loop/tree/v1.6.0" }, "funding": [ { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2022-03-17T11:10:22+00:00" + "time": "2025-11-17T20:46:25+00:00" }, { "name": "react/stream", - "version": "v1.2.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/reactphp/stream.git", - "reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9" + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/stream/zipball/7a423506ee1903e89f1e08ec5f0ed430ff784ae9", - "reference": "7a423506ee1903e89f1e08ec5f0ed430ff784ae9", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", "shasum": "" }, "require": { @@ -1654,12 +1623,12 @@ }, "require-dev": { "clue/stream-filter": "~1.2", - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" }, "type": "library", "autoload": { "psr-4": { - "React\\Stream\\": "src" + "React\\Stream\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1701,32 +1670,28 @@ ], "support": { "issues": "https://github.com/reactphp/stream/issues", - "source": "https://github.com/reactphp/stream/tree/v1.2.0" + "source": "https://github.com/reactphp/stream/tree/v1.4.0" }, "funding": [ { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2021-07-11T12:37:55+00:00" + "time": "2024-06-11T12:45:25+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", "shasum": "" }, "require": { @@ -1760,7 +1725,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.3" }, "funding": [ { @@ -1768,20 +1733,20 @@ "type": "github" } ], - "time": "2020-11-30T08:15:22+00:00" + "time": "2024-03-01T13:45:45+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.3", + "version": "3.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" + "reference": "bc7d8ac2fe1cce229bff9b5fd4efe65918a1ff52" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/bc7d8ac2fe1cce229bff9b5fd4efe65918a1ff52", + "reference": "bc7d8ac2fe1cce229bff9b5fd4efe65918a1ff52", "shasum": "" }, "require": { @@ -1834,28 +1799,40 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.7" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" } ], - "time": "2020-11-30T08:04:30+00:00" + "time": "2026-01-24T09:20:25+00:00" }, { "name": "sebastian/diff", - "version": "3.0.3", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/98ff311ca519c3aa73ccd3de053bdb377171d7b6", + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6", "shasum": "" }, "require": { @@ -1900,7 +1877,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.6" }, "funding": [ { @@ -1908,20 +1885,20 @@ "type": "github" } ], - "time": "2020-11-30T07:59:04+00:00" + "time": "2024-03-02T06:16:36+00:00" }, { "name": "sebastian/environment", - "version": "4.2.4", + "version": "4.2.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" + "reference": "56932f6049a0482853056ffd617c91ffcc754205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/56932f6049a0482853056ffd617c91ffcc754205", + "reference": "56932f6049a0482853056ffd617c91ffcc754205", "shasum": "" }, "require": { @@ -1963,7 +1940,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.5" }, "funding": [ { @@ -1971,24 +1948,24 @@ "type": "github" } ], - "time": "2020-11-30T07:53:42+00:00" + "time": "2024-03-01T13:49:59+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.4", + "version": "3.1.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db" + "reference": "64cfeaa341951ceb2019d7b98232399d57bb2296" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", - "reference": "0c32ea2e40dbf59de29f3b49bf375176ce7dd8db", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/64cfeaa341951ceb2019d7b98232399d57bb2296", + "reference": "64cfeaa341951ceb2019d7b98232399d57bb2296", "shasum": "" }, "require": { - "php": ">=7.0", + "php": ">=7.2", "sebastian/recursion-context": "^3.0" }, "require-dev": { @@ -2040,35 +2017,50 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.8" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" } ], - "time": "2021-11-11T13:51:24+00:00" + "time": "2025-09-24T05:55:14+00:00" }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "800689427e3e8cf57a8fe38fcd1d4344c9b2f046" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/800689427e3e8cf57a8fe38fcd1d4344c9b2f046", + "reference": "800689427e3e8cf57a8fe38fcd1d4344c9b2f046", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^8.0" }, "suggest": { "ext-uopz": "*" @@ -2076,7 +2068,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -2101,22 +2093,40 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.6" }, - "time": "2017-04-27T15:39:26+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" + } + ], + "time": "2025-08-10T05:40:12+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.4", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + "reference": "ac5b293dba925751b808e02923399fb44ff0d541" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/ac5b293dba925751b808e02923399fb44ff0d541", + "reference": "ac5b293dba925751b808e02923399fb44ff0d541", "shasum": "" }, "require": { @@ -2152,7 +2162,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.5" }, "funding": [ { @@ -2160,20 +2170,20 @@ "type": "github" } ], - "time": "2020-11-30T07:40:27+00:00" + "time": "2024-03-01T13:54:02+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/1d439c229e61f244ff1f211e5c99737f90c67def", + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def", "shasum": "" }, "require": { @@ -2207,7 +2217,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.3" }, "funding": [ { @@ -2215,20 +2225,20 @@ "type": "github" } ], - "time": "2020-11-30T07:37:18+00:00" + "time": "2024-03-01T13:56:04+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.1", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + "reference": "8fe7e75986a9d24b4cceae847314035df7703a5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/8fe7e75986a9d24b4cceae847314035df7703a5a", + "reference": "8fe7e75986a9d24b4cceae847314035df7703a5a", "shasum": "" }, "require": { @@ -2270,28 +2280,40 @@ "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "time": "2020-11-30T07:34:24+00:00" + "time": "2025-08-10T05:25:53+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/72a7f7674d053d548003b16ff5a106e7e0e06eee", + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee", "shasum": "" }, "require": { @@ -2321,8 +2343,7 @@ "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.3" }, "funding": [ { @@ -2330,7 +2351,63 @@ "type": "github" } ], - "time": "2020-11-30T07:30:19+00:00" + "time": "2024-03-01T13:59:09+00:00" + }, + { + "name": "sebastian/type", + "version": "1.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/18f071c3a29892b037d35e6b20ddf3ea39b42874", + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/1.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-01T14:04:07+00:00" }, { "name": "sebastian/version", @@ -2445,16 +2522,16 @@ }, { "name": "symfony/console", - "version": "v5.4.12", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1" + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c072aa8f724c3af64e2c7a96b796a4863d24dba1", - "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1", + "url": "https://api.github.com/repos/symfony/console/zipball/c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", "shasum": "" }, "require": { @@ -2519,12 +2596,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.12" + "source": "https://github.com/symfony/console/tree/v5.4.47" }, "funding": [ { @@ -2540,20 +2617,20 @@ "type": "tidelift" } ], - "time": "2022-08-17T13:18:05+00:00" + "time": "2024-11-06T11:30:55+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.2", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/605389f2a7e5625f273b53960dc46aeaf9c62918", + "reference": "605389f2a7e5625f273b53960dc46aeaf9c62918", "shasum": "" }, "require": { @@ -2561,12 +2638,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -2591,7 +2668,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.4" }, "funding": [ { @@ -2607,20 +2684,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/finder", - "version": "v5.4.11", + "version": "v5.4.45", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" + "reference": "63741784cd7b9967975eec610b256eed3ede022b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", - "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", + "url": "https://api.github.com/repos/symfony/finder/zipball/63741784cd7b9967975eec610b256eed3ede022b", + "reference": "63741784cd7b9967975eec610b256eed3ede022b", "shasum": "" }, "require": { @@ -2654,7 +2731,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.11" + "source": "https://github.com/symfony/finder/tree/v5.4.45" }, "funding": [ { @@ -2670,24 +2747,24 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:37:50+00:00" + "time": "2024-09-28T13:32:08+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.26.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -2697,12 +2774,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2736,7 +2810,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" }, "funding": [ { @@ -2747,41 +2821,42 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.26.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "433d05519ce6990bf3530fba6957499d327395c2" + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", - "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2817,7 +2892,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" }, "funding": [ { @@ -2828,41 +2903,42 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2025-06-27T09:58:17+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2901,7 +2977,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" }, "funding": [ { @@ -2912,29 +2988,34 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -2944,12 +3025,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2984,7 +3062,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -2995,38 +3073,39 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.26.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", - "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3063,7 +3142,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.33.0" }, "funding": [ { @@ -3074,38 +3153,39 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.26-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3146,7 +3226,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" }, "funding": [ { @@ -3157,25 +3237,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2025-01-02T08:10:11+00:00" }, { "name": "symfony/process", - "version": "v5.4.11", + "version": "v5.4.51", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" + "reference": "467bfc56f18f5ef6d5ccb09324d7e988c1c0a98f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", - "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", + "url": "https://api.github.com/repos/symfony/process/zipball/467bfc56f18f5ef6d5ccb09324d7e988c1c0a98f", + "reference": "467bfc56f18f5ef6d5ccb09324d7e988c1c0a98f", "shasum": "" }, "require": { @@ -3208,7 +3292,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.11" + "source": "https://github.com/symfony/process/tree/v5.4.51" }, "funding": [ { @@ -3219,25 +3303,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2022-06-27T16:58:25+00:00" + "time": "2026-01-26T15:53:37+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.2", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + "reference": "f37b419f7aea2e9abf10abd261832cace12e3300" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f37b419f7aea2e9abf10abd261832cace12e3300", + "reference": "f37b419f7aea2e9abf10abd261832cace12e3300", "shasum": "" }, "require": { @@ -3253,12 +3341,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -3291,7 +3379,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.4" }, "funding": [ { @@ -3307,20 +3395,20 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:29+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/string", - "version": "v5.4.12", + "version": "v5.4.47", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058" + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/2fc515e512d721bf31ea76bd02fe23ada4640058", - "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058", + "url": "https://api.github.com/repos/symfony/string/zipball/136ca7d72f72b599f2631aca474a4f8e26719799", + "reference": "136ca7d72f72b599f2631aca474a4f8e26719799", "shasum": "" }, "require": { @@ -3377,7 +3465,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.12" + "source": "https://github.com/symfony/string/tree/v5.4.47" }, "funding": [ { @@ -3393,20 +3481,20 @@ "type": "tidelift" } ], - "time": "2022-08-12T17:03:11+00:00" + "time": "2024-11-10T20:33:58+00:00" }, { "name": "symfony/yaml", - "version": "v5.4.12", + "version": "v5.4.45", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "7a3aa21ac8ab1a96cc6de5bbcab4bc9fc943b18c" + "reference": "a454d47278cc16a5db371fe73ae66a78a633371e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/7a3aa21ac8ab1a96cc6de5bbcab4bc9fc943b18c", - "reference": "7a3aa21ac8ab1a96cc6de5bbcab4bc9fc943b18c", + "url": "https://api.github.com/repos/symfony/yaml/zipball/a454d47278cc16a5db371fe73ae66a78a633371e", + "reference": "a454d47278cc16a5db371fe73ae66a78a633371e", "shasum": "" }, "require": { @@ -3452,7 +3540,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.4.12" + "source": "https://github.com/symfony/yaml/tree/v5.4.45" }, "funding": [ { @@ -3468,20 +3556,20 @@ "type": "tidelift" } ], - "time": "2022-08-02T15:52:22+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", "shasum": "" }, "require": { @@ -3510,7 +3598,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" }, "funding": [ { @@ -3518,20 +3606,20 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2025-11-17T20:03:58+00:00" }, { "name": "yoast/phpunit-polyfills", - "version": "1.0.3", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", - "reference": "5ea3536428944955f969bc764bbe09738e151ada" + "reference": "41aaac462fbd80feb8dd129e489f4bbc53fe26b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/5ea3536428944955f969bc764bbe09738e151ada", - "reference": "5ea3536428944955f969bc764bbe09738e151ada", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/41aaac462fbd80feb8dd129e489f4bbc53fe26b0", + "reference": "41aaac462fbd80feb8dd129e489f4bbc53fe26b0", "shasum": "" }, "require": { @@ -3539,13 +3627,14 @@ "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" }, "require-dev": { - "yoast/yoastcs": "^2.2.0" + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "yoast/yoastcs": "^3.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev", - "dev-develop": "1.x-dev" + "dev-main": "4.x-dev" } }, "autoload": { @@ -3577,9 +3666,10 @@ ], "support": { "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", + "security": "https://github.com/Yoast/PHPUnit-Polyfills/security/policy", "source": "https://github.com/Yoast/PHPUnit-Polyfills" }, - "time": "2021-11-23T01:37:03+00:00" + "time": "2025-08-10T04:54:36+00:00" }, { "name": "yosymfony/resource-watcher", @@ -3639,17 +3729,26 @@ "time": "2020-06-10T14:58:36+00:00" } ], - "aliases": [], + "aliases": [ + { + "package": "phpdocumentor/reflection-docblock", + "version": "dev-fix/php85-nullable-types", + "alias": "2.0.5", + "alias_normalized": "2.0.5.0" + } + ], "minimum-stability": "stable", "stability-flags": { + "phpdocumentor/reflection": 20, + "phpdocumentor/reflection-docblock": 20, "scribu/lib-posts-to-posts": 20, "scribu/scb-framework": 20 }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.4" + "php": ">=7.4" }, - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/generate-json-manually.php b/generate-json-manually.php new file mode 100644 index 00000000..1f4b99c5 --- /dev/null +++ b/generate-json-manually.php @@ -0,0 +1,62 @@ +_get_phpdoc_data( $path ); + } +} + +$f = fopen( $opts['o'], "w" ); + +fwrite( $f, ManualRunner::generate( $opts['d'] ) ); diff --git a/lib/class-file-reflector.php b/lib/class-file-reflector.php index 62f401d7..ef421ccf 100644 --- a/lib/class-file-reflector.php +++ b/lib/class-file-reflector.php @@ -12,6 +12,11 @@ * hooks and note function relationships. */ class File_Reflector extends FileReflector { + /** + * Attribute key used to store queued uses on PHP-Parser nodes. + */ + const USES_ATTRIBUTE = 'wp_parser_uses'; + /** * List of elements used in global scope in this file, indexed by element type. * @@ -40,7 +45,7 @@ class File_Reflector extends FileReflector { /** * Last DocBlock associated with a non-documentable element. * - * @var \PHPParser_Comment_Doc + * @var \PhpParser\Comment\Doc */ protected $last_doc = null; @@ -61,9 +66,9 @@ class File_Reflector extends FileReflector { * Finally, we pick up any docblocks for nodes that usually aren't documentable, * so they can be assigned to the hooks to which they may belong. * - * @param \PHPParser_Node $node + * @param \PhpParser\Node $node */ - public function enterNode( \PHPParser_Node $node ) { + public function enterNode( \PhpParser\Node $node ) { parent::enterNode( $node ); switch ( $node->getType() ) { @@ -79,7 +84,7 @@ public function enterNode( \PHPParser_Node $node ) { $function = new Function_Call_Reflector( $node, $this->context ); // Add the call to the list of functions used in this scope. - $this->getLocation()->uses['functions'][] = $function; + $this->add_use( 'functions', $function ); if ( $this->isFilter( $node ) ) { if ( $this->last_doc && ! $node->getDocComment() ) { @@ -90,7 +95,7 @@ public function enterNode( \PHPParser_Node $node ) { $hook = new Hook_Reflector( $node, $this->context ); // Add it to the list of hooks used in this scope. - $this->getLocation()->uses['hooks'][] = $hook; + $this->add_use( 'hooks', $hook ); } break; @@ -99,7 +104,7 @@ public function enterNode( \PHPParser_Node $node ) { $method = new Method_Call_Reflector( $node, $this->context ); // Add it to the list of methods used in this scope. - $this->getLocation()->uses['methods'][] = $method; + $this->add_use( 'methods', $method ); break; // Parse out method calls, so we can export where methods are used. @@ -107,7 +112,7 @@ public function enterNode( \PHPParser_Node $node ) { $method = new Static_Method_Call_Reflector( $node, $this->context ); // Add it to the list of methods used in this scope. - $this->getLocation()->uses['methods'][] = $method; + $this->add_use( 'methods', $method ); break; // Parse out `new Class()` calls as uses of Class::__construct(). @@ -115,7 +120,7 @@ public function enterNode( \PHPParser_Node $node ) { $method = new \WP_Parser\Method_Call_Reflector( $node, $this->context ); // Add it to the list of methods used in this scope. - $this->getLocation()->uses['methods'][] = $method; + $this->add_use( 'methods', $method ); break; } @@ -126,7 +131,11 @@ public function enterNode( \PHPParser_Node $node ) { // we don't ignore them, we'll end up picking up docblocks that are already // associated with a named element, and so aren't really from a non- // documentable element after all. - if ( ! $this->isNodeDocumentable( $node ) && 'Name' !== $node->getType() && ( $docblock = $node->getDocComment() ) ) { + if ( + ! $this->isNodeDocumentable( $node ) + && 'Name' !== $node->getType() + && 'Name_FullyQualified' !== $node->getType() + && ( $docblock = $node->getDocComment() ) ) { $this->last_doc = $docblock; } } @@ -137,9 +146,9 @@ public function enterNode( \PHPParser_Node $node ) { * We can now access the function/method reflectors, so we can assign any queued * hooks to them. The reflector for a node isn't created until the node is left. * - * @param \PHPParser_Node $node + * @param \PhpParser\Node $node */ - public function leaveNode( \PHPParser_Node $node ) { + public function leaveNode( \PhpParser\Node $node ) { parent::leaveNode( $node ); @@ -149,19 +158,20 @@ public function leaveNode( \PHPParser_Node $node ) { if ( ! empty( $this->method_uses_queue ) ) { /** @var Reflection\ClassReflector\MethodReflector $method */ foreach ( $class->getMethods() as $method ) { - if ( isset( $this->method_uses_queue[ $method->getName() ] ) ) { - if ( isset( $this->method_uses_queue[ $method->getName() ]['methods'] ) ) { + $method_name = $method->getName(); + if ( isset( $this->method_uses_queue[ $method_name ] ) ) { + if ( isset( $this->method_uses_queue[ $method_name ]['methods'] ) ) { /* * For methods used in a class, set the class on the method call. * That allows us to later get the correct class name for $this, self, parent. */ - foreach ( $this->method_uses_queue[ $method->getName() ]['methods'] as $method_call ) { + foreach ( $this->method_uses_queue[ $method_name ]['methods'] as $method_call ) { /** @var Method_Call_Reflector $method_call */ $method_call->set_class( $class ); } } - $method->uses = $this->method_uses_queue[ $method->getName() ]; + $method->uses = $this->method_uses_queue[ $method_name ]; } } } @@ -172,8 +182,9 @@ public function leaveNode( \PHPParser_Node $node ) { case 'Stmt_Function': $function = array_pop( $this->location ); - if ( isset( $function->uses ) && ! empty( $function->uses ) ) { - end( $this->functions )->uses = $function->uses; + $uses = $this->get_node_uses( $function ); + if ( ! empty( $uses ) ) { + end( $this->functions )->uses = $uses; } break; @@ -184,21 +195,24 @@ public function leaveNode( \PHPParser_Node $node ) { * Store the list of elements used by this method in the queue. We'll * assign them to the method upon leaving the class (see above). */ - if ( ! empty( $method->uses ) ) { - $this->method_uses_queue[ $method->name ] = $method->uses; + $uses = $this->get_node_uses( $method ); + if ( ! empty( $uses ) ) { + $this->method_uses_queue[ (string) $method->name ] = $uses; } break; } } /** - * @param \PHPParser_Node $node + * @param \PhpParser\Node $node * * @return bool */ - protected function isFilter( \PHPParser_Node $node ) { - // Ignore variable functions - if ( 'Name' !== $node->name->getType() ) { + protected function isFilter( \PhpParser\Node $node ) { + if ( + 'Name' !== $node->name->getType() && + 'Name_FullyQualified' !== $node->name->getType() + ) { return false; } @@ -224,13 +238,49 @@ protected function getLocation() { } /** - * @param \PHPParser_Node $node + * Add a used element to the current parser scope. + * + * File-scope uses are stored on this reflector, while function and method + * scope uses are stored as PHP-Parser node attributes until matching + * reflectors are available. + * + * @param string $type + * @param object $reflector + */ + protected function add_use( $type, $reflector ) { + $location = $this->getLocation(); + + if ( $location instanceof self ) { + $this->uses[ $type ][] = $reflector; + return; + } + + $uses = $this->get_node_uses( $location ); + $uses[ $type ][] = $reflector; + $location->setAttribute( self::USES_ATTRIBUTE, $uses ); + } + + /** + * Get queued uses from a PHP-Parser node. + * + * @param \PhpParser\Node $node + * + * @return array + */ + protected function get_node_uses( \PhpParser\Node $node ) { + $uses = $node->getAttribute( self::USES_ATTRIBUTE, array() ); + + return is_array( $uses ) ? $uses : array(); + } + + /** + * @param \PhpParser\Node $node * * @return bool */ - protected function isNodeDocumentable( \PHPParser_Node $node ) { + protected function isNodeDocumentable( \PhpParser\Node $node ) { return parent::isNodeDocumentable( $node ) - || ( $node instanceof \PHPParser_Node_Expr_FuncCall + || ( $node instanceof \PhpParser\Node\Expr\FuncCall && $this->isFilter( $node ) ); } } diff --git a/lib/class-function-call-reflector.php b/lib/class-function-call-reflector.php index 233e6d87..c41df6f2 100644 --- a/lib/class-function-call-reflector.php +++ b/lib/class-function-call-reflector.php @@ -20,30 +20,41 @@ class Function_Call_Reflector extends BaseReflector { */ public function getName() { if ( isset( $this->node->namespacedName ) ) { - return '\\' . implode( '\\', $this->node->namespacedName->parts ); + return '\\' . $this->nameToString( $this->node->namespacedName ); } $shortName = $this->getShortName(); - if ( is_a( $shortName, 'PHPParser_Node_Name_FullyQualified' ) ) { + if ( is_a( $shortName, 'PhpParser\Node\Name\FullyQualified' ) ) { return '\\' . (string) $shortName; } - if ( is_a( $shortName, 'PHPParser_Node_Name' ) ) { + if ( is_a( $shortName, 'PhpParser\Node\Name' ) ) { return (string) $shortName; } - /** @var \PHPParser_Node_Expr_ArrayDimFetch $shortName */ - if ( is_a( $shortName, 'PHPParser_Node_Expr_ArrayDimFetch' ) ) { - $var = $shortName->var->name; - $dim = $shortName->dim->name->parts[0]; + /** @var \PhpParser\Node\Expr\ArrayDimFetch $shortName */ + if ( is_a( $shortName, 'PhpParser\Node\Expr\ArrayDimFetch' ) ) { + $var = $this->nameToString( $shortName->var->name ); + $dim = isset( $shortName->dim->name ) + ? $this->nameToString( $shortName->dim->name ) + : ( isset( $shortName->dim->value ) ? $shortName->dim->value : (string) $shortName->dim ); return "\${$var}[{$dim}]"; } - /** @var \PHPParser_Node_Expr_Variable $shortName */ - if ( is_a( $shortName, 'PHPParser_Node_Expr_Variable' ) ) { - return $shortName->name; + /** @var \PhpParser\Node\Expr\Variable $shortName */ + if ( is_a( $shortName, 'PhpParser\Node\Expr\Variable' ) ) { + return $this->nameToString( $shortName->name ); + } + + /** @var \PhpParser\Node\Expr\PropertyFetch $shortName */ + if ( is_a( $shortName, 'PhpParser\Node\Expr\PropertyFetch' ) ) { + return sprintf( + '($%s->%s)', + $this->nameToString( $shortName->var->name ), + $this->nameToString( $shortName->name ) + ); } return (string) $shortName; diff --git a/lib/class-hook-reflector.php b/lib/class-hook-reflector.php index 50075e0f..6b979b93 100644 --- a/lib/class-hook-reflector.php +++ b/lib/class-hook-reflector.php @@ -3,7 +3,6 @@ namespace WP_Parser; use phpDocumentor\Reflection\BaseReflector; -use PHPParser_PrettyPrinter_Default; /** * Custom reflector for WordPress hooks. @@ -14,7 +13,7 @@ class Hook_Reflector extends BaseReflector { * @return string */ public function getName() { - $printer = new PHPParser_PrettyPrinter_Default; + $printer = new \PhpParser\PrettyPrinter\Standard(); return $this->cleanupName( $printer->prettyPrintExpr( $this->node->args[0]->value ) ); } @@ -73,7 +72,7 @@ public function getType() { case 'apply_filters_ref_array': $type = 'filter_reference'; break; - case 'apply_filters_deprecated'; + case 'apply_filters_deprecated': $type = 'filter_deprecated'; break; } diff --git a/lib/class-method-call-reflector.php b/lib/class-method-call-reflector.php index 570d5a54..9ad6bd20 100644 --- a/lib/class-method-call-reflector.php +++ b/lib/class-method-call-reflector.php @@ -32,23 +32,27 @@ public function getName() { $caller = $this->node->var; } - if ( $caller instanceof \PHPParser_Node_Expr ) { + if ( $caller instanceof \PhpParser\Node\Expr ) { $printer = new Pretty_Printer; $caller = $printer->prettyPrintExpr( $caller ); - } elseif ( $caller instanceof \PHPParser_Node_Name_FullyQualified ) { + } elseif ( $caller instanceof \PhpParser\Node\Name\FullyQualified ) { $caller = '\\' . $caller->toString(); - } elseif ( $caller instanceof \PHPParser_Node_Name ) { + } elseif ( $caller instanceof \PhpParser\Node\Name ) { $caller = $caller->toString(); + } elseif ( $caller instanceof \PhpParser\Node\Stmt\Class_ ) { + $caller = $caller->isAnonymous() + ? 'class@anonymous' + : $this->nameToString( $caller->name ); } $caller = $this->_resolveName( $caller ); // If the caller is a function, convert it to the function name - if ( is_a( $caller, 'PHPParser_Node_Expr_FuncCall' ) ) { + if ( is_a( $caller, 'PhpParser\Node\Expr\FuncCall' ) ) { // Add parentheses to signify this is a function call - /** @var \PHPParser_Node_Expr_FuncCall $caller */ - $caller = implode( '\\', $caller->name->parts ) . '()'; + /** @var \PhpParser\Node\Expr\FuncCall $caller */ + $caller = $this->nameToString( $caller->name ) . '()'; } $class_mapping = $this->_getClassMapping(); @@ -134,13 +138,12 @@ protected function _getClassMapping() { * * @return string The resolved class name. */ - protected function _resolveName( $class ) { + protected function _resolveName( string $class ): string { if ( ! $this->called_in_class ) { return $class; } - switch ( $class ) { case '$this': case 'self': diff --git a/lib/class-pretty-printer.php b/lib/class-pretty-printer.php index 31c37e28..7cfd0c55 100644 --- a/lib/class-pretty-printer.php +++ b/lib/class-pretty-printer.php @@ -2,21 +2,34 @@ namespace WP_Parser; -use PHPParser_Node_Arg; -use PHPParser_PrettyPrinter_Default; - /** * Extends default printer for arguments. */ -class Pretty_Printer extends PHPParser_PrettyPrinter_Default { +class Pretty_Printer extends \PhpParser\PrettyPrinter\Standard { /** * Pretty prints an argument. * - * @param PHPParser_Node_Arg $node Expression argument + * @param \PhpParser\Node\Arg $node Expression argument * * @return string Pretty printed argument */ - public function prettyPrintArg( PHPParser_Node_Arg $node ) { - return str_replace( "\n" . $this->noIndentToken, "\n", $this->p( $node ) ); + public function prettyPrintArg( \PhpParser\Node\Arg $node ) { + $printed = ''; + + if ( null !== $node->name ) { + $printed .= $node->name->toString() . ': '; + } + + if ( $node->byRef ) { + $printed .= '&'; + } + + if ( $node->unpack ) { + $printed .= '...'; + } + + $printed .= $this->prettyPrintExpr( $node->value ); + + return $printed; } } diff --git a/lib/class-static-method-call-reflector.php b/lib/class-static-method-call-reflector.php index 9d39c7c2..526538a0 100644 --- a/lib/class-static-method-call-reflector.php +++ b/lib/class-static-method-call-reflector.php @@ -12,10 +12,18 @@ class Static_Method_Call_Reflector extends Method_Call_Reflector { * * @return string[] Index 0 is the class name, 1 is the method name. */ - public function getName() { + public function getName(): array { $class = $this->node->class; - $prefix = ( is_a( $class, 'PHPParser_Node_Name_FullyQualified' ) ) ? '\\' : ''; - $class = $prefix . $this->_resolveName( implode( '\\', $class->parts ) ); + $prefix = ( is_a( $class, 'PhpParser\Node\Name\FullyQualified' ) ) ? '\\' : ''; + + if ( $class instanceof \PhpParser\Node\Stmt\Class_ && $class->isAnonymous() ) { + $class = 'class@anonymous'; + } elseif ( $class instanceof \PhpParser\Node\Expr\Variable ) { + // Static calls like `$foo::bar()` + $class = '$' . $this->nameToString( $class->name ); + } else { + $class = $prefix . $this->_resolveName( $this->nameToString( $class ) ); + } return array( $class, $this->getShortName() ); } diff --git a/lib/runner.php b/lib/runner.php index ba3efdd4..4250b23a 100644 --- a/lib/runner.php +++ b/lib/runner.php @@ -35,6 +35,8 @@ function get_wp_files( $directory ) { ); } + sort( $files ); + return $files; } @@ -47,89 +49,120 @@ function get_wp_files( $directory ) { function parse_files( $files, $root ) { $output = array(); - foreach ( $files as $filename ) { - $file = new File_Reflector( $filename ); - - $path = ltrim( substr( $filename, strlen( $root ) ), DIRECTORY_SEPARATOR ); - $file->setFilename( $path ); + try { + foreach ( $files as $filename ) { + $file = new File_Reflector( $filename ); - $file->process(); + $path = ltrim( substr( $filename, strlen( $root ) ), DIRECTORY_SEPARATOR ); + $file->setFilename( $path ); - // TODO proper exporter - $out = array( - 'file' => export_docblock( $file ), - 'path' => str_replace( DIRECTORY_SEPARATOR, '/', $file->getFilename() ), - 'root' => $root, - ); + $file->process(); - if ( ! empty( $file->uses ) ) { - $out['uses'] = export_uses( $file->uses ); - } - - foreach ( $file->getIncludes() as $include ) { - $out['includes'][] = array( - 'name' => $include->getName(), - 'line' => $include->getLineNumber(), - 'type' => $include->getType(), + // TODO proper exporter + $out = array( + 'file' => export_docblock( $file ), + 'path' => str_replace( DIRECTORY_SEPARATOR, '/', $file->getFilename() ), + 'root' => $root, ); - } - foreach ( $file->getConstants() as $constant ) { - $out['constants'][] = array( - 'name' => $constant->getShortName(), - 'line' => $constant->getLineNumber(), - 'value' => $constant->getValue(), - ); - } + if ( ! empty( $file->uses ) ) { + $out['uses'] = export_uses( $file->uses ); + } - if ( ! empty( $file->uses['hooks'] ) ) { - $out['hooks'] = export_hooks( $file->uses['hooks'] ); - } + foreach ( $file->getIncludes() as $include ) { + $out['includes'][] = array( + 'name' => $include->getName(), + 'line' => $include->getLineNumber(), + 'type' => $include->getType(), + ); + } - foreach ( $file->getFunctions() as $function ) { - $func = array( - 'name' => $function->getShortName(), - 'namespace' => $function->getNamespace(), - 'aliases' => $function->getNamespaceAliases(), - 'line' => $function->getLineNumber(), - 'end_line' => $function->getNode()->getAttribute( 'endLine' ), - 'arguments' => export_arguments( $function->getArguments() ), - 'doc' => export_docblock( $function ), - 'hooks' => array(), - ); + foreach ( $file->getConstants() as $constant ) { + $out['constants'][] = array( + 'name' => $constant->getShortName(), + 'line' => $constant->getLineNumber(), + 'value' => $constant->getValue(), + ); + } - if ( ! empty( $function->uses ) ) { - $func['uses'] = export_uses( $function->uses ); + if ( ! empty( $file->uses['hooks'] ) ) { + $out['hooks'] = export_hooks( $file->uses['hooks'] ); + } - if ( ! empty( $function->uses['hooks'] ) ) { - $func['hooks'] = export_hooks( $function->uses['hooks'] ); + foreach ( $file->getFunctions() as $function ) { + $func = array( + 'name' => $function->getShortName(), + 'namespace' => $function->getNamespace(), + 'aliases' => $function->getNamespaceAliases(), + 'line' => $function->getLineNumber(), + 'end_line' => $function->getNode()->getAttribute( 'endLine' ), + 'arguments' => export_arguments( $function->getArguments() ), + 'doc' => export_docblock( $function ), + 'hooks' => array(), + ); + + if ( ! empty( $function->uses ) ) { + $func['uses'] = export_uses( $function->uses ); + + if ( ! empty( $function->uses['hooks'] ) ) { + $func['hooks'] = export_hooks( $function->uses['hooks'] ); + } } - } - $out['functions'][] = $func; - } + $out['functions'][] = $func; + } - foreach ( $file->getClasses() as $class ) { - $class_data = array( - 'name' => $class->getShortName(), - 'namespace' => $class->getNamespace(), - 'line' => $class->getLineNumber(), - 'end_line' => $class->getNode()->getAttribute( 'endLine' ), - 'final' => $class->isFinal(), - 'abstract' => $class->isAbstract(), - 'extends' => $class->getParentClass(), - 'implements' => $class->getInterfaces(), - 'properties' => export_properties( $class->getProperties() ), - 'methods' => export_methods( $class->getMethods() ), - 'doc' => export_docblock( $class ), - ); + foreach ( $file->getClasses() as $class ) { + $class_data = array( + 'name' => $class->getShortName(), + 'namespace' => $class->getNamespace(), + 'line' => $class->getLineNumber(), + 'end_line' => $class->getNode()->getAttribute( 'endLine' ), + 'final' => $class->isFinal(), + 'abstract' => $class->isAbstract(), + 'extends' => $class->getParentClass(), + 'implements' => $class->getInterfaces(), + 'properties' => export_properties( $class->getProperties() ), + 'methods' => export_methods( $class->getMethods() ), + 'doc' => export_docblock( $class ), + ); + + $out['classes'][] = $class_data; + } - $out['classes'][] = $class_data; + $output[] = $out; } - - $output[] = $out; + } catch ( \Exception | \Error $e ) { + error_log( \sprintf( 'Error processing file [%s]: %s', $filename, $e->getMessage() ) ); + throw $e; } + /* + * nikic/php-parser in version 3 started adding a namespace prefix + * at the start of global names, but this is different than how the + * documentation was previously generated. this removes those prefixes + * by removing a leading reverse solidus (\) when no other reverse + * solidus appears before the end of a sequence of PHP identifier + * characters. + */ + array_walk_recursive( + $output, + static function( &$value ) { + if ( is_string( $value ) ) { + // "\wp_kses()" -> "wp_kses()" + $without_global_namespace = preg_replace( + '~(^|\p{Z})\\\\([A-Z_a-z\x80-\xFF][0-9A-Z_a-z\x80-\xFF]*)([:(\p{Z}]|->|$)~', + '$1$2$3', + $value, + ); + + if ( $value !== $without_global_namespace ) { + $value = $without_global_namespace; + } + } + } + ); + return $output; } @@ -396,8 +429,13 @@ function export_uses( array $uses ) { || '_deprecated_hook' === $name ) { $arguments = $element->getNode()->args; + $version = null; + + if ( isset( $arguments[1]->value->value ) && is_scalar( $arguments[1]->value->value ) ) { + $version = (string) $arguments[1]->value->value; + } - $out[ $type ][0]['deprecation_version'] = $arguments[1]->value->value; + $out[ $type ][0]['deprecation_version'] = $version; } break; diff --git a/package.json b/package.json index 5f190dfb..a7a763e4 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "test": "npm-run-all test:phpunit", "setup": "npm-run-all start composer:setup", "start": "wp-env start", - "composer": "wp-env run --env-cwd='wp-content/plugins/phpdoc-parser' tests-wordpress composer", - "composer:setup": "wp-env run --env-cwd='wp-content/plugins/phpdoc-parser' tests-wordpress composer install", + "composer": "wp-env run --env-cwd='wp-content/plugins/phpdoc-parser' tests-wordpress composer --no-interaction --no-security-blocking", + "composer:setup": "wp-env run --env-cwd='wp-content/plugins/phpdoc-parser' tests-wordpress composer install --no-interaction --no-security-blocking", "test:phpunit:setup": "npm-run-all start composer:setup", "test:phpunit": "wp-env run --env-cwd='wp-content/plugins/phpdoc-parser' tests-wordpress vendor/phpunit/phpunit/phpunit -c phpunit.xml.dist" }, diff --git a/prep-diff.php b/prep-diff.php new file mode 100644 index 00000000..42e69c8c --- /dev/null +++ b/prep-diff.php @@ -0,0 +1,279 @@ + before.norm.json + * php prep-diff.php < after.json > after.norm.json + * diff -u before.norm.json after.norm.json + */ + +/** + * Checks if an array is a JSON list. + * + * @param array $array Array to inspect. + * @return bool Whether the array is a list. + */ +function wp_parser_prep_diff_is_list( array $array ) { + if ( array() === $array ) { + return true; + } + + return array_keys( $array ) === range( 0, count( $array ) - 1 ); +} + +/** + * Checks whether a normalized path ends with the given key sequence. + * + * @param array $path Current JSON path. + * @param array $suffix Expected key suffix. + * @return bool Whether the path ends with the suffix. + */ +function wp_parser_prep_diff_path_ends_with( array $path, array $suffix ) { + if ( count( $suffix ) > count( $path ) ) { + return false; + } + + return array_slice( $path, -count( $suffix ) ) === $suffix; +} + +/** + * Checks whether a list contains simple records that should sort by name. + * + * @param array $list JSON list. + * @return bool Whether the list contains simple name records. + */ +function wp_parser_prep_diff_is_simple_name_record_list( array $list ) { + if ( array() === $list ) { + return false; + } + + $allowed_keys = array( 'endLine', 'end_line', 'line', 'name', 'startLine' ); + + foreach ( $list as $item ) { + if ( ! is_array( $item ) || ! isset( $item['name'] ) || ! is_scalar( $item['name'] ) ) { + return false; + } + + foreach ( array_keys( $item ) as $key ) { + if ( ! in_array( $key, $allowed_keys, true ) ) { + return false; + } + } + } + + return true; +} + +/** + * Normalizes scalar values that should not affect output comparisons. + * + * @param mixed $value Scalar value. + * @param string|null $key Parent object key. + * @return mixed Normalized value. + */ +function wp_parser_prep_diff_normalize_scalar( $value, $key ) { + if ( in_array( $key, array( 'line', 'end_line', 'startLine', 'endLine' ), true ) ) { + return 0; + } + + if ( 'root' === $key && is_string( $value ) ) { + return 'wordpress/'; + } + + if ( ! is_string( $value ) ) { + return $value; + } + + // "\wp_kses()" -> "wp_kses()". + $without_global_namespace = preg_replace( + '~(^|\p{Z})\\\\([A-Z_a-z\x80-\xFF][0-9A-Z_a-z\x80-\xFF]*)([:(\p{Z}]|->|$)~', + '$1$2$3', + $value + ); + + return null === $without_global_namespace ? $value : $without_global_namespace; +} + +/** + * Returns a canonical sort key for an item in an unordered parser collection. + * + * @param mixed $item Item from a JSON list. + * @param array $path Current JSON path. + * @return string Sort key. + */ +function wp_parser_prep_diff_sort_key( $item, array $path ) { + if ( ! is_array( $item ) ) { + return json_encode( $item ); + } + + if ( array() === $path ) { + return sprintf( + '%s/%s', + isset( $item['root'] ) ? $item['root'] : '', + isset( $item['path'] ) ? $item['path'] : '' + ); + } + + if ( wp_parser_prep_diff_path_ends_with( $path, array( 'uses', 'functions' ) ) ) { + return sprintf( '%s|%s', isset( $item['name'] ) ? $item['name'] : '', json_encode( $item ) ); + } + + if ( wp_parser_prep_diff_path_ends_with( $path, array( 'uses', 'methods' ) ) ) { + return sprintf( + '%s|%s|%s|%s', + isset( $item['class'] ) ? $item['class'] : '', + isset( $item['name'] ) ? ( is_scalar( $item['name'] ) ? $item['name'] : json_encode( $item['name'] ) ) : '', + isset( $item['static'] ) ? (int) $item['static'] : 0, + json_encode( $item ) + ); + } + + $key = end( $path ); + + switch ( $key ) { + case 'classes': + case 'interfaces': + case 'traits': + case 'functions': + case 'methods': + return sprintf( + '%s|%s|%s', + isset( $item['namespace'] ) ? $item['namespace'] : '', + isset( $item['name'] ) ? ( is_scalar( $item['name'] ) ? $item['name'] : json_encode( $item['name'] ) ) : '', + json_encode( $item ) + ); + + case 'properties': + case 'constants': + return sprintf( + '%s|%s', + isset( $item['name'] ) ? $item['name'] : '', + json_encode( $item ) + ); + + case 'hooks': + return sprintf( + '%s|%s|%s', + isset( $item['name'] ) ? $item['name'] : '', + isset( $item['type'] ) ? $item['type'] : '', + json_encode( $item ) + ); + + case 'includes': + return sprintf( + '%s|%s|%s', + isset( $item['type'] ) ? $item['type'] : '', + isset( $item['name'] ) ? $item['name'] : '', + json_encode( $item ) + ); + } + + if ( isset( $item['name'] ) && is_scalar( $item['name'] ) ) { + return sprintf( '%s|%s', $item['name'], json_encode( $item ) ); + } + + return json_encode( $item ); +} + +/** + * Checks if a list at the given path is safe to sort for diff review. + * + * @param array $path Current JSON path. + * @param array $list JSON list. + * @return bool Whether the list should be sorted. + */ +function wp_parser_prep_diff_should_sort_list( array $path, array $list ) { + if ( array() === $path ) { + return true; + } + + if ( wp_parser_prep_diff_is_simple_name_record_list( $list ) ) { + return true; + } + + if ( + wp_parser_prep_diff_path_ends_with( $path, array( 'uses', 'functions' ) ) || + wp_parser_prep_diff_path_ends_with( $path, array( 'uses', 'methods' ) ) + ) { + return true; + } + + return in_array( + end( $path ), + array( 'classes', 'interfaces', 'traits', 'functions', 'methods', 'properties', 'constants', 'hooks', 'includes' ), + true + ); +} + +/** + * Recursively normalizes decoded parser JSON. + * + * @param mixed $value Decoded JSON value. + * @param array $path Current JSON path. + * @param string|null $key Parent object key. + * @return mixed Normalized value. + */ +function wp_parser_prep_diff_normalize( $value, array $path = array(), $key = null ) { + if ( ! is_array( $value ) ) { + return wp_parser_prep_diff_normalize_scalar( $value, $key ); + } + + if ( wp_parser_prep_diff_is_list( $value ) ) { + foreach ( $value as $index => $item ) { + $value[ $index ] = wp_parser_prep_diff_normalize( $item, array_merge( $path, array( '[]' ) ) ); + } + + if ( wp_parser_prep_diff_should_sort_list( $path, $value ) ) { + usort( + $value, + static function( $a, $b ) use ( $path ) { + return strcmp( + wp_parser_prep_diff_sort_key( $a, $path ), + wp_parser_prep_diff_sort_key( $b, $path ) + ); + } + ); + } + + return $value; + } + + foreach ( $value as $child_key => $child_value ) { + $value[ $child_key ] = wp_parser_prep_diff_normalize( + $child_value, + array_merge( $path, array( $child_key ) ), + $child_key + ); + } + + ksort( $value, SORT_STRING ); + + return $value; +} + +$input = file_get_contents( 'php://stdin' ); +$json = json_decode( $input, true ); + +if ( JSON_ERROR_NONE !== json_last_error() ) { + fwrite( STDERR, 'Invalid JSON input: ' . json_last_error_msg() . PHP_EOL ); + exit( 1 ); +} + +$output = json_encode( + wp_parser_prep_diff_normalize( $json ), + JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE +); + +if ( false === $output ) { + fwrite( STDERR, 'Unable to encode normalized JSON: ' . json_last_error_msg() . PHP_EOL ); + exit( 1 ); +} + +echo $output . PHP_EOL; diff --git a/tests/phpunit/tests/export/uses/constructor.php b/tests/phpunit/tests/export/uses/constructor.php index 202eb7de..d05e15ae 100644 --- a/tests/phpunit/tests/export/uses/constructor.php +++ b/tests/phpunit/tests/export/uses/constructor.php @@ -21,7 +21,7 @@ public function test_new_class() { 'name' => '__construct', 'line' => 3, 'end_line' => 3, - 'class' => '\WP_Query', + 'class' => 'WP_Query', 'static' => false, ) ); @@ -32,7 +32,7 @@ public function test_new_class() { 'name' => '__construct', 'line' => 6, 'end_line' => 6, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => false, ) ); @@ -50,7 +50,7 @@ public function test_new_self() { 'name' => '__construct', 'line' => 12, 'end_line' => 12, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => false, ) ); @@ -68,7 +68,7 @@ public function test_new_parent() { 'name' => '__construct', 'line' => 16, 'end_line' => 16, - 'class' => '\Parent_Class', + 'class' => 'Parent_Class', 'static' => false, ) ); diff --git a/tests/phpunit/tests/export/uses/methods.php b/tests/phpunit/tests/export/uses/methods.php index 2def2399..aad38ff5 100644 --- a/tests/phpunit/tests/export/uses/methods.php +++ b/tests/phpunit/tests/export/uses/methods.php @@ -21,7 +21,7 @@ public function test_static_methods() { 'name' => 'static_method', 'line' => 3, 'end_line' => 3, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => true, ) ); @@ -32,7 +32,7 @@ public function test_static_methods() { 'name' => 'another_method', 'line' => 8, 'end_line' => 8, - 'class' => '\Another_Class', + 'class' => 'Another_Class', 'static' => true, ) ); @@ -44,7 +44,7 @@ public function test_static_methods() { 'name' => 'do_static_stuff', 'line' => 16, 'end_line' => 16, - 'class' => '\Another_Class', + 'class' => 'Another_Class', 'static' => true, ) ); @@ -56,7 +56,7 @@ public function test_static_methods() { 'name' => 'do_stuff', 'line' => 17, 'end_line' => 17, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => true, ) ); @@ -68,7 +68,7 @@ public function test_static_methods() { 'name' => 'do_parental_stuff', 'line' => 19, 'end_line' => 19, - 'class' => '\Parent_Class', + 'class' => 'Parent_Class', 'static' => true, ) ); @@ -107,7 +107,7 @@ public function test_instance_methods() { 'name' => 'go', 'line' => 18, 'end_line' => 18, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => false, ) ); diff --git a/tests/phpunit/tests/export/uses/nested.php b/tests/phpunit/tests/export/uses/nested.php index 4caaef6c..dc1ef80f 100644 --- a/tests/phpunit/tests/export/uses/nested.php +++ b/tests/phpunit/tests/export/uses/nested.php @@ -40,7 +40,7 @@ public function test_top_function_uses_correct() { 'name' => 'do_things', 'line' => 16, 'end_line' => 16, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => true, ) ); @@ -60,7 +60,7 @@ public function test_top_function_uses_correct() { 'name' => 'static_method', 'line' => 11, 'end_line' => 11, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => true, ) ); @@ -86,7 +86,7 @@ public function test_nested_function_uses_correct() { 'name' => 'static_method', 'line' => 11, 'end_line' => 11, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => true, ) ); @@ -132,7 +132,7 @@ public function test_method_uses_correct() { 'name' => 'do_it', 'line' => 23, 'end_line' => 23, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => false, ) ); @@ -164,7 +164,7 @@ public function test_method_uses_correct() { 'name' => 'a_method', 'line' => 29, 'end_line' => 29, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => true, ) ); @@ -190,7 +190,7 @@ public function test_nested_function_in_method_uses_correct() { 'name' => 'a_method', 'line' => 29, 'end_line' => 29, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => true, ) ); @@ -201,7 +201,7 @@ public function test_nested_function_in_method_uses_correct() { 'name' => 'do_it', 'line' => 23, 'end_line' => 23, - 'class' => '\My_Class', + 'class' => 'My_Class', 'static' => false, ) ); diff --git a/tests/prep-diff-test.php b/tests/prep-diff-test.php new file mode 100644 index 00000000..e4860e5f --- /dev/null +++ b/tests/prep-diff-test.php @@ -0,0 +1,153 @@ + array( 'pipe', 'r' ), + 1 => array( 'pipe', 'w' ), + 2 => array( 'pipe', 'w' ), + ); + + $process = proc_open( + escapeshellarg( PHP_BINARY ) . ' ' . escapeshellarg( $script ), + $descriptor_spec, + $pipes + ); + + if ( ! is_resource( $process ) ) { + throw new RuntimeException( 'Unable to start prep-diff.php.' ); + } + + fwrite( $pipes[0], $json ); + fclose( $pipes[0] ); + + $output = stream_get_contents( $pipes[1] ); + $error = stream_get_contents( $pipes[2] ); + + fclose( $pipes[1] ); + fclose( $pipes[2] ); + + $status = proc_close( $process ); + + if ( 0 !== $status ) { + throw new RuntimeException( trim( $error ) ); + } + + return $output; +} + +function assert_true( $condition, $message ) { + if ( ! $condition ) { + fwrite( STDERR, $message . PHP_EOL ); + exit( 1 ); + } +} + +$a = json_encode( + array( + array( + 'root' => '/tmp/build-a', + 'path' => 'beta.php', + 'call_graph' => array( + array( 'name' => 'zeta', 'line' => 9, 'end_line' => 9 ), + array( 'name' => 'alpha', 'line' => 3, 'end_line' => 3 ), + ), + 'functions' => array( + array( + 'uses' => array( + 'functions' => array( + array( 'name' => 'zeta', 'line' => 9, 'end_line' => 9 ), + array( 'name' => 'alpha', 'line' => 3, 'end_line' => 3 ), + ), + ), + 'line' => 20, + 'name' => 'beta', + 'namespace' => 'global', + 'arguments' => array( + array( 'name' => '$first', 'type' => '' ), + array( 'name' => '$second', 'type' => '' ), + ), + 'doc' => array( + 'tags' => array( + array( 'name' => 'since', 'content' => '1.0.0' ), + array( 'name' => 'param', 'content' => 'First.', 'variable' => '$first' ), + ), + 'long_description' => '', + 'description' => 'Calls \\alpha().', + ), + ), + ), + ), + array( + 'path' => 'alpha.php', + 'root' => '/tmp/build-a', + ), + ) +); + +$b = json_encode( + array( + array( + 'root' => '/tmp/build-b', + 'path' => 'alpha.php', + ), + array( + 'path' => 'beta.php', + 'root' => '/tmp/build-b', + 'call_graph' => array( + array( 'end_line' => 90, 'line' => 90, 'name' => 'zeta' ), + array( 'end_line' => 30, 'line' => 30, 'name' => 'alpha' ), + ), + 'functions' => array( + array( + 'namespace' => 'global', + 'name' => 'beta', + 'line' => 98, + 'doc' => array( + 'description' => 'Calls alpha().', + 'long_description' => '', + 'tags' => array( + array( 'name' => 'since', 'content' => '1.0.0' ), + array( 'name' => 'param', 'content' => 'First.', 'variable' => '$first' ), + ), + ), + 'arguments' => array( + array( 'type' => '', 'name' => '$first' ), + array( 'type' => '', 'name' => '$second' ), + ), + 'uses' => array( + 'functions' => array( + array( 'end_line' => 30, 'line' => 30, 'name' => 'alpha' ), + array( 'end_line' => 90, 'line' => 90, 'name' => 'zeta' ), + ), + ), + ), + ), + ), + ) +); + +$a_normalized = normalize_with_prep_diff( $script, $a ); +$b_normalized = normalize_with_prep_diff( $script, $b ); + +assert_true( $a_normalized === $b_normalized, 'Equivalent shuffled JSON should normalize identically.' ); + +$decoded = json_decode( $a_normalized, true ); + +assert_true( 'alpha.php' === $decoded[0]['path'], 'Top-level files should sort by path.' ); +assert_true( array( 'alpha', 'zeta' ) === array_column( $decoded[1]['call_graph'], 'name' ), 'Simple name records should sort by name.' ); +assert_true( array( '$first', '$second' ) === array_column( $decoded[1]['functions'][0]['arguments'], 'name' ), 'Function argument order should be preserved.' ); +assert_true( array( 'since', 'param' ) === array_column( $decoded[1]['functions'][0]['doc']['tags'], 'name' ), 'Doc tag order should be preserved.' ); +assert_true( array( 'alpha', 'zeta' ) === array_column( $decoded[1]['functions'][0]['uses']['functions'], 'name' ), 'Function uses should sort by name.' ); +assert_true( array_keys( $decoded[1]['functions'][0] ) === array( 'arguments', 'doc', 'line', 'name', 'namespace', 'uses' ), 'Object keys should be sorted.' ); + +$changed = json_decode( $b, true ); +$changed[1]['functions'][0]['name'] = 'changed'; + +assert_true( + $a_normalized !== normalize_with_prep_diff( $script, json_encode( $changed ) ), + 'Real content changes should remain visible.' +); + +echo "prep-diff tests passed\n";