1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! Structural PHPDoc comment parser.
//!
//! Parses `/** ... */` documentation blocks into a structured AST with accurate
//! spans and support for inline tags. Designed for type checkers, linters, IDEs,
//! and documentation generators.
//!
//! The crate is **agnostic** — it does not interpret tag semantics or parse type
//! expressions. Tag bodies are exposed as raw [`PhpDocText`], letting tools apply
//! their own type parsers and validation rules.
//!
//! # Quick start
//!
//! ```
//! use phpdoc_parser::parse;
//!
//! let text = "/** @param int $x The value */";
//! let doc = parse(text);
//! assert_eq!(doc.tags.len(), 1);
//! assert_eq!(doc.tags[0].name, "param");
//! ```
//!
//! # Common patterns
//!
//! ### Read a tag body
//!
//! ```
//! use phpdoc_parser::{parse, find_tags, body_text};
//!
//! let doc = parse("/** @param int $x The mapping */");
//! for param in find_tags(&doc, "param") {
//! let body = body_text(¶m.body).unwrap_or_default();
//! // body is "int $x The mapping" — parse the type yourself
//! }
//! ```
//!
//! ### Find inline references
//!
//! ```
//! use phpdoc_parser::{parse, inline_tags};
//!
//! let doc = parse("/** See {@link User::load()} for details. */");
//! if let Some(desc) = &doc.description {
//! for tag in inline_tags(desc) {
//! if tag.name == "link" {
//! // Process the reference to User::load()
//! }
//! }
//! }
//! ```
pub
pub
pub
pub use ;
pub use parse;
pub use Span;
// =============================================================================
// Utility functions for common tasks
// =============================================================================
/// Find the first tag with the given name.
///
/// # Example
/// ```
/// use phpdoc_parser::{parse, find_tag};
/// let doc = parse("/** @param int $x @return string */");
/// assert!(find_tag(&doc, "param").is_some());
/// assert!(find_tag(&doc, "throws").is_none());
/// ```
/// Find all tags with the given name.
///
/// # Example
/// ```
/// use phpdoc_parser::{parse, find_tags};
/// let doc = parse("/**\n * @param int $x\n * @param string $y\n */");
/// assert_eq!(find_tags(&doc, "param").len(), 2);
/// ```
/// Reconstruct the text content of a `PhpDocText`, including inline tags.
///
/// Inline tags are reconstructed as `{@name body}` format.
///
/// # Example
/// ```
/// use phpdoc_parser::{parse, text_content};
/// let doc = parse("/** See {@link Foo} for details. */");
/// let summary = text_content(doc.summary.as_ref().unwrap());
/// assert!(summary.contains("@link"));
/// ```
/// Get the text content of a tag body, if present.
///
/// # Example
/// ```
/// use phpdoc_parser::{parse, find_tag, body_text};
/// let doc = parse("/** @param int $x */");
/// let param = find_tag(&doc, "param").unwrap();
/// let text = body_text(¶m.body).unwrap();
/// assert!(text.contains("$x"));
/// ```
/// Extract all inline tags from a text segment.
///
/// # Example
/// ```
/// use phpdoc_parser::{parse, inline_tags};
/// let doc = parse("/** See {@link Foo} and {@link Bar}. */");
/// let tags = inline_tags(doc.summary.as_ref().unwrap());
/// assert_eq!(tags.len(), 2);
/// ```