1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of Railt package. |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
*/ |
8
|
|
|
declare(strict_types=1); |
9
|
|
|
|
10
|
|
|
namespace Railt\Reflection\Dictionary; |
11
|
|
|
|
12
|
|
|
use Railt\Reflection\Contracts\Definition; |
13
|
|
|
use Railt\Reflection\Contracts\Definition\TypeDefinition; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Class CallbackDictionary |
17
|
|
|
*/ |
18
|
|
|
class CallbackDictionary extends SimpleDictionary |
19
|
|
|
{ |
20
|
|
|
/** |
21
|
|
|
* @var array|\Closure[] |
22
|
|
|
*/ |
23
|
|
|
private $callbacks = []; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @param \Closure $then |
27
|
|
|
*/ |
28
|
|
|
public function onTypeNotFound(\Closure $then): void |
29
|
|
|
{ |
30
|
|
|
$this->callbacks[] = $then; |
31
|
|
|
} |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* @param string $name |
35
|
|
|
* @param Definition|null $from |
36
|
|
|
* @return TypeDefinition |
37
|
|
|
* @throws \Railt\Reflection\Exception\TypeNotFoundException |
38
|
|
|
*/ |
39
|
|
|
public function get(string $name, Definition $from = null): TypeDefinition |
40
|
|
|
{ |
41
|
|
|
$this->invoke($name, $from); |
|
|
|
|
42
|
|
|
|
43
|
|
|
return parent::get($name, $from); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @param string $name |
48
|
|
|
* @param TypeDefinition|null $from |
49
|
|
|
*/ |
50
|
|
|
private function invoke(string $name, TypeDefinition $from = null): void |
51
|
|
|
{ |
52
|
|
|
foreach ($this->callbacks as $callback) { |
53
|
|
|
if (! $this->has($name)) { |
54
|
|
|
$callback($name, $from, function (TypeDefinition $type): void { |
55
|
|
|
$this->add($type); |
56
|
|
|
}); |
57
|
|
|
} |
58
|
|
|
} |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @param string $name |
63
|
|
|
* @return bool |
64
|
|
|
*/ |
65
|
|
|
public function has(string $name): bool |
66
|
|
|
{ |
67
|
|
|
$this->invoke($name); |
68
|
|
|
|
69
|
|
|
return parent::has($name); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @param string $name |
74
|
|
|
* @return null|TypeDefinition |
75
|
|
|
*/ |
76
|
|
|
public function find(string $name): ?TypeDefinition |
77
|
|
|
{ |
78
|
|
|
$this->invoke($name); |
79
|
|
|
|
80
|
|
|
return parent::find($name); |
81
|
|
|
} |
82
|
|
|
} |
83
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.