|
27 | 27 | *
|
28 | 28 | * @final
|
29 | 29 | */
|
30 |
| -class PhpDocExtractor implements PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface |
| 30 | +class PhpDocExtractor implements PropertyDescriptionExtractorInterface, PropertyTypeExtractorInterface, ConstructorArgumentTypeExtractorInterface |
31 | 31 | {
|
32 | 32 | const PROPERTY = 0;
|
33 | 33 | const ACCESSOR = 1;
|
@@ -151,6 +151,63 @@ public function getTypes($class, $property, array $context = [])
|
151 | 151 | return [new Type(Type::BUILTIN_TYPE_ARRAY, false, null, true, new Type(Type::BUILTIN_TYPE_INT), $types[0])];
|
152 | 152 | }
|
153 | 153 |
|
| 154 | + /** |
| 155 | + * {@inheritdoc} |
| 156 | + */ |
| 157 | + public function getTypesFromConstructor(string $class, string $property): ?array |
| 158 | + { |
| 159 | + $docBlock = $this->getDocBlockFromConstructor($class, $property); |
| 160 | + |
| 161 | + if (!$docBlock) { |
| 162 | + return null; |
| 163 | + } |
| 164 | + |
| 165 | + $types = []; |
| 166 | + /** @var DocBlock\Tags\Var_|DocBlock\Tags\Return_|DocBlock\Tags\Param $tag */ |
| 167 | + foreach ($docBlock->getTagsByName('param') as $tag) { |
| 168 | + if ($tag && null !== $tag->getType()) { |
| 169 | + $types = array_merge($types, $this->phpDocTypeHelper->getTypes($tag->getType())); |
| 170 | + } |
| 171 | + } |
| 172 | + |
| 173 | + if (!isset($types[0])) { |
| 174 | + return null; |
| 175 | + } |
| 176 | + |
| 177 | + return $types; |
| 178 | + } |
| 179 | + |
| 180 | + private function getDocBlockFromConstructor(string $class, string $property): ?DocBlock |
| 181 | + { |
| 182 | + try { |
| 183 | + $reflectionClass = new \ReflectionClass($class); |
| 184 | + } catch (\ReflectionException $e) { |
| 185 | + return null; |
| 186 | + } |
| 187 | + $reflectionConstructor = $reflectionClass->getConstructor(); |
| 188 | + if (!$reflectionConstructor) { |
| 189 | + return null; |
| 190 | + } |
| 191 | + |
| 192 | + try { |
| 193 | + $docBlock = $this->docBlockFactory->create($reflectionConstructor, $this->contextFactory->createFromReflector($reflectionConstructor)); |
| 194 | + |
| 195 | + return $this->filterDocBlockParams($docBlock, $property); |
| 196 | + } catch (\InvalidArgumentException $e) { |
| 197 | + return null; |
| 198 | + } |
| 199 | + } |
| 200 | + |
| 201 | + private function filterDocBlockParams(DocBlock $docBlock, string $allowedParam): DocBlock |
| 202 | + { |
| 203 | + $tags = array_values(array_filter($docBlock->getTagsByName('param'), function ($tag) use ($allowedParam) { |
| 204 | + return $tag instanceof DocBlock\Tags\Param && $allowedParam === $tag->getVariableName(); |
| 205 | + })); |
| 206 | + |
| 207 | + return new DocBlock($docBlock->getSummary(), $docBlock->getDescription(), $tags, $docBlock->getContext(), |
| 208 | + $docBlock->getLocation(), $docBlock->isTemplateStart(), $docBlock->isTemplateEnd()); |
| 209 | + } |
| 210 | + |
154 | 211 | private function getDocBlock(string $class, string $property): array
|
155 | 212 | {
|
156 | 213 | $propertyHash = sprintf('%s::%s', $class, $property);
|
|
0 commit comments