These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace phpDocumentor\Descriptor\Builder\Reflector\Tags; |
||
4 | |||
5 | use phpDocumentor\Descriptor\Builder\Reflector\AssemblerAbstract; |
||
6 | use phpDocumentor\Descriptor\Collection as DescriptorCollection; |
||
7 | use phpDocumentor\Descriptor\DescriptorAbstract; |
||
8 | use phpDocumentor\Descriptor\Type\CollectionDescriptor; |
||
9 | use phpDocumentor\Descriptor\Type\UnknownTypeDescriptor; |
||
10 | use phpDocumentor\Reflection\DocBlock\Type\Collection; |
||
11 | |||
12 | /** |
||
13 | * Creates a Collection of type-related value objects for the given Type Collection from the Reflector. |
||
14 | */ |
||
15 | class TypeCollectionAssembler extends AssemblerAbstract |
||
16 | { |
||
17 | /** @var string[] a mapping of types to class names of the Value Object class that describes each type */ |
||
18 | protected $typeToValueObjectClassName = array( |
||
19 | 'string' => 'phpDocumentor\Descriptor\Type\StringDescriptor', |
||
20 | 'int' => 'phpDocumentor\Descriptor\Type\IntegerDescriptor', |
||
21 | 'integer' => 'phpDocumentor\Descriptor\Type\IntegerDescriptor', |
||
22 | 'float' => 'phpDocumentor\Descriptor\Type\FloatDescriptor', |
||
23 | 'boolean' => 'phpDocumentor\Descriptor\Type\BooleanDescriptor', |
||
24 | 'bool' => 'phpDocumentor\Descriptor\Type\BooleanDescriptor', |
||
25 | ); |
||
26 | |||
27 | /** |
||
28 | * Creates a Descriptor from the provided data. |
||
29 | * |
||
30 | * @param Collection $data |
||
31 | * |
||
32 | * @return DescriptorCollection |
||
33 | */ |
||
34 | public function create($data) |
||
35 | { |
||
36 | $collection = new DescriptorCollection(); |
||
37 | |||
38 | foreach ($data as $type) { |
||
39 | $collection->add($this->createDescriptorForType($type)); |
||
40 | } |
||
41 | |||
42 | return $collection; |
||
43 | } |
||
44 | |||
45 | /** |
||
46 | * Creates a Type ValueObject (Descriptor) for the provided type string. |
||
47 | * |
||
48 | * @param string $type |
||
49 | * |
||
50 | * @return DescriptorAbstract |
||
51 | */ |
||
52 | protected function createDescriptorForType($type) |
||
53 | { |
||
54 | if (!$this->isArrayNotation($type)) { |
||
55 | $className = $this->findClassNameForType($type); |
||
56 | |||
57 | return $className ? new $className() : new UnknownTypeDescriptor($type); |
||
58 | } |
||
59 | |||
60 | $type = $this->extractTypeFromArrayNotation($type); |
||
61 | $className = $this->findClassNameForType($type); |
||
62 | $descriptor = $className ? new $className() : new UnknownTypeDescriptor($type); |
||
63 | $descriptor = $this->convertToArrayDescriptor($descriptor); |
||
64 | |||
65 | return $descriptor; |
||
0 ignored issues
–
show
|
|||
66 | } |
||
67 | |||
68 | /** |
||
69 | * Detects if the given string representing a type equals an array. |
||
70 | * |
||
71 | * @param string $type |
||
72 | * |
||
73 | * @return boolean |
||
74 | */ |
||
75 | protected function isArrayNotation($type) |
||
76 | { |
||
77 | return (substr($type, -2) == '[]'); |
||
78 | } |
||
79 | |||
80 | /** |
||
81 | * Returns the value-type from an array notation. |
||
82 | * |
||
83 | * @param string $type |
||
84 | * |
||
85 | * @return string |
||
86 | */ |
||
87 | protected function extractTypeFromArrayNotation($type) |
||
88 | { |
||
89 | return substr($type, 0, -2); |
||
90 | } |
||
91 | |||
92 | /** |
||
93 | * Wraps the given Descriptor inside a Collection Descriptor of type array and returns that. |
||
94 | * |
||
95 | * @param DescriptorAbstract $descriptor |
||
96 | * |
||
97 | * @return CollectionDescriptor |
||
98 | */ |
||
99 | protected function convertToArrayDescriptor($descriptor) |
||
100 | { |
||
101 | $arrayDescriptor = new CollectionDescriptor('array'); |
||
0 ignored issues
–
show
'array' is of type string , but the function expects a object<phpDocumentor\Des...terfaces\TypeInterface> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
102 | $arrayDescriptor->setTypes(array($descriptor)); |
||
0 ignored issues
–
show
array($descriptor) is of type array<integer,object<php...\DescriptorAbstract>"}> , but the function expects a array<integer,object<php...erfaces\TypeInterface>> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
103 | $arrayDescriptor->setKeyTypes(array('mixed')); |
||
0 ignored issues
–
show
array('mixed') is of type array<integer,string,{"0":"string"}> , but the function expects a array<integer,object<php...erfaces\TypeInterface>> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
104 | |||
105 | return $arrayDescriptor; |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * Returns the class name of the Value Object class associated with a given type or false if the type is unknown. |
||
110 | * |
||
111 | * @param string $type |
||
112 | * |
||
113 | * @return string|boolean |
||
114 | */ |
||
115 | protected function findClassNameForType($type) |
||
116 | { |
||
117 | $className = $this->typeToValueObjectClassName[$type] ?? false; |
||
118 | |||
119 | return $className; |
||
120 | } |
||
121 | } |
||
122 |
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.
Let’s take a look at an example:
Our function
my_function
expects aPost
object, and outputs the author of the post. The base classPost
returns a simple string and outputting a simple string will work just fine. However, the child classBlogPost
which is a sub-type ofPost
instead decided to return anobject
, and is therefore violating the SOLID principles. If aBlogPost
were passed tomy_function
, PHP would not complain, but ultimately fail when executing thestrtoupper
call in its body.