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 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 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}