mago_docblock/
document.rs

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