diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 8a776ca319bccc465e60aea0a3dc3d5df6f053b0..984ad2bfe223ab232e6216b4cce2ec86a2604db9 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,11 +1,12 @@
version: 2
updates:
-- package-ecosystem: composer
- directory: "/"
- schedule:
- interval: weekly
- open-pull-requests-limit: 10
-- package-ecosystem: "github-actions"
- directory: "/"
- schedule:
- interval: "weekly"
+ - package-ecosystem: "composer"
+ directory: "/"
+ schedule:
+ interval: "daily"
+ open-pull-requests-limit: 10
+
+ - package-ecosystem: "github-actions"
+ directory: "/"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a6103633e57f5da177888963ffc40b55f73137ff
--- /dev/null
+++ b/.github/workflows/integrate.yaml
@@ -0,0 +1,60 @@
+# https://docs.github.com/en/actions
+
+name: "Integrate"
+
+on: # yamllint disable-line rule:truthy
+ push:
+ branches:
+ - "5.x"
+ pull_request: null
+ # Allow manually triggering the workflow.
+ workflow_dispatch: null
+
+jobs:
+ code-coverage:
+ name: "Code Coverage"
+ uses: "phpDocumentor/.github/.github/workflows/code-coverage.yml@main"
+ with:
+ composer-root-version: "5.x-dev"
+
+ coding-standards:
+ name: "Coding Standards"
+ uses: "phpDocumentor/.github/.github/workflows/coding-standards.yml@v0.5.0"
+ with:
+ composer-root-version: "5.x-dev"
+
+ dependency-analysis:
+ name: "Dependency analysis"
+ uses: "phpDocumentor/.github/.github/workflows/dependency-analysis.yml@v0.5.0"
+ with:
+ composer-root-version: "5.x-dev"
+
+ lint-root:
+ name: "Lint root"
+ uses: "phpDocumentor/.github/.github/workflows/lint.yml@main"
+ with:
+ composer-options: "--no-check-publish --ansi"
+
+ static-analysis:
+ name: "Static analysis"
+ uses: "phpDocumentor/.github/.github/workflows/static-analysis.yml@v0.5.0"
+ with:
+ php-extensions: "none, ctype, dom, json, mbstring, phar, simplexml, tokenizer, xml, xmlwriter, fileinfo, pcntl, posix"
+ composer-root-version: "5.x-dev"
+
+ unit-tests:
+ name: "Unit test"
+ uses: "phpDocumentor/.github/.github/workflows/continuous-integration.yml@v0.5.0"
+ with:
+ composer-root-version: "5.x-dev"
+ php-versions: "['7.4', '8.0', '8.1', '8.2', '8.3']"
+
+ bc_check:
+ name: "BC Check"
+ runs-on: "ubuntu-latest"
+ steps:
+ - uses: "actions/checkout@v3"
+ - name: "fetch tags"
+ run: "git fetch --depth=1 origin +refs/tags/*:refs/tags/*"
+ - name: "BC Check"
+ uses: "docker://nyholm/roave-bc-check-ga"
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
deleted file mode 100644
index 60ae4ff206f5c5758cd1bf7fe90fcd2553b79bdf..0000000000000000000000000000000000000000
--- a/.github/workflows/push.yml
+++ /dev/null
@@ -1,211 +0,0 @@
-on:
- push:
- branches:
- - master
- pull_request:
- # Allow manually triggering the workflow.
- workflow_dispatch:
-name: Qa workflow
-env:
- phiveGPGKeys: 4AA394086372C20A,D2CCAC42F6295E7D,E82B2FB314E9906E,8A03EA3B385DBAA1
-jobs:
- setup:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
-
- - name: composer
- uses: docker://composer
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- args: install --no-interaction --prefer-dist --optimize-autoloader
-
- - name: composer-require-checker
- uses: docker://phpga/composer-require-checker-ga
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- args: check --config-file ./composer-require-config.json composer.json
-
- phpunit-with-coverage:
- runs-on: ubuntu-latest
- name: Unit tests
- needs: setup
- steps:
- - uses: actions/checkout@v2
-
- - name: composer
- uses: docker://composer
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- args: install --no-interaction --prefer-dist --optimize-autoloader
-
- - name: PHPUnit
- uses: docker://phpdoc/phpunit-ga:latest
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Quick check code coverage level
- run: php tests/coverage-checker.php 91
-
- phpunit:
- name: Unit tests for PHP version ${{ matrix.php-versions }} on ${{ matrix.operating-system }}
- runs-on: ${{ matrix.operating-system }}
- strategy:
- fail-fast: false
- matrix:
- operating-system:
- - ubuntu-latest
- - windows-latest
- - macOS-latest
- php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1']
- env:
- extensions: mbstring
- key: cache-v1 # can be any string, change to clear the extension cache.
-
- needs:
- - setup
- - phpunit-with-coverage
-
- steps:
- - uses: actions/checkout@v2
-
- - name: Setup cache environment
- id: cache-env
- uses: shivammathur/cache-extensions@v1
- with:
- php-version: ${{ matrix.php-versions }}
- extensions: ${{ env.extensions }}
- key: ${{ env.key }}
-
- - name: Cache extensions
- uses: actions/cache@v2.1.6
- with:
- path: ${{ steps.cache-env.outputs.dir }}
- key: ${{ steps.cache-env.outputs.key }}
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php-versions }}
- extensions: ${{ env.extensions }}
- ini-values: memory_limit=2G, display_errors=On, error_reporting=-1
- tools: phive
-
- - name: Install PHAR dependencies
- env:
- GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: phive --no-progress install --copy --trust-gpg-keys ${{ env.phiveGPGKeys }} --force-accept-unsigned
-
- - name: Install phpunit 8 for php 7.2
- if: matrix.php-versions == '7.2'
- env:
- GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- run: phive --no-progress install --copy --trust-gpg-keys ${{ env.phiveGPGKeys }} phpunit:^8.5
-
- - name: Install Composer dependencies & cache dependencies
- uses: "ramsey/composer-install@v1"
- with:
- composer-options: --optimize-autoloader
-
- - name: Run PHPUnit
- run: php tools/phpunit
-
- codestyle:
- runs-on: ubuntu-latest
- needs: [setup, phpunit]
- steps:
- - uses: actions/checkout@v2
- - name: Restore/cache vendor folder
- uses: actions/cache@v2.1.6
- with:
- path: vendor
- key: all-build-${{ hashFiles('**/composer.lock') }}
- restore-keys: |
- all-build-${{ hashFiles('**/composer.lock') }}
- all-build-
- - name: Code style check
- uses: phpDocumentor/coding-standard@latest
- with:
- args: -s
-
- phpstan:
- runs-on: ubuntu-latest
- needs: [setup, phpunit]
- steps:
- - uses: actions/checkout@v2
- - name: composer
- uses: docker://composer
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- args: install --no-interaction --prefer-dist --optimize-autoloader
-
- - name: PHPStan
- uses: phpDocumentor/phpstan-ga@0.12.9
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- with:
- args: analyse src --configuration phpstan.neon
-
- psalm:
- name: Psalm
- runs-on: ${{ matrix.operating-system }}
- strategy:
- matrix:
- operating-system:
- - ubuntu-latest
- php-versions: ['7.2']
- env:
- extensions: mbstring
- key: cache-v1 # can be any string, change to clear the extension cache.
-
- needs:
- - setup
- - phpunit
-
- steps:
- - uses: actions/checkout@v2
-
- - name: Setup cache environment
- id: cache-env
- uses: shivammathur/cache-extensions@v1
- with:
- php-version: ${{ matrix.php-versions }}
- extensions: ${{ env.extensions }}
- key: ${{ env.key }}
-
- - name: Cache extensions
- uses: actions/cache@v2.1.6
- with:
- path: ${{ steps.cache-env.outputs.dir }}
- key: ${{ steps.cache-env.outputs.key }}
-
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
- with:
- php-version: ${{ matrix.php-versions }}
- extensions: ${{ env.extensions }}
- ini-values: memory_limit=2G, display_errors=On, error_reporting=-1
-
- - name: Install Composer dependencies & cache dependencies
- uses: "ramsey/composer-install@v1"
- with:
- composer-options: --optimize-autoloader
-
- - name: Run psalm
- run: vendor/bin/psalm.phar --output-format=github
-
-
- bc_check:
- name: BC Check
- runs-on: ubuntu-latest
- needs: [setup, phpunit]
- steps:
- - uses: actions/checkout@v2
- - name: fetch tags
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- - name: BC Check
- uses: docker://nyholm/roave-bc-check-ga
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
deleted file mode 100644
index 4c5f951187ce3d63d91d4234215e5b6e8b440c4a..0000000000000000000000000000000000000000
--- a/.scrutinizer.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-before_commands:
- - "composer install --no-dev --prefer-source"
-
-checks:
- php:
- excluded_dependencies:
- - phpstan/phpstan
-
-tools:
- external_code_coverage:
- enabled: true
- timeout: 300
- filter:
- excluded_paths: ["examples", "tests", "vendor"]
- php_code_sniffer:
- enabled: true
- config:
- standard: PSR2
- filter:
- paths: ["src/*", "tests/*"]
- excluded_paths: []
- php_cpd:
- enabled: true
- excluded_dirs: ["examples", "tests", "vendor"]
- php_cs_fixer:
- enabled: true
- config:
- level: all
- filter:
- paths: ["src/*", "tests/*"]
- php_loc:
- enabled: true
- excluded_dirs: ["examples", "tests", "vendor"]
- php_mess_detector:
- enabled: true
- config:
- ruleset: phpmd.xml.dist
- design_rules: { eval_expression: false }
- filter:
- paths: ["src/*"]
- php_pdepend:
- enabled: true
- excluded_dirs: ["examples", "tests", "vendor"]
- php_analyzer:
- enabled: true
- filter:
- paths: ["src/*", "tests/*"]
- sensiolabs_security_checker: true
diff --git a/.yamllint.yaml b/.yamllint.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..55695cd5633438c0829187898364f897270c49d7
--- /dev/null
+++ b/.yamllint.yaml
@@ -0,0 +1,65 @@
+extends: "default"
+
+ignore: |
+ .build/
+ .notes/
+ vendor/
+rules:
+ braces:
+ max-spaces-inside-empty: 0
+ max-spaces-inside: 1
+ min-spaces-inside-empty: 0
+ min-spaces-inside: 1
+ brackets:
+ max-spaces-inside-empty: 0
+ max-spaces-inside: 0
+ min-spaces-inside-empty: 0
+ min-spaces-inside: 0
+ colons:
+ max-spaces-after: 1
+ max-spaces-before: 0
+ commas:
+ max-spaces-after: 1
+ max-spaces-before: 0
+ min-spaces-after: 1
+ comments:
+ ignore-shebangs: true
+ min-spaces-from-content: 1
+ require-starting-space: true
+ comments-indentation: "enable"
+ document-end:
+ present: false
+ document-start:
+ present: false
+ indentation:
+ check-multi-line-strings: false
+ indent-sequences: true
+ spaces: 2
+ empty-lines:
+ max-end: 0
+ max-start: 0
+ max: 1
+ empty-values:
+ forbid-in-block-mappings: true
+ forbid-in-flow-mappings: true
+ hyphens:
+ max-spaces-after: 2
+ key-duplicates: "enable"
+ key-ordering: "disable"
+ line-length: "disable"
+ new-line-at-end-of-file: "enable"
+ new-lines:
+ type: "unix"
+ octal-values:
+ forbid-implicit-octal: true
+ quoted-strings:
+ quote-type: "double"
+ trailing-spaces: "enable"
+ truthy:
+ allowed-values:
+ - "false"
+ - "true"
+
+yaml-files:
+ - "*.yaml"
+ - "*.yml"
diff --git a/Makefile b/Makefile
index 1c92888d23e707bdc0d3db021d9249566ac63c51..9b28eb9ec1505072262484847160263780270d77 100644
--- a/Makefile
+++ b/Makefile
@@ -1,37 +1,43 @@
-.PHONY: install-phive
-install-phive:
- mkdir tools; \
- wget -O tools/phive.phar https://phar.io/releases/phive.phar; \
- wget -O tools/phive.phar.asc https://phar.io/releases/phive.phar.asc; \
- gpg --keyserver pool.sks-keyservers.net --recv-keys 0x9D8A98B29B2D5D79; \
- gpg --verify tools/phive.phar.asc tools/phive.phar; \
- chmod +x tools/phive.phar
-
-.PHONY: setup
-setup: install-phive
- docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phar-ga:latest php tools/phive.phar install --force-accept-unsigned
-
-.PHONY: phpcs
-phpcs:
- docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest -s
-
-.PHONY: phpcbf
-phpcbf:
- docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest phpcbf
+.PHONY: help
+help: ## Displays this list of targets with descriptions
+ @grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}'
+
+.PHONY: code-style
+code-style:
+ docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest -d memory_limit=1024M -s
-.PHONY: phpstan
-phpstan:
- docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpstan-ga:latest analyse src --no-progress --configuration phpstan.neon
+.PHONY: fix-code-style
+fix-code-style:
+ docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest phpcbf
-.PHONY: psalm
-psalm:
- docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.3 vendor/bin/psalm.phar
+.PHONY: static-code-analysis
+static-code-analysis: vendor ## Runs a static code analysis with phpstan/phpstan and vimeo/psalm
+ docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpstan --configuration=phpstan.neon
+ docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/psalm
.PHONY: test
-test:
- docker run -it --rm -v${CURDIR}:/github/workspace phpdoc/phpunit-ga
- docker run -it --rm -v${CURDIR}:/data -w /data php:7.2 -f ./tests/coverage-checker.php 90
+test: test-unit ## Runs all test suites with phpunit/phpunit
+ docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpunit
-.PHONY: pre-commit-test
-pre-commit-test: test phpcs phpstan psalm
+.PHONY: test-unit
+test-unit: ## Runs unit tests with phpunit/phpunit
+ docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpunit --testsuite=unit
+
+.PHONY: dependency-analysis
+dependency-analysis: vendor ## Runs a dependency analysis with maglnet/composer-require-checker
+ docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 .phive/composer-require-checker check --config-file=/opt/project/composer-require-checker.json
+vendor: composer.json composer.lock
+ composer validate --no-check-publish
+ composer install --no-interaction --no-progress
+
+.PHONY: benchmark
+benchmark:
+ docker run -it --rm -v${CURDIR}:/opt/project -w /opt/project php:7.4-cli tools/phpbench run
+
+.PHONY: rector
+rector: ## Refactor code using rector
+ docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/rector process
+
+.PHONY: pre-commit-test
+pre-commit-test: fix-code-style test code-style static-code-analysis
diff --git a/README.md b/README.md
index 51f10883b731b6e0aa93e3479b304359fa756306..a0fe02ba769176a17157f4146639e82b08d0385b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,5 @@
[](https://opensource.org/licenses/MIT)

-[](https://coveralls.io/github/phpDocumentor/ReflectionDocBlock?branch=master)
[](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionDocBlock/?branch=master)
[](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionDocBlock/?branch=master)
[](https://packagist.org/packages/phpdocumentor/reflection-docblock)
diff --git a/composer-require-config.json b/composer-require-checker.json
similarity index 100%
rename from composer-require-config.json
rename to composer-require-checker.json
diff --git a/composer.json b/composer.json
index d90763024dde47c0e19f7184182feb9d17290244..cf8f49d3705fb90dba61886a196988f6d550a92d 100644
--- a/composer.json
+++ b/composer.json
@@ -10,19 +10,26 @@
},
{
"name": "Jaap van Otterdijk",
- "email": "account@ijaap.nl"
+ "email": "opensource@ijaap.nl"
}
],
"require": {
- "php": "^7.2 || ^8.0",
- "phpdocumentor/type-resolver": "^1.3",
+ "php": "^7.4 || ^8.0",
+ "phpdocumentor/type-resolver": "^1.7",
"webmozart/assert": "^1.9.1",
"phpdocumentor/reflection-common": "^2.2",
- "ext-filter": "*"
+ "ext-filter": "*",
+ "phpstan/phpdoc-parser": "^1.7",
+ "doctrine/deprecations": "^1.1"
},
"require-dev": {
- "mockery/mockery": "~1.3.2",
- "psalm/phar": "^4.8"
+ "mockery/mockery": "~1.3.5",
+ "phpunit/phpunit": "^9.5",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-mockery": "^1.1",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan-webmozart-assert": "^1.2",
+ "vimeo/psalm": "^5.13"
},
"autoload": {
"psr-4": {
@@ -34,6 +41,14 @@
"phpDocumentor\\Reflection\\": ["tests/unit", "tests/integration"]
}
},
+ "config": {
+ "platform": {
+ "php":"7.4.0"
+ },
+ "allow-plugins": {
+ "phpstan/extension-installer": true
+ }
+ },
"extra": {
"branch-alias": {
"dev-master": "5.x-dev"
diff --git a/composer.lock b/composer.lock
index 69df42963fb12e9180962b2a4e3be397322880ca..25557a935fcc1b422b856a5d5b5ecd0b7fc5662a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,55 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "f1e7818879f1626c05926f50c2c96f44",
+ "content-hash": "be391d67a41b2aa6ba500afca03e00a5",
"packages": [
+ {
+ "name": "doctrine/deprecations",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+ "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9",
+ "phpstan/phpstan": "1.4.10 || 1.10.15",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psalm/plugin-phpunit": "0.18.4",
+ "psr/log": "^1 || ^2 || ^3",
+ "vimeo/psalm": "4.30.0 || 5.12.0"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/1.1.3"
+ },
+ "time": "2024-01-30T19:34:25+00:00"
+ },
{
"name": "phpdocumentor/reflection-common",
"version": "2.2.0",
@@ -61,25 +108,33 @@
},
{
"name": "phpdocumentor/type-resolver",
- "version": "1.5.1",
+ "version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae"
+ "reference": "153ae662783729388a584b4361f2545e4d841e3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae",
- "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
+ "reference": "153ae662783729388a584b4361f2545e4d841e3c",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0",
- "phpdocumentor/reflection-common": "^2.0"
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.3 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.0",
+ "phpstan/phpdoc-parser": "^1.13"
},
"require-dev": {
"ext-tokenizer": "*",
- "psalm/phar": "^4.8"
+ "phpbench/phpbench": "^1.2",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpunit/phpunit": "^9.5",
+ "rector/rector": "^0.13.9",
+ "vimeo/psalm": "^4.25"
},
"type": "library",
"extra": {
@@ -105,106 +160,72 @@
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1"
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2"
},
- "time": "2021-10-02T14:08:47+00:00"
+ "time": "2024-02-23T11:10:43+00:00"
},
{
- "name": "symfony/polyfill-ctype",
- "version": "v1.23.0",
+ "name": "phpstan/phpdoc-parser",
+ "version": "1.13.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "33aefcdab42900e36366d0feab6206e2dd68f947"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
- "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/33aefcdab42900e36366d0feab6206e2dd68f947",
+ "reference": "33aefcdab42900e36366d0feab6206e2dd68f947",
"shasum": ""
},
"require": {
- "php": ">=7.1"
+ "php": "^7.2 || ^8.0"
},
- "suggest": {
- "ext-ctype": "For best performance"
+ "require-dev": {
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^1.5",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpstan/phpstan-strict-rules": "^1.0",
+ "phpunit/phpunit": "^9.5",
+ "symfony/process": "^5.2"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-main": "1.23-dev"
- },
- "thanks": {
- "name": "symfony/polyfill",
- "url": "https://github.com/symfony/polyfill"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
- },
- "files": [
- "bootstrap.php"
- ]
+ "PHPStan\\PhpDocParser\\": [
+ "src/"
+ ]
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "authors": [
- {
- "name": "Gert de Pagter",
- "email": "BackEndTea@gmail.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Symfony polyfill for ctype functions",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
- ],
+ "description": "PHPDoc parser with support for nullable, intersection and generic types",
"support": {
- "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
+ "issues": "https://github.com/phpstan/phpdoc-parser/issues",
+ "source": "https://github.com/phpstan/phpdoc-parser/tree/1.13.0"
},
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2021-02-19T12:13:01+00:00"
+ "time": "2022-10-21T09:57:39+00:00"
},
{
"name": "webmozart/assert",
- "version": "1.10.0",
+ "version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
- "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
- "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0",
- "symfony/polyfill-ctype": "^1.8"
+ "ext-ctype": "*",
+ "php": "^7.2 || ^8.0"
},
"conflict": {
"phpstan/phpstan": "<0.12.20",
@@ -242,177 +263,3868 @@
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/1.10.0"
+ "source": "https://github.com/webmozarts/assert/tree/1.11.0"
},
- "time": "2021-03-09T10:59:23+00:00"
+ "time": "2022-06-03T18:03:27+00:00"
}
],
"packages-dev": [
{
- "name": "hamcrest/hamcrest-php",
- "version": "v2.0.1",
+ "name": "amphp/amp",
+ "version": "v2.6.2",
"source": {
"type": "git",
- "url": "https://github.com/hamcrest/hamcrest-php.git",
- "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
+ "url": "https://github.com/amphp/amp.git",
+ "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
- "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+ "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
+ "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
"shasum": ""
},
"require": {
- "php": "^5.3|^7.0|^8.0"
- },
- "replace": {
- "cordoval/hamcrest-php": "*",
- "davedevelopment/hamcrest-php": "*",
- "kodova/hamcrest-php": "*"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/php-file-iterator": "^1.4 || ^2.0",
- "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
+ "amphp/php-cs-fixer-config": "dev-master",
+ "amphp/phpunit-util": "^1",
+ "ext-json": "*",
+ "jetbrains/phpstorm-stubs": "^2019.3",
+ "phpunit/phpunit": "^7 | ^8 | ^9",
+ "psalm/phar": "^3.11@dev",
+ "react/promise": "^2"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.1-dev"
+ "dev-master": "2.x-dev"
}
},
"autoload": {
- "classmap": [
- "hamcrest"
- ]
+ "files": [
+ "lib/functions.php",
+ "lib/Internal/functions.php"
+ ],
+ "psr-4": {
+ "Amp\\": "lib"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
- "description": "This is the PHP port of Hamcrest Matchers",
+ "authors": [
+ {
+ "name": "Daniel Lowrey",
+ "email": "rdlowrey@php.net"
+ },
+ {
+ "name": "Aaron Piotrowski",
+ "email": "aaron@trowski.com"
+ },
+ {
+ "name": "Bob Weinand",
+ "email": "bobwei9@hotmail.com"
+ },
+ {
+ "name": "Niklas Keller",
+ "email": "me@kelunik.com"
+ }
+ ],
+ "description": "A non-blocking concurrency framework for PHP applications.",
+ "homepage": "https://amphp.org/amp",
"keywords": [
- "test"
+ "async",
+ "asynchronous",
+ "awaitable",
+ "concurrency",
+ "event",
+ "event-loop",
+ "future",
+ "non-blocking",
+ "promise"
],
"support": {
- "issues": "https://github.com/hamcrest/hamcrest-php/issues",
- "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1"
+ "irc": "irc://irc.freenode.org/amphp",
+ "issues": "https://github.com/amphp/amp/issues",
+ "source": "https://github.com/amphp/amp/tree/v2.6.2"
},
- "time": "2020-07-09T08:09:16+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/amphp",
+ "type": "github"
+ }
+ ],
+ "time": "2022-02-20T17:52:18+00:00"
},
{
- "name": "mockery/mockery",
- "version": "1.3.5",
+ "name": "amphp/byte-stream",
+ "version": "v1.8.1",
"source": {
"type": "git",
- "url": "https://github.com/mockery/mockery.git",
- "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d"
+ "url": "https://github.com/amphp/byte-stream.git",
+ "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mockery/mockery/zipball/472fa8ca4e55483d55ee1e73c963718c4393791d",
- "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d",
+ "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd",
+ "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd",
"shasum": ""
},
"require": {
- "hamcrest/hamcrest-php": "^2.0.1",
- "lib-pcre": ">=7.0",
- "php": ">=5.6.0"
+ "amphp/amp": "^2",
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "^5.7.10|^6.5|^7.5|^8.5|^9.3"
+ "amphp/php-cs-fixer-config": "dev-master",
+ "amphp/phpunit-util": "^1.4",
+ "friendsofphp/php-cs-fixer": "^2.3",
+ "jetbrains/phpstorm-stubs": "^2019.3",
+ "phpunit/phpunit": "^6 || ^7 || ^8",
+ "psalm/phar": "^3.11.4"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.3.x-dev"
+ "dev-master": "1.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Mockery": "library/"
+ "files": [
+ "lib/functions.php"
+ ],
+ "psr-4": {
+ "Amp\\ByteStream\\": "lib"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Pádraic Brady",
- "email": "padraic.brady@gmail.com",
- "homepage": "http://blog.astrumfutura.com"
+ "name": "Aaron Piotrowski",
+ "email": "aaron@trowski.com"
},
{
- "name": "Dave Marshall",
- "email": "dave.marshall@atstsolutions.co.uk",
- "homepage": "http://davedevelopment.co.uk"
+ "name": "Niklas Keller",
+ "email": "me@kelunik.com"
}
],
- "description": "Mockery is a simple yet flexible PHP mock object framework",
- "homepage": "https://github.com/mockery/mockery",
+ "description": "A stream abstraction to make working with non-blocking I/O simple.",
+ "homepage": "http://amphp.org/byte-stream",
"keywords": [
- "BDD",
- "TDD",
- "library",
- "mock",
- "mock objects",
- "mockery",
- "stub",
- "test",
- "test double",
- "testing"
+ "amp",
+ "amphp",
+ "async",
+ "io",
+ "non-blocking",
+ "stream"
],
"support": {
- "issues": "https://github.com/mockery/mockery/issues",
- "source": "https://github.com/mockery/mockery/tree/1.3.5"
+ "irc": "irc://irc.freenode.org/amphp",
+ "issues": "https://github.com/amphp/byte-stream/issues",
+ "source": "https://github.com/amphp/byte-stream/tree/v1.8.1"
},
- "time": "2021-09-13T15:33:03+00:00"
+ "funding": [
+ {
+ "url": "https://github.com/amphp",
+ "type": "github"
+ }
+ ],
+ "time": "2021-03-30T17:13:30+00:00"
},
{
- "name": "psalm/phar",
- "version": "4.10.0",
+ "name": "composer/pcre",
+ "version": "3.0.0",
"source": {
"type": "git",
- "url": "https://github.com/psalm/phar.git",
- "reference": "79c5b2210e1a1cabeee671db1160c96869572d08"
+ "url": "https://github.com/composer/pcre.git",
+ "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/psalm/phar/zipball/79c5b2210e1a1cabeee671db1160c96869572d08",
- "reference": "79c5b2210e1a1cabeee671db1160c96869572d08",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd",
+ "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd",
"shasum": ""
},
"require": {
- "php": "^7.1 || ^8.0"
+ "php": "^7.4 || ^8.0"
},
- "conflict": {
- "vimeo/psalm": "*"
+ "require-dev": {
+ "phpstan/phpstan": "^1.3",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "symfony/phpunit-bridge": "^5"
},
- "bin": [
- "psalm.phar"
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Pcre\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
+ "keywords": [
+ "PCRE",
+ "preg",
+ "regex",
+ "regular expression"
+ ],
+ "support": {
+ "issues": "https://github.com/composer/pcre/issues",
+ "source": "https://github.com/composer/pcre/tree/3.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
],
+ "time": "2022-02-25T20:21:48+00:00"
+ },
+ {
+ "name": "composer/semver",
+ "version": "3.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/semver.git",
+ "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
+ "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.4",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
+ },
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Semver\\": "src"
+ }
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "Composer-based Psalm Phar",
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "Semver library that offers utilities, version constraint parsing and validation.",
+ "keywords": [
+ "semantic",
+ "semver",
+ "validation",
+ "versioning"
+ ],
"support": {
- "issues": "https://github.com/psalm/phar/issues",
- "source": "https://github.com/psalm/phar/tree/4.10.0"
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/semver/issues",
+ "source": "https://github.com/composer/semver/tree/3.3.2"
},
- "time": "2021-09-05T00:07:08+00:00"
- }
- ],
- "aliases": [],
- "minimum-stability": "stable",
- "stability-flags": [],
- "prefer-stable": false,
- "prefer-lowest": false,
- "platform": {
- "php": "^7.2 || ^8.0",
- "ext-filter": "*"
- },
- "platform-dev": [],
- "plugin-api-version": "2.1.0"
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-04-01T19:23:25+00:00"
+ },
+ {
+ "name": "composer/xdebug-handler",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/xdebug-handler.git",
+ "reference": "ced299686f41dce890debac69273b47ffe98a40c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
+ "reference": "ced299686f41dce890debac69273b47ffe98a40c",
+ "shasum": ""
+ },
+ "require": {
+ "composer/pcre": "^1 || ^2 || ^3",
+ "php": "^7.2.5 || ^8.0",
+ "psr/log": "^1 || ^2 || ^3"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "symfony/phpunit-bridge": "^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Composer\\XdebugHandler\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "John Stevenson",
+ "email": "john-stevenson@blueyonder.co.uk"
+ }
+ ],
+ "description": "Restarts a process without Xdebug.",
+ "keywords": [
+ "Xdebug",
+ "performance"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/xdebug-handler/issues",
+ "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-02-25T21:32:43+00:00"
+ },
+ {
+ "name": "dnoegel/php-xdg-base-dir",
+ "version": "v0.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
+ "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
+ "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "XdgBaseDir\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "implementation of xdg base directory specification for php",
+ "support": {
+ "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues",
+ "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1"
+ },
+ "time": "2019-12-04T15:06:13+00:00"
+ },
+ {
+ "name": "doctrine/instantiator",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc",
+ "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9",
+ "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"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "https://ocramius.github.io/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+ "keywords": [
+ "constructor",
+ "instantiate"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/1.4.1"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-03-03T08:28:38+00:00"
+ },
+ {
+ "name": "felixfbecker/advanced-json-rpc",
+ "version": "v3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git",
+ "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447",
+ "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447",
+ "shasum": ""
+ },
+ "require": {
+ "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
+ "php": "^7.1 || ^8.0",
+ "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7.0 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "AdvancedJsonRpc\\": "lib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "ISC"
+ ],
+ "authors": [
+ {
+ "name": "Felix Becker",
+ "email": "felix.b@outlook.com"
+ }
+ ],
+ "description": "A more advanced JSONRPC implementation",
+ "support": {
+ "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues",
+ "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1"
+ },
+ "time": "2021-06-11T22:34:44+00:00"
+ },
+ {
+ "name": "felixfbecker/language-server-protocol",
+ "version": "v1.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/felixfbecker/php-language-server-protocol.git",
+ "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842",
+ "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "*",
+ "squizlabs/php_codesniffer": "^3.1",
+ "vimeo/psalm": "^4.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "LanguageServerProtocol\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "ISC"
+ ],
+ "authors": [
+ {
+ "name": "Felix Becker",
+ "email": "felix.b@outlook.com"
+ }
+ ],
+ "description": "PHP classes for the Language Server Protocol",
+ "keywords": [
+ "language",
+ "microsoft",
+ "php",
+ "server"
+ ],
+ "support": {
+ "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues",
+ "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2"
+ },
+ "time": "2022-03-02T22:36:06+00:00"
+ },
+ {
+ "name": "fidry/cpu-core-counter",
+ "version": "0.5.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theofidry/cpu-core-counter.git",
+ "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/b58e5a3933e541dc286cc91fc4f3898bbc6f1623",
+ "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "fidry/makefile": "^0.2.0",
+ "phpstan/extension-installer": "^1.2.0",
+ "phpstan/phpstan": "^1.9.2",
+ "phpstan/phpstan-deprecation-rules": "^1.0.0",
+ "phpstan/phpstan-phpunit": "^1.2.2",
+ "phpstan/phpstan-strict-rules": "^1.4.4",
+ "phpunit/phpunit": "^9.5.26 || ^8.5.31",
+ "theofidry/php-cs-fixer-config": "^1.0",
+ "webmozarts/strict-phpunit": "^7.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Fidry\\CpuCoreCounter\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Théo FIDRY",
+ "email": "theo.fidry@gmail.com"
+ }
+ ],
+ "description": "Tiny utility to get the number of CPU cores.",
+ "keywords": [
+ "CPU",
+ "core"
+ ],
+ "support": {
+ "issues": "https://github.com/theofidry/cpu-core-counter/issues",
+ "source": "https://github.com/theofidry/cpu-core-counter/tree/0.5.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theofidry",
+ "type": "github"
+ }
+ ],
+ "time": "2022-12-24T12:35:10+00:00"
+ },
+ {
+ "name": "hamcrest/hamcrest-php",
+ "version": "v2.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/hamcrest/hamcrest-php.git",
+ "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+ "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3|^7.0|^8.0"
+ },
+ "replace": {
+ "cordoval/hamcrest-php": "*",
+ "davedevelopment/hamcrest-php": "*",
+ "kodova/hamcrest-php": "*"
+ },
+ "require-dev": {
+ "phpunit/php-file-iterator": "^1.4 || ^2.0",
+ "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "hamcrest"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "description": "This is the PHP port of Hamcrest Matchers",
+ "keywords": [
+ "test"
+ ],
+ "support": {
+ "issues": "https://github.com/hamcrest/hamcrest-php/issues",
+ "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1"
+ },
+ "time": "2020-07-09T08:09:16+00:00"
+ },
+ {
+ "name": "mockery/mockery",
+ "version": "1.3.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/mockery/mockery.git",
+ "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/472fa8ca4e55483d55ee1e73c963718c4393791d",
+ "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d",
+ "shasum": ""
+ },
+ "require": {
+ "hamcrest/hamcrest-php": "^2.0.1",
+ "lib-pcre": ">=7.0",
+ "php": ">=5.6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7.10|^6.5|^7.5|^8.5|^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Mockery": "library/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Pádraic Brady",
+ "email": "padraic.brady@gmail.com",
+ "homepage": "http://blog.astrumfutura.com"
+ },
+ {
+ "name": "Dave Marshall",
+ "email": "dave.marshall@atstsolutions.co.uk",
+ "homepage": "http://davedevelopment.co.uk"
+ }
+ ],
+ "description": "Mockery is a simple yet flexible PHP mock object framework",
+ "homepage": "https://github.com/mockery/mockery",
+ "keywords": [
+ "BDD",
+ "TDD",
+ "library",
+ "mock",
+ "mock objects",
+ "mockery",
+ "stub",
+ "test",
+ "test double",
+ "testing"
+ ],
+ "support": {
+ "issues": "https://github.com/mockery/mockery/issues",
+ "source": "https://github.com/mockery/mockery/tree/1.3.5"
+ },
+ "time": "2021-09-13T15:33:03+00:00"
+ },
+ {
+ "name": "myclabs/deep-copy",
+ "version": "1.11.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
+ "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/collections": "<1.6.8",
+ "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+ },
+ "require-dev": {
+ "doctrine/collections": "^1.6.8",
+ "doctrine/common": "^2.13.3 || ^3.2.2",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ],
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Create deep copies (clones) of your objects",
+ "keywords": [
+ "clone",
+ "copy",
+ "duplicate",
+ "object",
+ "object graph"
+ ],
+ "support": {
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
+ },
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-03-03T13:19:32+00:00"
+ },
+ {
+ "name": "netresearch/jsonmapper",
+ "version": "v4.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/cweiske/jsonmapper.git",
+ "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
+ "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-reflection": "*",
+ "ext-spl": "*",
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0",
+ "squizlabs/php_codesniffer": "~3.5"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-0": {
+ "JsonMapper": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "OSL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "Christian Weiske",
+ "email": "cweiske@cweiske.de",
+ "homepage": "http://github.com/cweiske/jsonmapper/",
+ "role": "Developer"
+ }
+ ],
+ "description": "Map nested JSON structures onto PHP classes",
+ "support": {
+ "email": "cweiske@cweiske.de",
+ "issues": "https://github.com/cweiske/jsonmapper/issues",
+ "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0"
+ },
+ "time": "2020-12-01T19:48:11+00:00"
+ },
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.14.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1",
+ "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.0"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0"
+ },
+ "time": "2022-05-31T20:59:12+00:00"
+ },
+ {
+ "name": "phar-io/manifest",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/manifest.git",
+ "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
+ "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-phar": "*",
+ "ext-xmlwriter": "*",
+ "phar-io/version": "^3.0.1",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+ },
+ "time": "2021-07-20T11:28:43+00:00"
+ },
+ {
+ "name": "phar-io/version",
+ "version": "3.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phar-io/version.git",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Heuer",
+ "email": "sebastian@phpeople.de",
+ "role": "Developer"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "Library for handling version information and constraints",
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues",
+ "source": "https://github.com/phar-io/version/tree/3.2.1"
+ },
+ "time": "2022-02-21T01:04:05+00:00"
+ },
+ {
+ "name": "phpstan/extension-installer",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/extension-installer.git",
+ "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
+ "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.1 || ^2.0",
+ "php": "^7.1 || ^8.0",
+ "phpstan/phpstan": ">=0.11.6"
+ },
+ "require-dev": {
+ "composer/composer": "^1.8",
+ "phing/phing": "^2.16.3",
+ "php-parallel-lint/php-parallel-lint": "^1.2.0",
+ "phpstan/phpstan-strict-rules": "^0.11 || ^0.12"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "PHPStan\\ExtensionInstaller\\Plugin"
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\ExtensionInstaller\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Composer plugin for automatic installation of PHPStan extensions",
+ "support": {
+ "issues": "https://github.com/phpstan/extension-installer/issues",
+ "source": "https://github.com/phpstan/extension-installer/tree/1.1.0"
+ },
+ "time": "2020-12-13T13:06:13+00:00"
+ },
+ {
+ "name": "phpstan/phpstan",
+ "version": "1.8.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan.git",
+ "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c53312ecc575caf07b0e90dee43883fdf90ca67c",
+ "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2|^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan-shim": "*"
+ },
+ "bin": [
+ "phpstan",
+ "phpstan.phar"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPStan - PHP Static Analysis Tool",
+ "support": {
+ "issues": "https://github.com/phpstan/phpstan/issues",
+ "source": "https://github.com/phpstan/phpstan/tree/1.8.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/ondrejmirtes",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/phpstan",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/phpstan",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-07-20T09:57:31+00:00"
+ },
+ {
+ "name": "phpstan/phpstan-mockery",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan-mockery.git",
+ "reference": "245b17ccd00f04be3c6b9fc6645f63793b37b2ea"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan-mockery/zipball/245b17ccd00f04be3c6b9fc6645f63793b37b2ea",
+ "reference": "245b17ccd00f04be3c6b9fc6645f63793b37b2ea",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0",
+ "phpstan/phpstan": "^1.5.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.2.4",
+ "nikic/php-parser": "^4.13.0",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.0",
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "phpstan-extension",
+ "extra": {
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPStan Mockery extension",
+ "support": {
+ "issues": "https://github.com/phpstan/phpstan-mockery/issues",
+ "source": "https://github.com/phpstan/phpstan-mockery/tree/1.1.0"
+ },
+ "time": "2022-05-09T13:12:35+00:00"
+ },
+ {
+ "name": "phpstan/phpstan-webmozart-assert",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan-webmozart-assert.git",
+ "reference": "a7f12958f0c5e1f948df99a84aa03fa8df544992"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan-webmozart-assert/zipball/a7f12958f0c5e1f948df99a84aa03fa8df544992",
+ "reference": "a7f12958f0c5e1f948df99a84aa03fa8df544992",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0",
+ "phpstan/phpstan": "^1.6.4"
+ },
+ "require-dev": {
+ "nikic/php-parser": "^4.13.0",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.0",
+ "phpunit/phpunit": "^9.5",
+ "webmozart/assert": "^1.11.0"
+ },
+ "type": "phpstan-extension",
+ "extra": {
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPStan webmozart/assert extension",
+ "support": {
+ "issues": "https://github.com/phpstan/phpstan-webmozart-assert/issues",
+ "source": "https://github.com/phpstan/phpstan-webmozart-assert/tree/1.2.0"
+ },
+ "time": "2022-06-06T08:42:28+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "9.2.16",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073",
+ "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-libxml": "*",
+ "ext-xmlwriter": "*",
+ "nikic/php-parser": "^4.14",
+ "php": ">=7.3",
+ "phpunit/php-file-iterator": "^3.0.3",
+ "phpunit/php-text-template": "^2.0.2",
+ "sebastian/code-unit-reverse-lookup": "^2.0.2",
+ "sebastian/complexity": "^2.0",
+ "sebastian/environment": "^5.1.2",
+ "sebastian/lines-of-code": "^1.0.3",
+ "sebastian/version": "^3.0.1",
+ "theseer/tokenizer": "^1.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-pcov": "*",
+ "ext-xdebug": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "9.2-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-08-20T05:26:47+00:00"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "3.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-02T12:48:52+00:00"
+ },
+ {
+ "name": "phpunit/php-invoker",
+ "version": "3.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-invoker.git",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "ext-pcntl": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-pcntl": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Invoke callables with a timeout",
+ "homepage": "https://github.com/sebastianbergmann/php-invoker/",
+ "keywords": [
+ "process"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
+ "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:58:55+00:00"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T05:33:50+00:00"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "5.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:16:10+00:00"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "9.5.23",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "888556852e7e9bbeeedb9656afe46118765ade34"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34",
+ "reference": "888556852e7e9bbeeedb9656afe46118765ade34",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "^1.3.1",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-xml": "*",
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.10.1",
+ "phar-io/manifest": "^2.0.3",
+ "phar-io/version": "^3.0.2",
+ "php": ">=7.3",
+ "phpunit/php-code-coverage": "^9.2.13",
+ "phpunit/php-file-iterator": "^3.0.5",
+ "phpunit/php-invoker": "^3.1.1",
+ "phpunit/php-text-template": "^2.0.3",
+ "phpunit/php-timer": "^5.0.2",
+ "sebastian/cli-parser": "^1.0.1",
+ "sebastian/code-unit": "^1.0.6",
+ "sebastian/comparator": "^4.0.5",
+ "sebastian/diff": "^4.0.3",
+ "sebastian/environment": "^5.1.3",
+ "sebastian/exporter": "^4.0.3",
+ "sebastian/global-state": "^5.0.1",
+ "sebastian/object-enumerator": "^4.0.3",
+ "sebastian/resource-operations": "^3.0.3",
+ "sebastian/type": "^3.0",
+ "sebastian/version": "^3.0.2"
+ },
+ "suggest": {
+ "ext-soap": "*",
+ "ext-xdebug": "*"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "9.5-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/Framework/Assert/Functions.php"
+ ],
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23"
+ },
+ "funding": [
+ {
+ "url": "https://phpunit.de/sponsors.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-08-22T14:01:36+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
+ "reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.4.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/1.1.2"
+ },
+ "time": "2021-11-05T16:50:12+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/1.1.4"
+ },
+ "time": "2021-05-03T11:20:27+00:00"
+ },
+ {
+ "name": "sebastian/cli-parser",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+ "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for parsing CLI options",
+ "homepage": "https://github.com/sebastianbergmann/cli-parser",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:08:49+00:00"
+ },
+ {
+ "name": "sebastian/code-unit",
+ "version": "1.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit.git",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Collection of value objects that represent the PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/code-unit",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:08:54+00:00"
+ },
+ {
+ "name": "sebastian/code-unit-reverse-lookup",
+ "version": "2.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Looks up which function or method a line of code belongs to",
+ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:30:19+00:00"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "4.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "55f4261989e546dc112258c7a75935a81a7ce382"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382",
+ "reference": "55f4261989e546dc112258c7a75935a81a7ce382",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/diff": "^4.0",
+ "sebastian/exporter": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "https://github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T15:49:45+00:00"
+ },
+ {
+ "name": "sebastian/complexity",
+ "version": "2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
+ "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.7",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for calculating the complexity of PHP code units",
+ "homepage": "https://github.com/sebastianbergmann/complexity",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/complexity/issues",
+ "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T15:52:27+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "4.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
+ "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "https://github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:10:38+00:00"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "5.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7",
+ "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-posix": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.1-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-04-03T09:37:03+00:00"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "4.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9",
+ "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-mbstring": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@gmail.com"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "https://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-11-11T14:18:36+00:00"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "5.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2",
+ "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "ext-dom": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-02-14T08:28:10+00:00"
+ },
+ {
+ "name": "sebastian/lines-of-code",
+ "version": "1.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+ "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.6",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library for counting the lines of code in PHP source code",
+ "homepage": "https://github.com/sebastianbergmann/lines-of-code",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-28T06:42:11+00:00"
+ },
+ {
+ "name": "sebastian/object-enumerator",
+ "version": "4.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+ "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:12:34+00:00"
+ },
+ {
+ "name": "sebastian/object-reflector",
+ "version": "2.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/object-reflector.git",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Allows reflection of object attributes, including inherited and non-public ones",
+ "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:14:26+00:00"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "4.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
+ "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:17:30+00:00"
+ },
+ {
+ "name": "sebastian/resource-operations",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/resource-operations.git",
+ "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+ "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:45:17+00:00"
+ },
+ {
+ "name": "sebastian/type",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/type.git",
+ "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
+ "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "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/3.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-03-15T09:54:48+00:00"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "3.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/version/issues",
+ "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T06:39:44+00:00"
+ },
+ {
+ "name": "spatie/array-to-xml",
+ "version": "2.17.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/spatie/array-to-xml.git",
+ "reference": "5cbec9c6ab17e320c58a259f0cebe88bde4a7c46"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/5cbec9c6ab17e320c58a259f0cebe88bde4a7c46",
+ "reference": "5cbec9c6ab17e320c58a259f0cebe88bde4a7c46",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "php": "^7.4|^8.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.2",
+ "pestphp/pest": "^1.21",
+ "phpunit/phpunit": "^9.0",
+ "spatie/pest-plugin-snapshots": "^1.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Spatie\\ArrayToXml\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://freek.dev",
+ "role": "Developer"
+ }
+ ],
+ "description": "Convert an array to xml",
+ "homepage": "https://github.com/spatie/array-to-xml",
+ "keywords": [
+ "array",
+ "convert",
+ "xml"
+ ],
+ "support": {
+ "source": "https://github.com/spatie/array-to-xml/tree/2.17.1"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/spatie",
+ "type": "github"
+ }
+ ],
+ "time": "2022-12-26T08:22:07+00:00"
+ },
+ {
+ "name": "symfony/console",
+ "version": "v5.4.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/console.git",
+ "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/console/zipball/c072aa8f724c3af64e2c7a96b796a4863d24dba1",
+ "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php73": "^1.9",
+ "symfony/polyfill-php80": "^1.16",
+ "symfony/service-contracts": "^1.1|^2|^3",
+ "symfony/string": "^5.1|^6.0"
+ },
+ "conflict": {
+ "psr/log": ">=3",
+ "symfony/dependency-injection": "<4.4",
+ "symfony/dotenv": "<5.1",
+ "symfony/event-dispatcher": "<4.4",
+ "symfony/lock": "<4.4",
+ "symfony/process": "<4.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2",
+ "symfony/config": "^4.4|^5.0|^6.0",
+ "symfony/dependency-injection": "^4.4|^5.0|^6.0",
+ "symfony/event-dispatcher": "^4.4|^5.0|^6.0",
+ "symfony/lock": "^4.4|^5.0|^6.0",
+ "symfony/process": "^4.4|^5.0|^6.0",
+ "symfony/var-dumper": "^4.4|^5.0|^6.0"
+ },
+ "suggest": {
+ "psr/log": "For using the console logger",
+ "symfony/event-dispatcher": "",
+ "symfony/lock": "",
+ "symfony/process": ""
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v5.4.12"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-08-17T13:18:05+00:00"
+ },
+ {
+ "name": "symfony/deprecation-contracts",
+ "version": "v2.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+ "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "files": [
+ "function.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "A generic function and convention to trigger deprecation notices",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-01-02T09:53:40+00:00"
+ },
+ {
+ "name": "symfony/filesystem",
+ "version": "v5.4.35",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "5a553607d4ffbfa9c0ab62facadea296c9db7086"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/5a553607d4ffbfa9c0ab62facadea296c9db7086",
+ "reference": "5a553607d4ffbfa9c0ab62facadea296c9db7086",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.8",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Filesystem\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides basic utilities for the filesystem",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/filesystem/tree/v5.4.35"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-01-23T13:51:25+00:00"
+ },
+ {
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
+ "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for ctype functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "433d05519ce6990bf3530fba6957499d327395c2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2",
+ "reference": "433d05519ce6990bf3530fba6957499d327395c2",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "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"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's grapheme_* functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "219aa369ceff116e673852dce47c3a41794c14bd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd",
+ "reference": "219aa369ceff116e673852dce47c3a41794c14bd",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "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"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+ "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php73",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php73.git",
+ "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85",
+ "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php73\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+ "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-10T07:21:04+00:00"
+ },
+ {
+ "name": "symfony/service-contracts",
+ "version": "v2.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+ "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "psr/container": "^1.1",
+ "symfony/deprecation-contracts": "^2.1|^3"
+ },
+ "conflict": {
+ "ext-psr": "<1.1|>=2"
+ },
+ "suggest": {
+ "symfony/service-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "2.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Service\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to writing services",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/v2.5.2"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-30T19:17:29+00:00"
+ },
+ {
+ "name": "symfony/string",
+ "version": "v5.4.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/string.git",
+ "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/string/zipball/2fc515e512d721bf31ea76bd02fe23ada4640058",
+ "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php80": "~1.15"
+ },
+ "conflict": {
+ "symfony/translation-contracts": ">=3.0"
+ },
+ "require-dev": {
+ "symfony/error-handler": "^4.4|^5.0|^6.0",
+ "symfony/http-client": "^4.4|^5.0|^6.0",
+ "symfony/translation-contracts": "^1.1|^2",
+ "symfony/var-exporter": "^4.4|^5.0|^6.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\String\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v5.4.12"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-08-12T17:03:11+00:00"
+ },
+ {
+ "name": "theseer/tokenizer",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
+ "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Arne Blankerts",
+ "email": "arne@blankerts.de",
+ "role": "Developer"
+ }
+ ],
+ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+ "support": {
+ "issues": "https://github.com/theseer/tokenizer/issues",
+ "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/theseer",
+ "type": "github"
+ }
+ ],
+ "time": "2021-07-28T10:34:58+00:00"
+ },
+ {
+ "name": "vimeo/psalm",
+ "version": "5.13.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/vimeo/psalm.git",
+ "reference": "086b94371304750d1c673315321a55d15fc59015"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/vimeo/psalm/zipball/086b94371304750d1c673315321a55d15fc59015",
+ "reference": "086b94371304750d1c673315321a55d15fc59015",
+ "shasum": ""
+ },
+ "require": {
+ "amphp/amp": "^2.4.2",
+ "amphp/byte-stream": "^1.5",
+ "composer-runtime-api": "^2",
+ "composer/semver": "^1.4 || ^2.0 || ^3.0",
+ "composer/xdebug-handler": "^2.0 || ^3.0",
+ "dnoegel/php-xdg-base-dir": "^0.1.1",
+ "ext-ctype": "*",
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "felixfbecker/advanced-json-rpc": "^3.1",
+ "felixfbecker/language-server-protocol": "^1.5.2",
+ "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1",
+ "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
+ "nikic/php-parser": "^4.14",
+ "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0",
+ "sebastian/diff": "^4.0 || ^5.0",
+ "spatie/array-to-xml": "^2.17.0 || ^3.0",
+ "symfony/console": "^4.1.6 || ^5.0 || ^6.0",
+ "symfony/filesystem": "^5.4 || ^6.0"
+ },
+ "provide": {
+ "psalm/psalm": "self.version"
+ },
+ "require-dev": {
+ "amphp/phpunit-util": "^2.0",
+ "bamarni/composer-bin-plugin": "^1.4",
+ "brianium/paratest": "^6.9",
+ "ext-curl": "*",
+ "mockery/mockery": "^1.5",
+ "nunomaduro/mock-final-classes": "^1.1",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/phpdoc-parser": "^1.6",
+ "phpunit/phpunit": "^9.6",
+ "psalm/plugin-mockery": "^1.1",
+ "psalm/plugin-phpunit": "^0.18",
+ "slevomat/coding-standard": "^8.4",
+ "squizlabs/php_codesniffer": "^3.6",
+ "symfony/process": "^4.4 || ^5.0 || ^6.0"
+ },
+ "suggest": {
+ "ext-curl": "In order to send data to shepherd",
+ "ext-igbinary": "^2.0.5 is required, used to serialize caching data"
+ },
+ "bin": [
+ "psalm",
+ "psalm-language-server",
+ "psalm-plugin",
+ "psalm-refactor",
+ "psalter"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.x-dev",
+ "dev-4.x": "4.x-dev",
+ "dev-3.x": "3.x-dev",
+ "dev-2.x": "2.x-dev",
+ "dev-1.x": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psalm\\": "src/Psalm/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matthew Brown"
+ }
+ ],
+ "description": "A static analysis tool for finding errors in PHP applications",
+ "keywords": [
+ "code",
+ "inspection",
+ "php",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/vimeo/psalm/issues",
+ "source": "https://github.com/vimeo/psalm/tree/5.13.1"
+ },
+ "time": "2023-06-27T16:39:49+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": "^7.4 || ^8.0",
+ "ext-filter": "*"
+ },
+ "platform-dev": [],
+ "platform-overrides": {
+ "php": "7.4.0"
+ },
+ "plugin-api-version": "2.6.0"
}
diff --git a/examples/04-adding-your-own-tag.php b/examples/04-adding-your-own-tag.php
index 49f751d99eacf4e5a640aa0580edb2082a2b7588..38ab724831c44aaa144099fa015f0635c2c272e3 100644
--- a/examples/04-adding-your-own-tag.php
+++ b/examples/04-adding-your-own-tag.php
@@ -42,7 +42,7 @@ final class MyTag extends BaseTag
*
* @var string
*/
- protected $name = 'my-tag';
+ protected string $name = 'my-tag';
/**
* The constructor for this Tag; this should contain all properties for this object.
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 27aa317bf984592cb0d94b9bbc8952eeda36596a..03c8954182965db9d31551377a9bab6131295b4a 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -10,13 +10,10 @@
<!-- Set the minimum PHP version for PHPCompatibility.
This should be kept in sync with the requirements in the composer.json file. -->
- <config name="testVersion" value="7.2-"/>
+ <config name="testVersion" value="7.4-"/>
<rule ref="phpDocumentor">
<exclude name="SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly.ReferencedGeneralException" />
-
- <!-- Property type declarations are a PHP 7.4 feature. -->
- <exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint"/>
</rule>
<rule ref="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming.SuperfluousPrefix">
diff --git a/phpstan.neon b/phpstan.neon
index b215c6a944e9b0929b5b675fa7646d86b2065a53..bd23f0af153ccaee39fa4da3d92d68fd12bf1a83 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,8 +1,8 @@
-includes:
- - /composer/vendor/phpstan/phpstan-mockery/extension.neon
- - /composer/vendor/phpstan/phpstan-webmozart-assert/extension.neon
-
parameters:
level: max
ignoreErrors:
- - '#Call to static method Webmozart\\Assert\\Assert::implementsInterface\(\) with class-string#'
\ No newline at end of file
+ - '#Method phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::createTag\(\) should return phpDocumentor\\Reflection\\DocBlock\\Tag but returns mixed#'
+ - "#Strict comparison using !== between array{'name', 'type'} and array{'name', 'type'} will always evaluate to false#"
+ - '#Call to static method Webmozart\\Assert\\Assert::implementsInterface\(\) with class-string#'
+ paths:
+ - src
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index fd7ab7487b8b9221e1250bf2ff6b0ae7756603e5..baf0ad6351f251cc3ee35a3afac8260a0446215f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -4,8 +4,8 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.0/phpunit.xsd"
colors="true"
- convertDeprecationsToExceptions="true"
- beStrictAboutOutputDuringTests="true"
+ convertDeprecationsToExceptions="false"
+ beStrictAboutOutputDuringTests="false"
forceCoversAnnotation="true"
verbose="true"
bootstrap="vendor/autoload.php"
diff --git a/psalm.xml b/psalm.xml
index 16f283f8d6269bd3ab9f30ee27e152a7065de8dd..7f491f7f233a6ea1d112e6313c994d9e381f2e1b 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<psalm
- totallyTyped="false"
+ errorLevel="2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config file:///composer/vendor/vimeo/psalm/config.xsd"
@@ -34,6 +34,19 @@
</errorLevel>
</DeprecatedInterface>
+ <DeprecatedMethod>
+ <errorLevel type="info">
+ <!-- Will be removed in 6.0.0 issues/361 -->
+ <referencedMethod name="phpDocumentor\Reflection\DocBlock\Tags\Param::create"/>
+ </errorLevel>
+ </DeprecatedMethod>
+
+ <NoInterfaceProperties>
+ <errorLevel type="info">
+ <file name="src/DocBlock/Tags/Factory/ParamFactory.php"/>
+ </errorLevel>
+ </NoInterfaceProperties>
+
<RedundantConditionGivenDocblockType>
<errorLevel type="info">
<!-- Psalm manage to infer a more precise type than PHPStan. notNull assert is needed for PHPStan but
diff --git a/src/DocBlock.php b/src/DocBlock.php
index cc33e60e6e8ee7c8df9300c0ad1cd6522af03fd4..90d8066d5fed662d7d3dffb1366126e5d746ad06 100644
--- a/src/DocBlock.php
+++ b/src/DocBlock.php
@@ -20,25 +20,25 @@ use Webmozart\Assert\Assert;
final class DocBlock
{
/** @var string The opening line for this docblock. */
- private $summary;
+ private string $summary;
/** @var DocBlock\Description The actual description for this docblock. */
- private $description;
+ private DocBlock\Description $description;
/** @var Tag[] An array containing all the tags in this docblock; except inline. */
- private $tags = [];
+ private array $tags = [];
/** @var Types\Context|null Information about the context of this DocBlock. */
- private $context;
+ private ?Types\Context $context = null;
/** @var Location|null Information about the location of this DocBlock. */
- private $location;
+ private ?Location $location = null;
/** @var bool Is this DocBlock (the start of) a template? */
- private $isTemplateStart;
+ private bool $isTemplateStart;
/** @var bool Does this DocBlock signify the end of a DocBlock template? */
- private $isTemplateEnd;
+ private bool $isTemplateEnd;
/**
* @param DocBlock\Tag[] $tags
diff --git a/src/DocBlock/Description.php b/src/DocBlock/Description.php
index a31b2892a3530c42904d11a67d9f4e6447cd00ed..a188ae30f3ab6cf66b8f80e07ecc2c4bbee2ab3a 100644
--- a/src/DocBlock/Description.php
+++ b/src/DocBlock/Description.php
@@ -48,15 +48,14 @@ use function vsprintf;
* is mainly responsible for rendering.
*
* @see DescriptionFactory to create a new Description.
- * @see Description\Formatter for the formatting of the body and tags.
+ * @see Tags\Formatter for the formatting of the body and tags.
*/
class Description
{
- /** @var string */
- private $bodyTemplate;
+ private string $bodyTemplate;
/** @var Tag[] */
- private $tags;
+ private array $tags;
/**
* Initializes a Description with its body (template) and a listing of the tags used in the body template.
@@ -93,6 +92,10 @@ class Description
*/
public function render(?Formatter $formatter = null): string
{
+ if ($this->tags === []) {
+ return vsprintf($this->bodyTemplate, []);
+ }
+
if ($formatter === null) {
$formatter = new PassthroughFormatter();
}
diff --git a/src/DocBlock/DescriptionFactory.php b/src/DocBlock/DescriptionFactory.php
index 1a519ec4a4413e7b219b1a6b9d02811ebdea776a..e7bc616d18b84beb100b6364a35a3c6ab5718041 100644
--- a/src/DocBlock/DescriptionFactory.php
+++ b/src/DocBlock/DescriptionFactory.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
use phpDocumentor\Reflection\Types\Context as TypeContext;
use phpDocumentor\Reflection\Utils;
@@ -47,13 +48,12 @@ use const PREG_SPLIT_DELIM_CAPTURE;
*/
class DescriptionFactory
{
- /** @var TagFactory */
- private $tagFactory;
+ private Factory $tagFactory;
/**
* Initializes this factory with the means to construct (inline) tags.
*/
- public function __construct(TagFactory $tagFactory)
+ public function __construct(Factory $tagFactory)
{
$this->tagFactory = $tagFactory;
}
diff --git a/src/DocBlock/ExampleFinder.php b/src/DocBlock/ExampleFinder.php
index 6a6b47295e801c66a5f29d7249a03fc34477e773..7136e28f4ef3bd5b0f6d3493c683c1609ac57971 100644
--- a/src/DocBlock/ExampleFinder.php
+++ b/src/DocBlock/ExampleFinder.php
@@ -31,11 +31,10 @@ use const DIRECTORY_SEPARATOR;
*/
class ExampleFinder
{
- /** @var string */
- private $sourceDirectory = '';
+ private string $sourceDirectory = '';
/** @var string[] */
- private $exampleDirectories = [];
+ private array $exampleDirectories = [];
/**
* Attempts to find the example contents for the given descriptor.
diff --git a/src/DocBlock/Serializer.php b/src/DocBlock/Serializer.php
index 77e5fb5fa51f90212152904d2041f0e0cf074661..31ca29c50d6e4271a1a3afe504b879dbefdef0e4 100644
--- a/src/DocBlock/Serializer.php
+++ b/src/DocBlock/Serializer.php
@@ -29,21 +29,20 @@ use function wordwrap;
class Serializer
{
/** @var string The string to indent the comment with. */
- protected $indentString = ' ';
+ protected string $indentString = ' ';
/** @var int The number of times the indent string is repeated. */
- protected $indent = 0;
+ protected int $indent = 0;
/** @var bool Whether to indent the first line with the given indent amount and string. */
- protected $isFirstLineIndented = true;
+ protected bool $isFirstLineIndented = true;
/** @var int|null The max length of a line. */
- protected $lineLength;
+ protected ?int $lineLength = null;
/** @var Formatter A custom tag formatter. */
- protected $tagFormatter;
- /** @var string */
- private $lineEnding;
+ protected Formatter $tagFormatter;
+ private string $lineEnding;
/**
* Create a Serializer instance.
diff --git a/src/DocBlock/StandardTagFactory.php b/src/DocBlock/StandardTagFactory.php
index 8d765951097164f9bf8d349dfb4e711495771700..7360a707a408d69730971320ae167e86b76e6a88 100644
--- a/src/DocBlock/StandardTagFactory.php
+++ b/src/DocBlock/StandardTagFactory.php
@@ -17,6 +17,7 @@ use InvalidArgumentException;
use phpDocumentor\Reflection\DocBlock\Tags\Author;
use phpDocumentor\Reflection\DocBlock\Tags\Covers;
use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
use phpDocumentor\Reflection\DocBlock\Tags\Generic;
use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
use phpDocumentor\Reflection\DocBlock\Tags\Link as LinkTag;
@@ -40,12 +41,15 @@ use ReflectionNamedType;
use ReflectionParameter;
use Webmozart\Assert\Assert;
+use function array_key_exists;
use function array_merge;
use function array_slice;
use function call_user_func_array;
use function count;
use function get_class;
+use function is_object;
use function preg_match;
+use function sprintf;
use function strpos;
use function trim;
@@ -72,10 +76,10 @@ final class StandardTagFactory implements TagFactory
public const REGEX_TAGNAME = '[\w\-\_\\\\:]+';
/**
- * @var array<class-string<Tag>> An array with a tag as a key, and an
+ * @var array<class-string<Tag>|Factory> An array with a tag as a key, and an
* FQCN to a class that handles it as an array value.
*/
- private $tagHandlerMappings = [
+ private array $tagHandlerMappings = [
'author' => Author::class,
'covers' => Covers::class,
'deprecated' => Deprecated::class,
@@ -101,22 +105,21 @@ final class StandardTagFactory implements TagFactory
* @var array<class-string<Tag>> An array with a anotation s a key, and an
* FQCN to a class that handles it as an array value.
*/
- private $annotationMappings = [];
+ private array $annotationMappings = [];
/**
* @var ReflectionParameter[][] a lazy-loading cache containing parameters
* for each tagHandler that has been used.
*/
- private $tagHandlerParameterCache = [];
+ private array $tagHandlerParameterCache = [];
- /** @var FqsenResolver */
- private $fqsenResolver;
+ private FqsenResolver $fqsenResolver;
/**
* @var mixed[] an array representing a simple Service Locator where we can store parameters and
* services that can be inserted into the Factory Methods of Tag Handlers.
*/
- private $serviceLocator = [];
+ private array $serviceLocator = [];
/**
* Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers.
@@ -162,18 +165,25 @@ final class StandardTagFactory implements TagFactory
$this->serviceLocator[$alias ?: get_class($service)] = $service;
}
- public function registerTagHandler(string $tagName, string $handler): void
+ /** {@inheritDoc} */
+ public function registerTagHandler(string $tagName, $handler): void
{
Assert::stringNotEmpty($tagName);
- Assert::classExists($handler);
- Assert::implementsInterface($handler, Tag::class);
-
if (strpos($tagName, '\\') && $tagName[0] !== '\\') {
throw new InvalidArgumentException(
'A namespaced tag must have a leading backslash as it must be fully qualified'
);
}
+ if (is_object($handler)) {
+ Assert::isInstanceOf($handler, Factory::class);
+ $this->tagHandlerMappings[$tagName] = $handler;
+
+ return;
+ }
+
+ Assert::classExists($handler);
+ Assert::implementsInterface($handler, Tag::class);
$this->tagHandlerMappings[$tagName] = $handler;
}
@@ -210,6 +220,10 @@ final class StandardTagFactory implements TagFactory
$this->getServiceLocatorWithDynamicParameters($context, $name, $body)
);
+ if (array_key_exists('tagLine', $arguments)) {
+ $arguments['tagLine'] = sprintf('@%s %s', $name, $body);
+ }
+
try {
$callable = [$handlerClassName, 'create'];
Assert::isCallable($callable);
@@ -225,9 +239,9 @@ final class StandardTagFactory implements TagFactory
/**
* Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`).
*
- * @return class-string<Tag>
+ * @return class-string<Tag>|Factory
*/
- private function findHandlerClassName(string $tagName, TypeContext $context): string
+ private function findHandlerClassName(string $tagName, TypeContext $context)
{
$handlerClassName = Generic::class;
if (isset($this->tagHandlerMappings[$tagName])) {
@@ -268,18 +282,18 @@ final class StandardTagFactory implements TagFactory
}
}
+ $parameterName = $parameter->getName();
if (isset($locator[$typeHint])) {
- $arguments[] = $locator[$typeHint];
+ $arguments[$parameterName] = $locator[$typeHint];
continue;
}
- $parameterName = $parameter->getName();
if (isset($locator[$parameterName])) {
- $arguments[] = $locator[$parameterName];
+ $arguments[$parameterName] = $locator[$parameterName];
continue;
}
- $arguments[] = null;
+ $arguments[$parameterName] = null;
}
return $arguments;
@@ -289,12 +303,14 @@ final class StandardTagFactory implements TagFactory
* Retrieves a series of ReflectionParameter objects for the static 'create' method of the given
* tag handler class name.
*
- * @param class-string $handlerClassName
+ * @param class-string|Factory $handler
*
* @return ReflectionParameter[]
*/
- private function fetchParametersForHandlerFactoryMethod(string $handlerClassName): array
+ private function fetchParametersForHandlerFactoryMethod($handler): array
{
+ $handlerClassName = is_object($handler) ? get_class($handler) : $handler;
+
if (!isset($this->tagHandlerParameterCache[$handlerClassName])) {
$methodReflection = new ReflectionMethod($handlerClassName, 'create');
$this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters();
diff --git a/src/DocBlock/TagFactory.php b/src/DocBlock/TagFactory.php
index c0868dcbefda0acbb2fb40f51db0e92926d415fc..a6f1ae8d5d57109cfeb389ef35d808de27c2709f 100644
--- a/src/DocBlock/TagFactory.php
+++ b/src/DocBlock/TagFactory.php
@@ -14,9 +14,9 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock;
use InvalidArgumentException;
-use phpDocumentor\Reflection\Types\Context as TypeContext;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
-interface TagFactory
+interface TagFactory extends Factory
{
/**
* Adds a parameter to the service locator that can be injected in a tag's factory method.
@@ -40,17 +40,6 @@ interface TagFactory
*/
public function addParameter(string $name, $value): void;
- /**
- * Factory method responsible for instantiating the correct sub type.
- *
- * @param string $tagLine The text for this tag, including description.
- *
- * @return Tag A new tag object.
- *
- * @throws InvalidArgumentException If an invalid tag line was presented.
- */
- public function create(string $tagLine, ?TypeContext $context = null): Tag;
-
/**
* Registers a service with the Service Locator using the FQCN of the class or the alias, if provided.
*
@@ -71,7 +60,7 @@ interface TagFactory
*
* @param string $tagName Name of tag to register a handler for. When registering a namespaced
* tag, the full name, along with a prefixing slash MUST be provided.
- * @param class-string<Tag> $handler FQCN of handler.
+ * @param class-string<Tag>|Factory $handler FQCN of handler.
*
* @throws InvalidArgumentException If the tag name is not a string.
* @throws InvalidArgumentException If the tag name is namespaced (contains backslashes) but
@@ -80,5 +69,5 @@ interface TagFactory
* @throws InvalidArgumentException If the handler is not an existing class.
* @throws InvalidArgumentException If the handler does not implement the {@see Tag} interface.
*/
- public function registerTagHandler(string $tagName, string $handler): void;
+ public function registerTagHandler(string $tagName, $handler): void;
}
diff --git a/src/DocBlock/Tags/Author.php b/src/DocBlock/Tags/Author.php
index ae09ecf4211625d4583fe40771491f462891a2a9..290e5a9574962d5e058312703c6a9bcf1b27e73f 100644
--- a/src/DocBlock/Tags/Author.php
+++ b/src/DocBlock/Tags/Author.php
@@ -27,13 +27,13 @@ use const FILTER_VALIDATE_EMAIL;
final class Author extends BaseTag implements Factory\StaticMethod
{
/** @var string register that this is the author tag. */
- protected $name = 'author';
+ protected string $name = 'author';
/** @var string The name of the author */
- private $authorName;
+ private string $authorName;
/** @var string The email of the author */
- private $authorEmail;
+ private string $authorEmail;
/**
* Initializes this tag with the author name and e-mail.
diff --git a/src/DocBlock/Tags/BaseTag.php b/src/DocBlock/Tags/BaseTag.php
index a28d5bf98e01822786dffabbaf921d0db0fdc54e..98b0d881dbc8f8cd765a8ef08d8ad29e405287b7 100644
--- a/src/DocBlock/Tags/BaseTag.php
+++ b/src/DocBlock/Tags/BaseTag.php
@@ -22,10 +22,10 @@ use phpDocumentor\Reflection\DocBlock\Description;
abstract class BaseTag implements DocBlock\Tag
{
/** @var string Name of the tag */
- protected $name = '';
+ protected string $name = '';
/** @var Description|null Description of the tag. */
- protected $description;
+ protected ?Description $description = null;
/**
* Gets the name of this tag.
diff --git a/src/DocBlock/Tags/Covers.php b/src/DocBlock/Tags/Covers.php
index 3eff9d8bc143dbf2b4b44e4254f6e2ffd81f3561..022594e20c29739fdae68a2779b8850e42d62f9d 100644
--- a/src/DocBlock/Tags/Covers.php
+++ b/src/DocBlock/Tags/Covers.php
@@ -29,11 +29,9 @@ use function explode;
*/
final class Covers extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'covers';
+ protected string $name = 'covers';
- /** @var Fqsen */
- private $refers;
+ private Fqsen $refers;
/**
* Initializes this tag.
diff --git a/src/DocBlock/Tags/Deprecated.php b/src/DocBlock/Tags/Deprecated.php
index dbcad28c053cc153ad5b06a5ae7def14fc8241c1..a55cd914a40f1e08a3fcd392f04d3b05e5b41f92 100644
--- a/src/DocBlock/Tags/Deprecated.php
+++ b/src/DocBlock/Tags/Deprecated.php
@@ -25,8 +25,7 @@ use function preg_match;
*/
final class Deprecated extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'deprecated';
+ protected string $name = 'deprecated';
/**
* PCRE regular expression matching a version vector.
@@ -45,7 +44,7 @@ final class Deprecated extends BaseTag implements Factory\StaticMethod
)';
/** @var string|null The version vector. */
- private $version;
+ private ?string $version = null;
public function __construct(?string $version = null, ?Description $description = null)
{
diff --git a/src/DocBlock/Tags/Example.php b/src/DocBlock/Tags/Example.php
index 825355aaf78920248367c01eec2785df73930caf..fd9ef6eb400499bf73a7aeb71213f2aafa99154b 100644
--- a/src/DocBlock/Tags/Example.php
+++ b/src/DocBlock/Tags/Example.php
@@ -29,22 +29,19 @@ use function trim;
final class Example implements Tag, Factory\StaticMethod
{
/** @var string Path to a file to use as an example. May also be an absolute URI. */
- private $filePath;
+ private string $filePath;
/**
* @var bool Whether the file path component represents an URI. This determines how the file portion
* appears at {@link getContent()}.
*/
- private $isURI;
+ private bool $isURI;
- /** @var int */
- private $startingLine;
+ private int $startingLine;
- /** @var int */
- private $lineCount;
+ private int $lineCount;
- /** @var string|null */
- private $content;
+ private ?string $content = null;
public function __construct(
string $filePath,
diff --git a/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php b/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a5f8e2ccf0d2dba53ef87de49276786c5afbde4
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php
@@ -0,0 +1,73 @@
+<?php
+/*
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ *
+ */
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use PHPStan\PhpDocParser\Lexer\Lexer;
+use PHPStan\PhpDocParser\Parser\ConstExprParser;
+use PHPStan\PhpDocParser\Parser\PhpDocParser;
+use PHPStan\PhpDocParser\Parser\TokenIterator;
+use PHPStan\PhpDocParser\Parser\TypeParser;
+use RuntimeException;
+
+/**
+ * Factory class creating tags using phpstan's parser
+ *
+ * This class uses {@see PHPStanFactory} implementations to create tags
+ * from the ast of the phpstan docblock parser.
+ *
+ * @internal This class is not part of the BC promise of this library.
+ */
+class AbstractPHPStanFactory implements Factory
+{
+ private PhpDocParser $parser;
+ private Lexer $lexer;
+ /** @var PHPStanFactory[] */
+ private array $factories;
+
+ public function __construct(PHPStanFactory ...$factories)
+ {
+ $this->lexer = new Lexer();
+ $constParser = new ConstExprParser();
+ $this->parser = new PhpDocParser(new TypeParser($constParser), $constParser);
+ $this->factories = $factories;
+ }
+
+ public function create(string $tagLine, ?TypeContext $context = null): Tag
+ {
+ $tokens = $this->lexer->tokenize($tagLine);
+ $ast = $this->parser->parseTag(new TokenIterator($tokens));
+
+ if ($context === null) {
+ $context = new TypeContext('');
+ }
+
+ try {
+ foreach ($this->factories as $factory) {
+ if ($factory->supports($ast, $context)) {
+ return $factory->create($ast, $context);
+ }
+ }
+ } catch (RuntimeException $e) {
+ return InvalidTag::create((string) $ast->value, 'method')->withError($e);
+ }
+
+ return InvalidTag::create(
+ (string) $ast->value,
+ $ast->name
+ );
+ }
+}
diff --git a/src/DocBlock/Tags/Factory/Factory.php b/src/DocBlock/Tags/Factory/Factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..190d3ff85b51efc1fec5ae0372b458bc13bc3f6a
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/Factory.php
@@ -0,0 +1,41 @@
+<?php
+/*
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ *
+ */
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use InvalidArgumentException;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+
+interface Factory
+{
+ /**
+ * Factory method responsible for instantiating the correct sub type.
+ *
+ * @param string $tagLine The text for this tag, including description.
+ *
+ * @return Tag A new tag object.
+ *
+ * @throws InvalidArgumentException If an invalid tag line was presented.
+ */
+ public function create(string $tagLine, ?TypeContext $context = null): Tag;
+}
diff --git a/src/DocBlock/Tags/Factory/MethodFactory.php b/src/DocBlock/Tags/Factory/MethodFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..920be8451659ae038a1becfae69d06e6f089e14e
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/MethodFactory.php
@@ -0,0 +1,81 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlock\Tags\MethodParameter;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\Mixed_;
+use phpDocumentor\Reflection\Types\Void_;
+use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueParameterNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use Webmozart\Assert\Assert;
+
+use function array_map;
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class MethodFactory implements PHPStanFactory
+{
+ private DescriptionFactory $descriptionFactory;
+ private TypeResolver $typeResolver;
+
+ public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+ {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+
+ public function create(PhpDocTagNode $node, Context $context): Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, MethodTagValueNode::class);
+
+ return new Method(
+ $tagValue->methodName,
+ [],
+ $this->createReturnType($tagValue, $context),
+ $tagValue->isStatic,
+ $this->descriptionFactory->create($tagValue->description, $context),
+ false,
+ array_map(
+ function (MethodTagValueParameterNode $param) use ($context) {
+ return new MethodParameter(
+ trim($param->parameterName, '$'),
+ $param->type === null ? new Mixed_() : $this->typeResolver->createType(
+ $param->type,
+ $context
+ ),
+ $param->isReference,
+ $param->isVariadic,
+ (string) $param->defaultValue
+ );
+ },
+ $tagValue->parameters
+ ),
+ );
+ }
+
+ public function supports(PhpDocTagNode $node, Context $context): bool
+ {
+ return $node->value instanceof MethodTagValueNode;
+ }
+
+ private function createReturnType(MethodTagValueNode $tagValue, Context $context): Type
+ {
+ if ($tagValue->returnType === null) {
+ return new Void_();
+ }
+
+ return $this->typeResolver->createType($tagValue->returnType, $context);
+ }
+}
diff --git a/src/DocBlock/Tags/Factory/PHPStanFactory.php b/src/DocBlock/Tags/Factory/PHPStanFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf04a06e64e134957bfd5071ccb69b5333d20ead
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/PHPStanFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+
+interface PHPStanFactory
+{
+ public function create(PhpDocTagNode $node, Context $context): Tag;
+
+ public function supports(PhpDocTagNode $node, Context $context): bool;
+}
diff --git a/src/DocBlock/Tags/Factory/ParamFactory.php b/src/DocBlock/Tags/Factory/ParamFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e9bcaaca2acb188422b4e365df6971e0ee5321d
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/ParamFactory.php
@@ -0,0 +1,86 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use Doctrine\Deprecations\Deprecation;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Param;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\TypelessParamTagValueNode;
+use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
+use PHPStan\PhpDocParser\Ast\Type\OffsetAccessTypeNode;
+use Webmozart\Assert\Assert;
+
+use function sprintf;
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class ParamFactory implements PHPStanFactory
+{
+ private DescriptionFactory $descriptionFactory;
+ private TypeResolver $typeResolver;
+
+ public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+ {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+
+ public function create(PhpDocTagNode $node, Context $context): Tag
+ {
+ $tagValue = $node->value;
+
+ if ($tagValue instanceof InvalidTagValueNode) {
+ Deprecation::trigger(
+ 'phpdocumentor/reflection-docblock',
+ 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/362',
+ sprintf(
+ 'Param tag value "%s" is invalid, falling back to legacy parsing. Please update your docblocks.',
+ $tagValue->value
+ )
+ );
+
+ return Param::create($tagValue->value, $this->typeResolver, $this->descriptionFactory, $context);
+ }
+
+ Assert::isInstanceOfAny(
+ $tagValue,
+ [
+ ParamTagValueNode::class,
+ TypelessParamTagValueNode::class,
+ ]
+ );
+
+ if (($tagValue->type ?? null) instanceof OffsetAccessTypeNode) {
+ return InvalidTag::create(
+ (string) $tagValue,
+ 'param'
+ );
+ }
+
+ return new Param(
+ trim($tagValue->parameterName, '$'),
+ $this->typeResolver->createType($tagValue->type ?? new IdentifierTypeNode('mixed'), $context),
+ $tagValue->isVariadic,
+ $this->descriptionFactory->create($tagValue->description, $context),
+ $tagValue->isReference
+ );
+ }
+
+ public function supports(PhpDocTagNode $node, Context $context): bool
+ {
+ return $node->value instanceof ParamTagValueNode
+ || $node->value instanceof TypelessParamTagValueNode
+ || $node->name === '@param';
+ }
+}
diff --git a/src/DocBlock/Tags/Factory/PropertyFactory.php b/src/DocBlock/Tags/Factory/PropertyFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..83a18e8a64bde7ee76a3f974efb5064190e548f3
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/PropertyFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Property;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
+use Webmozart\Assert\Assert;
+
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class PropertyFactory implements PHPStanFactory
+{
+ private DescriptionFactory $descriptionFactory;
+ private TypeResolver $typeResolver;
+
+ public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+ {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+
+ public function create(PhpDocTagNode $node, Context $context): Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+
+ return new Property(
+ trim($tagValue->propertyName, '$'),
+ $this->typeResolver->createType($tagValue->type, $context),
+ $this->descriptionFactory->create($tagValue->description, $context)
+ );
+ }
+
+ public function supports(PhpDocTagNode $node, Context $context): bool
+ {
+ return $node->value instanceof PropertyTagValueNode && $node->name === '@property';
+ }
+}
diff --git a/src/DocBlock/Tags/Factory/PropertyReadFactory.php b/src/DocBlock/Tags/Factory/PropertyReadFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..be443ab6af218b2adf986102d328b2b6bfa091f6
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/PropertyReadFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\PropertyRead;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
+use Webmozart\Assert\Assert;
+
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class PropertyReadFactory implements PHPStanFactory
+{
+ private DescriptionFactory $descriptionFactory;
+ private TypeResolver $typeResolver;
+
+ public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+ {
+ $this->typeResolver = $typeResolver;
+ $this->descriptionFactory = $descriptionFactory;
+ }
+
+ public function create(PhpDocTagNode $node, Context $context): Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+
+ return new PropertyRead(
+ trim($tagValue->propertyName, '$'),
+ $this->typeResolver->createType($tagValue->type, $context),
+ $this->descriptionFactory->create($tagValue->description, $context)
+ );
+ }
+
+ public function supports(PhpDocTagNode $node, Context $context): bool
+ {
+ return $node->value instanceof PropertyTagValueNode && $node->name === '@property-read';
+ }
+}
diff --git a/src/DocBlock/Tags/Factory/PropertyWriteFactory.php b/src/DocBlock/Tags/Factory/PropertyWriteFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..08cf75342cdc9972f0205fd34f1efcc2998b4cdf
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/PropertyWriteFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
+use Webmozart\Assert\Assert;
+
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class PropertyWriteFactory implements PHPStanFactory
+{
+ private DescriptionFactory $descriptionFactory;
+ private TypeResolver $typeResolver;
+
+ public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+ {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+
+ public function create(PhpDocTagNode $node, Context $context): Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+
+ return new PropertyWrite(
+ trim($tagValue->propertyName, '$'),
+ $this->typeResolver->createType($tagValue->type, $context),
+ $this->descriptionFactory->create($tagValue->description, $context)
+ );
+ }
+
+ public function supports(PhpDocTagNode $node, Context $context): bool
+ {
+ return $node->value instanceof PropertyTagValueNode && $node->name === '@property-write';
+ }
+}
diff --git a/src/DocBlock/Tags/Factory/ReturnFactory.php b/src/DocBlock/Tags/Factory/ReturnFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ebe5ad48cb5761f261708d289f852bf476b62d1
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/ReturnFactory.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Return_;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
+use Webmozart\Assert\Assert;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class ReturnFactory implements PHPStanFactory
+{
+ private DescriptionFactory $descriptionFactory;
+ private TypeResolver $typeResolver;
+
+ public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+ {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+
+ public function create(PhpDocTagNode $node, Context $context): Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, ReturnTagValueNode::class);
+
+ return new Return_(
+ $this->typeResolver->createType($tagValue->type, $context),
+ $this->descriptionFactory->create($tagValue->description, $context)
+ );
+ }
+
+ public function supports(PhpDocTagNode $node, Context $context): bool
+ {
+ return $node->value instanceof ReturnTagValueNode;
+ }
+}
diff --git a/src/DocBlock/Tags/Factory/VarFactory.php b/src/DocBlock/Tags/Factory/VarFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..79ffdf12b8a0884b1404773c1568e286825bbcc7
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/VarFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Var_;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
+use Webmozart\Assert\Assert;
+
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class VarFactory implements PHPStanFactory
+{
+ private DescriptionFactory $descriptionFactory;
+ private TypeResolver $typeResolver;
+
+ public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+ {
+ $this->descriptionFactory = $descriptionFactory;
+ $this->typeResolver = $typeResolver;
+ }
+
+ public function create(PhpDocTagNode $node, Context $context): Tag
+ {
+ $tagValue = $node->value;
+ Assert::isInstanceOf($tagValue, VarTagValueNode::class);
+
+ return new Var_(
+ trim($tagValue->variableName, '$'),
+ $this->typeResolver->createType($tagValue->type, $context),
+ $this->descriptionFactory->create($tagValue->description, $context)
+ );
+ }
+
+ public function supports(PhpDocTagNode $node, Context $context): bool
+ {
+ return $node->value instanceof VarTagValueNode;
+ }
+}
diff --git a/src/DocBlock/Tags/Formatter/AlignFormatter.php b/src/DocBlock/Tags/Formatter/AlignFormatter.php
index 946443438152fe58170210a131c08bcd350af4fc..ea5c16f5affe154d465249de493432d4b39ec6f5 100644
--- a/src/DocBlock/Tags/Formatter/AlignFormatter.php
+++ b/src/DocBlock/Tags/Formatter/AlignFormatter.php
@@ -23,7 +23,7 @@ use function strlen;
class AlignFormatter implements Formatter
{
/** @var int The maximum tag name length. */
- protected $maxLen = 0;
+ protected int $maxLen = 0;
/**
* @param Tag[] $tags All tags that should later be aligned with the formatter.
diff --git a/src/DocBlock/Tags/InvalidTag.php b/src/DocBlock/Tags/InvalidTag.php
index 4e6abb8c4fffb29626d45f8dfe1ceb0cb2e33ef0..c7d3cd54ec67fc712d51565fc6cb286c8b7aec91 100644
--- a/src/DocBlock/Tags/InvalidTag.php
+++ b/src/DocBlock/Tags/InvalidTag.php
@@ -32,14 +32,11 @@ use function sprintf;
*/
final class InvalidTag implements Tag
{
- /** @var string */
- private $name;
+ private string $name;
- /** @var string */
- private $body;
+ private string $body;
- /** @var Throwable|null */
- private $throwable;
+ private ?Throwable $throwable = null;
private function __construct(string $name, string $body)
{
diff --git a/src/DocBlock/Tags/Link.php b/src/DocBlock/Tags/Link.php
index ee242e3b24d861a952a8867e83ee23e988eab69b..fcb6ec193e00925ad3588e23ccc1ed49c3b02f47 100644
--- a/src/DocBlock/Tags/Link.php
+++ b/src/DocBlock/Tags/Link.php
@@ -24,11 +24,9 @@ use Webmozart\Assert\Assert;
*/
final class Link extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'link';
+ protected string $name = 'link';
- /** @var string */
- private $link;
+ private string $link;
/**
* Initializes a link to a URL.
diff --git a/src/DocBlock/Tags/Method.php b/src/DocBlock/Tags/Method.php
index f08bfffdae44bbb5e117ff9ab7f9775de052dede..471ebe95525a6266ee5ec4cb5027875e7d1d46ac 100644
--- a/src/DocBlock/Tags/Method.php
+++ b/src/DocBlock/Tags/Method.php
@@ -24,6 +24,7 @@ use phpDocumentor\Reflection\Types\Void_;
use Webmozart\Assert\Assert;
use function array_keys;
+use function array_map;
use function explode;
use function implode;
use function is_string;
@@ -31,34 +32,33 @@ use function preg_match;
use function sort;
use function strpos;
use function substr;
+use function trigger_error;
use function trim;
use function var_export;
+use const E_USER_DEPRECATED;
+
/**
* Reflection class for an {@}method in a Docblock.
*/
final class Method extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'method';
+ protected string $name = 'method';
- /** @var string */
- private $methodName;
+ private string $methodName;
- /**
- * @phpstan-var array<int, array{name: string, type: Type}>
- * @var array<int, array<string, Type|string>>
- */
- private $arguments;
+ private bool $isStatic;
+
+ private Type $returnType;
- /** @var bool */
- private $isStatic;
+ private bool $returnsReference;
- /** @var Type */
- private $returnType;
+ /** @var MethodParameter[] */
+ private array $parameters;
/**
* @param array<int, array<string, Type|string>> $arguments
+ * @param MethodParameter[] $parameters
* @phpstan-param array<int, array{name: string, type: Type}|string> $arguments
*/
public function __construct(
@@ -66,7 +66,9 @@ final class Method extends BaseTag implements Factory\StaticMethod
array $arguments = [],
?Type $returnType = null,
bool $static = false,
- ?Description $description = null
+ ?Description $description = null,
+ bool $returnsReference = false,
+ ?array $parameters = null
) {
Assert::stringNotEmpty($methodName);
@@ -74,19 +76,31 @@ final class Method extends BaseTag implements Factory\StaticMethod
$returnType = new Void_();
}
- $this->methodName = $methodName;
- $this->arguments = $this->filterArguments($arguments);
- $this->returnType = $returnType;
- $this->isStatic = $static;
- $this->description = $description;
+ $arguments = $this->filterArguments($arguments);
+
+ $this->methodName = $methodName;
+ $this->returnType = $returnType;
+ $this->isStatic = $static;
+ $this->description = $description;
+ $this->returnsReference = $returnsReference;
+ $this->parameters = $parameters ?? $this->fromLegacyArguments($arguments);
}
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
public static function create(
string $body,
?TypeResolver $typeResolver = null,
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
): ?self {
+ trigger_error(
+ 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers',
+ E_USER_DEPRECATED
+ );
Assert::stringNotEmpty($body);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
@@ -95,11 +109,13 @@ final class Method extends BaseTag implements Factory\StaticMethod
// 2. optionally the keyword "static" followed by whitespace
// 3. optionally a word with underscores followed by whitespace : as
// type for the return value
- // 4. then optionally a word with underscores followed by () and
+ // 4. optionally an ampersand followed or not by whitespace : as
+ // a reference
+ // 5. then optionally a word with underscores followed by () and
// whitespace : as method name as used by phpDocumentor
- // 5. then a word with underscores, followed by ( and any character
+ // 6. then a word with underscores, followed by ( and any character
// until a ) and whitespace : as method name with signature
- // 6. any remaining text : as description
+ // 7. any remaining text : as description
if (
!preg_match(
'/^
@@ -122,6 +138,11 @@ final class Method extends BaseTag implements Factory\StaticMethod
)
\s+
)?
+ # Returns reference
+ (?:
+ (&)
+ \s*
+ )?
# Method name
([\w_]+)
# Arguments
@@ -139,7 +160,7 @@ final class Method extends BaseTag implements Factory\StaticMethod
return null;
}
- [, $static, $returnType, $methodName, $argumentLines, $description] = $matches;
+ [, $static, $returnType, $returnsReference, $methodName, $argumentLines, $description] = $matches;
$static = $static === 'static';
@@ -147,6 +168,8 @@ final class Method extends BaseTag implements Factory\StaticMethod
$returnType = 'void';
}
+ $returnsReference = $returnsReference === '&';
+
$returnType = $typeResolver->resolve($returnType, $context);
$description = $descriptionFactory->create($description, $context);
@@ -172,7 +195,14 @@ final class Method extends BaseTag implements Factory\StaticMethod
}
}
- return new static($methodName, $arguments, $returnType, $static, $description);
+ return new static(
+ $methodName,
+ $arguments,
+ $returnType,
+ $static,
+ $description,
+ $returnsReference
+ );
}
/**
@@ -184,12 +214,27 @@ final class Method extends BaseTag implements Factory\StaticMethod
}
/**
+ * @deprecated Method deprecated, use {@see self::getParameters()}
+ *
* @return array<int, array<string, Type|string>>
* @phpstan-return array<int, array{name: string, type: Type}>
*/
public function getArguments(): array
{
- return $this->arguments;
+ trigger_error('Method deprecated, use ::getParameters()', E_USER_DEPRECATED);
+
+ return array_map(
+ static function (MethodParameter $methodParameter) {
+ return ['name' => $methodParameter->getName(), 'type' => $methodParameter->getType()];
+ },
+ $this->parameters
+ );
+ }
+
+ /** @return MethodParameter[] */
+ public function getParameters(): array
+ {
+ return $this->parameters;
}
/**
@@ -207,11 +252,19 @@ final class Method extends BaseTag implements Factory\StaticMethod
return $this->returnType;
}
+ public function returnsReference(): bool
+ {
+ return $this->returnsReference;
+ }
+
public function __toString(): string
{
$arguments = [];
- foreach ($this->arguments as $argument) {
- $arguments[] = $argument['type'] . ' $' . $argument['name'];
+ foreach ($this->parameters as $parameter) {
+ $arguments[] = $parameter->getType() . ' ' .
+ ($parameter->isReference() ? '&' : '') .
+ ($parameter->isVariadic() ? '...' : '') .
+ '$' . $parameter->getName();
}
$argumentStr = '(' . implode(', ', $arguments) . ')';
@@ -228,9 +281,11 @@ final class Method extends BaseTag implements Factory\StaticMethod
$methodName = $this->methodName;
+ $reference = $this->returnsReference ? '&' : '';
+
return $static
. ($returnType !== '' ? ($static !== '' ? ' ' : '') . $returnType : '')
- . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $methodName : '')
+ . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $reference . $methodName : '')
. $argumentStr
. ($description !== '' ? ' ' . $description : '');
}
@@ -276,4 +331,28 @@ final class Method extends BaseTag implements Factory\StaticMethod
return $argument;
}
+
+ /**
+ * @param array{name: string, type: Type} $arguments
+ * @phpstan-param array<int, array{name: string, type: Type}> $arguments
+ *
+ * @return MethodParameter[]
+ */
+ private function fromLegacyArguments(array $arguments): array
+ {
+ trigger_error(
+ 'Create method parameters via legacy format is deprecated add parameters via the constructor',
+ E_USER_DEPRECATED
+ );
+
+ return array_map(
+ static function ($arg) {
+ return new MethodParameter(
+ $arg['name'],
+ $arg['type']
+ );
+ },
+ $arguments
+ );
+ }
}
diff --git a/src/DocBlock/Tags/MethodParameter.php b/src/DocBlock/Tags/MethodParameter.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c85d41ddf976aa40f99e0355b88f532d9e93f16
--- /dev/null
+++ b/src/DocBlock/Tags/MethodParameter.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\Type;
+
+final class MethodParameter
+{
+ private Type $type;
+
+ private bool $isReference;
+
+ private bool $isVariadic;
+
+ private string $name;
+
+ private ?string $defaultValue = null;
+
+ public function __construct(
+ string $name,
+ Type $type,
+ bool $isReference = false,
+ bool $isVariadic = false,
+ ?string $defaultValue = null
+ ) {
+ $this->type = $type;
+ $this->isReference = $isReference;
+ $this->isVariadic = $isVariadic;
+ $this->name = $name;
+ $this->defaultValue = $defaultValue;
+ }
+
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ public function getType(): Type
+ {
+ return $this->type;
+ }
+
+ public function isReference(): bool
+ {
+ return $this->isReference;
+ }
+
+ public function isVariadic(): bool
+ {
+ return $this->isVariadic;
+ }
+
+ public function getDefaultValue(): ?string
+ {
+ return $this->defaultValue;
+ }
+}
diff --git a/src/DocBlock/Tags/Param.php b/src/DocBlock/Tags/Param.php
index 3399649b83b18f9e8083ff2bbf7ad94f2fe5ea46..19b1b5fbd5ac0e7360ed3e7da7adbcd112462102 100644
--- a/src/DocBlock/Tags/Param.php
+++ b/src/DocBlock/Tags/Param.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags;
+use Doctrine\Deprecations\Deprecation;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\Type;
@@ -34,14 +35,13 @@ use const PREG_SPLIT_DELIM_CAPTURE;
*/
final class Param extends TagWithType implements Factory\StaticMethod
{
- /** @var string|null */
- private $variableName;
+ private ?string $variableName = null;
/** @var bool determines whether this is a variadic argument */
- private $isVariadic;
+ private bool $isVariadic;
/** @var bool determines whether this is passed by reference */
- private $isReference;
+ private bool $isReference;
public function __construct(
?string $variableName,
@@ -58,12 +58,23 @@ final class Param extends TagWithType implements Factory\StaticMethod
$this->isReference = $isReference;
}
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
public static function create(
string $body,
?TypeResolver $typeResolver = null,
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
): self {
+ Deprecation::triggerIfCalledFromOutside(
+ 'phpdocumentor/reflection-docblock',
+ 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+ 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers',
+ );
+
Assert::stringNotEmpty($body);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/Property.php b/src/DocBlock/Tags/Property.php
index 2521fb3f01b9c57eee09c4fe9139134d25a08b78..1287b6cc2ba02cc2ec1de7cf8142cb5c1a69ea49 100644
--- a/src/DocBlock/Tags/Property.php
+++ b/src/DocBlock/Tags/Property.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags;
+use Doctrine\Deprecations\Deprecation;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\Type;
@@ -34,8 +35,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
*/
final class Property extends TagWithType implements Factory\StaticMethod
{
- /** @var string|null */
- protected $variableName;
+ protected ?string $variableName = null;
public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
{
@@ -47,12 +47,23 @@ final class Property extends TagWithType implements Factory\StaticMethod
$this->description = $description;
}
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
public static function create(
string $body,
?TypeResolver $typeResolver = null,
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
): self {
+ Deprecation::triggerIfCalledFromOutside(
+ 'phpdocumentor/reflection-docblock',
+ 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+ 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers',
+ );
+
Assert::stringNotEmpty($body);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/PropertyRead.php b/src/DocBlock/Tags/PropertyRead.php
index 9491b39c3343fd9a1777983d5db4bb38e6128d25..2cf8e61a615cd06234ed7aed00df5438f316961e 100644
--- a/src/DocBlock/Tags/PropertyRead.php
+++ b/src/DocBlock/Tags/PropertyRead.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags;
+use Doctrine\Deprecations\Deprecation;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\Type;
@@ -34,8 +35,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
*/
final class PropertyRead extends TagWithType implements Factory\StaticMethod
{
- /** @var string|null */
- protected $variableName;
+ protected ?string $variableName = null;
public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
{
@@ -47,12 +47,23 @@ final class PropertyRead extends TagWithType implements Factory\StaticMethod
$this->description = $description;
}
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
public static function create(
string $body,
?TypeResolver $typeResolver = null,
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
): self {
+ Deprecation::triggerIfCalledFromOutside(
+ 'phpdocumentor/reflection-docblock',
+ 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+ 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers',
+ );
+
Assert::stringNotEmpty($body);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/PropertyWrite.php b/src/DocBlock/Tags/PropertyWrite.php
index 2bfdac6a0673d40d62a5abdcfa35452a4067b7cc..57e7eb103e9ab10be260c48575fced55b46bd37b 100644
--- a/src/DocBlock/Tags/PropertyWrite.php
+++ b/src/DocBlock/Tags/PropertyWrite.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags;
+use Doctrine\Deprecations\Deprecation;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\Type;
@@ -34,8 +35,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
*/
final class PropertyWrite extends TagWithType implements Factory\StaticMethod
{
- /** @var string */
- protected $variableName;
+ protected string $variableName;
public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
{
@@ -47,12 +47,23 @@ final class PropertyWrite extends TagWithType implements Factory\StaticMethod
$this->description = $description;
}
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
public static function create(
string $body,
?TypeResolver $typeResolver = null,
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
): self {
+ Deprecation::triggerIfCalledFromOutside(
+ 'phpdocumentor/reflection-docblock',
+ 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+ 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers',
+ );
+
Assert::stringNotEmpty($body);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/Reference/Fqsen.php b/src/DocBlock/Tags/Reference/Fqsen.php
index 532003dd8a68095c25c77792c5f7ce4bded742e5..e4e7e31c6317ad5f3f30d754caf70d983163974a 100644
--- a/src/DocBlock/Tags/Reference/Fqsen.php
+++ b/src/DocBlock/Tags/Reference/Fqsen.php
@@ -20,8 +20,7 @@ use phpDocumentor\Reflection\Fqsen as RealFqsen;
*/
final class Fqsen implements Reference
{
- /** @var RealFqsen */
- private $fqsen;
+ private RealFqsen $fqsen;
public function __construct(RealFqsen $fqsen)
{
diff --git a/src/DocBlock/Tags/Reference/Url.php b/src/DocBlock/Tags/Reference/Url.php
index edfba3fde8a5eb9e01bc492b53a0a2ecf28a7f00..5954a471796039d43a5c14e7c5fc3ec1876ef0ca 100644
--- a/src/DocBlock/Tags/Reference/Url.php
+++ b/src/DocBlock/Tags/Reference/Url.php
@@ -20,8 +20,7 @@ use Webmozart\Assert\Assert;
*/
final class Url implements Reference
{
- /** @var string */
- private $uri;
+ private string $uri;
public function __construct(string $uri)
{
diff --git a/src/DocBlock/Tags/Return_.php b/src/DocBlock/Tags/Return_.php
index f021b6092ec6ca5bfa9b5d783092719efe93ebf4..f130760a4ee4b75c500557bb4200861fe363b64a 100644
--- a/src/DocBlock/Tags/Return_.php
+++ b/src/DocBlock/Tags/Return_.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags;
+use Doctrine\Deprecations\Deprecation;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\Type;
@@ -32,12 +33,23 @@ final class Return_ extends TagWithType implements Factory\StaticMethod
$this->description = $description;
}
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
public static function create(
string $body,
?TypeResolver $typeResolver = null,
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
): self {
+ Deprecation::triggerIfCalledFromOutside(
+ 'phpdocumentor/reflection-docblock',
+ 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+ 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers',
+ );
+
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/See.php b/src/DocBlock/Tags/See.php
index a194c7dedabb6e89682525b0691cfa65c9b8c1ff..e7330e887efab4dce6c2b6f7238647571a4eb642 100644
--- a/src/DocBlock/Tags/See.php
+++ b/src/DocBlock/Tags/See.php
@@ -33,11 +33,9 @@ use function preg_match;
*/
final class See extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'see';
+ protected string $name = 'see';
- /** @var Reference */
- protected $refers;
+ protected Reference $refers;
/**
* Initializes this tag.
diff --git a/src/DocBlock/Tags/Since.php b/src/DocBlock/Tags/Since.php
index 54af43cd428be1b1f1df56ca5ce780b8e61848b8..24400fa1db5f8c5ffbb06b10e88806906d5468a6 100644
--- a/src/DocBlock/Tags/Since.php
+++ b/src/DocBlock/Tags/Since.php
@@ -25,8 +25,7 @@ use function preg_match;
*/
final class Since extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'since';
+ protected string $name = 'since';
/**
* PCRE regular expression matching a version vector.
@@ -45,7 +44,7 @@ final class Since extends BaseTag implements Factory\StaticMethod
)';
/** @var string|null The version vector. */
- private $version;
+ private ?string $version = null;
public function __construct(?string $version = null, ?Description $description = null)
{
diff --git a/src/DocBlock/Tags/Source.php b/src/DocBlock/Tags/Source.php
index 8b8c0fb47b8162b8b9be913ab386d35123c1d929..f6b4f57fad05691fc141980aa5e42fd0bc64a8fe 100644
--- a/src/DocBlock/Tags/Source.php
+++ b/src/DocBlock/Tags/Source.php
@@ -25,14 +25,13 @@ use function preg_match;
*/
final class Source extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'source';
+ protected string $name = 'source';
/** @var int The starting line, relative to the structural element's location. */
- private $startingLine;
+ private int $startingLine;
/** @var int|null The number of lines, relative to the starting line. NULL means "to the end". */
- private $lineCount;
+ private ?int $lineCount = null;
/**
* @param int|string $startingLine should be a to int convertible value
diff --git a/src/DocBlock/Tags/TagWithType.php b/src/DocBlock/Tags/TagWithType.php
index 158578bd2e423b87b5ec0b45fc800747646e175d..271c41b539555845e646bfa1cb32cfe7c49398e5 100644
--- a/src/DocBlock/Tags/TagWithType.php
+++ b/src/DocBlock/Tags/TagWithType.php
@@ -13,9 +13,11 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags;
+use InvalidArgumentException;
use phpDocumentor\Reflection\Type;
use function in_array;
+use function sprintf;
use function strlen;
use function substr;
use function trim;
@@ -23,7 +25,7 @@ use function trim;
abstract class TagWithType extends BaseTag
{
/** @var ?Type */
- protected $type;
+ protected ?Type $type = null;
/**
* Returns the type section of the variable.
@@ -59,6 +61,12 @@ abstract class TagWithType extends BaseTag
}
}
+ if ($nestingLevel < 0 || $nestingLevel > 0) {
+ throw new InvalidArgumentException(
+ sprintf('Could not find type in %s, please check for malformed notations', $body)
+ );
+ }
+
$description = trim(substr($body, strlen($type)));
return [$type, $description];
diff --git a/src/DocBlock/Tags/Uses.php b/src/DocBlock/Tags/Uses.php
index b72f403474c95f62b9cfbae4ae26472b47cf350a..d9aa3608fece147c9f293ba44a524743e38eabcf 100644
--- a/src/DocBlock/Tags/Uses.php
+++ b/src/DocBlock/Tags/Uses.php
@@ -29,11 +29,9 @@ use function explode;
*/
final class Uses extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'uses';
+ protected string $name = 'uses';
- /** @var Fqsen */
- protected $refers;
+ protected Fqsen $refers;
/**
* Initializes this tag.
diff --git a/src/DocBlock/Tags/Var_.php b/src/DocBlock/Tags/Var_.php
index fa1f9dbf656c6fa82921b320bcb616281ce95fa4..0a79ab94dec4ab74e03d1aa94d1853b9c690310d 100644
--- a/src/DocBlock/Tags/Var_.php
+++ b/src/DocBlock/Tags/Var_.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection\DocBlock\Tags;
+use Doctrine\Deprecations\Deprecation;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\Type;
@@ -34,8 +35,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
*/
final class Var_ extends TagWithType implements Factory\StaticMethod
{
- /** @var string|null */
- protected $variableName = '';
+ protected ?string $variableName = '';
public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
{
@@ -47,12 +47,22 @@ final class Var_ extends TagWithType implements Factory\StaticMethod
$this->description = $description;
}
+ /**
+ * @deprecated Create using static factory is deprecated,
+ * this method should not be called directly by library consumers
+ */
public static function create(
string $body,
?TypeResolver $typeResolver = null,
?DescriptionFactory $descriptionFactory = null,
?TypeContext $context = null
): self {
+ Deprecation::triggerIfCalledFromOutside(
+ 'phpdocumentor/reflection-docblock',
+ 'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+ 'Create using static factory is deprecated, this method should not be called directly
+ by library consumers',
+ );
Assert::stringNotEmpty($body);
Assert::notNull($typeResolver);
Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/Version.php b/src/DocBlock/Tags/Version.php
index f46e4b8c01dfd54e9c91a892630f547106896541..1ed25d173a828a53519ee130f24a10a461e220db 100644
--- a/src/DocBlock/Tags/Version.php
+++ b/src/DocBlock/Tags/Version.php
@@ -25,8 +25,7 @@ use function preg_match;
*/
final class Version extends BaseTag implements Factory\StaticMethod
{
- /** @var string */
- protected $name = 'version';
+ protected string $name = 'version';
/**
* PCRE regular expression matching a version vector.
@@ -45,7 +44,7 @@ final class Version extends BaseTag implements Factory\StaticMethod
)';
/** @var string|null The version vector. */
- private $version;
+ private ?string $version = null;
public function __construct(?string $version = null, ?Description $description = null)
{
diff --git a/src/DocBlockFactory.php b/src/DocBlockFactory.php
index 37f72dd2e30b2c1296c6262de74e61ea03dcb422..1f7faf1aad10cec039776aa77b85bd363d74f7d5 100644
--- a/src/DocBlockFactory.php
+++ b/src/DocBlockFactory.php
@@ -19,6 +19,15 @@ use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\TagFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\AbstractPHPStanFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory;
use Webmozart\Assert\Assert;
use function array_shift;
@@ -35,11 +44,9 @@ use function trim;
final class DocBlockFactory implements DocBlockFactoryInterface
{
- /** @var DocBlock\DescriptionFactory */
- private $descriptionFactory;
+ private DocBlock\DescriptionFactory $descriptionFactory;
- /** @var DocBlock\TagFactory */
- private $tagFactory;
+ private TagFactory $tagFactory;
/**
* Initializes this factory with the required subcontractors.
@@ -47,22 +54,40 @@ final class DocBlockFactory implements DocBlockFactoryInterface
public function __construct(DescriptionFactory $descriptionFactory, TagFactory $tagFactory)
{
$this->descriptionFactory = $descriptionFactory;
- $this->tagFactory = $tagFactory;
+ $this->tagFactory = $tagFactory;
}
/**
* Factory method for easy instantiation.
*
- * @param array<string, class-string<Tag>> $additionalTags
+ * @param array<string, class-string<Tag>|Factory> $additionalTags
*/
- public static function createInstance(array $additionalTags = []): self
+ public static function createInstance(array $additionalTags = []): DocBlockFactoryInterface
{
- $fqsenResolver = new FqsenResolver();
- $tagFactory = new StandardTagFactory($fqsenResolver);
+ $fqsenResolver = new FqsenResolver();
+ $tagFactory = new StandardTagFactory($fqsenResolver);
$descriptionFactory = new DescriptionFactory($tagFactory);
+ $typeResolver = new TypeResolver($fqsenResolver);
+
+ $phpstanTagFactory = new AbstractPHPStanFactory(
+ new ParamFactory($typeResolver, $descriptionFactory),
+ new VarFactory($typeResolver, $descriptionFactory),
+ new ReturnFactory($typeResolver, $descriptionFactory),
+ new PropertyFactory($typeResolver, $descriptionFactory),
+ new PropertyReadFactory($typeResolver, $descriptionFactory),
+ new PropertyWriteFactory($typeResolver, $descriptionFactory),
+ new MethodFactory($typeResolver, $descriptionFactory)
+ );
$tagFactory->addService($descriptionFactory);
- $tagFactory->addService(new TypeResolver($fqsenResolver));
+ $tagFactory->addService($typeResolver);
+ $tagFactory->registerTagHandler('param', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('var', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('return', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('property', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('property-read', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('property-write', $phpstanTagFactory);
+ $tagFactory->registerTagHandler('method', $phpstanTagFactory);
$docBlockFactory = new self($descriptionFactory, $tagFactory);
foreach ($additionalTags as $tagName => $tagHandler) {
@@ -111,9 +136,9 @@ final class DocBlockFactory implements DocBlockFactoryInterface
}
/**
- * @param class-string<Tag> $handler
+ * @param class-string<Tag>|Factory $handler
*/
- public function registerTagHandler(string $tagName, string $handler): void
+ public function registerTagHandler(string $tagName, $handler): void
{
$this->tagFactory->registerTagHandler($tagName, $handler);
}
@@ -138,6 +163,7 @@ final class DocBlockFactory implements DocBlockFactoryInterface
}
// phpcs:disable
+
/**
* Splits the DocBlock into a template marker, summary, description and block of tags.
*
@@ -149,7 +175,7 @@ final class DocBlockFactory implements DocBlockFactoryInterface
*
* @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.
*/
- private function splitDocBlock(string $comment) : array
+ private function splitDocBlock(string $comment): array
{
// phpcs:enable
// Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This
@@ -227,7 +253,7 @@ final class DocBlockFactory implements DocBlockFactoryInterface
/**
* Creates the tag objects.
*
- * @param string $tags Tag block to parse.
+ * @param string $tags Tag block to parse.
* @param Types\Context $context Context of the parsed Tag
*
* @return DocBlock\Tag[]
@@ -240,7 +266,7 @@ final class DocBlockFactory implements DocBlockFactoryInterface
}
$result = [];
- $lines = $this->splitTagBlockIntoTagLines($tags);
+ $lines = $this->splitTagBlockIntoTagLines($tags);
foreach ($lines as $key => $tagLine) {
$result[$key] = $this->tagFactory->create(trim($tagLine), $context);
}
diff --git a/src/DocBlockFactoryInterface.php b/src/DocBlockFactoryInterface.php
index 9995c0c0958d3db36e2a4b6e21c4d89ce441c632..cacc382e61b68ee90414082473f0e09a66eec161 100644
--- a/src/DocBlockFactoryInterface.php
+++ b/src/DocBlockFactoryInterface.php
@@ -14,7 +14,7 @@ interface DocBlockFactoryInterface
*
* @param array<string, class-string<Tag>> $additionalTags
*/
- public static function createInstance(array $additionalTags = []): DocBlockFactory;
+ public static function createInstance(array $additionalTags = []): self;
/**
* @param string|object $docblock
diff --git a/tests/integration/InterpretingDocBlocksTest.php b/tests/integration/InterpretingDocBlocksTest.php
index 2c8358cfbbd6daf570db84fc158cfa36099d0e4a..51f3e8f0e387b1e4198f6381758814c712e28c16 100644
--- a/tests/integration/InterpretingDocBlocksTest.php
+++ b/tests/integration/InterpretingDocBlocksTest.php
@@ -17,7 +17,19 @@ use Mockery as m;
use phpDocumentor\Reflection\DocBlock\Description;
use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlock\Tags\MethodParameter;
+use phpDocumentor\Reflection\DocBlock\Tags\Param;
+use phpDocumentor\Reflection\DocBlock\Tags\Return_;
use phpDocumentor\Reflection\DocBlock\Tags\See;
+use phpDocumentor\Reflection\PseudoTypes\ConstExpression;
+use phpDocumentor\Reflection\Types\Array_;
+use phpDocumentor\Reflection\Types\Integer;
+use phpDocumentor\Reflection\Types\Mixed_;
+use phpDocumentor\Reflection\Types\Self_;
+use phpDocumentor\Reflection\Types\String_;
+use phpDocumentor\Reflection\Types\Void_;
use PHPUnit\Framework\TestCase;
/**
@@ -83,7 +95,7 @@ DESCRIPTION;
str_replace(
PHP_EOL,
"\n",
- $descriptionText
+ $descriptionText
),
$description->render()
);
@@ -134,7 +146,7 @@ DESCRIPTION;
str_replace(
PHP_EOL,
"\n",
- <<<'DESCRIPTION'
+ <<<'DESCRIPTION'
You can escape the @-sign by surrounding it with braces, for example: @. And escape a closing brace within an
inline tag by adding an opening brace in front of it like this: }.
@@ -149,4 +161,111 @@ DESCRIPTION
$foundDescription
);
}
+
+ public function testMultilineTags(): void
+ {
+ $docCommment = <<<DOC
+/**
+ * This is an example of a summary.
+ *
+ * @param array<
+ * int,
+ * string
+ * > \$store
+ */
+DOC;
+ $factory = DocBlockFactory::createInstance();
+ $docblock = $factory->create($docCommment);
+
+ self::assertEquals(
+ [
+ new Param(
+ 'store',
+ new Array_(
+ new String_(),
+ new Integer()
+ ),
+ false,
+ new Description(''),
+ ),
+ ],
+ $docblock->getTags()
+ );
+
+ }
+
+ public function testMethodRegression(): void
+ {
+ $docCommment = <<<DOC
+/**
+ * This is an example of a summary.
+ *
+ * @method void setInteger(integer \$integer)
+ */
+DOC;
+ $factory = DocBlockFactory::createInstance();
+ $docblock = $factory->create($docCommment);
+
+ self::assertEquals(
+ [
+ new Method(
+ 'setInteger',
+ [],
+ new Void_(),
+ false,
+ new Description(''),
+ false,
+ [
+ new MethodParameter('integer', new Integer())
+ ]
+ ),
+ ],
+ $docblock->getTags()
+ );
+ }
+
+ public function testInvalidTypeParamResultsInInvalidTag(): void
+ {
+ $docCommment = '
+/**
+ * This is an example of a summary.
+ *
+ * @param array\Foo> $test
+ */
+';
+ $factory = DocBlockFactory::createInstance();
+ $docblock = $factory->create($docCommment);
+
+ self::assertEquals(
+ [
+ InvalidTag::create(
+ 'array\Foo> $test',
+ 'param',
+ )->withError(
+ new \InvalidArgumentException(
+ 'Could not find type in array\Foo> $test, please check for malformed notations')
+ ),
+ ],
+ $docblock->getTags()
+ );
+ }
+
+ public function testConstantReferenceTypes(): void
+ {
+ $docCommment = <<<DOC
+ /**
+ * @return self::STATUS_*
+ */
+DOC;
+
+ $factory = DocBlockFactory::createInstance();
+ $docblock = $factory->create($docCommment);
+
+ self::assertEquals(
+ [
+ new Return_(new ConstExpression(new Self_(), 'STATUS_*'), new Description('')),
+ ],
+ $docblock->getTags()
+ );
+ }
}
diff --git a/tests/integration/ReconstitutingADocBlockTest.php b/tests/integration/ReconstitutingADocBlockTest.php
index 02da4defc4812f606b743b1d1f6c45553432abf4..aef6598c9c7301e96f9025bafeef9e65f8feb055 100644
--- a/tests/integration/ReconstitutingADocBlockTest.php
+++ b/tests/integration/ReconstitutingADocBlockTest.php
@@ -14,6 +14,9 @@ declare(strict_types=1);
namespace phpDocumentor\Reflection;
use Mockery as m;
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Generic;
+use phpDocumentor\Reflection\Types\ContextFactory;
use PHPUnit\Framework\TestCase;
/**
@@ -40,4 +43,43 @@ class ReconstitutingADocBlockTest extends TestCase
$this->assertSame($docComment, $reconstitutedDocComment);
}
+
+
+ /**
+ * Method
+ *
+ * Method which contains a modulo sign (%) in its description.
+ *
+ * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic
+ * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag
+ * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter
+ *
+ * @covers ::__construct
+ * @covers ::render
+ * @covers ::__toString
+ */
+ public function testDescriptionCanContainPercent(): void
+ {
+ $factory = DocBlockFactory::createInstance();
+ $contextFactory = new ContextFactory();
+
+ $method = new \ReflectionMethod(self::class, 'testDescriptionCanContainPercent');
+
+ $docblock = $factory->create(
+ $method,
+ $contextFactory->createFromReflector($method->getDeclaringClass())
+ );
+
+ $tag1 = new Generic('JoinColumn', new Description('(name="column_id", referencedColumnName="id")'));
+ $tag2 = new Generic('JoinColumn', new Description('(name="column_id_2", referencedColumnName="id")'));
+
+ $tags = [
+ $tag1,
+ $tag2,
+ ];
+
+ $fixture = $docblock->getDescription();
+ $expected = 'Method which contains a modulo sign (%) in its description.';
+ $this->assertSame($expected, (string) $fixture);
+ }
}
diff --git a/tests/integration/TypedTagsTest.php b/tests/integration/TypedTagsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0f6d6516b2c2055c9adff410882fe13609209da
--- /dev/null
+++ b/tests/integration/TypedTagsTest.php
@@ -0,0 +1,194 @@
+<?php
+
+declare(strict_types=1);
+
+namespace integration;
+
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlock\Tags\Param;
+use phpDocumentor\Reflection\DocBlock\Tags\Var_;
+use phpDocumentor\Reflection\DocBlockFactory;
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\PseudoTypes\ArrayShape;
+use phpDocumentor\Reflection\PseudoTypes\ArrayShapeItem;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\Types\Array_;
+use phpDocumentor\Reflection\Types\Callable_;
+use phpDocumentor\Reflection\Types\CallableParameter;
+use phpDocumentor\Reflection\Types\Collection;
+use phpDocumentor\Reflection\Types\Integer;
+use phpDocumentor\Reflection\Types\Nullable;
+use phpDocumentor\Reflection\Types\Object_;
+use phpDocumentor\Reflection\Types\String_;
+use phpDocumentor\Reflection\Types\Void_;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @coversNothing
+ */
+final class TypedTagsTest extends TestCase
+{
+ /** @dataProvider typeProvider */
+ public function testParamFormats(string $type, Type $expectedType): void
+ {
+ $docblock = <<<DOCBLOCK
+/**
+ * @param $type \$param
+ */
+DOCBLOCK;
+
+ $factory = DocBlockFactory::createInstance();
+ $phpdoc = $factory->create($docblock);
+
+ $this->assertInstanceOf(Param::class, $phpdoc->getTags()[0]);
+ $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getType());
+ }
+
+ /** @dataProvider typeProvider */
+ public function testVarFormats(string $type, Type $expectedType): void
+ {
+ $docblock = <<<DOCBLOCK
+/**
+ * @var $type \$param
+ */
+DOCBLOCK;
+
+ $factory = DocBlockFactory::createInstance();
+ $phpdoc = $factory->create($docblock);
+
+ $this->assertInstanceOf(Var_::class, $phpdoc->getTags()[0]);
+ $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getType());
+ }
+
+ /** @dataProvider typeProvider */
+ public function testMethodFormats(string $type, Type $expectedType): void
+ {
+ $docblock = <<<DOCBLOCK
+/**
+ * @method $type setValue($type \$param)
+ */
+DOCBLOCK;
+
+ $factory = DocBlockFactory::createInstance();
+ $phpdoc = $factory->create($docblock);
+
+ $this->assertInstanceOf(Method::class, $phpdoc->getTags()[0]);
+ $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getReturnType());
+ $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getParameters()[0]->getType());
+ }
+
+ /** @dataProvider invalidFormatsProvider */
+ public function testInvalidParam(string $type): void
+ {
+ $docblock = <<<DOCBLOCK
+/**
+ * @param $type \$param
+ */
+DOCBLOCK;
+
+ $factory = DocBlockFactory::createInstance();
+ $phpdoc = $factory->create($docblock);
+
+ $this->assertInstanceOf(InvalidTag::class, $phpdoc->getTags()[0]);
+ $this->assertEquals("$type \$param", (string) $phpdoc->getTags()[0]);
+
+ }
+
+ /** @dataProvider invalidFormatsProvider */
+ public function testInvalidMethod(string $type): void
+ {
+ $docblock = <<<DOCBLOCK
+/**
+ * @method $type setValue($type \$param)
+ */
+DOCBLOCK;
+
+ $factory = DocBlockFactory::createInstance();
+ $phpdoc = $factory->create($docblock);
+
+ $this->assertInstanceOf(InvalidTag::class, $phpdoc->getTags()[0]);
+ $this->assertEquals("$type setValue($type \$param)", (string) $phpdoc->getTags()[0]);
+
+ }
+
+ public static function typeProvider(): array
+ {
+ return [
+ [
+ 'int',
+ new Integer(),
+ ],
+ [
+ 'integer',
+ new Integer(),
+ ],
+ [
+ 'string',
+ new String_(),
+ ],
+ [
+ 'T',
+ new Object_(new Fqsen('\\T')),
+ ],
+ [
+ 'array',
+ new Array_(),
+ ],
+ [
+ 'int[]',
+ new Array_(new Integer()),
+ ],
+ [
+ 'int[][]',
+ new Array_(new Array_(new Integer())),
+ ],
+ [
+ 'array<int, string>',
+ new Array_(new String_(), new Integer()),
+ ],
+ [
+ 'array{
+ foo: int,
+ bar?: ?string
+ }',
+ new ArrayShape(
+ new ArrayShapeItem('foo', new Integer(), false),
+ new ArrayShapeItem('bar', new Nullable(new String_()), true),
+
+ )
+ ],
+ [
+ 'Collection<int, string>',
+ new Collection(new Fqsen('\\Collection'), new String_(), new Integer()),
+ ],
+ [
+ 'Collection<TKey, Tvalue>',
+ new Collection(new Fqsen('\\Collection'), new Object_(new Fqsen('\\Tvalue')), new Object_(new Fqsen('\\TKey'))),
+ ],
+ [
+ 'Collection<Tvalue>',
+ new Collection(new Fqsen('\\Collection'), new Object_(new Fqsen('\\Tvalue'))),
+ ],
+ [
+ 'callable(int $foo, string $bar): void',
+ new Callable_([new CallableParameter(new Integer(), 'foo'), new CallableParameter(new String_(), 'bar')], new Void_()),
+ ],
+ ];
+ }
+
+ public static function invalidFormatsProvider(): \Generator
+ {
+ yield from [
+ 'invalid collection' => ['self<Tvalue>'],
+ ];
+
+ foreach (['<', '{', '('] as $badChar) {
+ yield "invalid format open $badChar" => ["array$badChar\\fooo"];
+ }
+
+ foreach (['>', '}', ')'] as $badChar) {
+ yield "invalid format close $badChar" => ["array\\fooo$badChar"];
+ }
+ }
+}
diff --git a/tests/unit/Assets/CustomTagFactory.php b/tests/unit/Assets/CustomTagFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..df4a3f6996dfd35d5d6f20b9f251e99f2c11a091
--- /dev/null
+++ b/tests/unit/Assets/CustomTagFactory.php
@@ -0,0 +1,31 @@
+<?php
+/*
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ *
+ */
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\Assets;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
+use phpDocumentor\Reflection\DocBlock\Tags\Generic;
+use phpDocumentor\Reflection\Types\Context;
+
+class CustomTagFactory implements Factory
+{
+ public $class;
+
+ public function create(string $tagLine, ?Context $context = null, CustomServiceClass $class = null): Tag
+ {
+ $this->class = $class;
+
+ return new Generic('custom');
+ }
+}
diff --git a/tests/unit/DocBlock/DescriptionTest.php b/tests/unit/DocBlock/DescriptionTest.php
index b4ddb492d553ca0e5cbab73600e2f907511abadf..e1ddbd6c87b360af5c97958d96ce9d00340ddfe1 100644
--- a/tests/unit/DocBlock/DescriptionTest.php
+++ b/tests/unit/DocBlock/DescriptionTest.php
@@ -142,4 +142,31 @@ class DescriptionTest extends TestCase
. 'inverseJoinColumns={@JoinColumn (name="column_id_2", referencedColumnName="id")})';
$this->assertSame($expected, (string) $fixture);
}
+
+ /**
+ * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter
+ *
+ * @covers ::__construct
+ * @covers ::render
+ * @covers ::__toString
+ */
+ public function testDescriptionWithEscapedCharactersAndNoTagsCanBeCastToString(): void
+ {
+ //% chars are escaped in \phpDocumentor\Reflection\DocBlock\DescriptionFactory::create
+ $body = <<<'EOT'
+ {%% for user in users %%}
+ {{ user.name }}
+ {%% endfor %%}';
+ EOT;
+
+ $expected = <<<'EOT'
+ {% for user in users %}
+ {{ user.name }}
+ {% endfor %}';
+ EOT;
+
+ $fixture = new Description($body, []);
+
+ $this->assertSame($expected, (string) $fixture);
+ }
}
diff --git a/tests/unit/DocBlock/ExampleFinderTest.php b/tests/unit/DocBlock/ExampleFinderTest.php
index c45337cb90dd18e034c722a54d7f68bc3ddf42b6..6bc17ec43c9154cee2a7266817bd1f0c5df58ab1 100644
--- a/tests/unit/DocBlock/ExampleFinderTest.php
+++ b/tests/unit/DocBlock/ExampleFinderTest.php
@@ -14,8 +14,7 @@ use PHPUnit\Framework\TestCase;
*/
class ExampleFinderTest extends TestCase
{
- /** @var ExampleFinder */
- private $fixture;
+ private ExampleFinder $fixture;
/**
* Call Mockery::close after each test.
diff --git a/tests/unit/DocBlock/StandardTagFactoryTest.php b/tests/unit/DocBlock/StandardTagFactoryTest.php
index 2e380d9186c91b73efe6db8a6e6b787360d3ec57..5a954d5247da4aeb42f0e7cd573f0d3c79331dc1 100644
--- a/tests/unit/DocBlock/StandardTagFactoryTest.php
+++ b/tests/unit/DocBlock/StandardTagFactoryTest.php
@@ -18,6 +18,7 @@ use Mockery as m;
use phpDocumentor\Reflection\Assets\CustomParam;
use phpDocumentor\Reflection\Assets\CustomServiceClass;
use phpDocumentor\Reflection\Assets\CustomServiceInterface;
+use phpDocumentor\Reflection\Assets\CustomTagFactory;
use phpDocumentor\Reflection\DocBlock\Tags\Author;
use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter;
@@ -225,6 +226,22 @@ class StandardTagFactoryTest extends TestCase
$this->assertSame('author', $tag->getName());
}
+ public function testTagWithHandlerObject(): void
+ {
+ $fqsenResolver = new FqsenResolver();
+
+ $customFactory = new CustomTagFactory();
+ $injectedClass = new CustomServiceClass();
+
+ $tagFactory = new StandardTagFactory($fqsenResolver);
+ $tagFactory->addService($injectedClass);
+ $tagFactory->registerTagHandler('param', $customFactory);
+ $tag = $tagFactory->create('@param foo');
+
+ self::assertSame('custom', $tag->getName());
+ self::assertSame($injectedClass, $customFactory->class);
+ }
+
/**
* @uses \phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService
* @uses \phpDocumentor\Reflection\DocBlock\Tags\Author
diff --git a/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..59f148db1c0d269df1eb8f03b1c88f98616498b9
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php
@@ -0,0 +1,163 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlock\Tags\MethodParameter;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\Integer;
+use phpDocumentor\Reflection\Types\Mixed_;
+use phpDocumentor\Reflection\Types\String_;
+use phpDocumentor\Reflection\Types\Void_;
+
+final class MethodFactoryTest extends TagFactoryTestCase
+{
+ /**
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory::__construct
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory::create
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory::supports
+ * @dataProvider tagProvider
+ */
+ public function testIsCreated(string $tagLine, Method $tag): void
+ {
+ $ast = $this->parseTag($tagLine);
+ $factory = new MethodFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+ $context = new Context('global');
+
+ self::assertTrue($factory->supports($ast, $context));
+ self::assertEquals(
+ $tag,
+ $factory->create($ast, $context)
+ );
+ }
+
+ /** @return array<array<string|Method>> */
+ public function tagProvider(): array
+ {
+ return [
+ [
+ '@method static string myMethod()',
+ new Method(
+ 'myMethod',
+ [],
+ new String_(),
+ true,
+ new Description(''),
+ false,
+ []
+ ),
+ ],
+ [
+ '@method string myMethod()',
+ new Method(
+ 'myMethod',
+ [],
+ new String_(),
+ false,
+ new Description(''),
+ false,
+ []
+ ),
+ ],
+ [
+ '@method myMethod()',
+ new Method(
+ 'myMethod',
+ [],
+ new Void_(),
+ false,
+ new Description(''),
+ false,
+ []
+ ),
+ ],
+ [
+ '@method myMethod($a)',
+ new Method(
+ 'myMethod',
+ [],
+ new Void_(),
+ false,
+ new Description(''),
+ false,
+ [new MethodParameter('a', new Mixed_())]
+ ),
+ ],
+ [
+ '@method void setInteger(integer $integer)',
+ new Method(
+ 'setInteger',
+ [],
+ new Void_(),
+ false,
+ new Description(''),
+ false,
+ [new MethodParameter('integer', new Integer())]
+ ),
+ ],
+ [
+ '@method myMethod($a = 1)',
+ new Method(
+ 'myMethod',
+ [],
+ new Void_(),
+ false,
+ new Description(''),
+ false,
+ [new MethodParameter('a', new Mixed_(), false, false, '1')]
+ ),
+ ],
+ [
+ '@method myMethod(int $a = 1)',
+ new Method(
+ 'myMethod',
+ [],
+ new Void_(),
+ false,
+ new Description(''),
+ false,
+ [new MethodParameter('a', new Integer(), false, false, '1')]
+ ),
+ ],
+ [
+ '@method myMethod(int ...$a)',
+ new Method(
+ 'myMethod',
+ [],
+ new Void_(),
+ false,
+ new Description(''),
+ false,
+ [new MethodParameter('a', new Integer(), false, true)]
+ ),
+ ],
+ [
+ '@method myMethod(int &$a, string $b)',
+ new Method(
+ 'myMethod',
+ [],
+ new Void_(),
+ false,
+ new Description(''),
+ false,
+ [
+ new MethodParameter('a', new Integer(), true, false),
+ new MethodParameter('b', new String_(), false, false),
+ ]
+ ),
+ ],
+ ];
+ }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5c50181c75848e4a89a63a5a623597049971b436
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php
@@ -0,0 +1,133 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Param;
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\PseudoTypes\IntegerValue;
+use phpDocumentor\Reflection\PseudoTypes\StringValue;
+use phpDocumentor\Reflection\Types\Compound;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\Integer;
+use phpDocumentor\Reflection\Types\Mixed_;
+use phpDocumentor\Reflection\Types\Object_;
+use phpDocumentor\Reflection\Types\String_;
+
+final class ParamFactoryTest extends TagFactoryTestCase
+{
+ /**
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::__construct
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::create
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::supports
+ * @dataProvider paramInputProvider
+ */
+ public function testParamIsCreated(string $input, Tag $expected): void
+ {
+ $ast = $this->parseTag($input);
+ $factory = new ParamFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+ $context = new Context('global');
+
+ self::assertTrue($factory->supports($ast, $context));
+ self::assertEquals(
+ $expected,
+ $factory->create($ast, $context)
+ );
+ }
+
+ /**
+ * @return array<array-key, string|Param>
+ */
+ public function paramInputProvider(): array
+ {
+ return [
+ [
+ '@param string $var',
+ new Param(
+ 'var',
+ new String_(),
+ false,
+ new Description(''),
+ false
+ ),
+ ],
+ [
+ '@param $param8 Description 4',
+ new Param(
+ 'param8',
+ new Mixed_(),
+ false,
+ new Description('Description 4'),
+ false
+ ),
+ ],
+ [
+ '@param $param9',
+ new Param(
+ 'param9',
+ new Mixed_(),
+ false,
+ new Description(''),
+ false
+ ),
+ ],
+ [
+ '@param int My Description',
+ new Param(
+ null,
+ new Integer(),
+ false,
+ new Description('My Description'),
+ false
+ ),
+ ],
+ [
+ '@param \'GET\'|SomeClass $arg My Description',
+ new Param(
+ 'arg',
+ new Compound(
+ [
+ new StringValue('GET'),
+ new Object_(new Fqsen('\SomeClass')),
+ ]
+ ),
+ false,
+ new Description('My Description'),
+ false
+ ),
+ ],
+ [
+ '@param 8|SomeClass $arg My Description',
+ new Param(
+ 'arg',
+ new Compound(
+ [
+ new IntegerValue(8),
+ new Object_(new Fqsen('\SomeClass')),
+ ]
+ ),
+ false,
+ new Description('My Description'),
+ false
+ ),
+ ],
+ [
+ '@param array[\Illuminate\Notifications\Channels\Notification] $notification',
+ InvalidTag::create('array[\Illuminate\Notifications\Channels\Notification] $notification', 'param'),
+ ],
+ ];
+ }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..738275cbc831beecb20501dc17939de11310c66e
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Property;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class PropertyFactoryTest extends TagFactoryTestCase
+{
+ /**
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory::__construct
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory::create
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory::supports
+ */
+ public function testParamIsCreated(): void
+ {
+ $ast = $this->parseTag('@property string $var');
+ $factory = new PropertyFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+ $context = new Context('global');
+
+ self::assertTrue($factory->supports($ast, $context));
+ self::assertEquals(
+ new Property(
+ 'var',
+ new String_(),
+ new Description('')
+ ),
+ $factory->create($ast, $context)
+ );
+ }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..40fd1226854e12c6f422291c1056a4136cec3978
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\PropertyRead;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class PropertyReadFactoryTest extends TagFactoryTestCase
+{
+ /**
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory::__construct
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory::create
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory::supports
+ */
+ public function testParamIsCreated(): void
+ {
+ $ast = $this->parseTag('@property-read string $var');
+ $factory = new PropertyReadFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+ $context = new Context('global');
+
+ self::assertTrue($factory->supports($ast, $context));
+ self::assertEquals(
+ new PropertyRead(
+ 'var',
+ new String_(),
+ new Description('')
+ ),
+ $factory->create($ast, $context)
+ );
+ }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f3e239d1729dcfa6f879f0d524b7338697ad02c
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class PropertyWriteFactoryTest extends TagFactoryTestCase
+{
+ /**
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory::__construct
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory::create
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory::supports
+ */
+ public function testParamIsCreated(): void
+ {
+ $ast = $this->parseTag('@property-write string $var');
+ $factory = new PropertyWriteFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+ $context = new Context('global');
+
+ self::assertTrue($factory->supports($ast, $context));
+ self::assertEquals(
+ new PropertyWrite(
+ 'var',
+ new String_(),
+ new Description('')
+ ),
+ $factory->create($ast, $context)
+ );
+ }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b664cc34c667575d804c42151afaca60cfe15f9
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Return_;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class ReturnFactoryTest extends TagFactoryTestCase
+{
+ /**
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory::__construct
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory::create
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory::supports
+ */
+ public function testParamIsCreated(): void
+ {
+ $ast = $this->parseTag('@return string');
+ $factory = new ReturnFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+ $context = new Context('global');
+
+ self::assertTrue($factory->supports($ast, $context));
+ self::assertEquals(
+ new Return_(
+ new String_(),
+ new Description('')
+ ),
+ $factory->create($ast, $context)
+ );
+ }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php b/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec9056541747466d86834c3ed5acad55d3e9b135
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php
@@ -0,0 +1,62 @@
+<?php
+/*
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ *
+ */
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use Mockery as m;
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\TypeResolver;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Lexer\Lexer;
+use PHPStan\PhpDocParser\Parser\ConstExprParser;
+use PHPStan\PhpDocParser\Parser\PhpDocParser;
+use PHPStan\PhpDocParser\Parser\TokenIterator;
+use PHPStan\PhpDocParser\Parser\TypeParser;
+use PHPUnit\Framework\TestCase;
+
+abstract class TagFactoryTestCase extends TestCase
+{
+ public function parseTag(string $tag): PhpDocTagNode
+ {
+ $lexer = new Lexer();
+ $tokens = $lexer->tokenize($tag);
+ $constParser = new ConstExprParser();
+
+ return (new PhpDocParser(new TypeParser($constParser), $constParser))->parseTag(new TokenIterator($tokens));
+ }
+
+ public function giveTypeResolver(): TypeResolver
+ {
+ return new TypeResolver(new FqsenResolver());
+ }
+
+ public function givenDescriptionFactory(): DescriptionFactory
+ {
+ $factory = m::mock(DescriptionFactory::class);
+ $factory->shouldReceive('create')->andReturnUsing(static fn ($args) => new Description($args));
+
+ return $factory;
+ }
+
+ /**
+ * Call Mockery::close after each test.
+ *
+ * @after
+ */
+ public function closeMockery(): void
+ {
+ m::close();
+ }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..61f22dfdd4a1b583a81fd3bef6d824bdd97a8a1a
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Var_;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class VarFactoryTest extends TagFactoryTestCase
+{
+ /**
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::__construct
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::create
+ * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::supports
+ */
+ public function testVarIsCreated(): void
+ {
+ $ast = $this->parseTag('@var string $var');
+ $factory = new VarFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+ $context = new Context('global');
+
+ self::assertTrue($factory->supports($ast, $context));
+ self::assertEquals(
+ new Var_(
+ 'var',
+ new String_(),
+ new Description('')
+ ),
+ $factory->create($ast, $context)
+ );
+ }
+}
diff --git a/tests/unit/DocBlock/Tags/MethodTest.php b/tests/unit/DocBlock/Tags/MethodTest.php
index 1f068dbb10d07bd85fe7f513b43057b95e673920..dfc0032bc0e807068eab7d3052cc9f511c9de7f1 100644
--- a/tests/unit/DocBlock/Tags/MethodTest.php
+++ b/tests/unit/DocBlock/Tags/MethodTest.php
@@ -339,6 +339,7 @@ class MethodTest extends TestCase
$this->assertEquals($expectedArguments, $fixture->getArguments());
$this->assertInstanceOf(Void_::class, $fixture->getReturnType());
$this->assertSame($description, $fixture->getDescription());
+ $this->assertFalse($fixture->returnsReference());
}
/**
@@ -370,6 +371,7 @@ class MethodTest extends TestCase
$this->assertSame('static $this myMethod()', (string) $fixture);
$this->assertSame('myMethod', $fixture->getMethodName());
$this->assertInstanceOf(This::class, $fixture->getReturnType());
+ $this->assertFalse($fixture->returnsReference());
}
/**
@@ -401,6 +403,7 @@ class MethodTest extends TestCase
$this->assertSame('void myVeryLongMethodName(mixed $node)', (string) $fixture);
$this->assertSame('myVeryLongMethodName', $fixture->getMethodName());
$this->assertInstanceOf(Void_::class, $fixture->getReturnType());
+ $this->assertFalse($fixture->returnsReference());
}
/**
@@ -542,6 +545,7 @@ class MethodTest extends TestCase
$this->assertEquals([], $fixture->getArguments());
$this->assertInstanceOf(Void_::class, $fixture->getReturnType());
$this->assertSame($description, $fixture->getDescription());
+ $this->assertFalse($fixture->returnsReference());
}
/**
@@ -578,6 +582,7 @@ class MethodTest extends TestCase
$this->assertEquals([], $fixture->getArguments());
$this->assertInstanceOf(Void_::class, $fixture->getReturnType());
$this->assertSame($description, $fixture->getDescription());
+ $this->assertFalse($fixture->returnsReference());
}
/**
@@ -613,6 +618,7 @@ class MethodTest extends TestCase
$this->assertEquals([], $fixture->getArguments());
$this->assertInstanceOf(Void_::class, $fixture->getReturnType());
$this->assertSame($description, $fixture->getDescription());
+ $this->assertFalse($fixture->returnsReference());
}
/**
@@ -656,4 +662,40 @@ class MethodTest extends TestCase
$fixture->getReturnType()
);
}
+
+ /**
+ * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::<public>
+ * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
+ * @uses \phpDocumentor\Reflection\TypeResolver
+ * @uses \phpDocumentor\Reflection\DocBlock\Description
+ * @uses \phpDocumentor\Reflection\Fqsen
+ * @uses \phpDocumentor\Reflection\Types\Context
+ * @uses \phpDocumentor\Reflection\Types\String_
+ *
+ * @covers ::create
+ */
+ public function testCreateWithReference(): void
+ {
+ $descriptionFactory = m::mock(DescriptionFactory::class);
+ $resolver = new TypeResolver();
+ $context = new Context('');
+
+ $description = new Description('');
+
+ $descriptionFactory->shouldReceive('create')->with('', $context)->andReturn($description);
+
+ $fixture = Method::create(
+ 'string &myMethod()',
+ $resolver,
+ $descriptionFactory,
+ $context
+ );
+
+ $this->assertSame('string &myMethod()', (string) $fixture);
+ $this->assertSame('myMethod', $fixture->getMethodName());
+ $this->assertEquals([], $fixture->getArguments());
+ $this->assertInstanceOf(String_::class, $fixture->getReturnType());
+ $this->assertSame($description, $fixture->getDescription());
+ $this->assertTrue($fixture->returnsReference());
+ }
}