Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 19e4658

Browse files
Resolve static in assert PHPDoc
1 parent e3c0981 commit 19e4658

File tree

8 files changed

+211
-1
lines changed

8 files changed

+211
-1
lines changed

‎src/Reflection/Dummy/ChangedTypeMethodReflection.php‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public function __construct(
2727
private ?array $namedArgumentsVariants,
2828
private ?Type $selfOutType,
2929
private ?Type $throwType,
30+
private Assertions $assertions,
3031
)
3132
{
3233
}
@@ -133,7 +134,7 @@ public function hasSideEffects(): TrinaryLogic
133134

134135
public function getAsserts(): Assertions
135136
{
136-
return $this->reflection->getAsserts();
137+
return $this->assertions;
137138
}
138139

139140
public function acceptsNamedArguments(): TrinaryLogic

‎src/Reflection/Type/CallbackUnresolvedMethodPrototypeReflection.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ private function transformMethodWithStaticType(ClassReflection $declaringClass,
137137
$namedArgumentVariants,
138138
$selfOutType,
139139
$throwType,
140+
$method->getAsserts()->mapTypes($this->transformStaticTypeCallback),
140141
);
141142
}
142143

‎src/Reflection/Type/CalledOnTypeUnresolvedMethodPrototypeReflection.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ private function transformMethodWithStaticType(ClassReflection $declaringClass,
132132
$namedArgumentsVariants,
133133
$selfOutType,
134134
$throwType,
135+
$method->getAsserts()->mapTypes(fn (Type $type): Type => $this->transformStaticType($type)),
135136
);
136137
}
137138

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug12376;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* workaround https://github.com/phpstan/phpstan-src/pull/3853
9+
*
10+
* @template T of object
11+
* @param class-string<T> $class
12+
* @return T
13+
*/
14+
function newNonFinalInstance(string $class): object
15+
{
16+
return new $class();
17+
}
18+
19+
class Base {}
20+
21+
class A extends Base
22+
{
23+
/**
24+
* @template T of object
25+
* @param T $object
26+
* @return (T is static ? T : static)
27+
*
28+
* @phpstan-assert static $object
29+
*/
30+
public static function assertInstanceOf(object $object)
31+
{
32+
if (!$object instanceof static) {
33+
throw new \Exception();
34+
}
35+
36+
return $object;
37+
}
38+
}
39+
40+
class B extends A {}
41+
class C extends Base {}
42+
43+
$o = newNonFinalInstance(\DateTime::class);
44+
$r = A::assertInstanceOf($o);
45+
assertType('*NEVER*', $o);
46+
assertType('Bug12376\A', $r);
47+
48+
$o = newNonFinalInstance(A::class);
49+
$r = A::assertInstanceOf($o);
50+
assertType('Bug12376\A', $o);
51+
assertType('Bug12376\A', $r);
52+
53+
$o = newNonFinalInstance(B::class);
54+
$r = A::assertInstanceOf($o);
55+
assertType('Bug12376\B', $o);
56+
assertType('Bug12376\B', $r);
57+
58+
$o = newNonFinalInstance(C::class);
59+
$r = A::assertInstanceOf($o);
60+
assertType('*NEVER*', $o);
61+
assertType('Bug12376\A', $r);
62+
63+
$o = newNonFinalInstance(A::class);
64+
$r = B::assertInstanceOf($o);
65+
assertType('Bug12376\B', $o);
66+
assertType('Bug12376\B', $r);

‎tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,6 +3608,16 @@ public function testBug9141(): void
36083608
$this->analyse([__DIR__ . '/data/bug-9141.php'], []);
36093609
}
36103610

3611+
public function testBug12548(): void
3612+
{
3613+
$this->checkThisOnly = false;
3614+
$this->checkNullables = true;
3615+
$this->checkUnionTypes = true;
3616+
$this->checkExplicitMixed = true;
3617+
3618+
$this->analyse([__DIR__ . '/data/bug-12548.php'], []);
3619+
}
3620+
36113621
public function testBug3589(): void
36123622
{
36133623
$this->checkThisOnly = false;
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug12548;
4+
5+
class BaseSat extends \stdClass
6+
{
7+
/**
8+
* @template T of object
9+
*
10+
* @param T $object
11+
*
12+
* @phpstan-assert-if-true =static $object
13+
*/
14+
public static function assertInstanceOf(object $object): bool
15+
{
16+
return $object instanceof static;
17+
}
18+
19+
/**
20+
* @template T of object
21+
*
22+
* @param T $object
23+
*
24+
* @return (T is static ? T : static)
25+
*
26+
* @phpstan-assert static $object
27+
*/
28+
public static function assertInstanceOf2(object $object)
29+
{
30+
if (!$object instanceof static) {
31+
throw new \Error('Object is not an instance of static class');
32+
}
33+
34+
return $object;
35+
}
36+
}
37+
38+
class StdSat extends BaseSat
39+
{
40+
public function foo(): void {}
41+
42+
/**
43+
* @template T of object
44+
*
45+
* @param T $object
46+
*
47+
* @return (T is static ? T : static)
48+
*
49+
* @phpstan-assert static $object
50+
*/
51+
public static function assertInstanceOf3(object $object)
52+
{
53+
if (!$object instanceof static) {
54+
throw new \Error('Object is not an instance of static class');
55+
}
56+
57+
return $object;
58+
}
59+
}
60+
61+
class TestCase
62+
{
63+
private function createStdSat(): \stdClass
64+
{
65+
return new StdSat();
66+
}
67+
68+
public function testAssertInstanceOf(): void
69+
{
70+
$o = $this->createStdSat();
71+
$o->foo(); // @phpstan-ignore method.nonObject (EXPECTED)
72+
73+
$o = $this->createStdSat();
74+
if (StdSat::assertInstanceOf($o)) {
75+
$o->foo();
76+
}
77+
78+
$o = $this->createStdSat();
79+
StdSat::assertInstanceOf2($o);
80+
$o->foo();
81+
82+
$o = $this->createStdSat();
83+
StdSat::assertInstanceOf3($o);
84+
$o->foo();
85+
}
86+
}

‎tests/PHPStan/Rules/Properties/AccessPropertiesRuleTest.php‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,14 @@ public function testBug12645(): void
11651165
]);
11661166
}
11671167

1168+
public function testBug11289(): void
1169+
{
1170+
$this->checkThisOnly = false;
1171+
$this->checkUnionTypes = true;
1172+
$this->checkDynamicProperties = false;
1173+
$this->analyse([__DIR__ . '/data/bug-11289.php'], []);
1174+
}
1175+
11681176
public function testBug8668(): void
11691177
{
11701178
$this->checkThisOnly = false;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php // lint >= 8.0
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug11289;
6+
7+
abstract class SomeAbstractClass
8+
{
9+
private bool $someValue = true;
10+
11+
/**
12+
* @phpstan-assert-if-true =static $other
13+
*/
14+
public function equals(?self $other): bool
15+
{
16+
return $other instanceof static
17+
&& $this->someValue === $other->someValue;
18+
}
19+
}
20+
21+
class SomeConcreteClass extends SomeAbstractClass
22+
{
23+
public function __construct(
24+
private bool $someOtherValue,
25+
) {}
26+
27+
public function equals(?SomeAbstractClass $other): bool
28+
{
29+
return parent::equals($other)
30+
&& $this->someOtherValue === $other->someOtherValue;
31+
}
32+
}
33+
34+
$a = new SomeConcreteClass(true);
35+
$b = new SomeConcreteClass(false);
36+
37+
var_dump($a->equals($b), $b->equals($b));

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /