Skip to content

Commit

Permalink
return mixed type
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Feb 4, 2022
1 parent 6652246 commit f682afa
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 43 deletions.
48 changes: 8 additions & 40 deletions src/Type/Php/JsonThrowOnErrorDynamicReturnTypeExtension.php
Expand Up @@ -12,21 +12,15 @@
use PHPStan\Reflection\FunctionReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Reflection\ReflectionProvider;
use PHPStan\Type\ArrayType;
use PHPStan\Type\BooleanType;
use PHPStan\Type\Constant\ConstantBooleanType;
use PHPStan\Type\Constant\ConstantIntegerType;
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ConstantTypeHelper;
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
use PHPStan\Type\FloatType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;
use stdClass;
use function json_decode;

Expand Down Expand Up @@ -66,11 +60,7 @@ public function getTypeFromFunctionCall(

// narrow type for json_decode()
if ($functionReflection->getName() === 'json_decode') {
$jsonDecodeNarrowedType = $this->narrowTypeForJsonDecode($functionCall, $scope);
// improve type
if (! $jsonDecodeNarrowedType instanceof MixedType) {
$defaultReturnType = $jsonDecodeNarrowedType;
}
$defaultReturnType = $this->narrowTypeForJsonDecode($functionCall, $scope);
}

if (!isset($functionCall->getArgs()[$argumentPosition])) {
Expand Down Expand Up @@ -128,35 +118,15 @@ private function narrowTypeForJsonDecode(FuncCall $funcCall, Scope $scope): Type
$firstValueType = $scope->getType($firstArgValue);

if ($firstValueType instanceof ConstantStringType) {
$resolvedType = $this->resolveConstantStringType($firstValueType, $isForceArray);
} else {
$resolvedType = new MixedType();
}

// prefer specific type
if (! $resolvedType instanceof MixedType) {
return $resolvedType;
return $this->resolveConstantStringType($firstValueType, $isForceArray);
}

// fallback type
if ($isForceArray) {
return new UnionType([
new ArrayType(new MixedType(), new MixedType()),
new StringType(),
new FloatType(),
new IntegerType(),
new BooleanType(),
]);
return new MixedType(true, new ObjectType(stdClass::class));
}

// scalar types with stdClass
return new UnionType([
new ObjectType(stdClass::class),
new StringType(),
new FloatType(),
new IntegerType(),
new BooleanType(),
]);
return new MixedType(true);
}

/**
Expand All @@ -167,18 +137,16 @@ private function isForceArray(FuncCall $funcCall): bool
{
$args = $funcCall->getArgs();

if (!isset($args[1])) {
if (! isset($args[1])) {
return false;
}

$secondArgValue = $args[1]->value;
if ($secondArgValue instanceof ConstFetch) {
if ($secondArgValue->name->toLowerString() === 'true') {
return true;
}
if (! $secondArgValue instanceof ConstFetch) {
return false;
}

return false;
return $secondArgValue->name->toLowerString() === 'true';
}

private function resolveConstantStringType(ConstantStringType $constantStringType, bool $isForceArray): Type
Expand Down
6 changes: 3 additions & 3 deletions tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php
Expand Up @@ -8749,15 +8749,15 @@ public function dataPhp73Functions(): array
'json_encode($mixed, $integer | JSON_THROW_ON_ERROR | JSON_NUMERIC_CHECK)',
],
[
'bool|float|int|stdClass|string',
'mixed',
'json_decode($mixed)',
],
[
'float|int|stdClass|string|true',
'mixed~false',
'json_decode($mixed, false, 512, JSON_THROW_ON_ERROR | JSON_NUMERIC_CHECK)',
],
[
'float|int|stdClass|string|true',
'mixed~false',
'json_decode($mixed, false, 512, $integer | JSON_THROW_ON_ERROR | JSON_NUMERIC_CHECK)',
],
[
Expand Down
6 changes: 6 additions & 0 deletions tests/PHPStan/Analyser/data/json-decode/narrow_type.php
Expand Up @@ -21,3 +21,9 @@

$value = json_decode('[1, 2, 3]');
assertType('array{1, 2, 3}', $value);


function ($mixed) {
$value = json_decode($mixed);
assertType('mixed', $value);
};
Expand Up @@ -21,3 +21,8 @@

$value = json_decode('[1, 2, 3]', true);
assertType('array{1, 2, 3}', $value);

function ($mixed) {
$value = json_decode($mixed, true);
assertType('mixed~stdClass', $value);
};

0 comments on commit f682afa

Please sign in to comment.