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