Skip to main content

mago_docblock/
document.rs

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