phpstan / phpstan-nette

Nette Framework class reflection extension for PHPStan & framework-specific rules
MIT License
100 stars 35 forks source link

[Types] Add JsonDecodeDynamicReturnTypeExtension #89

Open TomasVotruba opened 2 years ago

TomasVotruba commented 2 years ago

By default, the Nette\Utils\Json::decode() returns mixed, but in some cases we know there is more specific type.

We use this extension internally in private project to separate at array and stdClass, e.g.:

$values = Nette\Utils\Json::decode($values);
echo $values['item'];
// not possible - a stdClass type given

$values = Nette\Utils\Json::decode($values, Nette\Utils\Json::FORCE_ARRAY);
echo $values->item ;
// not possible - an array type given

It might be useful to have in Nette extension itself. What do you think?

cc @staabm @lulco @matthiasnoback

Based on https://twitter.com/VotrubaT/status/1487434178757074952

TomasVotruba commented 2 years ago

I actually tried to add function extension first but PHPStan analysed only non-basic function. Not sure why.

Apart that, is the type resolution in tests here correct?

ondrejmirtes commented 2 years ago

Instead of the whole resolveConstantStringType method you just should call this class https://github.com/phpstan/phpstan-src/blob/master/src/Type/ConstantTypeHelper.php, otherwise it looks fine.

ondrejmirtes commented 2 years ago

Just to reiterate - I still want this to be submitted as a json_decode extension to phpstan-src first. Then we can continue here, keep all the tests but make the extension implementation much simpler, delegating to json_decode logic.

TomasVotruba commented 2 years ago

@ondrejmirtes I understand that, I just want to make it work and confirm here, so we don't jump back and forth. Then function extension port to core and update here.

TomasVotruba commented 2 years ago

@ondrejmirtes As for json_decode, is FunctionTypeSpecifyingExtension the right interface to implement?

ondrejmirtes commented 2 years ago

No (https://phpstan.org/developing-extensions/dynamic-return-type-extensions):

functions using DynamicFunctionReturnTypeExtension interface and phpstan.broker.dynamicFunctionReturnTypeExtension service tag.

TomasVotruba commented 2 years ago

@ondrejmirtes Thanks :+1:

I'm trying to add JsonDecodeDynamicReturnTypeExtension, but the only function that is found is PHPStan\Testing\assertType. The json_decode is never passed.

What I'm doing wrong there?