Skip to content

Commit

Permalink
fix missing cases in whereNotNull (#1553)
Browse files Browse the repository at this point in the history
  • Loading branch information
crissi committed Feb 27, 2023
1 parent 74b58a4 commit 958b95d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\MethodReflection;
use PHPStan\Reflection\ParametersAcceptorSelector;
use PHPStan\Type\BooleanType;
use PHPStan\Type\DynamicMethodReturnTypeExtension;
use PHPStan\Type\FloatType;
use PHPStan\Type\Generic\GenericObjectType;
use PHPStan\Type\IntegerType;
use PHPStan\Type\NullType;
use PHPStan\Type\StringType;
use PHPStan\Type\Type;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\UnionType;

class CollectionWhereNotNullDynamicReturnTypeExtension implements DynamicMethodReturnTypeExtension
{
Expand Down Expand Up @@ -46,6 +52,30 @@ public function getTypeFromMethodCall(

$nonFalseyTypes = TypeCombinator::removeNull($valueType);

if (! $this->argumentIsString($methodCall, $scope)) {
return new GenericObjectType($calledOnType->getClassName(), [$keyType, $nonFalseyTypes]);
}

$scalarTypes = new UnionType([
new StringType(),
new IntegerType(),
new FloatType(),
new BooleanType(),
]);

$nonFalseyTypes = TypeCombinator::remove($nonFalseyTypes, $scalarTypes);

return new GenericObjectType($calledOnType->getClassName(), [$keyType, $nonFalseyTypes]);
}

public function argumentIsString(MethodCall $methodCall, Scope $scope): bool
{
if (count($methodCall->getArgs()) === 0) {
return false;
}

$argType = $scope->getType($methodCall->getArgs()[0]->value);

return (new NullType())->isSuperTypeOf($argType)->no();
}
}
5 changes: 5 additions & 0 deletions tests/Type/data/collection-where-not-null.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

assertType('Illuminate\Support\Collection<int, int|string>', collect([1, 2, null, '', 'hello'])->whereNotNull());
assertType('Illuminate\Support\Collection<int, int|string>', collect([1, 2, null, '', 'hello'])->whereNotNull());
assertType('Illuminate\Support\Collection<int, int|string>', collect([1, 2, null, '', 'hello'])->whereNotNull(null));
assertType(
'Illuminate\Support\Collection<int, App\User|array{id: string}|stdClass>',
collect([new \App\User, new \stdClass, ['id' => 'foo'], 'foo', true, 22])->whereNotNull('id')
);

/** @param \Illuminate\Database\Eloquent\Collection<int, \App\User> $foo */
function objectAndParam(EloquentCollection $foo): void
Expand Down

0 comments on commit 958b95d

Please sign in to comment.