thecodingmachine / safe

All PHP functions, rewritten to throw exceptions instead of returning false
MIT License
2.34k stars 140 forks source link

Add PHPStan/Psalm templates #124

Open BackEndTea opened 5 years ago

BackEndTea commented 5 years ago

Currently methods like preg_replace have a return type of string|array specified. When in reality that return type is dependant on the input.

Static analysis tools, like PHPStan and Psalm can be made aware of this by using @template annotations, like so:

https://phpstan.org/r/4f0fc5ec-ad1a-45e8-a592-a46106267d67

This means that the tools can understand what exactly the output is going to be, if they can infer the input types.

Would it be possible to add those annotations to the generated code?

moufmouf commented 5 years ago

I don't think there is a way to automatically "generate" the @template annotations. Code is generated from the PHP documentation and from the functionMap file

I cannot analyze those files automatically.

But the idea is very good, and I could make exceptions for those functions and have them written "by hand".

Now, the question is: where can I find a complete list of such functions? Would you have an idea how I can find those?

BackEndTea commented 5 years ago

I think @ondrejmirtes may know that for phpstan, or @muglug for psalm

ondrejmirtes commented 5 years ago

Some situations can be described by generics, but a lot of them are more complex and require custom logic. PHPStan has "dynamic return type extensions" for this purpose and they're here in this directory (besides type-specifying extensions for functions like assert or is_int):

https://github.com/phpstan/phpstan/tree/master/src/Type/Php

The problem is that they're not 1:1 reusable with Safe because Safe eliminates some return failure types. The best approach would probably be to copy-paste them to PHPStan Safe extension and change what's needed...

Kharhamel commented 4 years ago

@ondrejmirtes now that phpstan does implement templates, do you think we can generate them in safe?

ondrejmirtes commented 4 years ago

You might be able to describe some situations with generics, but not everything.

simPod commented 4 years ago

I found eg. this https://github.com/vimeo/psalm/blob/master/src/Psalm/Internal/Provider/ReturnTypeProvider/StrReplaceReturnTypeProvider.php

Perhaps we should be able to port this logic into something like thecodingmachine/safe-psalm-plugin. WDYT?