aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src')
-rw-r--r--crates/ra_syntax/src/algo.rs406
-rw-r--r--crates/ra_syntax/src/ast.rs331
-rw-r--r--crates/ra_syntax/src/ast/edit.rs642
-rw-r--r--crates/ra_syntax/src/ast/expr_ext.rs418
-rw-r--r--crates/ra_syntax/src/ast/generated.rs6
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs4071
-rw-r--r--crates/ra_syntax/src/ast/generated/tokens.rs91
-rw-r--r--crates/ra_syntax/src/ast/make.rs392
-rw-r--r--crates/ra_syntax/src/ast/node_ext.rs505
-rw-r--r--crates/ra_syntax/src/ast/token_ext.rs538
-rw-r--r--crates/ra_syntax/src/ast/traits.rs142
-rw-r--r--crates/ra_syntax/src/fuzz.rs73
-rw-r--r--crates/ra_syntax/src/lib.rs388
-rw-r--r--crates/ra_syntax/src/parsing.rs59
-rw-r--r--crates/ra_syntax/src/parsing/lexer.rs244
-rw-r--r--crates/ra_syntax/src/parsing/reparsing.rs455
-rw-r--r--crates/ra_syntax/src/parsing/text_token_source.rs84
-rw-r--r--crates/ra_syntax/src/parsing/text_tree_sink.rs183
-rw-r--r--crates/ra_syntax/src/ptr.rs105
-rw-r--r--crates/ra_syntax/src/syntax_error.rs44
-rw-r--r--crates/ra_syntax/src/syntax_node.rs77
-rw-r--r--crates/ra_syntax/src/tests.rs280
-rw-r--r--crates/ra_syntax/src/validation.rs303
-rw-r--r--crates/ra_syntax/src/validation/block.rs22
24 files changed, 0 insertions, 9859 deletions
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs
deleted file mode 100644
index 26b3c813a..000000000
--- a/crates/ra_syntax/src/algo.rs
+++ /dev/null
@@ -1,406 +0,0 @@
1//! FIXME: write short doc here
2
3use std::{
4 fmt,
5 ops::{self, RangeInclusive},
6};
7
8use itertools::Itertools;
9use ra_text_edit::TextEditBuilder;
10use rustc_hash::FxHashMap;
11
12use crate::{
13 AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
14 SyntaxToken, TextRange, TextSize,
15};
16
17/// Returns ancestors of the node at the offset, sorted by length. This should
18/// do the right thing at an edge, e.g. when searching for expressions at `{
19/// <|>foo }` we will get the name reference instead of the whole block, which
20/// we would get if we just did `find_token_at_offset(...).flat_map(|t|
21/// t.parent().ancestors())`.
22pub fn ancestors_at_offset(
23 node: &SyntaxNode,
24 offset: TextSize,
25) -> impl Iterator<Item = SyntaxNode> {
26 node.token_at_offset(offset)
27 .map(|token| token.parent().ancestors())
28 .kmerge_by(|node1, node2| node1.text_range().len() < node2.text_range().len())
29}
30
31/// Finds a node of specific Ast type at offset. Note that this is slightly
32/// imprecise: if the cursor is strictly between two nodes of the desired type,
33/// as in
34///
35/// ```no-run
36/// struct Foo {}|struct Bar;
37/// ```
38///
39/// then the shorter node will be silently preferred.
40pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextSize) -> Option<N> {
41 ancestors_at_offset(syntax, offset).find_map(N::cast)
42}
43
44pub fn find_node_at_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> {
45 find_covering_element(syntax, range).ancestors().find_map(N::cast)
46}
47
48/// Skip to next non `trivia` token
49pub fn skip_trivia_token(mut token: SyntaxToken, direction: Direction) -> Option<SyntaxToken> {
50 while token.kind().is_trivia() {
51 token = match direction {
52 Direction::Next => token.next_token()?,
53 Direction::Prev => token.prev_token()?,
54 }
55 }
56 Some(token)
57}
58
59/// Finds the first sibling in the given direction which is not `trivia`
60pub fn non_trivia_sibling(element: SyntaxElement, direction: Direction) -> Option<SyntaxElement> {
61 return match element {
62 NodeOrToken::Node(node) => node.siblings_with_tokens(direction).skip(1).find(not_trivia),
63 NodeOrToken::Token(token) => token.siblings_with_tokens(direction).skip(1).find(not_trivia),
64 };
65
66 fn not_trivia(element: &SyntaxElement) -> bool {
67 match element {
68 NodeOrToken::Node(_) => true,
69 NodeOrToken::Token(token) => !token.kind().is_trivia(),
70 }
71 }
72}
73
74pub fn find_covering_element(root: &SyntaxNode, range: TextRange) -> SyntaxElement {
75 root.covering_element(range)
76}
77
78pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNode> {
79 if u == v {
80 return Some(u.clone());
81 }
82
83 let u_depth = u.ancestors().count();
84 let v_depth = v.ancestors().count();
85 let keep = u_depth.min(v_depth);
86
87 let u_candidates = u.ancestors().skip(u_depth - keep);
88 let v_canidates = v.ancestors().skip(v_depth - keep);
89 let (res, _) = u_candidates.zip(v_canidates).find(|(x, y)| x == y)?;
90 Some(res)
91}
92
93pub fn neighbor<T: AstNode>(me: &T, direction: Direction) -> Option<T> {
94 me.syntax().siblings(direction).skip(1).find_map(T::cast)
95}
96
97pub fn has_errors(node: &SyntaxNode) -> bool {
98 node.children().any(|it| it.kind() == SyntaxKind::ERROR)
99}
100
101#[derive(Debug, PartialEq, Eq, Clone, Copy)]
102pub enum InsertPosition<T> {
103 First,
104 Last,
105 Before(T),
106 After(T),
107}
108
109pub struct TreeDiff {
110 replacements: FxHashMap<SyntaxElement, SyntaxElement>,
111}
112
113impl TreeDiff {
114 pub fn into_text_edit(&self, builder: &mut TextEditBuilder) {
115 for (from, to) in self.replacements.iter() {
116 builder.replace(from.text_range(), to.to_string())
117 }
118 }
119
120 pub fn is_empty(&self) -> bool {
121 self.replacements.is_empty()
122 }
123}
124
125/// Finds minimal the diff, which, applied to `from`, will result in `to`.
126///
127/// Specifically, returns a map whose keys are descendants of `from` and values
128/// are descendants of `to`, such that `replace_descendants(from, map) == to`.
129///
130/// A trivial solution is a singleton map `{ from: to }`, but this function
131/// tries to find a more fine-grained diff.
132pub fn diff(from: &SyntaxNode, to: &SyntaxNode) -> TreeDiff {
133 let mut buf = FxHashMap::default();
134 // FIXME: this is both horrible inefficient and gives larger than
135 // necessary diff. I bet there's a cool algorithm to diff trees properly.
136 go(&mut buf, from.clone().into(), to.clone().into());
137 return TreeDiff { replacements: buf };
138
139 fn go(
140 buf: &mut FxHashMap<SyntaxElement, SyntaxElement>,
141 lhs: SyntaxElement,
142 rhs: SyntaxElement,
143 ) {
144 if lhs.kind() == rhs.kind()
145 && lhs.text_range().len() == rhs.text_range().len()
146 && match (&lhs, &rhs) {
147 (NodeOrToken::Node(lhs), NodeOrToken::Node(rhs)) => {
148 lhs.green() == rhs.green() || lhs.text() == rhs.text()
149 }
150 (NodeOrToken::Token(lhs), NodeOrToken::Token(rhs)) => lhs.text() == rhs.text(),
151 _ => false,
152 }
153 {
154 return;
155 }
156 if let (Some(lhs), Some(rhs)) = (lhs.as_node(), rhs.as_node()) {
157 if lhs.children_with_tokens().count() == rhs.children_with_tokens().count() {
158 for (lhs, rhs) in lhs.children_with_tokens().zip(rhs.children_with_tokens()) {
159 go(buf, lhs, rhs)
160 }
161 return;
162 }
163 }
164 buf.insert(lhs, rhs);
165 }
166}
167
168/// Adds specified children (tokens or nodes) to the current node at the
169/// specific position.
170///
171/// This is a type-unsafe low-level editing API, if you need to use it,
172/// prefer to create a type-safe abstraction on top of it instead.
173pub fn insert_children(
174 parent: &SyntaxNode,
175 position: InsertPosition<SyntaxElement>,
176 to_insert: impl IntoIterator<Item = SyntaxElement>,
177) -> SyntaxNode {
178 let mut to_insert = to_insert.into_iter();
179 _insert_children(parent, position, &mut to_insert)
180}
181
182fn _insert_children(
183 parent: &SyntaxNode,
184 position: InsertPosition<SyntaxElement>,
185 to_insert: &mut dyn Iterator<Item = SyntaxElement>,
186) -> SyntaxNode {
187 let mut delta = TextSize::default();
188 let to_insert = to_insert.map(|element| {
189 delta += element.text_range().len();
190 to_green_element(element)
191 });
192
193 let mut old_children = parent.green().children().map(|it| match it {
194 NodeOrToken::Token(it) => NodeOrToken::Token(it.clone()),
195 NodeOrToken::Node(it) => NodeOrToken::Node(it.clone()),
196 });
197
198 let new_children = match &position {
199 InsertPosition::First => to_insert.chain(old_children).collect::<Vec<_>>(),
200 InsertPosition::Last => old_children.chain(to_insert).collect::<Vec<_>>(),
201 InsertPosition::Before(anchor) | InsertPosition::After(anchor) => {
202 let take_anchor = if let InsertPosition::After(_) = position { 1 } else { 0 };
203 let split_at = position_of_child(parent, anchor.clone()) + take_anchor;
204 let before = old_children.by_ref().take(split_at).collect::<Vec<_>>();
205 before.into_iter().chain(to_insert).chain(old_children).collect::<Vec<_>>()
206 }
207 };
208
209 with_children(parent, new_children)
210}
211
212/// Replaces all nodes in `to_delete` with nodes from `to_insert`
213///
214/// This is a type-unsafe low-level editing API, if you need to use it,
215/// prefer to create a type-safe abstraction on top of it instead.
216pub fn replace_children(
217 parent: &SyntaxNode,
218 to_delete: RangeInclusive<SyntaxElement>,
219 to_insert: impl IntoIterator<Item = SyntaxElement>,
220) -> SyntaxNode {
221 let mut to_insert = to_insert.into_iter();
222 _replace_children(parent, to_delete, &mut to_insert)
223}
224
225fn _replace_children(
226 parent: &SyntaxNode,
227 to_delete: RangeInclusive<SyntaxElement>,
228 to_insert: &mut dyn Iterator<Item = SyntaxElement>,
229) -> SyntaxNode {
230 let start = position_of_child(parent, to_delete.start().clone());
231 let end = position_of_child(parent, to_delete.end().clone());
232 let mut old_children = parent.green().children().map(|it| match it {
233 NodeOrToken::Token(it) => NodeOrToken::Token(it.clone()),
234 NodeOrToken::Node(it) => NodeOrToken::Node(it.clone()),
235 });
236
237 let before = old_children.by_ref().take(start).collect::<Vec<_>>();
238 let new_children = before
239 .into_iter()
240 .chain(to_insert.map(to_green_element))
241 .chain(old_children.skip(end + 1 - start))
242 .collect::<Vec<_>>();
243 with_children(parent, new_children)
244}
245
246#[derive(Default)]
247pub struct SyntaxRewriter<'a> {
248 f: Option<Box<dyn Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a>>,
249 //FIXME: add debug_assertions that all elements are in fact from the same file.
250 replacements: FxHashMap<SyntaxElement, Replacement>,
251}
252
253impl fmt::Debug for SyntaxRewriter<'_> {
254 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
255 f.debug_struct("SyntaxRewriter").field("replacements", &self.replacements).finish()
256 }
257}
258
259impl<'a> SyntaxRewriter<'a> {
260 pub fn from_fn(f: impl Fn(&SyntaxElement) -> Option<SyntaxElement> + 'a) -> SyntaxRewriter<'a> {
261 SyntaxRewriter { f: Some(Box::new(f)), replacements: FxHashMap::default() }
262 }
263 pub fn delete<T: Clone + Into<SyntaxElement>>(&mut self, what: &T) {
264 let what = what.clone().into();
265 let replacement = Replacement::Delete;
266 self.replacements.insert(what, replacement);
267 }
268 pub fn replace<T: Clone + Into<SyntaxElement>>(&mut self, what: &T, with: &T) {
269 let what = what.clone().into();
270 let replacement = Replacement::Single(with.clone().into());
271 self.replacements.insert(what, replacement);
272 }
273 pub fn replace_with_many<T: Clone + Into<SyntaxElement>>(
274 &mut self,
275 what: &T,
276 with: Vec<SyntaxElement>,
277 ) {
278 let what = what.clone().into();
279 let replacement = Replacement::Many(with);
280 self.replacements.insert(what, replacement);
281 }
282 pub fn replace_ast<T: AstNode>(&mut self, what: &T, with: &T) {
283 self.replace(what.syntax(), with.syntax())
284 }
285
286 pub fn rewrite(&self, node: &SyntaxNode) -> SyntaxNode {
287 if self.f.is_none() && self.replacements.is_empty() {
288 return node.clone();
289 }
290 self.rewrite_children(node)
291 }
292
293 pub fn rewrite_ast<N: AstNode>(self, node: &N) -> N {
294 N::cast(self.rewrite(node.syntax())).unwrap()
295 }
296
297 /// Returns a node that encompasses all replacements to be done by this rewriter.
298 ///
299 /// Passing the returned node to `rewrite` will apply all replacements queued up in `self`.
300 ///
301 /// Returns `None` when there are no replacements.
302 pub fn rewrite_root(&self) -> Option<SyntaxNode> {
303 assert!(self.f.is_none());
304 self.replacements
305 .keys()
306 .map(|element| match element {
307 SyntaxElement::Node(it) => it.clone(),
308 SyntaxElement::Token(it) => it.parent(),
309 })
310 // If we only have one replacement, we must return its parent node, since `rewrite` does
311 // not replace the node passed to it.
312 .map(|it| it.parent().unwrap_or(it))
313 .fold1(|a, b| least_common_ancestor(&a, &b).unwrap())
314 }
315
316 fn replacement(&self, element: &SyntaxElement) -> Option<Replacement> {
317 if let Some(f) = &self.f {
318 assert!(self.replacements.is_empty());
319 return f(element).map(Replacement::Single);
320 }
321 self.replacements.get(element).cloned()
322 }
323
324 fn rewrite_children(&self, node: &SyntaxNode) -> SyntaxNode {
325 // FIXME: this could be made much faster.
326 let mut new_children = Vec::new();
327 for child in node.children_with_tokens() {
328 self.rewrite_self(&mut new_children, &child);
329 }
330 with_children(node, new_children)
331 }
332
333 fn rewrite_self(
334 &self,
335 acc: &mut Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>,
336 element: &SyntaxElement,
337 ) {
338 if let Some(replacement) = self.replacement(&element) {
339 match replacement {
340 Replacement::Single(NodeOrToken::Node(it)) => {
341 acc.push(NodeOrToken::Node(it.green().clone()))
342 }
343 Replacement::Single(NodeOrToken::Token(it)) => {
344 acc.push(NodeOrToken::Token(it.green().clone()))
345 }
346 Replacement::Many(replacements) => {
347 acc.extend(replacements.iter().map(|it| match it {
348 NodeOrToken::Node(it) => NodeOrToken::Node(it.green().clone()),
349 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()),
350 }))
351 }
352 Replacement::Delete => (),
353 };
354 return;
355 }
356 let res = match element {
357 NodeOrToken::Token(it) => NodeOrToken::Token(it.green().clone()),
358 NodeOrToken::Node(it) => NodeOrToken::Node(self.rewrite_children(it).green().clone()),
359 };
360 acc.push(res)
361 }
362}
363
364impl ops::AddAssign for SyntaxRewriter<'_> {
365 fn add_assign(&mut self, rhs: SyntaxRewriter) {
366 assert!(rhs.f.is_none());
367 self.replacements.extend(rhs.replacements)
368 }
369}
370
371#[derive(Clone, Debug)]
372enum Replacement {
373 Delete,
374 Single(SyntaxElement),
375 Many(Vec<SyntaxElement>),
376}
377
378fn with_children(
379 parent: &SyntaxNode,
380 new_children: Vec<NodeOrToken<rowan::GreenNode, rowan::GreenToken>>,
381) -> SyntaxNode {
382 let len = new_children.iter().map(|it| it.text_len()).sum::<TextSize>();
383 let new_node = rowan::GreenNode::new(rowan::SyntaxKind(parent.kind() as u16), new_children);
384 let new_root_node = parent.replace_with(new_node);
385 let new_root_node = SyntaxNode::new_root(new_root_node);
386
387 // FIXME: use a more elegant way to re-fetch the node (#1185), make
388 // `range` private afterwards
389 let mut ptr = SyntaxNodePtr::new(parent);
390 ptr.range = TextRange::at(ptr.range.start(), len);
391 ptr.to_node(&new_root_node)
392}
393
394fn position_of_child(parent: &SyntaxNode, child: SyntaxElement) -> usize {
395 parent
396 .children_with_tokens()
397 .position(|it| it == child)
398 .expect("element is not a child of current element")
399}
400
401fn to_green_element(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> {
402 match element {
403 NodeOrToken::Node(it) => it.green().clone().into(),
404 NodeOrToken::Token(it) => it.green().clone().into(),
405 }
406}
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
deleted file mode 100644
index fd426ece9..000000000
--- a/crates/ra_syntax/src/ast.rs
+++ /dev/null
@@ -1,331 +0,0 @@
1//! Abstract Syntax Tree, layered on top of untyped `SyntaxNode`s
2
3mod generated;
4mod traits;
5mod token_ext;
6mod node_ext;
7mod expr_ext;
8pub mod edit;
9pub mod make;
10
11use std::marker::PhantomData;
12
13use crate::{
14 syntax_node::{SyntaxNode, SyntaxNodeChildren, SyntaxToken},
15 SmolStr, SyntaxKind,
16};
17
18pub use self::{
19 expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp},
20 generated::{nodes::*, tokens::*},
21 node_ext::{
22 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents,
23 StructKind, TypeBoundKind, VisibilityKind,
24 },
25 token_ext::*,
26 traits::*,
27};
28
29/// The main trait to go from untyped `SyntaxNode` to a typed ast. The
30/// conversion itself has zero runtime cost: ast and syntax nodes have exactly
31/// the same representation: a pointer to the tree root and a pointer to the
32/// node itself.
33pub trait AstNode {
34 fn can_cast(kind: SyntaxKind) -> bool
35 where
36 Self: Sized;
37
38 fn cast(syntax: SyntaxNode) -> Option<Self>
39 where
40 Self: Sized;
41
42 fn syntax(&self) -> &SyntaxNode;
43}
44
45/// Like `AstNode`, but wraps tokens rather than interior nodes.
46pub trait AstToken {
47 fn can_cast(token: SyntaxKind) -> bool
48 where
49 Self: Sized;
50
51 fn cast(syntax: SyntaxToken) -> Option<Self>
52 where
53 Self: Sized;
54
55 fn syntax(&self) -> &SyntaxToken;
56
57 fn text(&self) -> &SmolStr {
58 self.syntax().text()
59 }
60}
61
62/// An iterator over `SyntaxNode` children of a particular AST type.
63#[derive(Debug, Clone)]
64pub struct AstChildren<N> {
65 inner: SyntaxNodeChildren,
66 ph: PhantomData<N>,
67}
68
69impl<N> AstChildren<N> {
70 fn new(parent: &SyntaxNode) -> Self {
71 AstChildren { inner: parent.children(), ph: PhantomData }
72 }
73}
74
75impl<N: AstNode> Iterator for AstChildren<N> {
76 type Item = N;
77 fn next(&mut self) -> Option<N> {
78 self.inner.find_map(N::cast)
79 }
80}
81
82mod support {
83 use super::{AstChildren, AstNode, SyntaxKind, SyntaxNode, SyntaxToken};
84
85 pub(super) fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
86 parent.children().find_map(N::cast)
87 }
88
89 pub(super) fn children<N: AstNode>(parent: &SyntaxNode) -> AstChildren<N> {
90 AstChildren::new(parent)
91 }
92
93 pub(super) fn token(parent: &SyntaxNode, kind: SyntaxKind) -> Option<SyntaxToken> {
94 parent.children_with_tokens().filter_map(|it| it.into_token()).find(|it| it.kind() == kind)
95 }
96}
97
98#[test]
99fn assert_ast_is_object_safe() {
100 fn _f(_: &dyn AstNode, _: &dyn NameOwner) {}
101}
102
103#[test]
104fn test_doc_comment_none() {
105 let file = SourceFile::parse(
106 r#"
107 // non-doc
108 mod foo {}
109 "#,
110 )
111 .ok()
112 .unwrap();
113 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
114 assert!(module.doc_comment_text().is_none());
115}
116
117#[test]
118fn test_doc_comment_of_items() {
119 let file = SourceFile::parse(
120 r#"
121 //! doc
122 // non-doc
123 mod foo {}
124 "#,
125 )
126 .ok()
127 .unwrap();
128 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
129 assert_eq!("doc", module.doc_comment_text().unwrap());
130}
131
132#[test]
133fn test_doc_comment_of_statics() {
134 let file = SourceFile::parse(
135 r#"
136 /// Number of levels
137 static LEVELS: i32 = 0;
138 "#,
139 )
140 .ok()
141 .unwrap();
142 let st = file.syntax().descendants().find_map(Static::cast).unwrap();
143 assert_eq!("Number of levels", st.doc_comment_text().unwrap());
144}
145
146#[test]
147fn test_doc_comment_preserves_indents() {
148 let file = SourceFile::parse(
149 r#"
150 /// doc1
151 /// ```
152 /// fn foo() {
153 /// // ...
154 /// }
155 /// ```
156 mod foo {}
157 "#,
158 )
159 .ok()
160 .unwrap();
161 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
162 assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap());
163}
164
165#[test]
166fn test_doc_comment_preserves_newlines() {
167 let file = SourceFile::parse(
168 r#"
169 /// this
170 /// is
171 /// mod
172 /// foo
173 mod foo {}
174 "#,
175 )
176 .ok()
177 .unwrap();
178 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
179 assert_eq!("this\nis\nmod\nfoo", module.doc_comment_text().unwrap());
180}
181
182#[test]
183fn test_doc_comment_single_line_block_strips_suffix() {
184 let file = SourceFile::parse(
185 r#"
186 /** this is mod foo*/
187 mod foo {}
188 "#,
189 )
190 .ok()
191 .unwrap();
192 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
193 assert_eq!("this is mod foo", module.doc_comment_text().unwrap());
194}
195
196#[test]
197fn test_doc_comment_single_line_block_strips_suffix_whitespace() {
198 let file = SourceFile::parse(
199 r#"
200 /** this is mod foo */
201 mod foo {}
202 "#,
203 )
204 .ok()
205 .unwrap();
206 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
207 assert_eq!("this is mod foo ", module.doc_comment_text().unwrap());
208}
209
210#[test]
211fn test_doc_comment_multi_line_block_strips_suffix() {
212 let file = SourceFile::parse(
213 r#"
214 /**
215 this
216 is
217 mod foo
218 */
219 mod foo {}
220 "#,
221 )
222 .ok()
223 .unwrap();
224 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
225 assert_eq!(
226 " this\n is\n mod foo\n ",
227 module.doc_comment_text().unwrap()
228 );
229}
230
231#[test]
232fn test_comments_preserve_trailing_whitespace() {
233 let file = SourceFile::parse(
234 "\n/// Representation of a Realm. \n/// In the specification these are called Realm Records.\nstruct Realm {}",
235 )
236 .ok()
237 .unwrap();
238 let def = file.syntax().descendants().find_map(Struct::cast).unwrap();
239 assert_eq!(
240 "Representation of a Realm. \nIn the specification these are called Realm Records.",
241 def.doc_comment_text().unwrap()
242 );
243}
244
245#[test]
246fn test_four_slash_line_comment() {
247 let file = SourceFile::parse(
248 r#"
249 //// too many slashes to be a doc comment
250 /// doc comment
251 mod foo {}
252 "#,
253 )
254 .ok()
255 .unwrap();
256 let module = file.syntax().descendants().find_map(Module::cast).unwrap();
257 assert_eq!("doc comment", module.doc_comment_text().unwrap());
258}
259
260#[test]
261fn test_where_predicates() {
262 fn assert_bound(text: &str, bound: Option<TypeBound>) {
263 assert_eq!(text, bound.unwrap().syntax().text().to_string());
264 }
265
266 let file = SourceFile::parse(
267 r#"
268fn foo()
269where
270 T: Clone + Copy + Debug + 'static,
271 'a: 'b + 'c,
272 Iterator::Item: 'a + Debug,
273 Iterator::Item: Debug + 'a,
274 <T as Iterator>::Item: Debug + 'a,
275 for<'a> F: Fn(&'a str)
276{}
277 "#,
278 )
279 .ok()
280 .unwrap();
281 let where_clause = file.syntax().descendants().find_map(WhereClause::cast).unwrap();
282
283 let mut predicates = where_clause.predicates();
284
285 let pred = predicates.next().unwrap();
286 let mut bounds = pred.type_bound_list().unwrap().bounds();
287
288 assert!(pred.for_token().is_none());
289 assert!(pred.generic_param_list().is_none());
290 assert_eq!("T", pred.type_ref().unwrap().syntax().text().to_string());
291 assert_bound("Clone", bounds.next());
292 assert_bound("Copy", bounds.next());
293 assert_bound("Debug", bounds.next());
294 assert_bound("'static", bounds.next());
295
296 let pred = predicates.next().unwrap();
297 let mut bounds = pred.type_bound_list().unwrap().bounds();
298
299 assert_eq!("'a", pred.lifetime_token().unwrap().text());
300
301 assert_bound("'b", bounds.next());
302 assert_bound("'c", bounds.next());
303
304 let pred = predicates.next().unwrap();
305 let mut bounds = pred.type_bound_list().unwrap().bounds();
306
307 assert_eq!("Iterator::Item", pred.type_ref().unwrap().syntax().text().to_string());
308 assert_bound("'a", bounds.next());
309
310 let pred = predicates.next().unwrap();
311 let mut bounds = pred.type_bound_list().unwrap().bounds();
312
313 assert_eq!("Iterator::Item", pred.type_ref().unwrap().syntax().text().to_string());
314 assert_bound("Debug", bounds.next());
315 assert_bound("'a", bounds.next());
316
317 let pred = predicates.next().unwrap();
318 let mut bounds = pred.type_bound_list().unwrap().bounds();
319
320 assert_eq!("<T as Iterator>::Item", pred.type_ref().unwrap().syntax().text().to_string());
321 assert_bound("Debug", bounds.next());
322 assert_bound("'a", bounds.next());
323
324 let pred = predicates.next().unwrap();
325 let mut bounds = pred.type_bound_list().unwrap().bounds();
326
327 assert!(pred.for_token().is_some());
328 assert_eq!("<'a>", pred.generic_param_list().unwrap().syntax().text().to_string());
329 assert_eq!("F", pred.type_ref().unwrap().syntax().text().to_string());
330 assert_bound("Fn(&'a str)", bounds.next());
331}
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
deleted file mode 100644
index 8d3e42f25..000000000
--- a/crates/ra_syntax/src/ast/edit.rs
+++ /dev/null
@@ -1,642 +0,0 @@
1//! This module contains functions for editing syntax trees. As the trees are
2//! immutable, all function here return a fresh copy of the tree, instead of
3//! doing an in-place modification.
4use std::{
5 fmt, iter,
6 ops::{self, RangeInclusive},
7};
8
9use arrayvec::ArrayVec;
10
11use crate::{
12 algo::{self, neighbor, SyntaxRewriter},
13 ast::{
14 self,
15 make::{self, tokens},
16 AstNode, TypeBoundsOwner,
17 },
18 AstToken, Direction, InsertPosition, SmolStr, SyntaxElement, SyntaxKind,
19 SyntaxKind::{ATTR, COMMENT, WHITESPACE},
20 SyntaxNode, SyntaxToken, T,
21};
22
23impl ast::BinExpr {
24 #[must_use]
25 pub fn replace_op(&self, op: SyntaxKind) -> Option<ast::BinExpr> {
26 let op_node: SyntaxElement = self.op_details()?.0.into();
27 let to_insert: Option<SyntaxElement> = Some(make::token(op).into());
28 Some(self.replace_children(single_node(op_node), to_insert))
29 }
30}
31
32impl ast::Fn {
33 #[must_use]
34 pub fn with_body(&self, body: ast::BlockExpr) -> ast::Fn {
35 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
36 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() {
37 old_body.syntax().clone().into()
38 } else if let Some(semi) = self.semicolon_token() {
39 to_insert.push(make::tokens::single_space().into());
40 semi.into()
41 } else {
42 to_insert.push(make::tokens::single_space().into());
43 to_insert.push(body.syntax().clone().into());
44 return self.insert_children(InsertPosition::Last, to_insert);
45 };
46 to_insert.push(body.syntax().clone().into());
47 self.replace_children(single_node(old_body_or_semi), to_insert)
48 }
49}
50
51fn make_multiline<N>(node: N) -> N
52where
53 N: AstNode + Clone,
54{
55 let l_curly = match node.syntax().children_with_tokens().find(|it| it.kind() == T!['{']) {
56 Some(it) => it,
57 None => return node,
58 };
59 let sibling = match l_curly.next_sibling_or_token() {
60 Some(it) => it,
61 None => return node,
62 };
63 let existing_ws = match sibling.as_token() {
64 None => None,
65 Some(tok) if tok.kind() != WHITESPACE => None,
66 Some(ws) => {
67 if ws.text().contains('\n') {
68 return node;
69 }
70 Some(ws.clone())
71 }
72 };
73
74 let indent = leading_indent(node.syntax()).unwrap_or_default();
75 let ws = tokens::WsBuilder::new(&format!("\n{}", indent));
76 let to_insert = iter::once(ws.ws().into());
77 match existing_ws {
78 None => node.insert_children(InsertPosition::After(l_curly), to_insert),
79 Some(ws) => node.replace_children(single_node(ws), to_insert),
80 }
81}
82
83impl ast::AssocItemList {
84 #[must_use]
85 pub fn append_items(
86 &self,
87 items: impl IntoIterator<Item = ast::AssocItem>,
88 ) -> ast::AssocItemList {
89 let mut res = self.clone();
90 if !self.syntax().text().contains_char('\n') {
91 res = make_multiline(res);
92 }
93 items.into_iter().for_each(|it| res = res.append_item(it));
94 res
95 }
96
97 #[must_use]
98 pub fn append_item(&self, item: ast::AssocItem) -> ast::AssocItemList {
99 let (indent, position) = match self.assoc_items().last() {
100 Some(it) => (
101 leading_indent(it.syntax()).unwrap_or_default().to_string(),
102 InsertPosition::After(it.syntax().clone().into()),
103 ),
104 None => match self.l_curly_token() {
105 Some(it) => (
106 " ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(),
107 InsertPosition::After(it.into()),
108 ),
109 None => return self.clone(),
110 },
111 };
112 let ws = tokens::WsBuilder::new(&format!("\n{}", indent));
113 let to_insert: ArrayVec<[SyntaxElement; 2]> =
114 [ws.ws().into(), item.syntax().clone().into()].into();
115 self.insert_children(position, to_insert)
116 }
117}
118
119impl ast::RecordExprFieldList {
120 #[must_use]
121 pub fn append_field(&self, field: &ast::RecordExprField) -> ast::RecordExprFieldList {
122 self.insert_field(InsertPosition::Last, field)
123 }
124
125 #[must_use]
126 pub fn insert_field(
127 &self,
128 position: InsertPosition<&'_ ast::RecordExprField>,
129 field: &ast::RecordExprField,
130 ) -> ast::RecordExprFieldList {
131 let is_multiline = self.syntax().text().contains_char('\n');
132 let ws;
133 let space = if is_multiline {
134 ws = tokens::WsBuilder::new(&format!(
135 "\n{} ",
136 leading_indent(self.syntax()).unwrap_or_default()
137 ));
138 ws.ws()
139 } else {
140 tokens::single_space()
141 };
142
143 let mut to_insert: ArrayVec<[SyntaxElement; 4]> = ArrayVec::new();
144 to_insert.push(space.into());
145 to_insert.push(field.syntax().clone().into());
146 to_insert.push(make::token(T![,]).into());
147
148 macro_rules! after_l_curly {
149 () => {{
150 let anchor = match self.l_curly_token() {
151 Some(it) => it.into(),
152 None => return self.clone(),
153 };
154 InsertPosition::After(anchor)
155 }};
156 }
157
158 macro_rules! after_field {
159 ($anchor:expr) => {
160 if let Some(comma) = $anchor
161 .syntax()
162 .siblings_with_tokens(Direction::Next)
163 .find(|it| it.kind() == T![,])
164 {
165 InsertPosition::After(comma)
166 } else {
167 to_insert.insert(0, make::token(T![,]).into());
168 InsertPosition::After($anchor.syntax().clone().into())
169 }
170 };
171 };
172
173 let position = match position {
174 InsertPosition::First => after_l_curly!(),
175 InsertPosition::Last => {
176 if !is_multiline {
177 // don't insert comma before curly
178 to_insert.pop();
179 }
180 match self.fields().last() {
181 Some(it) => after_field!(it),
182 None => after_l_curly!(),
183 }
184 }
185 InsertPosition::Before(anchor) => {
186 InsertPosition::Before(anchor.syntax().clone().into())
187 }
188 InsertPosition::After(anchor) => after_field!(anchor),
189 };
190
191 self.insert_children(position, to_insert)
192 }
193}
194
195impl ast::TypeAlias {
196 #[must_use]
197 pub fn remove_bounds(&self) -> ast::TypeAlias {
198 let colon = match self.colon_token() {
199 Some(it) => it,
200 None => return self.clone(),
201 };
202 let end = match self.type_bound_list() {
203 Some(it) => it.syntax().clone().into(),
204 None => colon.clone().into(),
205 };
206 self.replace_children(colon.into()..=end, iter::empty())
207 }
208}
209
210impl ast::TypeParam {
211 #[must_use]
212 pub fn remove_bounds(&self) -> ast::TypeParam {
213 let colon = match self.colon_token() {
214 Some(it) => it,
215 None => return self.clone(),
216 };
217 let end = match self.type_bound_list() {
218 Some(it) => it.syntax().clone().into(),
219 None => colon.clone().into(),
220 };
221 self.replace_children(colon.into()..=end, iter::empty())
222 }
223}
224
225impl ast::Path {
226 #[must_use]
227 pub fn with_segment(&self, segment: ast::PathSegment) -> ast::Path {
228 if let Some(old) = self.segment() {
229 return self.replace_children(
230 single_node(old.syntax().clone()),
231 iter::once(segment.syntax().clone().into()),
232 );
233 }
234 self.clone()
235 }
236}
237
238impl ast::PathSegment {
239 #[must_use]
240 pub fn with_type_args(&self, type_args: ast::TypeArgList) -> ast::PathSegment {
241 self._with_type_args(type_args, false)
242 }
243
244 #[must_use]
245 pub fn with_turbo_fish(&self, type_args: ast::TypeArgList) -> ast::PathSegment {
246 self._with_type_args(type_args, true)
247 }
248
249 fn _with_type_args(&self, type_args: ast::TypeArgList, turbo: bool) -> ast::PathSegment {
250 if let Some(old) = self.type_arg_list() {
251 return self.replace_children(
252 single_node(old.syntax().clone()),
253 iter::once(type_args.syntax().clone().into()),
254 );
255 }
256 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
257 if turbo {
258 to_insert.push(make::token(T![::]).into());
259 }
260 to_insert.push(type_args.syntax().clone().into());
261 self.insert_children(InsertPosition::Last, to_insert)
262 }
263}
264
265impl ast::Use {
266 #[must_use]
267 pub fn with_use_tree(&self, use_tree: ast::UseTree) -> ast::Use {
268 if let Some(old) = self.use_tree() {
269 return self.replace_descendant(old, use_tree);
270 }
271 self.clone()
272 }
273
274 pub fn remove(&self) -> SyntaxRewriter<'static> {
275 let mut res = SyntaxRewriter::default();
276 res.delete(self.syntax());
277 let next_ws = self
278 .syntax()
279 .next_sibling_or_token()
280 .and_then(|it| it.into_token())
281 .and_then(ast::Whitespace::cast);
282 if let Some(next_ws) = next_ws {
283 let ws_text = next_ws.syntax().text();
284 if ws_text.starts_with('\n') {
285 let rest = &ws_text[1..];
286 if rest.is_empty() {
287 res.delete(next_ws.syntax())
288 } else {
289 res.replace(next_ws.syntax(), &make::tokens::whitespace(rest));
290 }
291 }
292 }
293 res
294 }
295}
296
297impl ast::UseTree {
298 #[must_use]
299 pub fn with_path(&self, path: ast::Path) -> ast::UseTree {
300 if let Some(old) = self.path() {
301 return self.replace_descendant(old, path);
302 }
303 self.clone()
304 }
305
306 #[must_use]
307 pub fn with_use_tree_list(&self, use_tree_list: ast::UseTreeList) -> ast::UseTree {
308 if let Some(old) = self.use_tree_list() {
309 return self.replace_descendant(old, use_tree_list);
310 }
311 self.clone()
312 }
313
314 #[must_use]
315 pub fn split_prefix(&self, prefix: &ast::Path) -> ast::UseTree {
316 let suffix = match split_path_prefix(&prefix) {
317 Some(it) => it,
318 None => return self.clone(),
319 };
320 let use_tree = make::use_tree(
321 suffix,
322 self.use_tree_list(),
323 self.rename(),
324 self.star_token().is_some(),
325 );
326 let nested = make::use_tree_list(iter::once(use_tree));
327 return make::use_tree(prefix.clone(), Some(nested), None, false);
328
329 fn split_path_prefix(prefix: &ast::Path) -> Option<ast::Path> {
330 let parent = prefix.parent_path()?;
331 let segment = parent.segment()?;
332 if algo::has_errors(segment.syntax()) {
333 return None;
334 }
335 let mut res = make::path_unqualified(segment);
336 for p in iter::successors(parent.parent_path(), |it| it.parent_path()) {
337 res = make::path_qualified(res, p.segment()?);
338 }
339 Some(res)
340 }
341 }
342
343 pub fn remove(&self) -> SyntaxRewriter<'static> {
344 let mut res = SyntaxRewriter::default();
345 res.delete(self.syntax());
346 for &dir in [Direction::Next, Direction::Prev].iter() {
347 if let Some(nb) = neighbor(self, dir) {
348 self.syntax()
349 .siblings_with_tokens(dir)
350 .skip(1)
351 .take_while(|it| it.as_node() != Some(nb.syntax()))
352 .for_each(|el| res.delete(&el));
353 return res;
354 }
355 }
356 res
357 }
358}
359
360impl ast::MatchArmList {
361 #[must_use]
362 pub fn append_arms(&self, items: impl IntoIterator<Item = ast::MatchArm>) -> ast::MatchArmList {
363 let mut res = self.clone();
364 res = res.strip_if_only_whitespace();
365 if !res.syntax().text().contains_char('\n') {
366 res = make_multiline(res);
367 }
368 items.into_iter().for_each(|it| res = res.append_arm(it));
369 res
370 }
371
372 fn strip_if_only_whitespace(&self) -> ast::MatchArmList {
373 let mut iter = self.syntax().children_with_tokens().skip_while(|it| it.kind() != T!['{']);
374 iter.next(); // Eat the curly
375 let mut inner = iter.take_while(|it| it.kind() != T!['}']);
376 if !inner.clone().all(|it| it.kind() == WHITESPACE) {
377 return self.clone();
378 }
379 let start = match inner.next() {
380 Some(s) => s,
381 None => return self.clone(),
382 };
383 let end = match inner.last() {
384 Some(s) => s,
385 None => start.clone(),
386 };
387 self.replace_children(start..=end, &mut iter::empty())
388 }
389
390 #[must_use]
391 pub fn remove_placeholder(&self) -> ast::MatchArmList {
392 let placeholder =
393 self.arms().find(|arm| matches!(arm.pat(), Some(ast::Pat::PlaceholderPat(_))));
394 if let Some(placeholder) = placeholder {
395 self.remove_arm(&placeholder)
396 } else {
397 self.clone()
398 }
399 }
400
401 #[must_use]
402 fn remove_arm(&self, arm: &ast::MatchArm) -> ast::MatchArmList {
403 let start = arm.syntax().clone();
404 let end = if let Some(comma) = start
405 .siblings_with_tokens(Direction::Next)
406 .skip(1)
407 .skip_while(|it| it.kind().is_trivia())
408 .next()
409 .filter(|it| it.kind() == T![,])
410 {
411 comma
412 } else {
413 start.clone().into()
414 };
415 self.replace_children(start.into()..=end, None)
416 }
417
418 #[must_use]
419 pub fn append_arm(&self, item: ast::MatchArm) -> ast::MatchArmList {
420 let r_curly = match self.syntax().children_with_tokens().find(|it| it.kind() == T!['}']) {
421 Some(t) => t,
422 None => return self.clone(),
423 };
424 let position = InsertPosition::Before(r_curly.into());
425 let arm_ws = tokens::WsBuilder::new(" ");
426 let match_indent = &leading_indent(self.syntax()).unwrap_or_default();
427 let match_ws = tokens::WsBuilder::new(&format!("\n{}", match_indent));
428 let to_insert: ArrayVec<[SyntaxElement; 3]> =
429 [arm_ws.ws().into(), item.syntax().clone().into(), match_ws.ws().into()].into();
430 self.insert_children(position, to_insert)
431 }
432}
433
434#[must_use]
435pub fn remove_attrs_and_docs<N: ast::AttrsOwner>(node: &N) -> N {
436 N::cast(remove_attrs_and_docs_inner(node.syntax().clone())).unwrap()
437}
438
439fn remove_attrs_and_docs_inner(mut node: SyntaxNode) -> SyntaxNode {
440 while let Some(start) =
441 node.children_with_tokens().find(|it| it.kind() == ATTR || it.kind() == COMMENT)
442 {
443 let end = match &start.next_sibling_or_token() {
444 Some(el) if el.kind() == WHITESPACE => el.clone(),
445 Some(_) | None => start.clone(),
446 };
447 node = algo::replace_children(&node, start..=end, &mut iter::empty());
448 }
449 node
450}
451
452#[derive(Debug, Clone, Copy)]
453pub struct IndentLevel(pub u8);
454
455impl From<u8> for IndentLevel {
456 fn from(level: u8) -> IndentLevel {
457 IndentLevel(level)
458 }
459}
460
461impl fmt::Display for IndentLevel {
462 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
463 let spaces = " ";
464 let buf;
465 let len = self.0 as usize * 4;
466 let indent = if len <= spaces.len() {
467 &spaces[..len]
468 } else {
469 buf = iter::repeat(' ').take(len).collect::<String>();
470 &buf
471 };
472 fmt::Display::fmt(indent, f)
473 }
474}
475
476impl ops::Add<u8> for IndentLevel {
477 type Output = IndentLevel;
478 fn add(self, rhs: u8) -> IndentLevel {
479 IndentLevel(self.0 + rhs)
480 }
481}
482
483impl IndentLevel {
484 pub fn from_node(node: &SyntaxNode) -> IndentLevel {
485 let first_token = match node.first_token() {
486 Some(it) => it,
487 None => return IndentLevel(0),
488 };
489 for ws in prev_tokens(first_token).filter_map(ast::Whitespace::cast) {
490 let text = ws.syntax().text();
491 if let Some(pos) = text.rfind('\n') {
492 let level = text[pos + 1..].chars().count() / 4;
493 return IndentLevel(level as u8);
494 }
495 }
496 IndentLevel(0)
497 }
498
499 /// XXX: this intentionally doesn't change the indent of the very first token.
500 /// Ie, in something like
501 /// ```
502 /// fn foo() {
503 /// 92
504 /// }
505 /// ```
506 /// if you indent the block, the `{` token would stay put.
507 fn increase_indent(self, node: SyntaxNode) -> SyntaxNode {
508 let mut rewriter = SyntaxRewriter::default();
509 node.descendants_with_tokens()
510 .filter_map(|el| el.into_token())
511 .filter_map(ast::Whitespace::cast)
512 .filter(|ws| {
513 let text = ws.syntax().text();
514 text.contains('\n')
515 })
516 .for_each(|ws| {
517 let new_ws = make::tokens::whitespace(&format!("{}{}", ws.syntax(), self,));
518 rewriter.replace(ws.syntax(), &new_ws)
519 });
520 rewriter.rewrite(&node)
521 }
522
523 fn decrease_indent(self, node: SyntaxNode) -> SyntaxNode {
524 let mut rewriter = SyntaxRewriter::default();
525 node.descendants_with_tokens()
526 .filter_map(|el| el.into_token())
527 .filter_map(ast::Whitespace::cast)
528 .filter(|ws| {
529 let text = ws.syntax().text();
530 text.contains('\n')
531 })
532 .for_each(|ws| {
533 let new_ws = make::tokens::whitespace(
534 &ws.syntax().text().replace(&format!("\n{}", self), "\n"),
535 );
536 rewriter.replace(ws.syntax(), &new_ws)
537 });
538 rewriter.rewrite(&node)
539 }
540}
541
542// FIXME: replace usages with IndentLevel above
543fn leading_indent(node: &SyntaxNode) -> Option<SmolStr> {
544 for token in prev_tokens(node.first_token()?) {
545 if let Some(ws) = ast::Whitespace::cast(token.clone()) {
546 let ws_text = ws.text();
547 if let Some(pos) = ws_text.rfind('\n') {
548 return Some(ws_text[pos + 1..].into());
549 }
550 }
551 if token.text().contains('\n') {
552 break;
553 }
554 }
555 None
556}
557
558fn prev_tokens(token: SyntaxToken) -> impl Iterator<Item = SyntaxToken> {
559 iter::successors(Some(token), |token| token.prev_token())
560}
561
562pub trait AstNodeEdit: AstNode + Clone + Sized {
563 #[must_use]
564 fn insert_children(
565 &self,
566 position: InsertPosition<SyntaxElement>,
567 to_insert: impl IntoIterator<Item = SyntaxElement>,
568 ) -> Self {
569 let new_syntax = algo::insert_children(self.syntax(), position, to_insert);
570 Self::cast(new_syntax).unwrap()
571 }
572
573 #[must_use]
574 fn replace_children(
575 &self,
576 to_replace: RangeInclusive<SyntaxElement>,
577 to_insert: impl IntoIterator<Item = SyntaxElement>,
578 ) -> Self {
579 let new_syntax = algo::replace_children(self.syntax(), to_replace, to_insert);
580 Self::cast(new_syntax).unwrap()
581 }
582
583 #[must_use]
584 fn replace_descendant<D: AstNode>(&self, old: D, new: D) -> Self {
585 self.replace_descendants(iter::once((old, new)))
586 }
587
588 #[must_use]
589 fn replace_descendants<D: AstNode>(
590 &self,
591 replacement_map: impl IntoIterator<Item = (D, D)>,
592 ) -> Self {
593 let mut rewriter = SyntaxRewriter::default();
594 for (from, to) in replacement_map {
595 rewriter.replace(from.syntax(), to.syntax())
596 }
597 rewriter.rewrite_ast(self)
598 }
599 #[must_use]
600 fn indent(&self, level: IndentLevel) -> Self {
601 Self::cast(level.increase_indent(self.syntax().clone())).unwrap()
602 }
603 #[must_use]
604 fn dedent(&self, level: IndentLevel) -> Self {
605 Self::cast(level.decrease_indent(self.syntax().clone())).unwrap()
606 }
607 #[must_use]
608 fn reset_indent(&self) -> Self {
609 let level = IndentLevel::from_node(self.syntax());
610 self.dedent(level)
611 }
612}
613
614impl<N: AstNode + Clone> AstNodeEdit for N {}
615
616fn single_node(element: impl Into<SyntaxElement>) -> RangeInclusive<SyntaxElement> {
617 let element = element.into();
618 element.clone()..=element
619}
620
621#[test]
622fn test_increase_indent() {
623 let arm_list = {
624 let arm = make::match_arm(iter::once(make::placeholder_pat().into()), make::expr_unit());
625 make::match_arm_list(vec![arm.clone(), arm])
626 };
627 assert_eq!(
628 arm_list.syntax().to_string(),
629 "{
630 _ => (),
631 _ => (),
632}"
633 );
634 let indented = arm_list.indent(IndentLevel(2));
635 assert_eq!(
636 indented.syntax().to_string(),
637 "{
638 _ => (),
639 _ => (),
640 }"
641 );
642}
diff --git a/crates/ra_syntax/src/ast/expr_ext.rs b/crates/ra_syntax/src/ast/expr_ext.rs
deleted file mode 100644
index f5ba87223..000000000
--- a/crates/ra_syntax/src/ast/expr_ext.rs
+++ /dev/null
@@ -1,418 +0,0 @@
1//! Various extension methods to ast Expr Nodes, which are hard to code-generate.
2
3use crate::{
4 ast::{self, support, AstChildren, AstNode},
5 SmolStr,
6 SyntaxKind::*,
7 SyntaxToken, T,
8};
9
10impl ast::AttrsOwner for ast::Expr {}
11
12impl ast::Expr {
13 pub fn is_block_like(&self) -> bool {
14 match self {
15 ast::Expr::IfExpr(_)
16 | ast::Expr::LoopExpr(_)
17 | ast::Expr::ForExpr(_)
18 | ast::Expr::WhileExpr(_)
19 | ast::Expr::BlockExpr(_)
20 | ast::Expr::MatchExpr(_)
21 | ast::Expr::EffectExpr(_) => true,
22 _ => false,
23 }
24 }
25}
26
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub enum ElseBranch {
29 Block(ast::BlockExpr),
30 IfExpr(ast::IfExpr),
31}
32
33impl ast::IfExpr {
34 pub fn then_branch(&self) -> Option<ast::BlockExpr> {
35 self.blocks().next()
36 }
37 pub fn else_branch(&self) -> Option<ElseBranch> {
38 let res = match self.blocks().nth(1) {
39 Some(block) => ElseBranch::Block(block),
40 None => {
41 let elif: ast::IfExpr = support::child(self.syntax())?;
42 ElseBranch::IfExpr(elif)
43 }
44 };
45 Some(res)
46 }
47
48 pub fn blocks(&self) -> AstChildren<ast::BlockExpr> {
49 support::children(self.syntax())
50 }
51}
52
53#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
54pub enum PrefixOp {
55 /// The `*` operator for dereferencing
56 Deref,
57 /// The `!` operator for logical inversion
58 Not,
59 /// The `-` operator for negation
60 Neg,
61}
62
63impl ast::PrefixExpr {
64 pub fn op_kind(&self) -> Option<PrefixOp> {
65 match self.op_token()?.kind() {
66 T![*] => Some(PrefixOp::Deref),
67 T![!] => Some(PrefixOp::Not),
68 T![-] => Some(PrefixOp::Neg),
69 _ => None,
70 }
71 }
72
73 pub fn op_token(&self) -> Option<SyntaxToken> {
74 self.syntax().first_child_or_token()?.into_token()
75 }
76}
77
78#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
79pub enum BinOp {
80 /// The `||` operator for boolean OR
81 BooleanOr,
82 /// The `&&` operator for boolean AND
83 BooleanAnd,
84 /// The `==` operator for equality testing
85 EqualityTest,
86 /// The `!=` operator for equality testing
87 NegatedEqualityTest,
88 /// The `<=` operator for lesser-equal testing
89 LesserEqualTest,
90 /// The `>=` operator for greater-equal testing
91 GreaterEqualTest,
92 /// The `<` operator for comparison
93 LesserTest,
94 /// The `>` operator for comparison
95 GreaterTest,
96 /// The `+` operator for addition
97 Addition,
98 /// The `*` operator for multiplication
99 Multiplication,
100 /// The `-` operator for subtraction
101 Subtraction,
102 /// The `/` operator for division
103 Division,
104 /// The `%` operator for remainder after division
105 Remainder,
106 /// The `<<` operator for left shift
107 LeftShift,
108 /// The `>>` operator for right shift
109 RightShift,
110 /// The `^` operator for bitwise XOR
111 BitwiseXor,
112 /// The `|` operator for bitwise OR
113 BitwiseOr,
114 /// The `&` operator for bitwise AND
115 BitwiseAnd,
116 /// The `=` operator for assignment
117 Assignment,
118 /// The `+=` operator for assignment after addition
119 AddAssign,
120 /// The `/=` operator for assignment after division
121 DivAssign,
122 /// The `*=` operator for assignment after multiplication
123 MulAssign,
124 /// The `%=` operator for assignment after remainders
125 RemAssign,
126 /// The `>>=` operator for assignment after shifting right
127 ShrAssign,
128 /// The `<<=` operator for assignment after shifting left
129 ShlAssign,
130 /// The `-=` operator for assignment after subtraction
131 SubAssign,
132 /// The `|=` operator for assignment after bitwise OR
133 BitOrAssign,
134 /// The `&=` operator for assignment after bitwise AND
135 BitAndAssign,
136 /// The `^=` operator for assignment after bitwise XOR
137 BitXorAssign,
138}
139
140impl BinOp {
141 pub fn is_assignment(self) -> bool {
142 match self {
143 BinOp::Assignment
144 | BinOp::AddAssign
145 | BinOp::DivAssign
146 | BinOp::MulAssign
147 | BinOp::RemAssign
148 | BinOp::ShrAssign
149 | BinOp::ShlAssign
150 | BinOp::SubAssign
151 | BinOp::BitOrAssign
152 | BinOp::BitAndAssign
153 | BinOp::BitXorAssign => true,
154 _ => false,
155 }
156 }
157}
158
159impl ast::BinExpr {
160 pub fn op_details(&self) -> Option<(SyntaxToken, BinOp)> {
161 self.syntax().children_with_tokens().filter_map(|it| it.into_token()).find_map(|c| {
162 let bin_op = match c.kind() {
163 T![||] => BinOp::BooleanOr,
164 T![&&] => BinOp::BooleanAnd,
165 T![==] => BinOp::EqualityTest,
166 T![!=] => BinOp::NegatedEqualityTest,
167 T![<=] => BinOp::LesserEqualTest,
168 T![>=] => BinOp::GreaterEqualTest,
169 T![<] => BinOp::LesserTest,
170 T![>] => BinOp::GreaterTest,
171 T![+] => BinOp::Addition,
172 T![*] => BinOp::Multiplication,
173 T![-] => BinOp::Subtraction,
174 T![/] => BinOp::Division,
175 T![%] => BinOp::Remainder,
176 T![<<] => BinOp::LeftShift,
177 T![>>] => BinOp::RightShift,
178 T![^] => BinOp::BitwiseXor,
179 T![|] => BinOp::BitwiseOr,
180 T![&] => BinOp::BitwiseAnd,
181 T![=] => BinOp::Assignment,
182 T![+=] => BinOp::AddAssign,
183 T![/=] => BinOp::DivAssign,
184 T![*=] => BinOp::MulAssign,
185 T![%=] => BinOp::RemAssign,
186 T![>>=] => BinOp::ShrAssign,
187 T![<<=] => BinOp::ShlAssign,
188 T![-=] => BinOp::SubAssign,
189 T![|=] => BinOp::BitOrAssign,
190 T![&=] => BinOp::BitAndAssign,
191 T![^=] => BinOp::BitXorAssign,
192 _ => return None,
193 };
194 Some((c, bin_op))
195 })
196 }
197
198 pub fn op_kind(&self) -> Option<BinOp> {
199 self.op_details().map(|t| t.1)
200 }
201
202 pub fn op_token(&self) -> Option<SyntaxToken> {
203 self.op_details().map(|t| t.0)
204 }
205
206 pub fn lhs(&self) -> Option<ast::Expr> {
207 support::children(self.syntax()).next()
208 }
209
210 pub fn rhs(&self) -> Option<ast::Expr> {
211 support::children(self.syntax()).nth(1)
212 }
213
214 pub fn sub_exprs(&self) -> (Option<ast::Expr>, Option<ast::Expr>) {
215 let mut children = support::children(self.syntax());
216 let first = children.next();
217 let second = children.next();
218 (first, second)
219 }
220}
221
222#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
223pub enum RangeOp {
224 /// `..`
225 Exclusive,
226 /// `..=`
227 Inclusive,
228}
229
230impl ast::RangeExpr {
231 fn op_details(&self) -> Option<(usize, SyntaxToken, RangeOp)> {
232 self.syntax().children_with_tokens().enumerate().find_map(|(ix, child)| {
233 let token = child.into_token()?;
234 let bin_op = match token.kind() {
235 T![..] => RangeOp::Exclusive,
236 T![..=] => RangeOp::Inclusive,
237 _ => return None,
238 };
239 Some((ix, token, bin_op))
240 })
241 }
242
243 pub fn op_kind(&self) -> Option<RangeOp> {
244 self.op_details().map(|t| t.2)
245 }
246
247 pub fn op_token(&self) -> Option<SyntaxToken> {
248 self.op_details().map(|t| t.1)
249 }
250
251 pub fn start(&self) -> Option<ast::Expr> {
252 let op_ix = self.op_details()?.0;
253 self.syntax()
254 .children_with_tokens()
255 .take(op_ix)
256 .find_map(|it| ast::Expr::cast(it.into_node()?))
257 }
258
259 pub fn end(&self) -> Option<ast::Expr> {
260 let op_ix = self.op_details()?.0;
261 self.syntax()
262 .children_with_tokens()
263 .skip(op_ix + 1)
264 .find_map(|it| ast::Expr::cast(it.into_node()?))
265 }
266}
267
268impl ast::IndexExpr {
269 pub fn base(&self) -> Option<ast::Expr> {
270 support::children(self.syntax()).next()
271 }
272 pub fn index(&self) -> Option<ast::Expr> {
273 support::children(self.syntax()).nth(1)
274 }
275}
276
277pub enum ArrayExprKind {
278 Repeat { initializer: Option<ast::Expr>, repeat: Option<ast::Expr> },
279 ElementList(AstChildren<ast::Expr>),
280}
281
282impl ast::ArrayExpr {
283 pub fn kind(&self) -> ArrayExprKind {
284 if self.is_repeat() {
285 ArrayExprKind::Repeat {
286 initializer: support::children(self.syntax()).next(),
287 repeat: support::children(self.syntax()).nth(1),
288 }
289 } else {
290 ArrayExprKind::ElementList(support::children(self.syntax()))
291 }
292 }
293
294 fn is_repeat(&self) -> bool {
295 self.syntax().children_with_tokens().any(|it| it.kind() == T![;])
296 }
297}
298
299#[derive(Clone, Debug, PartialEq, Eq, Hash)]
300pub enum LiteralKind {
301 String,
302 ByteString,
303 Char,
304 Byte,
305 IntNumber { suffix: Option<SmolStr> },
306 FloatNumber { suffix: Option<SmolStr> },
307 Bool(bool),
308}
309
310impl ast::Literal {
311 pub fn token(&self) -> SyntaxToken {
312 self.syntax()
313 .children_with_tokens()
314 .find(|e| e.kind() != ATTR && !e.kind().is_trivia())
315 .and_then(|e| e.into_token())
316 .unwrap()
317 }
318
319 fn find_suffix(text: &str, possible_suffixes: &[&str]) -> Option<SmolStr> {
320 possible_suffixes
321 .iter()
322 .find(|&suffix| text.ends_with(suffix))
323 .map(|&suffix| SmolStr::new(suffix))
324 }
325
326 pub fn kind(&self) -> LiteralKind {
327 const INT_SUFFIXES: [&str; 12] = [
328 "u64", "u32", "u16", "u8", "usize", "isize", "i64", "i32", "i16", "i8", "u128", "i128",
329 ];
330 const FLOAT_SUFFIXES: [&str; 2] = ["f32", "f64"];
331
332 let token = self.token();
333
334 match token.kind() {
335 INT_NUMBER => {
336 // FYI: there was a bug here previously, thus the if statement below is necessary.
337 // The lexer treats e.g. `1f64` as an integer literal. See
338 // https://github.com/rust-analyzer/rust-analyzer/issues/1592
339 // and the comments on the linked PR.
340
341 let text = token.text();
342 if let suffix @ Some(_) = Self::find_suffix(&text, &FLOAT_SUFFIXES) {
343 LiteralKind::FloatNumber { suffix }
344 } else {
345 LiteralKind::IntNumber { suffix: Self::find_suffix(&text, &INT_SUFFIXES) }
346 }
347 }
348 FLOAT_NUMBER => {
349 let text = token.text();
350 LiteralKind::FloatNumber { suffix: Self::find_suffix(&text, &FLOAT_SUFFIXES) }
351 }
352 STRING | RAW_STRING => LiteralKind::String,
353 T![true] => LiteralKind::Bool(true),
354 T![false] => LiteralKind::Bool(false),
355 BYTE_STRING | RAW_BYTE_STRING => LiteralKind::ByteString,
356 CHAR => LiteralKind::Char,
357 BYTE => LiteralKind::Byte,
358 _ => unreachable!(),
359 }
360 }
361}
362
363#[derive(Debug, Clone, PartialEq, Eq)]
364pub enum Effect {
365 Async(SyntaxToken),
366 Unsafe(SyntaxToken),
367 Try(SyntaxToken),
368 // Very much not an effect, but we stuff it into this node anyway
369 Label(ast::Label),
370}
371
372impl ast::EffectExpr {
373 pub fn effect(&self) -> Effect {
374 if let Some(token) = self.async_token() {
375 return Effect::Async(token);
376 }
377 if let Some(token) = self.unsafe_token() {
378 return Effect::Unsafe(token);
379 }
380 if let Some(token) = self.try_token() {
381 return Effect::Try(token);
382 }
383 if let Some(label) = self.label() {
384 return Effect::Label(label);
385 }
386 unreachable!("ast::EffectExpr without Effect")
387 }
388}
389
390impl ast::BlockExpr {
391 /// false if the block is an intrinsic part of the syntax and can't be
392 /// replaced with arbitrary expression.
393 ///
394 /// ```not_rust
395 /// fn foo() { not_stand_alone }
396 /// const FOO: () = { stand_alone };
397 /// ```
398 pub fn is_standalone(&self) -> bool {
399 let parent = match self.syntax().parent() {
400 Some(it) => it,
401 None => return true,
402 };
403 !matches!(parent.kind(), FN | IF_EXPR | WHILE_EXPR | LOOP_EXPR | EFFECT_EXPR)
404 }
405}
406
407#[test]
408fn test_literal_with_attr() {
409 let parse = ast::SourceFile::parse(r#"const _: &str = { #[attr] "Hello" };"#);
410 let lit = parse.tree().syntax().descendants().find_map(ast::Literal::cast).unwrap();
411 assert_eq!(lit.token().text(), r#""Hello""#);
412}
413
414impl ast::RecordExprField {
415 pub fn parent_record_lit(&self) -> ast::RecordExpr {
416 self.syntax().ancestors().find_map(ast::RecordExpr::cast).unwrap()
417 }
418}
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
deleted file mode 100644
index f5199e09f..000000000
--- a/crates/ra_syntax/src/ast/generated.rs
+++ /dev/null
@@ -1,6 +0,0 @@
1//! This file is actually hand-written, but the submodules are indeed generated.
2
3#[rustfmt::skip]
4pub(super) mod nodes;
5#[rustfmt::skip]
6pub(super) mod tokens;
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
deleted file mode 100644
index 4306efe13..000000000
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ /dev/null
@@ -1,4071 +0,0 @@
1//! Generated file, do not edit by hand, see `xtask/src/codegen`
2
3use crate::{
4 ast::{self, support, AstChildren, AstNode},
5 SyntaxKind::{self, *},
6 SyntaxNode, SyntaxToken, T,
7};
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct SourceFile {
10 pub(crate) syntax: SyntaxNode,
11}
12impl ast::AttrsOwner for SourceFile {}
13impl ast::ModuleItemOwner for SourceFile {}
14impl SourceFile {
15 pub fn shebang_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![shebang]) }
16}
17#[derive(Debug, Clone, PartialEq, Eq, Hash)]
18pub struct Attr {
19 pub(crate) syntax: SyntaxNode,
20}
21impl Attr {
22 pub fn pound_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![#]) }
23 pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
24 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
25 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
26 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
27 pub fn literal(&self) -> Option<Literal> { support::child(&self.syntax) }
28 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
29 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
30}
31#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32pub struct Const {
33 pub(crate) syntax: SyntaxNode,
34}
35impl ast::AttrsOwner for Const {}
36impl ast::NameOwner for Const {}
37impl ast::VisibilityOwner for Const {}
38impl Const {
39 pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
40 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
41 pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
42 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
43 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
44 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
45 pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
46 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
47}
48#[derive(Debug, Clone, PartialEq, Eq, Hash)]
49pub struct Enum {
50 pub(crate) syntax: SyntaxNode,
51}
52impl ast::AttrsOwner for Enum {}
53impl ast::NameOwner for Enum {}
54impl ast::VisibilityOwner for Enum {}
55impl ast::GenericParamsOwner for Enum {}
56impl Enum {
57 pub fn enum_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![enum]) }
58 pub fn variant_list(&self) -> Option<VariantList> { support::child(&self.syntax) }
59}
60#[derive(Debug, Clone, PartialEq, Eq, Hash)]
61pub struct ExternBlock {
62 pub(crate) syntax: SyntaxNode,
63}
64impl ast::AttrsOwner for ExternBlock {}
65impl ExternBlock {
66 pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
67 pub fn extern_item_list(&self) -> Option<ExternItemList> { support::child(&self.syntax) }
68}
69#[derive(Debug, Clone, PartialEq, Eq, Hash)]
70pub struct ExternCrate {
71 pub(crate) syntax: SyntaxNode,
72}
73impl ast::AttrsOwner for ExternCrate {}
74impl ast::VisibilityOwner for ExternCrate {}
75impl ExternCrate {
76 pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
77 pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
78 pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
79 pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
80 pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) }
81 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
82}
83#[derive(Debug, Clone, PartialEq, Eq, Hash)]
84pub struct Fn {
85 pub(crate) syntax: SyntaxNode,
86}
87impl ast::AttrsOwner for Fn {}
88impl ast::NameOwner for Fn {}
89impl ast::VisibilityOwner for Fn {}
90impl ast::GenericParamsOwner for Fn {}
91impl Fn {
92 pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
93 pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
94 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
95 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
96 pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
97 pub fn fn_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![fn]) }
98 pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
99 pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
100 pub fn body(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
101 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
102}
103#[derive(Debug, Clone, PartialEq, Eq, Hash)]
104pub struct Impl {
105 pub(crate) syntax: SyntaxNode,
106}
107impl ast::AttrsOwner for Impl {}
108impl ast::VisibilityOwner for Impl {}
109impl ast::GenericParamsOwner for Impl {}
110impl Impl {
111 pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
112 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
113 pub fn impl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![impl]) }
114 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
115 pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
116 pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
117 pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
118 pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) }
119}
120#[derive(Debug, Clone, PartialEq, Eq, Hash)]
121pub struct MacroCall {
122 pub(crate) syntax: SyntaxNode,
123}
124impl ast::AttrsOwner for MacroCall {}
125impl ast::NameOwner for MacroCall {}
126impl MacroCall {
127 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
128 pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
129 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
130 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
131}
132#[derive(Debug, Clone, PartialEq, Eq, Hash)]
133pub struct Module {
134 pub(crate) syntax: SyntaxNode,
135}
136impl ast::AttrsOwner for Module {}
137impl ast::NameOwner for Module {}
138impl ast::VisibilityOwner for Module {}
139impl Module {
140 pub fn mod_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mod]) }
141 pub fn item_list(&self) -> Option<ItemList> { support::child(&self.syntax) }
142 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
143}
144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub struct Static {
146 pub(crate) syntax: SyntaxNode,
147}
148impl ast::AttrsOwner for Static {}
149impl ast::NameOwner for Static {}
150impl ast::VisibilityOwner for Static {}
151impl Static {
152 pub fn static_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![static]) }
153 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
154 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
155 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
156 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
157 pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
158 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
159}
160#[derive(Debug, Clone, PartialEq, Eq, Hash)]
161pub struct Struct {
162 pub(crate) syntax: SyntaxNode,
163}
164impl ast::AttrsOwner for Struct {}
165impl ast::NameOwner for Struct {}
166impl ast::VisibilityOwner for Struct {}
167impl ast::GenericParamsOwner for Struct {}
168impl Struct {
169 pub fn struct_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![struct]) }
170 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
171 pub fn field_list(&self) -> Option<FieldList> { support::child(&self.syntax) }
172}
173#[derive(Debug, Clone, PartialEq, Eq, Hash)]
174pub struct Trait {
175 pub(crate) syntax: SyntaxNode,
176}
177impl ast::AttrsOwner for Trait {}
178impl ast::NameOwner for Trait {}
179impl ast::VisibilityOwner for Trait {}
180impl ast::GenericParamsOwner for Trait {}
181impl ast::TypeBoundsOwner for Trait {}
182impl Trait {
183 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
184 pub fn auto_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![auto]) }
185 pub fn trait_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![trait]) }
186 pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) }
187}
188#[derive(Debug, Clone, PartialEq, Eq, Hash)]
189pub struct TypeAlias {
190 pub(crate) syntax: SyntaxNode,
191}
192impl ast::AttrsOwner for TypeAlias {}
193impl ast::NameOwner for TypeAlias {}
194impl ast::VisibilityOwner for TypeAlias {}
195impl ast::GenericParamsOwner for TypeAlias {}
196impl ast::TypeBoundsOwner for TypeAlias {}
197impl TypeAlias {
198 pub fn default_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![default]) }
199 pub fn type_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![type]) }
200 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
201 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
202 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
203}
204#[derive(Debug, Clone, PartialEq, Eq, Hash)]
205pub struct Union {
206 pub(crate) syntax: SyntaxNode,
207}
208impl ast::AttrsOwner for Union {}
209impl ast::NameOwner for Union {}
210impl ast::VisibilityOwner for Union {}
211impl ast::GenericParamsOwner for Union {}
212impl Union {
213 pub fn union_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![union]) }
214 pub fn record_field_list(&self) -> Option<RecordFieldList> { support::child(&self.syntax) }
215}
216#[derive(Debug, Clone, PartialEq, Eq, Hash)]
217pub struct Use {
218 pub(crate) syntax: SyntaxNode,
219}
220impl ast::AttrsOwner for Use {}
221impl ast::VisibilityOwner for Use {}
222impl Use {
223 pub fn use_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![use]) }
224 pub fn use_tree(&self) -> Option<UseTree> { support::child(&self.syntax) }
225 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
226}
227#[derive(Debug, Clone, PartialEq, Eq, Hash)]
228pub struct Visibility {
229 pub(crate) syntax: SyntaxNode,
230}
231impl Visibility {
232 pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) }
233 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
234 pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) }
235 pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
236 pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
237 pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) }
238 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
239 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
240}
241#[derive(Debug, Clone, PartialEq, Eq, Hash)]
242pub struct Name {
243 pub(crate) syntax: SyntaxNode,
244}
245impl Name {
246 pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) }
247}
248#[derive(Debug, Clone, PartialEq, Eq, Hash)]
249pub struct ItemList {
250 pub(crate) syntax: SyntaxNode,
251}
252impl ast::AttrsOwner for ItemList {}
253impl ast::ModuleItemOwner for ItemList {}
254impl ItemList {
255 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
256 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
257}
258#[derive(Debug, Clone, PartialEq, Eq, Hash)]
259pub struct NameRef {
260 pub(crate) syntax: SyntaxNode,
261}
262impl NameRef {
263 pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) }
264}
265#[derive(Debug, Clone, PartialEq, Eq, Hash)]
266pub struct Rename {
267 pub(crate) syntax: SyntaxNode,
268}
269impl ast::NameOwner for Rename {}
270impl Rename {
271 pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
272 pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
273}
274#[derive(Debug, Clone, PartialEq, Eq, Hash)]
275pub struct UseTree {
276 pub(crate) syntax: SyntaxNode,
277}
278impl UseTree {
279 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
280 pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
281 pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
282 pub fn use_tree_list(&self) -> Option<UseTreeList> { support::child(&self.syntax) }
283 pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) }
284}
285#[derive(Debug, Clone, PartialEq, Eq, Hash)]
286pub struct Path {
287 pub(crate) syntax: SyntaxNode,
288}
289impl Path {
290 pub fn qualifier(&self) -> Option<Path> { support::child(&self.syntax) }
291 pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
292 pub fn segment(&self) -> Option<PathSegment> { support::child(&self.syntax) }
293}
294#[derive(Debug, Clone, PartialEq, Eq, Hash)]
295pub struct UseTreeList {
296 pub(crate) syntax: SyntaxNode,
297}
298impl UseTreeList {
299 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
300 pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) }
301 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
302}
303#[derive(Debug, Clone, PartialEq, Eq, Hash)]
304pub struct Abi {
305 pub(crate) syntax: SyntaxNode,
306}
307impl Abi {
308 pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
309}
310#[derive(Debug, Clone, PartialEq, Eq, Hash)]
311pub struct GenericParamList {
312 pub(crate) syntax: SyntaxNode,
313}
314impl GenericParamList {
315 pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
316 pub fn generic_params(&self) -> AstChildren<GenericParam> { support::children(&self.syntax) }
317 pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
318}
319#[derive(Debug, Clone, PartialEq, Eq, Hash)]
320pub struct ParamList {
321 pub(crate) syntax: SyntaxNode,
322}
323impl ParamList {
324 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
325 pub fn self_param(&self) -> Option<SelfParam> { support::child(&self.syntax) }
326 pub fn comma_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![,]) }
327 pub fn params(&self) -> AstChildren<Param> { support::children(&self.syntax) }
328 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
329}
330#[derive(Debug, Clone, PartialEq, Eq, Hash)]
331pub struct RetType {
332 pub(crate) syntax: SyntaxNode,
333}
334impl RetType {
335 pub fn thin_arrow_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![->]) }
336 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
337}
338#[derive(Debug, Clone, PartialEq, Eq, Hash)]
339pub struct WhereClause {
340 pub(crate) syntax: SyntaxNode,
341}
342impl WhereClause {
343 pub fn where_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![where]) }
344 pub fn predicates(&self) -> AstChildren<WherePred> { support::children(&self.syntax) }
345}
346#[derive(Debug, Clone, PartialEq, Eq, Hash)]
347pub struct BlockExpr {
348 pub(crate) syntax: SyntaxNode,
349}
350impl ast::AttrsOwner for BlockExpr {}
351impl ast::ModuleItemOwner for BlockExpr {}
352impl BlockExpr {
353 pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
354 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
355 pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
356 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
357 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
358}
359#[derive(Debug, Clone, PartialEq, Eq, Hash)]
360pub struct SelfParam {
361 pub(crate) syntax: SyntaxNode,
362}
363impl ast::AttrsOwner for SelfParam {}
364impl SelfParam {
365 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
366 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
367 support::token(&self.syntax, T![lifetime])
368 }
369 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
370 pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
371 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
372 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
373}
374#[derive(Debug, Clone, PartialEq, Eq, Hash)]
375pub struct Param {
376 pub(crate) syntax: SyntaxNode,
377}
378impl ast::AttrsOwner for Param {}
379impl Param {
380 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
381 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
382 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
383 pub fn dotdotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![...]) }
384}
385#[derive(Debug, Clone, PartialEq, Eq, Hash)]
386pub struct TypeBoundList {
387 pub(crate) syntax: SyntaxNode,
388}
389impl TypeBoundList {
390 pub fn bounds(&self) -> AstChildren<TypeBound> { support::children(&self.syntax) }
391}
392#[derive(Debug, Clone, PartialEq, Eq, Hash)]
393pub struct RecordFieldList {
394 pub(crate) syntax: SyntaxNode,
395}
396impl RecordFieldList {
397 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
398 pub fn fields(&self) -> AstChildren<RecordField> { support::children(&self.syntax) }
399 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
400}
401#[derive(Debug, Clone, PartialEq, Eq, Hash)]
402pub struct TupleFieldList {
403 pub(crate) syntax: SyntaxNode,
404}
405impl TupleFieldList {
406 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
407 pub fn fields(&self) -> AstChildren<TupleField> { support::children(&self.syntax) }
408 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
409}
410#[derive(Debug, Clone, PartialEq, Eq, Hash)]
411pub struct RecordField {
412 pub(crate) syntax: SyntaxNode,
413}
414impl ast::AttrsOwner for RecordField {}
415impl ast::NameOwner for RecordField {}
416impl ast::VisibilityOwner for RecordField {}
417impl RecordField {
418 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
419 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
420}
421#[derive(Debug, Clone, PartialEq, Eq, Hash)]
422pub struct TupleField {
423 pub(crate) syntax: SyntaxNode,
424}
425impl ast::AttrsOwner for TupleField {}
426impl ast::VisibilityOwner for TupleField {}
427impl TupleField {
428 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
429}
430#[derive(Debug, Clone, PartialEq, Eq, Hash)]
431pub struct VariantList {
432 pub(crate) syntax: SyntaxNode,
433}
434impl VariantList {
435 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
436 pub fn variants(&self) -> AstChildren<Variant> { support::children(&self.syntax) }
437 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
438}
439#[derive(Debug, Clone, PartialEq, Eq, Hash)]
440pub struct Variant {
441 pub(crate) syntax: SyntaxNode,
442}
443impl ast::AttrsOwner for Variant {}
444impl ast::NameOwner for Variant {}
445impl ast::VisibilityOwner for Variant {}
446impl Variant {
447 pub fn field_list(&self) -> Option<FieldList> { support::child(&self.syntax) }
448 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
449 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
450}
451#[derive(Debug, Clone, PartialEq, Eq, Hash)]
452pub struct AssocItemList {
453 pub(crate) syntax: SyntaxNode,
454}
455impl ast::AttrsOwner for AssocItemList {}
456impl AssocItemList {
457 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
458 pub fn assoc_items(&self) -> AstChildren<AssocItem> { support::children(&self.syntax) }
459 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
460}
461#[derive(Debug, Clone, PartialEq, Eq, Hash)]
462pub struct ExternItemList {
463 pub(crate) syntax: SyntaxNode,
464}
465impl ast::AttrsOwner for ExternItemList {}
466impl ExternItemList {
467 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
468 pub fn extern_items(&self) -> AstChildren<ExternItem> { support::children(&self.syntax) }
469 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
470}
471#[derive(Debug, Clone, PartialEq, Eq, Hash)]
472pub struct LifetimeParam {
473 pub(crate) syntax: SyntaxNode,
474}
475impl ast::AttrsOwner for LifetimeParam {}
476impl LifetimeParam {
477 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
478 support::token(&self.syntax, T![lifetime])
479 }
480}
481#[derive(Debug, Clone, PartialEq, Eq, Hash)]
482pub struct TypeParam {
483 pub(crate) syntax: SyntaxNode,
484}
485impl ast::AttrsOwner for TypeParam {}
486impl ast::NameOwner for TypeParam {}
487impl ast::TypeBoundsOwner for TypeParam {}
488impl TypeParam {
489 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
490 pub fn default_type(&self) -> Option<TypeRef> { support::child(&self.syntax) }
491}
492#[derive(Debug, Clone, PartialEq, Eq, Hash)]
493pub struct ConstParam {
494 pub(crate) syntax: SyntaxNode,
495}
496impl ast::AttrsOwner for ConstParam {}
497impl ast::NameOwner for ConstParam {}
498impl ConstParam {
499 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
500 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
501 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
502 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
503 pub fn default_val(&self) -> Option<Expr> { support::child(&self.syntax) }
504}
505#[derive(Debug, Clone, PartialEq, Eq, Hash)]
506pub struct Literal {
507 pub(crate) syntax: SyntaxNode,
508}
509impl Literal {}
510#[derive(Debug, Clone, PartialEq, Eq, Hash)]
511pub struct TokenTree {
512 pub(crate) syntax: SyntaxNode,
513}
514impl TokenTree {
515 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
516 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
517 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
518 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
519 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
520 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
521}
522#[derive(Debug, Clone, PartialEq, Eq, Hash)]
523pub struct ParenType {
524 pub(crate) syntax: SyntaxNode,
525}
526impl ParenType {
527 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
528 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
529 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
530}
531#[derive(Debug, Clone, PartialEq, Eq, Hash)]
532pub struct TupleType {
533 pub(crate) syntax: SyntaxNode,
534}
535impl TupleType {
536 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
537 pub fn fields(&self) -> AstChildren<TypeRef> { support::children(&self.syntax) }
538 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
539}
540#[derive(Debug, Clone, PartialEq, Eq, Hash)]
541pub struct NeverType {
542 pub(crate) syntax: SyntaxNode,
543}
544impl NeverType {
545 pub fn excl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![!]) }
546}
547#[derive(Debug, Clone, PartialEq, Eq, Hash)]
548pub struct PathType {
549 pub(crate) syntax: SyntaxNode,
550}
551impl PathType {
552 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
553}
554#[derive(Debug, Clone, PartialEq, Eq, Hash)]
555pub struct PointerType {
556 pub(crate) syntax: SyntaxNode,
557}
558impl PointerType {
559 pub fn star_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![*]) }
560 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
561 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
562 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
563}
564#[derive(Debug, Clone, PartialEq, Eq, Hash)]
565pub struct ArrayType {
566 pub(crate) syntax: SyntaxNode,
567}
568impl ArrayType {
569 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
570 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
571 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
572 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
573 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
574}
575#[derive(Debug, Clone, PartialEq, Eq, Hash)]
576pub struct SliceType {
577 pub(crate) syntax: SyntaxNode,
578}
579impl SliceType {
580 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
581 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
582 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
583}
584#[derive(Debug, Clone, PartialEq, Eq, Hash)]
585pub struct ReferenceType {
586 pub(crate) syntax: SyntaxNode,
587}
588impl ReferenceType {
589 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
590 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
591 support::token(&self.syntax, T![lifetime])
592 }
593 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
594 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
595}
596#[derive(Debug, Clone, PartialEq, Eq, Hash)]
597pub struct PlaceholderType {
598 pub(crate) syntax: SyntaxNode,
599}
600impl PlaceholderType {
601 pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
602}
603#[derive(Debug, Clone, PartialEq, Eq, Hash)]
604pub struct FnPointerType {
605 pub(crate) syntax: SyntaxNode,
606}
607impl FnPointerType {
608 pub fn abi(&self) -> Option<Abi> { support::child(&self.syntax) }
609 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
610 pub fn fn_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![fn]) }
611 pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
612 pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
613}
614#[derive(Debug, Clone, PartialEq, Eq, Hash)]
615pub struct ForType {
616 pub(crate) syntax: SyntaxNode,
617}
618impl ForType {
619 pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
620 pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
621 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
622}
623#[derive(Debug, Clone, PartialEq, Eq, Hash)]
624pub struct ImplTraitType {
625 pub(crate) syntax: SyntaxNode,
626}
627impl ImplTraitType {
628 pub fn impl_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![impl]) }
629 pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
630}
631#[derive(Debug, Clone, PartialEq, Eq, Hash)]
632pub struct DynTraitType {
633 pub(crate) syntax: SyntaxNode,
634}
635impl DynTraitType {
636 pub fn dyn_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![dyn]) }
637 pub fn type_bound_list(&self) -> Option<TypeBoundList> { support::child(&self.syntax) }
638}
639#[derive(Debug, Clone, PartialEq, Eq, Hash)]
640pub struct TupleExpr {
641 pub(crate) syntax: SyntaxNode,
642}
643impl ast::AttrsOwner for TupleExpr {}
644impl TupleExpr {
645 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
646 pub fn exprs(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
647 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
648}
649#[derive(Debug, Clone, PartialEq, Eq, Hash)]
650pub struct ArrayExpr {
651 pub(crate) syntax: SyntaxNode,
652}
653impl ast::AttrsOwner for ArrayExpr {}
654impl ArrayExpr {
655 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
656 pub fn exprs(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
657 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
658 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
659 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
660}
661#[derive(Debug, Clone, PartialEq, Eq, Hash)]
662pub struct ParenExpr {
663 pub(crate) syntax: SyntaxNode,
664}
665impl ast::AttrsOwner for ParenExpr {}
666impl ParenExpr {
667 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
668 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
669 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
670}
671#[derive(Debug, Clone, PartialEq, Eq, Hash)]
672pub struct PathExpr {
673 pub(crate) syntax: SyntaxNode,
674}
675impl PathExpr {
676 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
677}
678#[derive(Debug, Clone, PartialEq, Eq, Hash)]
679pub struct LambdaExpr {
680 pub(crate) syntax: SyntaxNode,
681}
682impl ast::AttrsOwner for LambdaExpr {}
683impl LambdaExpr {
684 pub fn static_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![static]) }
685 pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
686 pub fn move_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![move]) }
687 pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
688 pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
689 pub fn body(&self) -> Option<Expr> { support::child(&self.syntax) }
690}
691#[derive(Debug, Clone, PartialEq, Eq, Hash)]
692pub struct IfExpr {
693 pub(crate) syntax: SyntaxNode,
694}
695impl ast::AttrsOwner for IfExpr {}
696impl IfExpr {
697 pub fn if_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![if]) }
698 pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) }
699}
700#[derive(Debug, Clone, PartialEq, Eq, Hash)]
701pub struct Condition {
702 pub(crate) syntax: SyntaxNode,
703}
704impl Condition {
705 pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
706 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
707 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
708 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
709}
710#[derive(Debug, Clone, PartialEq, Eq, Hash)]
711pub struct EffectExpr {
712 pub(crate) syntax: SyntaxNode,
713}
714impl ast::AttrsOwner for EffectExpr {}
715impl EffectExpr {
716 pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
717 pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) }
718 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
719 pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
720 pub fn block_expr(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
721}
722#[derive(Debug, Clone, PartialEq, Eq, Hash)]
723pub struct Label {
724 pub(crate) syntax: SyntaxNode,
725}
726impl Label {
727 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
728 support::token(&self.syntax, T![lifetime])
729 }
730}
731#[derive(Debug, Clone, PartialEq, Eq, Hash)]
732pub struct LoopExpr {
733 pub(crate) syntax: SyntaxNode,
734}
735impl ast::AttrsOwner for LoopExpr {}
736impl ast::LoopBodyOwner for LoopExpr {}
737impl LoopExpr {
738 pub fn loop_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![loop]) }
739}
740#[derive(Debug, Clone, PartialEq, Eq, Hash)]
741pub struct ForExpr {
742 pub(crate) syntax: SyntaxNode,
743}
744impl ast::AttrsOwner for ForExpr {}
745impl ast::LoopBodyOwner for ForExpr {}
746impl ForExpr {
747 pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
748 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
749 pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) }
750 pub fn iterable(&self) -> Option<Expr> { support::child(&self.syntax) }
751}
752#[derive(Debug, Clone, PartialEq, Eq, Hash)]
753pub struct WhileExpr {
754 pub(crate) syntax: SyntaxNode,
755}
756impl ast::AttrsOwner for WhileExpr {}
757impl ast::LoopBodyOwner for WhileExpr {}
758impl WhileExpr {
759 pub fn while_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![while]) }
760 pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) }
761}
762#[derive(Debug, Clone, PartialEq, Eq, Hash)]
763pub struct ContinueExpr {
764 pub(crate) syntax: SyntaxNode,
765}
766impl ast::AttrsOwner for ContinueExpr {}
767impl ContinueExpr {
768 pub fn continue_token(&self) -> Option<SyntaxToken> {
769 support::token(&self.syntax, T![continue])
770 }
771 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
772 support::token(&self.syntax, T![lifetime])
773 }
774}
775#[derive(Debug, Clone, PartialEq, Eq, Hash)]
776pub struct BreakExpr {
777 pub(crate) syntax: SyntaxNode,
778}
779impl ast::AttrsOwner for BreakExpr {}
780impl BreakExpr {
781 pub fn break_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![break]) }
782 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
783 support::token(&self.syntax, T![lifetime])
784 }
785 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
786}
787#[derive(Debug, Clone, PartialEq, Eq, Hash)]
788pub struct ReturnExpr {
789 pub(crate) syntax: SyntaxNode,
790}
791impl ast::AttrsOwner for ReturnExpr {}
792impl ReturnExpr {
793 pub fn return_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![return]) }
794 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
795}
796#[derive(Debug, Clone, PartialEq, Eq, Hash)]
797pub struct CallExpr {
798 pub(crate) syntax: SyntaxNode,
799}
800impl ast::AttrsOwner for CallExpr {}
801impl ast::ArgListOwner for CallExpr {}
802impl CallExpr {
803 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
804}
805#[derive(Debug, Clone, PartialEq, Eq, Hash)]
806pub struct ArgList {
807 pub(crate) syntax: SyntaxNode,
808}
809impl ArgList {
810 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
811 pub fn args(&self) -> AstChildren<Expr> { support::children(&self.syntax) }
812 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
813}
814#[derive(Debug, Clone, PartialEq, Eq, Hash)]
815pub struct MethodCallExpr {
816 pub(crate) syntax: SyntaxNode,
817}
818impl ast::AttrsOwner for MethodCallExpr {}
819impl ast::ArgListOwner for MethodCallExpr {}
820impl MethodCallExpr {
821 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
822 pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
823 pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
824 pub fn type_arg_list(&self) -> Option<TypeArgList> { support::child(&self.syntax) }
825}
826#[derive(Debug, Clone, PartialEq, Eq, Hash)]
827pub struct TypeArgList {
828 pub(crate) syntax: SyntaxNode,
829}
830impl TypeArgList {
831 pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
832 pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
833 pub fn type_args(&self) -> AstChildren<TypeArg> { support::children(&self.syntax) }
834 pub fn lifetime_args(&self) -> AstChildren<LifetimeArg> { support::children(&self.syntax) }
835 pub fn assoc_type_args(&self) -> AstChildren<AssocTypeArg> { support::children(&self.syntax) }
836 pub fn const_args(&self) -> AstChildren<ConstArg> { support::children(&self.syntax) }
837 pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
838}
839#[derive(Debug, Clone, PartialEq, Eq, Hash)]
840pub struct FieldExpr {
841 pub(crate) syntax: SyntaxNode,
842}
843impl ast::AttrsOwner for FieldExpr {}
844impl FieldExpr {
845 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
846 pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
847 pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
848}
849#[derive(Debug, Clone, PartialEq, Eq, Hash)]
850pub struct IndexExpr {
851 pub(crate) syntax: SyntaxNode,
852}
853impl ast::AttrsOwner for IndexExpr {}
854impl IndexExpr {
855 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
856 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
857}
858#[derive(Debug, Clone, PartialEq, Eq, Hash)]
859pub struct AwaitExpr {
860 pub(crate) syntax: SyntaxNode,
861}
862impl ast::AttrsOwner for AwaitExpr {}
863impl AwaitExpr {
864 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
865 pub fn dot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![.]) }
866 pub fn await_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![await]) }
867}
868#[derive(Debug, Clone, PartialEq, Eq, Hash)]
869pub struct TryExpr {
870 pub(crate) syntax: SyntaxNode,
871}
872impl ast::AttrsOwner for TryExpr {}
873impl TryExpr {
874 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
875 pub fn question_mark_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![?]) }
876}
877#[derive(Debug, Clone, PartialEq, Eq, Hash)]
878pub struct CastExpr {
879 pub(crate) syntax: SyntaxNode,
880}
881impl ast::AttrsOwner for CastExpr {}
882impl CastExpr {
883 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
884 pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
885 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
886}
887#[derive(Debug, Clone, PartialEq, Eq, Hash)]
888pub struct RefExpr {
889 pub(crate) syntax: SyntaxNode,
890}
891impl ast::AttrsOwner for RefExpr {}
892impl RefExpr {
893 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
894 pub fn raw_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![raw]) }
895 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
896 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
897 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
898}
899#[derive(Debug, Clone, PartialEq, Eq, Hash)]
900pub struct PrefixExpr {
901 pub(crate) syntax: SyntaxNode,
902}
903impl ast::AttrsOwner for PrefixExpr {}
904impl PrefixExpr {
905 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
906}
907#[derive(Debug, Clone, PartialEq, Eq, Hash)]
908pub struct BoxExpr {
909 pub(crate) syntax: SyntaxNode,
910}
911impl ast::AttrsOwner for BoxExpr {}
912impl BoxExpr {
913 pub fn box_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![box]) }
914 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
915}
916#[derive(Debug, Clone, PartialEq, Eq, Hash)]
917pub struct RangeExpr {
918 pub(crate) syntax: SyntaxNode,
919}
920impl ast::AttrsOwner for RangeExpr {}
921impl RangeExpr {}
922#[derive(Debug, Clone, PartialEq, Eq, Hash)]
923pub struct BinExpr {
924 pub(crate) syntax: SyntaxNode,
925}
926impl ast::AttrsOwner for BinExpr {}
927impl BinExpr {}
928#[derive(Debug, Clone, PartialEq, Eq, Hash)]
929pub struct MatchExpr {
930 pub(crate) syntax: SyntaxNode,
931}
932impl ast::AttrsOwner for MatchExpr {}
933impl MatchExpr {
934 pub fn match_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![match]) }
935 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
936 pub fn match_arm_list(&self) -> Option<MatchArmList> { support::child(&self.syntax) }
937}
938#[derive(Debug, Clone, PartialEq, Eq, Hash)]
939pub struct MatchArmList {
940 pub(crate) syntax: SyntaxNode,
941}
942impl MatchArmList {
943 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
944 pub fn arms(&self) -> AstChildren<MatchArm> { support::children(&self.syntax) }
945 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
946}
947#[derive(Debug, Clone, PartialEq, Eq, Hash)]
948pub struct MatchArm {
949 pub(crate) syntax: SyntaxNode,
950}
951impl ast::AttrsOwner for MatchArm {}
952impl MatchArm {
953 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
954 pub fn guard(&self) -> Option<MatchGuard> { support::child(&self.syntax) }
955 pub fn fat_arrow_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=>]) }
956 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
957}
958#[derive(Debug, Clone, PartialEq, Eq, Hash)]
959pub struct MatchGuard {
960 pub(crate) syntax: SyntaxNode,
961}
962impl MatchGuard {
963 pub fn if_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![if]) }
964 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
965}
966#[derive(Debug, Clone, PartialEq, Eq, Hash)]
967pub struct RecordExpr {
968 pub(crate) syntax: SyntaxNode,
969}
970impl RecordExpr {
971 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
972 pub fn record_expr_field_list(&self) -> Option<RecordExprFieldList> {
973 support::child(&self.syntax)
974 }
975}
976#[derive(Debug, Clone, PartialEq, Eq, Hash)]
977pub struct RecordExprFieldList {
978 pub(crate) syntax: SyntaxNode,
979}
980impl RecordExprFieldList {
981 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
982 pub fn fields(&self) -> AstChildren<RecordExprField> { support::children(&self.syntax) }
983 pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
984 pub fn spread(&self) -> Option<Expr> { support::child(&self.syntax) }
985 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
986}
987#[derive(Debug, Clone, PartialEq, Eq, Hash)]
988pub struct RecordExprField {
989 pub(crate) syntax: SyntaxNode,
990}
991impl ast::AttrsOwner for RecordExprField {}
992impl RecordExprField {
993 pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
994 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
995 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
996}
997#[derive(Debug, Clone, PartialEq, Eq, Hash)]
998pub struct OrPat {
999 pub(crate) syntax: SyntaxNode,
1000}
1001impl OrPat {
1002 pub fn pats(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
1003}
1004#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1005pub struct ParenPat {
1006 pub(crate) syntax: SyntaxNode,
1007}
1008impl ParenPat {
1009 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
1010 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
1011 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
1012}
1013#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1014pub struct RefPat {
1015 pub(crate) syntax: SyntaxNode,
1016}
1017impl RefPat {
1018 pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
1019 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
1020 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
1021}
1022#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1023pub struct BoxPat {
1024 pub(crate) syntax: SyntaxNode,
1025}
1026impl BoxPat {
1027 pub fn box_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![box]) }
1028 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
1029}
1030#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1031pub struct BindPat {
1032 pub(crate) syntax: SyntaxNode,
1033}
1034impl ast::AttrsOwner for BindPat {}
1035impl ast::NameOwner for BindPat {}
1036impl BindPat {
1037 pub fn ref_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ref]) }
1038 pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
1039 pub fn at_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![@]) }
1040 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
1041}
1042#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1043pub struct PlaceholderPat {
1044 pub(crate) syntax: SyntaxNode,
1045}
1046impl PlaceholderPat {
1047 pub fn underscore_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![_]) }
1048}
1049#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1050pub struct DotDotPat {
1051 pub(crate) syntax: SyntaxNode,
1052}
1053impl DotDotPat {
1054 pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
1055}
1056#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1057pub struct PathPat {
1058 pub(crate) syntax: SyntaxNode,
1059}
1060impl PathPat {
1061 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
1062}
1063#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1064pub struct SlicePat {
1065 pub(crate) syntax: SyntaxNode,
1066}
1067impl SlicePat {
1068 pub fn l_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['[']) }
1069 pub fn args(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
1070 pub fn r_brack_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![']']) }
1071}
1072#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1073pub struct RangePat {
1074 pub(crate) syntax: SyntaxNode,
1075}
1076impl RangePat {
1077 pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
1078 pub fn dotdoteq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..=]) }
1079}
1080#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1081pub struct LiteralPat {
1082 pub(crate) syntax: SyntaxNode,
1083}
1084impl LiteralPat {
1085 pub fn literal(&self) -> Option<Literal> { support::child(&self.syntax) }
1086}
1087#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1088pub struct MacroPat {
1089 pub(crate) syntax: SyntaxNode,
1090}
1091impl MacroPat {
1092 pub fn macro_call(&self) -> Option<MacroCall> { support::child(&self.syntax) }
1093}
1094#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1095pub struct RecordPat {
1096 pub(crate) syntax: SyntaxNode,
1097}
1098impl RecordPat {
1099 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
1100 pub fn record_field_pat_list(&self) -> Option<RecordFieldPatList> {
1101 support::child(&self.syntax)
1102 }
1103}
1104#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1105pub struct RecordFieldPatList {
1106 pub(crate) syntax: SyntaxNode,
1107}
1108impl RecordFieldPatList {
1109 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
1110 pub fn record_field_pats(&self) -> AstChildren<RecordFieldPat> {
1111 support::children(&self.syntax)
1112 }
1113 pub fn bind_pats(&self) -> AstChildren<BindPat> { support::children(&self.syntax) }
1114 pub fn dotdot_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![..]) }
1115 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
1116}
1117#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1118pub struct RecordFieldPat {
1119 pub(crate) syntax: SyntaxNode,
1120}
1121impl ast::AttrsOwner for RecordFieldPat {}
1122impl RecordFieldPat {
1123 pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
1124 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
1125 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
1126}
1127#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1128pub struct TupleStructPat {
1129 pub(crate) syntax: SyntaxNode,
1130}
1131impl TupleStructPat {
1132 pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
1133 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
1134 pub fn args(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
1135 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
1136}
1137#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1138pub struct TuplePat {
1139 pub(crate) syntax: SyntaxNode,
1140}
1141impl TuplePat {
1142 pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
1143 pub fn args(&self) -> AstChildren<Pat> { support::children(&self.syntax) }
1144 pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
1145}
1146#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1147pub struct MacroDef {
1148 pub(crate) syntax: SyntaxNode,
1149}
1150impl ast::NameOwner for MacroDef {}
1151impl MacroDef {
1152 pub fn token_tree(&self) -> Option<TokenTree> { support::child(&self.syntax) }
1153}
1154#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1155pub struct MacroItems {
1156 pub(crate) syntax: SyntaxNode,
1157}
1158impl ast::ModuleItemOwner for MacroItems {}
1159impl MacroItems {}
1160#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1161pub struct MacroStmts {
1162 pub(crate) syntax: SyntaxNode,
1163}
1164impl MacroStmts {
1165 pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
1166 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
1167}
1168#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1169pub struct TypeBound {
1170 pub(crate) syntax: SyntaxNode,
1171}
1172impl TypeBound {
1173 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
1174 support::token(&self.syntax, T![lifetime])
1175 }
1176 pub fn const_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![const]) }
1177 pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
1178}
1179#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1180pub struct WherePred {
1181 pub(crate) syntax: SyntaxNode,
1182}
1183impl ast::TypeBoundsOwner for WherePred {}
1184impl WherePred {
1185 pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
1186 pub fn generic_param_list(&self) -> Option<GenericParamList> { support::child(&self.syntax) }
1187 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
1188 support::token(&self.syntax, T![lifetime])
1189 }
1190 pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
1191}
1192#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1193pub struct ExprStmt {
1194 pub(crate) syntax: SyntaxNode,
1195}
1196impl ast::AttrsOwner for ExprStmt {}
1197impl ExprStmt {
1198 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
1199 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
1200}
1201#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1202pub struct LetStmt {
1203 pub(crate) syntax: SyntaxNode,
1204}
1205impl ast::AttrsOwner for LetStmt {}
1206impl LetStmt {
1207 pub fn let_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![let]) }
1208 pub fn pat(&self) -> Option<Pat> { support::child(&self.syntax) }
1209 pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
1210 pub fn ty(&self) -> Option<TypeRef> { support::child(&self.syntax) }
1211 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
1212 pub fn initializer(&self) -> Option<Expr> { support::child(&self.syntax) }
1213 pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
1214}
1215#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1216pub struct PathSegment {
1217 pub(crate) syntax: SyntaxNode,
1218}
1219impl PathSegment {
1220 pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
1221 pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
1222 pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
1223 pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) }
1224 pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
1225 pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
1226 pub fn type_arg_list(&self) -> Option<TypeArgList> { support::child(&self.syntax) }
1227 pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
1228 pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
1229 pub fn path_type(&self) -> Option<PathType> { support::child(&self.syntax) }
1230 pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
1231}
1232#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1233pub struct TypeArg {
1234 pub(crate) syntax: SyntaxNode,
1235}
1236impl TypeArg {
1237 pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
1238}
1239#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1240pub struct LifetimeArg {
1241 pub(crate) syntax: SyntaxNode,
1242}
1243impl LifetimeArg {
1244 pub fn lifetime_token(&self) -> Option<SyntaxToken> {
1245 support::token(&self.syntax, T![lifetime])
1246 }
1247}
1248#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1249pub struct AssocTypeArg {
1250 pub(crate) syntax: SyntaxNode,
1251}
1252impl ast::TypeBoundsOwner for AssocTypeArg {}
1253impl AssocTypeArg {
1254 pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
1255 pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
1256 pub fn type_ref(&self) -> Option<TypeRef> { support::child(&self.syntax) }
1257}
1258#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1259pub struct ConstArg {
1260 pub(crate) syntax: SyntaxNode,
1261}
1262impl ConstArg {
1263 pub fn literal(&self) -> Option<Literal> { support::child(&self.syntax) }
1264 pub fn block_expr(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
1265}
1266#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1267pub enum Item {
1268 Const(Const),
1269 Enum(Enum),
1270 ExternBlock(ExternBlock),
1271 ExternCrate(ExternCrate),
1272 Fn(Fn),
1273 Impl(Impl),
1274 MacroCall(MacroCall),
1275 Module(Module),
1276 Static(Static),
1277 Struct(Struct),
1278 Trait(Trait),
1279 TypeAlias(TypeAlias),
1280 Union(Union),
1281 Use(Use),
1282}
1283impl ast::AttrsOwner for Item {}
1284#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1285pub enum TypeRef {
1286 ParenType(ParenType),
1287 TupleType(TupleType),
1288 NeverType(NeverType),
1289 PathType(PathType),
1290 PointerType(PointerType),
1291 ArrayType(ArrayType),
1292 SliceType(SliceType),
1293 ReferenceType(ReferenceType),
1294 PlaceholderType(PlaceholderType),
1295 FnPointerType(FnPointerType),
1296 ForType(ForType),
1297 ImplTraitType(ImplTraitType),
1298 DynTraitType(DynTraitType),
1299}
1300#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1301pub enum Pat {
1302 OrPat(OrPat),
1303 ParenPat(ParenPat),
1304 RefPat(RefPat),
1305 BoxPat(BoxPat),
1306 BindPat(BindPat),
1307 PlaceholderPat(PlaceholderPat),
1308 DotDotPat(DotDotPat),
1309 PathPat(PathPat),
1310 RecordPat(RecordPat),
1311 TupleStructPat(TupleStructPat),
1312 TuplePat(TuplePat),
1313 SlicePat(SlicePat),
1314 RangePat(RangePat),
1315 LiteralPat(LiteralPat),
1316 MacroPat(MacroPat),
1317}
1318#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1319pub enum FieldList {
1320 RecordFieldList(RecordFieldList),
1321 TupleFieldList(TupleFieldList),
1322}
1323#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1324pub enum Expr {
1325 TupleExpr(TupleExpr),
1326 ArrayExpr(ArrayExpr),
1327 ParenExpr(ParenExpr),
1328 PathExpr(PathExpr),
1329 LambdaExpr(LambdaExpr),
1330 IfExpr(IfExpr),
1331 LoopExpr(LoopExpr),
1332 ForExpr(ForExpr),
1333 WhileExpr(WhileExpr),
1334 ContinueExpr(ContinueExpr),
1335 BreakExpr(BreakExpr),
1336 Label(Label),
1337 BlockExpr(BlockExpr),
1338 ReturnExpr(ReturnExpr),
1339 MatchExpr(MatchExpr),
1340 RecordExpr(RecordExpr),
1341 CallExpr(CallExpr),
1342 IndexExpr(IndexExpr),
1343 MethodCallExpr(MethodCallExpr),
1344 FieldExpr(FieldExpr),
1345 AwaitExpr(AwaitExpr),
1346 TryExpr(TryExpr),
1347 EffectExpr(EffectExpr),
1348 CastExpr(CastExpr),
1349 RefExpr(RefExpr),
1350 PrefixExpr(PrefixExpr),
1351 RangeExpr(RangeExpr),
1352 BinExpr(BinExpr),
1353 Literal(Literal),
1354 MacroCall(MacroCall),
1355 BoxExpr(BoxExpr),
1356}
1357#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1358pub enum AssocItem {
1359 Fn(Fn),
1360 TypeAlias(TypeAlias),
1361 Const(Const),
1362 MacroCall(MacroCall),
1363}
1364impl ast::AttrsOwner for AssocItem {}
1365impl ast::NameOwner for AssocItem {}
1366#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1367pub enum ExternItem {
1368 Fn(Fn),
1369 Static(Static),
1370 MacroCall(MacroCall),
1371}
1372impl ast::AttrsOwner for ExternItem {}
1373impl ast::NameOwner for ExternItem {}
1374#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1375pub enum GenericParam {
1376 LifetimeParam(LifetimeParam),
1377 TypeParam(TypeParam),
1378 ConstParam(ConstParam),
1379}
1380impl ast::AttrsOwner for GenericParam {}
1381#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1382pub enum Stmt {
1383 LetStmt(LetStmt),
1384 ExprStmt(ExprStmt),
1385}
1386impl ast::AttrsOwner for Stmt {}
1387#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1388pub enum AdtDef {
1389 Struct(Struct),
1390 Enum(Enum),
1391 Union(Union),
1392}
1393impl ast::AttrsOwner for AdtDef {}
1394impl ast::GenericParamsOwner for AdtDef {}
1395impl ast::NameOwner for AdtDef {}
1396impl ast::VisibilityOwner for AdtDef {}
1397impl AstNode for SourceFile {
1398 fn can_cast(kind: SyntaxKind) -> bool { kind == SOURCE_FILE }
1399 fn cast(syntax: SyntaxNode) -> Option<Self> {
1400 if Self::can_cast(syntax.kind()) {
1401 Some(Self { syntax })
1402 } else {
1403 None
1404 }
1405 }
1406 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1407}
1408impl AstNode for Attr {
1409 fn can_cast(kind: SyntaxKind) -> bool { kind == ATTR }
1410 fn cast(syntax: SyntaxNode) -> Option<Self> {
1411 if Self::can_cast(syntax.kind()) {
1412 Some(Self { syntax })
1413 } else {
1414 None
1415 }
1416 }
1417 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1418}
1419impl AstNode for Const {
1420 fn can_cast(kind: SyntaxKind) -> bool { kind == CONST }
1421 fn cast(syntax: SyntaxNode) -> Option<Self> {
1422 if Self::can_cast(syntax.kind()) {
1423 Some(Self { syntax })
1424 } else {
1425 None
1426 }
1427 }
1428 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1429}
1430impl AstNode for Enum {
1431 fn can_cast(kind: SyntaxKind) -> bool { kind == ENUM }
1432 fn cast(syntax: SyntaxNode) -> Option<Self> {
1433 if Self::can_cast(syntax.kind()) {
1434 Some(Self { syntax })
1435 } else {
1436 None
1437 }
1438 }
1439 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1440}
1441impl AstNode for ExternBlock {
1442 fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_BLOCK }
1443 fn cast(syntax: SyntaxNode) -> Option<Self> {
1444 if Self::can_cast(syntax.kind()) {
1445 Some(Self { syntax })
1446 } else {
1447 None
1448 }
1449 }
1450 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1451}
1452impl AstNode for ExternCrate {
1453 fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_CRATE }
1454 fn cast(syntax: SyntaxNode) -> Option<Self> {
1455 if Self::can_cast(syntax.kind()) {
1456 Some(Self { syntax })
1457 } else {
1458 None
1459 }
1460 }
1461 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1462}
1463impl AstNode for Fn {
1464 fn can_cast(kind: SyntaxKind) -> bool { kind == FN }
1465 fn cast(syntax: SyntaxNode) -> Option<Self> {
1466 if Self::can_cast(syntax.kind()) {
1467 Some(Self { syntax })
1468 } else {
1469 None
1470 }
1471 }
1472 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1473}
1474impl AstNode for Impl {
1475 fn can_cast(kind: SyntaxKind) -> bool { kind == IMPL }
1476 fn cast(syntax: SyntaxNode) -> Option<Self> {
1477 if Self::can_cast(syntax.kind()) {
1478 Some(Self { syntax })
1479 } else {
1480 None
1481 }
1482 }
1483 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1484}
1485impl AstNode for MacroCall {
1486 fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_CALL }
1487 fn cast(syntax: SyntaxNode) -> Option<Self> {
1488 if Self::can_cast(syntax.kind()) {
1489 Some(Self { syntax })
1490 } else {
1491 None
1492 }
1493 }
1494 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1495}
1496impl AstNode for Module {
1497 fn can_cast(kind: SyntaxKind) -> bool { kind == MODULE }
1498 fn cast(syntax: SyntaxNode) -> Option<Self> {
1499 if Self::can_cast(syntax.kind()) {
1500 Some(Self { syntax })
1501 } else {
1502 None
1503 }
1504 }
1505 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1506}
1507impl AstNode for Static {
1508 fn can_cast(kind: SyntaxKind) -> bool { kind == STATIC }
1509 fn cast(syntax: SyntaxNode) -> Option<Self> {
1510 if Self::can_cast(syntax.kind()) {
1511 Some(Self { syntax })
1512 } else {
1513 None
1514 }
1515 }
1516 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1517}
1518impl AstNode for Struct {
1519 fn can_cast(kind: SyntaxKind) -> bool { kind == STRUCT }
1520 fn cast(syntax: SyntaxNode) -> Option<Self> {
1521 if Self::can_cast(syntax.kind()) {
1522 Some(Self { syntax })
1523 } else {
1524 None
1525 }
1526 }
1527 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1528}
1529impl AstNode for Trait {
1530 fn can_cast(kind: SyntaxKind) -> bool { kind == TRAIT }
1531 fn cast(syntax: SyntaxNode) -> Option<Self> {
1532 if Self::can_cast(syntax.kind()) {
1533 Some(Self { syntax })
1534 } else {
1535 None
1536 }
1537 }
1538 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1539}
1540impl AstNode for TypeAlias {
1541 fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ALIAS }
1542 fn cast(syntax: SyntaxNode) -> Option<Self> {
1543 if Self::can_cast(syntax.kind()) {
1544 Some(Self { syntax })
1545 } else {
1546 None
1547 }
1548 }
1549 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1550}
1551impl AstNode for Union {
1552 fn can_cast(kind: SyntaxKind) -> bool { kind == UNION }
1553 fn cast(syntax: SyntaxNode) -> Option<Self> {
1554 if Self::can_cast(syntax.kind()) {
1555 Some(Self { syntax })
1556 } else {
1557 None
1558 }
1559 }
1560 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1561}
1562impl AstNode for Use {
1563 fn can_cast(kind: SyntaxKind) -> bool { kind == USE }
1564 fn cast(syntax: SyntaxNode) -> Option<Self> {
1565 if Self::can_cast(syntax.kind()) {
1566 Some(Self { syntax })
1567 } else {
1568 None
1569 }
1570 }
1571 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1572}
1573impl AstNode for Visibility {
1574 fn can_cast(kind: SyntaxKind) -> bool { kind == VISIBILITY }
1575 fn cast(syntax: SyntaxNode) -> Option<Self> {
1576 if Self::can_cast(syntax.kind()) {
1577 Some(Self { syntax })
1578 } else {
1579 None
1580 }
1581 }
1582 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1583}
1584impl AstNode for Name {
1585 fn can_cast(kind: SyntaxKind) -> bool { kind == NAME }
1586 fn cast(syntax: SyntaxNode) -> Option<Self> {
1587 if Self::can_cast(syntax.kind()) {
1588 Some(Self { syntax })
1589 } else {
1590 None
1591 }
1592 }
1593 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1594}
1595impl AstNode for ItemList {
1596 fn can_cast(kind: SyntaxKind) -> bool { kind == ITEM_LIST }
1597 fn cast(syntax: SyntaxNode) -> Option<Self> {
1598 if Self::can_cast(syntax.kind()) {
1599 Some(Self { syntax })
1600 } else {
1601 None
1602 }
1603 }
1604 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1605}
1606impl AstNode for NameRef {
1607 fn can_cast(kind: SyntaxKind) -> bool { kind == NAME_REF }
1608 fn cast(syntax: SyntaxNode) -> Option<Self> {
1609 if Self::can_cast(syntax.kind()) {
1610 Some(Self { syntax })
1611 } else {
1612 None
1613 }
1614 }
1615 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1616}
1617impl AstNode for Rename {
1618 fn can_cast(kind: SyntaxKind) -> bool { kind == RENAME }
1619 fn cast(syntax: SyntaxNode) -> Option<Self> {
1620 if Self::can_cast(syntax.kind()) {
1621 Some(Self { syntax })
1622 } else {
1623 None
1624 }
1625 }
1626 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1627}
1628impl AstNode for UseTree {
1629 fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE }
1630 fn cast(syntax: SyntaxNode) -> Option<Self> {
1631 if Self::can_cast(syntax.kind()) {
1632 Some(Self { syntax })
1633 } else {
1634 None
1635 }
1636 }
1637 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1638}
1639impl AstNode for Path {
1640 fn can_cast(kind: SyntaxKind) -> bool { kind == PATH }
1641 fn cast(syntax: SyntaxNode) -> Option<Self> {
1642 if Self::can_cast(syntax.kind()) {
1643 Some(Self { syntax })
1644 } else {
1645 None
1646 }
1647 }
1648 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1649}
1650impl AstNode for UseTreeList {
1651 fn can_cast(kind: SyntaxKind) -> bool { kind == USE_TREE_LIST }
1652 fn cast(syntax: SyntaxNode) -> Option<Self> {
1653 if Self::can_cast(syntax.kind()) {
1654 Some(Self { syntax })
1655 } else {
1656 None
1657 }
1658 }
1659 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1660}
1661impl AstNode for Abi {
1662 fn can_cast(kind: SyntaxKind) -> bool { kind == ABI }
1663 fn cast(syntax: SyntaxNode) -> Option<Self> {
1664 if Self::can_cast(syntax.kind()) {
1665 Some(Self { syntax })
1666 } else {
1667 None
1668 }
1669 }
1670 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1671}
1672impl AstNode for GenericParamList {
1673 fn can_cast(kind: SyntaxKind) -> bool { kind == GENERIC_PARAM_LIST }
1674 fn cast(syntax: SyntaxNode) -> Option<Self> {
1675 if Self::can_cast(syntax.kind()) {
1676 Some(Self { syntax })
1677 } else {
1678 None
1679 }
1680 }
1681 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1682}
1683impl AstNode for ParamList {
1684 fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM_LIST }
1685 fn cast(syntax: SyntaxNode) -> Option<Self> {
1686 if Self::can_cast(syntax.kind()) {
1687 Some(Self { syntax })
1688 } else {
1689 None
1690 }
1691 }
1692 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1693}
1694impl AstNode for RetType {
1695 fn can_cast(kind: SyntaxKind) -> bool { kind == RET_TYPE }
1696 fn cast(syntax: SyntaxNode) -> Option<Self> {
1697 if Self::can_cast(syntax.kind()) {
1698 Some(Self { syntax })
1699 } else {
1700 None
1701 }
1702 }
1703 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1704}
1705impl AstNode for WhereClause {
1706 fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_CLAUSE }
1707 fn cast(syntax: SyntaxNode) -> Option<Self> {
1708 if Self::can_cast(syntax.kind()) {
1709 Some(Self { syntax })
1710 } else {
1711 None
1712 }
1713 }
1714 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1715}
1716impl AstNode for BlockExpr {
1717 fn can_cast(kind: SyntaxKind) -> bool { kind == BLOCK_EXPR }
1718 fn cast(syntax: SyntaxNode) -> Option<Self> {
1719 if Self::can_cast(syntax.kind()) {
1720 Some(Self { syntax })
1721 } else {
1722 None
1723 }
1724 }
1725 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1726}
1727impl AstNode for SelfParam {
1728 fn can_cast(kind: SyntaxKind) -> bool { kind == SELF_PARAM }
1729 fn cast(syntax: SyntaxNode) -> Option<Self> {
1730 if Self::can_cast(syntax.kind()) {
1731 Some(Self { syntax })
1732 } else {
1733 None
1734 }
1735 }
1736 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1737}
1738impl AstNode for Param {
1739 fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM }
1740 fn cast(syntax: SyntaxNode) -> Option<Self> {
1741 if Self::can_cast(syntax.kind()) {
1742 Some(Self { syntax })
1743 } else {
1744 None
1745 }
1746 }
1747 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1748}
1749impl AstNode for TypeBoundList {
1750 fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND_LIST }
1751 fn cast(syntax: SyntaxNode) -> Option<Self> {
1752 if Self::can_cast(syntax.kind()) {
1753 Some(Self { syntax })
1754 } else {
1755 None
1756 }
1757 }
1758 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1759}
1760impl AstNode for RecordFieldList {
1761 fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_LIST }
1762 fn cast(syntax: SyntaxNode) -> Option<Self> {
1763 if Self::can_cast(syntax.kind()) {
1764 Some(Self { syntax })
1765 } else {
1766 None
1767 }
1768 }
1769 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1770}
1771impl AstNode for TupleFieldList {
1772 fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_FIELD_LIST }
1773 fn cast(syntax: SyntaxNode) -> Option<Self> {
1774 if Self::can_cast(syntax.kind()) {
1775 Some(Self { syntax })
1776 } else {
1777 None
1778 }
1779 }
1780 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1781}
1782impl AstNode for RecordField {
1783 fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD }
1784 fn cast(syntax: SyntaxNode) -> Option<Self> {
1785 if Self::can_cast(syntax.kind()) {
1786 Some(Self { syntax })
1787 } else {
1788 None
1789 }
1790 }
1791 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1792}
1793impl AstNode for TupleField {
1794 fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_FIELD }
1795 fn cast(syntax: SyntaxNode) -> Option<Self> {
1796 if Self::can_cast(syntax.kind()) {
1797 Some(Self { syntax })
1798 } else {
1799 None
1800 }
1801 }
1802 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1803}
1804impl AstNode for VariantList {
1805 fn can_cast(kind: SyntaxKind) -> bool { kind == VARIANT_LIST }
1806 fn cast(syntax: SyntaxNode) -> Option<Self> {
1807 if Self::can_cast(syntax.kind()) {
1808 Some(Self { syntax })
1809 } else {
1810 None
1811 }
1812 }
1813 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1814}
1815impl AstNode for Variant {
1816 fn can_cast(kind: SyntaxKind) -> bool { kind == VARIANT }
1817 fn cast(syntax: SyntaxNode) -> Option<Self> {
1818 if Self::can_cast(syntax.kind()) {
1819 Some(Self { syntax })
1820 } else {
1821 None
1822 }
1823 }
1824 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1825}
1826impl AstNode for AssocItemList {
1827 fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_ITEM_LIST }
1828 fn cast(syntax: SyntaxNode) -> Option<Self> {
1829 if Self::can_cast(syntax.kind()) {
1830 Some(Self { syntax })
1831 } else {
1832 None
1833 }
1834 }
1835 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1836}
1837impl AstNode for ExternItemList {
1838 fn can_cast(kind: SyntaxKind) -> bool { kind == EXTERN_ITEM_LIST }
1839 fn cast(syntax: SyntaxNode) -> Option<Self> {
1840 if Self::can_cast(syntax.kind()) {
1841 Some(Self { syntax })
1842 } else {
1843 None
1844 }
1845 }
1846 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1847}
1848impl AstNode for LifetimeParam {
1849 fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_PARAM }
1850 fn cast(syntax: SyntaxNode) -> Option<Self> {
1851 if Self::can_cast(syntax.kind()) {
1852 Some(Self { syntax })
1853 } else {
1854 None
1855 }
1856 }
1857 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1858}
1859impl AstNode for TypeParam {
1860 fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_PARAM }
1861 fn cast(syntax: SyntaxNode) -> Option<Self> {
1862 if Self::can_cast(syntax.kind()) {
1863 Some(Self { syntax })
1864 } else {
1865 None
1866 }
1867 }
1868 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1869}
1870impl AstNode for ConstParam {
1871 fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_PARAM }
1872 fn cast(syntax: SyntaxNode) -> Option<Self> {
1873 if Self::can_cast(syntax.kind()) {
1874 Some(Self { syntax })
1875 } else {
1876 None
1877 }
1878 }
1879 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1880}
1881impl AstNode for Literal {
1882 fn can_cast(kind: SyntaxKind) -> bool { kind == LITERAL }
1883 fn cast(syntax: SyntaxNode) -> Option<Self> {
1884 if Self::can_cast(syntax.kind()) {
1885 Some(Self { syntax })
1886 } else {
1887 None
1888 }
1889 }
1890 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1891}
1892impl AstNode for TokenTree {
1893 fn can_cast(kind: SyntaxKind) -> bool { kind == TOKEN_TREE }
1894 fn cast(syntax: SyntaxNode) -> Option<Self> {
1895 if Self::can_cast(syntax.kind()) {
1896 Some(Self { syntax })
1897 } else {
1898 None
1899 }
1900 }
1901 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1902}
1903impl AstNode for ParenType {
1904 fn can_cast(kind: SyntaxKind) -> bool { kind == PAREN_TYPE }
1905 fn cast(syntax: SyntaxNode) -> Option<Self> {
1906 if Self::can_cast(syntax.kind()) {
1907 Some(Self { syntax })
1908 } else {
1909 None
1910 }
1911 }
1912 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1913}
1914impl AstNode for TupleType {
1915 fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_TYPE }
1916 fn cast(syntax: SyntaxNode) -> Option<Self> {
1917 if Self::can_cast(syntax.kind()) {
1918 Some(Self { syntax })
1919 } else {
1920 None
1921 }
1922 }
1923 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1924}
1925impl AstNode for NeverType {
1926 fn can_cast(kind: SyntaxKind) -> bool { kind == NEVER_TYPE }
1927 fn cast(syntax: SyntaxNode) -> Option<Self> {
1928 if Self::can_cast(syntax.kind()) {
1929 Some(Self { syntax })
1930 } else {
1931 None
1932 }
1933 }
1934 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1935}
1936impl AstNode for PathType {
1937 fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_TYPE }
1938 fn cast(syntax: SyntaxNode) -> Option<Self> {
1939 if Self::can_cast(syntax.kind()) {
1940 Some(Self { syntax })
1941 } else {
1942 None
1943 }
1944 }
1945 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1946}
1947impl AstNode for PointerType {
1948 fn can_cast(kind: SyntaxKind) -> bool { kind == POINTER_TYPE }
1949 fn cast(syntax: SyntaxNode) -> Option<Self> {
1950 if Self::can_cast(syntax.kind()) {
1951 Some(Self { syntax })
1952 } else {
1953 None
1954 }
1955 }
1956 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1957}
1958impl AstNode for ArrayType {
1959 fn can_cast(kind: SyntaxKind) -> bool { kind == ARRAY_TYPE }
1960 fn cast(syntax: SyntaxNode) -> Option<Self> {
1961 if Self::can_cast(syntax.kind()) {
1962 Some(Self { syntax })
1963 } else {
1964 None
1965 }
1966 }
1967 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1968}
1969impl AstNode for SliceType {
1970 fn can_cast(kind: SyntaxKind) -> bool { kind == SLICE_TYPE }
1971 fn cast(syntax: SyntaxNode) -> Option<Self> {
1972 if Self::can_cast(syntax.kind()) {
1973 Some(Self { syntax })
1974 } else {
1975 None
1976 }
1977 }
1978 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1979}
1980impl AstNode for ReferenceType {
1981 fn can_cast(kind: SyntaxKind) -> bool { kind == REFERENCE_TYPE }
1982 fn cast(syntax: SyntaxNode) -> Option<Self> {
1983 if Self::can_cast(syntax.kind()) {
1984 Some(Self { syntax })
1985 } else {
1986 None
1987 }
1988 }
1989 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1990}
1991impl AstNode for PlaceholderType {
1992 fn can_cast(kind: SyntaxKind) -> bool { kind == PLACEHOLDER_TYPE }
1993 fn cast(syntax: SyntaxNode) -> Option<Self> {
1994 if Self::can_cast(syntax.kind()) {
1995 Some(Self { syntax })
1996 } else {
1997 None
1998 }
1999 }
2000 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2001}
2002impl AstNode for FnPointerType {
2003 fn can_cast(kind: SyntaxKind) -> bool { kind == FN_POINTER_TYPE }
2004 fn cast(syntax: SyntaxNode) -> Option<Self> {
2005 if Self::can_cast(syntax.kind()) {
2006 Some(Self { syntax })
2007 } else {
2008 None
2009 }
2010 }
2011 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2012}
2013impl AstNode for ForType {
2014 fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_TYPE }
2015 fn cast(syntax: SyntaxNode) -> Option<Self> {
2016 if Self::can_cast(syntax.kind()) {
2017 Some(Self { syntax })
2018 } else {
2019 None
2020 }
2021 }
2022 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2023}
2024impl AstNode for ImplTraitType {
2025 fn can_cast(kind: SyntaxKind) -> bool { kind == IMPL_TRAIT_TYPE }
2026 fn cast(syntax: SyntaxNode) -> Option<Self> {
2027 if Self::can_cast(syntax.kind()) {
2028 Some(Self { syntax })
2029 } else {
2030 None
2031 }
2032 }
2033 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2034}
2035impl AstNode for DynTraitType {
2036 fn can_cast(kind: SyntaxKind) -> bool { kind == DYN_TRAIT_TYPE }
2037 fn cast(syntax: SyntaxNode) -> Option<Self> {
2038 if Self::can_cast(syntax.kind()) {
2039 Some(Self { syntax })
2040 } else {
2041 None
2042 }
2043 }
2044 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2045}
2046impl AstNode for TupleExpr {
2047 fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_EXPR }
2048 fn cast(syntax: SyntaxNode) -> Option<Self> {
2049 if Self::can_cast(syntax.kind()) {
2050 Some(Self { syntax })
2051 } else {
2052 None
2053 }
2054 }
2055 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2056}
2057impl AstNode for ArrayExpr {
2058 fn can_cast(kind: SyntaxKind) -> bool { kind == ARRAY_EXPR }
2059 fn cast(syntax: SyntaxNode) -> Option<Self> {
2060 if Self::can_cast(syntax.kind()) {
2061 Some(Self { syntax })
2062 } else {
2063 None
2064 }
2065 }
2066 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2067}
2068impl AstNode for ParenExpr {
2069 fn can_cast(kind: SyntaxKind) -> bool { kind == PAREN_EXPR }
2070 fn cast(syntax: SyntaxNode) -> Option<Self> {
2071 if Self::can_cast(syntax.kind()) {
2072 Some(Self { syntax })
2073 } else {
2074 None
2075 }
2076 }
2077 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2078}
2079impl AstNode for PathExpr {
2080 fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_EXPR }
2081 fn cast(syntax: SyntaxNode) -> Option<Self> {
2082 if Self::can_cast(syntax.kind()) {
2083 Some(Self { syntax })
2084 } else {
2085 None
2086 }
2087 }
2088 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2089}
2090impl AstNode for LambdaExpr {
2091 fn can_cast(kind: SyntaxKind) -> bool { kind == LAMBDA_EXPR }
2092 fn cast(syntax: SyntaxNode) -> Option<Self> {
2093 if Self::can_cast(syntax.kind()) {
2094 Some(Self { syntax })
2095 } else {
2096 None
2097 }
2098 }
2099 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2100}
2101impl AstNode for IfExpr {
2102 fn can_cast(kind: SyntaxKind) -> bool { kind == IF_EXPR }
2103 fn cast(syntax: SyntaxNode) -> Option<Self> {
2104 if Self::can_cast(syntax.kind()) {
2105 Some(Self { syntax })
2106 } else {
2107 None
2108 }
2109 }
2110 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2111}
2112impl AstNode for Condition {
2113 fn can_cast(kind: SyntaxKind) -> bool { kind == CONDITION }
2114 fn cast(syntax: SyntaxNode) -> Option<Self> {
2115 if Self::can_cast(syntax.kind()) {
2116 Some(Self { syntax })
2117 } else {
2118 None
2119 }
2120 }
2121 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2122}
2123impl AstNode for EffectExpr {
2124 fn can_cast(kind: SyntaxKind) -> bool { kind == EFFECT_EXPR }
2125 fn cast(syntax: SyntaxNode) -> Option<Self> {
2126 if Self::can_cast(syntax.kind()) {
2127 Some(Self { syntax })
2128 } else {
2129 None
2130 }
2131 }
2132 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2133}
2134impl AstNode for Label {
2135 fn can_cast(kind: SyntaxKind) -> bool { kind == LABEL }
2136 fn cast(syntax: SyntaxNode) -> Option<Self> {
2137 if Self::can_cast(syntax.kind()) {
2138 Some(Self { syntax })
2139 } else {
2140 None
2141 }
2142 }
2143 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2144}
2145impl AstNode for LoopExpr {
2146 fn can_cast(kind: SyntaxKind) -> bool { kind == LOOP_EXPR }
2147 fn cast(syntax: SyntaxNode) -> Option<Self> {
2148 if Self::can_cast(syntax.kind()) {
2149 Some(Self { syntax })
2150 } else {
2151 None
2152 }
2153 }
2154 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2155}
2156impl AstNode for ForExpr {
2157 fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_EXPR }
2158 fn cast(syntax: SyntaxNode) -> Option<Self> {
2159 if Self::can_cast(syntax.kind()) {
2160 Some(Self { syntax })
2161 } else {
2162 None
2163 }
2164 }
2165 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2166}
2167impl AstNode for WhileExpr {
2168 fn can_cast(kind: SyntaxKind) -> bool { kind == WHILE_EXPR }
2169 fn cast(syntax: SyntaxNode) -> Option<Self> {
2170 if Self::can_cast(syntax.kind()) {
2171 Some(Self { syntax })
2172 } else {
2173 None
2174 }
2175 }
2176 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2177}
2178impl AstNode for ContinueExpr {
2179 fn can_cast(kind: SyntaxKind) -> bool { kind == CONTINUE_EXPR }
2180 fn cast(syntax: SyntaxNode) -> Option<Self> {
2181 if Self::can_cast(syntax.kind()) {
2182 Some(Self { syntax })
2183 } else {
2184 None
2185 }
2186 }
2187 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2188}
2189impl AstNode for BreakExpr {
2190 fn can_cast(kind: SyntaxKind) -> bool { kind == BREAK_EXPR }
2191 fn cast(syntax: SyntaxNode) -> Option<Self> {
2192 if Self::can_cast(syntax.kind()) {
2193 Some(Self { syntax })
2194 } else {
2195 None
2196 }
2197 }
2198 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2199}
2200impl AstNode for ReturnExpr {
2201 fn can_cast(kind: SyntaxKind) -> bool { kind == RETURN_EXPR }
2202 fn cast(syntax: SyntaxNode) -> Option<Self> {
2203 if Self::can_cast(syntax.kind()) {
2204 Some(Self { syntax })
2205 } else {
2206 None
2207 }
2208 }
2209 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2210}
2211impl AstNode for CallExpr {
2212 fn can_cast(kind: SyntaxKind) -> bool { kind == CALL_EXPR }
2213 fn cast(syntax: SyntaxNode) -> Option<Self> {
2214 if Self::can_cast(syntax.kind()) {
2215 Some(Self { syntax })
2216 } else {
2217 None
2218 }
2219 }
2220 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2221}
2222impl AstNode for ArgList {
2223 fn can_cast(kind: SyntaxKind) -> bool { kind == ARG_LIST }
2224 fn cast(syntax: SyntaxNode) -> Option<Self> {
2225 if Self::can_cast(syntax.kind()) {
2226 Some(Self { syntax })
2227 } else {
2228 None
2229 }
2230 }
2231 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2232}
2233impl AstNode for MethodCallExpr {
2234 fn can_cast(kind: SyntaxKind) -> bool { kind == METHOD_CALL_EXPR }
2235 fn cast(syntax: SyntaxNode) -> Option<Self> {
2236 if Self::can_cast(syntax.kind()) {
2237 Some(Self { syntax })
2238 } else {
2239 None
2240 }
2241 }
2242 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2243}
2244impl AstNode for TypeArgList {
2245 fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ARG_LIST }
2246 fn cast(syntax: SyntaxNode) -> Option<Self> {
2247 if Self::can_cast(syntax.kind()) {
2248 Some(Self { syntax })
2249 } else {
2250 None
2251 }
2252 }
2253 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2254}
2255impl AstNode for FieldExpr {
2256 fn can_cast(kind: SyntaxKind) -> bool { kind == FIELD_EXPR }
2257 fn cast(syntax: SyntaxNode) -> Option<Self> {
2258 if Self::can_cast(syntax.kind()) {
2259 Some(Self { syntax })
2260 } else {
2261 None
2262 }
2263 }
2264 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2265}
2266impl AstNode for IndexExpr {
2267 fn can_cast(kind: SyntaxKind) -> bool { kind == INDEX_EXPR }
2268 fn cast(syntax: SyntaxNode) -> Option<Self> {
2269 if Self::can_cast(syntax.kind()) {
2270 Some(Self { syntax })
2271 } else {
2272 None
2273 }
2274 }
2275 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2276}
2277impl AstNode for AwaitExpr {
2278 fn can_cast(kind: SyntaxKind) -> bool { kind == AWAIT_EXPR }
2279 fn cast(syntax: SyntaxNode) -> Option<Self> {
2280 if Self::can_cast(syntax.kind()) {
2281 Some(Self { syntax })
2282 } else {
2283 None
2284 }
2285 }
2286 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2287}
2288impl AstNode for TryExpr {
2289 fn can_cast(kind: SyntaxKind) -> bool { kind == TRY_EXPR }
2290 fn cast(syntax: SyntaxNode) -> Option<Self> {
2291 if Self::can_cast(syntax.kind()) {
2292 Some(Self { syntax })
2293 } else {
2294 None
2295 }
2296 }
2297 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2298}
2299impl AstNode for CastExpr {
2300 fn can_cast(kind: SyntaxKind) -> bool { kind == CAST_EXPR }
2301 fn cast(syntax: SyntaxNode) -> Option<Self> {
2302 if Self::can_cast(syntax.kind()) {
2303 Some(Self { syntax })
2304 } else {
2305 None
2306 }
2307 }
2308 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2309}
2310impl AstNode for RefExpr {
2311 fn can_cast(kind: SyntaxKind) -> bool { kind == REF_EXPR }
2312 fn cast(syntax: SyntaxNode) -> Option<Self> {
2313 if Self::can_cast(syntax.kind()) {
2314 Some(Self { syntax })
2315 } else {
2316 None
2317 }
2318 }
2319 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2320}
2321impl AstNode for PrefixExpr {
2322 fn can_cast(kind: SyntaxKind) -> bool { kind == PREFIX_EXPR }
2323 fn cast(syntax: SyntaxNode) -> Option<Self> {
2324 if Self::can_cast(syntax.kind()) {
2325 Some(Self { syntax })
2326 } else {
2327 None
2328 }
2329 }
2330 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2331}
2332impl AstNode for BoxExpr {
2333 fn can_cast(kind: SyntaxKind) -> bool { kind == BOX_EXPR }
2334 fn cast(syntax: SyntaxNode) -> Option<Self> {
2335 if Self::can_cast(syntax.kind()) {
2336 Some(Self { syntax })
2337 } else {
2338 None
2339 }
2340 }
2341 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2342}
2343impl AstNode for RangeExpr {
2344 fn can_cast(kind: SyntaxKind) -> bool { kind == RANGE_EXPR }
2345 fn cast(syntax: SyntaxNode) -> Option<Self> {
2346 if Self::can_cast(syntax.kind()) {
2347 Some(Self { syntax })
2348 } else {
2349 None
2350 }
2351 }
2352 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2353}
2354impl AstNode for BinExpr {
2355 fn can_cast(kind: SyntaxKind) -> bool { kind == BIN_EXPR }
2356 fn cast(syntax: SyntaxNode) -> Option<Self> {
2357 if Self::can_cast(syntax.kind()) {
2358 Some(Self { syntax })
2359 } else {
2360 None
2361 }
2362 }
2363 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2364}
2365impl AstNode for MatchExpr {
2366 fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_EXPR }
2367 fn cast(syntax: SyntaxNode) -> Option<Self> {
2368 if Self::can_cast(syntax.kind()) {
2369 Some(Self { syntax })
2370 } else {
2371 None
2372 }
2373 }
2374 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2375}
2376impl AstNode for MatchArmList {
2377 fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_ARM_LIST }
2378 fn cast(syntax: SyntaxNode) -> Option<Self> {
2379 if Self::can_cast(syntax.kind()) {
2380 Some(Self { syntax })
2381 } else {
2382 None
2383 }
2384 }
2385 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2386}
2387impl AstNode for MatchArm {
2388 fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_ARM }
2389 fn cast(syntax: SyntaxNode) -> Option<Self> {
2390 if Self::can_cast(syntax.kind()) {
2391 Some(Self { syntax })
2392 } else {
2393 None
2394 }
2395 }
2396 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2397}
2398impl AstNode for MatchGuard {
2399 fn can_cast(kind: SyntaxKind) -> bool { kind == MATCH_GUARD }
2400 fn cast(syntax: SyntaxNode) -> Option<Self> {
2401 if Self::can_cast(syntax.kind()) {
2402 Some(Self { syntax })
2403 } else {
2404 None
2405 }
2406 }
2407 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2408}
2409impl AstNode for RecordExpr {
2410 fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_EXPR }
2411 fn cast(syntax: SyntaxNode) -> Option<Self> {
2412 if Self::can_cast(syntax.kind()) {
2413 Some(Self { syntax })
2414 } else {
2415 None
2416 }
2417 }
2418 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2419}
2420impl AstNode for RecordExprFieldList {
2421 fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_EXPR_FIELD_LIST }
2422 fn cast(syntax: SyntaxNode) -> Option<Self> {
2423 if Self::can_cast(syntax.kind()) {
2424 Some(Self { syntax })
2425 } else {
2426 None
2427 }
2428 }
2429 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2430}
2431impl AstNode for RecordExprField {
2432 fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_EXPR_FIELD }
2433 fn cast(syntax: SyntaxNode) -> Option<Self> {
2434 if Self::can_cast(syntax.kind()) {
2435 Some(Self { syntax })
2436 } else {
2437 None
2438 }
2439 }
2440 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2441}
2442impl AstNode for OrPat {
2443 fn can_cast(kind: SyntaxKind) -> bool { kind == OR_PAT }
2444 fn cast(syntax: SyntaxNode) -> Option<Self> {
2445 if Self::can_cast(syntax.kind()) {
2446 Some(Self { syntax })
2447 } else {
2448 None
2449 }
2450 }
2451 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2452}
2453impl AstNode for ParenPat {
2454 fn can_cast(kind: SyntaxKind) -> bool { kind == PAREN_PAT }
2455 fn cast(syntax: SyntaxNode) -> Option<Self> {
2456 if Self::can_cast(syntax.kind()) {
2457 Some(Self { syntax })
2458 } else {
2459 None
2460 }
2461 }
2462 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2463}
2464impl AstNode for RefPat {
2465 fn can_cast(kind: SyntaxKind) -> bool { kind == REF_PAT }
2466 fn cast(syntax: SyntaxNode) -> Option<Self> {
2467 if Self::can_cast(syntax.kind()) {
2468 Some(Self { syntax })
2469 } else {
2470 None
2471 }
2472 }
2473 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2474}
2475impl AstNode for BoxPat {
2476 fn can_cast(kind: SyntaxKind) -> bool { kind == BOX_PAT }
2477 fn cast(syntax: SyntaxNode) -> Option<Self> {
2478 if Self::can_cast(syntax.kind()) {
2479 Some(Self { syntax })
2480 } else {
2481 None
2482 }
2483 }
2484 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2485}
2486impl AstNode for BindPat {
2487 fn can_cast(kind: SyntaxKind) -> bool { kind == BIND_PAT }
2488 fn cast(syntax: SyntaxNode) -> Option<Self> {
2489 if Self::can_cast(syntax.kind()) {
2490 Some(Self { syntax })
2491 } else {
2492 None
2493 }
2494 }
2495 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2496}
2497impl AstNode for PlaceholderPat {
2498 fn can_cast(kind: SyntaxKind) -> bool { kind == PLACEHOLDER_PAT }
2499 fn cast(syntax: SyntaxNode) -> Option<Self> {
2500 if Self::can_cast(syntax.kind()) {
2501 Some(Self { syntax })
2502 } else {
2503 None
2504 }
2505 }
2506 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2507}
2508impl AstNode for DotDotPat {
2509 fn can_cast(kind: SyntaxKind) -> bool { kind == DOT_DOT_PAT }
2510 fn cast(syntax: SyntaxNode) -> Option<Self> {
2511 if Self::can_cast(syntax.kind()) {
2512 Some(Self { syntax })
2513 } else {
2514 None
2515 }
2516 }
2517 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2518}
2519impl AstNode for PathPat {
2520 fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_PAT }
2521 fn cast(syntax: SyntaxNode) -> Option<Self> {
2522 if Self::can_cast(syntax.kind()) {
2523 Some(Self { syntax })
2524 } else {
2525 None
2526 }
2527 }
2528 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2529}
2530impl AstNode for SlicePat {
2531 fn can_cast(kind: SyntaxKind) -> bool { kind == SLICE_PAT }
2532 fn cast(syntax: SyntaxNode) -> Option<Self> {
2533 if Self::can_cast(syntax.kind()) {
2534 Some(Self { syntax })
2535 } else {
2536 None
2537 }
2538 }
2539 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2540}
2541impl AstNode for RangePat {
2542 fn can_cast(kind: SyntaxKind) -> bool { kind == RANGE_PAT }
2543 fn cast(syntax: SyntaxNode) -> Option<Self> {
2544 if Self::can_cast(syntax.kind()) {
2545 Some(Self { syntax })
2546 } else {
2547 None
2548 }
2549 }
2550 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2551}
2552impl AstNode for LiteralPat {
2553 fn can_cast(kind: SyntaxKind) -> bool { kind == LITERAL_PAT }
2554 fn cast(syntax: SyntaxNode) -> Option<Self> {
2555 if Self::can_cast(syntax.kind()) {
2556 Some(Self { syntax })
2557 } else {
2558 None
2559 }
2560 }
2561 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2562}
2563impl AstNode for MacroPat {
2564 fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_PAT }
2565 fn cast(syntax: SyntaxNode) -> Option<Self> {
2566 if Self::can_cast(syntax.kind()) {
2567 Some(Self { syntax })
2568 } else {
2569 None
2570 }
2571 }
2572 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2573}
2574impl AstNode for RecordPat {
2575 fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_PAT }
2576 fn cast(syntax: SyntaxNode) -> Option<Self> {
2577 if Self::can_cast(syntax.kind()) {
2578 Some(Self { syntax })
2579 } else {
2580 None
2581 }
2582 }
2583 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2584}
2585impl AstNode for RecordFieldPatList {
2586 fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_PAT_LIST }
2587 fn cast(syntax: SyntaxNode) -> Option<Self> {
2588 if Self::can_cast(syntax.kind()) {
2589 Some(Self { syntax })
2590 } else {
2591 None
2592 }
2593 }
2594 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2595}
2596impl AstNode for RecordFieldPat {
2597 fn can_cast(kind: SyntaxKind) -> bool { kind == RECORD_FIELD_PAT }
2598 fn cast(syntax: SyntaxNode) -> Option<Self> {
2599 if Self::can_cast(syntax.kind()) {
2600 Some(Self { syntax })
2601 } else {
2602 None
2603 }
2604 }
2605 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2606}
2607impl AstNode for TupleStructPat {
2608 fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_STRUCT_PAT }
2609 fn cast(syntax: SyntaxNode) -> Option<Self> {
2610 if Self::can_cast(syntax.kind()) {
2611 Some(Self { syntax })
2612 } else {
2613 None
2614 }
2615 }
2616 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2617}
2618impl AstNode for TuplePat {
2619 fn can_cast(kind: SyntaxKind) -> bool { kind == TUPLE_PAT }
2620 fn cast(syntax: SyntaxNode) -> Option<Self> {
2621 if Self::can_cast(syntax.kind()) {
2622 Some(Self { syntax })
2623 } else {
2624 None
2625 }
2626 }
2627 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2628}
2629impl AstNode for MacroDef {
2630 fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_DEF }
2631 fn cast(syntax: SyntaxNode) -> Option<Self> {
2632 if Self::can_cast(syntax.kind()) {
2633 Some(Self { syntax })
2634 } else {
2635 None
2636 }
2637 }
2638 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2639}
2640impl AstNode for MacroItems {
2641 fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_ITEMS }
2642 fn cast(syntax: SyntaxNode) -> Option<Self> {
2643 if Self::can_cast(syntax.kind()) {
2644 Some(Self { syntax })
2645 } else {
2646 None
2647 }
2648 }
2649 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2650}
2651impl AstNode for MacroStmts {
2652 fn can_cast(kind: SyntaxKind) -> bool { kind == MACRO_STMTS }
2653 fn cast(syntax: SyntaxNode) -> Option<Self> {
2654 if Self::can_cast(syntax.kind()) {
2655 Some(Self { syntax })
2656 } else {
2657 None
2658 }
2659 }
2660 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2661}
2662impl AstNode for TypeBound {
2663 fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_BOUND }
2664 fn cast(syntax: SyntaxNode) -> Option<Self> {
2665 if Self::can_cast(syntax.kind()) {
2666 Some(Self { syntax })
2667 } else {
2668 None
2669 }
2670 }
2671 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2672}
2673impl AstNode for WherePred {
2674 fn can_cast(kind: SyntaxKind) -> bool { kind == WHERE_PRED }
2675 fn cast(syntax: SyntaxNode) -> Option<Self> {
2676 if Self::can_cast(syntax.kind()) {
2677 Some(Self { syntax })
2678 } else {
2679 None
2680 }
2681 }
2682 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2683}
2684impl AstNode for ExprStmt {
2685 fn can_cast(kind: SyntaxKind) -> bool { kind == EXPR_STMT }
2686 fn cast(syntax: SyntaxNode) -> Option<Self> {
2687 if Self::can_cast(syntax.kind()) {
2688 Some(Self { syntax })
2689 } else {
2690 None
2691 }
2692 }
2693 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2694}
2695impl AstNode for LetStmt {
2696 fn can_cast(kind: SyntaxKind) -> bool { kind == LET_STMT }
2697 fn cast(syntax: SyntaxNode) -> Option<Self> {
2698 if Self::can_cast(syntax.kind()) {
2699 Some(Self { syntax })
2700 } else {
2701 None
2702 }
2703 }
2704 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2705}
2706impl AstNode for PathSegment {
2707 fn can_cast(kind: SyntaxKind) -> bool { kind == PATH_SEGMENT }
2708 fn cast(syntax: SyntaxNode) -> Option<Self> {
2709 if Self::can_cast(syntax.kind()) {
2710 Some(Self { syntax })
2711 } else {
2712 None
2713 }
2714 }
2715 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2716}
2717impl AstNode for TypeArg {
2718 fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ARG }
2719 fn cast(syntax: SyntaxNode) -> Option<Self> {
2720 if Self::can_cast(syntax.kind()) {
2721 Some(Self { syntax })
2722 } else {
2723 None
2724 }
2725 }
2726 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2727}
2728impl AstNode for LifetimeArg {
2729 fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME_ARG }
2730 fn cast(syntax: SyntaxNode) -> Option<Self> {
2731 if Self::can_cast(syntax.kind()) {
2732 Some(Self { syntax })
2733 } else {
2734 None
2735 }
2736 }
2737 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2738}
2739impl AstNode for AssocTypeArg {
2740 fn can_cast(kind: SyntaxKind) -> bool { kind == ASSOC_TYPE_ARG }
2741 fn cast(syntax: SyntaxNode) -> Option<Self> {
2742 if Self::can_cast(syntax.kind()) {
2743 Some(Self { syntax })
2744 } else {
2745 None
2746 }
2747 }
2748 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2749}
2750impl AstNode for ConstArg {
2751 fn can_cast(kind: SyntaxKind) -> bool { kind == CONST_ARG }
2752 fn cast(syntax: SyntaxNode) -> Option<Self> {
2753 if Self::can_cast(syntax.kind()) {
2754 Some(Self { syntax })
2755 } else {
2756 None
2757 }
2758 }
2759 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2760}
2761impl From<Const> for Item {
2762 fn from(node: Const) -> Item { Item::Const(node) }
2763}
2764impl From<Enum> for Item {
2765 fn from(node: Enum) -> Item { Item::Enum(node) }
2766}
2767impl From<ExternBlock> for Item {
2768 fn from(node: ExternBlock) -> Item { Item::ExternBlock(node) }
2769}
2770impl From<ExternCrate> for Item {
2771 fn from(node: ExternCrate) -> Item { Item::ExternCrate(node) }
2772}
2773impl From<Fn> for Item {
2774 fn from(node: Fn) -> Item { Item::Fn(node) }
2775}
2776impl From<Impl> for Item {
2777 fn from(node: Impl) -> Item { Item::Impl(node) }
2778}
2779impl From<MacroCall> for Item {
2780 fn from(node: MacroCall) -> Item { Item::MacroCall(node) }
2781}
2782impl From<Module> for Item {
2783 fn from(node: Module) -> Item { Item::Module(node) }
2784}
2785impl From<Static> for Item {
2786 fn from(node: Static) -> Item { Item::Static(node) }
2787}
2788impl From<Struct> for Item {
2789 fn from(node: Struct) -> Item { Item::Struct(node) }
2790}
2791impl From<Trait> for Item {
2792 fn from(node: Trait) -> Item { Item::Trait(node) }
2793}
2794impl From<TypeAlias> for Item {
2795 fn from(node: TypeAlias) -> Item { Item::TypeAlias(node) }
2796}
2797impl From<Union> for Item {
2798 fn from(node: Union) -> Item { Item::Union(node) }
2799}
2800impl From<Use> for Item {
2801 fn from(node: Use) -> Item { Item::Use(node) }
2802}
2803impl AstNode for Item {
2804 fn can_cast(kind: SyntaxKind) -> bool {
2805 match kind {
2806 CONST | ENUM | EXTERN_BLOCK | EXTERN_CRATE | FN | IMPL | MACRO_CALL | MODULE
2807 | STATIC | STRUCT | TRAIT | TYPE_ALIAS | UNION | USE => true,
2808 _ => false,
2809 }
2810 }
2811 fn cast(syntax: SyntaxNode) -> Option<Self> {
2812 let res = match syntax.kind() {
2813 CONST => Item::Const(Const { syntax }),
2814 ENUM => Item::Enum(Enum { syntax }),
2815 EXTERN_BLOCK => Item::ExternBlock(ExternBlock { syntax }),
2816 EXTERN_CRATE => Item::ExternCrate(ExternCrate { syntax }),
2817 FN => Item::Fn(Fn { syntax }),
2818 IMPL => Item::Impl(Impl { syntax }),
2819 MACRO_CALL => Item::MacroCall(MacroCall { syntax }),
2820 MODULE => Item::Module(Module { syntax }),
2821 STATIC => Item::Static(Static { syntax }),
2822 STRUCT => Item::Struct(Struct { syntax }),
2823 TRAIT => Item::Trait(Trait { syntax }),
2824 TYPE_ALIAS => Item::TypeAlias(TypeAlias { syntax }),
2825 UNION => Item::Union(Union { syntax }),
2826 USE => Item::Use(Use { syntax }),
2827 _ => return None,
2828 };
2829 Some(res)
2830 }
2831 fn syntax(&self) -> &SyntaxNode {
2832 match self {
2833 Item::Const(it) => &it.syntax,
2834 Item::Enum(it) => &it.syntax,
2835 Item::ExternBlock(it) => &it.syntax,
2836 Item::ExternCrate(it) => &it.syntax,
2837 Item::Fn(it) => &it.syntax,
2838 Item::Impl(it) => &it.syntax,
2839 Item::MacroCall(it) => &it.syntax,
2840 Item::Module(it) => &it.syntax,
2841 Item::Static(it) => &it.syntax,
2842 Item::Struct(it) => &it.syntax,
2843 Item::Trait(it) => &it.syntax,
2844 Item::TypeAlias(it) => &it.syntax,
2845 Item::Union(it) => &it.syntax,
2846 Item::Use(it) => &it.syntax,
2847 }
2848 }
2849}
2850impl From<ParenType> for TypeRef {
2851 fn from(node: ParenType) -> TypeRef { TypeRef::ParenType(node) }
2852}
2853impl From<TupleType> for TypeRef {
2854 fn from(node: TupleType) -> TypeRef { TypeRef::TupleType(node) }
2855}
2856impl From<NeverType> for TypeRef {
2857 fn from(node: NeverType) -> TypeRef { TypeRef::NeverType(node) }
2858}
2859impl From<PathType> for TypeRef {
2860 fn from(node: PathType) -> TypeRef { TypeRef::PathType(node) }
2861}
2862impl From<PointerType> for TypeRef {
2863 fn from(node: PointerType) -> TypeRef { TypeRef::PointerType(node) }
2864}
2865impl From<ArrayType> for TypeRef {
2866 fn from(node: ArrayType) -> TypeRef { TypeRef::ArrayType(node) }
2867}
2868impl From<SliceType> for TypeRef {
2869 fn from(node: SliceType) -> TypeRef { TypeRef::SliceType(node) }
2870}
2871impl From<ReferenceType> for TypeRef {
2872 fn from(node: ReferenceType) -> TypeRef { TypeRef::ReferenceType(node) }
2873}
2874impl From<PlaceholderType> for TypeRef {
2875 fn from(node: PlaceholderType) -> TypeRef { TypeRef::PlaceholderType(node) }
2876}
2877impl From<FnPointerType> for TypeRef {
2878 fn from(node: FnPointerType) -> TypeRef { TypeRef::FnPointerType(node) }
2879}
2880impl From<ForType> for TypeRef {
2881 fn from(node: ForType) -> TypeRef { TypeRef::ForType(node) }
2882}
2883impl From<ImplTraitType> for TypeRef {
2884 fn from(node: ImplTraitType) -> TypeRef { TypeRef::ImplTraitType(node) }
2885}
2886impl From<DynTraitType> for TypeRef {
2887 fn from(node: DynTraitType) -> TypeRef { TypeRef::DynTraitType(node) }
2888}
2889impl AstNode for TypeRef {
2890 fn can_cast(kind: SyntaxKind) -> bool {
2891 match kind {
2892 PAREN_TYPE | TUPLE_TYPE | NEVER_TYPE | PATH_TYPE | POINTER_TYPE | ARRAY_TYPE
2893 | SLICE_TYPE | REFERENCE_TYPE | PLACEHOLDER_TYPE | FN_POINTER_TYPE | FOR_TYPE
2894 | IMPL_TRAIT_TYPE | DYN_TRAIT_TYPE => true,
2895 _ => false,
2896 }
2897 }
2898 fn cast(syntax: SyntaxNode) -> Option<Self> {
2899 let res = match syntax.kind() {
2900 PAREN_TYPE => TypeRef::ParenType(ParenType { syntax }),
2901 TUPLE_TYPE => TypeRef::TupleType(TupleType { syntax }),
2902 NEVER_TYPE => TypeRef::NeverType(NeverType { syntax }),
2903 PATH_TYPE => TypeRef::PathType(PathType { syntax }),
2904 POINTER_TYPE => TypeRef::PointerType(PointerType { syntax }),
2905 ARRAY_TYPE => TypeRef::ArrayType(ArrayType { syntax }),
2906 SLICE_TYPE => TypeRef::SliceType(SliceType { syntax }),
2907 REFERENCE_TYPE => TypeRef::ReferenceType(ReferenceType { syntax }),
2908 PLACEHOLDER_TYPE => TypeRef::PlaceholderType(PlaceholderType { syntax }),
2909 FN_POINTER_TYPE => TypeRef::FnPointerType(FnPointerType { syntax }),
2910 FOR_TYPE => TypeRef::ForType(ForType { syntax }),
2911 IMPL_TRAIT_TYPE => TypeRef::ImplTraitType(ImplTraitType { syntax }),
2912 DYN_TRAIT_TYPE => TypeRef::DynTraitType(DynTraitType { syntax }),
2913 _ => return None,
2914 };
2915 Some(res)
2916 }
2917 fn syntax(&self) -> &SyntaxNode {
2918 match self {
2919 TypeRef::ParenType(it) => &it.syntax,
2920 TypeRef::TupleType(it) => &it.syntax,
2921 TypeRef::NeverType(it) => &it.syntax,
2922 TypeRef::PathType(it) => &it.syntax,
2923 TypeRef::PointerType(it) => &it.syntax,
2924 TypeRef::ArrayType(it) => &it.syntax,
2925 TypeRef::SliceType(it) => &it.syntax,
2926 TypeRef::ReferenceType(it) => &it.syntax,
2927 TypeRef::PlaceholderType(it) => &it.syntax,
2928 TypeRef::FnPointerType(it) => &it.syntax,
2929 TypeRef::ForType(it) => &it.syntax,
2930 TypeRef::ImplTraitType(it) => &it.syntax,
2931 TypeRef::DynTraitType(it) => &it.syntax,
2932 }
2933 }
2934}
2935impl From<OrPat> for Pat {
2936 fn from(node: OrPat) -> Pat { Pat::OrPat(node) }
2937}
2938impl From<ParenPat> for Pat {
2939 fn from(node: ParenPat) -> Pat { Pat::ParenPat(node) }
2940}
2941impl From<RefPat> for Pat {
2942 fn from(node: RefPat) -> Pat { Pat::RefPat(node) }
2943}
2944impl From<BoxPat> for Pat {
2945 fn from(node: BoxPat) -> Pat { Pat::BoxPat(node) }
2946}
2947impl From<BindPat> for Pat {
2948 fn from(node: BindPat) -> Pat { Pat::BindPat(node) }
2949}
2950impl From<PlaceholderPat> for Pat {
2951 fn from(node: PlaceholderPat) -> Pat { Pat::PlaceholderPat(node) }
2952}
2953impl From<DotDotPat> for Pat {
2954 fn from(node: DotDotPat) -> Pat { Pat::DotDotPat(node) }
2955}
2956impl From<PathPat> for Pat {
2957 fn from(node: PathPat) -> Pat { Pat::PathPat(node) }
2958}
2959impl From<RecordPat> for Pat {
2960 fn from(node: RecordPat) -> Pat { Pat::RecordPat(node) }
2961}
2962impl From<TupleStructPat> for Pat {
2963 fn from(node: TupleStructPat) -> Pat { Pat::TupleStructPat(node) }
2964}
2965impl From<TuplePat> for Pat {
2966 fn from(node: TuplePat) -> Pat { Pat::TuplePat(node) }
2967}
2968impl From<SlicePat> for Pat {
2969 fn from(node: SlicePat) -> Pat { Pat::SlicePat(node) }
2970}
2971impl From<RangePat> for Pat {
2972 fn from(node: RangePat) -> Pat { Pat::RangePat(node) }
2973}
2974impl From<LiteralPat> for Pat {
2975 fn from(node: LiteralPat) -> Pat { Pat::LiteralPat(node) }
2976}
2977impl From<MacroPat> for Pat {
2978 fn from(node: MacroPat) -> Pat { Pat::MacroPat(node) }
2979}
2980impl AstNode for Pat {
2981 fn can_cast(kind: SyntaxKind) -> bool {
2982 match kind {
2983 OR_PAT | PAREN_PAT | REF_PAT | BOX_PAT | BIND_PAT | PLACEHOLDER_PAT | DOT_DOT_PAT
2984 | PATH_PAT | RECORD_PAT | TUPLE_STRUCT_PAT | TUPLE_PAT | SLICE_PAT | RANGE_PAT
2985 | LITERAL_PAT | MACRO_PAT => true,
2986 _ => false,
2987 }
2988 }
2989 fn cast(syntax: SyntaxNode) -> Option<Self> {
2990 let res = match syntax.kind() {
2991 OR_PAT => Pat::OrPat(OrPat { syntax }),
2992 PAREN_PAT => Pat::ParenPat(ParenPat { syntax }),
2993 REF_PAT => Pat::RefPat(RefPat { syntax }),
2994 BOX_PAT => Pat::BoxPat(BoxPat { syntax }),
2995 BIND_PAT => Pat::BindPat(BindPat { syntax }),
2996 PLACEHOLDER_PAT => Pat::PlaceholderPat(PlaceholderPat { syntax }),
2997 DOT_DOT_PAT => Pat::DotDotPat(DotDotPat { syntax }),
2998 PATH_PAT => Pat::PathPat(PathPat { syntax }),
2999 RECORD_PAT => Pat::RecordPat(RecordPat { syntax }),
3000 TUPLE_STRUCT_PAT => Pat::TupleStructPat(TupleStructPat { syntax }),
3001 TUPLE_PAT => Pat::TuplePat(TuplePat { syntax }),
3002 SLICE_PAT => Pat::SlicePat(SlicePat { syntax }),
3003 RANGE_PAT => Pat::RangePat(RangePat { syntax }),
3004 LITERAL_PAT => Pat::LiteralPat(LiteralPat { syntax }),
3005 MACRO_PAT => Pat::MacroPat(MacroPat { syntax }),
3006 _ => return None,
3007 };
3008 Some(res)
3009 }
3010 fn syntax(&self) -> &SyntaxNode {
3011 match self {
3012 Pat::OrPat(it) => &it.syntax,
3013 Pat::ParenPat(it) => &it.syntax,
3014 Pat::RefPat(it) => &it.syntax,
3015 Pat::BoxPat(it) => &it.syntax,
3016 Pat::BindPat(it) => &it.syntax,
3017 Pat::PlaceholderPat(it) => &it.syntax,
3018 Pat::DotDotPat(it) => &it.syntax,
3019 Pat::PathPat(it) => &it.syntax,
3020 Pat::RecordPat(it) => &it.syntax,
3021 Pat::TupleStructPat(it) => &it.syntax,
3022 Pat::TuplePat(it) => &it.syntax,
3023 Pat::SlicePat(it) => &it.syntax,
3024 Pat::RangePat(it) => &it.syntax,
3025 Pat::LiteralPat(it) => &it.syntax,
3026 Pat::MacroPat(it) => &it.syntax,
3027 }
3028 }
3029}
3030impl From<RecordFieldList> for FieldList {
3031 fn from(node: RecordFieldList) -> FieldList { FieldList::RecordFieldList(node) }
3032}
3033impl From<TupleFieldList> for FieldList {
3034 fn from(node: TupleFieldList) -> FieldList { FieldList::TupleFieldList(node) }
3035}
3036impl AstNode for FieldList {
3037 fn can_cast(kind: SyntaxKind) -> bool {
3038 match kind {
3039 RECORD_FIELD_LIST | TUPLE_FIELD_LIST => true,
3040 _ => false,
3041 }
3042 }
3043 fn cast(syntax: SyntaxNode) -> Option<Self> {
3044 let res = match syntax.kind() {
3045 RECORD_FIELD_LIST => FieldList::RecordFieldList(RecordFieldList { syntax }),
3046 TUPLE_FIELD_LIST => FieldList::TupleFieldList(TupleFieldList { syntax }),
3047 _ => return None,
3048 };
3049 Some(res)
3050 }
3051 fn syntax(&self) -> &SyntaxNode {
3052 match self {
3053 FieldList::RecordFieldList(it) => &it.syntax,
3054 FieldList::TupleFieldList(it) => &it.syntax,
3055 }
3056 }
3057}
3058impl From<TupleExpr> for Expr {
3059 fn from(node: TupleExpr) -> Expr { Expr::TupleExpr(node) }
3060}
3061impl From<ArrayExpr> for Expr {
3062 fn from(node: ArrayExpr) -> Expr { Expr::ArrayExpr(node) }
3063}
3064impl From<ParenExpr> for Expr {
3065 fn from(node: ParenExpr) -> Expr { Expr::ParenExpr(node) }
3066}
3067impl From<PathExpr> for Expr {
3068 fn from(node: PathExpr) -> Expr { Expr::PathExpr(node) }
3069}
3070impl From<LambdaExpr> for Expr {
3071 fn from(node: LambdaExpr) -> Expr { Expr::LambdaExpr(node) }
3072}
3073impl From<IfExpr> for Expr {
3074 fn from(node: IfExpr) -> Expr { Expr::IfExpr(node) }
3075}
3076impl From<LoopExpr> for Expr {
3077 fn from(node: LoopExpr) -> Expr { Expr::LoopExpr(node) }
3078}
3079impl From<ForExpr> for Expr {
3080 fn from(node: ForExpr) -> Expr { Expr::ForExpr(node) }
3081}
3082impl From<WhileExpr> for Expr {
3083 fn from(node: WhileExpr) -> Expr { Expr::WhileExpr(node) }
3084}
3085impl From<ContinueExpr> for Expr {
3086 fn from(node: ContinueExpr) -> Expr { Expr::ContinueExpr(node) }
3087}
3088impl From<BreakExpr> for Expr {
3089 fn from(node: BreakExpr) -> Expr { Expr::BreakExpr(node) }
3090}
3091impl From<Label> for Expr {
3092 fn from(node: Label) -> Expr { Expr::Label(node) }
3093}
3094impl From<BlockExpr> for Expr {
3095 fn from(node: BlockExpr) -> Expr { Expr::BlockExpr(node) }
3096}
3097impl From<ReturnExpr> for Expr {
3098 fn from(node: ReturnExpr) -> Expr { Expr::ReturnExpr(node) }
3099}
3100impl From<MatchExpr> for Expr {
3101 fn from(node: MatchExpr) -> Expr { Expr::MatchExpr(node) }
3102}
3103impl From<RecordExpr> for Expr {
3104 fn from(node: RecordExpr) -> Expr { Expr::RecordExpr(node) }
3105}
3106impl From<CallExpr> for Expr {
3107 fn from(node: CallExpr) -> Expr { Expr::CallExpr(node) }
3108}
3109impl From<IndexExpr> for Expr {
3110 fn from(node: IndexExpr) -> Expr { Expr::IndexExpr(node) }
3111}
3112impl From<MethodCallExpr> for Expr {
3113 fn from(node: MethodCallExpr) -> Expr { Expr::MethodCallExpr(node) }
3114}
3115impl From<FieldExpr> for Expr {
3116 fn from(node: FieldExpr) -> Expr { Expr::FieldExpr(node) }
3117}
3118impl From<AwaitExpr> for Expr {
3119 fn from(node: AwaitExpr) -> Expr { Expr::AwaitExpr(node) }
3120}
3121impl From<TryExpr> for Expr {
3122 fn from(node: TryExpr) -> Expr { Expr::TryExpr(node) }
3123}
3124impl From<EffectExpr> for Expr {
3125 fn from(node: EffectExpr) -> Expr { Expr::EffectExpr(node) }
3126}
3127impl From<CastExpr> for Expr {
3128 fn from(node: CastExpr) -> Expr { Expr::CastExpr(node) }
3129}
3130impl From<RefExpr> for Expr {
3131 fn from(node: RefExpr) -> Expr { Expr::RefExpr(node) }
3132}
3133impl From<PrefixExpr> for Expr {
3134 fn from(node: PrefixExpr) -> Expr { Expr::PrefixExpr(node) }
3135}
3136impl From<RangeExpr> for Expr {
3137 fn from(node: RangeExpr) -> Expr { Expr::RangeExpr(node) }
3138}
3139impl From<BinExpr> for Expr {
3140 fn from(node: BinExpr) -> Expr { Expr::BinExpr(node) }
3141}
3142impl From<Literal> for Expr {
3143 fn from(node: Literal) -> Expr { Expr::Literal(node) }
3144}
3145impl From<MacroCall> for Expr {
3146 fn from(node: MacroCall) -> Expr { Expr::MacroCall(node) }
3147}
3148impl From<BoxExpr> for Expr {
3149 fn from(node: BoxExpr) -> Expr { Expr::BoxExpr(node) }
3150}
3151impl AstNode for Expr {
3152 fn can_cast(kind: SyntaxKind) -> bool {
3153 match kind {
3154 TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR
3155 | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
3156 | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_EXPR | CALL_EXPR | INDEX_EXPR
3157 | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | EFFECT_EXPR | CAST_EXPR
3158 | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL | BOX_EXPR => {
3159 true
3160 }
3161 _ => false,
3162 }
3163 }
3164 fn cast(syntax: SyntaxNode) -> Option<Self> {
3165 let res = match syntax.kind() {
3166 TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }),
3167 ARRAY_EXPR => Expr::ArrayExpr(ArrayExpr { syntax }),
3168 PAREN_EXPR => Expr::ParenExpr(ParenExpr { syntax }),
3169 PATH_EXPR => Expr::PathExpr(PathExpr { syntax }),
3170 LAMBDA_EXPR => Expr::LambdaExpr(LambdaExpr { syntax }),
3171 IF_EXPR => Expr::IfExpr(IfExpr { syntax }),
3172 LOOP_EXPR => Expr::LoopExpr(LoopExpr { syntax }),
3173 FOR_EXPR => Expr::ForExpr(ForExpr { syntax }),
3174 WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }),
3175 CONTINUE_EXPR => Expr::ContinueExpr(ContinueExpr { syntax }),
3176 BREAK_EXPR => Expr::BreakExpr(BreakExpr { syntax }),
3177 LABEL => Expr::Label(Label { syntax }),
3178 BLOCK_EXPR => Expr::BlockExpr(BlockExpr { syntax }),
3179 RETURN_EXPR => Expr::ReturnExpr(ReturnExpr { syntax }),
3180 MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }),
3181 RECORD_EXPR => Expr::RecordExpr(RecordExpr { syntax }),
3182 CALL_EXPR => Expr::CallExpr(CallExpr { syntax }),
3183 INDEX_EXPR => Expr::IndexExpr(IndexExpr { syntax }),
3184 METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }),
3185 FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
3186 AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
3187 TRY_EXPR => Expr::TryExpr(TryExpr { syntax }),
3188 EFFECT_EXPR => Expr::EffectExpr(EffectExpr { syntax }),
3189 CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
3190 REF_EXPR => Expr::RefExpr(RefExpr { syntax }),
3191 PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
3192 RANGE_EXPR => Expr::RangeExpr(RangeExpr { syntax }),
3193 BIN_EXPR => Expr::BinExpr(BinExpr { syntax }),
3194 LITERAL => Expr::Literal(Literal { syntax }),
3195 MACRO_CALL => Expr::MacroCall(MacroCall { syntax }),
3196 BOX_EXPR => Expr::BoxExpr(BoxExpr { syntax }),
3197 _ => return None,
3198 };
3199 Some(res)
3200 }
3201 fn syntax(&self) -> &SyntaxNode {
3202 match self {
3203 Expr::TupleExpr(it) => &it.syntax,
3204 Expr::ArrayExpr(it) => &it.syntax,
3205 Expr::ParenExpr(it) => &it.syntax,
3206 Expr::PathExpr(it) => &it.syntax,
3207 Expr::LambdaExpr(it) => &it.syntax,
3208 Expr::IfExpr(it) => &it.syntax,
3209 Expr::LoopExpr(it) => &it.syntax,
3210 Expr::ForExpr(it) => &it.syntax,
3211 Expr::WhileExpr(it) => &it.syntax,
3212 Expr::ContinueExpr(it) => &it.syntax,
3213 Expr::BreakExpr(it) => &it.syntax,
3214 Expr::Label(it) => &it.syntax,
3215 Expr::BlockExpr(it) => &it.syntax,
3216 Expr::ReturnExpr(it) => &it.syntax,
3217 Expr::MatchExpr(it) => &it.syntax,
3218 Expr::RecordExpr(it) => &it.syntax,
3219 Expr::CallExpr(it) => &it.syntax,
3220 Expr::IndexExpr(it) => &it.syntax,
3221 Expr::MethodCallExpr(it) => &it.syntax,
3222 Expr::FieldExpr(it) => &it.syntax,
3223 Expr::AwaitExpr(it) => &it.syntax,
3224 Expr::TryExpr(it) => &it.syntax,
3225 Expr::EffectExpr(it) => &it.syntax,
3226 Expr::CastExpr(it) => &it.syntax,
3227 Expr::RefExpr(it) => &it.syntax,
3228 Expr::PrefixExpr(it) => &it.syntax,
3229 Expr::RangeExpr(it) => &it.syntax,
3230 Expr::BinExpr(it) => &it.syntax,
3231 Expr::Literal(it) => &it.syntax,
3232 Expr::MacroCall(it) => &it.syntax,
3233 Expr::BoxExpr(it) => &it.syntax,
3234 }
3235 }
3236}
3237impl From<Fn> for AssocItem {
3238 fn from(node: Fn) -> AssocItem { AssocItem::Fn(node) }
3239}
3240impl From<TypeAlias> for AssocItem {
3241 fn from(node: TypeAlias) -> AssocItem { AssocItem::TypeAlias(node) }
3242}
3243impl From<Const> for AssocItem {
3244 fn from(node: Const) -> AssocItem { AssocItem::Const(node) }
3245}
3246impl From<MacroCall> for AssocItem {
3247 fn from(node: MacroCall) -> AssocItem { AssocItem::MacroCall(node) }
3248}
3249impl AstNode for AssocItem {
3250 fn can_cast(kind: SyntaxKind) -> bool {
3251 match kind {
3252 FN | TYPE_ALIAS | CONST | MACRO_CALL => true,
3253 _ => false,
3254 }
3255 }
3256 fn cast(syntax: SyntaxNode) -> Option<Self> {
3257 let res = match syntax.kind() {
3258 FN => AssocItem::Fn(Fn { syntax }),
3259 TYPE_ALIAS => AssocItem::TypeAlias(TypeAlias { syntax }),
3260 CONST => AssocItem::Const(Const { syntax }),
3261 MACRO_CALL => AssocItem::MacroCall(MacroCall { syntax }),
3262 _ => return None,
3263 };
3264 Some(res)
3265 }
3266 fn syntax(&self) -> &SyntaxNode {
3267 match self {
3268 AssocItem::Fn(it) => &it.syntax,
3269 AssocItem::TypeAlias(it) => &it.syntax,
3270 AssocItem::Const(it) => &it.syntax,
3271 AssocItem::MacroCall(it) => &it.syntax,
3272 }
3273 }
3274}
3275impl From<Fn> for ExternItem {
3276 fn from(node: Fn) -> ExternItem { ExternItem::Fn(node) }
3277}
3278impl From<Static> for ExternItem {
3279 fn from(node: Static) -> ExternItem { ExternItem::Static(node) }
3280}
3281impl From<MacroCall> for ExternItem {
3282 fn from(node: MacroCall) -> ExternItem { ExternItem::MacroCall(node) }
3283}
3284impl AstNode for ExternItem {
3285 fn can_cast(kind: SyntaxKind) -> bool {
3286 match kind {
3287 FN | STATIC | MACRO_CALL => true,
3288 _ => false,
3289 }
3290 }
3291 fn cast(syntax: SyntaxNode) -> Option<Self> {
3292 let res = match syntax.kind() {
3293 FN => ExternItem::Fn(Fn { syntax }),
3294 STATIC => ExternItem::Static(Static { syntax }),
3295 MACRO_CALL => ExternItem::MacroCall(MacroCall { syntax }),
3296 _ => return None,
3297 };
3298 Some(res)
3299 }
3300 fn syntax(&self) -> &SyntaxNode {
3301 match self {
3302 ExternItem::Fn(it) => &it.syntax,
3303 ExternItem::Static(it) => &it.syntax,
3304 ExternItem::MacroCall(it) => &it.syntax,
3305 }
3306 }
3307}
3308impl From<LifetimeParam> for GenericParam {
3309 fn from(node: LifetimeParam) -> GenericParam { GenericParam::LifetimeParam(node) }
3310}
3311impl From<TypeParam> for GenericParam {
3312 fn from(node: TypeParam) -> GenericParam { GenericParam::TypeParam(node) }
3313}
3314impl From<ConstParam> for GenericParam {
3315 fn from(node: ConstParam) -> GenericParam { GenericParam::ConstParam(node) }
3316}
3317impl AstNode for GenericParam {
3318 fn can_cast(kind: SyntaxKind) -> bool {
3319 match kind {
3320 LIFETIME_PARAM | TYPE_PARAM | CONST_PARAM => true,
3321 _ => false,
3322 }
3323 }
3324 fn cast(syntax: SyntaxNode) -> Option<Self> {
3325 let res = match syntax.kind() {
3326 LIFETIME_PARAM => GenericParam::LifetimeParam(LifetimeParam { syntax }),
3327 TYPE_PARAM => GenericParam::TypeParam(TypeParam { syntax }),
3328 CONST_PARAM => GenericParam::ConstParam(ConstParam { syntax }),
3329 _ => return None,
3330 };
3331 Some(res)
3332 }
3333 fn syntax(&self) -> &SyntaxNode {
3334 match self {
3335 GenericParam::LifetimeParam(it) => &it.syntax,
3336 GenericParam::TypeParam(it) => &it.syntax,
3337 GenericParam::ConstParam(it) => &it.syntax,
3338 }
3339 }
3340}
3341impl From<LetStmt> for Stmt {
3342 fn from(node: LetStmt) -> Stmt { Stmt::LetStmt(node) }
3343}
3344impl From<ExprStmt> for Stmt {
3345 fn from(node: ExprStmt) -> Stmt { Stmt::ExprStmt(node) }
3346}
3347impl AstNode for Stmt {
3348 fn can_cast(kind: SyntaxKind) -> bool {
3349 match kind {
3350 LET_STMT | EXPR_STMT => true,
3351 _ => false,
3352 }
3353 }
3354 fn cast(syntax: SyntaxNode) -> Option<Self> {
3355 let res = match syntax.kind() {
3356 LET_STMT => Stmt::LetStmt(LetStmt { syntax }),
3357 EXPR_STMT => Stmt::ExprStmt(ExprStmt { syntax }),
3358 _ => return None,
3359 };
3360 Some(res)
3361 }
3362 fn syntax(&self) -> &SyntaxNode {
3363 match self {
3364 Stmt::LetStmt(it) => &it.syntax,
3365 Stmt::ExprStmt(it) => &it.syntax,
3366 }
3367 }
3368}
3369impl From<Struct> for AdtDef {
3370 fn from(node: Struct) -> AdtDef { AdtDef::Struct(node) }
3371}
3372impl From<Enum> for AdtDef {
3373 fn from(node: Enum) -> AdtDef { AdtDef::Enum(node) }
3374}
3375impl From<Union> for AdtDef {
3376 fn from(node: Union) -> AdtDef { AdtDef::Union(node) }
3377}
3378impl AstNode for AdtDef {
3379 fn can_cast(kind: SyntaxKind) -> bool {
3380 match kind {
3381 STRUCT | ENUM | UNION => true,
3382 _ => false,
3383 }
3384 }
3385 fn cast(syntax: SyntaxNode) -> Option<Self> {
3386 let res = match syntax.kind() {
3387 STRUCT => AdtDef::Struct(Struct { syntax }),
3388 ENUM => AdtDef::Enum(Enum { syntax }),
3389 UNION => AdtDef::Union(Union { syntax }),
3390 _ => return None,
3391 };
3392 Some(res)
3393 }
3394 fn syntax(&self) -> &SyntaxNode {
3395 match self {
3396 AdtDef::Struct(it) => &it.syntax,
3397 AdtDef::Enum(it) => &it.syntax,
3398 AdtDef::Union(it) => &it.syntax,
3399 }
3400 }
3401}
3402impl std::fmt::Display for Item {
3403 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3404 std::fmt::Display::fmt(self.syntax(), f)
3405 }
3406}
3407impl std::fmt::Display for TypeRef {
3408 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3409 std::fmt::Display::fmt(self.syntax(), f)
3410 }
3411}
3412impl std::fmt::Display for Pat {
3413 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3414 std::fmt::Display::fmt(self.syntax(), f)
3415 }
3416}
3417impl std::fmt::Display for FieldList {
3418 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3419 std::fmt::Display::fmt(self.syntax(), f)
3420 }
3421}
3422impl std::fmt::Display for Expr {
3423 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3424 std::fmt::Display::fmt(self.syntax(), f)
3425 }
3426}
3427impl std::fmt::Display for AssocItem {
3428 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3429 std::fmt::Display::fmt(self.syntax(), f)
3430 }
3431}
3432impl std::fmt::Display for ExternItem {
3433 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3434 std::fmt::Display::fmt(self.syntax(), f)
3435 }
3436}
3437impl std::fmt::Display for GenericParam {
3438 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3439 std::fmt::Display::fmt(self.syntax(), f)
3440 }
3441}
3442impl std::fmt::Display for Stmt {
3443 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3444 std::fmt::Display::fmt(self.syntax(), f)
3445 }
3446}
3447impl std::fmt::Display for AdtDef {
3448 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3449 std::fmt::Display::fmt(self.syntax(), f)
3450 }
3451}
3452impl std::fmt::Display for SourceFile {
3453 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3454 std::fmt::Display::fmt(self.syntax(), f)
3455 }
3456}
3457impl std::fmt::Display for Attr {
3458 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3459 std::fmt::Display::fmt(self.syntax(), f)
3460 }
3461}
3462impl std::fmt::Display for Const {
3463 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3464 std::fmt::Display::fmt(self.syntax(), f)
3465 }
3466}
3467impl std::fmt::Display for Enum {
3468 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3469 std::fmt::Display::fmt(self.syntax(), f)
3470 }
3471}
3472impl std::fmt::Display for ExternBlock {
3473 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3474 std::fmt::Display::fmt(self.syntax(), f)
3475 }
3476}
3477impl std::fmt::Display for ExternCrate {
3478 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3479 std::fmt::Display::fmt(self.syntax(), f)
3480 }
3481}
3482impl std::fmt::Display for Fn {
3483 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3484 std::fmt::Display::fmt(self.syntax(), f)
3485 }
3486}
3487impl std::fmt::Display for Impl {
3488 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3489 std::fmt::Display::fmt(self.syntax(), f)
3490 }
3491}
3492impl std::fmt::Display for MacroCall {
3493 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3494 std::fmt::Display::fmt(self.syntax(), f)
3495 }
3496}
3497impl std::fmt::Display for Module {
3498 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3499 std::fmt::Display::fmt(self.syntax(), f)
3500 }
3501}
3502impl std::fmt::Display for Static {
3503 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3504 std::fmt::Display::fmt(self.syntax(), f)
3505 }
3506}
3507impl std::fmt::Display for Struct {
3508 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3509 std::fmt::Display::fmt(self.syntax(), f)
3510 }
3511}
3512impl std::fmt::Display for Trait {
3513 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3514 std::fmt::Display::fmt(self.syntax(), f)
3515 }
3516}
3517impl std::fmt::Display for TypeAlias {
3518 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3519 std::fmt::Display::fmt(self.syntax(), f)
3520 }
3521}
3522impl std::fmt::Display for Union {
3523 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3524 std::fmt::Display::fmt(self.syntax(), f)
3525 }
3526}
3527impl std::fmt::Display for Use {
3528 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3529 std::fmt::Display::fmt(self.syntax(), f)
3530 }
3531}
3532impl std::fmt::Display for Visibility {
3533 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3534 std::fmt::Display::fmt(self.syntax(), f)
3535 }
3536}
3537impl std::fmt::Display for Name {
3538 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3539 std::fmt::Display::fmt(self.syntax(), f)
3540 }
3541}
3542impl std::fmt::Display for ItemList {
3543 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3544 std::fmt::Display::fmt(self.syntax(), f)
3545 }
3546}
3547impl std::fmt::Display for NameRef {
3548 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3549 std::fmt::Display::fmt(self.syntax(), f)
3550 }
3551}
3552impl std::fmt::Display for Rename {
3553 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3554 std::fmt::Display::fmt(self.syntax(), f)
3555 }
3556}
3557impl std::fmt::Display for UseTree {
3558 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3559 std::fmt::Display::fmt(self.syntax(), f)
3560 }
3561}
3562impl std::fmt::Display for Path {
3563 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3564 std::fmt::Display::fmt(self.syntax(), f)
3565 }
3566}
3567impl std::fmt::Display for UseTreeList {
3568 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3569 std::fmt::Display::fmt(self.syntax(), f)
3570 }
3571}
3572impl std::fmt::Display for Abi {
3573 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3574 std::fmt::Display::fmt(self.syntax(), f)
3575 }
3576}
3577impl std::fmt::Display for GenericParamList {
3578 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3579 std::fmt::Display::fmt(self.syntax(), f)
3580 }
3581}
3582impl std::fmt::Display for ParamList {
3583 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3584 std::fmt::Display::fmt(self.syntax(), f)
3585 }
3586}
3587impl std::fmt::Display for RetType {
3588 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3589 std::fmt::Display::fmt(self.syntax(), f)
3590 }
3591}
3592impl std::fmt::Display for WhereClause {
3593 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3594 std::fmt::Display::fmt(self.syntax(), f)
3595 }
3596}
3597impl std::fmt::Display for BlockExpr {
3598 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3599 std::fmt::Display::fmt(self.syntax(), f)
3600 }
3601}
3602impl std::fmt::Display for SelfParam {
3603 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3604 std::fmt::Display::fmt(self.syntax(), f)
3605 }
3606}
3607impl std::fmt::Display for Param {
3608 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3609 std::fmt::Display::fmt(self.syntax(), f)
3610 }
3611}
3612impl std::fmt::Display for TypeBoundList {
3613 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3614 std::fmt::Display::fmt(self.syntax(), f)
3615 }
3616}
3617impl std::fmt::Display for RecordFieldList {
3618 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3619 std::fmt::Display::fmt(self.syntax(), f)
3620 }
3621}
3622impl std::fmt::Display for TupleFieldList {
3623 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3624 std::fmt::Display::fmt(self.syntax(), f)
3625 }
3626}
3627impl std::fmt::Display for RecordField {
3628 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3629 std::fmt::Display::fmt(self.syntax(), f)
3630 }
3631}
3632impl std::fmt::Display for TupleField {
3633 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3634 std::fmt::Display::fmt(self.syntax(), f)
3635 }
3636}
3637impl std::fmt::Display for VariantList {
3638 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3639 std::fmt::Display::fmt(self.syntax(), f)
3640 }
3641}
3642impl std::fmt::Display for Variant {
3643 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3644 std::fmt::Display::fmt(self.syntax(), f)
3645 }
3646}
3647impl std::fmt::Display for AssocItemList {
3648 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3649 std::fmt::Display::fmt(self.syntax(), f)
3650 }
3651}
3652impl std::fmt::Display for ExternItemList {
3653 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3654 std::fmt::Display::fmt(self.syntax(), f)
3655 }
3656}
3657impl std::fmt::Display for LifetimeParam {
3658 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3659 std::fmt::Display::fmt(self.syntax(), f)
3660 }
3661}
3662impl std::fmt::Display for TypeParam {
3663 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3664 std::fmt::Display::fmt(self.syntax(), f)
3665 }
3666}
3667impl std::fmt::Display for ConstParam {
3668 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3669 std::fmt::Display::fmt(self.syntax(), f)
3670 }
3671}
3672impl std::fmt::Display for Literal {
3673 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3674 std::fmt::Display::fmt(self.syntax(), f)
3675 }
3676}
3677impl std::fmt::Display for TokenTree {
3678 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3679 std::fmt::Display::fmt(self.syntax(), f)
3680 }
3681}
3682impl std::fmt::Display for ParenType {
3683 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3684 std::fmt::Display::fmt(self.syntax(), f)
3685 }
3686}
3687impl std::fmt::Display for TupleType {
3688 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3689 std::fmt::Display::fmt(self.syntax(), f)
3690 }
3691}
3692impl std::fmt::Display for NeverType {
3693 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3694 std::fmt::Display::fmt(self.syntax(), f)
3695 }
3696}
3697impl std::fmt::Display for PathType {
3698 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3699 std::fmt::Display::fmt(self.syntax(), f)
3700 }
3701}
3702impl std::fmt::Display for PointerType {
3703 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3704 std::fmt::Display::fmt(self.syntax(), f)
3705 }
3706}
3707impl std::fmt::Display for ArrayType {
3708 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3709 std::fmt::Display::fmt(self.syntax(), f)
3710 }
3711}
3712impl std::fmt::Display for SliceType {
3713 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3714 std::fmt::Display::fmt(self.syntax(), f)
3715 }
3716}
3717impl std::fmt::Display for ReferenceType {
3718 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3719 std::fmt::Display::fmt(self.syntax(), f)
3720 }
3721}
3722impl std::fmt::Display for PlaceholderType {
3723 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3724 std::fmt::Display::fmt(self.syntax(), f)
3725 }
3726}
3727impl std::fmt::Display for FnPointerType {
3728 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3729 std::fmt::Display::fmt(self.syntax(), f)
3730 }
3731}
3732impl std::fmt::Display for ForType {
3733 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3734 std::fmt::Display::fmt(self.syntax(), f)
3735 }
3736}
3737impl std::fmt::Display for ImplTraitType {
3738 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3739 std::fmt::Display::fmt(self.syntax(), f)
3740 }
3741}
3742impl std::fmt::Display for DynTraitType {
3743 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3744 std::fmt::Display::fmt(self.syntax(), f)
3745 }
3746}
3747impl std::fmt::Display for TupleExpr {
3748 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3749 std::fmt::Display::fmt(self.syntax(), f)
3750 }
3751}
3752impl std::fmt::Display for ArrayExpr {
3753 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3754 std::fmt::Display::fmt(self.syntax(), f)
3755 }
3756}
3757impl std::fmt::Display for ParenExpr {
3758 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3759 std::fmt::Display::fmt(self.syntax(), f)
3760 }
3761}
3762impl std::fmt::Display for PathExpr {
3763 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3764 std::fmt::Display::fmt(self.syntax(), f)
3765 }
3766}
3767impl std::fmt::Display for LambdaExpr {
3768 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3769 std::fmt::Display::fmt(self.syntax(), f)
3770 }
3771}
3772impl std::fmt::Display for IfExpr {
3773 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3774 std::fmt::Display::fmt(self.syntax(), f)
3775 }
3776}
3777impl std::fmt::Display for Condition {
3778 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3779 std::fmt::Display::fmt(self.syntax(), f)
3780 }
3781}
3782impl std::fmt::Display for EffectExpr {
3783 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3784 std::fmt::Display::fmt(self.syntax(), f)
3785 }
3786}
3787impl std::fmt::Display for Label {
3788 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3789 std::fmt::Display::fmt(self.syntax(), f)
3790 }
3791}
3792impl std::fmt::Display for LoopExpr {
3793 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3794 std::fmt::Display::fmt(self.syntax(), f)
3795 }
3796}
3797impl std::fmt::Display for ForExpr {
3798 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3799 std::fmt::Display::fmt(self.syntax(), f)
3800 }
3801}
3802impl std::fmt::Display for WhileExpr {
3803 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3804 std::fmt::Display::fmt(self.syntax(), f)
3805 }
3806}
3807impl std::fmt::Display for ContinueExpr {
3808 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3809 std::fmt::Display::fmt(self.syntax(), f)
3810 }
3811}
3812impl std::fmt::Display for BreakExpr {
3813 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3814 std::fmt::Display::fmt(self.syntax(), f)
3815 }
3816}
3817impl std::fmt::Display for ReturnExpr {
3818 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3819 std::fmt::Display::fmt(self.syntax(), f)
3820 }
3821}
3822impl std::fmt::Display for CallExpr {
3823 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3824 std::fmt::Display::fmt(self.syntax(), f)
3825 }
3826}
3827impl std::fmt::Display for ArgList {
3828 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3829 std::fmt::Display::fmt(self.syntax(), f)
3830 }
3831}
3832impl std::fmt::Display for MethodCallExpr {
3833 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3834 std::fmt::Display::fmt(self.syntax(), f)
3835 }
3836}
3837impl std::fmt::Display for TypeArgList {
3838 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3839 std::fmt::Display::fmt(self.syntax(), f)
3840 }
3841}
3842impl std::fmt::Display for FieldExpr {
3843 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3844 std::fmt::Display::fmt(self.syntax(), f)
3845 }
3846}
3847impl std::fmt::Display for IndexExpr {
3848 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3849 std::fmt::Display::fmt(self.syntax(), f)
3850 }
3851}
3852impl std::fmt::Display for AwaitExpr {
3853 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3854 std::fmt::Display::fmt(self.syntax(), f)
3855 }
3856}
3857impl std::fmt::Display for TryExpr {
3858 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3859 std::fmt::Display::fmt(self.syntax(), f)
3860 }
3861}
3862impl std::fmt::Display for CastExpr {
3863 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3864 std::fmt::Display::fmt(self.syntax(), f)
3865 }
3866}
3867impl std::fmt::Display for RefExpr {
3868 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3869 std::fmt::Display::fmt(self.syntax(), f)
3870 }
3871}
3872impl std::fmt::Display for PrefixExpr {
3873 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3874 std::fmt::Display::fmt(self.syntax(), f)
3875 }
3876}
3877impl std::fmt::Display for BoxExpr {
3878 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3879 std::fmt::Display::fmt(self.syntax(), f)
3880 }
3881}
3882impl std::fmt::Display for RangeExpr {
3883 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3884 std::fmt::Display::fmt(self.syntax(), f)
3885 }
3886}
3887impl std::fmt::Display for BinExpr {
3888 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3889 std::fmt::Display::fmt(self.syntax(), f)
3890 }
3891}
3892impl std::fmt::Display for MatchExpr {
3893 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3894 std::fmt::Display::fmt(self.syntax(), f)
3895 }
3896}
3897impl std::fmt::Display for MatchArmList {
3898 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3899 std::fmt::Display::fmt(self.syntax(), f)
3900 }
3901}
3902impl std::fmt::Display for MatchArm {
3903 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3904 std::fmt::Display::fmt(self.syntax(), f)
3905 }
3906}
3907impl std::fmt::Display for MatchGuard {
3908 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3909 std::fmt::Display::fmt(self.syntax(), f)
3910 }
3911}
3912impl std::fmt::Display for RecordExpr {
3913 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3914 std::fmt::Display::fmt(self.syntax(), f)
3915 }
3916}
3917impl std::fmt::Display for RecordExprFieldList {
3918 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3919 std::fmt::Display::fmt(self.syntax(), f)
3920 }
3921}
3922impl std::fmt::Display for RecordExprField {
3923 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3924 std::fmt::Display::fmt(self.syntax(), f)
3925 }
3926}
3927impl std::fmt::Display for OrPat {
3928 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3929 std::fmt::Display::fmt(self.syntax(), f)
3930 }
3931}
3932impl std::fmt::Display for ParenPat {
3933 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3934 std::fmt::Display::fmt(self.syntax(), f)
3935 }
3936}
3937impl std::fmt::Display for RefPat {
3938 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3939 std::fmt::Display::fmt(self.syntax(), f)
3940 }
3941}
3942impl std::fmt::Display for BoxPat {
3943 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3944 std::fmt::Display::fmt(self.syntax(), f)
3945 }
3946}
3947impl std::fmt::Display for BindPat {
3948 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3949 std::fmt::Display::fmt(self.syntax(), f)
3950 }
3951}
3952impl std::fmt::Display for PlaceholderPat {
3953 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3954 std::fmt::Display::fmt(self.syntax(), f)
3955 }
3956}
3957impl std::fmt::Display for DotDotPat {
3958 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3959 std::fmt::Display::fmt(self.syntax(), f)
3960 }
3961}
3962impl std::fmt::Display for PathPat {
3963 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3964 std::fmt::Display::fmt(self.syntax(), f)
3965 }
3966}
3967impl std::fmt::Display for SlicePat {
3968 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3969 std::fmt::Display::fmt(self.syntax(), f)
3970 }
3971}
3972impl std::fmt::Display for RangePat {
3973 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3974 std::fmt::Display::fmt(self.syntax(), f)
3975 }
3976}
3977impl std::fmt::Display for LiteralPat {
3978 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3979 std::fmt::Display::fmt(self.syntax(), f)
3980 }
3981}
3982impl std::fmt::Display for MacroPat {
3983 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3984 std::fmt::Display::fmt(self.syntax(), f)
3985 }
3986}
3987impl std::fmt::Display for RecordPat {
3988 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3989 std::fmt::Display::fmt(self.syntax(), f)
3990 }
3991}
3992impl std::fmt::Display for RecordFieldPatList {
3993 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3994 std::fmt::Display::fmt(self.syntax(), f)
3995 }
3996}
3997impl std::fmt::Display for RecordFieldPat {
3998 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3999 std::fmt::Display::fmt(self.syntax(), f)
4000 }
4001}
4002impl std::fmt::Display for TupleStructPat {
4003 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4004 std::fmt::Display::fmt(self.syntax(), f)
4005 }
4006}
4007impl std::fmt::Display for TuplePat {
4008 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4009 std::fmt::Display::fmt(self.syntax(), f)
4010 }
4011}
4012impl std::fmt::Display for MacroDef {
4013 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4014 std::fmt::Display::fmt(self.syntax(), f)
4015 }
4016}
4017impl std::fmt::Display for MacroItems {
4018 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4019 std::fmt::Display::fmt(self.syntax(), f)
4020 }
4021}
4022impl std::fmt::Display for MacroStmts {
4023 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4024 std::fmt::Display::fmt(self.syntax(), f)
4025 }
4026}
4027impl std::fmt::Display for TypeBound {
4028 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4029 std::fmt::Display::fmt(self.syntax(), f)
4030 }
4031}
4032impl std::fmt::Display for WherePred {
4033 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4034 std::fmt::Display::fmt(self.syntax(), f)
4035 }
4036}
4037impl std::fmt::Display for ExprStmt {
4038 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4039 std::fmt::Display::fmt(self.syntax(), f)
4040 }
4041}
4042impl std::fmt::Display for LetStmt {
4043 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4044 std::fmt::Display::fmt(self.syntax(), f)
4045 }
4046}
4047impl std::fmt::Display for PathSegment {
4048 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4049 std::fmt::Display::fmt(self.syntax(), f)
4050 }
4051}
4052impl std::fmt::Display for TypeArg {
4053 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4054 std::fmt::Display::fmt(self.syntax(), f)
4055 }
4056}
4057impl std::fmt::Display for LifetimeArg {
4058 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4059 std::fmt::Display::fmt(self.syntax(), f)
4060 }
4061}
4062impl std::fmt::Display for AssocTypeArg {
4063 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4064 std::fmt::Display::fmt(self.syntax(), f)
4065 }
4066}
4067impl std::fmt::Display for ConstArg {
4068 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
4069 std::fmt::Display::fmt(self.syntax(), f)
4070 }
4071}
diff --git a/crates/ra_syntax/src/ast/generated/tokens.rs b/crates/ra_syntax/src/ast/generated/tokens.rs
deleted file mode 100644
index abadd0b61..000000000
--- a/crates/ra_syntax/src/ast/generated/tokens.rs
+++ /dev/null
@@ -1,91 +0,0 @@
1//! Generated file, do not edit by hand, see `xtask/src/codegen`
2
3use crate::{
4 ast::AstToken,
5 SyntaxKind::{self, *},
6 SyntaxToken,
7};
8
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct Whitespace {
11 pub(crate) syntax: SyntaxToken,
12}
13impl std::fmt::Display for Whitespace {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 std::fmt::Display::fmt(&self.syntax, f)
16 }
17}
18impl AstToken for Whitespace {
19 fn can_cast(kind: SyntaxKind) -> bool { kind == WHITESPACE }
20 fn cast(syntax: SyntaxToken) -> Option<Self> {
21 if Self::can_cast(syntax.kind()) {
22 Some(Self { syntax })
23 } else {
24 None
25 }
26 }
27 fn syntax(&self) -> &SyntaxToken { &self.syntax }
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, Hash)]
31pub struct Comment {
32 pub(crate) syntax: SyntaxToken,
33}
34impl std::fmt::Display for Comment {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 std::fmt::Display::fmt(&self.syntax, f)
37 }
38}
39impl AstToken for Comment {
40 fn can_cast(kind: SyntaxKind) -> bool { kind == COMMENT }
41 fn cast(syntax: SyntaxToken) -> Option<Self> {
42 if Self::can_cast(syntax.kind()) {
43 Some(Self { syntax })
44 } else {
45 None
46 }
47 }
48 fn syntax(&self) -> &SyntaxToken { &self.syntax }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Hash)]
52pub struct String {
53 pub(crate) syntax: SyntaxToken,
54}
55impl std::fmt::Display for String {
56 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57 std::fmt::Display::fmt(&self.syntax, f)
58 }
59}
60impl AstToken for String {
61 fn can_cast(kind: SyntaxKind) -> bool { kind == STRING }
62 fn cast(syntax: SyntaxToken) -> Option<Self> {
63 if Self::can_cast(syntax.kind()) {
64 Some(Self { syntax })
65 } else {
66 None
67 }
68 }
69 fn syntax(&self) -> &SyntaxToken { &self.syntax }
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Hash)]
73pub struct RawString {
74 pub(crate) syntax: SyntaxToken,
75}
76impl std::fmt::Display for RawString {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 std::fmt::Display::fmt(&self.syntax, f)
79 }
80}
81impl AstToken for RawString {
82 fn can_cast(kind: SyntaxKind) -> bool { kind == RAW_STRING }
83 fn cast(syntax: SyntaxToken) -> Option<Self> {
84 if Self::can_cast(syntax.kind()) {
85 Some(Self { syntax })
86 } else {
87 None
88 }
89 }
90 fn syntax(&self) -> &SyntaxToken { &self.syntax }
91}
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
deleted file mode 100644
index 509e8ae7a..000000000
--- a/crates/ra_syntax/src/ast/make.rs
+++ /dev/null
@@ -1,392 +0,0 @@
1//! This module contains free-standing functions for creating AST fragments out
2//! of smaller pieces.
3//!
4//! Note that all functions here intended to be stupid constructors, which just
5//! assemble a finish node from immediate children. If you want to do something
6//! smarter than that, it probably doesn't belong in this module.
7use itertools::Itertools;
8use stdx::format_to;
9
10use crate::{ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, SyntaxToken};
11
12pub fn name(text: &str) -> ast::Name {
13 ast_from_text(&format!("mod {};", text))
14}
15
16pub fn name_ref(text: &str) -> ast::NameRef {
17 ast_from_text(&format!("fn f() {{ {}; }}", text))
18}
19
20pub fn type_ref(text: &str) -> ast::TypeRef {
21 ast_from_text(&format!("impl {} for D {{}};", text))
22}
23
24pub fn path_segment(name_ref: ast::NameRef) -> ast::PathSegment {
25 ast_from_text(&format!("use {};", name_ref))
26}
27pub fn path_unqualified(segment: ast::PathSegment) -> ast::Path {
28 path_from_text(&format!("use {}", segment))
29}
30pub fn path_qualified(qual: ast::Path, segment: ast::PathSegment) -> ast::Path {
31 path_from_text(&format!("{}::{}", qual, segment))
32}
33fn path_from_text(text: &str) -> ast::Path {
34 ast_from_text(text)
35}
36
37pub fn use_tree(
38 path: ast::Path,
39 use_tree_list: Option<ast::UseTreeList>,
40 alias: Option<ast::Rename>,
41 add_star: bool,
42) -> ast::UseTree {
43 let mut buf = "use ".to_string();
44 buf += &path.syntax().to_string();
45 if let Some(use_tree_list) = use_tree_list {
46 format_to!(buf, "::{}", use_tree_list);
47 }
48 if add_star {
49 buf += "::*";
50 }
51
52 if let Some(alias) = alias {
53 format_to!(buf, " {}", alias);
54 }
55 ast_from_text(&buf)
56}
57
58pub fn use_tree_list(use_trees: impl IntoIterator<Item = ast::UseTree>) -> ast::UseTreeList {
59 let use_trees = use_trees.into_iter().map(|it| it.syntax().clone()).join(", ");
60 ast_from_text(&format!("use {{{}}};", use_trees))
61}
62
63pub fn use_item(use_tree: ast::UseTree) -> ast::Use {
64 ast_from_text(&format!("use {};", use_tree))
65}
66
67pub fn record_field(name: ast::NameRef, expr: Option<ast::Expr>) -> ast::RecordExprField {
68 return match expr {
69 Some(expr) => from_text(&format!("{}: {}", name, expr)),
70 None => from_text(&name.to_string()),
71 };
72
73 fn from_text(text: &str) -> ast::RecordExprField {
74 ast_from_text(&format!("fn f() {{ S {{ {}, }} }}", text))
75 }
76}
77
78pub fn record_field_def(name: ast::NameRef, ty: ast::TypeRef) -> ast::RecordField {
79 ast_from_text(&format!("struct S {{ {}: {}, }}", name, ty))
80}
81
82pub fn block_expr(
83 stmts: impl IntoIterator<Item = ast::Stmt>,
84 tail_expr: Option<ast::Expr>,
85) -> ast::BlockExpr {
86 let mut buf = "{\n".to_string();
87 for stmt in stmts.into_iter() {
88 format_to!(buf, " {}\n", stmt);
89 }
90 if let Some(tail_expr) = tail_expr {
91 format_to!(buf, " {}\n", tail_expr)
92 }
93 buf += "}";
94 ast_from_text(&format!("fn f() {}", buf))
95}
96
97pub fn expr_unit() -> ast::Expr {
98 expr_from_text("()")
99}
100pub fn expr_empty_block() -> ast::Expr {
101 expr_from_text("{}")
102}
103pub fn expr_unimplemented() -> ast::Expr {
104 expr_from_text("unimplemented!()")
105}
106pub fn expr_unreachable() -> ast::Expr {
107 expr_from_text("unreachable!()")
108}
109pub fn expr_todo() -> ast::Expr {
110 expr_from_text("todo!()")
111}
112pub fn expr_path(path: ast::Path) -> ast::Expr {
113 expr_from_text(&path.to_string())
114}
115pub fn expr_continue() -> ast::Expr {
116 expr_from_text("continue")
117}
118pub fn expr_break() -> ast::Expr {
119 expr_from_text("break")
120}
121pub fn expr_return() -> ast::Expr {
122 expr_from_text("return")
123}
124pub fn expr_match(expr: ast::Expr, match_arm_list: ast::MatchArmList) -> ast::Expr {
125 expr_from_text(&format!("match {} {}", expr, match_arm_list))
126}
127pub fn expr_if(condition: ast::Condition, then_branch: ast::BlockExpr) -> ast::Expr {
128 expr_from_text(&format!("if {} {}", condition, then_branch))
129}
130pub fn expr_prefix(op: SyntaxKind, expr: ast::Expr) -> ast::Expr {
131 let token = token(op);
132 expr_from_text(&format!("{}{}", token, expr))
133}
134fn expr_from_text(text: &str) -> ast::Expr {
135 ast_from_text(&format!("const C: () = {};", text))
136}
137
138pub fn try_expr_from_text(text: &str) -> Option<ast::Expr> {
139 try_ast_from_text(&format!("const C: () = {};", text))
140}
141
142pub fn condition(expr: ast::Expr, pattern: Option<ast::Pat>) -> ast::Condition {
143 match pattern {
144 None => ast_from_text(&format!("const _: () = while {} {{}};", expr)),
145 Some(pattern) => {
146 ast_from_text(&format!("const _: () = while let {} = {} {{}};", pattern, expr))
147 }
148 }
149}
150
151pub fn bind_pat(name: ast::Name) -> ast::BindPat {
152 return from_text(name.text());
153
154 fn from_text(text: &str) -> ast::BindPat {
155 ast_from_text(&format!("fn f({}: ())", text))
156 }
157}
158
159pub fn placeholder_pat() -> ast::PlaceholderPat {
160 return from_text("_");
161
162 fn from_text(text: &str) -> ast::PlaceholderPat {
163 ast_from_text(&format!("fn f({}: ())", text))
164 }
165}
166
167/// Creates a tuple of patterns from an interator of patterns.
168///
169/// Invariant: `pats` must be length > 1
170///
171/// FIXME handle `pats` length == 1
172pub fn tuple_pat(pats: impl IntoIterator<Item = ast::Pat>) -> ast::TuplePat {
173 let pats_str = pats.into_iter().map(|p| p.to_string()).join(", ");
174 return from_text(&format!("({})", pats_str));
175
176 fn from_text(text: &str) -> ast::TuplePat {
177 ast_from_text(&format!("fn f({}: ())", text))
178 }
179}
180
181pub fn tuple_struct_pat(
182 path: ast::Path,
183 pats: impl IntoIterator<Item = ast::Pat>,
184) -> ast::TupleStructPat {
185 let pats_str = pats.into_iter().join(", ");
186 return from_text(&format!("{}({})", path, pats_str));
187
188 fn from_text(text: &str) -> ast::TupleStructPat {
189 ast_from_text(&format!("fn f({}: ())", text))
190 }
191}
192
193pub fn record_pat(path: ast::Path, pats: impl IntoIterator<Item = ast::Pat>) -> ast::RecordPat {
194 let pats_str = pats.into_iter().join(", ");
195 return from_text(&format!("{} {{ {} }}", path, pats_str));
196
197 fn from_text(text: &str) -> ast::RecordPat {
198 ast_from_text(&format!("fn f({}: ())", text))
199 }
200}
201
202/// Returns a `BindPat` if the path has just one segment, a `PathPat` otherwise.
203pub fn path_pat(path: ast::Path) -> ast::Pat {
204 return from_text(&path.to_string());
205 fn from_text(text: &str) -> ast::Pat {
206 ast_from_text(&format!("fn f({}: ())", text))
207 }
208}
209
210pub fn match_arm(pats: impl IntoIterator<Item = ast::Pat>, expr: ast::Expr) -> ast::MatchArm {
211 let pats_str = pats.into_iter().join(" | ");
212 return from_text(&format!("{} => {}", pats_str, expr));
213
214 fn from_text(text: &str) -> ast::MatchArm {
215 ast_from_text(&format!("fn f() {{ match () {{{}}} }}", text))
216 }
217}
218
219pub fn match_arm_list(arms: impl IntoIterator<Item = ast::MatchArm>) -> ast::MatchArmList {
220 let arms_str = arms
221 .into_iter()
222 .map(|arm| {
223 let needs_comma = arm.expr().map_or(true, |it| !it.is_block_like());
224 let comma = if needs_comma { "," } else { "" };
225 format!(" {}{}\n", arm.syntax(), comma)
226 })
227 .collect::<String>();
228 return from_text(&arms_str);
229
230 fn from_text(text: &str) -> ast::MatchArmList {
231 ast_from_text(&format!("fn f() {{ match () {{\n{}}} }}", text))
232 }
233}
234
235pub fn where_pred(
236 path: ast::Path,
237 bounds: impl IntoIterator<Item = ast::TypeBound>,
238) -> ast::WherePred {
239 let bounds = bounds.into_iter().join(" + ");
240 return from_text(&format!("{}: {}", path, bounds));
241
242 fn from_text(text: &str) -> ast::WherePred {
243 ast_from_text(&format!("fn f() where {} {{ }}", text))
244 }
245}
246
247pub fn where_clause(preds: impl IntoIterator<Item = ast::WherePred>) -> ast::WhereClause {
248 let preds = preds.into_iter().join(", ");
249 return from_text(preds.as_str());
250
251 fn from_text(text: &str) -> ast::WhereClause {
252 ast_from_text(&format!("fn f() where {} {{ }}", text))
253 }
254}
255
256pub fn let_stmt(pattern: ast::Pat, initializer: Option<ast::Expr>) -> ast::LetStmt {
257 let text = match initializer {
258 Some(it) => format!("let {} = {};", pattern, it),
259 None => format!("let {};", pattern),
260 };
261 ast_from_text(&format!("fn f() {{ {} }}", text))
262}
263pub fn expr_stmt(expr: ast::Expr) -> ast::ExprStmt {
264 let semi = if expr.is_block_like() { "" } else { ";" };
265 ast_from_text(&format!("fn f() {{ {}{} (); }}", expr, semi))
266}
267
268pub fn token(kind: SyntaxKind) -> SyntaxToken {
269 tokens::SOURCE_FILE
270 .tree()
271 .syntax()
272 .descendants_with_tokens()
273 .filter_map(|it| it.into_token())
274 .find(|it| it.kind() == kind)
275 .unwrap_or_else(|| panic!("unhandled token: {:?}", kind))
276}
277
278pub fn param(name: String, ty: String) -> ast::Param {
279 ast_from_text(&format!("fn f({}: {}) {{ }}", name, ty))
280}
281
282pub fn param_list(pats: impl IntoIterator<Item = ast::Param>) -> ast::ParamList {
283 let args = pats.into_iter().join(", ");
284 ast_from_text(&format!("fn f({}) {{ }}", args))
285}
286
287pub fn visibility_pub_crate() -> ast::Visibility {
288 ast_from_text("pub(crate) struct S")
289}
290
291pub fn fn_def(
292 visibility: Option<ast::Visibility>,
293 fn_name: ast::Name,
294 type_params: Option<ast::GenericParamList>,
295 params: ast::ParamList,
296 body: ast::BlockExpr,
297) -> ast::Fn {
298 let type_params =
299 if let Some(type_params) = type_params { format!("<{}>", type_params) } else { "".into() };
300 let visibility = match visibility {
301 None => String::new(),
302 Some(it) => format!("{} ", it),
303 };
304 ast_from_text(&format!("{}fn {}{}{} {}", visibility, fn_name, type_params, params, body))
305}
306
307fn ast_from_text<N: AstNode>(text: &str) -> N {
308 let parse = SourceFile::parse(text);
309 let node = match parse.tree().syntax().descendants().find_map(N::cast) {
310 Some(it) => it,
311 None => {
312 panic!("Failed to make ast node `{}` from text {}", std::any::type_name::<N>(), text)
313 }
314 };
315 let node = node.syntax().clone();
316 let node = unroot(node);
317 let node = N::cast(node).unwrap();
318 assert_eq!(node.syntax().text_range().start(), 0.into());
319 node
320}
321
322fn try_ast_from_text<N: AstNode>(text: &str) -> Option<N> {
323 let parse = SourceFile::parse(text);
324 let node = parse.tree().syntax().descendants().find_map(N::cast)?;
325 let node = node.syntax().clone();
326 let node = unroot(node);
327 let node = N::cast(node).unwrap();
328 assert_eq!(node.syntax().text_range().start(), 0.into());
329 Some(node)
330}
331
332fn unroot(n: SyntaxNode) -> SyntaxNode {
333 SyntaxNode::new_root(n.green().clone())
334}
335
336pub mod tokens {
337 use once_cell::sync::Lazy;
338
339 use crate::{ast, AstNode, Parse, SourceFile, SyntaxKind::*, SyntaxToken};
340
341 pub(super) static SOURCE_FILE: Lazy<Parse<SourceFile>> =
342 Lazy::new(|| SourceFile::parse("const C: <()>::Item = (1 != 1, 2 == 2, !true)\n;"));
343
344 pub fn single_space() -> SyntaxToken {
345 SOURCE_FILE
346 .tree()
347 .syntax()
348 .descendants_with_tokens()
349 .filter_map(|it| it.into_token())
350 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == " ")
351 .unwrap()
352 }
353
354 pub fn whitespace(text: &str) -> SyntaxToken {
355 assert!(text.trim().is_empty());
356 let sf = SourceFile::parse(text).ok().unwrap();
357 sf.syntax().first_child_or_token().unwrap().into_token().unwrap()
358 }
359
360 pub fn doc_comment(text: &str) -> SyntaxToken {
361 assert!(!text.trim().is_empty());
362 let sf = SourceFile::parse(text).ok().unwrap();
363 sf.syntax().first_child_or_token().unwrap().into_token().unwrap()
364 }
365
366 pub fn literal(text: &str) -> SyntaxToken {
367 assert_eq!(text.trim(), text);
368 let lit: ast::Literal = super::ast_from_text(&format!("fn f() {{ let _ = {}; }}", text));
369 lit.syntax().first_child_or_token().unwrap().into_token().unwrap()
370 }
371
372 pub fn single_newline() -> SyntaxToken {
373 SOURCE_FILE
374 .tree()
375 .syntax()
376 .descendants_with_tokens()
377 .filter_map(|it| it.into_token())
378 .find(|it| it.kind() == WHITESPACE && it.text().as_str() == "\n")
379 .unwrap()
380 }
381
382 pub struct WsBuilder(SourceFile);
383
384 impl WsBuilder {
385 pub fn new(text: &str) -> WsBuilder {
386 WsBuilder(SourceFile::parse(text).ok().unwrap())
387 }
388 pub fn ws(&self) -> SyntaxToken {
389 self.0.syntax().first_child_or_token().unwrap().into_token().unwrap()
390 }
391 }
392}
diff --git a/crates/ra_syntax/src/ast/node_ext.rs b/crates/ra_syntax/src/ast/node_ext.rs
deleted file mode 100644
index bba7310ad..000000000
--- a/crates/ra_syntax/src/ast/node_ext.rs
+++ /dev/null
@@ -1,505 +0,0 @@
1//! Various extension methods to ast Nodes, which are hard to code-generate.
2//! Extensions for various expressions live in a sibling `expr_extensions` module.
3
4use std::fmt;
5
6use itertools::Itertools;
7use ra_parser::SyntaxKind;
8
9use crate::{
10 ast::{self, support, AstNode, NameOwner, SyntaxNode},
11 SmolStr, SyntaxElement, SyntaxToken, T,
12};
13
14impl ast::Name {
15 pub fn text(&self) -> &SmolStr {
16 text_of_first_token(self.syntax())
17 }
18}
19
20impl ast::NameRef {
21 pub fn text(&self) -> &SmolStr {
22 text_of_first_token(self.syntax())
23 }
24
25 pub fn as_tuple_field(&self) -> Option<usize> {
26 self.text().parse().ok()
27 }
28}
29
30fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
31 node.green().children().next().and_then(|it| it.into_token()).unwrap().text()
32}
33
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub enum AttrKind {
36 Inner,
37 Outer,
38}
39
40impl ast::Attr {
41 pub fn as_simple_atom(&self) -> Option<SmolStr> {
42 if self.eq_token().is_some() || self.token_tree().is_some() {
43 return None;
44 }
45 self.simple_name()
46 }
47
48 pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
49 let tt = self.token_tree()?;
50 Some((self.simple_name()?, tt))
51 }
52
53 pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
54 let lit = self.literal()?;
55 let key = self.simple_name()?;
56 // FIXME: escape? raw string?
57 let value = lit.syntax().first_token()?.text().trim_matches('"').into();
58 Some((key, value))
59 }
60
61 pub fn simple_name(&self) -> Option<SmolStr> {
62 let path = self.path()?;
63 match (path.segment(), path.qualifier()) {
64 (Some(segment), None) => Some(segment.syntax().first_token()?.text().clone()),
65 _ => None,
66 }
67 }
68
69 pub fn kind(&self) -> AttrKind {
70 let first_token = self.syntax().first_token();
71 let first_token_kind = first_token.as_ref().map(SyntaxToken::kind);
72 let second_token_kind =
73 first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind);
74
75 match (first_token_kind, second_token_kind) {
76 (Some(SyntaxKind::POUND), Some(T![!])) => AttrKind::Inner,
77 _ => AttrKind::Outer,
78 }
79 }
80}
81
82#[derive(Debug, Clone, PartialEq, Eq)]
83pub enum PathSegmentKind {
84 Name(ast::NameRef),
85 Type { type_ref: Option<ast::TypeRef>, trait_ref: Option<ast::PathType> },
86 SelfKw,
87 SuperKw,
88 CrateKw,
89}
90
91impl ast::PathSegment {
92 pub fn parent_path(&self) -> ast::Path {
93 self.syntax()
94 .parent()
95 .and_then(ast::Path::cast)
96 .expect("segments are always nested in paths")
97 }
98
99 pub fn kind(&self) -> Option<PathSegmentKind> {
100 let res = if let Some(name_ref) = self.name_ref() {
101 PathSegmentKind::Name(name_ref)
102 } else {
103 match self.syntax().first_child_or_token()?.kind() {
104 T![self] => PathSegmentKind::SelfKw,
105 T![super] => PathSegmentKind::SuperKw,
106 T![crate] => PathSegmentKind::CrateKw,
107 T![<] => {
108 // <T> or <T as Trait>
109 // T is any TypeRef, Trait has to be a PathType
110 let mut type_refs =
111 self.syntax().children().filter(|node| ast::TypeRef::can_cast(node.kind()));
112 let type_ref = type_refs.next().and_then(ast::TypeRef::cast);
113 let trait_ref = type_refs.next().and_then(ast::PathType::cast);
114 PathSegmentKind::Type { type_ref, trait_ref }
115 }
116 _ => return None,
117 }
118 };
119 Some(res)
120 }
121}
122
123impl ast::Path {
124 pub fn parent_path(&self) -> Option<ast::Path> {
125 self.syntax().parent().and_then(ast::Path::cast)
126 }
127}
128
129impl ast::UseTreeList {
130 pub fn parent_use_tree(&self) -> ast::UseTree {
131 self.syntax()
132 .parent()
133 .and_then(ast::UseTree::cast)
134 .expect("UseTreeLists are always nested in UseTrees")
135 }
136}
137
138impl ast::Impl {
139 pub fn target_type(&self) -> Option<ast::TypeRef> {
140 match self.target() {
141 (Some(t), None) | (_, Some(t)) => Some(t),
142 _ => None,
143 }
144 }
145
146 pub fn target_trait(&self) -> Option<ast::TypeRef> {
147 match self.target() {
148 (Some(t), Some(_)) => Some(t),
149 _ => None,
150 }
151 }
152
153 fn target(&self) -> (Option<ast::TypeRef>, Option<ast::TypeRef>) {
154 let mut types = support::children(self.syntax());
155 let first = types.next();
156 let second = types.next();
157 (first, second)
158 }
159}
160
161#[derive(Debug, Clone, PartialEq, Eq)]
162pub enum StructKind {
163 Record(ast::RecordFieldList),
164 Tuple(ast::TupleFieldList),
165 Unit,
166}
167
168impl StructKind {
169 fn from_node<N: AstNode>(node: &N) -> StructKind {
170 if let Some(nfdl) = support::child::<ast::RecordFieldList>(node.syntax()) {
171 StructKind::Record(nfdl)
172 } else if let Some(pfl) = support::child::<ast::TupleFieldList>(node.syntax()) {
173 StructKind::Tuple(pfl)
174 } else {
175 StructKind::Unit
176 }
177 }
178}
179
180impl ast::Struct {
181 pub fn kind(&self) -> StructKind {
182 StructKind::from_node(self)
183 }
184}
185
186impl ast::RecordExprField {
187 pub fn for_field_name(field_name: &ast::NameRef) -> Option<ast::RecordExprField> {
188 let candidate =
189 field_name.syntax().parent().and_then(ast::RecordExprField::cast).or_else(|| {
190 field_name.syntax().ancestors().nth(4).and_then(ast::RecordExprField::cast)
191 })?;
192 if candidate.field_name().as_ref() == Some(field_name) {
193 Some(candidate)
194 } else {
195 None
196 }
197 }
198
199 /// Deals with field init shorthand
200 pub fn field_name(&self) -> Option<ast::NameRef> {
201 if let Some(name_ref) = self.name_ref() {
202 return Some(name_ref);
203 }
204 if let Some(ast::Expr::PathExpr(expr)) = self.expr() {
205 let path = expr.path()?;
206 let segment = path.segment()?;
207 let name_ref = segment.name_ref()?;
208 if path.qualifier().is_none() {
209 return Some(name_ref);
210 }
211 }
212 None
213 }
214}
215
216pub enum NameOrNameRef {
217 Name(ast::Name),
218 NameRef(ast::NameRef),
219}
220
221impl fmt::Display for NameOrNameRef {
222 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
223 match self {
224 NameOrNameRef::Name(it) => fmt::Display::fmt(it, f),
225 NameOrNameRef::NameRef(it) => fmt::Display::fmt(it, f),
226 }
227 }
228}
229
230impl ast::RecordFieldPat {
231 /// Deals with field init shorthand
232 pub fn field_name(&self) -> Option<NameOrNameRef> {
233 if let Some(name_ref) = self.name_ref() {
234 return Some(NameOrNameRef::NameRef(name_ref));
235 }
236 if let Some(ast::Pat::BindPat(pat)) = self.pat() {
237 let name = pat.name()?;
238 return Some(NameOrNameRef::Name(name));
239 }
240 None
241 }
242}
243
244impl ast::Variant {
245 pub fn parent_enum(&self) -> ast::Enum {
246 self.syntax()
247 .parent()
248 .and_then(|it| it.parent())
249 .and_then(ast::Enum::cast)
250 .expect("EnumVariants are always nested in Enums")
251 }
252 pub fn kind(&self) -> StructKind {
253 StructKind::from_node(self)
254 }
255}
256
257#[derive(Debug, Clone, PartialEq, Eq)]
258pub enum FieldKind {
259 Name(ast::NameRef),
260 Index(SyntaxToken),
261}
262
263impl ast::FieldExpr {
264 pub fn index_token(&self) -> Option<SyntaxToken> {
265 self.syntax
266 .children_with_tokens()
267 // FIXME: Accepting floats here to reject them in validation later
268 .find(|c| c.kind() == SyntaxKind::INT_NUMBER || c.kind() == SyntaxKind::FLOAT_NUMBER)
269 .as_ref()
270 .and_then(SyntaxElement::as_token)
271 .cloned()
272 }
273
274 pub fn field_access(&self) -> Option<FieldKind> {
275 if let Some(nr) = self.name_ref() {
276 Some(FieldKind::Name(nr))
277 } else if let Some(tok) = self.index_token() {
278 Some(FieldKind::Index(tok))
279 } else {
280 None
281 }
282 }
283}
284
285pub struct SlicePatComponents {
286 pub prefix: Vec<ast::Pat>,
287 pub slice: Option<ast::Pat>,
288 pub suffix: Vec<ast::Pat>,
289}
290
291impl ast::SlicePat {
292 pub fn components(&self) -> SlicePatComponents {
293 let mut args = self.args().peekable();
294 let prefix = args
295 .peeking_take_while(|p| match p {
296 ast::Pat::DotDotPat(_) => false,
297 ast::Pat::BindPat(bp) => match bp.pat() {
298 Some(ast::Pat::DotDotPat(_)) => false,
299 _ => true,
300 },
301 ast::Pat::RefPat(rp) => match rp.pat() {
302 Some(ast::Pat::DotDotPat(_)) => false,
303 Some(ast::Pat::BindPat(bp)) => match bp.pat() {
304 Some(ast::Pat::DotDotPat(_)) => false,
305 _ => true,
306 },
307 _ => true,
308 },
309 _ => true,
310 })
311 .collect();
312 let slice = args.next();
313 let suffix = args.collect();
314
315 SlicePatComponents { prefix, slice, suffix }
316 }
317}
318
319#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
320pub enum SelfParamKind {
321 /// self
322 Owned,
323 /// &self
324 Ref,
325 /// &mut self
326 MutRef,
327}
328
329impl ast::SelfParam {
330 pub fn kind(&self) -> SelfParamKind {
331 if self.amp_token().is_some() {
332 if self.mut_token().is_some() {
333 SelfParamKind::MutRef
334 } else {
335 SelfParamKind::Ref
336 }
337 } else {
338 SelfParamKind::Owned
339 }
340 }
341}
342
343#[derive(Clone, Debug, PartialEq, Eq, Hash)]
344pub enum TypeBoundKind {
345 /// Trait
346 PathType(ast::PathType),
347 /// for<'a> ...
348 ForType(ast::ForType),
349 /// 'a
350 Lifetime(SyntaxToken),
351}
352
353impl ast::TypeBound {
354 pub fn kind(&self) -> TypeBoundKind {
355 if let Some(path_type) = support::children(self.syntax()).next() {
356 TypeBoundKind::PathType(path_type)
357 } else if let Some(for_type) = support::children(self.syntax()).next() {
358 TypeBoundKind::ForType(for_type)
359 } else if let Some(lifetime) = self.lifetime_token() {
360 TypeBoundKind::Lifetime(lifetime)
361 } else {
362 unreachable!()
363 }
364 }
365
366 pub fn const_question_token(&self) -> Option<SyntaxToken> {
367 self.syntax()
368 .children_with_tokens()
369 .filter_map(|it| it.into_token())
370 .take_while(|it| it.kind() != T![const])
371 .find(|it| it.kind() == T![?])
372 }
373
374 pub fn question_token(&self) -> Option<SyntaxToken> {
375 if self.const_token().is_some() {
376 self.syntax()
377 .children_with_tokens()
378 .filter_map(|it| it.into_token())
379 .skip_while(|it| it.kind() != T![const])
380 .find(|it| it.kind() == T![?])
381 } else {
382 support::token(&self.syntax, T![?])
383 }
384 }
385}
386
387pub enum VisibilityKind {
388 In(ast::Path),
389 PubCrate,
390 PubSuper,
391 PubSelf,
392 Pub,
393}
394
395impl ast::Visibility {
396 pub fn kind(&self) -> VisibilityKind {
397 if let Some(path) = support::children(self.syntax()).next() {
398 VisibilityKind::In(path)
399 } else if self.crate_token().is_some() {
400 VisibilityKind::PubCrate
401 } else if self.super_token().is_some() {
402 VisibilityKind::PubSuper
403 } else if self.self_token().is_some() {
404 VisibilityKind::PubSelf
405 } else {
406 VisibilityKind::Pub
407 }
408 }
409}
410
411impl ast::MacroCall {
412 pub fn is_macro_rules(&self) -> Option<ast::Name> {
413 let name_ref = self.path()?.segment()?.name_ref()?;
414 if name_ref.text() == "macro_rules" {
415 self.name()
416 } else {
417 None
418 }
419 }
420
421 pub fn is_bang(&self) -> bool {
422 self.is_macro_rules().is_none()
423 }
424}
425
426impl ast::LifetimeParam {
427 pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> {
428 self.syntax()
429 .children_with_tokens()
430 .filter_map(|it| it.into_token())
431 .skip_while(|x| x.kind() != T![:])
432 .filter(|it| it.kind() == T![lifetime])
433 }
434}
435
436impl ast::RangePat {
437 pub fn start(&self) -> Option<ast::Pat> {
438 self.syntax()
439 .children_with_tokens()
440 .take_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
441 .filter_map(|it| it.into_node())
442 .find_map(ast::Pat::cast)
443 }
444
445 pub fn end(&self) -> Option<ast::Pat> {
446 self.syntax()
447 .children_with_tokens()
448 .skip_while(|it| !(it.kind() == T![..] || it.kind() == T![..=]))
449 .filter_map(|it| it.into_node())
450 .find_map(ast::Pat::cast)
451 }
452}
453
454impl ast::TokenTree {
455 pub fn left_delimiter_token(&self) -> Option<SyntaxToken> {
456 self.syntax()
457 .first_child_or_token()?
458 .into_token()
459 .filter(|it| matches!(it.kind(), T!['{'] | T!['('] | T!['[']))
460 }
461
462 pub fn right_delimiter_token(&self) -> Option<SyntaxToken> {
463 self.syntax()
464 .last_child_or_token()?
465 .into_token()
466 .filter(|it| matches!(it.kind(), T!['}'] | T![')'] | T![']']))
467 }
468}
469
470impl ast::GenericParamList {
471 pub fn lifetime_params(&self) -> impl Iterator<Item = ast::LifetimeParam> {
472 self.generic_params().filter_map(|param| match param {
473 ast::GenericParam::LifetimeParam(it) => Some(it),
474 ast::GenericParam::TypeParam(_) | ast::GenericParam::ConstParam(_) => None,
475 })
476 }
477 pub fn type_params(&self) -> impl Iterator<Item = ast::TypeParam> {
478 self.generic_params().filter_map(|param| match param {
479 ast::GenericParam::TypeParam(it) => Some(it),
480 ast::GenericParam::LifetimeParam(_) | ast::GenericParam::ConstParam(_) => None,
481 })
482 }
483 pub fn const_params(&self) -> impl Iterator<Item = ast::ConstParam> {
484 self.generic_params().filter_map(|param| match param {
485 ast::GenericParam::ConstParam(it) => Some(it),
486 ast::GenericParam::TypeParam(_) | ast::GenericParam::LifetimeParam(_) => None,
487 })
488 }
489}
490
491impl ast::DocCommentsOwner for ast::SourceFile {}
492impl ast::DocCommentsOwner for ast::Fn {}
493impl ast::DocCommentsOwner for ast::Struct {}
494impl ast::DocCommentsOwner for ast::Union {}
495impl ast::DocCommentsOwner for ast::RecordField {}
496impl ast::DocCommentsOwner for ast::TupleField {}
497impl ast::DocCommentsOwner for ast::Enum {}
498impl ast::DocCommentsOwner for ast::Variant {}
499impl ast::DocCommentsOwner for ast::Trait {}
500impl ast::DocCommentsOwner for ast::Module {}
501impl ast::DocCommentsOwner for ast::Static {}
502impl ast::DocCommentsOwner for ast::Const {}
503impl ast::DocCommentsOwner for ast::TypeAlias {}
504impl ast::DocCommentsOwner for ast::Impl {}
505impl ast::DocCommentsOwner for ast::MacroCall {}
diff --git a/crates/ra_syntax/src/ast/token_ext.rs b/crates/ra_syntax/src/ast/token_ext.rs
deleted file mode 100644
index c5ef92733..000000000
--- a/crates/ra_syntax/src/ast/token_ext.rs
+++ /dev/null
@@ -1,538 +0,0 @@
1//! There are many AstNodes, but only a few tokens, so we hand-write them here.
2
3use std::{
4 borrow::Cow,
5 convert::{TryFrom, TryInto},
6};
7
8use rustc_lexer::unescape::{unescape_literal, Mode};
9
10use crate::{
11 ast::{AstToken, Comment, RawString, String, Whitespace},
12 TextRange, TextSize,
13};
14
15impl Comment {
16 pub fn kind(&self) -> CommentKind {
17 kind_by_prefix(self.text())
18 }
19
20 pub fn prefix(&self) -> &'static str {
21 for (prefix, k) in COMMENT_PREFIX_TO_KIND.iter() {
22 if *k == self.kind() && self.text().starts_with(prefix) {
23 return prefix;
24 }
25 }
26 unreachable!()
27 }
28}
29
30#[derive(Debug, PartialEq, Eq, Clone, Copy)]
31pub struct CommentKind {
32 pub shape: CommentShape,
33 pub doc: Option<CommentPlacement>,
34}
35
36#[derive(Debug, PartialEq, Eq, Clone, Copy)]
37pub enum CommentShape {
38 Line,
39 Block,
40}
41
42impl CommentShape {
43 pub fn is_line(self) -> bool {
44 self == CommentShape::Line
45 }
46
47 pub fn is_block(self) -> bool {
48 self == CommentShape::Block
49 }
50}
51
52#[derive(Debug, PartialEq, Eq, Clone, Copy)]
53pub enum CommentPlacement {
54 Inner,
55 Outer,
56}
57
58const COMMENT_PREFIX_TO_KIND: &[(&str, CommentKind)] = {
59 use {CommentPlacement::*, CommentShape::*};
60 &[
61 ("////", CommentKind { shape: Line, doc: None }),
62 ("///", CommentKind { shape: Line, doc: Some(Outer) }),
63 ("//!", CommentKind { shape: Line, doc: Some(Inner) }),
64 ("/**", CommentKind { shape: Block, doc: Some(Outer) }),
65 ("/*!", CommentKind { shape: Block, doc: Some(Inner) }),
66 ("//", CommentKind { shape: Line, doc: None }),
67 ("/*", CommentKind { shape: Block, doc: None }),
68 ]
69};
70
71fn kind_by_prefix(text: &str) -> CommentKind {
72 if text == "/**/" {
73 return CommentKind { shape: CommentShape::Block, doc: None };
74 }
75 for (prefix, kind) in COMMENT_PREFIX_TO_KIND.iter() {
76 if text.starts_with(prefix) {
77 return *kind;
78 }
79 }
80 panic!("bad comment text: {:?}", text)
81}
82
83impl Whitespace {
84 pub fn spans_multiple_lines(&self) -> bool {
85 let text = self.text();
86 text.find('\n').map_or(false, |idx| text[idx + 1..].contains('\n'))
87 }
88}
89
90pub struct QuoteOffsets {
91 pub quotes: (TextRange, TextRange),
92 pub contents: TextRange,
93}
94
95impl QuoteOffsets {
96 fn new(literal: &str) -> Option<QuoteOffsets> {
97 let left_quote = literal.find('"')?;
98 let right_quote = literal.rfind('"')?;
99 if left_quote == right_quote {
100 // `literal` only contains one quote
101 return None;
102 }
103
104 let start = TextSize::from(0);
105 let left_quote = TextSize::try_from(left_quote).unwrap() + TextSize::of('"');
106 let right_quote = TextSize::try_from(right_quote).unwrap();
107 let end = TextSize::of(literal);
108
109 let res = QuoteOffsets {
110 quotes: (TextRange::new(start, left_quote), TextRange::new(right_quote, end)),
111 contents: TextRange::new(left_quote, right_quote),
112 };
113 Some(res)
114 }
115}
116
117pub trait HasQuotes: AstToken {
118 fn quote_offsets(&self) -> Option<QuoteOffsets> {
119 let text = self.text().as_str();
120 let offsets = QuoteOffsets::new(text)?;
121 let o = self.syntax().text_range().start();
122 let offsets = QuoteOffsets {
123 quotes: (offsets.quotes.0 + o, offsets.quotes.1 + o),
124 contents: offsets.contents + o,
125 };
126 Some(offsets)
127 }
128 fn open_quote_text_range(&self) -> Option<TextRange> {
129 self.quote_offsets().map(|it| it.quotes.0)
130 }
131
132 fn close_quote_text_range(&self) -> Option<TextRange> {
133 self.quote_offsets().map(|it| it.quotes.1)
134 }
135
136 fn text_range_between_quotes(&self) -> Option<TextRange> {
137 self.quote_offsets().map(|it| it.contents)
138 }
139}
140
141impl HasQuotes for String {}
142impl HasQuotes for RawString {}
143
144pub trait HasStringValue: HasQuotes {
145 fn value(&self) -> Option<Cow<'_, str>>;
146}
147
148impl HasStringValue for String {
149 fn value(&self) -> Option<Cow<'_, str>> {
150 let text = self.text().as_str();
151 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
152
153 let mut buf = std::string::String::with_capacity(text.len());
154 let mut has_error = false;
155 unescape_literal(text, Mode::Str, &mut |_, unescaped_char| match unescaped_char {
156 Ok(c) => buf.push(c),
157 Err(_) => has_error = true,
158 });
159
160 if has_error {
161 return None;
162 }
163 // FIXME: don't actually allocate for borrowed case
164 let res = if buf == text { Cow::Borrowed(text) } else { Cow::Owned(buf) };
165 Some(res)
166 }
167}
168
169impl HasStringValue for RawString {
170 fn value(&self) -> Option<Cow<'_, str>> {
171 let text = self.text().as_str();
172 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
173 Some(Cow::Borrowed(text))
174 }
175}
176
177impl RawString {
178 pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> {
179 let contents_range = self.text_range_between_quotes()?;
180 assert!(TextRange::up_to(contents_range.len()).contains_range(range));
181 Some(range + contents_range.start())
182 }
183}
184
185#[derive(Debug)]
186pub enum FormatSpecifier {
187 Open,
188 Close,
189 Integer,
190 Identifier,
191 Colon,
192 Fill,
193 Align,
194 Sign,
195 NumberSign,
196 Zero,
197 DollarSign,
198 Dot,
199 Asterisk,
200 QuestionMark,
201}
202
203pub trait HasFormatSpecifier: AstToken {
204 fn char_ranges(
205 &self,
206 ) -> Option<Vec<(TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>>;
207
208 fn lex_format_specifier<F>(&self, mut callback: F)
209 where
210 F: FnMut(TextRange, FormatSpecifier),
211 {
212 let char_ranges = if let Some(char_ranges) = self.char_ranges() {
213 char_ranges
214 } else {
215 return;
216 };
217 let mut chars = char_ranges.iter().peekable();
218
219 while let Some((range, first_char)) = chars.next() {
220 match first_char {
221 Ok('{') => {
222 // Format specifier, see syntax at https://doc.rust-lang.org/std/fmt/index.html#syntax
223 if let Some((_, Ok('{'))) = chars.peek() {
224 // Escaped format specifier, `{{`
225 chars.next();
226 continue;
227 }
228
229 callback(*range, FormatSpecifier::Open);
230
231 // check for integer/identifier
232 match chars
233 .peek()
234 .and_then(|next| next.1.as_ref().ok())
235 .copied()
236 .unwrap_or_default()
237 {
238 '0'..='9' => {
239 // integer
240 read_integer(&mut chars, &mut callback);
241 }
242 c if c == '_' || c.is_alphabetic() => {
243 // identifier
244 read_identifier(&mut chars, &mut callback);
245 }
246 _ => {}
247 }
248
249 if let Some((_, Ok(':'))) = chars.peek() {
250 skip_char_and_emit(&mut chars, FormatSpecifier::Colon, &mut callback);
251
252 // check for fill/align
253 let mut cloned = chars.clone().take(2);
254 let first = cloned
255 .next()
256 .and_then(|next| next.1.as_ref().ok())
257 .copied()
258 .unwrap_or_default();
259 let second = cloned
260 .next()
261 .and_then(|next| next.1.as_ref().ok())
262 .copied()
263 .unwrap_or_default();
264 match second {
265 '<' | '^' | '>' => {
266 // alignment specifier, first char specifies fillment
267 skip_char_and_emit(
268 &mut chars,
269 FormatSpecifier::Fill,
270 &mut callback,
271 );
272 skip_char_and_emit(
273 &mut chars,
274 FormatSpecifier::Align,
275 &mut callback,
276 );
277 }
278 _ => match first {
279 '<' | '^' | '>' => {
280 skip_char_and_emit(
281 &mut chars,
282 FormatSpecifier::Align,
283 &mut callback,
284 );
285 }
286 _ => {}
287 },
288 }
289
290 // check for sign
291 match chars
292 .peek()
293 .and_then(|next| next.1.as_ref().ok())
294 .copied()
295 .unwrap_or_default()
296 {
297 '+' | '-' => {
298 skip_char_and_emit(
299 &mut chars,
300 FormatSpecifier::Sign,
301 &mut callback,
302 );
303 }
304 _ => {}
305 }
306
307 // check for `#`
308 if let Some((_, Ok('#'))) = chars.peek() {
309 skip_char_and_emit(
310 &mut chars,
311 FormatSpecifier::NumberSign,
312 &mut callback,
313 );
314 }
315
316 // check for `0`
317 let mut cloned = chars.clone().take(2);
318 let first = cloned.next().and_then(|next| next.1.as_ref().ok()).copied();
319 let second = cloned.next().and_then(|next| next.1.as_ref().ok()).copied();
320
321 if first == Some('0') && second != Some('$') {
322 skip_char_and_emit(&mut chars, FormatSpecifier::Zero, &mut callback);
323 }
324
325 // width
326 match chars
327 .peek()
328 .and_then(|next| next.1.as_ref().ok())
329 .copied()
330 .unwrap_or_default()
331 {
332 '0'..='9' => {
333 read_integer(&mut chars, &mut callback);
334 if let Some((_, Ok('$'))) = chars.peek() {
335 skip_char_and_emit(
336 &mut chars,
337 FormatSpecifier::DollarSign,
338 &mut callback,
339 );
340 }
341 }
342 c if c == '_' || c.is_alphabetic() => {
343 read_identifier(&mut chars, &mut callback);
344 // can be either width (indicated by dollar sign, or type in which case
345 // the next sign has to be `}`)
346 let next =
347 chars.peek().and_then(|next| next.1.as_ref().ok()).copied();
348 match next {
349 Some('$') => skip_char_and_emit(
350 &mut chars,
351 FormatSpecifier::DollarSign,
352 &mut callback,
353 ),
354 Some('}') => {
355 skip_char_and_emit(
356 &mut chars,
357 FormatSpecifier::Close,
358 &mut callback,
359 );
360 continue;
361 }
362 _ => continue,
363 };
364 }
365 _ => {}
366 }
367
368 // precision
369 if let Some((_, Ok('.'))) = chars.peek() {
370 skip_char_and_emit(&mut chars, FormatSpecifier::Dot, &mut callback);
371
372 match chars
373 .peek()
374 .and_then(|next| next.1.as_ref().ok())
375 .copied()
376 .unwrap_or_default()
377 {
378 '*' => {
379 skip_char_and_emit(
380 &mut chars,
381 FormatSpecifier::Asterisk,
382 &mut callback,
383 );
384 }
385 '0'..='9' => {
386 read_integer(&mut chars, &mut callback);
387 if let Some((_, Ok('$'))) = chars.peek() {
388 skip_char_and_emit(
389 &mut chars,
390 FormatSpecifier::DollarSign,
391 &mut callback,
392 );
393 }
394 }
395 c if c == '_' || c.is_alphabetic() => {
396 read_identifier(&mut chars, &mut callback);
397 if chars.peek().and_then(|next| next.1.as_ref().ok()).copied()
398 != Some('$')
399 {
400 continue;
401 }
402 skip_char_and_emit(
403 &mut chars,
404 FormatSpecifier::DollarSign,
405 &mut callback,
406 );
407 }
408 _ => {
409 continue;
410 }
411 }
412 }
413
414 // type
415 match chars
416 .peek()
417 .and_then(|next| next.1.as_ref().ok())
418 .copied()
419 .unwrap_or_default()
420 {
421 '?' => {
422 skip_char_and_emit(
423 &mut chars,
424 FormatSpecifier::QuestionMark,
425 &mut callback,
426 );
427 }
428 c if c == '_' || c.is_alphabetic() => {
429 read_identifier(&mut chars, &mut callback);
430 }
431 _ => {}
432 }
433 }
434
435 if let Some((_, Ok('}'))) = chars.peek() {
436 skip_char_and_emit(&mut chars, FormatSpecifier::Close, &mut callback);
437 } else {
438 continue;
439 }
440 }
441 _ => {
442 while let Some((_, Ok(next_char))) = chars.peek() {
443 match next_char {
444 '{' => break,
445 _ => {}
446 }
447 chars.next();
448 }
449 }
450 };
451 }
452
453 fn skip_char_and_emit<'a, I, F>(
454 chars: &mut std::iter::Peekable<I>,
455 emit: FormatSpecifier,
456 callback: &mut F,
457 ) where
458 I: Iterator<Item = &'a (TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>,
459 F: FnMut(TextRange, FormatSpecifier),
460 {
461 let (range, _) = chars.next().unwrap();
462 callback(*range, emit);
463 }
464
465 fn read_integer<'a, I, F>(chars: &mut std::iter::Peekable<I>, callback: &mut F)
466 where
467 I: Iterator<Item = &'a (TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>,
468 F: FnMut(TextRange, FormatSpecifier),
469 {
470 let (mut range, c) = chars.next().unwrap();
471 assert!(c.as_ref().unwrap().is_ascii_digit());
472 while let Some((r, Ok(next_char))) = chars.peek() {
473 if next_char.is_ascii_digit() {
474 chars.next();
475 range = range.cover(*r);
476 } else {
477 break;
478 }
479 }
480 callback(range, FormatSpecifier::Integer);
481 }
482
483 fn read_identifier<'a, I, F>(chars: &mut std::iter::Peekable<I>, callback: &mut F)
484 where
485 I: Iterator<Item = &'a (TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>,
486 F: FnMut(TextRange, FormatSpecifier),
487 {
488 let (mut range, c) = chars.next().unwrap();
489 assert!(c.as_ref().unwrap().is_alphabetic() || *c.as_ref().unwrap() == '_');
490 while let Some((r, Ok(next_char))) = chars.peek() {
491 if *next_char == '_' || next_char.is_ascii_digit() || next_char.is_alphabetic() {
492 chars.next();
493 range = range.cover(*r);
494 } else {
495 break;
496 }
497 }
498 callback(range, FormatSpecifier::Identifier);
499 }
500 }
501}
502
503impl HasFormatSpecifier for String {
504 fn char_ranges(
505 &self,
506 ) -> Option<Vec<(TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>> {
507 let text = self.text().as_str();
508 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
509 let offset = self.text_range_between_quotes()?.start() - self.syntax().text_range().start();
510
511 let mut res = Vec::with_capacity(text.len());
512 unescape_literal(text, Mode::Str, &mut |range, unescaped_char| {
513 res.push((
514 TextRange::new(range.start.try_into().unwrap(), range.end.try_into().unwrap())
515 + offset,
516 unescaped_char,
517 ))
518 });
519
520 Some(res)
521 }
522}
523
524impl HasFormatSpecifier for RawString {
525 fn char_ranges(
526 &self,
527 ) -> Option<Vec<(TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>> {
528 let text = self.text().as_str();
529 let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
530 let offset = self.text_range_between_quotes()?.start() - self.syntax().text_range().start();
531
532 let mut res = Vec::with_capacity(text.len());
533 for (idx, c) in text.char_indices() {
534 res.push((TextRange::at(idx.try_into().unwrap(), TextSize::of(c)) + offset, Ok(c)));
535 }
536 Some(res)
537 }
538}
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
deleted file mode 100644
index 3a56b1674..000000000
--- a/crates/ra_syntax/src/ast/traits.rs
+++ /dev/null
@@ -1,142 +0,0 @@
1//! Various traits that are implemented by ast nodes.
2//!
3//! The implementations are usually trivial, and live in generated.rs
4use stdx::SepBy;
5
6use crate::{
7 ast::{self, support, AstChildren, AstNode, AstToken},
8 syntax_node::SyntaxElementChildren,
9 SyntaxToken, T,
10};
11
12pub trait NameOwner: AstNode {
13 fn name(&self) -> Option<ast::Name> {
14 support::child(self.syntax())
15 }
16}
17
18pub trait VisibilityOwner: AstNode {
19 fn visibility(&self) -> Option<ast::Visibility> {
20 support::child(self.syntax())
21 }
22}
23
24pub trait LoopBodyOwner: AstNode {
25 fn loop_body(&self) -> Option<ast::BlockExpr> {
26 support::child(self.syntax())
27 }
28
29 fn label(&self) -> Option<ast::Label> {
30 support::child(self.syntax())
31 }
32}
33
34pub trait ArgListOwner: AstNode {
35 fn arg_list(&self) -> Option<ast::ArgList> {
36 support::child(self.syntax())
37 }
38}
39
40pub trait ModuleItemOwner: AstNode {
41 fn items(&self) -> AstChildren<ast::Item> {
42 support::children(self.syntax())
43 }
44}
45
46pub trait GenericParamsOwner: AstNode {
47 fn generic_param_list(&self) -> Option<ast::GenericParamList> {
48 support::child(self.syntax())
49 }
50
51 fn where_clause(&self) -> Option<ast::WhereClause> {
52 support::child(self.syntax())
53 }
54}
55
56pub trait TypeBoundsOwner: AstNode {
57 fn type_bound_list(&self) -> Option<ast::TypeBoundList> {
58 support::child(self.syntax())
59 }
60
61 fn colon_token(&self) -> Option<SyntaxToken> {
62 support::token(self.syntax(), T![:])
63 }
64}
65
66pub trait AttrsOwner: AstNode {
67 fn attrs(&self) -> AstChildren<ast::Attr> {
68 support::children(self.syntax())
69 }
70 fn has_atom_attr(&self, atom: &str) -> bool {
71 self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom)
72 }
73}
74
75pub trait DocCommentsOwner: AstNode {
76 fn doc_comments(&self) -> CommentIter {
77 CommentIter { iter: self.syntax().children_with_tokens() }
78 }
79
80 fn doc_comment_text(&self) -> Option<String> {
81 self.doc_comments().doc_comment_text()
82 }
83}
84
85impl CommentIter {
86 pub fn from_syntax_node(syntax_node: &ast::SyntaxNode) -> CommentIter {
87 CommentIter { iter: syntax_node.children_with_tokens() }
88 }
89
90 /// Returns the textual content of a doc comment block as a single string.
91 /// That is, strips leading `///` (+ optional 1 character of whitespace),
92 /// trailing `*/`, trailing whitespace and then joins the lines.
93 pub fn doc_comment_text(self) -> Option<String> {
94 let mut has_comments = false;
95 let docs = self
96 .filter(|comment| comment.kind().doc.is_some())
97 .map(|comment| {
98 has_comments = true;
99 let prefix_len = comment.prefix().len();
100
101 let line: &str = comment.text().as_str();
102
103 // Determine if the prefix or prefix + 1 char is stripped
104 let pos =
105 if let Some(ws) = line.chars().nth(prefix_len).filter(|c| c.is_whitespace()) {
106 prefix_len + ws.len_utf8()
107 } else {
108 prefix_len
109 };
110
111 let end = if comment.kind().shape.is_block() && line.ends_with("*/") {
112 line.len() - 2
113 } else {
114 line.len()
115 };
116
117 // Note that we do not trim the end of the line here
118 // since whitespace can have special meaning at the end
119 // of a line in markdown.
120 line[pos..end].to_owned()
121 })
122 .sep_by("\n")
123 .to_string();
124
125 if has_comments {
126 Some(docs)
127 } else {
128 None
129 }
130 }
131}
132
133pub struct CommentIter {
134 iter: SyntaxElementChildren,
135}
136
137impl Iterator for CommentIter {
138 type Item = ast::Comment;
139 fn next(&mut self) -> Option<ast::Comment> {
140 self.iter.by_ref().find_map(|el| el.into_token().and_then(ast::Comment::cast))
141 }
142}
diff --git a/crates/ra_syntax/src/fuzz.rs b/crates/ra_syntax/src/fuzz.rs
deleted file mode 100644
index 39f9b12ab..000000000
--- a/crates/ra_syntax/src/fuzz.rs
+++ /dev/null
@@ -1,73 +0,0 @@
1//! FIXME: write short doc here
2
3use std::{
4 convert::TryInto,
5 str::{self, FromStr},
6};
7
8use ra_text_edit::Indel;
9
10use crate::{validation, AstNode, SourceFile, TextRange};
11
12fn check_file_invariants(file: &SourceFile) {
13 let root = file.syntax();
14 validation::validate_block_structure(root);
15}
16
17pub fn check_parser(text: &str) {
18 let file = SourceFile::parse(text);
19 check_file_invariants(&file.tree());
20}
21
22#[derive(Debug, Clone)]
23pub struct CheckReparse {
24 text: String,
25 edit: Indel,
26 edited_text: String,
27}
28
29impl CheckReparse {
30 pub fn from_data(data: &[u8]) -> Option<Self> {
31 const PREFIX: &str = "fn main(){\n\t";
32 const SUFFIX: &str = "\n}";
33
34 let data = str::from_utf8(data).ok()?;
35 let mut lines = data.lines();
36 let delete_start = usize::from_str(lines.next()?).ok()? + PREFIX.len();
37 let delete_len = usize::from_str(lines.next()?).ok()?;
38 let insert = lines.next()?.to_string();
39 let text = lines.collect::<Vec<_>>().join("\n");
40 let text = format!("{}{}{}", PREFIX, text, SUFFIX);
41 text.get(delete_start..delete_start.checked_add(delete_len)?)?; // make sure delete is a valid range
42 let delete =
43 TextRange::at(delete_start.try_into().unwrap(), delete_len.try_into().unwrap());
44 let edited_text =
45 format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]);
46 let edit = Indel { delete, insert };
47 Some(CheckReparse { text, edit, edited_text })
48 }
49
50 pub fn run(&self) {
51 let parse = SourceFile::parse(&self.text);
52 let new_parse = parse.reparse(&self.edit);
53 check_file_invariants(&new_parse.tree());
54 assert_eq!(&new_parse.tree().syntax().text().to_string(), &self.edited_text);
55 let full_reparse = SourceFile::parse(&self.edited_text);
56 for (a, b) in
57 new_parse.tree().syntax().descendants().zip(full_reparse.tree().syntax().descendants())
58 {
59 if (a.kind(), a.text_range()) != (b.kind(), b.text_range()) {
60 eprint!("original:\n{:#?}", parse.tree().syntax());
61 eprint!("reparsed:\n{:#?}", new_parse.tree().syntax());
62 eprint!("full reparse:\n{:#?}", full_reparse.tree().syntax());
63 assert_eq!(
64 format!("{:?}", a),
65 format!("{:?}", b),
66 "different syntax tree produced by the full reparse"
67 );
68 }
69 }
70 // FIXME
71 // assert_eq!(new_file.errors(), full_reparse.errors());
72 }
73}
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
deleted file mode 100644
index 6203b6206..000000000
--- a/crates/ra_syntax/src/lib.rs
+++ /dev/null
@@ -1,388 +0,0 @@
1//! Syntax Tree library used throughout the rust analyzer.
2//!
3//! Properties:
4//! - easy and fast incremental re-parsing
5//! - graceful handling of errors
6//! - full-fidelity representation (*any* text can be precisely represented as
7//! a syntax tree)
8//!
9//! For more information, see the [RFC]. Current implementation is inspired by
10//! the [Swift] one.
11//!
12//! The most interesting modules here are `syntax_node` (which defines concrete
13//! syntax tree) and `ast` (which defines abstract syntax tree on top of the
14//! CST). The actual parser live in a separate `ra_parser` crate, though the
15//! lexer lives in this crate.
16//!
17//! See `api_walkthrough` test in this file for a quick API tour!
18//!
19//! [RFC]: <https://github.com/rust-lang/rfcs/pull/2256>
20//! [Swift]: <https://github.com/apple/swift/blob/13d593df6f359d0cb2fc81cfaac273297c539455/lib/Syntax/README.md>
21
22#[allow(unused)]
23macro_rules! eprintln {
24 ($($tt:tt)*) => { stdx::eprintln!($($tt)*) };
25}
26
27mod syntax_node;
28mod syntax_error;
29mod parsing;
30mod validation;
31mod ptr;
32#[cfg(test)]
33mod tests;
34
35pub mod algo;
36pub mod ast;
37#[doc(hidden)]
38pub mod fuzz;
39
40use std::{marker::PhantomData, sync::Arc};
41
42use ra_text_edit::Indel;
43use stdx::format_to;
44
45pub use crate::{
46 algo::InsertPosition,
47 ast::{AstNode, AstToken},
48 parsing::{lex_single_syntax_kind, lex_single_valid_syntax_kind, tokenize, Token},
49 ptr::{AstPtr, SyntaxNodePtr},
50 syntax_error::SyntaxError,
51 syntax_node::{
52 Direction, GreenNode, NodeOrToken, SyntaxElement, SyntaxElementChildren, SyntaxNode,
53 SyntaxNodeChildren, SyntaxToken, SyntaxTreeBuilder,
54 },
55};
56pub use ra_parser::{SyntaxKind, T};
57pub use rowan::{SmolStr, SyntaxText, TextRange, TextSize, TokenAtOffset, WalkEvent};
58
59/// `Parse` is the result of the parsing: a syntax tree and a collection of
60/// errors.
61///
62/// Note that we always produce a syntax tree, even for completely invalid
63/// files.
64#[derive(Debug, PartialEq, Eq)]
65pub struct Parse<T> {
66 green: GreenNode,
67 errors: Arc<Vec<SyntaxError>>,
68 _ty: PhantomData<fn() -> T>,
69}
70
71impl<T> Clone for Parse<T> {
72 fn clone(&self) -> Parse<T> {
73 Parse { green: self.green.clone(), errors: self.errors.clone(), _ty: PhantomData }
74 }
75}
76
77impl<T> Parse<T> {
78 fn new(green: GreenNode, errors: Vec<SyntaxError>) -> Parse<T> {
79 Parse { green, errors: Arc::new(errors), _ty: PhantomData }
80 }
81
82 pub fn syntax_node(&self) -> SyntaxNode {
83 SyntaxNode::new_root(self.green.clone())
84 }
85}
86
87impl<T: AstNode> Parse<T> {
88 pub fn to_syntax(self) -> Parse<SyntaxNode> {
89 Parse { green: self.green, errors: self.errors, _ty: PhantomData }
90 }
91
92 pub fn tree(&self) -> T {
93 T::cast(self.syntax_node()).unwrap()
94 }
95
96 pub fn errors(&self) -> &[SyntaxError] {
97 &*self.errors
98 }
99
100 pub fn ok(self) -> Result<T, Arc<Vec<SyntaxError>>> {
101 if self.errors.is_empty() {
102 Ok(self.tree())
103 } else {
104 Err(self.errors)
105 }
106 }
107}
108
109impl Parse<SyntaxNode> {
110 pub fn cast<N: AstNode>(self) -> Option<Parse<N>> {
111 if N::cast(self.syntax_node()).is_some() {
112 Some(Parse { green: self.green, errors: self.errors, _ty: PhantomData })
113 } else {
114 None
115 }
116 }
117}
118
119impl Parse<SourceFile> {
120 pub fn debug_dump(&self) -> String {
121 let mut buf = format!("{:#?}", self.tree().syntax());
122 for err in self.errors.iter() {
123 format_to!(buf, "error {:?}: {}\n", err.range(), err);
124 }
125 buf
126 }
127
128 pub fn reparse(&self, indel: &Indel) -> Parse<SourceFile> {
129 self.incremental_reparse(indel).unwrap_or_else(|| self.full_reparse(indel))
130 }
131
132 fn incremental_reparse(&self, indel: &Indel) -> Option<Parse<SourceFile>> {
133 // FIXME: validation errors are not handled here
134 parsing::incremental_reparse(self.tree().syntax(), indel, self.errors.to_vec()).map(
135 |(green_node, errors, _reparsed_range)| Parse {
136 green: green_node,
137 errors: Arc::new(errors),
138 _ty: PhantomData,
139 },
140 )
141 }
142
143 fn full_reparse(&self, indel: &Indel) -> Parse<SourceFile> {
144 let mut text = self.tree().syntax().text().to_string();
145 indel.apply(&mut text);
146 SourceFile::parse(&text)
147 }
148}
149
150/// `SourceFile` represents a parse tree for a single Rust file.
151pub use crate::ast::SourceFile;
152
153impl SourceFile {
154 pub fn parse(text: &str) -> Parse<SourceFile> {
155 let (green, mut errors) = parsing::parse_text(text);
156 let root = SyntaxNode::new_root(green.clone());
157
158 if cfg!(debug_assertions) {
159 validation::validate_block_structure(&root);
160 }
161
162 errors.extend(validation::validate(&root));
163
164 assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE);
165 Parse { green, errors: Arc::new(errors), _ty: PhantomData }
166 }
167}
168
169impl ast::Path {
170 /// Returns `text`, parsed as a path, but only if it has no errors.
171 pub fn parse(text: &str) -> Result<Self, ()> {
172 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Path)
173 }
174}
175
176impl ast::Pat {
177 /// Returns `text`, parsed as a pattern, but only if it has no errors.
178 pub fn parse(text: &str) -> Result<Self, ()> {
179 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Pattern)
180 }
181}
182
183impl ast::Expr {
184 /// Returns `text`, parsed as an expression, but only if it has no errors.
185 pub fn parse(text: &str) -> Result<Self, ()> {
186 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Expr)
187 }
188}
189
190impl ast::Item {
191 /// Returns `text`, parsed as an item, but only if it has no errors.
192 pub fn parse(text: &str) -> Result<Self, ()> {
193 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Item)
194 }
195}
196
197impl ast::TypeRef {
198 /// Returns `text`, parsed as an type reference, but only if it has no errors.
199 pub fn parse(text: &str) -> Result<Self, ()> {
200 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Type)
201 }
202}
203
204/// Matches a `SyntaxNode` against an `ast` type.
205///
206/// # Example:
207///
208/// ```ignore
209/// match_ast! {
210/// match node {
211/// ast::CallExpr(it) => { ... },
212/// ast::MethodCallExpr(it) => { ... },
213/// ast::MacroCall(it) => { ... },
214/// _ => None,
215/// }
216/// }
217/// ```
218#[macro_export]
219macro_rules! match_ast {
220 (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) };
221
222 (match ($node:expr) {
223 $( ast::$ast:ident($it:ident) => $res:expr, )*
224 _ => $catch_all:expr $(,)?
225 }) => {{
226 $( if let Some($it) = ast::$ast::cast($node.clone()) { $res } else )*
227 { $catch_all }
228 }};
229}
230
231/// This test does not assert anything and instead just shows off the crate's
232/// API.
233#[test]
234fn api_walkthrough() {
235 use ast::{ModuleItemOwner, NameOwner};
236
237 let source_code = "
238 fn foo() {
239 1 + 1
240 }
241 ";
242 // `SourceFile` is the main entry point.
243 //
244 // The `parse` method returns a `Parse` -- a pair of syntax tree and a list
245 // of errors. That is, syntax tree is constructed even in presence of errors.
246 let parse = SourceFile::parse(source_code);
247 assert!(parse.errors().is_empty());
248
249 // The `tree` method returns an owned syntax node of type `SourceFile`.
250 // Owned nodes are cheap: inside, they are `Rc` handles to the underling data.
251 let file: SourceFile = parse.tree();
252
253 // `SourceFile` is the root of the syntax tree. We can iterate file's items.
254 // Let's fetch the `foo` function.
255 let mut func = None;
256 for item in file.items() {
257 match item {
258 ast::Item::Fn(f) => func = Some(f),
259 _ => unreachable!(),
260 }
261 }
262 let func: ast::Fn = func.unwrap();
263
264 // Each AST node has a bunch of getters for children. All getters return
265 // `Option`s though, to account for incomplete code. Some getters are common
266 // for several kinds of node. In this case, a trait like `ast::NameOwner`
267 // usually exists. By convention, all ast types should be used with `ast::`
268 // qualifier.
269 let name: Option<ast::Name> = func.name();
270 let name = name.unwrap();
271 assert_eq!(name.text(), "foo");
272
273 // Let's get the `1 + 1` expression!
274 let body: ast::BlockExpr = func.body().unwrap();
275 let expr: ast::Expr = body.expr().unwrap();
276
277 // Enums are used to group related ast nodes together, and can be used for
278 // matching. However, because there are no public fields, it's possible to
279 // match only the top level enum: that is the price we pay for increased API
280 // flexibility
281 let bin_expr: &ast::BinExpr = match &expr {
282 ast::Expr::BinExpr(e) => e,
283 _ => unreachable!(),
284 };
285
286 // Besides the "typed" AST API, there's an untyped CST one as well.
287 // To switch from AST to CST, call `.syntax()` method:
288 let expr_syntax: &SyntaxNode = expr.syntax();
289
290 // Note how `expr` and `bin_expr` are in fact the same node underneath:
291 assert!(expr_syntax == bin_expr.syntax());
292
293 // To go from CST to AST, `AstNode::cast` function is used:
294 let _expr: ast::Expr = match ast::Expr::cast(expr_syntax.clone()) {
295 Some(e) => e,
296 None => unreachable!(),
297 };
298
299 // The two properties each syntax node has is a `SyntaxKind`:
300 assert_eq!(expr_syntax.kind(), SyntaxKind::BIN_EXPR);
301
302 // And text range:
303 assert_eq!(expr_syntax.text_range(), TextRange::new(32.into(), 37.into()));
304
305 // You can get node's text as a `SyntaxText` object, which will traverse the
306 // tree collecting token's text:
307 let text: SyntaxText = expr_syntax.text();
308 assert_eq!(text.to_string(), "1 + 1");
309
310 // There's a bunch of traversal methods on `SyntaxNode`:
311 assert_eq!(expr_syntax.parent().as_ref(), Some(body.syntax()));
312 assert_eq!(body.syntax().first_child_or_token().map(|it| it.kind()), Some(T!['{']));
313 assert_eq!(
314 expr_syntax.next_sibling_or_token().map(|it| it.kind()),
315 Some(SyntaxKind::WHITESPACE)
316 );
317
318 // As well as some iterator helpers:
319 let f = expr_syntax.ancestors().find_map(ast::Fn::cast);
320 assert_eq!(f, Some(func));
321 assert!(expr_syntax.siblings_with_tokens(Direction::Next).any(|it| it.kind() == T!['}']));
322 assert_eq!(
323 expr_syntax.descendants_with_tokens().count(),
324 8, // 5 tokens `1`, ` `, `+`, ` `, `!`
325 // 2 child literal expressions: `1`, `1`
326 // 1 the node itself: `1 + 1`
327 );
328
329 // There's also a `preorder` method with a more fine-grained iteration control:
330 let mut buf = String::new();
331 let mut indent = 0;
332 for event in expr_syntax.preorder_with_tokens() {
333 match event {
334 WalkEvent::Enter(node) => {
335 let text = match &node {
336 NodeOrToken::Node(it) => it.text().to_string(),
337 NodeOrToken::Token(it) => it.text().to_string(),
338 };
339 format_to!(buf, "{:indent$}{:?} {:?}\n", " ", text, node.kind(), indent = indent);
340 indent += 2;
341 }
342 WalkEvent::Leave(_) => indent -= 2,
343 }
344 }
345 assert_eq!(indent, 0);
346 assert_eq!(
347 buf.trim(),
348 r#"
349"1 + 1" BIN_EXPR
350 "1" LITERAL
351 "1" INT_NUMBER
352 " " WHITESPACE
353 "+" PLUS
354 " " WHITESPACE
355 "1" LITERAL
356 "1" INT_NUMBER
357"#
358 .trim()
359 );
360
361 // To recursively process the tree, there are three approaches:
362 // 1. explicitly call getter methods on AST nodes.
363 // 2. use descendants and `AstNode::cast`.
364 // 3. use descendants and `match_ast!`.
365 //
366 // Here's how the first one looks like:
367 let exprs_cast: Vec<String> = file
368 .syntax()
369 .descendants()
370 .filter_map(ast::Expr::cast)
371 .map(|expr| expr.syntax().text().to_string())
372 .collect();
373
374 // An alternative is to use a macro.
375 let mut exprs_visit = Vec::new();
376 for node in file.syntax().descendants() {
377 match_ast! {
378 match node {
379 ast::Expr(it) => {
380 let res = it.syntax().text().to_string();
381 exprs_visit.push(res);
382 },
383 _ => (),
384 }
385 }
386 }
387 assert_eq!(exprs_cast, exprs_visit);
388}
diff --git a/crates/ra_syntax/src/parsing.rs b/crates/ra_syntax/src/parsing.rs
deleted file mode 100644
index 0ed3c20ef..000000000
--- a/crates/ra_syntax/src/parsing.rs
+++ /dev/null
@@ -1,59 +0,0 @@
1//! Lexing, bridging to ra_parser (which does the actual parsing) and
2//! incremental reparsing.
3
4mod lexer;
5mod text_token_source;
6mod text_tree_sink;
7mod reparsing;
8
9use crate::{syntax_node::GreenNode, AstNode, SyntaxError, SyntaxNode};
10use text_token_source::TextTokenSource;
11use text_tree_sink::TextTreeSink;
12
13pub use lexer::*;
14
15pub(crate) use self::reparsing::incremental_reparse;
16use ra_parser::SyntaxKind;
17
18pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) {
19 let (tokens, lexer_errors) = tokenize(&text);
20
21 let mut token_source = TextTokenSource::new(text, &tokens);
22 let mut tree_sink = TextTreeSink::new(text, &tokens);
23
24 ra_parser::parse(&mut token_source, &mut tree_sink);
25
26 let (tree, mut parser_errors) = tree_sink.finish();
27 parser_errors.extend(lexer_errors);
28
29 (tree, parser_errors)
30}
31
32/// Returns `text` parsed as a `T` provided there are no parse errors.
33pub(crate) fn parse_text_fragment<T: AstNode>(
34 text: &str,
35 fragment_kind: ra_parser::FragmentKind,
36) -> Result<T, ()> {
37 let (tokens, lexer_errors) = tokenize(&text);
38 if !lexer_errors.is_empty() {
39 return Err(());
40 }
41
42 let mut token_source = TextTokenSource::new(text, &tokens);
43 let mut tree_sink = TextTreeSink::new(text, &tokens);
44
45 // TextTreeSink assumes that there's at least some root node to which it can attach errors and
46 // tokens. We arbitrarily give it a SourceFile.
47 use ra_parser::TreeSink;
48 tree_sink.start_node(SyntaxKind::SOURCE_FILE);
49 ra_parser::parse_fragment(&mut token_source, &mut tree_sink, fragment_kind);
50 tree_sink.finish_node();
51
52 let (tree, parser_errors) = tree_sink.finish();
53 use ra_parser::TokenSource;
54 if !parser_errors.is_empty() || token_source.current().kind != SyntaxKind::EOF {
55 return Err(());
56 }
57
58 SyntaxNode::new_root(tree).first_child().and_then(T::cast).ok_or(())
59}
diff --git a/crates/ra_syntax/src/parsing/lexer.rs b/crates/ra_syntax/src/parsing/lexer.rs
deleted file mode 100644
index fa3be1016..000000000
--- a/crates/ra_syntax/src/parsing/lexer.rs
+++ /dev/null
@@ -1,244 +0,0 @@
1//! Lexer analyzes raw input string and produces lexemes (tokens).
2//! It is just a bridge to `rustc_lexer`.
3
4use rustc_lexer::{LiteralKind as LK, RawStrError};
5
6use std::convert::TryInto;
7
8use crate::{
9 SyntaxError,
10 SyntaxKind::{self, *},
11 TextRange, TextSize, T,
12};
13
14/// A token of Rust source.
15#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
16pub struct Token {
17 /// The kind of token.
18 pub kind: SyntaxKind,
19 /// The length of the token.
20 pub len: TextSize,
21}
22
23/// Break a string up into its component tokens.
24/// Beware that it checks for shebang first and its length contributes to resulting
25/// tokens offsets.
26pub fn tokenize(text: &str) -> (Vec<Token>, Vec<SyntaxError>) {
27 // non-empty string is a precondtion of `rustc_lexer::strip_shebang()`.
28 if text.is_empty() {
29 return Default::default();
30 }
31
32 let mut tokens = Vec::new();
33 let mut errors = Vec::new();
34
35 let mut offset = match rustc_lexer::strip_shebang(text) {
36 Some(shebang_len) => {
37 tokens.push(Token { kind: SHEBANG, len: shebang_len.try_into().unwrap() });
38 shebang_len
39 }
40 None => 0,
41 };
42
43 let text_without_shebang = &text[offset..];
44
45 for rustc_token in rustc_lexer::tokenize(text_without_shebang) {
46 let token_len: TextSize = rustc_token.len.try_into().unwrap();
47 let token_range = TextRange::at(offset.try_into().unwrap(), token_len);
48
49 let (syntax_kind, err_message) =
50 rustc_token_kind_to_syntax_kind(&rustc_token.kind, &text[token_range]);
51
52 tokens.push(Token { kind: syntax_kind, len: token_len });
53
54 if let Some(err_message) = err_message {
55 errors.push(SyntaxError::new(err_message, token_range));
56 }
57
58 offset += rustc_token.len;
59 }
60
61 (tokens, errors)
62}
63
64/// Returns `SyntaxKind` and `Option<SyntaxError>` of the first token
65/// encountered at the beginning of the string.
66///
67/// Returns `None` if the string contains zero *or two or more* tokens.
68/// The token is malformed if the returned error is not `None`.
69///
70/// Beware that unescape errors are not checked at tokenization time.
71pub fn lex_single_syntax_kind(text: &str) -> Option<(SyntaxKind, Option<SyntaxError>)> {
72 lex_first_token(text)
73 .filter(|(token, _)| token.len == TextSize::of(text))
74 .map(|(token, error)| (token.kind, error))
75}
76
77/// The same as `lex_single_syntax_kind()` but returns only `SyntaxKind` and
78/// returns `None` if any tokenization error occured.
79///
80/// Beware that unescape errors are not checked at tokenization time.
81pub fn lex_single_valid_syntax_kind(text: &str) -> Option<SyntaxKind> {
82 lex_first_token(text)
83 .filter(|(token, error)| !error.is_some() && token.len == TextSize::of(text))
84 .map(|(token, _error)| token.kind)
85}
86
87/// Returns `SyntaxKind` and `Option<SyntaxError>` of the first token
88/// encountered at the beginning of the string.
89///
90/// Returns `None` if the string contains zero tokens or if the token was parsed
91/// with an error.
92/// The token is malformed if the returned error is not `None`.
93///
94/// Beware that unescape errors are not checked at tokenization time.
95fn lex_first_token(text: &str) -> Option<(Token, Option<SyntaxError>)> {
96 // non-empty string is a precondtion of `rustc_lexer::first_token()`.
97 if text.is_empty() {
98 return None;
99 }
100
101 let rustc_token = rustc_lexer::first_token(text);
102 let (syntax_kind, err_message) = rustc_token_kind_to_syntax_kind(&rustc_token.kind, text);
103
104 let token = Token { kind: syntax_kind, len: rustc_token.len.try_into().unwrap() };
105 let optional_error = err_message
106 .map(|err_message| SyntaxError::new(err_message, TextRange::up_to(TextSize::of(text))));
107
108 Some((token, optional_error))
109}
110
111/// Returns `SyntaxKind` and an optional tokenize error message.
112fn rustc_token_kind_to_syntax_kind(
113 rustc_token_kind: &rustc_lexer::TokenKind,
114 token_text: &str,
115) -> (SyntaxKind, Option<&'static str>) {
116 // A note on an intended tradeoff:
117 // We drop some useful infromation here (see patterns with double dots `..`)
118 // Storing that info in `SyntaxKind` is not possible due to its layout requirements of
119 // being `u16` that come from `rowan::SyntaxKind`.
120
121 let syntax_kind = {
122 match rustc_token_kind {
123 rustc_lexer::TokenKind::LineComment => COMMENT,
124
125 rustc_lexer::TokenKind::BlockComment { terminated: true } => COMMENT,
126 rustc_lexer::TokenKind::BlockComment { terminated: false } => {
127 return (
128 COMMENT,
129 Some("Missing trailing `*/` symbols to terminate the block comment"),
130 );
131 }
132
133 rustc_lexer::TokenKind::Whitespace => WHITESPACE,
134
135 rustc_lexer::TokenKind::Ident => {
136 if token_text == "_" {
137 UNDERSCORE
138 } else {
139 SyntaxKind::from_keyword(token_text).unwrap_or(IDENT)
140 }
141 }
142
143 rustc_lexer::TokenKind::RawIdent => IDENT,
144 rustc_lexer::TokenKind::Literal { kind, .. } => return match_literal_kind(&kind),
145
146 rustc_lexer::TokenKind::Lifetime { starts_with_number: false } => LIFETIME,
147 rustc_lexer::TokenKind::Lifetime { starts_with_number: true } => {
148 return (LIFETIME, Some("Lifetime name cannot start with a number"))
149 }
150
151 rustc_lexer::TokenKind::Semi => T![;],
152 rustc_lexer::TokenKind::Comma => T![,],
153 rustc_lexer::TokenKind::Dot => T![.],
154 rustc_lexer::TokenKind::OpenParen => T!['('],
155 rustc_lexer::TokenKind::CloseParen => T![')'],
156 rustc_lexer::TokenKind::OpenBrace => T!['{'],
157 rustc_lexer::TokenKind::CloseBrace => T!['}'],
158 rustc_lexer::TokenKind::OpenBracket => T!['['],
159 rustc_lexer::TokenKind::CloseBracket => T![']'],
160 rustc_lexer::TokenKind::At => T![@],
161 rustc_lexer::TokenKind::Pound => T![#],
162 rustc_lexer::TokenKind::Tilde => T![~],
163 rustc_lexer::TokenKind::Question => T![?],
164 rustc_lexer::TokenKind::Colon => T![:],
165 rustc_lexer::TokenKind::Dollar => T![$],
166 rustc_lexer::TokenKind::Eq => T![=],
167 rustc_lexer::TokenKind::Not => T![!],
168 rustc_lexer::TokenKind::Lt => T![<],
169 rustc_lexer::TokenKind::Gt => T![>],
170 rustc_lexer::TokenKind::Minus => T![-],
171 rustc_lexer::TokenKind::And => T![&],
172 rustc_lexer::TokenKind::Or => T![|],
173 rustc_lexer::TokenKind::Plus => T![+],
174 rustc_lexer::TokenKind::Star => T![*],
175 rustc_lexer::TokenKind::Slash => T![/],
176 rustc_lexer::TokenKind::Caret => T![^],
177 rustc_lexer::TokenKind::Percent => T![%],
178 rustc_lexer::TokenKind::Unknown => ERROR,
179 }
180 };
181
182 return (syntax_kind, None);
183
184 fn match_literal_kind(kind: &rustc_lexer::LiteralKind) -> (SyntaxKind, Option<&'static str>) {
185 #[rustfmt::skip]
186 let syntax_kind = match *kind {
187 LK::Int { empty_int: false, .. } => INT_NUMBER,
188 LK::Int { empty_int: true, .. } => {
189 return (INT_NUMBER, Some("Missing digits after the integer base prefix"))
190 }
191
192 LK::Float { empty_exponent: false, .. } => FLOAT_NUMBER,
193 LK::Float { empty_exponent: true, .. } => {
194 return (FLOAT_NUMBER, Some("Missing digits after the exponent symbol"))
195 }
196
197 LK::Char { terminated: true } => CHAR,
198 LK::Char { terminated: false } => {
199 return (CHAR, Some("Missing trailing `'` symbol to terminate the character literal"))
200 }
201
202 LK::Byte { terminated: true } => BYTE,
203 LK::Byte { terminated: false } => {
204 return (BYTE, Some("Missing trailing `'` symbol to terminate the byte literal"))
205 }
206
207 LK::Str { terminated: true } => STRING,
208 LK::Str { terminated: false } => {
209 return (STRING, Some("Missing trailing `\"` symbol to terminate the string literal"))
210 }
211
212
213 LK::ByteStr { terminated: true } => BYTE_STRING,
214 LK::ByteStr { terminated: false } => {
215 return (BYTE_STRING, Some("Missing trailing `\"` symbol to terminate the byte string literal"))
216 }
217
218 LK::RawStr { err, .. } => match err {
219 None => RAW_STRING,
220 Some(RawStrError::InvalidStarter { .. }) => return (RAW_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw string literal")),
221 Some(RawStrError::NoTerminator { expected, found, .. }) => if expected == found {
222 return (RAW_STRING, Some("Missing trailing `\"` to terminate the raw string literal"))
223 } else {
224 return (RAW_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw string literal"))
225
226 },
227 Some(RawStrError::TooManyDelimiters { .. }) => return (RAW_STRING, Some("Too many `#` symbols: raw strings may be delimited by up to 65535 `#` symbols")),
228 },
229 LK::RawByteStr { err, .. } => match err {
230 None => RAW_BYTE_STRING,
231 Some(RawStrError::InvalidStarter { .. }) => return (RAW_BYTE_STRING, Some("Missing `\"` symbol after `#` symbols to begin the raw byte string literal")),
232 Some(RawStrError::NoTerminator { expected, found, .. }) => if expected == found {
233 return (RAW_BYTE_STRING, Some("Missing trailing `\"` to terminate the raw byte string literal"))
234 } else {
235 return (RAW_BYTE_STRING, Some("Missing trailing `\"` with `#` symbols to terminate the raw byte string literal"))
236
237 },
238 Some(RawStrError::TooManyDelimiters { .. }) => return (RAW_BYTE_STRING, Some("Too many `#` symbols: raw byte strings may be delimited by up to 65535 `#` symbols")),
239 },
240 };
241
242 (syntax_kind, None)
243 }
244}
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs
deleted file mode 100644
index ed5a42ea3..000000000
--- a/crates/ra_syntax/src/parsing/reparsing.rs
+++ /dev/null
@@ -1,455 +0,0 @@
1//! Implementation of incremental re-parsing.
2//!
3//! We use two simple strategies for this:
4//! - if the edit modifies only a single token (like changing an identifier's
5//! letter), we replace only this token.
6//! - otherwise, we search for the nearest `{}` block which contains the edit
7//! and try to parse only this block.
8
9use ra_parser::Reparser;
10use ra_text_edit::Indel;
11
12use crate::{
13 algo,
14 parsing::{
15 lexer::{lex_single_syntax_kind, tokenize, Token},
16 text_token_source::TextTokenSource,
17 text_tree_sink::TextTreeSink,
18 },
19 syntax_node::{GreenNode, GreenToken, NodeOrToken, SyntaxElement, SyntaxNode},
20 SyntaxError,
21 SyntaxKind::*,
22 TextRange, TextSize, T,
23};
24
25pub(crate) fn incremental_reparse(
26 node: &SyntaxNode,
27 edit: &Indel,
28 errors: Vec<SyntaxError>,
29) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> {
30 if let Some((green, new_errors, old_range)) = reparse_token(node, &edit) {
31 return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range));
32 }
33
34 if let Some((green, new_errors, old_range)) = reparse_block(node, &edit) {
35 return Some((green, merge_errors(errors, new_errors, old_range, edit), old_range));
36 }
37 None
38}
39
40fn reparse_token<'node>(
41 root: &'node SyntaxNode,
42 edit: &Indel,
43) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> {
44 let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone();
45 let prev_token_kind = prev_token.kind();
46 match prev_token_kind {
47 WHITESPACE | COMMENT | IDENT | STRING | RAW_STRING => {
48 if prev_token_kind == WHITESPACE || prev_token_kind == COMMENT {
49 // removing a new line may extends previous token
50 let deleted_range = edit.delete - prev_token.text_range().start();
51 if prev_token.text()[deleted_range].contains('\n') {
52 return None;
53 }
54 }
55
56 let mut new_text = get_text_after_edit(prev_token.clone().into(), &edit);
57 let (new_token_kind, new_err) = lex_single_syntax_kind(&new_text)?;
58
59 if new_token_kind != prev_token_kind
60 || (new_token_kind == IDENT && is_contextual_kw(&new_text))
61 {
62 return None;
63 }
64
65 // Check that edited token is not a part of the bigger token.
66 // E.g. if for source code `bruh"str"` the user removed `ruh`, then
67 // `b` no longer remains an identifier, but becomes a part of byte string literal
68 if let Some(next_char) = root.text().char_at(prev_token.text_range().end()) {
69 new_text.push(next_char);
70 let token_with_next_char = lex_single_syntax_kind(&new_text);
71 if let Some((_kind, _error)) = token_with_next_char {
72 return None;
73 }
74 new_text.pop();
75 }
76
77 let new_token =
78 GreenToken::new(rowan::SyntaxKind(prev_token_kind.into()), new_text.into());
79 Some((
80 prev_token.replace_with(new_token),
81 new_err.into_iter().collect(),
82 prev_token.text_range(),
83 ))
84 }
85 _ => None,
86 }
87}
88
89fn reparse_block<'node>(
90 root: &'node SyntaxNode,
91 edit: &Indel,
92) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> {
93 let (node, reparser) = find_reparsable_node(root, edit.delete)?;
94 let text = get_text_after_edit(node.clone().into(), edit);
95
96 let (tokens, new_lexer_errors) = tokenize(&text);
97 if !is_balanced(&tokens) {
98 return None;
99 }
100
101 let mut token_source = TextTokenSource::new(&text, &tokens);
102 let mut tree_sink = TextTreeSink::new(&text, &tokens);
103 reparser.parse(&mut token_source, &mut tree_sink);
104
105 let (green, mut new_parser_errors) = tree_sink.finish();
106 new_parser_errors.extend(new_lexer_errors);
107
108 Some((node.replace_with(green), new_parser_errors, node.text_range()))
109}
110
111fn get_text_after_edit(element: SyntaxElement, edit: &Indel) -> String {
112 let edit = Indel::replace(edit.delete - element.text_range().start(), edit.insert.clone());
113
114 let mut text = match element {
115 NodeOrToken::Token(token) => token.text().to_string(),
116 NodeOrToken::Node(node) => node.text().to_string(),
117 };
118 edit.apply(&mut text);
119 text
120}
121
122fn is_contextual_kw(text: &str) -> bool {
123 matches!(text, "auto" | "default" | "union")
124}
125
126fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(SyntaxNode, Reparser)> {
127 let node = algo::find_covering_element(node, range);
128
129 let mut ancestors = match node {
130 NodeOrToken::Token(it) => it.parent().ancestors(),
131 NodeOrToken::Node(it) => it.ancestors(),
132 };
133 ancestors.find_map(|node| {
134 let first_child = node.first_child_or_token().map(|it| it.kind());
135 let parent = node.parent().map(|it| it.kind());
136 Reparser::for_node(node.kind(), first_child, parent).map(|r| (node, r))
137 })
138}
139
140fn is_balanced(tokens: &[Token]) -> bool {
141 if tokens.is_empty()
142 || tokens.first().unwrap().kind != T!['{']
143 || tokens.last().unwrap().kind != T!['}']
144 {
145 return false;
146 }
147 let mut balance = 0usize;
148 for t in &tokens[1..tokens.len() - 1] {
149 match t.kind {
150 T!['{'] => balance += 1,
151 T!['}'] => {
152 balance = match balance.checked_sub(1) {
153 Some(b) => b,
154 None => return false,
155 }
156 }
157 _ => (),
158 }
159 }
160 balance == 0
161}
162
163fn merge_errors(
164 old_errors: Vec<SyntaxError>,
165 new_errors: Vec<SyntaxError>,
166 range_before_reparse: TextRange,
167 edit: &Indel,
168) -> Vec<SyntaxError> {
169 let mut res = Vec::new();
170
171 for old_err in old_errors {
172 let old_err_range = old_err.range();
173 if old_err_range.end() <= range_before_reparse.start() {
174 res.push(old_err);
175 } else if old_err_range.start() >= range_before_reparse.end() {
176 let inserted_len = TextSize::of(&edit.insert);
177 res.push(old_err.with_range((old_err_range + inserted_len) - edit.delete.len()));
178 // Note: extra parens are intentional to prevent uint underflow, HWAB (here was a bug)
179 }
180 }
181 res.extend(new_errors.into_iter().map(|new_err| {
182 // fighting borrow checker with a variable ;)
183 let offseted_range = new_err.range() + range_before_reparse.start();
184 new_err.with_range(offseted_range)
185 }));
186 res
187}
188
189#[cfg(test)]
190mod tests {
191 use test_utils::{assert_eq_text, extract_range};
192
193 use super::*;
194 use crate::{AstNode, Parse, SourceFile};
195
196 fn do_check(before: &str, replace_with: &str, reparsed_len: u32) {
197 let (range, before) = extract_range(before);
198 let edit = Indel::replace(range, replace_with.to_owned());
199 let after = {
200 let mut after = before.clone();
201 edit.apply(&mut after);
202 after
203 };
204
205 let fully_reparsed = SourceFile::parse(&after);
206 let incrementally_reparsed: Parse<SourceFile> = {
207 let before = SourceFile::parse(&before);
208 let (green, new_errors, range) =
209 incremental_reparse(before.tree().syntax(), &edit, before.errors.to_vec()).unwrap();
210 assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length");
211 Parse::new(green, new_errors)
212 };
213
214 assert_eq_text!(
215 &format!("{:#?}", fully_reparsed.tree().syntax()),
216 &format!("{:#?}", incrementally_reparsed.tree().syntax()),
217 );
218 assert_eq!(fully_reparsed.errors(), incrementally_reparsed.errors());
219 }
220
221 #[test] // FIXME: some test here actually test token reparsing
222 fn reparse_block_tests() {
223 do_check(
224 r"
225fn foo() {
226 let x = foo + <|>bar<|>
227}
228",
229 "baz",
230 3,
231 );
232 do_check(
233 r"
234fn foo() {
235 let x = foo<|> + bar<|>
236}
237",
238 "baz",
239 25,
240 );
241 do_check(
242 r"
243struct Foo {
244 f: foo<|><|>
245}
246",
247 ",\n g: (),",
248 14,
249 );
250 do_check(
251 r"
252fn foo {
253 let;
254 1 + 1;
255 <|>92<|>;
256}
257",
258 "62",
259 31, // FIXME: reparse only int literal here
260 );
261 do_check(
262 r"
263mod foo {
264 fn <|><|>
265}
266",
267 "bar",
268 11,
269 );
270
271 do_check(
272 r"
273trait Foo {
274 type <|>Foo<|>;
275}
276",
277 "Output",
278 3,
279 );
280 do_check(
281 r"
282impl IntoIterator<Item=i32> for Foo {
283 f<|><|>
284}
285",
286 "n next(",
287 9,
288 );
289 do_check(r"use a::b::{foo,<|>,bar<|>};", "baz", 10);
290 do_check(
291 r"
292pub enum A {
293 Foo<|><|>
294}
295",
296 "\nBar;\n",
297 11,
298 );
299 do_check(
300 r"
301foo!{a, b<|><|> d}
302",
303 ", c[3]",
304 8,
305 );
306 do_check(
307 r"
308fn foo() {
309 vec![<|><|>]
310}
311",
312 "123",
313 14,
314 );
315 do_check(
316 r"
317extern {
318 fn<|>;<|>
319}
320",
321 " exit(code: c_int)",
322 11,
323 );
324 }
325
326 #[test]
327 fn reparse_token_tests() {
328 do_check(
329 r"<|><|>
330fn foo() -> i32 { 1 }
331",
332 "\n\n\n \n",
333 1,
334 );
335 do_check(
336 r"
337fn foo() -> <|><|> {}
338",
339 " \n",
340 2,
341 );
342 do_check(
343 r"
344fn <|>foo<|>() -> i32 { 1 }
345",
346 "bar",
347 3,
348 );
349 do_check(
350 r"
351fn foo<|><|>foo() { }
352",
353 "bar",
354 6,
355 );
356 do_check(
357 r"
358fn foo /* <|><|> */ () {}
359",
360 "some comment",
361 6,
362 );
363 do_check(
364 r"
365fn baz <|><|> () {}
366",
367 " \t\t\n\n",
368 2,
369 );
370 do_check(
371 r"
372fn baz <|><|> () {}
373",
374 " \t\t\n\n",
375 2,
376 );
377 do_check(
378 r"
379/// foo <|><|>omment
380mod { }
381",
382 "c",
383 14,
384 );
385 do_check(
386 r#"
387fn -> &str { "Hello<|><|>" }
388"#,
389 ", world",
390 7,
391 );
392 do_check(
393 r#"
394fn -> &str { // "Hello<|><|>"
395"#,
396 ", world",
397 10,
398 );
399 do_check(
400 r##"
401fn -> &str { r#"Hello<|><|>"#
402"##,
403 ", world",
404 10,
405 );
406 do_check(
407 r"
408#[derive(<|>Copy<|>)]
409enum Foo {
410
411}
412",
413 "Clone",
414 4,
415 );
416 }
417
418 #[test]
419 fn reparse_str_token_with_error_unchanged() {
420 do_check(r#""<|>Unclosed<|> string literal"#, "Still unclosed", 24);
421 }
422
423 #[test]
424 fn reparse_str_token_with_error_fixed() {
425 do_check(r#""unterinated<|><|>"#, "\"", 12);
426 }
427
428 #[test]
429 fn reparse_block_with_error_in_middle_unchanged() {
430 do_check(
431 r#"fn main() {
432 if {}
433 32 + 4<|><|>
434 return
435 if {}
436 }"#,
437 "23",
438 105,
439 )
440 }
441
442 #[test]
443 fn reparse_block_with_error_in_middle_fixed() {
444 do_check(
445 r#"fn main() {
446 if {}
447 32 + 4<|><|>
448 return
449 if {}
450 }"#,
451 ";",
452 105,
453 )
454 }
455}
diff --git a/crates/ra_syntax/src/parsing/text_token_source.rs b/crates/ra_syntax/src/parsing/text_token_source.rs
deleted file mode 100644
index 97aa3e795..000000000
--- a/crates/ra_syntax/src/parsing/text_token_source.rs
+++ /dev/null
@@ -1,84 +0,0 @@
1//! See `TextTokenSource` docs.
2
3use ra_parser::TokenSource;
4
5use crate::{parsing::lexer::Token, SyntaxKind::EOF, TextRange, TextSize};
6
7/// Implementation of `ra_parser::TokenSource` that takes tokens from source code text.
8pub(crate) struct TextTokenSource<'t> {
9 text: &'t str,
10 /// token and its start position (non-whitespace/comment tokens)
11 /// ```non-rust
12 /// struct Foo;
13 /// ^------^--^-
14 /// | | \________
15 /// | \____ \
16 /// | \ |
17 /// (struct, 0) (Foo, 7) (;, 10)
18 /// ```
19 /// `[(struct, 0), (Foo, 7), (;, 10)]`
20 token_offset_pairs: Vec<(Token, TextSize)>,
21
22 /// Current token and position
23 curr: (ra_parser::Token, usize),
24}
25
26impl<'t> TokenSource for TextTokenSource<'t> {
27 fn current(&self) -> ra_parser::Token {
28 self.curr.0
29 }
30
31 fn lookahead_nth(&self, n: usize) -> ra_parser::Token {
32 mk_token(self.curr.1 + n, &self.token_offset_pairs)
33 }
34
35 fn bump(&mut self) {
36 if self.curr.0.kind == EOF {
37 return;
38 }
39
40 let pos = self.curr.1 + 1;
41 self.curr = (mk_token(pos, &self.token_offset_pairs), pos);
42 }
43
44 fn is_keyword(&self, kw: &str) -> bool {
45 self.token_offset_pairs
46 .get(self.curr.1)
47 .map(|(token, offset)| &self.text[TextRange::at(*offset, token.len)] == kw)
48 .unwrap_or(false)
49 }
50}
51
52fn mk_token(pos: usize, token_offset_pairs: &[(Token, TextSize)]) -> ra_parser::Token {
53 let (kind, is_jointed_to_next) = match token_offset_pairs.get(pos) {
54 Some((token, offset)) => (
55 token.kind,
56 token_offset_pairs
57 .get(pos + 1)
58 .map(|(_, next_offset)| offset + token.len == *next_offset)
59 .unwrap_or(false),
60 ),
61 None => (EOF, false),
62 };
63 ra_parser::Token { kind, is_jointed_to_next }
64}
65
66impl<'t> TextTokenSource<'t> {
67 /// Generate input from tokens(expect comment and whitespace).
68 pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> TextTokenSource<'t> {
69 let token_offset_pairs: Vec<_> = raw_tokens
70 .iter()
71 .filter_map({
72 let mut len = 0.into();
73 move |token| {
74 let pair = if token.kind.is_trivia() { None } else { Some((*token, len)) };
75 len += token.len;
76 pair
77 }
78 })
79 .collect();
80
81 let first = mk_token(0, &token_offset_pairs);
82 TextTokenSource { text, token_offset_pairs, curr: (first, 0) }
83 }
84}
diff --git a/crates/ra_syntax/src/parsing/text_tree_sink.rs b/crates/ra_syntax/src/parsing/text_tree_sink.rs
deleted file mode 100644
index 6d1828d20..000000000
--- a/crates/ra_syntax/src/parsing/text_tree_sink.rs
+++ /dev/null
@@ -1,183 +0,0 @@
1//! FIXME: write short doc here
2
3use std::mem;
4
5use ra_parser::{ParseError, TreeSink};
6
7use crate::{
8 parsing::Token,
9 syntax_node::GreenNode,
10 SmolStr, SyntaxError,
11 SyntaxKind::{self, *},
12 SyntaxTreeBuilder, TextRange, TextSize,
13};
14
15/// Bridges the parser with our specific syntax tree representation.
16///
17/// `TextTreeSink` also handles attachment of trivia (whitespace) to nodes.
18pub(crate) struct TextTreeSink<'a> {
19 text: &'a str,
20 tokens: &'a [Token],
21 text_pos: TextSize,
22 token_pos: usize,
23 state: State,
24 inner: SyntaxTreeBuilder,
25}
26
27enum State {
28 PendingStart,
29 Normal,
30 PendingFinish,
31}
32
33impl<'a> TreeSink for TextTreeSink<'a> {
34 fn token(&mut self, kind: SyntaxKind, n_tokens: u8) {
35 match mem::replace(&mut self.state, State::Normal) {
36 State::PendingStart => unreachable!(),
37 State::PendingFinish => self.inner.finish_node(),
38 State::Normal => (),
39 }
40 self.eat_trivias();
41 let n_tokens = n_tokens as usize;
42 let len = self.tokens[self.token_pos..self.token_pos + n_tokens]
43 .iter()
44 .map(|it| it.len)
45 .sum::<TextSize>();
46 self.do_token(kind, len, n_tokens);
47 }
48
49 fn start_node(&mut self, kind: SyntaxKind) {
50 match mem::replace(&mut self.state, State::Normal) {
51 State::PendingStart => {
52 self.inner.start_node(kind);
53 // No need to attach trivias to previous node: there is no
54 // previous node.
55 return;
56 }
57 State::PendingFinish => self.inner.finish_node(),
58 State::Normal => (),
59 }
60
61 let n_trivias =
62 self.tokens[self.token_pos..].iter().take_while(|it| it.kind.is_trivia()).count();
63 let leading_trivias = &self.tokens[self.token_pos..self.token_pos + n_trivias];
64 let mut trivia_end =
65 self.text_pos + leading_trivias.iter().map(|it| it.len).sum::<TextSize>();
66
67 let n_attached_trivias = {
68 let leading_trivias = leading_trivias.iter().rev().map(|it| {
69 let next_end = trivia_end - it.len;
70 let range = TextRange::new(next_end, trivia_end);
71 trivia_end = next_end;
72 (it.kind, &self.text[range])
73 });
74 n_attached_trivias(kind, leading_trivias)
75 };
76 self.eat_n_trivias(n_trivias - n_attached_trivias);
77 self.inner.start_node(kind);
78 self.eat_n_trivias(n_attached_trivias);
79 }
80
81 fn finish_node(&mut self) {
82 match mem::replace(&mut self.state, State::PendingFinish) {
83 State::PendingStart => unreachable!(),
84 State::PendingFinish => self.inner.finish_node(),
85 State::Normal => (),
86 }
87 }
88
89 fn error(&mut self, error: ParseError) {
90 self.inner.error(error, self.text_pos)
91 }
92}
93
94impl<'a> TextTreeSink<'a> {
95 pub(super) fn new(text: &'a str, tokens: &'a [Token]) -> Self {
96 Self {
97 text,
98 tokens,
99 text_pos: 0.into(),
100 token_pos: 0,
101 state: State::PendingStart,
102 inner: SyntaxTreeBuilder::default(),
103 }
104 }
105
106 pub(super) fn finish(mut self) -> (GreenNode, Vec<SyntaxError>) {
107 match mem::replace(&mut self.state, State::Normal) {
108 State::PendingFinish => {
109 self.eat_trivias();
110 self.inner.finish_node()
111 }
112 State::PendingStart | State::Normal => unreachable!(),
113 }
114
115 self.inner.finish_raw()
116 }
117
118 fn eat_trivias(&mut self) {
119 while let Some(&token) = self.tokens.get(self.token_pos) {
120 if !token.kind.is_trivia() {
121 break;
122 }
123 self.do_token(token.kind, token.len, 1);
124 }
125 }
126
127 fn eat_n_trivias(&mut self, n: usize) {
128 for _ in 0..n {
129 let token = self.tokens[self.token_pos];
130 assert!(token.kind.is_trivia());
131 self.do_token(token.kind, token.len, 1);
132 }
133 }
134
135 fn do_token(&mut self, kind: SyntaxKind, len: TextSize, n_tokens: usize) {
136 let range = TextRange::at(self.text_pos, len);
137 let text: SmolStr = self.text[range].into();
138 self.text_pos += len;
139 self.token_pos += n_tokens;
140 self.inner.token(kind, text);
141 }
142}
143
144fn n_attached_trivias<'a>(
145 kind: SyntaxKind,
146 trivias: impl Iterator<Item = (SyntaxKind, &'a str)>,
147) -> usize {
148 match kind {
149 MACRO_CALL | CONST | TYPE_ALIAS | STRUCT | ENUM | VARIANT | FN | TRAIT | MODULE
150 | RECORD_FIELD | STATIC => {
151 let mut res = 0;
152 let mut trivias = trivias.enumerate().peekable();
153
154 while let Some((i, (kind, text))) = trivias.next() {
155 match kind {
156 WHITESPACE => {
157 if text.contains("\n\n") {
158 // we check whether the next token is a doc-comment
159 // and skip the whitespace in this case
160 if let Some((peek_kind, peek_text)) =
161 trivias.peek().map(|(_, pair)| pair)
162 {
163 if *peek_kind == COMMENT
164 && peek_text.starts_with("///")
165 && !peek_text.starts_with("////")
166 {
167 continue;
168 }
169 }
170 break;
171 }
172 }
173 COMMENT => {
174 res = i + 1;
175 }
176 _ => (),
177 }
178 }
179 res
180 }
181 _ => 0,
182 }
183}
diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs
deleted file mode 100644
index ca7957747..000000000
--- a/crates/ra_syntax/src/ptr.rs
+++ /dev/null
@@ -1,105 +0,0 @@
1//! FIXME: write short doc here
2
3use std::{
4 hash::{Hash, Hasher},
5 iter::successors,
6 marker::PhantomData,
7};
8
9use crate::{AstNode, SyntaxKind, SyntaxNode, TextRange};
10
11/// A pointer to a syntax node inside a file. It can be used to remember a
12/// specific node across reparses of the same file.
13#[derive(Debug, Clone, PartialEq, Eq, Hash)]
14pub struct SyntaxNodePtr {
15 pub(crate) range: TextRange,
16 kind: SyntaxKind,
17}
18
19impl SyntaxNodePtr {
20 pub fn new(node: &SyntaxNode) -> SyntaxNodePtr {
21 SyntaxNodePtr { range: node.text_range(), kind: node.kind() }
22 }
23
24 pub fn to_node(&self, root: &SyntaxNode) -> SyntaxNode {
25 assert!(root.parent().is_none());
26 successors(Some(root.clone()), |node| {
27 node.children().find(|it| it.text_range().contains_range(self.range))
28 })
29 .find(|it| it.text_range() == self.range && it.kind() == self.kind)
30 .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self))
31 }
32
33 pub fn cast<N: AstNode>(self) -> Option<AstPtr<N>> {
34 if !N::can_cast(self.kind) {
35 return None;
36 }
37 Some(AstPtr { raw: self, _ty: PhantomData })
38 }
39}
40
41/// Like `SyntaxNodePtr`, but remembers the type of node
42#[derive(Debug)]
43pub struct AstPtr<N: AstNode> {
44 raw: SyntaxNodePtr,
45 _ty: PhantomData<fn() -> N>,
46}
47
48impl<N: AstNode> Clone for AstPtr<N> {
49 fn clone(&self) -> AstPtr<N> {
50 AstPtr { raw: self.raw.clone(), _ty: PhantomData }
51 }
52}
53
54impl<N: AstNode> Eq for AstPtr<N> {}
55
56impl<N: AstNode> PartialEq for AstPtr<N> {
57 fn eq(&self, other: &AstPtr<N>) -> bool {
58 self.raw == other.raw
59 }
60}
61
62impl<N: AstNode> Hash for AstPtr<N> {
63 fn hash<H: Hasher>(&self, state: &mut H) {
64 self.raw.hash(state)
65 }
66}
67
68impl<N: AstNode> AstPtr<N> {
69 pub fn new(node: &N) -> AstPtr<N> {
70 AstPtr { raw: SyntaxNodePtr::new(node.syntax()), _ty: PhantomData }
71 }
72
73 pub fn to_node(&self, root: &SyntaxNode) -> N {
74 let syntax_node = self.raw.to_node(root);
75 N::cast(syntax_node).unwrap()
76 }
77
78 pub fn syntax_node_ptr(&self) -> SyntaxNodePtr {
79 self.raw.clone()
80 }
81
82 pub fn cast<U: AstNode>(self) -> Option<AstPtr<U>> {
83 if !U::can_cast(self.raw.kind) {
84 return None;
85 }
86 Some(AstPtr { raw: self.raw, _ty: PhantomData })
87 }
88}
89
90impl<N: AstNode> From<AstPtr<N>> for SyntaxNodePtr {
91 fn from(ptr: AstPtr<N>) -> SyntaxNodePtr {
92 ptr.raw
93 }
94}
95
96#[test]
97fn test_local_syntax_ptr() {
98 use crate::{ast, AstNode, SourceFile};
99
100 let file = SourceFile::parse("struct Foo { f: u32, }").ok().unwrap();
101 let field = file.syntax().descendants().find_map(ast::RecordField::cast).unwrap();
102 let ptr = SyntaxNodePtr::new(field.syntax());
103 let field_syntax = ptr.to_node(file.syntax());
104 assert_eq!(field.syntax(), &field_syntax);
105}
diff --git a/crates/ra_syntax/src/syntax_error.rs b/crates/ra_syntax/src/syntax_error.rs
deleted file mode 100644
index 7c4511fec..000000000
--- a/crates/ra_syntax/src/syntax_error.rs
+++ /dev/null
@@ -1,44 +0,0 @@
1//! See docs for `SyntaxError`.
2
3use std::fmt;
4
5use crate::{TextRange, TextSize};
6
7/// Represents the result of unsuccessful tokenization, parsing
8/// or tree validation.
9#[derive(Debug, Clone, PartialEq, Eq, Hash)]
10pub struct SyntaxError(String, TextRange);
11
12// FIXME: there was an unused SyntaxErrorKind previously (before this enum was removed)
13// It was introduced in this PR: https://github.com/rust-analyzer/rust-analyzer/pull/846/files#diff-827da9b03b8f9faa1bade5cdd44d5dafR95
14// but it was not removed by a mistake.
15//
16// So, we need to find a place where to stick validation for attributes in match clauses.
17// Code before refactor:
18// InvalidMatchInnerAttr => {
19// write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression")
20// }
21
22impl SyntaxError {
23 pub fn new(message: impl Into<String>, range: TextRange) -> Self {
24 Self(message.into(), range)
25 }
26 pub fn new_at_offset(message: impl Into<String>, offset: TextSize) -> Self {
27 Self(message.into(), TextRange::empty(offset))
28 }
29
30 pub fn range(&self) -> TextRange {
31 self.1
32 }
33
34 pub fn with_range(mut self, range: TextRange) -> Self {
35 self.1 = range;
36 self
37 }
38}
39
40impl fmt::Display for SyntaxError {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 self.0.fmt(f)
43 }
44}
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs
deleted file mode 100644
index a7dbdba7b..000000000
--- a/crates/ra_syntax/src/syntax_node.rs
+++ /dev/null
@@ -1,77 +0,0 @@
1//! This module defines Concrete Syntax Tree (CST), used by rust-analyzer.
2//!
3//! The CST includes comments and whitespace, provides a single node type,
4//! `SyntaxNode`, and a basic traversal API (parent, children, siblings).
5//!
6//! The *real* implementation is in the (language-agnostic) `rowan` crate, this
7//! module just wraps its API.
8
9use rowan::{GreenNodeBuilder, Language};
10
11use crate::{Parse, SmolStr, SyntaxError, SyntaxKind, TextSize};
12
13pub use rowan::GreenNode;
14
15pub(crate) use rowan::GreenToken;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
18pub enum RustLanguage {}
19impl Language for RustLanguage {
20 type Kind = SyntaxKind;
21
22 fn kind_from_raw(raw: rowan::SyntaxKind) -> SyntaxKind {
23 SyntaxKind::from(raw.0)
24 }
25
26 fn kind_to_raw(kind: SyntaxKind) -> rowan::SyntaxKind {
27 rowan::SyntaxKind(kind.into())
28 }
29}
30
31pub type SyntaxNode = rowan::SyntaxNode<RustLanguage>;
32pub type SyntaxToken = rowan::SyntaxToken<RustLanguage>;
33pub type SyntaxElement = rowan::SyntaxElement<RustLanguage>;
34pub type SyntaxNodeChildren = rowan::SyntaxNodeChildren<RustLanguage>;
35pub type SyntaxElementChildren = rowan::SyntaxElementChildren<RustLanguage>;
36
37pub use rowan::{Direction, NodeOrToken};
38
39#[derive(Default)]
40pub struct SyntaxTreeBuilder {
41 errors: Vec<SyntaxError>,
42 inner: GreenNodeBuilder<'static>,
43}
44
45impl SyntaxTreeBuilder {
46 pub(crate) fn finish_raw(self) -> (GreenNode, Vec<SyntaxError>) {
47 let green = self.inner.finish();
48 (green, self.errors)
49 }
50
51 pub fn finish(self) -> Parse<SyntaxNode> {
52 let (green, errors) = self.finish_raw();
53 if cfg!(debug_assertions) {
54 let node = SyntaxNode::new_root(green.clone());
55 crate::validation::validate_block_structure(&node);
56 }
57 Parse::new(green, errors)
58 }
59
60 pub fn token(&mut self, kind: SyntaxKind, text: SmolStr) {
61 let kind = RustLanguage::kind_to_raw(kind);
62 self.inner.token(kind, text)
63 }
64
65 pub fn start_node(&mut self, kind: SyntaxKind) {
66 let kind = RustLanguage::kind_to_raw(kind);
67 self.inner.start_node(kind)
68 }
69
70 pub fn finish_node(&mut self) {
71 self.inner.finish_node()
72 }
73
74 pub fn error(&mut self, error: ra_parser::ParseError, text_pos: TextSize) {
75 self.errors.push(SyntaxError::new_at_offset(*error.0, text_pos))
76 }
77}
diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs
deleted file mode 100644
index 68cee8914..000000000
--- a/crates/ra_syntax/src/tests.rs
+++ /dev/null
@@ -1,280 +0,0 @@
1use std::{
2 fmt::Write,
3 fs,
4 path::{Path, PathBuf},
5};
6
7use expect::expect_file;
8use rayon::prelude::*;
9use test_utils::project_dir;
10
11use crate::{fuzz, tokenize, SourceFile, SyntaxError, TextRange, TextSize, Token};
12
13#[test]
14fn lexer_tests() {
15 // FIXME:
16 // * Add tests for unicode escapes in byte-character and [raw]-byte-string literals
17 // * Add tests for unescape errors
18
19 dir_tests(&test_data_dir(), &["lexer/ok"], "txt", |text, path| {
20 let (tokens, errors) = tokenize(text);
21 assert_errors_are_absent(&errors, path);
22 dump_tokens_and_errors(&tokens, &errors, text)
23 });
24 dir_tests(&test_data_dir(), &["lexer/err"], "txt", |text, path| {
25 let (tokens, errors) = tokenize(text);
26 assert_errors_are_present(&errors, path);
27 dump_tokens_and_errors(&tokens, &errors, text)
28 });
29}
30
31#[test]
32fn parse_smoke_test() {
33 let code = r##"
34fn main() {
35 println!("Hello, world!")
36}
37 "##;
38
39 let parse = SourceFile::parse(code);
40 // eprintln!("{:#?}", parse.syntax_node());
41 assert!(parse.ok().is_ok());
42}
43
44#[test]
45fn parser_tests() {
46 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], "rast", |text, path| {
47 let parse = SourceFile::parse(text);
48 let errors = parse.errors();
49 assert_errors_are_absent(&errors, path);
50 parse.debug_dump()
51 });
52 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], "rast", |text, path| {
53 let parse = SourceFile::parse(text);
54 let errors = parse.errors();
55 assert_errors_are_present(&errors, path);
56 parse.debug_dump()
57 });
58}
59
60#[test]
61fn expr_parser_tests() {
62 fragment_parser_dir_test(
63 &["parser/fragments/expr/ok"],
64 &["parser/fragments/expr/err"],
65 crate::ast::Expr::parse,
66 );
67}
68
69#[test]
70fn path_parser_tests() {
71 fragment_parser_dir_test(
72 &["parser/fragments/path/ok"],
73 &["parser/fragments/path/err"],
74 crate::ast::Path::parse,
75 );
76}
77
78#[test]
79fn pattern_parser_tests() {
80 fragment_parser_dir_test(
81 &["parser/fragments/pattern/ok"],
82 &["parser/fragments/pattern/err"],
83 crate::ast::Pat::parse,
84 );
85}
86
87#[test]
88fn item_parser_tests() {
89 fragment_parser_dir_test(
90 &["parser/fragments/item/ok"],
91 &["parser/fragments/item/err"],
92 crate::ast::Item::parse,
93 );
94}
95
96#[test]
97fn type_parser_tests() {
98 fragment_parser_dir_test(
99 &["parser/fragments/type/ok"],
100 &["parser/fragments/type/err"],
101 crate::ast::TypeRef::parse,
102 );
103}
104
105#[test]
106fn parser_fuzz_tests() {
107 for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) {
108 fuzz::check_parser(&text)
109 }
110}
111
112#[test]
113fn reparse_fuzz_tests() {
114 for (_, text) in collect_rust_files(&test_data_dir(), &["reparse/fuzz-failures"]) {
115 let check = fuzz::CheckReparse::from_data(text.as_bytes()).unwrap();
116 println!("{:?}", check);
117 check.run();
118 }
119}
120
121/// Test that Rust-analyzer can parse and validate the rust-analyzer
122/// FIXME: Use this as a benchmark
123#[test]
124fn self_hosting_parsing() {
125 let dir = project_dir().join("crates");
126 let files = walkdir::WalkDir::new(dir)
127 .into_iter()
128 .filter_entry(|entry| {
129 // Get all files which are not in the crates/ra_syntax/test_data folder
130 !entry.path().components().any(|component| component.as_os_str() == "test_data")
131 })
132 .map(|e| e.unwrap())
133 .filter(|entry| {
134 // Get all `.rs ` files
135 !entry.path().is_dir() && (entry.path().extension().unwrap_or_default() == "rs")
136 })
137 .map(|entry| entry.into_path())
138 .collect::<Vec<_>>();
139 assert!(
140 files.len() > 100,
141 "self_hosting_parsing found too few files - is it running in the right directory?"
142 );
143
144 let errors = files
145 .into_par_iter()
146 .filter_map(|file| {
147 let text = read_text(&file);
148 match SourceFile::parse(&text).ok() {
149 Ok(_) => None,
150 Err(err) => Some((file, err)),
151 }
152 })
153 .collect::<Vec<_>>();
154
155 if !errors.is_empty() {
156 let errors = errors
157 .into_iter()
158 .map(|(path, err)| format!("{}: {:?}\n", path.display(), err))
159 .collect::<String>();
160 panic!("Parsing errors:\n{}\n", errors);
161 }
162}
163
164fn test_data_dir() -> PathBuf {
165 project_dir().join("crates/ra_syntax/test_data")
166}
167
168fn assert_errors_are_present(errors: &[SyntaxError], path: &Path) {
169 assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display());
170}
171fn assert_errors_are_absent(errors: &[SyntaxError], path: &Path) {
172 assert_eq!(
173 errors,
174 &[] as &[SyntaxError],
175 "There should be no errors in the file {:?}",
176 path.display(),
177 );
178}
179
180fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str) -> String {
181 let mut acc = String::new();
182 let mut offset: TextSize = 0.into();
183 for token in tokens {
184 let token_len = token.len;
185 let token_text = &text[TextRange::at(offset, token.len)];
186 offset += token.len;
187 writeln!(acc, "{:?} {:?} {:?}", token.kind, token_len, token_text).unwrap();
188 }
189 for err in errors {
190 writeln!(acc, "> error{:?} token({:?}) msg({})", err.range(), &text[err.range()], err)
191 .unwrap();
192 }
193 acc
194}
195
196fn fragment_parser_dir_test<T, F>(ok_paths: &[&str], err_paths: &[&str], f: F)
197where
198 T: crate::AstNode,
199 F: Fn(&str) -> Result<T, ()>,
200{
201 dir_tests(&test_data_dir(), ok_paths, "rast", |text, path| {
202 if let Ok(node) = f(text) {
203 format!("{:#?}", crate::ast::AstNode::syntax(&node))
204 } else {
205 panic!("Failed to parse '{:?}'", path);
206 }
207 });
208 dir_tests(&test_data_dir(), err_paths, "rast", |text, path| {
209 if let Ok(_) = f(text) {
210 panic!("'{:?}' successfully parsed when it should have errored", path);
211 } else {
212 "ERROR\n".to_owned()
213 }
214 });
215}
216
217/// Calls callback `f` with input code and file paths for each `.rs` file in `test_data_dir`
218/// subdirectories defined by `paths`.
219///
220/// If the content of the matching output file differs from the output of `f()`
221/// the test will fail.
222///
223/// If there is no matching output file it will be created and filled with the
224/// output of `f()`, but the test will fail.
225fn dir_tests<F>(test_data_dir: &Path, paths: &[&str], outfile_extension: &str, f: F)
226where
227 F: Fn(&str, &Path) -> String,
228{
229 for (path, input_code) in collect_rust_files(test_data_dir, paths) {
230 let actual = f(&input_code, &path);
231 let path = path.with_extension(outfile_extension);
232 expect_file![path].assert_eq(&actual)
233 }
234}
235
236/// Collects all `.rs` files from `dir` subdirectories defined by `paths`.
237fn collect_rust_files(root_dir: &Path, paths: &[&str]) -> Vec<(PathBuf, String)> {
238 paths
239 .iter()
240 .flat_map(|path| {
241 let path = root_dir.to_owned().join(path);
242 rust_files_in_dir(&path).into_iter()
243 })
244 .map(|path| {
245 let text = read_text(&path);
246 (path, text)
247 })
248 .collect()
249}
250
251/// Collects paths to all `.rs` files from `dir` in a sorted `Vec<PathBuf>`.
252fn rust_files_in_dir(dir: &Path) -> Vec<PathBuf> {
253 let mut acc = Vec::new();
254 for file in fs::read_dir(&dir).unwrap() {
255 let file = file.unwrap();
256 let path = file.path();
257 if path.extension().unwrap_or_default() == "rs" {
258 acc.push(path);
259 }
260 }
261 acc.sort();
262 acc
263}
264
265/// Read file and normalize newlines.
266///
267/// `rustc` seems to always normalize `\r\n` newlines to `\n`:
268///
269/// ```
270/// let s = "
271/// ";
272/// assert_eq!(s.as_bytes(), &[10]);
273/// ```
274///
275/// so this should always be correct.
276fn read_text(path: &Path) -> String {
277 fs::read_to_string(path)
278 .unwrap_or_else(|_| panic!("File at {:?} should be valid", path))
279 .replace("\r\n", "\n")
280}
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs
deleted file mode 100644
index 0325ab0b4..000000000
--- a/crates/ra_syntax/src/validation.rs
+++ /dev/null
@@ -1,303 +0,0 @@
1//! FIXME: write short doc here
2
3mod block;
4
5use crate::{
6 ast, match_ast, AstNode, SyntaxError,
7 SyntaxKind::{BYTE, BYTE_STRING, CHAR, CONST, FN, INT_NUMBER, STRING, TYPE_ALIAS},
8 SyntaxNode, SyntaxToken, TextSize, T,
9};
10use rustc_lexer::unescape::{
11 self, unescape_byte, unescape_byte_literal, unescape_char, unescape_literal, Mode,
12};
13use std::convert::TryFrom;
14
15fn rustc_unescape_error_to_string(err: unescape::EscapeError) -> &'static str {
16 use unescape::EscapeError as EE;
17
18 #[rustfmt::skip]
19 let err_message = match err {
20 EE::ZeroChars => {
21 "Literal must not be empty"
22 }
23 EE::MoreThanOneChar => {
24 "Literal must be one character long"
25 }
26 EE::LoneSlash => {
27 "Character must be escaped: `\\`"
28 }
29 EE::InvalidEscape => {
30 "Invalid escape"
31 }
32 EE::BareCarriageReturn | EE::BareCarriageReturnInRawString => {
33 "Character must be escaped: `\r`"
34 }
35 EE::EscapeOnlyChar => {
36 "Escape character `\\` must be escaped itself"
37 }
38 EE::TooShortHexEscape => {
39 "ASCII hex escape code must have exactly two digits"
40 }
41 EE::InvalidCharInHexEscape => {
42 "ASCII hex escape code must contain only hex characters"
43 }
44 EE::OutOfRangeHexEscape => {
45 "ASCII hex escape code must be at most 0x7F"
46 }
47 EE::NoBraceInUnicodeEscape => {
48 "Missing `{` to begin the unicode escape"
49 }
50 EE::InvalidCharInUnicodeEscape => {
51 "Unicode escape must contain only hex characters and underscores"
52 }
53 EE::EmptyUnicodeEscape => {
54 "Unicode escape must not be empty"
55 }
56 EE::UnclosedUnicodeEscape => {
57 "Missing `}` to terminate the unicode escape"
58 }
59 EE::LeadingUnderscoreUnicodeEscape => {
60 "Unicode escape code must not begin with an underscore"
61 }
62 EE::OverlongUnicodeEscape => {
63 "Unicode escape code must have at most 6 digits"
64 }
65 EE::LoneSurrogateUnicodeEscape => {
66 "Unicode escape code must not be a surrogate"
67 }
68 EE::OutOfRangeUnicodeEscape => {
69 "Unicode escape code must be at most 0x10FFFF"
70 }
71 EE::UnicodeEscapeInByte => {
72 "Byte literals must not contain unicode escapes"
73 }
74 EE::NonAsciiCharInByte | EE::NonAsciiCharInByteString => {
75 "Byte literals must not contain non-ASCII characters"
76 }
77 };
78
79 err_message
80}
81
82pub(crate) fn validate(root: &SyntaxNode) -> Vec<SyntaxError> {
83 // FIXME:
84 // * Add unescape validation of raw string literals and raw byte string literals
85 // * Add validation of doc comments are being attached to nodes
86
87 let mut errors = Vec::new();
88 for node in root.descendants() {
89 match_ast! {
90 match node {
91 ast::Literal(it) => validate_literal(it, &mut errors),
92 ast::BlockExpr(it) => block::validate_block_expr(it, &mut errors),
93 ast::FieldExpr(it) => validate_numeric_name(it.name_ref(), &mut errors),
94 ast::RecordExprField(it) => validate_numeric_name(it.name_ref(), &mut errors),
95 ast::Visibility(it) => validate_visibility(it, &mut errors),
96 ast::RangeExpr(it) => validate_range_expr(it, &mut errors),
97 ast::PathSegment(it) => validate_path_keywords(it, &mut errors),
98 _ => (),
99 }
100 }
101 }
102 errors
103}
104
105fn validate_literal(literal: ast::Literal, acc: &mut Vec<SyntaxError>) {
106 // FIXME: move this function to outer scope (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366196658)
107 fn unquote(text: &str, prefix_len: usize, end_delimiter: char) -> Option<&str> {
108 text.rfind(end_delimiter).and_then(|end| text.get(prefix_len..end))
109 }
110
111 let token = literal.token();
112 let text = token.text().as_str();
113
114 // FIXME: lift this lambda refactor to `fn` (https://github.com/rust-analyzer/rust-analyzer/pull/2834#discussion_r366199205)
115 let mut push_err = |prefix_len, (off, err): (usize, unescape::EscapeError)| {
116 let off = token.text_range().start() + TextSize::try_from(off + prefix_len).unwrap();
117 acc.push(SyntaxError::new_at_offset(rustc_unescape_error_to_string(err), off));
118 };
119
120 match token.kind() {
121 BYTE => {
122 if let Some(Err(e)) = unquote(text, 2, '\'').map(unescape_byte) {
123 push_err(2, e);
124 }
125 }
126 CHAR => {
127 if let Some(Err(e)) = unquote(text, 1, '\'').map(unescape_char) {
128 push_err(1, e);
129 }
130 }
131 BYTE_STRING => {
132 if let Some(without_quotes) = unquote(text, 2, '"') {
133 unescape_byte_literal(without_quotes, Mode::ByteStr, &mut |range, char| {
134 if let Err(err) = char {
135 push_err(2, (range.start, err));
136 }
137 })
138 }
139 }
140 STRING => {
141 if let Some(without_quotes) = unquote(text, 1, '"') {
142 unescape_literal(without_quotes, Mode::Str, &mut |range, char| {
143 if let Err(err) = char {
144 push_err(1, (range.start, err));
145 }
146 })
147 }
148 }
149 _ => (),
150 }
151}
152
153pub(crate) fn validate_block_structure(root: &SyntaxNode) {
154 let mut stack = Vec::new();
155 for node in root.descendants() {
156 match node.kind() {
157 T!['{'] => stack.push(node),
158 T!['}'] => {
159 if let Some(pair) = stack.pop() {
160 assert_eq!(
161 node.parent(),
162 pair.parent(),
163 "\nunpaired curleys:\n{}\n{:#?}\n",
164 root.text(),
165 root,
166 );
167 assert!(
168 node.next_sibling().is_none() && pair.prev_sibling().is_none(),
169 "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n",
170 node,
171 root.text(),
172 node.text(),
173 );
174 }
175 }
176 _ => (),
177 }
178 }
179}
180
181fn validate_numeric_name(name_ref: Option<ast::NameRef>, errors: &mut Vec<SyntaxError>) {
182 if let Some(int_token) = int_token(name_ref) {
183 if int_token.text().chars().any(|c| !c.is_digit(10)) {
184 errors.push(SyntaxError::new(
185 "Tuple (struct) field access is only allowed through \
186 decimal integers with no underscores or suffix",
187 int_token.text_range(),
188 ));
189 }
190 }
191
192 fn int_token(name_ref: Option<ast::NameRef>) -> Option<SyntaxToken> {
193 name_ref?.syntax().first_child_or_token()?.into_token().filter(|it| it.kind() == INT_NUMBER)
194 }
195}
196
197fn validate_visibility(vis: ast::Visibility, errors: &mut Vec<SyntaxError>) {
198 let parent = match vis.syntax().parent() {
199 Some(it) => it,
200 None => return,
201 };
202 match parent.kind() {
203 FN | CONST | TYPE_ALIAS => (),
204 _ => return,
205 }
206
207 let impl_def = match parent.parent().and_then(|it| it.parent()).and_then(ast::Impl::cast) {
208 Some(it) => it,
209 None => return,
210 };
211 if impl_def.target_trait().is_some() {
212 errors.push(SyntaxError::new("Unnecessary visibility qualifier", vis.syntax.text_range()));
213 }
214}
215
216fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) {
217 if expr.op_kind() == Some(ast::RangeOp::Inclusive) && expr.end().is_none() {
218 errors.push(SyntaxError::new(
219 "An inclusive range must have an end expression",
220 expr.syntax().text_range(),
221 ));
222 }
223}
224
225fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxError>) {
226 use ast::PathSegmentKind;
227
228 let path = segment.parent_path();
229 let is_path_start = segment.coloncolon_token().is_none() && path.qualifier().is_none();
230
231 if let Some(token) = segment.self_token() {
232 if !is_path_start {
233 errors.push(SyntaxError::new(
234 "The `self` keyword is only allowed as the first segment of a path",
235 token.text_range(),
236 ));
237 }
238 } else if let Some(token) = segment.crate_token() {
239 if !is_path_start || use_prefix(path).is_some() {
240 errors.push(SyntaxError::new(
241 "The `crate` keyword is only allowed as the first segment of a path",
242 token.text_range(),
243 ));
244 }
245 } else if let Some(token) = segment.super_token() {
246 if !all_supers(&path) {
247 errors.push(SyntaxError::new(
248 "The `super` keyword may only be preceded by other `super`s",
249 token.text_range(),
250 ));
251 return;
252 }
253
254 let mut curr_path = path;
255 while let Some(prefix) = use_prefix(curr_path) {
256 if !all_supers(&prefix) {
257 errors.push(SyntaxError::new(
258 "The `super` keyword may only be preceded by other `super`s",
259 token.text_range(),
260 ));
261 return;
262 }
263 curr_path = prefix;
264 }
265 }
266
267 fn use_prefix(mut path: ast::Path) -> Option<ast::Path> {
268 for node in path.syntax().ancestors().skip(1) {
269 match_ast! {
270 match node {
271 ast::UseTree(it) => if let Some(tree_path) = it.path() {
272 // Even a top-level path exists within a `UseTree` so we must explicitly
273 // allow our path but disallow anything else
274 if tree_path != path {
275 return Some(tree_path);
276 }
277 },
278 ast::UseTreeList(_it) => continue,
279 ast::Path(parent) => path = parent,
280 _ => return None,
281 }
282 };
283 }
284 return None;
285 }
286
287 fn all_supers(path: &ast::Path) -> bool {
288 let segment = match path.segment() {
289 Some(it) => it,
290 None => return false,
291 };
292
293 if segment.kind() != Some(PathSegmentKind::SuperKw) {
294 return false;
295 }
296
297 if let Some(ref subpath) = path.qualifier() {
298 return all_supers(subpath);
299 }
300
301 return true;
302 }
303}
diff --git a/crates/ra_syntax/src/validation/block.rs b/crates/ra_syntax/src/validation/block.rs
deleted file mode 100644
index ad9901468..000000000
--- a/crates/ra_syntax/src/validation/block.rs
+++ /dev/null
@@ -1,22 +0,0 @@
1//! Logic for validating block expressions i.e. `ast::BlockExpr`.
2
3use crate::{
4 ast::{self, AstNode, AttrsOwner},
5 SyntaxError,
6 SyntaxKind::*,
7};
8
9pub(crate) fn validate_block_expr(block: ast::BlockExpr, errors: &mut Vec<SyntaxError>) {
10 if let Some(parent) = block.syntax().parent() {
11 match parent.kind() {
12 FN | EXPR_STMT | BLOCK_EXPR => return,
13 _ => {}
14 }
15 }
16 errors.extend(block.attrs().map(|attr| {
17 SyntaxError::new(
18 "A block in this position cannot accept inner attributes",
19 attr.syntax().text_range(),
20 )
21 }))
22}