1pub mod ast;
33pub mod kind;
34
35pub use kind::SyntaxKind;
36
37use kind::RonLang;
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
45pub struct TextRange {
46 start: usize,
47 end: usize,
48}
49
50impl TextRange {
51 #[inline]
53 #[must_use]
54 pub fn new(start: usize, end: usize) -> Self {
55 debug_assert!(start <= end, "TextRange start must not exceed end");
56 Self { start, end }
57 }
58
59 #[inline]
61 #[must_use]
62 pub fn start(self) -> usize {
63 self.start
64 }
65
66 #[inline]
68 #[must_use]
69 pub fn end(self) -> usize {
70 self.end
71 }
72
73 #[inline]
75 #[must_use]
76 pub fn len(self) -> usize {
77 self.end - self.start
78 }
79
80 #[inline]
82 #[must_use]
83 pub fn is_empty(self) -> bool {
84 self.start == self.end
85 }
86
87 #[inline]
89 #[must_use]
90 pub fn contains(self, offset: usize) -> bool {
91 self.start <= offset && offset < self.end
92 }
93}
94
95impl From<rowan::TextRange> for TextRange {
96 #[inline]
97 fn from(r: rowan::TextRange) -> Self {
98 Self {
99 start: usize::from(r.start()),
100 end: usize::from(r.end()),
101 }
102 }
103}
104
105#[derive(Clone, PartialEq, Eq, Hash)]
109pub struct SyntaxNode(rowan::SyntaxNode<RonLang>);
110
111#[derive(Clone, PartialEq, Eq, Hash)]
115pub struct SyntaxToken(rowan::SyntaxToken<RonLang>);
116
117#[derive(Clone, PartialEq, Eq, Hash)]
119pub enum SyntaxElement {
120 Node(SyntaxNode),
122 Token(SyntaxToken),
124}
125
126impl SyntaxNode {
127 #[inline]
129 #[allow(dead_code)] pub(crate) fn from_rowan(node: rowan::SyntaxNode<RonLang>) -> Self {
131 Self(node)
132 }
133
134 #[inline]
136 pub(crate) fn new_root(green: rowan::GreenNode) -> Self {
137 Self(rowan::SyntaxNode::new_root(green))
138 }
139
140 #[inline]
142 #[allow(dead_code)] pub(crate) fn raw(&self) -> &rowan::SyntaxNode<RonLang> {
144 &self.0
145 }
146
147 #[inline]
149 #[must_use]
150 pub fn kind(&self) -> SyntaxKind {
151 self.0.kind()
152 }
153
154 #[inline]
156 #[must_use]
157 pub fn text_range(&self) -> TextRange {
158 self.0.text_range().into()
159 }
160
161 #[must_use]
163 pub fn text(&self) -> String {
164 self.0.text().to_string()
165 }
166
167 #[inline]
169 #[must_use]
170 pub fn parent(&self) -> Option<SyntaxNode> {
171 self.0.parent().map(SyntaxNode)
172 }
173
174 pub fn children(&self) -> impl Iterator<Item = SyntaxNode> {
176 self.0.children().map(SyntaxNode)
177 }
178
179 pub fn children_with_tokens(&self) -> impl Iterator<Item = SyntaxElement> {
181 self.0.children_with_tokens().map(SyntaxElement::from_rowan)
182 }
183
184 pub fn descendant_tokens(&self) -> impl Iterator<Item = SyntaxToken> {
186 self.0.descendants_with_tokens().filter_map(|el| match el {
187 rowan::NodeOrToken::Token(t) => Some(SyntaxToken(t)),
188 rowan::NodeOrToken::Node(_) => None,
189 })
190 }
191
192 #[must_use]
194 pub fn first_token_of(&self, kind: SyntaxKind) -> Option<SyntaxToken> {
195 self.0
196 .children_with_tokens()
197 .filter_map(|el| el.into_token())
198 .find(|t| t.kind() == kind)
199 .map(SyntaxToken)
200 }
201}
202
203impl SyntaxToken {
204 #[inline]
206 #[must_use]
207 pub fn kind(&self) -> SyntaxKind {
208 self.0.kind()
209 }
210
211 #[inline]
213 #[must_use]
214 pub fn text_range(&self) -> TextRange {
215 self.0.text_range().into()
216 }
217
218 #[inline]
220 #[must_use]
221 pub fn text(&self) -> &str {
222 self.0.text()
223 }
224
225 #[inline]
227 #[must_use]
228 pub fn parent(&self) -> Option<SyntaxNode> {
229 self.0.parent().map(SyntaxNode)
230 }
231
232 #[inline]
234 #[must_use]
235 pub fn is_trivia(&self) -> bool {
236 self.kind().is_trivia()
237 }
238}
239
240impl SyntaxElement {
241 #[inline]
242 fn from_rowan(el: rowan::SyntaxElement<RonLang>) -> Self {
243 match el {
244 rowan::NodeOrToken::Node(n) => Self::Node(SyntaxNode(n)),
245 rowan::NodeOrToken::Token(t) => Self::Token(SyntaxToken(t)),
246 }
247 }
248
249 #[inline]
251 #[must_use]
252 pub fn kind(&self) -> SyntaxKind {
253 match self {
254 Self::Node(n) => n.kind(),
255 Self::Token(t) => t.kind(),
256 }
257 }
258
259 #[inline]
261 #[must_use]
262 pub fn text_range(&self) -> TextRange {
263 match self {
264 Self::Node(n) => n.text_range(),
265 Self::Token(t) => t.text_range(),
266 }
267 }
268
269 #[inline]
271 #[must_use]
272 pub fn as_node(&self) -> Option<&SyntaxNode> {
273 match self {
274 Self::Node(n) => Some(n),
275 Self::Token(_) => None,
276 }
277 }
278
279 #[inline]
281 #[must_use]
282 pub fn as_token(&self) -> Option<&SyntaxToken> {
283 match self {
284 Self::Token(t) => Some(t),
285 Self::Node(_) => None,
286 }
287 }
288}
289
290impl std::fmt::Debug for SyntaxNode {
291 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
292 write!(f, "{:?}@{:?}", self.kind(), self.text_range())
293 }
294}
295
296impl std::fmt::Debug for SyntaxToken {
297 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
298 write!(
299 f,
300 "{:?}@{:?} {:?}",
301 self.kind(),
302 self.text_range(),
303 self.text()
304 )
305 }
306}
307
308impl std::fmt::Debug for SyntaxElement {
309 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
310 match self {
311 Self::Node(n) => std::fmt::Debug::fmt(n, f),
312 Self::Token(t) => std::fmt::Debug::fmt(t, f),
313 }
314 }
315}