Skip to content

Add support for the callable-string type#296

Merged
ondrejmirtes merged 2 commits intophpstan:masterfrom
ste93cry:feature/3723-add-callable-string-type-support
Aug 12, 2020
Merged

Add support for the callable-string type#296
ondrejmirtes merged 2 commits intophpstan:masterfrom
ste93cry:feature/3723-add-callable-string-type-support

Conversation

@ste93cry
Copy link
Copy Markdown
Contributor

@ste93cry ste93cry commented Aug 8, 2020

With this PR I would like to add support for the callable-string type as it works in Psalm. I have deliberately decided not to check through the broker if the function exists as I think that it may be an issue in some cases due to false positives, but let me know if we want to go stricter. I did some tests with Psalm and it looks like there is no validation at all of the value itself. This fixes the specific case reported in phpstan/phpstan#3723, although the original problem with the missing fallback of PHPStan to the plain PHPDoc annotation remains

@ondrejmirtes
Copy link
Copy Markdown
Member

Hi, I don't understand this:

looks like there is no validation at all of the value itself

What's the point then? I'd definitely want the validation.

Copy link
Copy Markdown
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

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

I'll fix the build of dev-master, you can then rebase.

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.

You can also add some testcases to TypeCombinatorTest::dataIntersect. It should work like this:

  • Intersection of string and callable-string -> callable-string.
  • Intersection of ConstantStringType and CallableStringType - depends on the value, can be normalized to ConstantStringType, it might not. Please test both cases.

@ondrejmirtes
Copy link
Copy Markdown
Member

Actually, I just checked what is_callable() does and it looks like it creates an intersection of CallableType and StringType: https://phpstan.org/r/4321ed59-36f6-4ee3-aad9-30da2a08c367

So we can scratch the new whole CallableStringType class and just work with the intersection...

@ste93cry
Copy link
Copy Markdown
Contributor Author

So we can scratch the new whole CallableStringType class

I did some testing (I'm not practical enough of how PHPStan internals works, so I'm having an hard time contributing), but changing the TypeNodeResolver to return UnionType([new StringType(), new CallableType()]) instead of a whole new type produces issues elsewhere, for example PHPDoc tag @param for parameter $str with type (callable)|string is not subtype of native type string. I'm sure it's possible to handle this and that I'm doing something wrong, but wouldn't be more simple to handle the callable-string with its own type like the class-string implementation?

@ondrejmirtes
Copy link
Copy Markdown
Member

You need to make callable-string basically an alias of callable&string, not callable|string. Which means using IntersectionType, not UnionType.

@ondrejmirtes
Copy link
Copy Markdown
Member

Thank you.

@ondrejmirtes ondrejmirtes merged commit 73f7e73 into phpstan:master Aug 12, 2020
@ste93cry
Copy link
Copy Markdown
Contributor Author

Uuum, thank you for merging the PR but I still had to push the commit with the additional tests of the TypeCombinatorTest class... I will open a new PR to add them

@ste93cry ste93cry deleted the feature/3723-add-callable-string-type-support branch August 12, 2020 15:46
@ondrejmirtes
Copy link
Copy Markdown
Member

PR is a PR, you're always risking I'm gonna merge it unless it's a draft :)

@ondrejmirtes
Copy link
Copy Markdown
Member

ondrejmirtes commented Aug 12, 2020

When you're at it, a new NodeScopeResolver::testFileAsserts data provider with callable-string in PHPDoc and assertType('callable&string', $param) would also be nice.

@ste93cry
Copy link
Copy Markdown
Contributor Author

you're always risking I'm gonna merge it unless it's a draft

Lesson learned 😄

When you're at it, a new NodeScopeResolver::testFileAsserts data provider with callable-string in PHPDoc and assertType('callable&string', $param) would also be nice.

Sure, will do 👍

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.

2 participants