Skip to content

feat: add dynamic parameter type extensions - #4290

Open
calebdw wants to merge 5 commits into
phpstan:2.2.xfrom
calebdw:dynamic_parameter_extension
Open

feat: add dynamic parameter type extensions#4290
calebdw wants to merge 5 commits into
phpstan:2.2.xfrom
calebdw:dynamic_parameter_extension

Conversation

@calebdw

@calebdw calebdw commented Sep 5, 2025

Copy link
Copy Markdown
Contributor

Closes phpstan/phpstan#11707, closes phpstan/phpstan#12585

Supersedes #3828, supersedes #3131, supersedes #3823

Hello!

This adds generalized dynamic parameter type extensions and deprecates the parameter closure type extensions per phpstan/phpstan#11707 (comment).

This also fixes the return.type and the argument.type errors described in phpstan/phpstan#12585 when the parameter type is overridden via the extension.

Note

This currently only works for array and closure arguments, if support is desired for other argument types in the future then that will have to be added.

CC: @canvural, @Neol3108

Thanks!

@calebdw
calebdw force-pushed the dynamic_parameter_extension branch 4 times, most recently from 49c7da8 to 58e51fb Compare September 5, 2025 14:15
@calebdw
calebdw marked this pull request as draft September 5, 2025 16:35
@calebdw
calebdw force-pushed the dynamic_parameter_extension branch from 58e51fb to 79de0a6 Compare September 5, 2025 17:05
@calebdw
calebdw marked this pull request as ready for review September 5, 2025 17:36
@phpstan-bot

Copy link
Copy Markdown
Collaborator

This pull request has been marked as ready for review.

@canvural

canvural commented Sep 6, 2025

Copy link
Copy Markdown
Contributor

I tested it by porting my previous implementation for Larastan to this one, and looks like it works fine! Will try to implement more use cases and see if I can find any bugs. Also will try to test it on real projects.But so far so good. Thanks for this!

I'll also try to review this PR (though Ondrej would do a better job 😄 )

@ondrejmirtes ondrejmirtes left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks solid, just a few questions as a start, will do deep review later 👍

Comment thread e2e/parameter-type-extension/src/ParameterTypeExtension.php
Comment thread src/Analyser/ExpressionContext.php Outdated
Comment thread src/Analyser/ExpressionContext.php Outdated
@canvural

canvural commented Oct 2, 2025

Copy link
Copy Markdown
Contributor

@calebdw @ondrejmirtes Sorry to bother you, but I wanted to ask how we can move this forward? I'm really interested in this feature.

@calebdw

calebdw commented Oct 2, 2025

Copy link
Copy Markdown
Contributor Author

No worries, just been busy with personal life, I'll try to get to the comments soon

@calebdw
calebdw force-pushed the dynamic_parameter_extension branch 2 times, most recently from b9ce6ac to b293d32 Compare November 10, 2025 15:46
@calebdw

calebdw commented Nov 10, 2025

Copy link
Copy Markdown
Contributor Author

@ondrejmirtes, @canvural, sorry it took so long to address these comments---just been busy with personal life but hoping to move this forward now 🙏

@CamKemBell

Copy link
Copy Markdown

@calebdw - is this still planned on going ahead? Does this fix the issue with using whereHas with custom builders?

I've seen multiple projects now look to using custom builders since the implementation of the attribute & official support from Laravel last year, only to find issues when trying to type the arguments in eloquent method for type hints / auto complete, etc.

https://laravel-news.com/defining-a-dedicated-query-builder-in-laravel-12-with-php-attributes

In the meantime, we have been using whereRelation, which compiles to whereHas under the hood, but it would be nice to use whereHas directly.

image

@dnyg

dnyg commented Jan 15, 2026

Copy link
Copy Markdown

My team are also eagerly awaiting the outcome of this PR! Hope it can be pushed forward 🙏

@calebdw
calebdw force-pushed the dynamic_parameter_extension branch 2 times, most recently from 08bc956 to 7823716 Compare January 19, 2026 15:17
@calebdw

calebdw commented Jan 19, 2026

Copy link
Copy Markdown
Contributor Author

@CamKemBell, yes I just rebased and resolved all the conflicts

@ondrejmirtes, this is ready to review 👍

@dnyg

dnyg commented Feb 12, 2026

Copy link
Copy Markdown

What is the status on this PR?

@VincentLanglet

Copy link
Copy Markdown
Contributor

Hi @calebdw sorry for the delay there is now more review for the PHPStan codebase.

Are you still interested by the PR ?
There is a lot of conflict, can you solve them please ?

Thanks !

@calebdw
calebdw force-pushed the dynamic_parameter_extension branch from 9e68ce4 to c67e140 Compare February 16, 2026 14:43
Comment thread src/Type/DynamicFunctionParameterTypeExtension.php

@staabm staabm left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it looks mostly good, a few questions

  • if I did not miss it, it seems none of the tests is covering a error case?
  • $overriddenType is passed thru a lot of handlers. I think we should have a few more tests which show that the overridden type gets correctly passed thru complex expressions
  • I wonder if we really need end-to-end test-cases only or whether we could at least have some in-phpunit suite tests (these are easier to run, debug and maintain)
  • you should look into issue-bot results and judge whether these are expected/related (some of them might go-away after rebase)
  • we need this PR to target 2.2.x

Comment thread src/Analyser/ExprHandler/ArrayHandler.php
Comment thread e2e/bug-12585/src/test.php
@canvural

Copy link
Copy Markdown
Contributor

@calebdw Would you have time to address the comments? Or if you allow, I can open another PR with your code and fix there.

@calebdw

calebdw commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

Yes, sorry been busy---I'll get to this shortly

@calebdw
calebdw force-pushed the dynamic_parameter_extension branch from 0a17a77 to 79dd1ad Compare June 23, 2026 02:59
path: phpstan-dist
token: ${{ secrets.PHPSTAN_BOT_TOKEN }}
ref: 2.1.x
ref: 2.2.x
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: 2.1.x
ref: 2.2.x

@github-advanced-security github-advanced-security AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zizmor found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

Comment thread .github/workflows/e2e-tests.yml Fixed
Comment thread .github/workflows/e2e-tests.yml Fixed
@calebdw
calebdw force-pushed the dynamic_parameter_extension branch from 79dd1ad to edb86a0 Compare June 23, 2026 03:03
@calebdw
calebdw changed the base branch from 2.1.x to 2.2.x June 23, 2026 03:05
@calebdw
calebdw force-pushed the dynamic_parameter_extension branch 2 times, most recently from 3e2e16d to 9b99f72 Compare June 23, 2026 03:23
@canvural

Copy link
Copy Markdown
Contributor

Tested the latest PHAR, still works alright 👍🏽 Static analysis fails on CI looks legit though. But didn't happen at runtime 🤔 Maybe didn't hit that code path.

Comment thread .github/workflows/e2e-tests.yml Outdated
@CamKemBell

Copy link
Copy Markdown

Would love to see this over the line...

@canvural

Copy link
Copy Markdown
Contributor

Can I sponsor/pay someone to bring this over the finish line? Resolving conflicts <--> wait for review loop doesn't seem to end 😄

// @ondrejmirtes @staabm @VincentLanglet

@calebdw
calebdw force-pushed the dynamic_parameter_extension branch 2 times, most recently from 0bb1ff7 to 849e432 Compare July 30, 2026 02:38
@calebdw

calebdw commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

@staabm,

if I did not miss it, it seems none of the tests is covering a error case?

I've added tests

$overriddenType is passed thru a lot of handlers. I think we should have a few more tests which show that the overridden type gets correctly passed thru complex expressions

Same here, added tests

I wonder if we really need end-to-end test-cases only or whether we could at least have some in-phpunit suite tests (these are easier to run, debug and maintain)

The existing DynamicParameterTypeExtensionClosuresTest and DynamicParameterTypeExtensionArraysTest are already PHPUnit TypeInferenceTestCase tests (not just e2e). The e2e tests are supplementary for integration validation.

@calebdw
calebdw force-pushed the dynamic_parameter_extension branch from 849e432 to cdeb328 Compare July 30, 2026 02:51
@calebdw
calebdw force-pushed the dynamic_parameter_extension branch 3 times, most recently from 0354bcc to 3e72bd1 Compare July 30, 2026 03:26
@calebdw
calebdw force-pushed the dynamic_parameter_extension branch from 3e72bd1 to ee0d648 Compare July 30, 2026 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Invalid argument types when using MethodParameterClosureTypeExtension Allow specifying that parameters should be covariant

9 participants