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