1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\PhpDocParser\Ast\PhpDoc;
4:
5: use PHPStan\PhpDocParser\Ast\Node;
6: use PHPStan\PhpDocParser\Ast\NodeAttributes;
7: use function array_column;
8: use function array_filter;
9: use function array_map;
10: use function implode;
11:
12: class PhpDocNode implements Node
13: {
14:
15: use NodeAttributes;
16:
17: /** @var PhpDocChildNode[] */
18: public $children;
19:
20: /**
21: * @param PhpDocChildNode[] $children
22: */
23: public function __construct(array $children)
24: {
25: $this->children = $children;
26: }
27:
28:
29: /**
30: * @return PhpDocTagNode[]
31: */
32: public function getTags(): array
33: {
34: return array_filter($this->children, static function (PhpDocChildNode $child): bool {
35: return $child instanceof PhpDocTagNode;
36: });
37: }
38:
39:
40: /**
41: * @return PhpDocTagNode[]
42: */
43: public function getTagsByName(string $tagName): array
44: {
45: return array_filter($this->getTags(), static function (PhpDocTagNode $tag) use ($tagName): bool {
46: return $tag->name === $tagName;
47: });
48: }
49:
50:
51: /**
52: * @return VarTagValueNode[]
53: */
54: public function getVarTagValues(string $tagName = '@var'): array
55: {
56: return array_filter(
57: array_column($this->getTagsByName($tagName), 'value'),
58: static function (PhpDocTagValueNode $value): bool {
59: return $value instanceof VarTagValueNode;
60: }
61: );
62: }
63:
64:
65: /**
66: * @return ParamTagValueNode[]
67: */
68: public function getParamTagValues(string $tagName = '@param'): array
69: {
70: return array_filter(
71: array_column($this->getTagsByName($tagName), 'value'),
72: static function (PhpDocTagValueNode $value): bool {
73: return $value instanceof ParamTagValueNode;
74: }
75: );
76: }
77:
78:
79: /**
80: * @return TypelessParamTagValueNode[]
81: */
82: public function getTypelessParamTagValues(string $tagName = '@param'): array
83: {
84: return array_filter(
85: array_column($this->getTagsByName($tagName), 'value'),
86: static function (PhpDocTagValueNode $value): bool {
87: return $value instanceof TypelessParamTagValueNode;
88: }
89: );
90: }
91:
92:
93: /**
94: * @return TemplateTagValueNode[]
95: */
96: public function getTemplateTagValues(string $tagName = '@template'): array
97: {
98: return array_filter(
99: array_column($this->getTagsByName($tagName), 'value'),
100: static function (PhpDocTagValueNode $value): bool {
101: return $value instanceof TemplateTagValueNode;
102: }
103: );
104: }
105:
106:
107: /**
108: * @return ExtendsTagValueNode[]
109: */
110: public function getExtendsTagValues(string $tagName = '@extends'): array
111: {
112: return array_filter(
113: array_column($this->getTagsByName($tagName), 'value'),
114: static function (PhpDocTagValueNode $value): bool {
115: return $value instanceof ExtendsTagValueNode;
116: }
117: );
118: }
119:
120:
121: /**
122: * @return ImplementsTagValueNode[]
123: */
124: public function getImplementsTagValues(string $tagName = '@implements'): array
125: {
126: return array_filter(
127: array_column($this->getTagsByName($tagName), 'value'),
128: static function (PhpDocTagValueNode $value): bool {
129: return $value instanceof ImplementsTagValueNode;
130: }
131: );
132: }
133:
134:
135: /**
136: * @return UsesTagValueNode[]
137: */
138: public function getUsesTagValues(string $tagName = '@use'): array
139: {
140: return array_filter(
141: array_column($this->getTagsByName($tagName), 'value'),
142: static function (PhpDocTagValueNode $value): bool {
143: return $value instanceof UsesTagValueNode;
144: }
145: );
146: }
147:
148:
149: /**
150: * @return ReturnTagValueNode[]
151: */
152: public function getReturnTagValues(string $tagName = '@return'): array
153: {
154: return array_filter(
155: array_column($this->getTagsByName($tagName), 'value'),
156: static function (PhpDocTagValueNode $value): bool {
157: return $value instanceof ReturnTagValueNode;
158: }
159: );
160: }
161:
162:
163: /**
164: * @return ThrowsTagValueNode[]
165: */
166: public function getThrowsTagValues(string $tagName = '@throws'): array
167: {
168: return array_filter(
169: array_column($this->getTagsByName($tagName), 'value'),
170: static function (PhpDocTagValueNode $value): bool {
171: return $value instanceof ThrowsTagValueNode;
172: }
173: );
174: }
175:
176:
177: /**
178: * @return MixinTagValueNode[]
179: */
180: public function getMixinTagValues(string $tagName = '@mixin'): array
181: {
182: return array_filter(
183: array_column($this->getTagsByName($tagName), 'value'),
184: static function (PhpDocTagValueNode $value): bool {
185: return $value instanceof MixinTagValueNode;
186: }
187: );
188: }
189:
190:
191: /**
192: * @return DeprecatedTagValueNode[]
193: */
194: public function getDeprecatedTagValues(): array
195: {
196: return array_filter(
197: array_column($this->getTagsByName('@deprecated'), 'value'),
198: static function (PhpDocTagValueNode $value): bool {
199: return $value instanceof DeprecatedTagValueNode;
200: }
201: );
202: }
203:
204:
205: /**
206: * @return PropertyTagValueNode[]
207: */
208: public function getPropertyTagValues(string $tagName = '@property'): array
209: {
210: return array_filter(
211: array_column($this->getTagsByName($tagName), 'value'),
212: static function (PhpDocTagValueNode $value): bool {
213: return $value instanceof PropertyTagValueNode;
214: }
215: );
216: }
217:
218:
219: /**
220: * @return PropertyTagValueNode[]
221: */
222: public function getPropertyReadTagValues(string $tagName = '@property-read'): array
223: {
224: return array_filter(
225: array_column($this->getTagsByName($tagName), 'value'),
226: static function (PhpDocTagValueNode $value): bool {
227: return $value instanceof PropertyTagValueNode;
228: }
229: );
230: }
231:
232:
233: /**
234: * @return PropertyTagValueNode[]
235: */
236: public function getPropertyWriteTagValues(string $tagName = '@property-write'): array
237: {
238: return array_filter(
239: array_column($this->getTagsByName($tagName), 'value'),
240: static function (PhpDocTagValueNode $value): bool {
241: return $value instanceof PropertyTagValueNode;
242: }
243: );
244: }
245:
246:
247: /**
248: * @return MethodTagValueNode[]
249: */
250: public function getMethodTagValues(string $tagName = '@method'): array
251: {
252: return array_filter(
253: array_column($this->getTagsByName($tagName), 'value'),
254: static function (PhpDocTagValueNode $value): bool {
255: return $value instanceof MethodTagValueNode;
256: }
257: );
258: }
259:
260:
261: /**
262: * @return TypeAliasTagValueNode[]
263: */
264: public function getTypeAliasTagValues(string $tagName = '@phpstan-type'): array
265: {
266: return array_filter(
267: array_column($this->getTagsByName($tagName), 'value'),
268: static function (PhpDocTagValueNode $value): bool {
269: return $value instanceof TypeAliasTagValueNode;
270: }
271: );
272: }
273:
274:
275: /**
276: * @return TypeAliasImportTagValueNode[]
277: */
278: public function getTypeAliasImportTagValues(string $tagName = '@phpstan-import-type'): array
279: {
280: return array_filter(
281: array_column($this->getTagsByName($tagName), 'value'),
282: static function (PhpDocTagValueNode $value): bool {
283: return $value instanceof TypeAliasImportTagValueNode;
284: }
285: );
286: }
287:
288:
289: /**
290: * @return AssertTagValueNode[]
291: */
292: public function getAssertTagValues(string $tagName = '@phpstan-assert'): array
293: {
294: return array_filter(
295: array_column($this->getTagsByName($tagName), 'value'),
296: static function (PhpDocTagValueNode $value): bool {
297: return $value instanceof AssertTagValueNode;
298: }
299: );
300: }
301:
302:
303: /**
304: * @return AssertTagPropertyValueNode[]
305: */
306: public function getAssertPropertyTagValues(string $tagName = '@phpstan-assert'): array
307: {
308: return array_filter(
309: array_column($this->getTagsByName($tagName), 'value'),
310: static function (PhpDocTagValueNode $value): bool {
311: return $value instanceof AssertTagPropertyValueNode;
312: }
313: );
314: }
315:
316:
317: /**
318: * @return AssertTagMethodValueNode[]
319: */
320: public function getAssertMethodTagValues(string $tagName = '@phpstan-assert'): array
321: {
322: return array_filter(
323: array_column($this->getTagsByName($tagName), 'value'),
324: static function (PhpDocTagValueNode $value): bool {
325: return $value instanceof AssertTagMethodValueNode;
326: }
327: );
328: }
329:
330:
331: /**
332: * @return SelfOutTagValueNode[]
333: */
334: public function getSelfOutTypeTagValues(string $tagName = '@phpstan-this-out'): array
335: {
336: return array_filter(
337: array_column($this->getTagsByName($tagName), 'value'),
338: static function (PhpDocTagValueNode $value): bool {
339: return $value instanceof SelfOutTagValueNode;
340: }
341: );
342: }
343:
344:
345: /**
346: * @return ParamOutTagValueNode[]
347: */
348: public function getParamOutTypeTagValues(string $tagName = '@param-out'): array
349: {
350: return array_filter(
351: array_column($this->getTagsByName($tagName), 'value'),
352: static function (PhpDocTagValueNode $value): bool {
353: return $value instanceof ParamOutTagValueNode;
354: }
355: );
356: }
357:
358:
359: public function __toString(): string
360: {
361: $children = array_map(
362: static function (PhpDocChildNode $child): string {
363: $s = (string) $child;
364: return $s === '' ? '' : ' ' . $s;
365: },
366: $this->children
367: );
368: return "/**\n *" . implode("\n *", $children) . "\n */";
369: }
370:
371: }
372: