Skip to content

Commit 8b82dd9

Browse files
authored
Merge pull request phpspec#605 from stof/better_analysis
Improve types for places dealing with class or interface names
2 parents 03cfe36 + 9ab4a3c commit 8b82dd9

File tree

7 files changed

+55
-62
lines changed

7 files changed

+55
-62
lines changed

phpstan-baseline.neon

+3-33
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,12 @@ parameters:
1111
path: src/Prophecy/Call/CallCenter.php
1212

1313
-
14-
message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\<T of object\\>\\|T of object, string given\\.$#"
14+
message: "#^Method Prophecy\\\\Doubler\\\\CachedDoubler\\:\\:createDoubleClass\\(\\) should return class\\-string\\<Prophecy\\\\Doubler\\\\DoubleInterface&T of object\\> but returns class\\-string\\.$#"
1515
count: 1
16-
path: src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php
16+
path: src/Prophecy/Doubler/CachedDoubler.php
1717

1818
-
19-
message: "#^Method Prophecy\\\\Doubler\\\\Doubler\\:\\:double\\(\\) should return Prophecy\\\\Doubler\\\\DoubleInterface but returns object\\.$#"
20-
count: 3
21-
path: src/Prophecy/Doubler/Doubler.php
22-
23-
-
24-
message: "#^Parameter \\#1 \\$className of method Doctrine\\\\Instantiator\\\\Instantiator\\:\\:instantiate\\(\\) expects class\\-string\\<object\\>, string given\\.$#"
25-
count: 1
26-
path: src/Prophecy/Doubler/Doubler.php
27-
28-
-
29-
message: "#^Parameter \\#1 \\$objectOrClass of class ReflectionClass constructor expects class\\-string\\<T of object\\>\\|T of object, string given\\.$#"
30-
count: 1
31-
path: src/Prophecy/Doubler/Doubler.php
32-
33-
-
34-
message: "#^Unable to resolve the template type T in call to method Doctrine\\\\Instantiator\\\\Instantiator\\:\\:instantiate\\(\\)$#"
19+
message: "#^Method Prophecy\\\\Doubler\\\\Doubler\\:\\:createDoubleClass\\(\\) should return class\\-string\\<Prophecy\\\\Doubler\\\\DoubleInterface&T of object\\> but returns class\\-string\\.$#"
3520
count: 1
3621
path: src/Prophecy/Doubler/Doubler.php
3722

@@ -44,18 +29,3 @@ parameters:
4429
message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(ReflectionIntersectionType\\|ReflectionNamedType\\)\\: mixed\\)\\|null, Closure\\(ReflectionNamedType\\)\\: string given\\.$#"
4530
count: 1
4631
path: src/Prophecy/Prophecy/MethodProphecy.php
47-
48-
-
49-
message: "#^Unable to resolve the template type T in call to method Prophecy\\\\Prophet\\:\\:prophesize\\(\\)$#"
50-
count: 1
51-
path: src/Prophecy/Prophecy/MethodProphecy.php
52-
53-
-
54-
message: "#^Method Prophecy\\\\Prophecy\\\\ObjectProphecy\\:\\:reveal\\(\\) should return T of object but returns Prophecy\\\\Doubler\\\\DoubleInterface&Prophecy\\\\Prophecy\\\\ProphecySubjectInterface\\.$#"
55-
count: 1
56-
path: src/Prophecy/Prophecy/ObjectProphecy.php
57-
58-
-
59-
message: "#^Method Prophecy\\\\Prophet\\:\\:prophesize\\(\\) should return Prophecy\\\\Prophecy\\\\ObjectProphecy\\<T of object\\> but returns Prophecy\\\\Prophecy\\\\ObjectProphecy\\<object\\>\\.$#"
60-
count: 3
61-
path: src/Prophecy/Prophet.php

src/Prophecy/Doubler/CachedDoubler.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
class CachedDoubler extends Doubler
2323
{
2424
/**
25-
* @var array<string, string>
25+
* @var array<string, class-string>
2626
*/
2727
private static $classes = array();
2828

@@ -37,8 +37,8 @@ protected function createDoubleClass(ReflectionClass $class = null, array $inter
3737
}
3838

3939
/**
40-
* @param ReflectionClass<object> $class
41-
* @param ReflectionClass<object>[] $interfaces
40+
* @param ReflectionClass<object>|null $class
41+
* @param ReflectionClass<object>[] $interfaces
4242
*
4343
* @return string
4444
*/

src/Prophecy/Doubler/Doubler.php

+12-7
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,13 @@ public function registerClassPatch(ClassPatchInterface $patch)
7777
/**
7878
* Creates double from specific class or/and list of interfaces.
7979
*
80-
* @param ReflectionClass<object>|null $class
81-
* @param ReflectionClass<object>[] $interfaces Array of ReflectionClass instances
82-
* @param array<mixed>|null $args Constructor arguments
80+
* @template T of object
8381
*
84-
* @return DoubleInterface
82+
* @param ReflectionClass<T>|null $class
83+
* @param ReflectionClass<object>[] $interfaces Array of ReflectionClass instances
84+
* @param array<mixed>|null $args Constructor arguments
85+
*
86+
* @return T&DoubleInterface
8587
*
8688
* @throws \Prophecy\Exception\InvalidArgumentException
8789
*/
@@ -118,10 +120,12 @@ public function double(ReflectionClass $class = null, array $interfaces, array $
118120
/**
119121
* Creates double class and returns its FQN.
120122
*
121-
* @param ReflectionClass<object>|null $class
122-
* @param ReflectionClass<object>[] $interfaces
123+
* @template T of object
124+
*
125+
* @param ReflectionClass<T>|null $class
126+
* @param ReflectionClass<object>[] $interfaces
123127
*
124-
* @return string
128+
* @return class-string<T&DoubleInterface>
125129
*/
126130
protected function createDoubleClass(ReflectionClass $class = null, array $interfaces)
127131
{
@@ -136,6 +140,7 @@ protected function createDoubleClass(ReflectionClass $class = null, array $inter
136140
$node->addInterface(DoubleInterface::class);
137141

138142
$this->creator->create($name, $node);
143+
\assert(class_exists($name, false));
139144

140145
return $name;
141146
}

src/Prophecy/Doubler/Generator/Node/ClassNode.php

+7-7
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
class ClassNode
2323
{
2424
/**
25-
* @var string
25+
* @var class-string
2626
*/
2727
private $parentClass = 'stdClass';
2828
/**
29-
* @var list<string>
29+
* @var list<class-string>
3030
*/
3131
private $interfaces = array();
3232

@@ -53,15 +53,15 @@ class ClassNode
5353
private $methods = array();
5454

5555
/**
56-
* @return string
56+
* @return class-string
5757
*/
5858
public function getParentClass()
5959
{
6060
return $this->parentClass;
6161
}
6262

6363
/**
64-
* @param string $class
64+
* @param class-string|null $class
6565
*
6666
* @return void
6767
*/
@@ -71,15 +71,15 @@ public function setParentClass($class)
7171
}
7272

7373
/**
74-
* @return list<string>
74+
* @return list<class-string>
7575
*/
7676
public function getInterfaces()
7777
{
7878
return $this->interfaces;
7979
}
8080

8181
/**
82-
* @param string $interface
82+
* @param class-string $interface
8383
*
8484
* @return void
8585
*/
@@ -93,7 +93,7 @@ public function addInterface($interface)
9393
}
9494

9595
/**
96-
* @param string $interface
96+
* @param class-string $interface
9797
*
9898
* @return bool
9999
*/

src/Prophecy/Doubler/LazyDouble.php

+21-9
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
* Lazy double.
2121
* Gives simple interface to describe double before creating it.
2222
*
23+
* @template T of object
24+
*
2325
* @author Konstantin Kudryashov <[email protected]>
2426
*/
2527
class LazyDouble
2628
{
2729
private $doubler;
2830
/**
29-
* @var ReflectionClass<object>|null
31+
* @var ReflectionClass<T>|null
3032
*/
3133
private $class;
3234
/**
@@ -38,7 +40,7 @@ class LazyDouble
3840
*/
3941
private $arguments = null;
4042
/**
41-
* @var DoubleInterface|null
43+
* @var (T&DoubleInterface)|null
4244
*/
4345
private $double;
4446

@@ -50,12 +52,16 @@ public function __construct(Doubler $doubler)
5052
/**
5153
* Tells doubler to use specific class as parent one for double.
5254
*
53-
* @param string|ReflectionClass<object> $class
55+
* @param class-string|ReflectionClass<object> $class
5456
*
5557
* @return void
5658
*
57-
* @throws \Prophecy\Exception\Doubler\ClassNotFoundException
58-
* @throws \Prophecy\Exception\Doubler\DoubleException
59+
* @template U of object
60+
* @phpstan-param class-string<U>|ReflectionClass<U> $class
61+
* @phpstan-this-out static<U>
62+
*
63+
* @throws ClassNotFoundException
64+
* @throws DoubleException
5965
*/
6066
public function setParentClass($class)
6167
{
@@ -71,18 +77,24 @@ public function setParentClass($class)
7177
$class = new ReflectionClass($class);
7278
}
7379

80+
/** @var static<U> $this */
81+
7482
$this->class = $class;
7583
}
7684

7785
/**
7886
* Tells doubler to implement specific interface with double.
7987
*
80-
* @param string|ReflectionClass<object> $interface
88+
* @param class-string|ReflectionClass<object> $interface
8189
*
8290
* @return void
8391
*
84-
* @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException
85-
* @throws \Prophecy\Exception\Doubler\DoubleException
92+
* @template U of object
93+
* @phpstan-param class-string<U>|ReflectionClass<U> $interface
94+
* @phpstan-this-out static<T&U>
95+
*
96+
* @throws InterfaceNotFoundException
97+
* @throws DoubleException
8698
*/
8799
public function addInterface($interface)
88100
{
@@ -121,7 +133,7 @@ public function setArguments(array $arguments = null)
121133
/**
122134
* Creates double instance or returns already created one.
123135
*
124-
* @return DoubleInterface
136+
* @return T&DoubleInterface
125137
*/
126138
public function getInstance()
127139
{

src/Prophecy/Prophecy/ObjectProphecy.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
*/
3232
class ObjectProphecy implements ProphecyInterface
3333
{
34+
/**
35+
* @var LazyDouble<T>
36+
*/
3437
private $lazyDouble;
3538
private $callCenter;
3639
private $revealer;
@@ -41,6 +44,9 @@ class ObjectProphecy implements ProphecyInterface
4144
*/
4245
private $methodProphecies = array();
4346

47+
/**
48+
* @param LazyDouble<T> $lazyDouble
49+
*/
4450
public function __construct(
4551
LazyDouble $lazyDouble,
4652
CallCenter $callCenter = null,
@@ -61,7 +67,7 @@ public function __construct(
6167
*
6268
* @return $this
6369
*
64-
* @template U
70+
* @template U of object
6571
* @phpstan-param class-string<U> $class
6672
* @phpstan-this-out static<T&U>
6773
*/
@@ -79,7 +85,7 @@ public function willExtend($class)
7985
*
8086
* @return $this
8187
*
82-
* @template U
88+
* @template U of object
8389
* @phpstan-param class-string<U> $interface
8490
* @phpstan-this-out static<T&U>
8591
*/

src/Prophecy/Prophet.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public function __construct(
7474
*
7575
* @template T of object
7676
* @phpstan-param class-string<T>|null $classOrInterface
77-
* @phpstan-return ObjectProphecy<T>
77+
* @phpstan-return ($classOrInterface is null ? ObjectProphecy<object> : ObjectProphecy<T>)
7878
*/
7979
public function prophesize($classOrInterface = null)
8080
{

0 commit comments

Comments
 (0)