mago_docblock/
document.rs

1use mago_span::HasSpan;
2use serde::Deserialize;
3use serde::Serialize;
4
5use mago_interner::StringIdentifier;
6use mago_span::Span;
7
8#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
9pub struct Document {
10    pub span: Span,
11    pub elements: Vec<Element>,
12}
13
14#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
15pub enum Element {
16    Text(Text),
17    Code(Code),
18    Tag(Tag),
19    Line(Span),
20    Annotation(Annotation),
21}
22
23#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
24pub struct Text {
25    pub span: Span,
26    pub segments: Vec<TextSegment>,
27}
28
29#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
30pub struct Code {
31    pub span: Span,
32    pub directives: Vec<StringIdentifier>,
33    pub content: StringIdentifier,
34}
35
36#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
37pub enum TextSegment {
38    Paragraph { span: Span, content: StringIdentifier },
39    InlineCode(Code),
40    InlineTag(Tag),
41}
42
43#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
44pub struct Annotation {
45    pub span: Span,
46    pub name: StringIdentifier,
47    pub arguments: Option<StringIdentifier>,
48}
49
50#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
51pub struct Tag {
52    pub span: Span,
53    pub name: StringIdentifier,
54    pub kind: TagKind,
55    pub description: StringIdentifier,
56    pub description_span: Span,
57}
58
59#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
60#[non_exhaustive]
61pub enum TagKind {
62    Abstract,
63    Access,
64    Author,
65    Category,
66    Copyright,
67    Deprecated,
68    Example,
69    Final,
70    FileSource,
71    Global,
72    Ignore,
73    Internal,
74    License,
75    Link,
76    Method,
77    Mixin,
78    Name,
79    Package,
80    Param,
81    Property,
82    PropertyRead,
83    PropertyWrite,
84    SealProperties,
85    NoSealProperties,
86    SealMethods,
87    NoSealMethods,
88    ReadOnly,
89    NoNamedArguments,
90    Api,
91    PsalmApi,
92    PsalmInheritors,
93    Return,
94    See,
95    Since,
96    Static,
97    StaticVar,
98    SubPackage,
99    Todo,
100    Tutorial,
101    Uses,
102    Var,
103    Throws,
104    Version,
105    ParamLaterInvokedCallable,
106    ParamImmediatelyInvokedCallable,
107    ParamClosureThis,
108    Extends,
109    Implements,
110    Use,
111    NotDeprecated,
112    PhpstanImpure,
113    PhpstanPure,
114    Pure,
115    Immutable,
116    InheritDoc,
117    ParamOut,
118    Assert,
119    AssertIfTrue,
120    AssertIfFalse,
121    ConsistentConstructor,
122    PsalmConsistentConstructor,
123    PsalmConsistentTemplates,
124    PsalmParamOut,
125    PsalmVar,
126    PsalmParam,
127    PsalmReturn,
128    PsalmProperty,
129    PsalmPropertyRead,
130    PsalmPropertyWrite,
131    PsalmMethod,
132    PsalmIgnoreVar,
133    PsalmSuppress,
134    PsalmAssert,
135    PsalmAssertIfTrue,
136    PsalmAssertIfFalse,
137    PsalmIfThisIs,
138    PsalmThisOut,
139    PsalmIgnoreNullableReturn,
140    PsalmIgnoreFalsableReturn,
141    PsalmSealProperties,
142    PsalmNoSealProperties,
143    PsalmSealMethods,
144    PsalmNoSealMethods,
145    PsalmInternal,
146    PsalmReadOnly,
147    PsalmMutationFree,
148    PsalmExternalMutationFree,
149    MutationFree,
150    ExternalMutationFree,
151    PsalmImmutable,
152    PsalmPure,
153    PsalmAllowPrivateMutation,
154    PsalmReadOnlyAllowPrivateMutation,
155    PsalmTrace,
156    PsalmCheckType,
157    PsalmCheckTypeExact,
158    PsalmTaintSource,
159    PsalmTaintSink,
160    PsalmTaintEscape,
161    PsalmTaintUnescape,
162    PsalmTaintSpecialize,
163    PsalmFlow,
164    PsalmType,
165    PsalmImportType,
166    PsalmRequireExtends,
167    PsalmRequireImplements,
168    PsalmIgnoreVariableProperty,
169    PsalmIgnoreVariableMethod,
170    PsalmYield,
171    PhpstanAssert,
172    PhpstanAssertIfTrue,
173    PhpstanAssertIfFalse,
174    PhpstanSelfOut,
175    PhpstanThisOut,
176    PhpstanRequireExtends,
177    PhpstanRequireImplements,
178    PhpstanParam,
179    PhpstanReturn,
180    PhpstanVar,
181    PhpstanReadOnly,
182    PhpstanImmutable,
183    Template,
184    TemplateInvariant,
185    TemplateCovariant,
186    TemplateContravariant,
187    PsalmTemplate,
188    PsalmTemplateInvariant,
189    PsalmTemplateCovariant,
190    PsalmTemplateContravariant,
191    PhpstanTemplate,
192    PhpstanTemplateInvariant,
193    PhpstanTemplateCovariant,
194    PhpstanTemplateContravariant,
195    Other,
196}
197
198#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Serialize, Deserialize, PartialOrd, Ord)]
199pub enum TagVendor {
200    Phpstan,
201    Psalm,
202}
203
204impl Document {
205    pub fn get_tags(&self) -> impl Iterator<Item = &Tag> {
206        self.elements.iter().filter_map(|element| if let Element::Tag(tag) = element { Some(tag) } else { None })
207    }
208
209    pub fn get_tags_by_kind(&self, kind: TagKind) -> impl Iterator<Item = &Tag> {
210        self.get_tags().filter(move |tag| tag.kind == kind)
211    }
212}
213
214impl HasSpan for Document {
215    fn span(&self) -> Span {
216        self.span
217    }
218}
219
220impl TagKind {
221    /// Returns the vendor of the tag, if it has one.
222    ///
223    /// If the tag does not have a vendor, `None` is returned.
224    pub fn get_vendor(&self) -> Option<TagVendor> {
225        match self {
226            Self::PsalmConsistentConstructor
227            | Self::PsalmConsistentTemplates
228            | Self::PsalmParamOut
229            | Self::PsalmVar
230            | Self::PsalmParam
231            | Self::PsalmReturn
232            | Self::PsalmProperty
233            | Self::PsalmPropertyRead
234            | Self::PsalmPropertyWrite
235            | Self::PsalmMethod
236            | Self::PsalmIgnoreVar
237            | Self::PsalmSuppress
238            | Self::PsalmAssert
239            | Self::PsalmAssertIfTrue
240            | Self::PsalmAssertIfFalse
241            | Self::PsalmIfThisIs
242            | Self::PsalmThisOut
243            | Self::PsalmIgnoreNullableReturn
244            | Self::PsalmIgnoreFalsableReturn
245            | Self::PsalmSealProperties
246            | Self::PsalmNoSealProperties
247            | Self::PsalmSealMethods
248            | Self::PsalmNoSealMethods
249            | Self::PsalmInternal
250            | Self::PsalmReadOnly
251            | Self::PsalmMutationFree
252            | Self::PsalmExternalMutationFree
253            | Self::PsalmImmutable
254            | Self::PsalmPure
255            | Self::PsalmAllowPrivateMutation
256            | Self::PsalmReadOnlyAllowPrivateMutation
257            | Self::PsalmTrace
258            | Self::PsalmCheckType
259            | Self::PsalmCheckTypeExact
260            | Self::PsalmTaintSource
261            | Self::PsalmTaintSink
262            | Self::PsalmTaintEscape
263            | Self::PsalmTaintUnescape
264            | Self::PsalmTaintSpecialize
265            | Self::PsalmFlow
266            | Self::PsalmType
267            | Self::PsalmImportType
268            | Self::PsalmRequireExtends
269            | Self::PsalmRequireImplements
270            | Self::PsalmIgnoreVariableProperty
271            | Self::PsalmIgnoreVariableMethod
272            | Self::PsalmYield
273            | Self::PsalmTemplate
274            | Self::PsalmTemplateInvariant
275            | Self::PsalmTemplateCovariant
276            | Self::PsalmTemplateContravariant => Some(TagVendor::Psalm),
277            Self::PhpstanAssert
278            | Self::PhpstanAssertIfTrue
279            | Self::PhpstanAssertIfFalse
280            | Self::PhpstanSelfOut
281            | Self::PhpstanThisOut
282            | Self::PhpstanRequireExtends
283            | Self::PhpstanRequireImplements
284            | Self::PhpstanTemplate
285            | Self::PhpstanTemplateInvariant
286            | Self::PhpstanTemplateCovariant
287            | Self::PhpstanTemplateContravariant
288            | Self::PhpstanParam
289            | Self::PhpstanReturn
290            | Self::PhpstanVar
291            | Self::PhpstanReadOnly
292            | Self::PhpstanImmutable => Some(TagVendor::Phpstan),
293            _ => None,
294        }
295    }
296
297    /// Returns the non-vendored variant of the tag, if it exists.
298    ///
299    /// Note that not all vendored tags have a non-vendored variant.
300    ///
301    /// If the tag is not vendored, or if it does not have a non-vendored variant,
302    ///  `None` is returned.
303    pub fn get_non_vendored_variant(&self) -> Option<TagKind> {
304        match self {
305            Self::PsalmConsistentConstructor => Some(Self::ConsistentConstructor),
306            Self::PsalmParamOut => Some(Self::ParamOut),
307            Self::PsalmVar => Some(Self::Var),
308            Self::PsalmParam => Some(Self::Param),
309            Self::PsalmReturn => Some(Self::Return),
310            Self::PsalmProperty => Some(Self::Property),
311            Self::PsalmPropertyRead => Some(Self::PropertyRead),
312            Self::PsalmPropertyWrite => Some(Self::PropertyWrite),
313            Self::PsalmMethod => Some(Self::Method),
314            Self::PsalmSealProperties => Some(Self::SealProperties),
315            Self::PsalmNoSealProperties => Some(Self::NoSealProperties),
316            Self::PsalmSealMethods => Some(Self::SealMethods),
317            Self::PsalmNoSealMethods => Some(Self::NoSealMethods),
318            Self::PsalmInternal => Some(Self::Internal),
319            Self::PsalmReadOnly => Some(Self::ReadOnly),
320            Self::PsalmImmutable => Some(Self::Immutable),
321            Self::PsalmPure => Some(Self::Pure),
322            Self::PhpstanParam => Some(Self::Param),
323            Self::PhpstanReturn => Some(Self::Return),
324            Self::PhpstanVar => Some(Self::Var),
325            Self::PhpstanReadOnly => Some(Self::ReadOnly),
326            Self::PhpstanImmutable => Some(Self::Immutable),
327            Self::PhpstanAssert | Self::PsalmAssert => Some(Self::Assert),
328            Self::PhpstanAssertIfTrue | Self::PsalmAssertIfTrue => Some(Self::AssertIfTrue),
329            Self::PhpstanAssertIfFalse | Self::PsalmAssertIfFalse => Some(Self::AssertIfFalse),
330            Self::PhpstanTemplate | Self::PsalmTemplate => Some(Self::Template),
331            Self::PhpstanTemplateInvariant | Self::PsalmTemplateInvariant => Some(Self::TemplateInvariant),
332            Self::PhpstanTemplateCovariant | Self::PsalmTemplateCovariant => Some(Self::TemplateCovariant),
333            Self::PhpstanTemplateContravariant | Self::PsalmTemplateContravariant => Some(Self::TemplateContravariant),
334            Self::PsalmMutationFree => Some(Self::MutationFree),
335            Self::PsalmExternalMutationFree => Some(Self::ExternalMutationFree),
336            _ => None,
337        }
338    }
339
340    pub fn is_repeatable(&self) -> bool {
341        matches!(
342            self,
343            Self::Author
344                | Self::Deprecated
345                | Self::Example
346                | Self::Ignore
347                | Self::Link
348                | Self::Method
349                | Self::Mixin
350                | Self::Package
351                | Self::Param
352                | Self::Property
353                | Self::PropertyRead
354                | Self::PropertyWrite
355                | Self::Return
356                | Self::See
357                | Self::Since
358                | Self::Throws
359                | Self::Uses
360                | Self::Var
361        )
362    }
363}
364
365impl<T> From<T> for TagKind
366where
367    T: AsRef<str>,
368{
369    fn from(value: T) -> Self {
370        match value.as_ref().to_ascii_lowercase().as_str() {
371            "abstract" => TagKind::Abstract,
372            "access" => TagKind::Access,
373            "author" => TagKind::Author,
374            "category" => TagKind::Category,
375            "copyright" => TagKind::Copyright,
376            "deprecated" => TagKind::Deprecated,
377            "example" => TagKind::Example,
378            "final" => TagKind::Final,
379            "filesource" => TagKind::FileSource,
380            "global" => TagKind::Global,
381            "ignore" => TagKind::Ignore,
382            "internal" => TagKind::Internal,
383            "license" => TagKind::License,
384            "link" => TagKind::Link,
385            "method" => TagKind::Method,
386            "mixin" => TagKind::Mixin,
387            "name" => TagKind::Name,
388            "package" => TagKind::Package,
389            "param" => TagKind::Param,
390            "property" => TagKind::Property,
391            "property-read" => TagKind::PropertyRead,
392            "propertyread" => TagKind::PropertyRead,
393            "property-write" => TagKind::PropertyWrite,
394            "propertywrite" => TagKind::PropertyWrite,
395            "sealproperties" => TagKind::SealProperties,
396            "seal-properties" => TagKind::SealProperties,
397            "nosealproperties" => TagKind::NoSealProperties,
398            "no-seal-properties" => TagKind::NoSealProperties,
399            "sealmethods" => TagKind::SealMethods,
400            "seal-methods" => TagKind::SealMethods,
401            "nosealmethods" => TagKind::NoSealMethods,
402            "no-seal-methods" => TagKind::NoSealMethods,
403            "readonly" => TagKind::ReadOnly,
404            "nonamedarguments" => TagKind::NoNamedArguments,
405            "no-named-arguments" => TagKind::NoNamedArguments,
406            "api" => TagKind::Api,
407            "psalm-api" => TagKind::PsalmApi,
408            "psalm-inheritors" => TagKind::PsalmInheritors,
409            "return" => TagKind::Return,
410            "see" => TagKind::See,
411            "since" => TagKind::Since,
412            "static" => TagKind::Static,
413            "staticvar" => TagKind::StaticVar,
414            "static-var" => TagKind::StaticVar,
415            "subpackage" => TagKind::SubPackage,
416            "sub-package" => TagKind::SubPackage,
417            "todo" => TagKind::Todo,
418            "tutorial" => TagKind::Tutorial,
419            "uses" => TagKind::Uses,
420            "var" => TagKind::Var,
421            "throws" => TagKind::Throws,
422            "version" => TagKind::Version,
423            "assert" => TagKind::Assert,
424            "assert-if-true" | "assertiftrue" => TagKind::AssertIfTrue,
425            "assert-if-false" | "assertiffalse" => TagKind::AssertIfFalse,
426            "param-later-invoked-callable" => TagKind::ParamLaterInvokedCallable,
427            "paramlaterinvokedcallable" => TagKind::ParamLaterInvokedCallable,
428            "param-immediately-invoked-callable" => TagKind::ParamImmediatelyInvokedCallable,
429            "paramimmediatelyinvokedcallable" => TagKind::ParamImmediatelyInvokedCallable,
430            "param-closure-this" => TagKind::ParamClosureThis,
431            "paramclosurethis" => TagKind::ParamClosureThis,
432            "extends" => TagKind::Extends,
433            "implements" => TagKind::Implements,
434            "use" => TagKind::Use,
435            "not-deprecated" => TagKind::NotDeprecated,
436            "notdeprecated" => TagKind::NotDeprecated,
437            "phpstan-impure" => TagKind::PhpstanImpure,
438            "phpstan-pure" => TagKind::PhpstanPure,
439            "pure" => TagKind::Pure,
440            "immutable" => TagKind::Immutable,
441            "inheritdoc" => TagKind::InheritDoc,
442            "inherit-doc" => TagKind::InheritDoc,
443            "param-out" => TagKind::ParamOut,
444            "psalm-param-out" => TagKind::PsalmParamOut,
445            "consistentconstructor" | "consistent-constructor" => TagKind::ConsistentConstructor,
446            "psalmconsistentconstructor" | "psalm-consistent-constructor" => TagKind::PsalmConsistentConstructor,
447            "psalmconsistenttemplates" | "psalm-consistent-templates" => TagKind::PsalmConsistentTemplates,
448            "psalm-var" => TagKind::PsalmVar,
449            "psalm-param" => TagKind::PsalmParam,
450            "psalm-return" => TagKind::PsalmReturn,
451            "psalm-property" => TagKind::PsalmProperty,
452            "psalm-property-read" => TagKind::PsalmPropertyRead,
453            "psalm-propertyread" => TagKind::PsalmPropertyRead,
454            "psalm-property-write" => TagKind::PsalmPropertyWrite,
455            "psalm-propertywrite" => TagKind::PsalmPropertyWrite,
456            "psalm-method" => TagKind::PsalmMethod,
457            "psalm-ignore-var" => TagKind::PsalmIgnoreVar,
458            "psalmignorevar" => TagKind::PsalmIgnoreVar,
459            "psalm-suppress" => TagKind::PsalmSuppress,
460            "psalm-assert" => TagKind::PsalmAssert,
461            "psalm-assert-if-true" => TagKind::PsalmAssertIfTrue,
462            "psalm-assertiftrue" => TagKind::PsalmAssertIfTrue,
463            "psalm-assert-if-false" => TagKind::PsalmAssertIfFalse,
464            "psalm-assertiffalse" => TagKind::PsalmAssertIfFalse,
465            "psalm-if-this-is" => TagKind::PsalmIfThisIs,
466            "psalmifthisis" => TagKind::PsalmIfThisIs,
467            "psalm-this-out" => TagKind::PsalmThisOut,
468            "psalmthisout" => TagKind::PsalmThisOut,
469            "psalm-ignore-nullable-return" => TagKind::PsalmIgnoreNullableReturn,
470            "psalmignorenullablereturn" => TagKind::PsalmIgnoreNullableReturn,
471            "psalm-ignore-falsable-return" => TagKind::PsalmIgnoreFalsableReturn,
472            "psalmignorefalsablereturn" => TagKind::PsalmIgnoreFalsableReturn,
473            "psalm-seal-properties" => TagKind::PsalmSealProperties,
474            "psalmsealproperties" => TagKind::PsalmSealProperties,
475            "psalm-no-seal-properties" => TagKind::PsalmNoSealProperties,
476            "psalmnosealproperties" => TagKind::PsalmNoSealProperties,
477            "psalm-seal-methods" => TagKind::PsalmSealMethods,
478            "psalmsealmethods" => TagKind::PsalmSealMethods,
479            "psalm-no-seal-methods" => TagKind::PsalmNoSealMethods,
480            "psalmnosealmethods" => TagKind::PsalmNoSealMethods,
481            "psalm-internal" => TagKind::PsalmInternal,
482            "psalm-readonly" => TagKind::PsalmReadOnly,
483            "psalm-mutation-free" | "psalmmutationfree" => TagKind::PsalmMutationFree,
484            "psalm-external-mutation-free" | "psalmexternalmutationfree" => TagKind::PsalmExternalMutationFree,
485            "mutation-free" | "mutationfree" => TagKind::MutationFree,
486            "external-mutation-free" | "externalmutationfree" => TagKind::ExternalMutationFree,
487            "psalm-immutable" => TagKind::PsalmImmutable,
488            "psalm-pure" => TagKind::PsalmPure,
489            "psalm-allow-private-mutation" => TagKind::PsalmAllowPrivateMutation,
490            "psalmallowprivatemutation" => TagKind::PsalmAllowPrivateMutation,
491            "psalm-readonly-allow-private-mutation" => TagKind::PsalmReadOnlyAllowPrivateMutation,
492            "psalmreadonlyallowprivatemutation" => TagKind::PsalmReadOnlyAllowPrivateMutation,
493            "psalm-trace" => TagKind::PsalmTrace,
494            "psalm-check-type" => TagKind::PsalmCheckType,
495            "psalmchecktype" => TagKind::PsalmCheckType,
496            "psalm-check-type-exact" => TagKind::PsalmCheckTypeExact,
497            "psalmchecktypeexact" => TagKind::PsalmCheckTypeExact,
498            "psalm-taint-source" => TagKind::PsalmTaintSource,
499            "psalmtaintsource" => TagKind::PsalmTaintSource,
500            "psalm-taint-sink" => TagKind::PsalmTaintSink,
501            "psalmtaintsink" => TagKind::PsalmTaintSink,
502            "psalm-taint-escape" => TagKind::PsalmTaintEscape,
503            "psalmtaintescape" => TagKind::PsalmTaintEscape,
504            "psalm-taint-unescape" => TagKind::PsalmTaintUnescape,
505            "psalmtaintunescape" => TagKind::PsalmTaintUnescape,
506            "psalm-taint-specialize" => TagKind::PsalmTaintSpecialize,
507            "psalmtaintspecialize" => TagKind::PsalmTaintSpecialize,
508            "psalm-flow" => TagKind::PsalmFlow,
509            "psalmflow" => TagKind::PsalmFlow,
510            "psalm-type" => TagKind::PsalmType,
511            "psalm-import-type" => TagKind::PsalmImportType,
512            "psalm-require-extends" => TagKind::PsalmRequireExtends,
513            "psalmrequireextends" => TagKind::PsalmRequireExtends,
514            "psalm-require-implements" => TagKind::PsalmRequireImplements,
515            "psalmrequireimplements" => TagKind::PsalmRequireImplements,
516            "psalm-ignore-variable-property" => TagKind::PsalmIgnoreVariableProperty,
517            "psalmignorevariableproperty" => TagKind::PsalmIgnoreVariableProperty,
518            "psalm-ignore-variable-method" => TagKind::PsalmIgnoreVariableMethod,
519            "psalmignorevariablemethod" => TagKind::PsalmIgnoreVariableMethod,
520            "psalm-yield" => TagKind::PsalmYield,
521            "phpstan-assert" => TagKind::PhpstanAssert,
522            "phpstan-assert-if-true" => TagKind::PhpstanAssertIfTrue,
523            "phpstan-assert-if-false" => TagKind::PhpstanAssertIfFalse,
524            "phpstan-self-out" => TagKind::PhpstanSelfOut,
525            "phpstan-this-out" => TagKind::PhpstanThisOut,
526            "phpstan-require-extends" => TagKind::PhpstanRequireExtends,
527            "phpstan-require-implements" => TagKind::PhpstanRequireImplements,
528            "template" => TagKind::Template,
529            "template-invariant" | "templateinvariant" => TagKind::TemplateInvariant,
530            "template-covariant" | "templatecovariant" => TagKind::TemplateCovariant,
531            "template-contravariant" | "templatecontravariant" => TagKind::TemplateContravariant,
532            "psalm-template" | "psalmtemplate" => TagKind::PsalmTemplate,
533            "psalm-template-invariant" | "psalmtemplateinvariant" => TagKind::PsalmTemplateInvariant,
534            "psalm-template-covariant" | "psalmtemplatecovariant" => TagKind::PsalmTemplateCovariant,
535            "psalm-template-contravariant" | "psalmtemplatecontravariant" => TagKind::PsalmTemplateContravariant,
536            "phpstan-template" | "phpstantemplate" => TagKind::PhpstanTemplate,
537            "phpstan-template-invariant" | "phpstantemplateinvariant" => TagKind::PhpstanTemplateInvariant,
538            "phpstan-template-covariant" | "phpstantemplatecovariant" => TagKind::PhpstanTemplateCovariant,
539            "phpstan-template-contravariant" | "phpstantemplatecontravariant" => TagKind::PhpstanTemplateContravariant,
540            "phpstan-param" => TagKind::PhpstanParam,
541            "phpstan-return" => TagKind::PhpstanReturn,
542            "phpstan-var" => TagKind::PhpstanVar,
543            "phpstan-readonly" => TagKind::PhpstanReadOnly,
544            "phpstan-immutable" => TagKind::PhpstanImmutable,
545            _ => TagKind::Other,
546        }
547    }
548}