From 47d423decd0fd98218cd2ad971bb7c116a3f6397 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 09:15:09 +1200 Subject: [PATCH 01/11] Added PHPCS --- .github/workflows/phpcs.yml | 43 +++++++++++++++++++++++++++++++++++++ phpcs.xml | 36 +++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 .github/workflows/phpcs.yml create mode 100644 phpcs.xml diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml new file mode 100644 index 0000000..0eb4bf3 --- /dev/null +++ b/.github/workflows/phpcs.yml @@ -0,0 +1,43 @@ +name: PHPCS check + +on: pull_request + +permissions: + actions: read + checks: read + contents: read + deployments: none + issues: read + packages: none + pull-requests: read + repository-projects: none + security-events: none + statuses: read + +jobs: + phpcs: + name: PHPCS + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + with: + lfs: false + persist-credentials: false + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + tools: cs2pr + - name: Install dependencies + run: + composer init --name=matomo/openapidocs --quiet; + composer --no-plugins config allow-plugins.dealerdirect/phpcodesniffer-composer-installer true -n; + composer config repositories.matomo-coding-standards vcs https://github.com/matomo-org/matomo-coding-standards -n; + composer require matomo-org/matomo-coding-standards:dev-master; + composer install --dev --prefer-dist --no-progress --no-suggest + - name: Check PHP code styles + id: phpcs + run: ./vendor/bin/phpcs --report-full --standard=phpcs.xml --report-checkstyle=./phpcs-report.xml + - name: Show PHPCS results in PR + if: ${{ always() && steps.phpcs.outcome == 'failure' }} + run: cs2pr ./phpcs-report.xml --prepend-filename \ No newline at end of file diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..74a69ed --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,36 @@ + + + + Matomo Coding Standard for OpenApiDocs plugin + + + + . + + tests/javascript/* + */vendor/* + + + + + + + + tests/* + + + + + Updates/* + + + + + tests/* + + + + + tests/* + + \ No newline at end of file From def9376c6b1863e5bae14c75b76cf1b253a57e20 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 09:25:59 +1200 Subject: [PATCH 02/11] Fix code style issues --- Annotations/AnnotationGenerator.php | 9 ++++++--- Annotations/GlobalApiComponents.php | 3 +-- Renderer/Yaml.php | 3 +-- Specs/SpecGenerator.php | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Annotations/AnnotationGenerator.php b/Annotations/AnnotationGenerator.php index 85d071a..86cdfa6 100644 --- a/Annotations/AnnotationGenerator.php +++ b/Annotations/AnnotationGenerator.php @@ -92,8 +92,10 @@ protected function buildAnnotationForMethod(array $rules, string $pluginName, \R { $existing = $reflectionMethod->getDocComment(); // Skip methods which have been marked as internal or auto annotations disabled - if ($existing !== false && (stripos($existing, 'OA-AUTO:OFF') !== false - || stripos($existing, '@internal') !== false)) { + if ( + $existing !== false && (stripos($existing, 'OA-AUTO:OFF') !== false + || stripos($existing, '@internal') !== false) + ) { return []; } @@ -114,7 +116,8 @@ protected function buildAnnotationForMethod(array $rules, string $pluginName, \R return $this->compileOperationLines($path, $opId, $pluginName, $methodName, $params, $responses, $isPost); } - protected function getParamInfoFromDocBlock(string $docBlock): array { + protected function getParamInfoFromDocBlock(string $docBlock): array + { $lexer = new Lexer(); $tokens = $lexer->tokenize($docBlock); $expressionParser = new ConstExprParser(); diff --git a/Annotations/GlobalApiComponents.php b/Annotations/GlobalApiComponents.php index ccdf110..af76b57 100644 --- a/Annotations/GlobalApiComponents.php +++ b/Annotations/GlobalApiComponents.php @@ -345,5 +345,4 @@ */ class GlobalApiComponents { - -} \ No newline at end of file +} diff --git a/Renderer/Yaml.php b/Renderer/Yaml.php index 394eba7..06c4996 100644 --- a/Renderer/Yaml.php +++ b/Renderer/Yaml.php @@ -11,7 +11,6 @@ use Piwik\API\ApiRenderer; use Piwik\Common; -use Piwik\DataTable\Renderer; use Symfony\Component\Yaml\Yaml as SymfonyYaml; class Yaml extends ApiRenderer @@ -45,4 +44,4 @@ public function renderDataTable($dataTable) { return $dataTable->getFirstRow()->getColumn(0); } -} \ No newline at end of file +} diff --git a/Specs/SpecGenerator.php b/Specs/SpecGenerator.php index 797f13a..6dcea6d 100644 --- a/Specs/SpecGenerator.php +++ b/Specs/SpecGenerator.php @@ -23,7 +23,7 @@ class SpecGenerator public function __construct() { // Set the constant for the current instance's URL - if(!defined('LOCAL_MATOMO_SERVER_URL')) { + if (!defined('LOCAL_MATOMO_SERVER_URL')) { define('LOCAL_MATOMO_SERVER_URL', SettingsPiwik::getPiwikUrl()); } } From 75b5b9efdc37da4aec5fc543d59b7d04a63bf8af Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 09:56:36 +1200 Subject: [PATCH 03/11] Adding PHPStan --- .git-hooks-matomo/pre-push | 107 ++++++++++++++++++++++++++++++++++ .github/workflows/phpstan.yml | 81 +++++++++++++++++++++++++ phpstan.neon | 21 +++++++ 3 files changed, 209 insertions(+) create mode 100755 .git-hooks-matomo/pre-push create mode 100644 .github/workflows/phpstan.yml create mode 100644 phpstan.neon diff --git a/.git-hooks-matomo/pre-push b/.git-hooks-matomo/pre-push new file mode 100755 index 0000000..61d26af --- /dev/null +++ b/.git-hooks-matomo/pre-push @@ -0,0 +1,107 @@ +#!/bin/bash + +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# + + + +### Check we're running in the context of a plugin and get helpful dir variables ### + +REPO_DIR="$(git rev-parse --show-toplevel)" +echo "Running pre-commit hook in repo: $REPO_DIR" + +if [[ "$REPO_DIR" =~ /plugins/(.*) ]]; then + PLUGIN_PATH="plugins/${BASH_REMATCH[1]}/" +else + echo "Not a plugin, not running any further checks" + exit 1 +fi +MATOMO_DIR=$(echo "$REPO_DIR" | sed -E 's|/plugins/.*$||') + + + +### Figure out how to run PHPStan - ddev or not. ### + +COMMAND="" +# Use local PHP if setup +if command -v php >/dev/null 2>&1; then + if [ -f "${MATOMO_DIR}/vendor/bin/phpstan" ]; then + COMMAND="${MATOMO_DIR}/vendor/bin/phpstan" + PLUGIN_PATH='' + fi +fi +# Use ddev if setup (overridding local setup) +if command -v ddev >/dev/null 2>&1; then + if [ -d "$MATOMO_DIR/.ddev" ]; then + cd "$MATOMO_DIR" || exit 1 + if ddev status 2>&1 > /dev/null; then + COMMAND="ddev exec phpstan" + fi + fi +fi +# If no command, exit +if [[ -z "$COMMAND" ]]; then + echo "No way to run phpstan found." + exit 1 +fi + + + +# Basic setup +cd "$REPO_DIR" +STATUS=0 + + + + +### Run PHPStan on newly created files. ### + +PHPSTAN_CREATED_CONFIG=phpstan/phpstan.created.neon +MAIN_BRANCH='5.x-dev' +if [[ -f "$PHPSTAN_CREATED_CONFIG" ]]; then + CHANGED_FILES=$(git diff --name-only ${MAIN_BRANCH} --diff-filter=A | grep '\.php$' || true) + if [ -z "$CHANGED_FILES" ]; then + echo "No created PHP files" + else + echo "Running PHPstan at a very high level on new files" + CHANGED_FILES=`echo "$CHANGED_FILES" | sed -e 's/^\(.*\)$/"\1"/' | xargs -I{} echo "${PLUGIN_PATH}{}"` + echo "$CHANGED_FILES" | xargs $COMMAND analyse -c ${PLUGIN_PATH}${PHPSTAN_CREATED_CONFIG} || STATUS=1 + fi +fi + + + +### Run PHPStan on modified files. ### +PHPSTAN_MODIFIED_CONFIG=phpstan/phpstan.modified.neon +if [[ -f "$PHPSTAN_MODIFIED_CONFIG" ]]; then + CHANGED_FILES=$(git diff --name-only ${MAIN_BRANCH} --diff-filter=CM | grep '\.php$' || true) + if [ -z "$CHANGED_FILES" ]; then + echo "No changed PHP files" + else + echo "Running PHPstan on modified files" + CHANGED_FILES=`echo "$CHANGED_FILES" | sed -e 's/^\(.*\)$/"\1"/' | xargs -I{} echo "${PLUGIN_PATH}{}"` + echo "$CHANGED_FILES" | xargs $COMMAND analyse -c ${PLUGIN_PATH}${PHPSTAN_MODIFIED_CONFIG} || STATUS=1 + fi +fi + +# Don't bother running the full check, as we check changes files already, and +# can assume that the unchanged files don't need rechecking. +# +# Github will check this anyway. +# +# PHPSTAN_BASE_CONFIG=phpstan.neon +# if [[ -f "$PHPSTAN_BASE_CONFIG" ]]; then +# echo "Running PHPstan at a base level on all plugin files" +# $COMMAND analyse -c ${PLUGIN_PATH}/${PHPSTAN_BASE_CONFIG} || STATUS=1 +# fi + +exit $STATUS diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml new file mode 100644 index 0000000..4ab4683 --- /dev/null +++ b/.github/workflows/phpstan.yml @@ -0,0 +1,81 @@ +name: PHPStan check + +on: pull_request + +permissions: + actions: read + checks: read + contents: read + deployments: none + issues: read + packages: none + pull-requests: read + repository-projects: none + security-events: none + statuses: read + +env: + PLUGIN_NAME: OpenApiDocs + +jobs: + phpstan: + name: PHPStan + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + lfs: false + persist-credentials: false + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.2' + + - name: Check out github-action-tests repository + uses: actions/checkout@v4 + with: + repository: matomo-org/github-action-tests + ref: main + path: github-action-tests + + - name: checkout matomo for plugin builds + shell: bash + run: ${{ github.workspace }}/github-action-tests/scripts/bash/checkout_matomo.sh + env: + PLUGIN_NAME: ${{ env.PLUGIN_NAME }} + WORKSPACE: ${{ github.workspace }} + ACTION_PATH: ${{ github.workspace }}/github-action-tests + MATOMO_TEST_TARGET: maximum_supported_matomo + + - name: prepare setup + shell: bash + run: | + cd ${{ github.workspace }}/matomo + echo -e "composer install" + composer install --ignore-platform-reqs + - name: checkout additional plugins + if: ${{ env.DEPENDENT_PLUGINS != '' }} + shell: bash + working-directory: ${{ github.workspace }}/matomo + run: ${{ github.workspace }}/github-action-tests/scripts/bash/checkout_dependent_plugins.sh + + env: + GITHUB_USER_TOKEN: ${{ secrets.TESTS_ACCESS_TOKEN || secrets.GITHUB_TOKEN }} + + - name: "Restore result cache" + uses: actions/cache/restore@v4 + with: + path: /tmp/phpstan # same as in phpstan.neon + key: "phpstan-result-cache-${{ github.run_id }}" + restore-keys: | + phpstan-result-cache- + - name: PHPStan whole repo + id: phpstan-all + run: cd ${{ github.workspace }}/matomo && composer run phpstan -- -vvv -c plugins/${{ env.PLUGIN_NAME }}/phpstan.neon + + - name: "Save result cache" + uses: actions/cache/save@v4 + if: ${{ !cancelled() }} + with: + path: /tmp/phpstan # same as in phpstan.neon + key: "phpstan-result-cache-${{ github.run_id }}" \ No newline at end of file diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..b5ec903 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,21 @@ +parameters: + level: 5 + phpVersion: 70200 + tmpDir: /tmp/phpstan/OpenApiDocs/main + paths: + - . + excludePaths: + - tests/* + - github-action-tests + bootstrapFiles: + - ../../bootstrap-phpstan.php + universalObjectCratesClasses: + - Piwik\Config + - Piwik\View + - Piwik\ViewDataTable\Config + scanDirectories: + # ../../ does not actually seem to give us anything + # that ../plugins/ does not, but including it for + # completeness. It does not seem to slow down performance. + - . + From f2ba1a99343caac5a94acbd3a20bd123843ffa8d Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 10:15:02 +1200 Subject: [PATCH 04/11] Add test YML --- .github/workflows/matomo-tests.yml | 58 ++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/matomo-tests.yml diff --git a/.github/workflows/matomo-tests.yml b/.github/workflows/matomo-tests.yml new file mode 100644 index 0000000..6b8dd16 --- /dev/null +++ b/.github/workflows/matomo-tests.yml @@ -0,0 +1,58 @@ +# Action for running tests +# This file has been automatically created. +# To recreate it you can run this command +# ./console generate:test-action --plugin="OpenApiDocs" --php-versions="7.2,8.4" --schedule-cron="0 19 * * 6" + +name: Plugin OpenApiDocs Tests + +on: + pull_request: + types: [opened, synchronize] + push: + branches: + - '**.x-dev' + workflow_dispatch: + schedule: + - cron: "0 19 * * 6" + +permissions: + actions: read + checks: none + contents: read + deployments: none + issues: read + packages: none + pull-requests: read + repository-projects: none + security-events: none + statuses: none + +concurrency: + group: php-${{ github.ref }} + cancel-in-progress: true + +jobs: + PluginTests: + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + php: [ '7.2', '8.4' ] + target: ['minimum_required_matomo', 'maximum_supported_matomo'] + steps: + - uses: actions/checkout@v3 + with: + lfs: true + persist-credentials: false + - name: Install package ripgrep + run: sudo apt-get install ripgrep + - name: Run tests + uses: matomo-org/github-action-tests@main + with: + plugin-name: 'OpenApiDocs' + php-version: ${{ matrix.php }} + test-type: 'PluginTests' + matomo-test-branch: ${{ matrix.target }} + redis-service: true + artifacts-pass: ${{ secrets.ARTIFACTS_PASS }} + upload-artifacts: ${{ matrix.php == '7.2' && matrix.target == 'maximum_supported_matomo' }} \ No newline at end of file From 083a52335e841e0c026db26e2fb6d7a962dca5ca Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 11:10:16 +1200 Subject: [PATCH 05/11] Add unit test case --- Annotations/AnnotationGenerator.php | 6 ++- tests/Unit/AnnotationGeneratorTest.php | 70 ++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tests/Unit/AnnotationGeneratorTest.php diff --git a/Annotations/AnnotationGenerator.php b/Annotations/AnnotationGenerator.php index 86cdfa6..7ee2e5b 100644 --- a/Annotations/AnnotationGenerator.php +++ b/Annotations/AnnotationGenerator.php @@ -213,14 +213,18 @@ protected function determineParameters(array $rules, string $plugin, string $met * @param string $type The PHP type from the method signature or doc-block * @return string The normalised Data Type to be used in the swagger-php annotation */ - protected function getOpenApiTypeFromPhpType(string $type): string + public function getOpenApiTypeFromPhpType(string $type): string { // TODO - Is there a good way to handle object type or should that always be ref? // TODO - Eventually handle the Data Type Formats: https://spec.openapis.org/oas/v3.1.1.html#data-type-format switch (strtolower($type)) { case 'array': + case '[]': case 'int[]': case 'string[]': + case 'bool[]': + case 'float[]': + case 'double[]': $type = 'array'; break; case 'int': diff --git a/tests/Unit/AnnotationGeneratorTest.php b/tests/Unit/AnnotationGeneratorTest.php new file mode 100644 index 0000000..22beaf4 --- /dev/null +++ b/tests/Unit/AnnotationGeneratorTest.php @@ -0,0 +1,70 @@ +annotationGenerator = new AnnotationGenerator(new DocumentationGenerator()); + } + + /** + * @dataProvider getTestDataForGetOpenApiTypeFromPhpType + * + * @param string $type + * @param string $expected + * @return void + */ + public function testGetOpenApiTypeFromPhpType(string $type, string $expected): void + { + $this->assertEquals($expected, $this->annotationGenerator->getOpenApiTypeFromPhpType($type)); + } + + /** + * @return iterable + */ + public function getTestDataForGetOpenApiTypeFromPhpType(): iterable + { + yield 'should be string for empty' => ['', 'string']; + yield 'should be string for unknown' => ['unknown', 'string']; + yield 'should be string for abc123' => ['abc123', 'string']; + yield 'should be array for array' => ['array', 'array']; + yield 'should be array for []' => ['[]', 'array']; + yield 'should be array for int[]' => ['int[]', 'array']; + yield 'should be array for string[]' => ['string[]', 'array']; + yield 'should be array for bool[]' => ['bool[]', 'array']; + yield 'should be array for float[]' => ['float[]', 'array']; + yield 'should be array for double[]' => ['double[]', 'array']; + yield 'should be integer for int' => ['int', 'integer']; + yield 'should be integer for integer' => ['integer', 'integer']; + yield 'should be boolean for bool' => ['bool', 'boolean']; + yield 'should be boolean for boolean' => ['boolean', 'boolean']; + yield 'should be number for float' => ['float', 'number']; + yield 'should be number for double' => ['double', 'number']; + } +} From a28af3356684f16df9c41b2a9aa035f70fc4fe31 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 11:17:06 +1200 Subject: [PATCH 06/11] Exclude vendor directory from PHPStan --- phpstan.neon | 1 + 1 file changed, 1 insertion(+) diff --git a/phpstan.neon b/phpstan.neon index b5ec903..0c62078 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -6,6 +6,7 @@ parameters: - . excludePaths: - tests/* + - vendor/* - github-action-tests bootstrapFiles: - ../../bootstrap-phpstan.php From c298361c8ddc80007770243bfacde8222cfd9097 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 11:31:08 +1200 Subject: [PATCH 07/11] Add more PHPStan files --- phpstan/phpstan.created.neon | 5 +++++ phpstan/phpstan.modified.neon | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 phpstan/phpstan.created.neon create mode 100644 phpstan/phpstan.modified.neon diff --git a/phpstan/phpstan.created.neon b/phpstan/phpstan.created.neon new file mode 100644 index 0000000..01e5495 --- /dev/null +++ b/phpstan/phpstan.created.neon @@ -0,0 +1,5 @@ +includes: + - ../phpstan.neon +parameters: + level: 5 + tmpDir: /tmp/phpstan/OpenApiDocs/created \ No newline at end of file diff --git a/phpstan/phpstan.modified.neon b/phpstan/phpstan.modified.neon new file mode 100644 index 0000000..c9967f1 --- /dev/null +++ b/phpstan/phpstan.modified.neon @@ -0,0 +1,5 @@ +includes: + - ../phpstan.neon +parameters: + level: 5 + tmpDir: /tmp/phpstan/OpenApiDocs/modified \ No newline at end of file From cf4db379a55cf3ed03e00a6eafa38cfb99778f49 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 11:59:46 +1200 Subject: [PATCH 08/11] Making a couple more PHPStan changes --- Specs/SpecGenerator.php | 1 + phpstan.neon | 1 + 2 files changed, 2 insertions(+) diff --git a/Specs/SpecGenerator.php b/Specs/SpecGenerator.php index 6dcea6d..089e858 100644 --- a/Specs/SpecGenerator.php +++ b/Specs/SpecGenerator.php @@ -43,6 +43,7 @@ public function generatePluginDoc(string $pluginName, string $format = 'json'): $pluginDir . '/API.php', ]); + // @phpstan-ignore method.notFound, method.notFound return strtolower($format) === 'yaml' ? $openapi->toYaml() : $openapi->toJson(); } } diff --git a/phpstan.neon b/phpstan.neon index 0c62078..a399bde 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,6 +8,7 @@ parameters: - tests/* - vendor/* - github-action-tests + - scoper.inc.php bootstrapFiles: - ../../bootstrap-phpstan.php universalObjectCratesClasses: From c117f4d41e14402b742e1aeb278d743ae4bc412b Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 12:23:21 +1200 Subject: [PATCH 09/11] Fixed pre-push issue --- .git-hooks-matomo/pre-push | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.git-hooks-matomo/pre-push b/.git-hooks-matomo/pre-push index 61d26af..79c6658 100755 --- a/.git-hooks-matomo/pre-push +++ b/.git-hooks-matomo/pre-push @@ -38,9 +38,8 @@ if command -v php >/dev/null 2>&1; then COMMAND="${MATOMO_DIR}/vendor/bin/phpstan" PLUGIN_PATH='' fi -fi # Use ddev if setup (overridding local setup) -if command -v ddev >/dev/null 2>&1; then +elif command -v ddev >/dev/null 2>&1; then if [ -d "$MATOMO_DIR/.ddev" ]; then cd "$MATOMO_DIR" || exit 1 if ddev status 2>&1 > /dev/null; then From 29b4efdd2ad32ace4fb9d227adf64360b4d389a0 Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Mon, 1 Sep 2025 12:47:36 +1200 Subject: [PATCH 10/11] Temporarily have PHPStan ignore class --- Specs/SpecGenerator.php | 1 - phpstan.neon | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Specs/SpecGenerator.php b/Specs/SpecGenerator.php index 089e858..6dcea6d 100644 --- a/Specs/SpecGenerator.php +++ b/Specs/SpecGenerator.php @@ -43,7 +43,6 @@ public function generatePluginDoc(string $pluginName, string $format = 'json'): $pluginDir . '/API.php', ]); - // @phpstan-ignore method.notFound, method.notFound return strtolower($format) === 'yaml' ? $openapi->toYaml() : $openapi->toJson(); } } diff --git a/phpstan.neon b/phpstan.neon index a399bde..7eeb31a 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,6 +9,7 @@ parameters: - vendor/* - github-action-tests - scoper.inc.php + - Specs/SpecGenerator.php bootstrapFiles: - ../../bootstrap-phpstan.php universalObjectCratesClasses: From 52bc68e15fc4bbd7f7b8995147d38f3261880b9d Mon Sep 17 00:00:00 2001 From: Jacob Ransom Date: Tue, 2 Sep 2025 14:01:32 +1200 Subject: [PATCH 11/11] Fixing code style issue after merging parent --- Annotations/AnnotationGenerator.php | 1 - 1 file changed, 1 deletion(-) diff --git a/Annotations/AnnotationGenerator.php b/Annotations/AnnotationGenerator.php index a7a019e..da5ec93 100644 --- a/Annotations/AnnotationGenerator.php +++ b/Annotations/AnnotationGenerator.php @@ -23,7 +23,6 @@ use PHPStan\PhpDocParser\Parser\TypeParser; use PHPStan\PhpDocParser\Parser\ConstExprParser; use PHPStan\PhpDocParser\Parser\TokenIterator; -use function _PHPStan_3d4486d07\RingCentral\Psr7\str; class AnnotationGenerator {