Skip to content

Adjust and make space for tests for new behaviour of new #3852

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions tests/PHPStan/Analyser/data/array-destructuring.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?php
function () {
function (\stdClass $obj) {
/** @var mixed $array */
$array = getMixed();
[$a, $b, [$c]] = $array;
Expand Down Expand Up @@ -51,7 +51,6 @@ function () {

[$newArray['newKey']] = [new stdClass(), new stdClass()];

$obj = new stdClass();
[$obj[0]] = ['error', 'error-error'];

$constantAssocArray = [1, 'foo', 'key' => true, 'value' => '123'];
Expand Down
3 changes: 1 addition & 2 deletions tests/PHPStan/Analyser/data/nested-functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ public function doFoo(): self

}

function () {
$foo = new Foo();
function (Foo $foo) {
$foo->doFoo()
->doFoo()
->doFoo()
Expand Down
28 changes: 13 additions & 15 deletions tests/PHPStan/Analyser/nsrt/bug-6462.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,19 @@ public function getThis(): self
}
}

$base = new Base();
$child = new Child();
$fixedChild = new FixedChild();
function (Base $base, Child $child, FixedChild $fixedChild): void {
assertType('Bug6462\Base', $base->getThis());
assertType('Bug6462\Child', $child->getThis());

assertType('Bug6462\Base', $base->getThis());
assertType('Bug6462\Child', $child->getThis());

if ($base instanceof \Traversable) {
assertType('Bug6462\Base&Traversable', $base->getThis());
}
if ($base instanceof \Traversable) {
assertType('Bug6462\Base&Traversable', $base->getThis());
}

if ($child instanceof \Traversable) {
assertType('Bug6462\Child&Traversable', $child->getThis());
}
if ($child instanceof \Traversable) {
assertType('Bug6462\Child&Traversable', $child->getThis());
}

if ($fixedChild instanceof \Traversable) {
assertType('Bug6462\FixedChild&Traversable', $fixedChild->getThis());
}
if ($fixedChild instanceof \Traversable) {
assertType('Bug6462\FixedChild&Traversable', $fixedChild->getThis());
}
};
3 changes: 2 additions & 1 deletion tests/PHPStan/Analyser/nsrt/get-debug-type.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class D {}
* @param int|string $intOrString
* @param array|A $arrayOrObject
*/
function doFoo(bool $b, int $i, float $f, $d, $r, string $s, array $a, $intOrString, $arrayOrObject) {
function doFoo(bool $b, int $i, float $f, $d, $r, string $s, array $a, $intOrString, $arrayOrObject, \stdClass $std) {
$null = null;
$resource = fopen('php://memory', 'r');
$o = new \stdClass();
Expand All @@ -34,6 +34,7 @@ function doFoo(bool $b, int $i, float $f, $d, $r, string $s, array $a, $intOrStr
assertType("'string'", get_debug_type($s));
assertType("'array'", get_debug_type($a));
assertType("string", get_debug_type($o));
assertType("string", get_debug_type($std));
assertType("'GetDebugType\\\\A'", get_debug_type($A));
assertType("string", get_debug_type($r));
assertType("'bool'|string", get_debug_type($resource));
Expand Down
3 changes: 1 addition & 2 deletions tests/PHPStan/Analyser/nsrt/instanceof.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@ abstract class BarParent
class Foo extends BarParent
{

public function someMethod(Expr $foo)
public function someMethod(Expr $foo, Foo $intersected)
{
$bar = $foo;
$baz = doFoo();
$intersected = new Foo();
$parent = doFoo();

if ($baz instanceof Foo) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,169 +96,177 @@ public function testImpossibleCheckTypeFunctionCall(): void
'Call to function method_exists() with CheckTypeFunctionCall\Foo and \'doFoo\' will always evaluate to true.',
179,
],
[
'Call to function method_exists() with CheckTypeFunctionCall\Foo and \'doFoo\' will always evaluate to true.',
189,
],
[
'Call to function method_exists() with $this(CheckTypeFunctionCall\FinalClassWithMethodExists) and \'doFoo\' will always evaluate to true.',
191,
201,
],
[
'Call to function method_exists() with $this(CheckTypeFunctionCall\FinalClassWithMethodExists) and \'doBar\' will always evaluate to false.',
194,
204,
],
[
'Call to function property_exists() with $this(CheckTypeFunctionCall\FinalClassWithPropertyExists) and \'fooProperty\' will always evaluate to true.',
210,
220,
],
[
'Call to function in_array() with arguments int, array{\'foo\', \'bar\'} and true will always evaluate to false.',
236,
246,
],
[
'Call to function in_array() with arguments \'bar\'|\'foo\', array{\'baz\', \'lorem\'} and true will always evaluate to false.',
245,
255,
],
[
'Call to function in_array() with arguments \'foo\', array{\'foo\'} and true will always evaluate to true.',
253,
263,
],
[
'Call to function in_array() with arguments \'foo\', array{\'foo\', \'bar\'} and true will always evaluate to true.',
257,
267,
],
[
'Call to function in_array() with arguments \'bar\', array{}|array{\'foo\'} and true will always evaluate to false.',
321,
331,
],
[
'Call to function in_array() with arguments \'baz\', array{0: \'bar\', 1?: \'foo\'} and true will always evaluate to false.',
337,
347,
],
[
'Call to function in_array() with arguments \'foo\', array{} and true will always evaluate to false.',
344,
354,
],
[
'Call to function array_key_exists() with \'a\' and array{a: 1, b?: 2} will always evaluate to true.',
361,
371,
],
[
'Call to function array_key_exists() with \'c\' and array{a: 1, b?: 2} will always evaluate to false.',
367,
377,
],
[
'Call to function is_string() with mixed will always evaluate to false.',
561,
571,
],
[
'Call to function is_callable() with mixed will always evaluate to false.',
572,
582,
],
[
'Call to function method_exists() with \'CheckTypeFunctionCall\\\\MethodExists\' and \'testWithStringFirst…\' will always evaluate to true.',
586,
596,
],
[
'Call to function method_exists() with \'UndefinedClass\' and string will always evaluate to false.',
595,
605,
],
[
'Call to function method_exists() with \'UndefinedClass\' and \'test\' will always evaluate to false.',
598,
608,
],
[
'Call to function method_exists() with CheckTypeFunctionCall\MethodExists and \'testWithNewObjectIn…\' will always evaluate to true.',
620,
],
[
'Call to function method_exists() with CheckTypeFunctionCall\MethodExists and \'testWithNewObjectIn…\' will always evaluate to true.',
610,
635,
],
[
'Call to function method_exists() with $this(CheckTypeFunctionCall\MethodExistsWithTrait) and \'method\' will always evaluate to true.',
625,
650,
],
[
'Call to function method_exists() with $this(CheckTypeFunctionCall\MethodExistsWithTrait) and \'someAnother\' will always evaluate to true.',
628,
653,
],
[
'Call to function method_exists() with $this(CheckTypeFunctionCall\MethodExistsWithTrait) and \'unknown\' will always evaluate to false.',
631,
656,
],
[
'Call to function method_exists() with \'CheckTypeFunctionCall\\\\MethodExistsWithTrait\' and \'method\' will always evaluate to true.',
634,
659,
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Call to function method_exists() with \'CheckTypeFunctionCall\\\\MethodExistsWithTrait\' and \'someAnother\' will always evaluate to true.',
637,
662,
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Call to function method_exists() with \'CheckTypeFunctionCall\\\\MethodExistsWithTrait\' and \'unknown\' will always evaluate to false.',
640,
665,
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Call to function method_exists() with \'CheckTypeFunctionCall\\\\MethodExistsWithTrait\' and \'method\' will always evaluate to true.',
643,
668,
],
[
'Call to function method_exists() with \'CheckTypeFunctionCall\\\\MethodExistsWithTrait\' and \'someAnother\' will always evaluate to true.',
646,
671,
],
[
'Call to function method_exists() with \'CheckTypeFunctionCall\\\\MethodExistsWithTrait\' and \'unknown\' will always evaluate to false.',
649,
674,
],
[
'Call to function is_string() with string will always evaluate to true.',
678,
703,
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Call to function assert() with true will always evaluate to true.',
693,
718,
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Call to function is_numeric() with \'123\' will always evaluate to true.',
693,
718,
],
[
'Call to function assert() with false will always evaluate to false.',
694,
719,
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Call to function is_numeric() with \'blabla\' will always evaluate to false.',
694,
719,
],
[
'Call to function assert() with true will always evaluate to true.',
701,
726,
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
],
[
'Call to function is_numeric() with 123|float will always evaluate to true.',
701,
726,
],
[
'Call to function property_exists() with CheckTypeFunctionCall\Bug2221 and \'foo\' will always evaluate to true.',
784,
809,
],
[
'Call to function property_exists() with CheckTypeFunctionCall\Bug2221 and \'foo\' will always evaluate to true.',
788,
813,
],
[
'Call to function testIsInt() with int will always evaluate to true.',
875,
900,
],
[
'Call to function is_int() with int will always evaluate to true.',
889,
914,
'Remove remaining cases below this one and this error will disappear too.',
],
[
'Call to function in_array() with arguments 1, array<string> and true will always evaluate to false.',
927,
952,
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
],
],
Expand Down
25 changes: 25 additions & 0 deletions tests/PHPStan/Rules/Comparison/data/check-type-function-call.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,16 @@ public function doFoo()
}
}

public function doBar(Foo $foo)
{
if (method_exists($foo, 'test')) {

}
if (method_exists($foo, 'doFoo')) {

}
}

}

final class FinalClassWithMethodExists
Expand Down Expand Up @@ -616,6 +626,21 @@ public function testWithNewObjectInFirstArgument(): void
if (method_exists((new MethodExists()), $string)) {
}
}

public function testWithTypehintedObject(MethodExists $methodExists): void
{
/** @var string $string */
$string = doFoo();

if (method_exists($methodExists, 'testWithNewObjectInFirstArgument')) {
}

if (method_exists($methodExists, 'undefinedMethod')) {
}

if (method_exists($methodExists, $string)) {
}
}
}

trait MethodExistsTrait
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,17 @@ public function testRule(): void
'Call to method CallToMethodWithoutImpurePoints\y::myFinalBaseFunc() on a separate line has no effect.',
41,
],
[
'Call to method CallToMethodWithoutImpurePoints\y::myFinalBaseFunc() on a separate line has no effect.',
62,
],
[
'Call to method CallToMethodWithoutImpurePoints\AbstractFoo::myFunc() on a separate line has no effect.',
119,
140,
],
[
'Call to method CallToMethodWithoutImpurePoints\CallsPrivateMethodWithoutImpurePoints::doBar() on a separate line has no effect.',
127,
148,
],
]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ function (): void {
$subSubY->myFinalBaseFunc();
};

function (y $xy, finalX $finalX): void {
$xy = new y();
if (rand(0,1)) {
$xy = $finalX;
}
$xy->myFunc();
};

function (Y $xy, finalX $finalX): void {
// case-insensitive class name
if (rand(0,1)) {
$xy = $finalX;
}
$xy->myFunc();
};

function (subY $subY): void {
$subY->myFunc();
$subY->myFinalBaseFunc();
};

class y
{
function myFunc()
Expand Down
Loading
Loading