Skip to content

Commit 542cb0a

Browse files
Michael Voříšekondrejmirtes
authored andcommitted
Narrow Closure::bind $newScope param
1 parent 29c440e commit 542cb0a

File tree

5 files changed

+49
-1
lines changed

5 files changed

+49
-1
lines changed

resources/functionMap_bleedingEdge.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
return [
44
'new' => [
5+
'Closure::bind' => ['Closure', 'old'=>'Closure', 'to'=>'?object', 'scope='=>'object|class-string|\'static\'|null'],
6+
'Closure::bindTo' => ['Closure', 'new'=>'?object', 'newscope='=>'object|class-string|\'static\'|null'],
57
'error_log' => ['bool', 'message'=>'string', 'message_type='=>'0|1|2|3|4', 'destination='=>'string', 'extra_headers='=>'string'],
68
'SplFileObject::flock' => ['bool', 'operation'=>'int-mask<LOCK_SH, LOCK_EX, LOCK_UN, LOCK_NB>', '&w_wouldblock='=>'0|1'],
79
'Imagick::adaptiveBlurImage' => ['bool', 'radius'=>'float', 'sigma'=>'float', 'channel='=>'Imagick::CHANNEL_*'],

tests/PHPStan/Reflection/SignatureMap/Php8SignatureMapProviderTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPStan\Type\ArrayType;
1515
use PHPStan\Type\BooleanType;
1616
use PHPStan\Type\CallableType;
17+
use PHPStan\Type\ClassStringType;
1718
use PHPStan\Type\Constant\ConstantArrayType;
1819
use PHPStan\Type\Constant\ConstantBooleanType;
1920
use PHPStan\Type\Constant\ConstantStringType;
@@ -189,7 +190,8 @@ public function dataMethods(): array
189190
'optional' => true,
190191
'type' => new UnionType([
191192
new ObjectWithoutClassType(),
192-
new StringType(),
193+
new ClassStringType(),
194+
new ConstantStringType('static'),
193195
new NullType(),
194196
]),
195197
'nativeType' => new UnionType([

tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,10 @@ public function testClosureBind(): void
968968
'Call to an undefined method CallClosureBind\Foo::nonexistentMethod().',
969969
44,
970970
],
971+
[
972+
'Parameter #2 $newScope of method Closure::bindTo() expects \'static\'|class-string|object|null, \'CallClosureBind\\\Bar3\' given.',
973+
74,
974+
],
971975
]);
972976
}
973977

tests/PHPStan/Rules/Methods/CallStaticMethodsRuleTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,4 +817,15 @@ public function testConditionalParam(): void
817817
]);
818818
}
819819

820+
public function testClosureBind(): void
821+
{
822+
$this->checkThisOnly = false;
823+
$this->analyse([__DIR__ . '/data/closure-bind.php'], [
824+
[
825+
'Parameter #3 $newScope of static method Closure::bind() expects \'static\'|class-string|object|null, \'CallClosureBind\\\Bar3\' given.',
826+
68,
827+
],
828+
]);
829+
}
830+
820831
}

tests/PHPStan/Rules/Methods/data/closure-bind.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,33 @@ public function fooMethod(): Foo
4949
})->call(new Foo());
5050
}
5151

52+
public function x(): bool
53+
{
54+
return 1.0;
55+
}
56+
57+
public function testClassString(): bool
58+
{
59+
$fx = function () {
60+
return $this->x();
61+
};
62+
63+
$res = 0.0;
64+
$res += \Closure::bind($fx, $this)();
65+
$res += \Closure::bind($fx, $this, 'static')();
66+
$res += \Closure::bind($fx, $this, Foo2::class)();
67+
$res += \Closure::bind($fx, $this, 'CallClosureBind\Bar2')();
68+
$res += \Closure::bind($fx, $this, 'CallClosureBind\Bar3')();
69+
70+
$res += $fx->bindTo($this)();
71+
$res += $fx->bindTo($this, 'static')();
72+
$res += $fx->bindTo($this, Foo2::class)();
73+
$res += $fx->bindTo($this, 'CallClosureBind\Bar2')();
74+
$res += $fx->bindTo($this, 'CallClosureBind\Bar3')();
75+
76+
return $res;
77+
}
78+
5279
}
80+
81+
class Bar2 extends Bar {}

0 commit comments

Comments
 (0)