From de60355bd9abaae7dd23cb2269fd46361fa1aa4e Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 09:41:57 +0200 Subject: [PATCH 01/13] Fix "False positive staticMethod.alreadyNarrowedType for Strings::length() inside numeric comparison" --- src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php index d48bcc6..f03b8ad 100644 --- a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php +++ b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php @@ -54,7 +54,7 @@ public function specifyTypes(MethodReflection $staticMethodReflection, StaticCal new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]), $context, $scope, - ); + )->setRootExpr($node); } } From d0990ea771b96d363d7e6dd3b2a3fc4ecd2e2387 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 10:52:20 +0200 Subject: [PATCH 02/13] add test --- .github/workflows/e2e-tests.yml | 57 +++++++++++++++++++++++++++++++++ e2e/bug-208/.gitignore | 2 ++ e2e/bug-208/composer.json | 11 +++++++ e2e/bug-208/phpstan.neon | 4 +++ 4 files changed, 74 insertions(+) create mode 100644 .github/workflows/e2e-tests.yml create mode 100644 e2e/bug-208/.gitignore create mode 100644 e2e/bug-208/composer.json create mode 100644 e2e/bug-208/phpstan.neon diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml new file mode 100644 index 0000000..1cfbd6f --- /dev/null +++ b/.github/workflows/e2e-tests.yml @@ -0,0 +1,57 @@ +# https://help.github.com/en/categories/automating-your-workflow-with-github-actions + +name: "E2E Tests" + +on: + pull_request: + push: + branches: + - "2.0.x" + +concurrency: + group: e2e-${{ github.head_ref || github.run_id }} # will be canceled on subsequent pushes in pull requests but not branches + cancel-in-progress: true + +permissions: + contents: read + +jobs: + e2e-tests: + name: "E2E tests" + runs-on: "ubuntu-latest" + timeout-minutes: 60 + + strategy: + fail-fast: false + matrix: + include: + - script: | + cd e2e/bug-208 + ../../bin/phpstan + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 + with: + egress-policy: audit + + - name: "Checkout" + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: "Install PHP" + uses: "shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc" # v2.37.1 + with: + coverage: "none" + php-version: "8.2" + tools: ${{ matrix.tools }} + extensions: ${{ matrix.extensions }} + + - uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0 + + - name: "Install bashunit" + uses: "TypedDevs/bashunit@ffa9c79e71ecbb9990e777348bc9ba12314b62d0" # 0.39.1 + with: + directory: "e2e" + + - name: "Test" + run: ${{ matrix.script }} diff --git a/e2e/bug-208/.gitignore b/e2e/bug-208/.gitignore new file mode 100644 index 0000000..8b7ef35 --- /dev/null +++ b/e2e/bug-208/.gitignore @@ -0,0 +1,2 @@ +/vendor +composer.lock diff --git a/e2e/bug-208/composer.json b/e2e/bug-208/composer.json new file mode 100644 index 0000000..0213be4 --- /dev/null +++ b/e2e/bug-208/composer.json @@ -0,0 +1,11 @@ +{ + "require-dev": { + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan-nette": "@dev" + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + } + } +} diff --git a/e2e/bug-208/phpstan.neon b/e2e/bug-208/phpstan.neon new file mode 100644 index 0000000..c308dcf --- /dev/null +++ b/e2e/bug-208/phpstan.neon @@ -0,0 +1,4 @@ +parameters: + level: 8 + paths: + - src From 09366f016e1e3fb80ddfd4336ba5ee2bd7555a83 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 10:52:33 +0200 Subject: [PATCH 03/13] Update StringsLengthTypeSpecifiyingExtension.php --- src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php index f03b8ad..2f4eac8 100644 --- a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php +++ b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php @@ -54,7 +54,9 @@ public function specifyTypes(MethodReflection $staticMethodReflection, StaticCal new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]), $context, $scope, - )->setRootExpr($node); + ) + //->setRootExpr($node) + ; } } From 52193ac2cfd9494bba2c5b9de8021e7bba30baee Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 10:56:33 +0200 Subject: [PATCH 04/13] Update composer.json --- e2e/bug-208/composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/e2e/bug-208/composer.json b/e2e/bug-208/composer.json index 0213be4..667228f 100644 --- a/e2e/bug-208/composer.json +++ b/e2e/bug-208/composer.json @@ -1,7 +1,8 @@ { "require-dev": { "phpstan/extension-installer": "^1.4", - "phpstan/phpstan-nette": "@dev" + "phpstan/phpstan-nette": "@dev", + "phpstan/phpstan": "@dev" }, "config": { "allow-plugins": { From 6125f3a034d5faf31f2528d7e89d210f85b35cee Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 10:59:33 +0200 Subject: [PATCH 05/13] repro --- e2e/bug-208/composer.json | 1 + e2e/bug-208/src/foo.php | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 e2e/bug-208/src/foo.php diff --git a/e2e/bug-208/composer.json b/e2e/bug-208/composer.json index 667228f..406ee52 100644 --- a/e2e/bug-208/composer.json +++ b/e2e/bug-208/composer.json @@ -1,5 +1,6 @@ { "require-dev": { + "nette/utils": "^3.2.5", "phpstan/extension-installer": "^1.4", "phpstan/phpstan-nette": "@dev", "phpstan/phpstan": "@dev" diff --git a/e2e/bug-208/src/foo.php b/e2e/bug-208/src/foo.php new file mode 100644 index 0000000..bc753cc --- /dev/null +++ b/e2e/bug-208/src/foo.php @@ -0,0 +1,18 @@ + Date: Thu, 2 Jul 2026 11:00:33 +0200 Subject: [PATCH 06/13] Update e2e-tests.yml --- .github/workflows/e2e-tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 1cfbd6f..3accc21 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -43,8 +43,6 @@ jobs: with: coverage: "none" php-version: "8.2" - tools: ${{ matrix.tools }} - extensions: ${{ matrix.extensions }} - uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0 From 625899257af9899726164e772c30f39458d9de27 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 11:02:45 +0200 Subject: [PATCH 07/13] Update e2e-tests.yml --- .github/workflows/e2e-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 3accc21..a0844a6 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -27,7 +27,7 @@ jobs: include: - script: | cd e2e/bug-208 - ../../bin/phpstan + vendor/bin/phpstan steps: - name: Harden the runner (Audit all outbound calls) From 244009bf435f36743da1347e45ddb36d5a215ff7 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 11:04:52 +0200 Subject: [PATCH 08/13] Update e2e-tests.yml --- .github/workflows/e2e-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index a0844a6..98253f0 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -27,6 +27,7 @@ jobs: include: - script: | cd e2e/bug-208 + composer install vendor/bin/phpstan steps: From e9b26e0901538f20504a8c4e541e5a850f817420 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 11:05:43 +0200 Subject: [PATCH 09/13] Update e2e-tests.yml --- .github/workflows/e2e-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 98253f0..5c06fb3 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -43,7 +43,7 @@ jobs: uses: "shivammathur/setup-php@7c071dfe9dc99bdf297fa79cb49ea005b9fcadbc" # v2.37.1 with: coverage: "none" - php-version: "8.2" + php-version: "8.3" - uses: "ramsey/composer-install@65e4f84970763564f46a70b8a54b90d033b3bdda" # v4.0.0 From 7c519b44a7567fad21e9589c89dbc3beb71d192d Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 11:06:20 +0200 Subject: [PATCH 10/13] Revert "Update StringsLengthTypeSpecifiyingExtension.php" This reverts commit 09366f016e1e3fb80ddfd4336ba5ee2bd7555a83. --- src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php index 2f4eac8..f03b8ad 100644 --- a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php +++ b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php @@ -54,9 +54,7 @@ public function specifyTypes(MethodReflection $staticMethodReflection, StaticCal new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]), $context, $scope, - ) - //->setRootExpr($node) - ; + )->setRootExpr($node); } } From d08853bf6222274b979a52c38ccc51e8f3d79f75 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 11:15:02 +0200 Subject: [PATCH 11/13] better repro --- e2e/bug-208/composer.json | 14 +++++++------- e2e/bug-208/phpstan.neon | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/e2e/bug-208/composer.json b/e2e/bug-208/composer.json index 406ee52..8f24ae8 100644 --- a/e2e/bug-208/composer.json +++ b/e2e/bug-208/composer.json @@ -1,13 +1,13 @@ { "require-dev": { "nette/utils": "^3.2.5", - "phpstan/extension-installer": "^1.4", - "phpstan/phpstan-nette": "@dev", + "phpstan/phpstan-nette": "@dev", "phpstan/phpstan": "@dev" }, - "config": { - "allow-plugins": { - "phpstan/extension-installer": true - } - } + "repositories": [ + { + "type": "path", + "url": "../../" + } + ] } diff --git a/e2e/bug-208/phpstan.neon b/e2e/bug-208/phpstan.neon index c308dcf..8ea2ed2 100644 --- a/e2e/bug-208/phpstan.neon +++ b/e2e/bug-208/phpstan.neon @@ -1,3 +1,7 @@ +includes: + - ../../extension.neon + - ../../rules.neon + parameters: level: 8 paths: From f571e6c47a9cb8a79b056c41e1e654ac0d334212 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 11:16:39 +0200 Subject: [PATCH 12/13] Reapply "Update StringsLengthTypeSpecifiyingExtension.php" This reverts commit 7c519b44a7567fad21e9589c89dbc3beb71d192d. --- src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php index f03b8ad..2f4eac8 100644 --- a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php +++ b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php @@ -54,7 +54,9 @@ public function specifyTypes(MethodReflection $staticMethodReflection, StaticCal new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]), $context, $scope, - )->setRootExpr($node); + ) + //->setRootExpr($node) + ; } } From 96f8daa85c52612896ad98f5a9c2f3ae4148e0f1 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Thu, 2 Jul 2026 11:18:41 +0200 Subject: [PATCH 13/13] Revert "Reapply "Update StringsLengthTypeSpecifiyingExtension.php"" This reverts commit f571e6c47a9cb8a79b056c41e1e654ac0d334212. --- src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php index 2f4eac8..f03b8ad 100644 --- a/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php +++ b/src/Type/Nette/StringsLengthTypeSpecifiyingExtension.php @@ -54,9 +54,7 @@ public function specifyTypes(MethodReflection $staticMethodReflection, StaticCal new IntersectionType([new StringType(), new AccessoryNonEmptyStringType()]), $context, $scope, - ) - //->setRootExpr($node) - ; + )->setRootExpr($node); } }