blob: f4fb13b80852321aca8236285bae12737b18ea7b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
<?php
declare(strict_types=1);
namespace OpenTelemetry\SDK\Common\Util;
use Closure;
use function get_class;
use ReflectionFunction;
use stdClass;
use WeakReference;
/**
* @internal
*/
function closure(callable $callable): Closure
{
return Closure::fromCallable($callable);
}
/**
* @internal
* @see https://github.com/amphp/amp/blob/f682341c856b1f688026f787bef4f77eaa5c7970/src/functions.php#L140-L191
*/
function weaken(Closure $closure, ?object &$target = null): Closure
{
$reflection = new ReflectionFunction($closure);
if (!$target = $reflection->getClosureThis()) {
return $closure;
}
$scope = $reflection->getClosureScopeClass();
$name = $reflection->getShortName();
if ($name !== '{closure}') {
/** @psalm-suppress InvalidScope @phpstan-ignore-next-line @phan-suppress-next-line PhanUndeclaredThis */
$closure = fn (...$args) => $this->$name(...$args);
if ($scope !== null) {
$closure = $closure->bindTo(null, $scope->name);
}
}
static $placeholder;
$placeholder ??= new stdClass();
$closure = $closure->bindTo($placeholder);
$ref = WeakReference::create($target);
/** @psalm-suppress PossiblyInvalidFunctionCall */
return $scope && get_class($target) === $scope->name && !$scope->isInternal()
? static fn (...$args) => ($obj = $ref->get()) ? $closure->call($obj, ...$args) : null
: static fn (...$args) => ($obj = $ref->get()) ? $closure->bindTo($obj)(...$args) : null;
}
|