diff options
author | Aleksey Kladov <[email protected]> | 2018-09-16 10:54:24 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-09-16 11:07:39 +0100 |
commit | b5021411a84822cb3f1e3aeffad9550dd15bdeb6 (patch) | |
tree | 9dca564f8e51b298dced01c4ce669c756dce3142 /crates/ra_syntax | |
parent | ba0bfeee12e19da40b5eabc8d0408639af10e96f (diff) |
rename all things
Diffstat (limited to 'crates/ra_syntax')
422 files changed, 21903 insertions, 0 deletions
diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml new file mode 100644 index 000000000..a0fd633e0 --- /dev/null +++ b/crates/ra_syntax/Cargo.toml | |||
@@ -0,0 +1,17 @@ | |||
1 | [package] | ||
2 | name = "ra_syntax" | ||
3 | version = "0.1.0" | ||
4 | authors = ["Aleksey Kladov <[email protected]>"] | ||
5 | license = "MIT OR Apache-2.0" | ||
6 | |||
7 | [dependencies] | ||
8 | unicode-xid = "0.1.0" | ||
9 | text_unit = "0.1.4" | ||
10 | itertools = "0.7.8" | ||
11 | drop_bomb = "0.1.4" | ||
12 | parking_lot = "0.6.0" | ||
13 | smol_str = "0.1.6" | ||
14 | |||
15 | [dev-dependencies] | ||
16 | test_utils = { path = "../test_utils" } | ||
17 | walkdir = "2.2.0" | ||
diff --git a/crates/ra_syntax/fuzz/.gitignore b/crates/ra_syntax/fuzz/.gitignore new file mode 100644 index 000000000..572e03bdf --- /dev/null +++ b/crates/ra_syntax/fuzz/.gitignore | |||
@@ -0,0 +1,4 @@ | |||
1 | |||
2 | target | ||
3 | corpus | ||
4 | artifacts | ||
diff --git a/crates/ra_syntax/fuzz/Cargo.toml b/crates/ra_syntax/fuzz/Cargo.toml new file mode 100644 index 000000000..65ded6a21 --- /dev/null +++ b/crates/ra_syntax/fuzz/Cargo.toml | |||
@@ -0,0 +1,22 @@ | |||
1 | |||
2 | [package] | ||
3 | name = "ra_syntax-fuzz" | ||
4 | version = "0.0.1" | ||
5 | authors = ["Automatically generated"] | ||
6 | publish = false | ||
7 | |||
8 | [package.metadata] | ||
9 | cargo-fuzz = true | ||
10 | |||
11 | [dependencies.ra_syntax] | ||
12 | path = ".." | ||
13 | [dependencies.libfuzzer-sys] | ||
14 | git = "https://github.com/rust-fuzz/libfuzzer-sys.git" | ||
15 | |||
16 | # Prevent this from interfering with workspaces | ||
17 | [workspace] | ||
18 | members = ["."] | ||
19 | |||
20 | [[bin]] | ||
21 | name = "parser" | ||
22 | path = "fuzz_targets/parser.rs" | ||
diff --git a/crates/ra_syntax/fuzz/fuzz_targets/parser.rs b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs new file mode 100644 index 000000000..396c0ecaf --- /dev/null +++ b/crates/ra_syntax/fuzz/fuzz_targets/parser.rs | |||
@@ -0,0 +1,9 @@ | |||
1 | #![no_main] | ||
2 | #[macro_use] extern crate libfuzzer_sys; | ||
3 | extern crate ra_syntax; | ||
4 | |||
5 | fuzz_target!(|data: &[u8]| { | ||
6 | if let Ok(text) = std::str::from_utf8(data) { | ||
7 | ra_syntax::utils::check_fuzz_invariants(text) | ||
8 | } | ||
9 | }); | ||
diff --git a/crates/ra_syntax/src/algo/mod.rs b/crates/ra_syntax/src/algo/mod.rs new file mode 100644 index 000000000..7287f5bb2 --- /dev/null +++ b/crates/ra_syntax/src/algo/mod.rs | |||
@@ -0,0 +1,129 @@ | |||
1 | pub mod walk; | ||
2 | pub mod visit; | ||
3 | |||
4 | use { | ||
5 | SyntaxNodeRef, TextUnit, TextRange, | ||
6 | text_utils::{contains_offset_nonstrict, is_subrange}, | ||
7 | }; | ||
8 | |||
9 | pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { | ||
10 | let range = node.range(); | ||
11 | assert!( | ||
12 | contains_offset_nonstrict(range, offset), | ||
13 | "Bad offset: range {:?} offset {:?}", range, offset | ||
14 | ); | ||
15 | if range.is_empty() { | ||
16 | return LeafAtOffset::None; | ||
17 | } | ||
18 | |||
19 | if node.is_leaf() { | ||
20 | return LeafAtOffset::Single(node); | ||
21 | } | ||
22 | |||
23 | let mut children = node.children() | ||
24 | .filter(|child| { | ||
25 | let child_range = child.range(); | ||
26 | !child_range.is_empty() && contains_offset_nonstrict(child_range, offset) | ||
27 | }); | ||
28 | |||
29 | let left = children.next().unwrap(); | ||
30 | let right = children.next(); | ||
31 | assert!(children.next().is_none()); | ||
32 | return if let Some(right) = right { | ||
33 | match (find_leaf_at_offset(left, offset), find_leaf_at_offset(right, offset)) { | ||
34 | (LeafAtOffset::Single(left), LeafAtOffset::Single(right)) => | ||
35 | LeafAtOffset::Between(left, right), | ||
36 | _ => unreachable!() | ||
37 | } | ||
38 | } else { | ||
39 | find_leaf_at_offset(left, offset) | ||
40 | }; | ||
41 | } | ||
42 | |||
43 | #[derive(Clone, Copy, Debug)] | ||
44 | pub enum LeafAtOffset<'a> { | ||
45 | None, | ||
46 | Single(SyntaxNodeRef<'a>), | ||
47 | Between(SyntaxNodeRef<'a>, SyntaxNodeRef<'a>) | ||
48 | } | ||
49 | |||
50 | impl<'a> LeafAtOffset<'a> { | ||
51 | pub fn right_biased(self) -> Option<SyntaxNodeRef<'a>> { | ||
52 | match self { | ||
53 | LeafAtOffset::None => None, | ||
54 | LeafAtOffset::Single(node) => Some(node), | ||
55 | LeafAtOffset::Between(_, right) => Some(right) | ||
56 | } | ||
57 | } | ||
58 | |||
59 | pub fn left_biased(self) -> Option<SyntaxNodeRef<'a>> { | ||
60 | match self { | ||
61 | LeafAtOffset::None => None, | ||
62 | LeafAtOffset::Single(node) => Some(node), | ||
63 | LeafAtOffset::Between(left, _) => Some(left) | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | |||
68 | impl<'f> Iterator for LeafAtOffset<'f> { | ||
69 | type Item = SyntaxNodeRef<'f>; | ||
70 | |||
71 | fn next(&mut self) -> Option<SyntaxNodeRef<'f>> { | ||
72 | match *self { | ||
73 | LeafAtOffset::None => None, | ||
74 | LeafAtOffset::Single(node) => { *self = LeafAtOffset::None; Some(node) } | ||
75 | LeafAtOffset::Between(left, right) => { *self = LeafAtOffset::Single(right); Some(left) } | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef { | ||
81 | assert!(is_subrange(root.range(), range)); | ||
82 | let (left, right) = match ( | ||
83 | find_leaf_at_offset(root, range.start()).right_biased(), | ||
84 | find_leaf_at_offset(root, range.end()).left_biased() | ||
85 | ) { | ||
86 | (Some(l), Some(r)) => (l, r), | ||
87 | _ => return root | ||
88 | }; | ||
89 | |||
90 | common_ancestor(left, right) | ||
91 | } | ||
92 | |||
93 | pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
94 | generate(Some(node), |&node| node.parent()) | ||
95 | } | ||
96 | |||
97 | #[derive(Debug)] | ||
98 | pub enum Direction { | ||
99 | Forward, | ||
100 | Backward, | ||
101 | } | ||
102 | |||
103 | pub fn siblings<'a>( | ||
104 | node: SyntaxNodeRef<'a>, | ||
105 | direction: Direction | ||
106 | ) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | ||
107 | generate(Some(node), move |&node| match direction { | ||
108 | Direction::Forward => node.next_sibling(), | ||
109 | Direction::Backward => node.prev_sibling(), | ||
110 | }) | ||
111 | } | ||
112 | |||
113 | fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { | ||
114 | for p in ancestors(n1) { | ||
115 | if ancestors(n2).any(|a| a == p) { | ||
116 | return p; | ||
117 | } | ||
118 | } | ||
119 | panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) | ||
120 | } | ||
121 | |||
122 | pub fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item=T> { | ||
123 | ::itertools::unfold(seed, move |slot| { | ||
124 | slot.take().map(|curr| { | ||
125 | *slot = step(&curr); | ||
126 | curr | ||
127 | }) | ||
128 | }) | ||
129 | } | ||
diff --git a/crates/ra_syntax/src/algo/visit.rs b/crates/ra_syntax/src/algo/visit.rs new file mode 100644 index 000000000..9f1c127c7 --- /dev/null +++ b/crates/ra_syntax/src/algo/visit.rs | |||
@@ -0,0 +1,110 @@ | |||
1 | use std::marker::PhantomData; | ||
2 | use {SyntaxNodeRef, AstNode}; | ||
3 | |||
4 | |||
5 | pub fn visitor<'a, T>() -> impl Visitor<'a, Output=T> { | ||
6 | EmptyVisitor { ph: PhantomData } | ||
7 | } | ||
8 | |||
9 | pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output=T, Ctx=C> { | ||
10 | EmptyVisitorCtx { ph: PhantomData, ctx } | ||
11 | } | ||
12 | |||
13 | pub trait Visitor<'a>: Sized { | ||
14 | type Output; | ||
15 | fn accept(self, node: SyntaxNodeRef<'a>) -> Option<Self::Output>; | ||
16 | fn visit<N, F>(self, f: F) -> Vis<Self, N, F> | ||
17 | where N: AstNode<'a>, | ||
18 | F: FnOnce(N) -> Self::Output, | ||
19 | { | ||
20 | Vis { inner: self, f, ph: PhantomData } | ||
21 | } | ||
22 | } | ||
23 | |||
24 | pub trait VisitorCtx<'a>: Sized { | ||
25 | type Output; | ||
26 | type Ctx; | ||
27 | fn accept(self, node: SyntaxNodeRef<'a>) -> Result<Self::Output, Self::Ctx>; | ||
28 | fn visit<N, F>(self, f: F) -> VisCtx<Self, N, F> | ||
29 | where N: AstNode<'a>, | ||
30 | F: FnOnce(N, Self::Ctx) -> Self::Output, | ||
31 | { | ||
32 | VisCtx { inner: self, f, ph: PhantomData } | ||
33 | } | ||
34 | } | ||
35 | |||
36 | #[derive(Debug)] | ||
37 | struct EmptyVisitor<T> { | ||
38 | ph: PhantomData<fn() -> T> | ||
39 | } | ||
40 | |||
41 | impl<'a, T> Visitor<'a> for EmptyVisitor<T> { | ||
42 | type Output = T; | ||
43 | |||
44 | fn accept(self, _node: SyntaxNodeRef<'a>) -> Option<T> { | ||
45 | None | ||
46 | } | ||
47 | } | ||
48 | |||
49 | #[derive(Debug)] | ||
50 | struct EmptyVisitorCtx<T, C> { | ||
51 | ctx: C, | ||
52 | ph: PhantomData<fn() -> T>, | ||
53 | } | ||
54 | |||
55 | impl<'a, T, C> VisitorCtx<'a> for EmptyVisitorCtx<T, C> { | ||
56 | type Output = T; | ||
57 | type Ctx = C; | ||
58 | |||
59 | fn accept(self, _node: SyntaxNodeRef<'a>) -> Result<T, C> { | ||
60 | Err(self.ctx) | ||
61 | } | ||
62 | } | ||
63 | |||
64 | #[derive(Debug)] | ||
65 | pub struct Vis<V, N, F> { | ||
66 | inner: V, | ||
67 | f: F, | ||
68 | ph: PhantomData<fn(N)>, | ||
69 | } | ||
70 | |||
71 | impl<'a, V, N, F> Visitor<'a> for Vis<V, N, F> | ||
72 | where | ||
73 | V: Visitor<'a>, | ||
74 | N: AstNode<'a>, | ||
75 | F: FnOnce(N) -> <V as Visitor<'a>>::Output, | ||
76 | { | ||
77 | type Output = <V as Visitor<'a>>::Output; | ||
78 | |||
79 | fn accept(self, node: SyntaxNodeRef<'a>) -> Option<Self::Output> { | ||
80 | let Vis { inner, f, .. } = self; | ||
81 | inner.accept(node).or_else(|| N::cast(node).map(f)) | ||
82 | } | ||
83 | } | ||
84 | |||
85 | #[derive(Debug)] | ||
86 | pub struct VisCtx<V, N, F> { | ||
87 | inner: V, | ||
88 | f: F, | ||
89 | ph: PhantomData<fn(N)>, | ||
90 | } | ||
91 | |||
92 | impl<'a, V, N, F> VisitorCtx<'a> for VisCtx<V, N, F> | ||
93 | where | ||
94 | V: VisitorCtx<'a>, | ||
95 | N: AstNode<'a>, | ||
96 | F: FnOnce(N, <V as VisitorCtx<'a>>::Ctx) -> <V as VisitorCtx<'a>>::Output, | ||
97 | { | ||
98 | type Output = <V as VisitorCtx<'a>>::Output; | ||
99 | type Ctx = <V as VisitorCtx<'a>>::Ctx; | ||
100 | |||
101 | fn accept(self, node: SyntaxNodeRef<'a>) -> Result<Self::Output, Self::Ctx> { | ||
102 | let VisCtx { inner, f, .. } = self; | ||
103 | inner.accept(node).or_else(|ctx| | ||
104 | match N::cast(node) { | ||
105 | None => Err(ctx), | ||
106 | Some(node) => Ok(f(node, ctx)) | ||
107 | } | ||
108 | ) | ||
109 | } | ||
110 | } | ||
diff --git a/crates/ra_syntax/src/algo/walk.rs b/crates/ra_syntax/src/algo/walk.rs new file mode 100644 index 000000000..536ee705f --- /dev/null +++ b/crates/ra_syntax/src/algo/walk.rs | |||
@@ -0,0 +1,38 @@ | |||
1 | use { | ||
2 | SyntaxNodeRef, | ||
3 | algo::generate, | ||
4 | }; | ||
5 | |||
6 | pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> { | ||
7 | walk(root).filter_map(|event| match event { | ||
8 | WalkEvent::Enter(node) => Some(node), | ||
9 | WalkEvent::Exit(_) => None, | ||
10 | }) | ||
11 | } | ||
12 | |||
13 | #[derive(Debug, Copy, Clone)] | ||
14 | pub enum WalkEvent<'a> { | ||
15 | Enter(SyntaxNodeRef<'a>), | ||
16 | Exit(SyntaxNodeRef<'a>), | ||
17 | } | ||
18 | |||
19 | pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> { | ||
20 | generate(Some(WalkEvent::Enter(root)), move |pos| { | ||
21 | let next = match *pos { | ||
22 | WalkEvent::Enter(node) => match node.first_child() { | ||
23 | Some(child) => WalkEvent::Enter(child), | ||
24 | None => WalkEvent::Exit(node), | ||
25 | }, | ||
26 | WalkEvent::Exit(node) => { | ||
27 | if node == root { | ||
28 | return None; | ||
29 | } | ||
30 | match node.next_sibling() { | ||
31 | Some(sibling) => WalkEvent::Enter(sibling), | ||
32 | None => WalkEvent::Exit(node.parent().unwrap()), | ||
33 | } | ||
34 | } | ||
35 | }; | ||
36 | Some(next) | ||
37 | }) | ||
38 | } | ||
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs new file mode 100644 index 000000000..c945c094a --- /dev/null +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -0,0 +1,2142 @@ | |||
1 | use { | ||
2 | ast, | ||
3 | SyntaxNodeRef, AstNode, | ||
4 | SyntaxKind::*, | ||
5 | }; | ||
6 | |||
7 | // ArgList | ||
8 | #[derive(Debug, Clone, Copy)] | ||
9 | pub struct ArgList<'a> { | ||
10 | syntax: SyntaxNodeRef<'a>, | ||
11 | } | ||
12 | |||
13 | impl<'a> AstNode<'a> for ArgList<'a> { | ||
14 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
15 | match syntax.kind() { | ||
16 | ARG_LIST => Some(ArgList { syntax }), | ||
17 | _ => None, | ||
18 | } | ||
19 | } | ||
20 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
21 | } | ||
22 | |||
23 | impl<'a> ArgList<'a> { | ||
24 | pub fn args(self) -> impl Iterator<Item = Expr<'a>> + 'a { | ||
25 | super::children(self) | ||
26 | } | ||
27 | } | ||
28 | |||
29 | // ArrayExpr | ||
30 | #[derive(Debug, Clone, Copy)] | ||
31 | pub struct ArrayExpr<'a> { | ||
32 | syntax: SyntaxNodeRef<'a>, | ||
33 | } | ||
34 | |||
35 | impl<'a> AstNode<'a> for ArrayExpr<'a> { | ||
36 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
37 | match syntax.kind() { | ||
38 | ARRAY_EXPR => Some(ArrayExpr { syntax }), | ||
39 | _ => None, | ||
40 | } | ||
41 | } | ||
42 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
43 | } | ||
44 | |||
45 | impl<'a> ArrayExpr<'a> {} | ||
46 | |||
47 | // ArrayType | ||
48 | #[derive(Debug, Clone, Copy)] | ||
49 | pub struct ArrayType<'a> { | ||
50 | syntax: SyntaxNodeRef<'a>, | ||
51 | } | ||
52 | |||
53 | impl<'a> AstNode<'a> for ArrayType<'a> { | ||
54 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
55 | match syntax.kind() { | ||
56 | ARRAY_TYPE => Some(ArrayType { syntax }), | ||
57 | _ => None, | ||
58 | } | ||
59 | } | ||
60 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
61 | } | ||
62 | |||
63 | impl<'a> ArrayType<'a> {} | ||
64 | |||
65 | // Attr | ||
66 | #[derive(Debug, Clone, Copy)] | ||
67 | pub struct Attr<'a> { | ||
68 | syntax: SyntaxNodeRef<'a>, | ||
69 | } | ||
70 | |||
71 | impl<'a> AstNode<'a> for Attr<'a> { | ||
72 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
73 | match syntax.kind() { | ||
74 | ATTR => Some(Attr { syntax }), | ||
75 | _ => None, | ||
76 | } | ||
77 | } | ||
78 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
79 | } | ||
80 | |||
81 | impl<'a> Attr<'a> {pub fn value(self) -> Option<TokenTree<'a>> { | ||
82 | super::child_opt(self) | ||
83 | } | ||
84 | } | ||
85 | |||
86 | // BinExpr | ||
87 | #[derive(Debug, Clone, Copy)] | ||
88 | pub struct BinExpr<'a> { | ||
89 | syntax: SyntaxNodeRef<'a>, | ||
90 | } | ||
91 | |||
92 | impl<'a> AstNode<'a> for BinExpr<'a> { | ||
93 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
94 | match syntax.kind() { | ||
95 | BIN_EXPR => Some(BinExpr { syntax }), | ||
96 | _ => None, | ||
97 | } | ||
98 | } | ||
99 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
100 | } | ||
101 | |||
102 | impl<'a> BinExpr<'a> {} | ||
103 | |||
104 | // BindPat | ||
105 | #[derive(Debug, Clone, Copy)] | ||
106 | pub struct BindPat<'a> { | ||
107 | syntax: SyntaxNodeRef<'a>, | ||
108 | } | ||
109 | |||
110 | impl<'a> AstNode<'a> for BindPat<'a> { | ||
111 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
112 | match syntax.kind() { | ||
113 | BIND_PAT => Some(BindPat { syntax }), | ||
114 | _ => None, | ||
115 | } | ||
116 | } | ||
117 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
118 | } | ||
119 | |||
120 | impl<'a> ast::NameOwner<'a> for BindPat<'a> {} | ||
121 | impl<'a> BindPat<'a> {} | ||
122 | |||
123 | // Block | ||
124 | #[derive(Debug, Clone, Copy)] | ||
125 | pub struct Block<'a> { | ||
126 | syntax: SyntaxNodeRef<'a>, | ||
127 | } | ||
128 | |||
129 | impl<'a> AstNode<'a> for Block<'a> { | ||
130 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
131 | match syntax.kind() { | ||
132 | BLOCK => Some(Block { syntax }), | ||
133 | _ => None, | ||
134 | } | ||
135 | } | ||
136 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
137 | } | ||
138 | |||
139 | impl<'a> Block<'a> { | ||
140 | pub fn statements(self) -> impl Iterator<Item = Stmt<'a>> + 'a { | ||
141 | super::children(self) | ||
142 | } | ||
143 | pub fn expr(self) -> Option<Expr<'a>> { | ||
144 | super::child_opt(self) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | // BlockExpr | ||
149 | #[derive(Debug, Clone, Copy)] | ||
150 | pub struct BlockExpr<'a> { | ||
151 | syntax: SyntaxNodeRef<'a>, | ||
152 | } | ||
153 | |||
154 | impl<'a> AstNode<'a> for BlockExpr<'a> { | ||
155 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
156 | match syntax.kind() { | ||
157 | BLOCK_EXPR => Some(BlockExpr { syntax }), | ||
158 | _ => None, | ||
159 | } | ||
160 | } | ||
161 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
162 | } | ||
163 | |||
164 | impl<'a> BlockExpr<'a> {pub fn block(self) -> Option<Block<'a>> { | ||
165 | super::child_opt(self) | ||
166 | } | ||
167 | } | ||
168 | |||
169 | // BreakExpr | ||
170 | #[derive(Debug, Clone, Copy)] | ||
171 | pub struct BreakExpr<'a> { | ||
172 | syntax: SyntaxNodeRef<'a>, | ||
173 | } | ||
174 | |||
175 | impl<'a> AstNode<'a> for BreakExpr<'a> { | ||
176 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
177 | match syntax.kind() { | ||
178 | BREAK_EXPR => Some(BreakExpr { syntax }), | ||
179 | _ => None, | ||
180 | } | ||
181 | } | ||
182 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
183 | } | ||
184 | |||
185 | impl<'a> BreakExpr<'a> {} | ||
186 | |||
187 | // CallExpr | ||
188 | #[derive(Debug, Clone, Copy)] | ||
189 | pub struct CallExpr<'a> { | ||
190 | syntax: SyntaxNodeRef<'a>, | ||
191 | } | ||
192 | |||
193 | impl<'a> AstNode<'a> for CallExpr<'a> { | ||
194 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
195 | match syntax.kind() { | ||
196 | CALL_EXPR => Some(CallExpr { syntax }), | ||
197 | _ => None, | ||
198 | } | ||
199 | } | ||
200 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
201 | } | ||
202 | |||
203 | impl<'a> ast::ArgListOwner<'a> for CallExpr<'a> {} | ||
204 | impl<'a> CallExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> { | ||
205 | super::child_opt(self) | ||
206 | } | ||
207 | } | ||
208 | |||
209 | // CastExpr | ||
210 | #[derive(Debug, Clone, Copy)] | ||
211 | pub struct CastExpr<'a> { | ||
212 | syntax: SyntaxNodeRef<'a>, | ||
213 | } | ||
214 | |||
215 | impl<'a> AstNode<'a> for CastExpr<'a> { | ||
216 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
217 | match syntax.kind() { | ||
218 | CAST_EXPR => Some(CastExpr { syntax }), | ||
219 | _ => None, | ||
220 | } | ||
221 | } | ||
222 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
223 | } | ||
224 | |||
225 | impl<'a> CastExpr<'a> {} | ||
226 | |||
227 | // Condition | ||
228 | #[derive(Debug, Clone, Copy)] | ||
229 | pub struct Condition<'a> { | ||
230 | syntax: SyntaxNodeRef<'a>, | ||
231 | } | ||
232 | |||
233 | impl<'a> AstNode<'a> for Condition<'a> { | ||
234 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
235 | match syntax.kind() { | ||
236 | CONDITION => Some(Condition { syntax }), | ||
237 | _ => None, | ||
238 | } | ||
239 | } | ||
240 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
241 | } | ||
242 | |||
243 | impl<'a> Condition<'a> {pub fn pat(self) -> Option<Pat<'a>> { | ||
244 | super::child_opt(self) | ||
245 | } | ||
246 | pub fn expr(self) -> Option<Expr<'a>> { | ||
247 | super::child_opt(self) | ||
248 | } | ||
249 | } | ||
250 | |||
251 | // ConstDef | ||
252 | #[derive(Debug, Clone, Copy)] | ||
253 | pub struct ConstDef<'a> { | ||
254 | syntax: SyntaxNodeRef<'a>, | ||
255 | } | ||
256 | |||
257 | impl<'a> AstNode<'a> for ConstDef<'a> { | ||
258 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
259 | match syntax.kind() { | ||
260 | CONST_DEF => Some(ConstDef { syntax }), | ||
261 | _ => None, | ||
262 | } | ||
263 | } | ||
264 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
265 | } | ||
266 | |||
267 | impl<'a> ast::NameOwner<'a> for ConstDef<'a> {} | ||
268 | impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {} | ||
269 | impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {} | ||
270 | impl<'a> ConstDef<'a> {} | ||
271 | |||
272 | // ContinueExpr | ||
273 | #[derive(Debug, Clone, Copy)] | ||
274 | pub struct ContinueExpr<'a> { | ||
275 | syntax: SyntaxNodeRef<'a>, | ||
276 | } | ||
277 | |||
278 | impl<'a> AstNode<'a> for ContinueExpr<'a> { | ||
279 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
280 | match syntax.kind() { | ||
281 | CONTINUE_EXPR => Some(ContinueExpr { syntax }), | ||
282 | _ => None, | ||
283 | } | ||
284 | } | ||
285 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
286 | } | ||
287 | |||
288 | impl<'a> ContinueExpr<'a> {} | ||
289 | |||
290 | // DynTraitType | ||
291 | #[derive(Debug, Clone, Copy)] | ||
292 | pub struct DynTraitType<'a> { | ||
293 | syntax: SyntaxNodeRef<'a>, | ||
294 | } | ||
295 | |||
296 | impl<'a> AstNode<'a> for DynTraitType<'a> { | ||
297 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
298 | match syntax.kind() { | ||
299 | DYN_TRAIT_TYPE => Some(DynTraitType { syntax }), | ||
300 | _ => None, | ||
301 | } | ||
302 | } | ||
303 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
304 | } | ||
305 | |||
306 | impl<'a> DynTraitType<'a> {} | ||
307 | |||
308 | // EnumDef | ||
309 | #[derive(Debug, Clone, Copy)] | ||
310 | pub struct EnumDef<'a> { | ||
311 | syntax: SyntaxNodeRef<'a>, | ||
312 | } | ||
313 | |||
314 | impl<'a> AstNode<'a> for EnumDef<'a> { | ||
315 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
316 | match syntax.kind() { | ||
317 | ENUM_DEF => Some(EnumDef { syntax }), | ||
318 | _ => None, | ||
319 | } | ||
320 | } | ||
321 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
322 | } | ||
323 | |||
324 | impl<'a> ast::NameOwner<'a> for EnumDef<'a> {} | ||
325 | impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} | ||
326 | impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} | ||
327 | impl<'a> EnumDef<'a> {} | ||
328 | |||
329 | // Expr | ||
330 | #[derive(Debug, Clone, Copy)] | ||
331 | pub enum Expr<'a> { | ||
332 | TupleExpr(TupleExpr<'a>), | ||
333 | ArrayExpr(ArrayExpr<'a>), | ||
334 | ParenExpr(ParenExpr<'a>), | ||
335 | PathExpr(PathExpr<'a>), | ||
336 | LambdaExpr(LambdaExpr<'a>), | ||
337 | IfExpr(IfExpr<'a>), | ||
338 | LoopExpr(LoopExpr<'a>), | ||
339 | ForExpr(ForExpr<'a>), | ||
340 | WhileExpr(WhileExpr<'a>), | ||
341 | ContinueExpr(ContinueExpr<'a>), | ||
342 | BreakExpr(BreakExpr<'a>), | ||
343 | Label(Label<'a>), | ||
344 | BlockExpr(BlockExpr<'a>), | ||
345 | ReturnExpr(ReturnExpr<'a>), | ||
346 | MatchExpr(MatchExpr<'a>), | ||
347 | MatchArmList(MatchArmList<'a>), | ||
348 | MatchArm(MatchArm<'a>), | ||
349 | MatchGuard(MatchGuard<'a>), | ||
350 | StructLit(StructLit<'a>), | ||
351 | NamedFieldList(NamedFieldList<'a>), | ||
352 | NamedField(NamedField<'a>), | ||
353 | CallExpr(CallExpr<'a>), | ||
354 | IndexExpr(IndexExpr<'a>), | ||
355 | MethodCallExpr(MethodCallExpr<'a>), | ||
356 | FieldExpr(FieldExpr<'a>), | ||
357 | TryExpr(TryExpr<'a>), | ||
358 | CastExpr(CastExpr<'a>), | ||
359 | RefExpr(RefExpr<'a>), | ||
360 | PrefixExpr(PrefixExpr<'a>), | ||
361 | RangeExpr(RangeExpr<'a>), | ||
362 | BinExpr(BinExpr<'a>), | ||
363 | Literal(Literal<'a>), | ||
364 | } | ||
365 | |||
366 | impl<'a> AstNode<'a> for Expr<'a> { | ||
367 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
368 | match syntax.kind() { | ||
369 | TUPLE_EXPR => Some(Expr::TupleExpr(TupleExpr { syntax })), | ||
370 | ARRAY_EXPR => Some(Expr::ArrayExpr(ArrayExpr { syntax })), | ||
371 | PAREN_EXPR => Some(Expr::ParenExpr(ParenExpr { syntax })), | ||
372 | PATH_EXPR => Some(Expr::PathExpr(PathExpr { syntax })), | ||
373 | LAMBDA_EXPR => Some(Expr::LambdaExpr(LambdaExpr { syntax })), | ||
374 | IF_EXPR => Some(Expr::IfExpr(IfExpr { syntax })), | ||
375 | LOOP_EXPR => Some(Expr::LoopExpr(LoopExpr { syntax })), | ||
376 | FOR_EXPR => Some(Expr::ForExpr(ForExpr { syntax })), | ||
377 | WHILE_EXPR => Some(Expr::WhileExpr(WhileExpr { syntax })), | ||
378 | CONTINUE_EXPR => Some(Expr::ContinueExpr(ContinueExpr { syntax })), | ||
379 | BREAK_EXPR => Some(Expr::BreakExpr(BreakExpr { syntax })), | ||
380 | LABEL => Some(Expr::Label(Label { syntax })), | ||
381 | BLOCK_EXPR => Some(Expr::BlockExpr(BlockExpr { syntax })), | ||
382 | RETURN_EXPR => Some(Expr::ReturnExpr(ReturnExpr { syntax })), | ||
383 | MATCH_EXPR => Some(Expr::MatchExpr(MatchExpr { syntax })), | ||
384 | MATCH_ARM_LIST => Some(Expr::MatchArmList(MatchArmList { syntax })), | ||
385 | MATCH_ARM => Some(Expr::MatchArm(MatchArm { syntax })), | ||
386 | MATCH_GUARD => Some(Expr::MatchGuard(MatchGuard { syntax })), | ||
387 | STRUCT_LIT => Some(Expr::StructLit(StructLit { syntax })), | ||
388 | NAMED_FIELD_LIST => Some(Expr::NamedFieldList(NamedFieldList { syntax })), | ||
389 | NAMED_FIELD => Some(Expr::NamedField(NamedField { syntax })), | ||
390 | CALL_EXPR => Some(Expr::CallExpr(CallExpr { syntax })), | ||
391 | INDEX_EXPR => Some(Expr::IndexExpr(IndexExpr { syntax })), | ||
392 | METHOD_CALL_EXPR => Some(Expr::MethodCallExpr(MethodCallExpr { syntax })), | ||
393 | FIELD_EXPR => Some(Expr::FieldExpr(FieldExpr { syntax })), | ||
394 | TRY_EXPR => Some(Expr::TryExpr(TryExpr { syntax })), | ||
395 | CAST_EXPR => Some(Expr::CastExpr(CastExpr { syntax })), | ||
396 | REF_EXPR => Some(Expr::RefExpr(RefExpr { syntax })), | ||
397 | PREFIX_EXPR => Some(Expr::PrefixExpr(PrefixExpr { syntax })), | ||
398 | RANGE_EXPR => Some(Expr::RangeExpr(RangeExpr { syntax })), | ||
399 | BIN_EXPR => Some(Expr::BinExpr(BinExpr { syntax })), | ||
400 | LITERAL => Some(Expr::Literal(Literal { syntax })), | ||
401 | _ => None, | ||
402 | } | ||
403 | } | ||
404 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
405 | match self { | ||
406 | Expr::TupleExpr(inner) => inner.syntax(), | ||
407 | Expr::ArrayExpr(inner) => inner.syntax(), | ||
408 | Expr::ParenExpr(inner) => inner.syntax(), | ||
409 | Expr::PathExpr(inner) => inner.syntax(), | ||
410 | Expr::LambdaExpr(inner) => inner.syntax(), | ||
411 | Expr::IfExpr(inner) => inner.syntax(), | ||
412 | Expr::LoopExpr(inner) => inner.syntax(), | ||
413 | Expr::ForExpr(inner) => inner.syntax(), | ||
414 | Expr::WhileExpr(inner) => inner.syntax(), | ||
415 | Expr::ContinueExpr(inner) => inner.syntax(), | ||
416 | Expr::BreakExpr(inner) => inner.syntax(), | ||
417 | Expr::Label(inner) => inner.syntax(), | ||
418 | Expr::BlockExpr(inner) => inner.syntax(), | ||
419 | Expr::ReturnExpr(inner) => inner.syntax(), | ||
420 | Expr::MatchExpr(inner) => inner.syntax(), | ||
421 | Expr::MatchArmList(inner) => inner.syntax(), | ||
422 | Expr::MatchArm(inner) => inner.syntax(), | ||
423 | Expr::MatchGuard(inner) => inner.syntax(), | ||
424 | Expr::StructLit(inner) => inner.syntax(), | ||
425 | Expr::NamedFieldList(inner) => inner.syntax(), | ||
426 | Expr::NamedField(inner) => inner.syntax(), | ||
427 | Expr::CallExpr(inner) => inner.syntax(), | ||
428 | Expr::IndexExpr(inner) => inner.syntax(), | ||
429 | Expr::MethodCallExpr(inner) => inner.syntax(), | ||
430 | Expr::FieldExpr(inner) => inner.syntax(), | ||
431 | Expr::TryExpr(inner) => inner.syntax(), | ||
432 | Expr::CastExpr(inner) => inner.syntax(), | ||
433 | Expr::RefExpr(inner) => inner.syntax(), | ||
434 | Expr::PrefixExpr(inner) => inner.syntax(), | ||
435 | Expr::RangeExpr(inner) => inner.syntax(), | ||
436 | Expr::BinExpr(inner) => inner.syntax(), | ||
437 | Expr::Literal(inner) => inner.syntax(), | ||
438 | } | ||
439 | } | ||
440 | } | ||
441 | |||
442 | impl<'a> Expr<'a> {} | ||
443 | |||
444 | // ExprStmt | ||
445 | #[derive(Debug, Clone, Copy)] | ||
446 | pub struct ExprStmt<'a> { | ||
447 | syntax: SyntaxNodeRef<'a>, | ||
448 | } | ||
449 | |||
450 | impl<'a> AstNode<'a> for ExprStmt<'a> { | ||
451 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
452 | match syntax.kind() { | ||
453 | EXPR_STMT => Some(ExprStmt { syntax }), | ||
454 | _ => None, | ||
455 | } | ||
456 | } | ||
457 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
458 | } | ||
459 | |||
460 | impl<'a> ExprStmt<'a> {pub fn expr(self) -> Option<Expr<'a>> { | ||
461 | super::child_opt(self) | ||
462 | } | ||
463 | } | ||
464 | |||
465 | // ExternCrateItem | ||
466 | #[derive(Debug, Clone, Copy)] | ||
467 | pub struct ExternCrateItem<'a> { | ||
468 | syntax: SyntaxNodeRef<'a>, | ||
469 | } | ||
470 | |||
471 | impl<'a> AstNode<'a> for ExternCrateItem<'a> { | ||
472 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
473 | match syntax.kind() { | ||
474 | EXTERN_CRATE_ITEM => Some(ExternCrateItem { syntax }), | ||
475 | _ => None, | ||
476 | } | ||
477 | } | ||
478 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
479 | } | ||
480 | |||
481 | impl<'a> ExternCrateItem<'a> {} | ||
482 | |||
483 | // FieldExpr | ||
484 | #[derive(Debug, Clone, Copy)] | ||
485 | pub struct FieldExpr<'a> { | ||
486 | syntax: SyntaxNodeRef<'a>, | ||
487 | } | ||
488 | |||
489 | impl<'a> AstNode<'a> for FieldExpr<'a> { | ||
490 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
491 | match syntax.kind() { | ||
492 | FIELD_EXPR => Some(FieldExpr { syntax }), | ||
493 | _ => None, | ||
494 | } | ||
495 | } | ||
496 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
497 | } | ||
498 | |||
499 | impl<'a> FieldExpr<'a> {} | ||
500 | |||
501 | // FieldPatList | ||
502 | #[derive(Debug, Clone, Copy)] | ||
503 | pub struct FieldPatList<'a> { | ||
504 | syntax: SyntaxNodeRef<'a>, | ||
505 | } | ||
506 | |||
507 | impl<'a> AstNode<'a> for FieldPatList<'a> { | ||
508 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
509 | match syntax.kind() { | ||
510 | FIELD_PAT_LIST => Some(FieldPatList { syntax }), | ||
511 | _ => None, | ||
512 | } | ||
513 | } | ||
514 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
515 | } | ||
516 | |||
517 | impl<'a> FieldPatList<'a> {} | ||
518 | |||
519 | // FnDef | ||
520 | #[derive(Debug, Clone, Copy)] | ||
521 | pub struct FnDef<'a> { | ||
522 | syntax: SyntaxNodeRef<'a>, | ||
523 | } | ||
524 | |||
525 | impl<'a> AstNode<'a> for FnDef<'a> { | ||
526 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
527 | match syntax.kind() { | ||
528 | FN_DEF => Some(FnDef { syntax }), | ||
529 | _ => None, | ||
530 | } | ||
531 | } | ||
532 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
533 | } | ||
534 | |||
535 | impl<'a> ast::NameOwner<'a> for FnDef<'a> {} | ||
536 | impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {} | ||
537 | impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {} | ||
538 | impl<'a> FnDef<'a> {pub fn param_list(self) -> Option<ParamList<'a>> { | ||
539 | super::child_opt(self) | ||
540 | } | ||
541 | pub fn body(self) -> Option<Block<'a>> { | ||
542 | super::child_opt(self) | ||
543 | } | ||
544 | pub fn ret_type(self) -> Option<RetType<'a>> { | ||
545 | super::child_opt(self) | ||
546 | } | ||
547 | } | ||
548 | |||
549 | // FnPointerType | ||
550 | #[derive(Debug, Clone, Copy)] | ||
551 | pub struct FnPointerType<'a> { | ||
552 | syntax: SyntaxNodeRef<'a>, | ||
553 | } | ||
554 | |||
555 | impl<'a> AstNode<'a> for FnPointerType<'a> { | ||
556 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
557 | match syntax.kind() { | ||
558 | FN_POINTER_TYPE => Some(FnPointerType { syntax }), | ||
559 | _ => None, | ||
560 | } | ||
561 | } | ||
562 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
563 | } | ||
564 | |||
565 | impl<'a> FnPointerType<'a> {} | ||
566 | |||
567 | // ForExpr | ||
568 | #[derive(Debug, Clone, Copy)] | ||
569 | pub struct ForExpr<'a> { | ||
570 | syntax: SyntaxNodeRef<'a>, | ||
571 | } | ||
572 | |||
573 | impl<'a> AstNode<'a> for ForExpr<'a> { | ||
574 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
575 | match syntax.kind() { | ||
576 | FOR_EXPR => Some(ForExpr { syntax }), | ||
577 | _ => None, | ||
578 | } | ||
579 | } | ||
580 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
581 | } | ||
582 | |||
583 | impl<'a> ast::LoopBodyOwner<'a> for ForExpr<'a> {} | ||
584 | impl<'a> ForExpr<'a> {pub fn pat(self) -> Option<Pat<'a>> { | ||
585 | super::child_opt(self) | ||
586 | } | ||
587 | pub fn iterable(self) -> Option<Expr<'a>> { | ||
588 | super::child_opt(self) | ||
589 | } | ||
590 | } | ||
591 | |||
592 | // ForType | ||
593 | #[derive(Debug, Clone, Copy)] | ||
594 | pub struct ForType<'a> { | ||
595 | syntax: SyntaxNodeRef<'a>, | ||
596 | } | ||
597 | |||
598 | impl<'a> AstNode<'a> for ForType<'a> { | ||
599 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
600 | match syntax.kind() { | ||
601 | FOR_TYPE => Some(ForType { syntax }), | ||
602 | _ => None, | ||
603 | } | ||
604 | } | ||
605 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
606 | } | ||
607 | |||
608 | impl<'a> ForType<'a> {} | ||
609 | |||
610 | // IfExpr | ||
611 | #[derive(Debug, Clone, Copy)] | ||
612 | pub struct IfExpr<'a> { | ||
613 | syntax: SyntaxNodeRef<'a>, | ||
614 | } | ||
615 | |||
616 | impl<'a> AstNode<'a> for IfExpr<'a> { | ||
617 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
618 | match syntax.kind() { | ||
619 | IF_EXPR => Some(IfExpr { syntax }), | ||
620 | _ => None, | ||
621 | } | ||
622 | } | ||
623 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
624 | } | ||
625 | |||
626 | impl<'a> IfExpr<'a> {pub fn condition(self) -> Option<Condition<'a>> { | ||
627 | super::child_opt(self) | ||
628 | } | ||
629 | } | ||
630 | |||
631 | // ImplItem | ||
632 | #[derive(Debug, Clone, Copy)] | ||
633 | pub struct ImplItem<'a> { | ||
634 | syntax: SyntaxNodeRef<'a>, | ||
635 | } | ||
636 | |||
637 | impl<'a> AstNode<'a> for ImplItem<'a> { | ||
638 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
639 | match syntax.kind() { | ||
640 | IMPL_ITEM => Some(ImplItem { syntax }), | ||
641 | _ => None, | ||
642 | } | ||
643 | } | ||
644 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
645 | } | ||
646 | |||
647 | impl<'a> ImplItem<'a> {} | ||
648 | |||
649 | // ImplTraitType | ||
650 | #[derive(Debug, Clone, Copy)] | ||
651 | pub struct ImplTraitType<'a> { | ||
652 | syntax: SyntaxNodeRef<'a>, | ||
653 | } | ||
654 | |||
655 | impl<'a> AstNode<'a> for ImplTraitType<'a> { | ||
656 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
657 | match syntax.kind() { | ||
658 | IMPL_TRAIT_TYPE => Some(ImplTraitType { syntax }), | ||
659 | _ => None, | ||
660 | } | ||
661 | } | ||
662 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
663 | } | ||
664 | |||
665 | impl<'a> ImplTraitType<'a> {} | ||
666 | |||
667 | // IndexExpr | ||
668 | #[derive(Debug, Clone, Copy)] | ||
669 | pub struct IndexExpr<'a> { | ||
670 | syntax: SyntaxNodeRef<'a>, | ||
671 | } | ||
672 | |||
673 | impl<'a> AstNode<'a> for IndexExpr<'a> { | ||
674 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
675 | match syntax.kind() { | ||
676 | INDEX_EXPR => Some(IndexExpr { syntax }), | ||
677 | _ => None, | ||
678 | } | ||
679 | } | ||
680 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
681 | } | ||
682 | |||
683 | impl<'a> IndexExpr<'a> {} | ||
684 | |||
685 | // ItemList | ||
686 | #[derive(Debug, Clone, Copy)] | ||
687 | pub struct ItemList<'a> { | ||
688 | syntax: SyntaxNodeRef<'a>, | ||
689 | } | ||
690 | |||
691 | impl<'a> AstNode<'a> for ItemList<'a> { | ||
692 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
693 | match syntax.kind() { | ||
694 | ITEM_LIST => Some(ItemList { syntax }), | ||
695 | _ => None, | ||
696 | } | ||
697 | } | ||
698 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
699 | } | ||
700 | |||
701 | impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} | ||
702 | impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {} | ||
703 | impl<'a> ItemList<'a> {} | ||
704 | |||
705 | // Label | ||
706 | #[derive(Debug, Clone, Copy)] | ||
707 | pub struct Label<'a> { | ||
708 | syntax: SyntaxNodeRef<'a>, | ||
709 | } | ||
710 | |||
711 | impl<'a> AstNode<'a> for Label<'a> { | ||
712 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
713 | match syntax.kind() { | ||
714 | LABEL => Some(Label { syntax }), | ||
715 | _ => None, | ||
716 | } | ||
717 | } | ||
718 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
719 | } | ||
720 | |||
721 | impl<'a> Label<'a> {} | ||
722 | |||
723 | // LambdaExpr | ||
724 | #[derive(Debug, Clone, Copy)] | ||
725 | pub struct LambdaExpr<'a> { | ||
726 | syntax: SyntaxNodeRef<'a>, | ||
727 | } | ||
728 | |||
729 | impl<'a> AstNode<'a> for LambdaExpr<'a> { | ||
730 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
731 | match syntax.kind() { | ||
732 | LAMBDA_EXPR => Some(LambdaExpr { syntax }), | ||
733 | _ => None, | ||
734 | } | ||
735 | } | ||
736 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
737 | } | ||
738 | |||
739 | impl<'a> LambdaExpr<'a> {pub fn param_list(self) -> Option<ParamList<'a>> { | ||
740 | super::child_opt(self) | ||
741 | } | ||
742 | pub fn body(self) -> Option<Expr<'a>> { | ||
743 | super::child_opt(self) | ||
744 | } | ||
745 | } | ||
746 | |||
747 | // LetStmt | ||
748 | #[derive(Debug, Clone, Copy)] | ||
749 | pub struct LetStmt<'a> { | ||
750 | syntax: SyntaxNodeRef<'a>, | ||
751 | } | ||
752 | |||
753 | impl<'a> AstNode<'a> for LetStmt<'a> { | ||
754 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
755 | match syntax.kind() { | ||
756 | LET_STMT => Some(LetStmt { syntax }), | ||
757 | _ => None, | ||
758 | } | ||
759 | } | ||
760 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
761 | } | ||
762 | |||
763 | impl<'a> LetStmt<'a> {pub fn pat(self) -> Option<Pat<'a>> { | ||
764 | super::child_opt(self) | ||
765 | } | ||
766 | pub fn initializer(self) -> Option<Expr<'a>> { | ||
767 | super::child_opt(self) | ||
768 | } | ||
769 | } | ||
770 | |||
771 | // Lifetime | ||
772 | #[derive(Debug, Clone, Copy)] | ||
773 | pub struct Lifetime<'a> { | ||
774 | syntax: SyntaxNodeRef<'a>, | ||
775 | } | ||
776 | |||
777 | impl<'a> AstNode<'a> for Lifetime<'a> { | ||
778 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
779 | match syntax.kind() { | ||
780 | LIFETIME => Some(Lifetime { syntax }), | ||
781 | _ => None, | ||
782 | } | ||
783 | } | ||
784 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
785 | } | ||
786 | |||
787 | impl<'a> Lifetime<'a> {} | ||
788 | |||
789 | // LifetimeParam | ||
790 | #[derive(Debug, Clone, Copy)] | ||
791 | pub struct LifetimeParam<'a> { | ||
792 | syntax: SyntaxNodeRef<'a>, | ||
793 | } | ||
794 | |||
795 | impl<'a> AstNode<'a> for LifetimeParam<'a> { | ||
796 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
797 | match syntax.kind() { | ||
798 | LIFETIME_PARAM => Some(LifetimeParam { syntax }), | ||
799 | _ => None, | ||
800 | } | ||
801 | } | ||
802 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
803 | } | ||
804 | |||
805 | impl<'a> LifetimeParam<'a> {pub fn lifetime(self) -> Option<Lifetime<'a>> { | ||
806 | super::child_opt(self) | ||
807 | } | ||
808 | } | ||
809 | |||
810 | // Literal | ||
811 | #[derive(Debug, Clone, Copy)] | ||
812 | pub struct Literal<'a> { | ||
813 | syntax: SyntaxNodeRef<'a>, | ||
814 | } | ||
815 | |||
816 | impl<'a> AstNode<'a> for Literal<'a> { | ||
817 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
818 | match syntax.kind() { | ||
819 | LITERAL => Some(Literal { syntax }), | ||
820 | _ => None, | ||
821 | } | ||
822 | } | ||
823 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
824 | } | ||
825 | |||
826 | impl<'a> Literal<'a> {} | ||
827 | |||
828 | // LoopExpr | ||
829 | #[derive(Debug, Clone, Copy)] | ||
830 | pub struct LoopExpr<'a> { | ||
831 | syntax: SyntaxNodeRef<'a>, | ||
832 | } | ||
833 | |||
834 | impl<'a> AstNode<'a> for LoopExpr<'a> { | ||
835 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
836 | match syntax.kind() { | ||
837 | LOOP_EXPR => Some(LoopExpr { syntax }), | ||
838 | _ => None, | ||
839 | } | ||
840 | } | ||
841 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
842 | } | ||
843 | |||
844 | impl<'a> ast::LoopBodyOwner<'a> for LoopExpr<'a> {} | ||
845 | impl<'a> LoopExpr<'a> {} | ||
846 | |||
847 | // MatchArm | ||
848 | #[derive(Debug, Clone, Copy)] | ||
849 | pub struct MatchArm<'a> { | ||
850 | syntax: SyntaxNodeRef<'a>, | ||
851 | } | ||
852 | |||
853 | impl<'a> AstNode<'a> for MatchArm<'a> { | ||
854 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
855 | match syntax.kind() { | ||
856 | MATCH_ARM => Some(MatchArm { syntax }), | ||
857 | _ => None, | ||
858 | } | ||
859 | } | ||
860 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
861 | } | ||
862 | |||
863 | impl<'a> MatchArm<'a> { | ||
864 | pub fn pats(self) -> impl Iterator<Item = Pat<'a>> + 'a { | ||
865 | super::children(self) | ||
866 | } | ||
867 | pub fn guard(self) -> Option<MatchGuard<'a>> { | ||
868 | super::child_opt(self) | ||
869 | } | ||
870 | pub fn expr(self) -> Option<Expr<'a>> { | ||
871 | super::child_opt(self) | ||
872 | } | ||
873 | } | ||
874 | |||
875 | // MatchArmList | ||
876 | #[derive(Debug, Clone, Copy)] | ||
877 | pub struct MatchArmList<'a> { | ||
878 | syntax: SyntaxNodeRef<'a>, | ||
879 | } | ||
880 | |||
881 | impl<'a> AstNode<'a> for MatchArmList<'a> { | ||
882 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
883 | match syntax.kind() { | ||
884 | MATCH_ARM_LIST => Some(MatchArmList { syntax }), | ||
885 | _ => None, | ||
886 | } | ||
887 | } | ||
888 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
889 | } | ||
890 | |||
891 | impl<'a> MatchArmList<'a> { | ||
892 | pub fn arms(self) -> impl Iterator<Item = MatchArm<'a>> + 'a { | ||
893 | super::children(self) | ||
894 | } | ||
895 | } | ||
896 | |||
897 | // MatchExpr | ||
898 | #[derive(Debug, Clone, Copy)] | ||
899 | pub struct MatchExpr<'a> { | ||
900 | syntax: SyntaxNodeRef<'a>, | ||
901 | } | ||
902 | |||
903 | impl<'a> AstNode<'a> for MatchExpr<'a> { | ||
904 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
905 | match syntax.kind() { | ||
906 | MATCH_EXPR => Some(MatchExpr { syntax }), | ||
907 | _ => None, | ||
908 | } | ||
909 | } | ||
910 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
911 | } | ||
912 | |||
913 | impl<'a> MatchExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> { | ||
914 | super::child_opt(self) | ||
915 | } | ||
916 | pub fn match_arm_list(self) -> Option<MatchArmList<'a>> { | ||
917 | super::child_opt(self) | ||
918 | } | ||
919 | } | ||
920 | |||
921 | // MatchGuard | ||
922 | #[derive(Debug, Clone, Copy)] | ||
923 | pub struct MatchGuard<'a> { | ||
924 | syntax: SyntaxNodeRef<'a>, | ||
925 | } | ||
926 | |||
927 | impl<'a> AstNode<'a> for MatchGuard<'a> { | ||
928 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
929 | match syntax.kind() { | ||
930 | MATCH_GUARD => Some(MatchGuard { syntax }), | ||
931 | _ => None, | ||
932 | } | ||
933 | } | ||
934 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
935 | } | ||
936 | |||
937 | impl<'a> MatchGuard<'a> {} | ||
938 | |||
939 | // MethodCallExpr | ||
940 | #[derive(Debug, Clone, Copy)] | ||
941 | pub struct MethodCallExpr<'a> { | ||
942 | syntax: SyntaxNodeRef<'a>, | ||
943 | } | ||
944 | |||
945 | impl<'a> AstNode<'a> for MethodCallExpr<'a> { | ||
946 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
947 | match syntax.kind() { | ||
948 | METHOD_CALL_EXPR => Some(MethodCallExpr { syntax }), | ||
949 | _ => None, | ||
950 | } | ||
951 | } | ||
952 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
953 | } | ||
954 | |||
955 | impl<'a> ast::ArgListOwner<'a> for MethodCallExpr<'a> {} | ||
956 | impl<'a> MethodCallExpr<'a> {pub fn expr(self) -> Option<Expr<'a>> { | ||
957 | super::child_opt(self) | ||
958 | } | ||
959 | } | ||
960 | |||
961 | // Module | ||
962 | #[derive(Debug, Clone, Copy)] | ||
963 | pub struct Module<'a> { | ||
964 | syntax: SyntaxNodeRef<'a>, | ||
965 | } | ||
966 | |||
967 | impl<'a> AstNode<'a> for Module<'a> { | ||
968 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
969 | match syntax.kind() { | ||
970 | MODULE => Some(Module { syntax }), | ||
971 | _ => None, | ||
972 | } | ||
973 | } | ||
974 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
975 | } | ||
976 | |||
977 | impl<'a> ast::NameOwner<'a> for Module<'a> {} | ||
978 | impl<'a> ast::AttrsOwner<'a> for Module<'a> {} | ||
979 | impl<'a> Module<'a> {pub fn item_list(self) -> Option<ItemList<'a>> { | ||
980 | super::child_opt(self) | ||
981 | } | ||
982 | } | ||
983 | |||
984 | // ModuleItem | ||
985 | #[derive(Debug, Clone, Copy)] | ||
986 | pub enum ModuleItem<'a> { | ||
987 | StructDef(StructDef<'a>), | ||
988 | EnumDef(EnumDef<'a>), | ||
989 | FnDef(FnDef<'a>), | ||
990 | TraitDef(TraitDef<'a>), | ||
991 | TypeDef(TypeDef<'a>), | ||
992 | ImplItem(ImplItem<'a>), | ||
993 | UseItem(UseItem<'a>), | ||
994 | ExternCrateItem(ExternCrateItem<'a>), | ||
995 | ConstDef(ConstDef<'a>), | ||
996 | StaticDef(StaticDef<'a>), | ||
997 | Module(Module<'a>), | ||
998 | } | ||
999 | |||
1000 | impl<'a> AstNode<'a> for ModuleItem<'a> { | ||
1001 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1002 | match syntax.kind() { | ||
1003 | STRUCT_DEF => Some(ModuleItem::StructDef(StructDef { syntax })), | ||
1004 | ENUM_DEF => Some(ModuleItem::EnumDef(EnumDef { syntax })), | ||
1005 | FN_DEF => Some(ModuleItem::FnDef(FnDef { syntax })), | ||
1006 | TRAIT_DEF => Some(ModuleItem::TraitDef(TraitDef { syntax })), | ||
1007 | TYPE_DEF => Some(ModuleItem::TypeDef(TypeDef { syntax })), | ||
1008 | IMPL_ITEM => Some(ModuleItem::ImplItem(ImplItem { syntax })), | ||
1009 | USE_ITEM => Some(ModuleItem::UseItem(UseItem { syntax })), | ||
1010 | EXTERN_CRATE_ITEM => Some(ModuleItem::ExternCrateItem(ExternCrateItem { syntax })), | ||
1011 | CONST_DEF => Some(ModuleItem::ConstDef(ConstDef { syntax })), | ||
1012 | STATIC_DEF => Some(ModuleItem::StaticDef(StaticDef { syntax })), | ||
1013 | MODULE => Some(ModuleItem::Module(Module { syntax })), | ||
1014 | _ => None, | ||
1015 | } | ||
1016 | } | ||
1017 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1018 | match self { | ||
1019 | ModuleItem::StructDef(inner) => inner.syntax(), | ||
1020 | ModuleItem::EnumDef(inner) => inner.syntax(), | ||
1021 | ModuleItem::FnDef(inner) => inner.syntax(), | ||
1022 | ModuleItem::TraitDef(inner) => inner.syntax(), | ||
1023 | ModuleItem::TypeDef(inner) => inner.syntax(), | ||
1024 | ModuleItem::ImplItem(inner) => inner.syntax(), | ||
1025 | ModuleItem::UseItem(inner) => inner.syntax(), | ||
1026 | ModuleItem::ExternCrateItem(inner) => inner.syntax(), | ||
1027 | ModuleItem::ConstDef(inner) => inner.syntax(), | ||
1028 | ModuleItem::StaticDef(inner) => inner.syntax(), | ||
1029 | ModuleItem::Module(inner) => inner.syntax(), | ||
1030 | } | ||
1031 | } | ||
1032 | } | ||
1033 | |||
1034 | impl<'a> ModuleItem<'a> {} | ||
1035 | |||
1036 | // Name | ||
1037 | #[derive(Debug, Clone, Copy)] | ||
1038 | pub struct Name<'a> { | ||
1039 | syntax: SyntaxNodeRef<'a>, | ||
1040 | } | ||
1041 | |||
1042 | impl<'a> AstNode<'a> for Name<'a> { | ||
1043 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1044 | match syntax.kind() { | ||
1045 | NAME => Some(Name { syntax }), | ||
1046 | _ => None, | ||
1047 | } | ||
1048 | } | ||
1049 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1050 | } | ||
1051 | |||
1052 | impl<'a> Name<'a> {} | ||
1053 | |||
1054 | // NameRef | ||
1055 | #[derive(Debug, Clone, Copy)] | ||
1056 | pub struct NameRef<'a> { | ||
1057 | syntax: SyntaxNodeRef<'a>, | ||
1058 | } | ||
1059 | |||
1060 | impl<'a> AstNode<'a> for NameRef<'a> { | ||
1061 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1062 | match syntax.kind() { | ||
1063 | NAME_REF => Some(NameRef { syntax }), | ||
1064 | _ => None, | ||
1065 | } | ||
1066 | } | ||
1067 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1068 | } | ||
1069 | |||
1070 | impl<'a> NameRef<'a> {} | ||
1071 | |||
1072 | // NamedField | ||
1073 | #[derive(Debug, Clone, Copy)] | ||
1074 | pub struct NamedField<'a> { | ||
1075 | syntax: SyntaxNodeRef<'a>, | ||
1076 | } | ||
1077 | |||
1078 | impl<'a> AstNode<'a> for NamedField<'a> { | ||
1079 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1080 | match syntax.kind() { | ||
1081 | NAMED_FIELD => Some(NamedField { syntax }), | ||
1082 | _ => None, | ||
1083 | } | ||
1084 | } | ||
1085 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1086 | } | ||
1087 | |||
1088 | impl<'a> NamedField<'a> {} | ||
1089 | |||
1090 | // NamedFieldDef | ||
1091 | #[derive(Debug, Clone, Copy)] | ||
1092 | pub struct NamedFieldDef<'a> { | ||
1093 | syntax: SyntaxNodeRef<'a>, | ||
1094 | } | ||
1095 | |||
1096 | impl<'a> AstNode<'a> for NamedFieldDef<'a> { | ||
1097 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1098 | match syntax.kind() { | ||
1099 | NAMED_FIELD_DEF => Some(NamedFieldDef { syntax }), | ||
1100 | _ => None, | ||
1101 | } | ||
1102 | } | ||
1103 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1104 | } | ||
1105 | |||
1106 | impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} | ||
1107 | impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} | ||
1108 | impl<'a> NamedFieldDef<'a> {} | ||
1109 | |||
1110 | // NamedFieldList | ||
1111 | #[derive(Debug, Clone, Copy)] | ||
1112 | pub struct NamedFieldList<'a> { | ||
1113 | syntax: SyntaxNodeRef<'a>, | ||
1114 | } | ||
1115 | |||
1116 | impl<'a> AstNode<'a> for NamedFieldList<'a> { | ||
1117 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1118 | match syntax.kind() { | ||
1119 | NAMED_FIELD_LIST => Some(NamedFieldList { syntax }), | ||
1120 | _ => None, | ||
1121 | } | ||
1122 | } | ||
1123 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1124 | } | ||
1125 | |||
1126 | impl<'a> NamedFieldList<'a> {} | ||
1127 | |||
1128 | // NeverType | ||
1129 | #[derive(Debug, Clone, Copy)] | ||
1130 | pub struct NeverType<'a> { | ||
1131 | syntax: SyntaxNodeRef<'a>, | ||
1132 | } | ||
1133 | |||
1134 | impl<'a> AstNode<'a> for NeverType<'a> { | ||
1135 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1136 | match syntax.kind() { | ||
1137 | NEVER_TYPE => Some(NeverType { syntax }), | ||
1138 | _ => None, | ||
1139 | } | ||
1140 | } | ||
1141 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1142 | } | ||
1143 | |||
1144 | impl<'a> NeverType<'a> {} | ||
1145 | |||
1146 | // NominalDef | ||
1147 | #[derive(Debug, Clone, Copy)] | ||
1148 | pub enum NominalDef<'a> { | ||
1149 | StructDef(StructDef<'a>), | ||
1150 | EnumDef(EnumDef<'a>), | ||
1151 | } | ||
1152 | |||
1153 | impl<'a> AstNode<'a> for NominalDef<'a> { | ||
1154 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1155 | match syntax.kind() { | ||
1156 | STRUCT_DEF => Some(NominalDef::StructDef(StructDef { syntax })), | ||
1157 | ENUM_DEF => Some(NominalDef::EnumDef(EnumDef { syntax })), | ||
1158 | _ => None, | ||
1159 | } | ||
1160 | } | ||
1161 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1162 | match self { | ||
1163 | NominalDef::StructDef(inner) => inner.syntax(), | ||
1164 | NominalDef::EnumDef(inner) => inner.syntax(), | ||
1165 | } | ||
1166 | } | ||
1167 | } | ||
1168 | |||
1169 | impl<'a> ast::NameOwner<'a> for NominalDef<'a> {} | ||
1170 | impl<'a> ast::TypeParamsOwner<'a> for NominalDef<'a> {} | ||
1171 | impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {} | ||
1172 | impl<'a> NominalDef<'a> {} | ||
1173 | |||
1174 | // Param | ||
1175 | #[derive(Debug, Clone, Copy)] | ||
1176 | pub struct Param<'a> { | ||
1177 | syntax: SyntaxNodeRef<'a>, | ||
1178 | } | ||
1179 | |||
1180 | impl<'a> AstNode<'a> for Param<'a> { | ||
1181 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1182 | match syntax.kind() { | ||
1183 | PARAM => Some(Param { syntax }), | ||
1184 | _ => None, | ||
1185 | } | ||
1186 | } | ||
1187 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1188 | } | ||
1189 | |||
1190 | impl<'a> Param<'a> {pub fn pat(self) -> Option<Pat<'a>> { | ||
1191 | super::child_opt(self) | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | // ParamList | ||
1196 | #[derive(Debug, Clone, Copy)] | ||
1197 | pub struct ParamList<'a> { | ||
1198 | syntax: SyntaxNodeRef<'a>, | ||
1199 | } | ||
1200 | |||
1201 | impl<'a> AstNode<'a> for ParamList<'a> { | ||
1202 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1203 | match syntax.kind() { | ||
1204 | PARAM_LIST => Some(ParamList { syntax }), | ||
1205 | _ => None, | ||
1206 | } | ||
1207 | } | ||
1208 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1209 | } | ||
1210 | |||
1211 | impl<'a> ParamList<'a> { | ||
1212 | pub fn params(self) -> impl Iterator<Item = Param<'a>> + 'a { | ||
1213 | super::children(self) | ||
1214 | } | ||
1215 | pub fn self_param(self) -> Option<SelfParam<'a>> { | ||
1216 | super::child_opt(self) | ||
1217 | } | ||
1218 | } | ||
1219 | |||
1220 | // ParenExpr | ||
1221 | #[derive(Debug, Clone, Copy)] | ||
1222 | pub struct ParenExpr<'a> { | ||
1223 | syntax: SyntaxNodeRef<'a>, | ||
1224 | } | ||
1225 | |||
1226 | impl<'a> AstNode<'a> for ParenExpr<'a> { | ||
1227 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1228 | match syntax.kind() { | ||
1229 | PAREN_EXPR => Some(ParenExpr { syntax }), | ||
1230 | _ => None, | ||
1231 | } | ||
1232 | } | ||
1233 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1234 | } | ||
1235 | |||
1236 | impl<'a> ParenExpr<'a> {} | ||
1237 | |||
1238 | // ParenType | ||
1239 | #[derive(Debug, Clone, Copy)] | ||
1240 | pub struct ParenType<'a> { | ||
1241 | syntax: SyntaxNodeRef<'a>, | ||
1242 | } | ||
1243 | |||
1244 | impl<'a> AstNode<'a> for ParenType<'a> { | ||
1245 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1246 | match syntax.kind() { | ||
1247 | PAREN_TYPE => Some(ParenType { syntax }), | ||
1248 | _ => None, | ||
1249 | } | ||
1250 | } | ||
1251 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1252 | } | ||
1253 | |||
1254 | impl<'a> ParenType<'a> {} | ||
1255 | |||
1256 | // Pat | ||
1257 | #[derive(Debug, Clone, Copy)] | ||
1258 | pub enum Pat<'a> { | ||
1259 | RefPat(RefPat<'a>), | ||
1260 | BindPat(BindPat<'a>), | ||
1261 | PlaceholderPat(PlaceholderPat<'a>), | ||
1262 | PathPat(PathPat<'a>), | ||
1263 | StructPat(StructPat<'a>), | ||
1264 | FieldPatList(FieldPatList<'a>), | ||
1265 | TupleStructPat(TupleStructPat<'a>), | ||
1266 | TuplePat(TuplePat<'a>), | ||
1267 | SlicePat(SlicePat<'a>), | ||
1268 | RangePat(RangePat<'a>), | ||
1269 | } | ||
1270 | |||
1271 | impl<'a> AstNode<'a> for Pat<'a> { | ||
1272 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1273 | match syntax.kind() { | ||
1274 | REF_PAT => Some(Pat::RefPat(RefPat { syntax })), | ||
1275 | BIND_PAT => Some(Pat::BindPat(BindPat { syntax })), | ||
1276 | PLACEHOLDER_PAT => Some(Pat::PlaceholderPat(PlaceholderPat { syntax })), | ||
1277 | PATH_PAT => Some(Pat::PathPat(PathPat { syntax })), | ||
1278 | STRUCT_PAT => Some(Pat::StructPat(StructPat { syntax })), | ||
1279 | FIELD_PAT_LIST => Some(Pat::FieldPatList(FieldPatList { syntax })), | ||
1280 | TUPLE_STRUCT_PAT => Some(Pat::TupleStructPat(TupleStructPat { syntax })), | ||
1281 | TUPLE_PAT => Some(Pat::TuplePat(TuplePat { syntax })), | ||
1282 | SLICE_PAT => Some(Pat::SlicePat(SlicePat { syntax })), | ||
1283 | RANGE_PAT => Some(Pat::RangePat(RangePat { syntax })), | ||
1284 | _ => None, | ||
1285 | } | ||
1286 | } | ||
1287 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1288 | match self { | ||
1289 | Pat::RefPat(inner) => inner.syntax(), | ||
1290 | Pat::BindPat(inner) => inner.syntax(), | ||
1291 | Pat::PlaceholderPat(inner) => inner.syntax(), | ||
1292 | Pat::PathPat(inner) => inner.syntax(), | ||
1293 | Pat::StructPat(inner) => inner.syntax(), | ||
1294 | Pat::FieldPatList(inner) => inner.syntax(), | ||
1295 | Pat::TupleStructPat(inner) => inner.syntax(), | ||
1296 | Pat::TuplePat(inner) => inner.syntax(), | ||
1297 | Pat::SlicePat(inner) => inner.syntax(), | ||
1298 | Pat::RangePat(inner) => inner.syntax(), | ||
1299 | } | ||
1300 | } | ||
1301 | } | ||
1302 | |||
1303 | impl<'a> Pat<'a> {} | ||
1304 | |||
1305 | // Path | ||
1306 | #[derive(Debug, Clone, Copy)] | ||
1307 | pub struct Path<'a> { | ||
1308 | syntax: SyntaxNodeRef<'a>, | ||
1309 | } | ||
1310 | |||
1311 | impl<'a> AstNode<'a> for Path<'a> { | ||
1312 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1313 | match syntax.kind() { | ||
1314 | PATH => Some(Path { syntax }), | ||
1315 | _ => None, | ||
1316 | } | ||
1317 | } | ||
1318 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1319 | } | ||
1320 | |||
1321 | impl<'a> Path<'a> {pub fn segment(self) -> Option<PathSegment<'a>> { | ||
1322 | super::child_opt(self) | ||
1323 | } | ||
1324 | } | ||
1325 | |||
1326 | // PathExpr | ||
1327 | #[derive(Debug, Clone, Copy)] | ||
1328 | pub struct PathExpr<'a> { | ||
1329 | syntax: SyntaxNodeRef<'a>, | ||
1330 | } | ||
1331 | |||
1332 | impl<'a> AstNode<'a> for PathExpr<'a> { | ||
1333 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1334 | match syntax.kind() { | ||
1335 | PATH_EXPR => Some(PathExpr { syntax }), | ||
1336 | _ => None, | ||
1337 | } | ||
1338 | } | ||
1339 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1340 | } | ||
1341 | |||
1342 | impl<'a> PathExpr<'a> {} | ||
1343 | |||
1344 | // PathPat | ||
1345 | #[derive(Debug, Clone, Copy)] | ||
1346 | pub struct PathPat<'a> { | ||
1347 | syntax: SyntaxNodeRef<'a>, | ||
1348 | } | ||
1349 | |||
1350 | impl<'a> AstNode<'a> for PathPat<'a> { | ||
1351 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1352 | match syntax.kind() { | ||
1353 | PATH_PAT => Some(PathPat { syntax }), | ||
1354 | _ => None, | ||
1355 | } | ||
1356 | } | ||
1357 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1358 | } | ||
1359 | |||
1360 | impl<'a> PathPat<'a> {} | ||
1361 | |||
1362 | // PathSegment | ||
1363 | #[derive(Debug, Clone, Copy)] | ||
1364 | pub struct PathSegment<'a> { | ||
1365 | syntax: SyntaxNodeRef<'a>, | ||
1366 | } | ||
1367 | |||
1368 | impl<'a> AstNode<'a> for PathSegment<'a> { | ||
1369 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1370 | match syntax.kind() { | ||
1371 | PATH_SEGMENT => Some(PathSegment { syntax }), | ||
1372 | _ => None, | ||
1373 | } | ||
1374 | } | ||
1375 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1376 | } | ||
1377 | |||
1378 | impl<'a> PathSegment<'a> {pub fn name_ref(self) -> Option<NameRef<'a>> { | ||
1379 | super::child_opt(self) | ||
1380 | } | ||
1381 | } | ||
1382 | |||
1383 | // PathType | ||
1384 | #[derive(Debug, Clone, Copy)] | ||
1385 | pub struct PathType<'a> { | ||
1386 | syntax: SyntaxNodeRef<'a>, | ||
1387 | } | ||
1388 | |||
1389 | impl<'a> AstNode<'a> for PathType<'a> { | ||
1390 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1391 | match syntax.kind() { | ||
1392 | PATH_TYPE => Some(PathType { syntax }), | ||
1393 | _ => None, | ||
1394 | } | ||
1395 | } | ||
1396 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1397 | } | ||
1398 | |||
1399 | impl<'a> PathType<'a> {} | ||
1400 | |||
1401 | // PlaceholderPat | ||
1402 | #[derive(Debug, Clone, Copy)] | ||
1403 | pub struct PlaceholderPat<'a> { | ||
1404 | syntax: SyntaxNodeRef<'a>, | ||
1405 | } | ||
1406 | |||
1407 | impl<'a> AstNode<'a> for PlaceholderPat<'a> { | ||
1408 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1409 | match syntax.kind() { | ||
1410 | PLACEHOLDER_PAT => Some(PlaceholderPat { syntax }), | ||
1411 | _ => None, | ||
1412 | } | ||
1413 | } | ||
1414 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1415 | } | ||
1416 | |||
1417 | impl<'a> PlaceholderPat<'a> {} | ||
1418 | |||
1419 | // PlaceholderType | ||
1420 | #[derive(Debug, Clone, Copy)] | ||
1421 | pub struct PlaceholderType<'a> { | ||
1422 | syntax: SyntaxNodeRef<'a>, | ||
1423 | } | ||
1424 | |||
1425 | impl<'a> AstNode<'a> for PlaceholderType<'a> { | ||
1426 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1427 | match syntax.kind() { | ||
1428 | PLACEHOLDER_TYPE => Some(PlaceholderType { syntax }), | ||
1429 | _ => None, | ||
1430 | } | ||
1431 | } | ||
1432 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1433 | } | ||
1434 | |||
1435 | impl<'a> PlaceholderType<'a> {} | ||
1436 | |||
1437 | // PointerType | ||
1438 | #[derive(Debug, Clone, Copy)] | ||
1439 | pub struct PointerType<'a> { | ||
1440 | syntax: SyntaxNodeRef<'a>, | ||
1441 | } | ||
1442 | |||
1443 | impl<'a> AstNode<'a> for PointerType<'a> { | ||
1444 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1445 | match syntax.kind() { | ||
1446 | POINTER_TYPE => Some(PointerType { syntax }), | ||
1447 | _ => None, | ||
1448 | } | ||
1449 | } | ||
1450 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1451 | } | ||
1452 | |||
1453 | impl<'a> PointerType<'a> {} | ||
1454 | |||
1455 | // PrefixExpr | ||
1456 | #[derive(Debug, Clone, Copy)] | ||
1457 | pub struct PrefixExpr<'a> { | ||
1458 | syntax: SyntaxNodeRef<'a>, | ||
1459 | } | ||
1460 | |||
1461 | impl<'a> AstNode<'a> for PrefixExpr<'a> { | ||
1462 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1463 | match syntax.kind() { | ||
1464 | PREFIX_EXPR => Some(PrefixExpr { syntax }), | ||
1465 | _ => None, | ||
1466 | } | ||
1467 | } | ||
1468 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1469 | } | ||
1470 | |||
1471 | impl<'a> PrefixExpr<'a> {} | ||
1472 | |||
1473 | // RangeExpr | ||
1474 | #[derive(Debug, Clone, Copy)] | ||
1475 | pub struct RangeExpr<'a> { | ||
1476 | syntax: SyntaxNodeRef<'a>, | ||
1477 | } | ||
1478 | |||
1479 | impl<'a> AstNode<'a> for RangeExpr<'a> { | ||
1480 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1481 | match syntax.kind() { | ||
1482 | RANGE_EXPR => Some(RangeExpr { syntax }), | ||
1483 | _ => None, | ||
1484 | } | ||
1485 | } | ||
1486 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1487 | } | ||
1488 | |||
1489 | impl<'a> RangeExpr<'a> {} | ||
1490 | |||
1491 | // RangePat | ||
1492 | #[derive(Debug, Clone, Copy)] | ||
1493 | pub struct RangePat<'a> { | ||
1494 | syntax: SyntaxNodeRef<'a>, | ||
1495 | } | ||
1496 | |||
1497 | impl<'a> AstNode<'a> for RangePat<'a> { | ||
1498 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1499 | match syntax.kind() { | ||
1500 | RANGE_PAT => Some(RangePat { syntax }), | ||
1501 | _ => None, | ||
1502 | } | ||
1503 | } | ||
1504 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1505 | } | ||
1506 | |||
1507 | impl<'a> RangePat<'a> {} | ||
1508 | |||
1509 | // RefExpr | ||
1510 | #[derive(Debug, Clone, Copy)] | ||
1511 | pub struct RefExpr<'a> { | ||
1512 | syntax: SyntaxNodeRef<'a>, | ||
1513 | } | ||
1514 | |||
1515 | impl<'a> AstNode<'a> for RefExpr<'a> { | ||
1516 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1517 | match syntax.kind() { | ||
1518 | REF_EXPR => Some(RefExpr { syntax }), | ||
1519 | _ => None, | ||
1520 | } | ||
1521 | } | ||
1522 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1523 | } | ||
1524 | |||
1525 | impl<'a> RefExpr<'a> {} | ||
1526 | |||
1527 | // RefPat | ||
1528 | #[derive(Debug, Clone, Copy)] | ||
1529 | pub struct RefPat<'a> { | ||
1530 | syntax: SyntaxNodeRef<'a>, | ||
1531 | } | ||
1532 | |||
1533 | impl<'a> AstNode<'a> for RefPat<'a> { | ||
1534 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1535 | match syntax.kind() { | ||
1536 | REF_PAT => Some(RefPat { syntax }), | ||
1537 | _ => None, | ||
1538 | } | ||
1539 | } | ||
1540 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1541 | } | ||
1542 | |||
1543 | impl<'a> RefPat<'a> {} | ||
1544 | |||
1545 | // ReferenceType | ||
1546 | #[derive(Debug, Clone, Copy)] | ||
1547 | pub struct ReferenceType<'a> { | ||
1548 | syntax: SyntaxNodeRef<'a>, | ||
1549 | } | ||
1550 | |||
1551 | impl<'a> AstNode<'a> for ReferenceType<'a> { | ||
1552 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1553 | match syntax.kind() { | ||
1554 | REFERENCE_TYPE => Some(ReferenceType { syntax }), | ||
1555 | _ => None, | ||
1556 | } | ||
1557 | } | ||
1558 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1559 | } | ||
1560 | |||
1561 | impl<'a> ReferenceType<'a> {} | ||
1562 | |||
1563 | // RetType | ||
1564 | #[derive(Debug, Clone, Copy)] | ||
1565 | pub struct RetType<'a> { | ||
1566 | syntax: SyntaxNodeRef<'a>, | ||
1567 | } | ||
1568 | |||
1569 | impl<'a> AstNode<'a> for RetType<'a> { | ||
1570 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1571 | match syntax.kind() { | ||
1572 | RET_TYPE => Some(RetType { syntax }), | ||
1573 | _ => None, | ||
1574 | } | ||
1575 | } | ||
1576 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1577 | } | ||
1578 | |||
1579 | impl<'a> RetType<'a> {} | ||
1580 | |||
1581 | // ReturnExpr | ||
1582 | #[derive(Debug, Clone, Copy)] | ||
1583 | pub struct ReturnExpr<'a> { | ||
1584 | syntax: SyntaxNodeRef<'a>, | ||
1585 | } | ||
1586 | |||
1587 | impl<'a> AstNode<'a> for ReturnExpr<'a> { | ||
1588 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1589 | match syntax.kind() { | ||
1590 | RETURN_EXPR => Some(ReturnExpr { syntax }), | ||
1591 | _ => None, | ||
1592 | } | ||
1593 | } | ||
1594 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1595 | } | ||
1596 | |||
1597 | impl<'a> ReturnExpr<'a> {} | ||
1598 | |||
1599 | // Root | ||
1600 | #[derive(Debug, Clone, Copy)] | ||
1601 | pub struct Root<'a> { | ||
1602 | syntax: SyntaxNodeRef<'a>, | ||
1603 | } | ||
1604 | |||
1605 | impl<'a> AstNode<'a> for Root<'a> { | ||
1606 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1607 | match syntax.kind() { | ||
1608 | ROOT => Some(Root { syntax }), | ||
1609 | _ => None, | ||
1610 | } | ||
1611 | } | ||
1612 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1613 | } | ||
1614 | |||
1615 | impl<'a> ast::ModuleItemOwner<'a> for Root<'a> {} | ||
1616 | impl<'a> ast::FnDefOwner<'a> for Root<'a> {} | ||
1617 | impl<'a> Root<'a> { | ||
1618 | pub fn modules(self) -> impl Iterator<Item = Module<'a>> + 'a { | ||
1619 | super::children(self) | ||
1620 | } | ||
1621 | } | ||
1622 | |||
1623 | // SelfParam | ||
1624 | #[derive(Debug, Clone, Copy)] | ||
1625 | pub struct SelfParam<'a> { | ||
1626 | syntax: SyntaxNodeRef<'a>, | ||
1627 | } | ||
1628 | |||
1629 | impl<'a> AstNode<'a> for SelfParam<'a> { | ||
1630 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1631 | match syntax.kind() { | ||
1632 | SELF_PARAM => Some(SelfParam { syntax }), | ||
1633 | _ => None, | ||
1634 | } | ||
1635 | } | ||
1636 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1637 | } | ||
1638 | |||
1639 | impl<'a> SelfParam<'a> {} | ||
1640 | |||
1641 | // SlicePat | ||
1642 | #[derive(Debug, Clone, Copy)] | ||
1643 | pub struct SlicePat<'a> { | ||
1644 | syntax: SyntaxNodeRef<'a>, | ||
1645 | } | ||
1646 | |||
1647 | impl<'a> AstNode<'a> for SlicePat<'a> { | ||
1648 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1649 | match syntax.kind() { | ||
1650 | SLICE_PAT => Some(SlicePat { syntax }), | ||
1651 | _ => None, | ||
1652 | } | ||
1653 | } | ||
1654 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1655 | } | ||
1656 | |||
1657 | impl<'a> SlicePat<'a> {} | ||
1658 | |||
1659 | // SliceType | ||
1660 | #[derive(Debug, Clone, Copy)] | ||
1661 | pub struct SliceType<'a> { | ||
1662 | syntax: SyntaxNodeRef<'a>, | ||
1663 | } | ||
1664 | |||
1665 | impl<'a> AstNode<'a> for SliceType<'a> { | ||
1666 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1667 | match syntax.kind() { | ||
1668 | SLICE_TYPE => Some(SliceType { syntax }), | ||
1669 | _ => None, | ||
1670 | } | ||
1671 | } | ||
1672 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1673 | } | ||
1674 | |||
1675 | impl<'a> SliceType<'a> {} | ||
1676 | |||
1677 | // StaticDef | ||
1678 | #[derive(Debug, Clone, Copy)] | ||
1679 | pub struct StaticDef<'a> { | ||
1680 | syntax: SyntaxNodeRef<'a>, | ||
1681 | } | ||
1682 | |||
1683 | impl<'a> AstNode<'a> for StaticDef<'a> { | ||
1684 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1685 | match syntax.kind() { | ||
1686 | STATIC_DEF => Some(StaticDef { syntax }), | ||
1687 | _ => None, | ||
1688 | } | ||
1689 | } | ||
1690 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1691 | } | ||
1692 | |||
1693 | impl<'a> ast::NameOwner<'a> for StaticDef<'a> {} | ||
1694 | impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {} | ||
1695 | impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {} | ||
1696 | impl<'a> StaticDef<'a> {} | ||
1697 | |||
1698 | // Stmt | ||
1699 | #[derive(Debug, Clone, Copy)] | ||
1700 | pub enum Stmt<'a> { | ||
1701 | ExprStmt(ExprStmt<'a>), | ||
1702 | LetStmt(LetStmt<'a>), | ||
1703 | } | ||
1704 | |||
1705 | impl<'a> AstNode<'a> for Stmt<'a> { | ||
1706 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1707 | match syntax.kind() { | ||
1708 | EXPR_STMT => Some(Stmt::ExprStmt(ExprStmt { syntax })), | ||
1709 | LET_STMT => Some(Stmt::LetStmt(LetStmt { syntax })), | ||
1710 | _ => None, | ||
1711 | } | ||
1712 | } | ||
1713 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
1714 | match self { | ||
1715 | Stmt::ExprStmt(inner) => inner.syntax(), | ||
1716 | Stmt::LetStmt(inner) => inner.syntax(), | ||
1717 | } | ||
1718 | } | ||
1719 | } | ||
1720 | |||
1721 | impl<'a> Stmt<'a> {} | ||
1722 | |||
1723 | // StructDef | ||
1724 | #[derive(Debug, Clone, Copy)] | ||
1725 | pub struct StructDef<'a> { | ||
1726 | syntax: SyntaxNodeRef<'a>, | ||
1727 | } | ||
1728 | |||
1729 | impl<'a> AstNode<'a> for StructDef<'a> { | ||
1730 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1731 | match syntax.kind() { | ||
1732 | STRUCT_DEF => Some(StructDef { syntax }), | ||
1733 | _ => None, | ||
1734 | } | ||
1735 | } | ||
1736 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1737 | } | ||
1738 | |||
1739 | impl<'a> ast::NameOwner<'a> for StructDef<'a> {} | ||
1740 | impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} | ||
1741 | impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} | ||
1742 | impl<'a> StructDef<'a> { | ||
1743 | pub fn fields(self) -> impl Iterator<Item = NamedFieldDef<'a>> + 'a { | ||
1744 | super::children(self) | ||
1745 | } | ||
1746 | } | ||
1747 | |||
1748 | // StructLit | ||
1749 | #[derive(Debug, Clone, Copy)] | ||
1750 | pub struct StructLit<'a> { | ||
1751 | syntax: SyntaxNodeRef<'a>, | ||
1752 | } | ||
1753 | |||
1754 | impl<'a> AstNode<'a> for StructLit<'a> { | ||
1755 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1756 | match syntax.kind() { | ||
1757 | STRUCT_LIT => Some(StructLit { syntax }), | ||
1758 | _ => None, | ||
1759 | } | ||
1760 | } | ||
1761 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1762 | } | ||
1763 | |||
1764 | impl<'a> StructLit<'a> {} | ||
1765 | |||
1766 | // StructPat | ||
1767 | #[derive(Debug, Clone, Copy)] | ||
1768 | pub struct StructPat<'a> { | ||
1769 | syntax: SyntaxNodeRef<'a>, | ||
1770 | } | ||
1771 | |||
1772 | impl<'a> AstNode<'a> for StructPat<'a> { | ||
1773 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1774 | match syntax.kind() { | ||
1775 | STRUCT_PAT => Some(StructPat { syntax }), | ||
1776 | _ => None, | ||
1777 | } | ||
1778 | } | ||
1779 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1780 | } | ||
1781 | |||
1782 | impl<'a> StructPat<'a> {} | ||
1783 | |||
1784 | // TokenTree | ||
1785 | #[derive(Debug, Clone, Copy)] | ||
1786 | pub struct TokenTree<'a> { | ||
1787 | syntax: SyntaxNodeRef<'a>, | ||
1788 | } | ||
1789 | |||
1790 | impl<'a> AstNode<'a> for TokenTree<'a> { | ||
1791 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1792 | match syntax.kind() { | ||
1793 | TOKEN_TREE => Some(TokenTree { syntax }), | ||
1794 | _ => None, | ||
1795 | } | ||
1796 | } | ||
1797 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1798 | } | ||
1799 | |||
1800 | impl<'a> TokenTree<'a> {} | ||
1801 | |||
1802 | // TraitDef | ||
1803 | #[derive(Debug, Clone, Copy)] | ||
1804 | pub struct TraitDef<'a> { | ||
1805 | syntax: SyntaxNodeRef<'a>, | ||
1806 | } | ||
1807 | |||
1808 | impl<'a> AstNode<'a> for TraitDef<'a> { | ||
1809 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1810 | match syntax.kind() { | ||
1811 | TRAIT_DEF => Some(TraitDef { syntax }), | ||
1812 | _ => None, | ||
1813 | } | ||
1814 | } | ||
1815 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1816 | } | ||
1817 | |||
1818 | impl<'a> ast::NameOwner<'a> for TraitDef<'a> {} | ||
1819 | impl<'a> ast::AttrsOwner<'a> for TraitDef<'a> {} | ||
1820 | impl<'a> TraitDef<'a> {} | ||
1821 | |||
1822 | // TryExpr | ||
1823 | #[derive(Debug, Clone, Copy)] | ||
1824 | pub struct TryExpr<'a> { | ||
1825 | syntax: SyntaxNodeRef<'a>, | ||
1826 | } | ||
1827 | |||
1828 | impl<'a> AstNode<'a> for TryExpr<'a> { | ||
1829 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1830 | match syntax.kind() { | ||
1831 | TRY_EXPR => Some(TryExpr { syntax }), | ||
1832 | _ => None, | ||
1833 | } | ||
1834 | } | ||
1835 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1836 | } | ||
1837 | |||
1838 | impl<'a> TryExpr<'a> {} | ||
1839 | |||
1840 | // TupleExpr | ||
1841 | #[derive(Debug, Clone, Copy)] | ||
1842 | pub struct TupleExpr<'a> { | ||
1843 | syntax: SyntaxNodeRef<'a>, | ||
1844 | } | ||
1845 | |||
1846 | impl<'a> AstNode<'a> for TupleExpr<'a> { | ||
1847 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1848 | match syntax.kind() { | ||
1849 | TUPLE_EXPR => Some(TupleExpr { syntax }), | ||
1850 | _ => None, | ||
1851 | } | ||
1852 | } | ||
1853 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1854 | } | ||
1855 | |||
1856 | impl<'a> TupleExpr<'a> {} | ||
1857 | |||
1858 | // TuplePat | ||
1859 | #[derive(Debug, Clone, Copy)] | ||
1860 | pub struct TuplePat<'a> { | ||
1861 | syntax: SyntaxNodeRef<'a>, | ||
1862 | } | ||
1863 | |||
1864 | impl<'a> AstNode<'a> for TuplePat<'a> { | ||
1865 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1866 | match syntax.kind() { | ||
1867 | TUPLE_PAT => Some(TuplePat { syntax }), | ||
1868 | _ => None, | ||
1869 | } | ||
1870 | } | ||
1871 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1872 | } | ||
1873 | |||
1874 | impl<'a> TuplePat<'a> {} | ||
1875 | |||
1876 | // TupleStructPat | ||
1877 | #[derive(Debug, Clone, Copy)] | ||
1878 | pub struct TupleStructPat<'a> { | ||
1879 | syntax: SyntaxNodeRef<'a>, | ||
1880 | } | ||
1881 | |||
1882 | impl<'a> AstNode<'a> for TupleStructPat<'a> { | ||
1883 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1884 | match syntax.kind() { | ||
1885 | TUPLE_STRUCT_PAT => Some(TupleStructPat { syntax }), | ||
1886 | _ => None, | ||
1887 | } | ||
1888 | } | ||
1889 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1890 | } | ||
1891 | |||
1892 | impl<'a> TupleStructPat<'a> {} | ||
1893 | |||
1894 | // TupleType | ||
1895 | #[derive(Debug, Clone, Copy)] | ||
1896 | pub struct TupleType<'a> { | ||
1897 | syntax: SyntaxNodeRef<'a>, | ||
1898 | } | ||
1899 | |||
1900 | impl<'a> AstNode<'a> for TupleType<'a> { | ||
1901 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1902 | match syntax.kind() { | ||
1903 | TUPLE_TYPE => Some(TupleType { syntax }), | ||
1904 | _ => None, | ||
1905 | } | ||
1906 | } | ||
1907 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1908 | } | ||
1909 | |||
1910 | impl<'a> TupleType<'a> {} | ||
1911 | |||
1912 | // TypeDef | ||
1913 | #[derive(Debug, Clone, Copy)] | ||
1914 | pub struct TypeDef<'a> { | ||
1915 | syntax: SyntaxNodeRef<'a>, | ||
1916 | } | ||
1917 | |||
1918 | impl<'a> AstNode<'a> for TypeDef<'a> { | ||
1919 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1920 | match syntax.kind() { | ||
1921 | TYPE_DEF => Some(TypeDef { syntax }), | ||
1922 | _ => None, | ||
1923 | } | ||
1924 | } | ||
1925 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1926 | } | ||
1927 | |||
1928 | impl<'a> ast::NameOwner<'a> for TypeDef<'a> {} | ||
1929 | impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {} | ||
1930 | impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {} | ||
1931 | impl<'a> TypeDef<'a> {} | ||
1932 | |||
1933 | // TypeParam | ||
1934 | #[derive(Debug, Clone, Copy)] | ||
1935 | pub struct TypeParam<'a> { | ||
1936 | syntax: SyntaxNodeRef<'a>, | ||
1937 | } | ||
1938 | |||
1939 | impl<'a> AstNode<'a> for TypeParam<'a> { | ||
1940 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1941 | match syntax.kind() { | ||
1942 | TYPE_PARAM => Some(TypeParam { syntax }), | ||
1943 | _ => None, | ||
1944 | } | ||
1945 | } | ||
1946 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1947 | } | ||
1948 | |||
1949 | impl<'a> ast::NameOwner<'a> for TypeParam<'a> {} | ||
1950 | impl<'a> TypeParam<'a> {} | ||
1951 | |||
1952 | // TypeParamList | ||
1953 | #[derive(Debug, Clone, Copy)] | ||
1954 | pub struct TypeParamList<'a> { | ||
1955 | syntax: SyntaxNodeRef<'a>, | ||
1956 | } | ||
1957 | |||
1958 | impl<'a> AstNode<'a> for TypeParamList<'a> { | ||
1959 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1960 | match syntax.kind() { | ||
1961 | TYPE_PARAM_LIST => Some(TypeParamList { syntax }), | ||
1962 | _ => None, | ||
1963 | } | ||
1964 | } | ||
1965 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
1966 | } | ||
1967 | |||
1968 | impl<'a> TypeParamList<'a> { | ||
1969 | pub fn type_params(self) -> impl Iterator<Item = TypeParam<'a>> + 'a { | ||
1970 | super::children(self) | ||
1971 | } | ||
1972 | |||
1973 | pub fn lifetime_params(self) -> impl Iterator<Item = LifetimeParam<'a>> + 'a { | ||
1974 | super::children(self) | ||
1975 | } | ||
1976 | } | ||
1977 | |||
1978 | // TypeRef | ||
1979 | #[derive(Debug, Clone, Copy)] | ||
1980 | pub enum TypeRef<'a> { | ||
1981 | ParenType(ParenType<'a>), | ||
1982 | TupleType(TupleType<'a>), | ||
1983 | NeverType(NeverType<'a>), | ||
1984 | PathType(PathType<'a>), | ||
1985 | PointerType(PointerType<'a>), | ||
1986 | ArrayType(ArrayType<'a>), | ||
1987 | SliceType(SliceType<'a>), | ||
1988 | ReferenceType(ReferenceType<'a>), | ||
1989 | PlaceholderType(PlaceholderType<'a>), | ||
1990 | FnPointerType(FnPointerType<'a>), | ||
1991 | ForType(ForType<'a>), | ||
1992 | ImplTraitType(ImplTraitType<'a>), | ||
1993 | DynTraitType(DynTraitType<'a>), | ||
1994 | } | ||
1995 | |||
1996 | impl<'a> AstNode<'a> for TypeRef<'a> { | ||
1997 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
1998 | match syntax.kind() { | ||
1999 | PAREN_TYPE => Some(TypeRef::ParenType(ParenType { syntax })), | ||
2000 | TUPLE_TYPE => Some(TypeRef::TupleType(TupleType { syntax })), | ||
2001 | NEVER_TYPE => Some(TypeRef::NeverType(NeverType { syntax })), | ||
2002 | PATH_TYPE => Some(TypeRef::PathType(PathType { syntax })), | ||
2003 | POINTER_TYPE => Some(TypeRef::PointerType(PointerType { syntax })), | ||
2004 | ARRAY_TYPE => Some(TypeRef::ArrayType(ArrayType { syntax })), | ||
2005 | SLICE_TYPE => Some(TypeRef::SliceType(SliceType { syntax })), | ||
2006 | REFERENCE_TYPE => Some(TypeRef::ReferenceType(ReferenceType { syntax })), | ||
2007 | PLACEHOLDER_TYPE => Some(TypeRef::PlaceholderType(PlaceholderType { syntax })), | ||
2008 | FN_POINTER_TYPE => Some(TypeRef::FnPointerType(FnPointerType { syntax })), | ||
2009 | FOR_TYPE => Some(TypeRef::ForType(ForType { syntax })), | ||
2010 | IMPL_TRAIT_TYPE => Some(TypeRef::ImplTraitType(ImplTraitType { syntax })), | ||
2011 | DYN_TRAIT_TYPE => Some(TypeRef::DynTraitType(DynTraitType { syntax })), | ||
2012 | _ => None, | ||
2013 | } | ||
2014 | } | ||
2015 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
2016 | match self { | ||
2017 | TypeRef::ParenType(inner) => inner.syntax(), | ||
2018 | TypeRef::TupleType(inner) => inner.syntax(), | ||
2019 | TypeRef::NeverType(inner) => inner.syntax(), | ||
2020 | TypeRef::PathType(inner) => inner.syntax(), | ||
2021 | TypeRef::PointerType(inner) => inner.syntax(), | ||
2022 | TypeRef::ArrayType(inner) => inner.syntax(), | ||
2023 | TypeRef::SliceType(inner) => inner.syntax(), | ||
2024 | TypeRef::ReferenceType(inner) => inner.syntax(), | ||
2025 | TypeRef::PlaceholderType(inner) => inner.syntax(), | ||
2026 | TypeRef::FnPointerType(inner) => inner.syntax(), | ||
2027 | TypeRef::ForType(inner) => inner.syntax(), | ||
2028 | TypeRef::ImplTraitType(inner) => inner.syntax(), | ||
2029 | TypeRef::DynTraitType(inner) => inner.syntax(), | ||
2030 | } | ||
2031 | } | ||
2032 | } | ||
2033 | |||
2034 | impl<'a> TypeRef<'a> {} | ||
2035 | |||
2036 | // UseItem | ||
2037 | #[derive(Debug, Clone, Copy)] | ||
2038 | pub struct UseItem<'a> { | ||
2039 | syntax: SyntaxNodeRef<'a>, | ||
2040 | } | ||
2041 | |||
2042 | impl<'a> AstNode<'a> for UseItem<'a> { | ||
2043 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2044 | match syntax.kind() { | ||
2045 | USE_ITEM => Some(UseItem { syntax }), | ||
2046 | _ => None, | ||
2047 | } | ||
2048 | } | ||
2049 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2050 | } | ||
2051 | |||
2052 | impl<'a> UseItem<'a> {pub fn use_tree(self) -> Option<UseTree<'a>> { | ||
2053 | super::child_opt(self) | ||
2054 | } | ||
2055 | } | ||
2056 | |||
2057 | // UseTree | ||
2058 | #[derive(Debug, Clone, Copy)] | ||
2059 | pub struct UseTree<'a> { | ||
2060 | syntax: SyntaxNodeRef<'a>, | ||
2061 | } | ||
2062 | |||
2063 | impl<'a> AstNode<'a> for UseTree<'a> { | ||
2064 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2065 | match syntax.kind() { | ||
2066 | USE_TREE => Some(UseTree { syntax }), | ||
2067 | _ => None, | ||
2068 | } | ||
2069 | } | ||
2070 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2071 | } | ||
2072 | |||
2073 | impl<'a> UseTree<'a> {pub fn path(self) -> Option<Path<'a>> { | ||
2074 | super::child_opt(self) | ||
2075 | } | ||
2076 | pub fn use_tree_list(self) -> Option<UseTreeList<'a>> { | ||
2077 | super::child_opt(self) | ||
2078 | } | ||
2079 | } | ||
2080 | |||
2081 | // UseTreeList | ||
2082 | #[derive(Debug, Clone, Copy)] | ||
2083 | pub struct UseTreeList<'a> { | ||
2084 | syntax: SyntaxNodeRef<'a>, | ||
2085 | } | ||
2086 | |||
2087 | impl<'a> AstNode<'a> for UseTreeList<'a> { | ||
2088 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2089 | match syntax.kind() { | ||
2090 | USE_TREE_LIST => Some(UseTreeList { syntax }), | ||
2091 | _ => None, | ||
2092 | } | ||
2093 | } | ||
2094 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2095 | } | ||
2096 | |||
2097 | impl<'a> UseTreeList<'a> { | ||
2098 | pub fn use_trees(self) -> impl Iterator<Item = UseTree<'a>> + 'a { | ||
2099 | super::children(self) | ||
2100 | } | ||
2101 | } | ||
2102 | |||
2103 | // WhereClause | ||
2104 | #[derive(Debug, Clone, Copy)] | ||
2105 | pub struct WhereClause<'a> { | ||
2106 | syntax: SyntaxNodeRef<'a>, | ||
2107 | } | ||
2108 | |||
2109 | impl<'a> AstNode<'a> for WhereClause<'a> { | ||
2110 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2111 | match syntax.kind() { | ||
2112 | WHERE_CLAUSE => Some(WhereClause { syntax }), | ||
2113 | _ => None, | ||
2114 | } | ||
2115 | } | ||
2116 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2117 | } | ||
2118 | |||
2119 | impl<'a> WhereClause<'a> {} | ||
2120 | |||
2121 | // WhileExpr | ||
2122 | #[derive(Debug, Clone, Copy)] | ||
2123 | pub struct WhileExpr<'a> { | ||
2124 | syntax: SyntaxNodeRef<'a>, | ||
2125 | } | ||
2126 | |||
2127 | impl<'a> AstNode<'a> for WhileExpr<'a> { | ||
2128 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
2129 | match syntax.kind() { | ||
2130 | WHILE_EXPR => Some(WhileExpr { syntax }), | ||
2131 | _ => None, | ||
2132 | } | ||
2133 | } | ||
2134 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
2135 | } | ||
2136 | |||
2137 | impl<'a> ast::LoopBodyOwner<'a> for WhileExpr<'a> {} | ||
2138 | impl<'a> WhileExpr<'a> {pub fn condition(self) -> Option<Condition<'a>> { | ||
2139 | super::child_opt(self) | ||
2140 | } | ||
2141 | } | ||
2142 | |||
diff --git a/crates/ra_syntax/src/ast/generated.rs.tera b/crates/ra_syntax/src/ast/generated.rs.tera new file mode 100644 index 000000000..a72e9b732 --- /dev/null +++ b/crates/ra_syntax/src/ast/generated.rs.tera | |||
@@ -0,0 +1,83 @@ | |||
1 | use { | ||
2 | ast, | ||
3 | SyntaxNodeRef, AstNode, | ||
4 | SyntaxKind::*, | ||
5 | }; | ||
6 | {% for node, methods in ast %} | ||
7 | // {{ node }} | ||
8 | {%- if methods.enum %} | ||
9 | #[derive(Debug, Clone, Copy)] | ||
10 | pub enum {{ node }}<'a> { | ||
11 | {%- for kind in methods.enum %} | ||
12 | {{ kind }}({{ kind }}<'a>), | ||
13 | {%- endfor %} | ||
14 | } | ||
15 | |||
16 | impl<'a> AstNode<'a> for {{ node }}<'a> { | ||
17 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
18 | match syntax.kind() { | ||
19 | {%- for kind in methods.enum %} | ||
20 | {{ kind | SCREAM }} => Some({{ node }}::{{ kind }}({{ kind }} { syntax })), | ||
21 | {%- endfor %} | ||
22 | _ => None, | ||
23 | } | ||
24 | } | ||
25 | fn syntax(self) -> SyntaxNodeRef<'a> { | ||
26 | match self { | ||
27 | {%- for kind in methods.enum %} | ||
28 | {{ node }}::{{ kind }}(inner) => inner.syntax(), | ||
29 | {%- endfor %} | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | {% else %} | ||
34 | #[derive(Debug, Clone, Copy)] | ||
35 | pub struct {{ node }}<'a> { | ||
36 | syntax: SyntaxNodeRef<'a>, | ||
37 | } | ||
38 | |||
39 | impl<'a> AstNode<'a> for {{ node }}<'a> { | ||
40 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> { | ||
41 | match syntax.kind() { | ||
42 | {{ node | SCREAM }} => Some({{ node }} { syntax }), | ||
43 | _ => None, | ||
44 | } | ||
45 | } | ||
46 | fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } | ||
47 | } | ||
48 | {% endif %} | ||
49 | {% if methods.traits -%} | ||
50 | {%- for t in methods.traits -%} | ||
51 | impl<'a> ast::{{ t }}<'a> for {{ node }}<'a> {} | ||
52 | {% endfor -%} | ||
53 | {%- endif -%} | ||
54 | |||
55 | impl<'a> {{ node }}<'a> { | ||
56 | {%- if methods.collections -%} | ||
57 | {%- for m in methods.collections -%} | ||
58 | {%- set method_name = m.0 -%} | ||
59 | {%- set ChildName = m.1 %} | ||
60 | pub fn {{ method_name }}(self) -> impl Iterator<Item = {{ ChildName }}<'a>> + 'a { | ||
61 | super::children(self) | ||
62 | } | ||
63 | {% endfor -%} | ||
64 | {%- endif -%} | ||
65 | |||
66 | {%- if methods.options -%} | ||
67 | {%- for m in methods.options -%} | ||
68 | |||
69 | {%- if m is string -%} | ||
70 | {%- set method_name = m | snake -%} | ||
71 | {%- set ChildName = m %} | ||
72 | {%- else -%} | ||
73 | {%- set method_name = m.0 -%} | ||
74 | {%- set ChildName = m.1 %} | ||
75 | {%- endif -%} | ||
76 | |||
77 | pub fn {{ method_name }}(self) -> Option<{{ ChildName }}<'a>> { | ||
78 | super::child_opt(self) | ||
79 | } | ||
80 | {% endfor -%} | ||
81 | {%- endif -%} | ||
82 | } | ||
83 | {% endfor %} | ||
diff --git a/crates/ra_syntax/src/ast/mod.rs b/crates/ra_syntax/src/ast/mod.rs new file mode 100644 index 000000000..a6da82957 --- /dev/null +++ b/crates/ra_syntax/src/ast/mod.rs | |||
@@ -0,0 +1,206 @@ | |||
1 | mod generated; | ||
2 | |||
3 | use std::marker::PhantomData; | ||
4 | |||
5 | use itertools::Itertools; | ||
6 | use smol_str::SmolStr; | ||
7 | |||
8 | use { | ||
9 | SyntaxNodeRef, SyntaxKind::*, | ||
10 | yellow::{RefRoot, SyntaxNodeChildren}, | ||
11 | }; | ||
12 | pub use self::generated::*; | ||
13 | |||
14 | pub trait AstNode<'a>: Clone + Copy + 'a { | ||
15 | fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> | ||
16 | where Self: Sized; | ||
17 | fn syntax(self) -> SyntaxNodeRef<'a>; | ||
18 | } | ||
19 | |||
20 | pub trait NameOwner<'a>: AstNode<'a> { | ||
21 | fn name(self) -> Option<Name<'a>> { | ||
22 | child_opt(self) | ||
23 | } | ||
24 | } | ||
25 | |||
26 | pub trait LoopBodyOwner<'a>: AstNode<'a> { | ||
27 | fn loop_body(self) -> Option<Block<'a>> { | ||
28 | child_opt(self) | ||
29 | } | ||
30 | } | ||
31 | |||
32 | pub trait ArgListOwner<'a>: AstNode<'a> { | ||
33 | fn arg_list(self) -> Option<ArgList<'a>> { | ||
34 | child_opt(self) | ||
35 | } | ||
36 | } | ||
37 | |||
38 | pub trait FnDefOwner<'a>: AstNode<'a> { | ||
39 | fn functions(self) -> AstChildren<'a, FnDef<'a>> { | ||
40 | children(self) | ||
41 | } | ||
42 | } | ||
43 | |||
44 | pub trait ModuleItemOwner<'a>: AstNode<'a> { | ||
45 | fn items(self) -> AstChildren<'a, ModuleItem<'a>> { | ||
46 | children(self) | ||
47 | } | ||
48 | } | ||
49 | |||
50 | pub trait TypeParamsOwner<'a>: AstNode<'a> { | ||
51 | fn type_param_list(self) -> Option<TypeParamList<'a>> { | ||
52 | child_opt(self) | ||
53 | } | ||
54 | |||
55 | fn where_clause(self) -> Option<WhereClause<'a>> { | ||
56 | child_opt(self) | ||
57 | } | ||
58 | } | ||
59 | |||
60 | pub trait AttrsOwner<'a>: AstNode<'a> { | ||
61 | fn attrs(self) -> AstChildren<'a, Attr<'a>> { | ||
62 | children(self) | ||
63 | } | ||
64 | } | ||
65 | |||
66 | impl<'a> FnDef<'a> { | ||
67 | pub fn has_atom_attr(&self, atom: &str) -> bool { | ||
68 | self.attrs() | ||
69 | .filter_map(|x| x.as_atom()) | ||
70 | .any(|x| x == atom) | ||
71 | } | ||
72 | } | ||
73 | |||
74 | impl<'a> Attr<'a> { | ||
75 | pub fn as_atom(&self) -> Option<SmolStr> { | ||
76 | let tt = self.value()?; | ||
77 | let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; | ||
78 | if attr.kind() == IDENT { | ||
79 | Some(attr.leaf_text().unwrap()) | ||
80 | } else { | ||
81 | None | ||
82 | } | ||
83 | } | ||
84 | |||
85 | pub fn as_call(&self) -> Option<(SmolStr, TokenTree<'a>)> { | ||
86 | let tt = self.value()?; | ||
87 | let (_bra, attr, args, _ket) = tt.syntax().children().collect_tuple()?; | ||
88 | let args = TokenTree::cast(args)?; | ||
89 | if attr.kind() == IDENT { | ||
90 | Some((attr.leaf_text().unwrap(), args)) | ||
91 | } else { | ||
92 | None | ||
93 | } | ||
94 | } | ||
95 | } | ||
96 | |||
97 | impl<'a> Lifetime<'a> { | ||
98 | pub fn text(&self) -> SmolStr { | ||
99 | self.syntax().leaf_text().unwrap() | ||
100 | } | ||
101 | } | ||
102 | |||
103 | impl<'a> Name<'a> { | ||
104 | pub fn text(&self) -> SmolStr { | ||
105 | let ident = self.syntax().first_child() | ||
106 | .unwrap(); | ||
107 | ident.leaf_text().unwrap() | ||
108 | } | ||
109 | } | ||
110 | |||
111 | impl<'a> NameRef<'a> { | ||
112 | pub fn text(&self) -> SmolStr { | ||
113 | let ident = self.syntax().first_child() | ||
114 | .unwrap(); | ||
115 | ident.leaf_text().unwrap() | ||
116 | } | ||
117 | } | ||
118 | |||
119 | impl<'a> ImplItem<'a> { | ||
120 | pub fn target_type(self) -> Option<TypeRef<'a>> { | ||
121 | match self.target() { | ||
122 | (Some(t), None) | (_, Some(t)) => Some(t), | ||
123 | _ => None, | ||
124 | } | ||
125 | } | ||
126 | |||
127 | pub fn target_trait(self) -> Option<TypeRef<'a>> { | ||
128 | match self.target() { | ||
129 | (Some(t), Some(_)) => Some(t), | ||
130 | _ => None, | ||
131 | } | ||
132 | } | ||
133 | |||
134 | fn target(self) -> (Option<TypeRef<'a>>, Option<TypeRef<'a>>) { | ||
135 | let mut types = children(self); | ||
136 | let first = types.next(); | ||
137 | let second = types.next(); | ||
138 | (first, second) | ||
139 | } | ||
140 | } | ||
141 | |||
142 | impl<'a> Module<'a> { | ||
143 | pub fn has_semi(self) -> bool { | ||
144 | match self.syntax().last_child() { | ||
145 | None => false, | ||
146 | Some(node) => node.kind() == SEMI, | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | impl<'a> LetStmt<'a> { | ||
152 | pub fn has_semi(self) -> bool { | ||
153 | match self.syntax().last_child() { | ||
154 | None => false, | ||
155 | Some(node) => node.kind() == SEMI, | ||
156 | } | ||
157 | } | ||
158 | } | ||
159 | |||
160 | impl<'a> IfExpr<'a> { | ||
161 | pub fn then_branch(self) -> Option<Block<'a>> { | ||
162 | self.blocks().nth(0) | ||
163 | } | ||
164 | pub fn else_branch(self) -> Option<Block<'a>> { | ||
165 | self.blocks().nth(1) | ||
166 | } | ||
167 | fn blocks(self) -> AstChildren<'a, Block<'a>> { | ||
168 | children(self) | ||
169 | } | ||
170 | } | ||
171 | |||
172 | fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option<C> { | ||
173 | children(parent).next() | ||
174 | } | ||
175 | |||
176 | fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> AstChildren<'a, C> { | ||
177 | AstChildren::new(parent.syntax()) | ||
178 | } | ||
179 | |||
180 | |||
181 | #[derive(Debug)] | ||
182 | pub struct AstChildren<'a, N> { | ||
183 | inner: SyntaxNodeChildren<RefRoot<'a>>, | ||
184 | ph: PhantomData<N>, | ||
185 | } | ||
186 | |||
187 | impl<'a, N> AstChildren<'a, N> { | ||
188 | fn new(parent: SyntaxNodeRef<'a>) -> Self { | ||
189 | AstChildren { | ||
190 | inner: parent.children(), | ||
191 | ph: PhantomData, | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
196 | impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> { | ||
197 | type Item = N; | ||
198 | fn next(&mut self) -> Option<N> { | ||
199 | loop { | ||
200 | match N::cast(self.inner.next()?) { | ||
201 | Some(n) => return Some(n), | ||
202 | None => (), | ||
203 | } | ||
204 | } | ||
205 | } | ||
206 | } | ||
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron new file mode 100644 index 000000000..77ae4c7db --- /dev/null +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -0,0 +1,538 @@ | |||
1 | Grammar( | ||
2 | single_byte_tokens: [ | ||
3 | [";", "SEMI"], | ||
4 | [",", "COMMA"], | ||
5 | ["(", "L_PAREN"], | ||
6 | [")", "R_PAREN"], | ||
7 | ["{", "L_CURLY"], | ||
8 | ["}", "R_CURLY"], | ||
9 | ["[", "L_BRACK"], | ||
10 | ["]", "R_BRACK"], | ||
11 | ["<", "L_ANGLE"], | ||
12 | [">", "R_ANGLE"], | ||
13 | ["@", "AT"], | ||
14 | ["#", "POUND"], | ||
15 | ["~", "TILDE"], | ||
16 | ["?", "QUESTION"], | ||
17 | ["$", "DOLLAR"], | ||
18 | ["&", "AMP"], | ||
19 | ["|", "PIPE"], | ||
20 | ["+", "PLUS"], | ||
21 | ["*", "STAR"], | ||
22 | ["/", "SLASH"], | ||
23 | ["^", "CARET"], | ||
24 | ["%", "PERCENT"], | ||
25 | ], | ||
26 | multi_byte_tokens: [ | ||
27 | [".", "DOT"], | ||
28 | ["..", "DOTDOT"], | ||
29 | ["...", "DOTDOTDOT"], | ||
30 | ["..=", "DOTDOTEQ"], | ||
31 | [":", "COLON"], | ||
32 | ["::", "COLONCOLON"], | ||
33 | ["=", "EQ"], | ||
34 | ["==", "EQEQ"], | ||
35 | ["=>", "FAT_ARROW"], | ||
36 | ["!", "EXCL"], | ||
37 | ["!=", "NEQ"], | ||
38 | ["-", "MINUS"], | ||
39 | ["->", "THIN_ARROW"], | ||
40 | ["<=", "LTEQ"], | ||
41 | [">=", "GTEQ"], | ||
42 | ["+=", "PLUSEQ"], | ||
43 | ["-=", "MINUSEQ"], | ||
44 | ["|=", "PIPEEQ"], | ||
45 | ["&=", "AMPEQ"], | ||
46 | ["^=", "CARETEQ"], | ||
47 | ["/=", "SLASHEQ"], | ||
48 | ["*=", "STAREQ"], | ||
49 | ["&&", "AMPAMP"], | ||
50 | ["||", "PIPEPIPE"], | ||
51 | ["<<", "SHL"], | ||
52 | [">>", "SHR"], | ||
53 | ["<<=", "SHLEQ"], | ||
54 | [">>=", "SHREQ"], | ||
55 | ], | ||
56 | keywords: [ | ||
57 | "use", | ||
58 | "fn", | ||
59 | "struct", | ||
60 | "enum", | ||
61 | "trait", | ||
62 | "impl", | ||
63 | "dyn", | ||
64 | "true", | ||
65 | "false", | ||
66 | "as", | ||
67 | "extern", | ||
68 | "crate", | ||
69 | "mod", | ||
70 | "pub", | ||
71 | "self", | ||
72 | "super", | ||
73 | "in", | ||
74 | "where", | ||
75 | "for", | ||
76 | "loop", | ||
77 | "while", | ||
78 | "continue", | ||
79 | "break", | ||
80 | "if", | ||
81 | "else", | ||
82 | "match", | ||
83 | "const", | ||
84 | "static", | ||
85 | "mut", | ||
86 | "unsafe", | ||
87 | "type", | ||
88 | "ref", | ||
89 | "let", | ||
90 | "move", | ||
91 | "return", | ||
92 | ], | ||
93 | contextual_keywords: [ | ||
94 | "auto", | ||
95 | "default", | ||
96 | "union", | ||
97 | ], | ||
98 | tokens: [ | ||
99 | "ERROR", | ||
100 | "IDENT", | ||
101 | "UNDERSCORE", | ||
102 | "WHITESPACE", | ||
103 | "INT_NUMBER", | ||
104 | "FLOAT_NUMBER", | ||
105 | "LIFETIME", | ||
106 | "CHAR", | ||
107 | "BYTE", | ||
108 | "STRING", | ||
109 | "RAW_STRING", | ||
110 | "BYTE_STRING", | ||
111 | "RAW_BYTE_STRING", | ||
112 | "COMMENT", | ||
113 | "DOC_COMMENT", | ||
114 | "SHEBANG", | ||
115 | ], | ||
116 | nodes: [ | ||
117 | "ROOT", | ||
118 | |||
119 | "STRUCT_DEF", | ||
120 | "ENUM_DEF", | ||
121 | "FN_DEF", | ||
122 | "RET_TYPE", | ||
123 | "EXTERN_CRATE_ITEM", | ||
124 | "MODULE", | ||
125 | "USE_ITEM", | ||
126 | "STATIC_DEF", | ||
127 | "CONST_DEF", | ||
128 | "TRAIT_DEF", | ||
129 | "IMPL_ITEM", | ||
130 | "TYPE_DEF", | ||
131 | "MACRO_CALL", | ||
132 | "TOKEN_TREE", | ||
133 | |||
134 | "PAREN_TYPE", | ||
135 | "TUPLE_TYPE", | ||
136 | "NEVER_TYPE", | ||
137 | "PATH_TYPE", | ||
138 | "POINTER_TYPE", | ||
139 | "ARRAY_TYPE", | ||
140 | "SLICE_TYPE", | ||
141 | "REFERENCE_TYPE", | ||
142 | "PLACEHOLDER_TYPE", | ||
143 | "FN_POINTER_TYPE", | ||
144 | "FOR_TYPE", | ||
145 | "IMPL_TRAIT_TYPE", | ||
146 | "DYN_TRAIT_TYPE", | ||
147 | |||
148 | "REF_PAT", | ||
149 | "BIND_PAT", | ||
150 | "PLACEHOLDER_PAT", | ||
151 | "PATH_PAT", | ||
152 | "STRUCT_PAT", | ||
153 | "FIELD_PAT_LIST", | ||
154 | "TUPLE_STRUCT_PAT", | ||
155 | "TUPLE_PAT", | ||
156 | "SLICE_PAT", | ||
157 | "RANGE_PAT", | ||
158 | |||
159 | // atoms | ||
160 | "TUPLE_EXPR", | ||
161 | "ARRAY_EXPR", | ||
162 | "PAREN_EXPR", | ||
163 | "PATH_EXPR", | ||
164 | "LAMBDA_EXPR", | ||
165 | "IF_EXPR", | ||
166 | "WHILE_EXPR", | ||
167 | "CONDITION", | ||
168 | "LOOP_EXPR", | ||
169 | "FOR_EXPR", | ||
170 | "CONTINUE_EXPR", | ||
171 | "BREAK_EXPR", | ||
172 | "LABEL", | ||
173 | "BLOCK_EXPR", | ||
174 | "RETURN_EXPR", | ||
175 | "MATCH_EXPR", | ||
176 | "MATCH_ARM_LIST", | ||
177 | "MATCH_ARM", | ||
178 | "MATCH_GUARD", | ||
179 | "STRUCT_LIT", | ||
180 | "NAMED_FIELD_LIST", | ||
181 | "NAMED_FIELD", | ||
182 | |||
183 | // postfix | ||
184 | "CALL_EXPR", | ||
185 | "INDEX_EXPR", | ||
186 | "METHOD_CALL_EXPR", | ||
187 | "FIELD_EXPR", | ||
188 | "TRY_EXPR", | ||
189 | "CAST_EXPR", | ||
190 | |||
191 | // unary | ||
192 | "REF_EXPR", | ||
193 | "PREFIX_EXPR", | ||
194 | |||
195 | "RANGE_EXPR", // just weird | ||
196 | "BIN_EXPR", | ||
197 | |||
198 | "BLOCK", | ||
199 | "EXTERN_BLOCK", | ||
200 | "EXTERN_ITEM_LIST", | ||
201 | "ENUM_VARIANT", | ||
202 | "NAMED_FIELD_DEF_LIST", | ||
203 | "NAMED_FIELD_DEF", | ||
204 | "POS_FIELD_LIST", | ||
205 | "POS_FIELD", | ||
206 | "ENUM_VARIANT_LIST", | ||
207 | "ITEM_LIST", | ||
208 | "ATTR", | ||
209 | "META_ITEM", // not an item actually | ||
210 | "USE_TREE", | ||
211 | "USE_TREE_LIST", | ||
212 | "PATH", | ||
213 | "PATH_SEGMENT", | ||
214 | "LITERAL", | ||
215 | "ALIAS", | ||
216 | "VISIBILITY", | ||
217 | "WHERE_CLAUSE", | ||
218 | "WHERE_PRED", | ||
219 | "ABI", | ||
220 | "NAME", | ||
221 | "NAME_REF", | ||
222 | |||
223 | "LET_STMT", | ||
224 | "EXPR_STMT", | ||
225 | |||
226 | "TYPE_PARAM_LIST", | ||
227 | "LIFETIME_PARAM", | ||
228 | "TYPE_PARAM", | ||
229 | "TYPE_ARG_LIST", | ||
230 | "LIFETIME_ARG", | ||
231 | "TYPE_ARG", | ||
232 | "ASSOC_TYPE_ARG", | ||
233 | |||
234 | "PARAM_LIST", | ||
235 | "PARAM", | ||
236 | "SELF_PARAM", | ||
237 | "ARG_LIST", | ||
238 | ], | ||
239 | ast: { | ||
240 | "Root": ( | ||
241 | traits: [ "ModuleItemOwner", "FnDefOwner" ], | ||
242 | collections: [ | ||
243 | ["modules", "Module"], | ||
244 | ] | ||
245 | ), | ||
246 | "FnDef": ( | ||
247 | traits: [ | ||
248 | "NameOwner", | ||
249 | "TypeParamsOwner", | ||
250 | "AttrsOwner", | ||
251 | ], | ||
252 | options: [ "ParamList", ["body", "Block"], "RetType" ], | ||
253 | ), | ||
254 | "RetType": (), | ||
255 | "StructDef": ( | ||
256 | traits: [ | ||
257 | "NameOwner", | ||
258 | "TypeParamsOwner", | ||
259 | "AttrsOwner", | ||
260 | ], | ||
261 | collections: [ | ||
262 | ["fields", "NamedFieldDef"] | ||
263 | ] | ||
264 | ), | ||
265 | "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"] ), | ||
266 | "EnumDef": ( traits: [ | ||
267 | "NameOwner", | ||
268 | "TypeParamsOwner", | ||
269 | "AttrsOwner", | ||
270 | ] ), | ||
271 | "TraitDef": ( traits: ["NameOwner", "AttrsOwner"] ), | ||
272 | "Module": ( | ||
273 | traits: ["NameOwner", "AttrsOwner" ], | ||
274 | options: [ "ItemList" ] | ||
275 | ), | ||
276 | "ItemList": ( | ||
277 | traits: [ "FnDefOwner", "ModuleItemOwner" ], | ||
278 | ), | ||
279 | "ConstDef": ( traits: [ | ||
280 | "NameOwner", | ||
281 | "TypeParamsOwner", | ||
282 | "AttrsOwner", | ||
283 | ] ), | ||
284 | "StaticDef": ( traits: [ | ||
285 | "NameOwner", | ||
286 | "TypeParamsOwner", | ||
287 | "AttrsOwner", | ||
288 | ] ), | ||
289 | "TypeDef": ( traits: [ | ||
290 | "NameOwner", | ||
291 | "TypeParamsOwner", | ||
292 | "AttrsOwner", | ||
293 | ] ), | ||
294 | "ImplItem": (), | ||
295 | |||
296 | "ParenType": (), | ||
297 | "TupleType": (), | ||
298 | "NeverType": (), | ||
299 | "PathType": (), | ||
300 | "PointerType": (), | ||
301 | "ArrayType": (), | ||
302 | "SliceType": (), | ||
303 | "ReferenceType": (), | ||
304 | "PlaceholderType": (), | ||
305 | "FnPointerType": (), | ||
306 | "ForType": (), | ||
307 | "ImplTraitType": (), | ||
308 | "DynTraitType": (), | ||
309 | |||
310 | "TypeRef": ( enum: [ | ||
311 | "ParenType", | ||
312 | "TupleType", | ||
313 | "NeverType", | ||
314 | "PathType", | ||
315 | "PointerType", | ||
316 | "ArrayType", | ||
317 | "SliceType", | ||
318 | "ReferenceType", | ||
319 | "PlaceholderType", | ||
320 | "FnPointerType", | ||
321 | "ForType", | ||
322 | "ImplTraitType", | ||
323 | "DynTraitType", | ||
324 | ]), | ||
325 | |||
326 | "NominalDef": ( | ||
327 | enum: ["StructDef", "EnumDef"], | ||
328 | traits: [ | ||
329 | "NameOwner", | ||
330 | "TypeParamsOwner", | ||
331 | "AttrsOwner" | ||
332 | ], | ||
333 | ), | ||
334 | "ModuleItem": ( | ||
335 | enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplItem", | ||
336 | "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ] | ||
337 | ), | ||
338 | |||
339 | "TupleExpr": (), | ||
340 | "ArrayExpr": (), | ||
341 | "ParenExpr": (), | ||
342 | "PathExpr": (), | ||
343 | "LambdaExpr": ( | ||
344 | options: [ | ||
345 | "ParamList", | ||
346 | ["body", "Expr"], | ||
347 | ] | ||
348 | ), | ||
349 | "IfExpr": ( | ||
350 | options: [ "Condition" ] | ||
351 | ), | ||
352 | "LoopExpr": ( | ||
353 | traits: ["LoopBodyOwner"], | ||
354 | ), | ||
355 | "ForExpr": ( | ||
356 | traits: ["LoopBodyOwner"], | ||
357 | options: [ | ||
358 | "Pat", | ||
359 | ["iterable", "Expr"], | ||
360 | ] | ||
361 | ), | ||
362 | "WhileExpr": ( | ||
363 | traits: ["LoopBodyOwner"], | ||
364 | options: [ "Condition" ] | ||
365 | ), | ||
366 | "ContinueExpr": (), | ||
367 | "BreakExpr": (), | ||
368 | "Label": (), | ||
369 | "BlockExpr": ( | ||
370 | options: [ "Block" ] | ||
371 | ), | ||
372 | "ReturnExpr": (), | ||
373 | "MatchExpr": ( | ||
374 | options: [ "Expr", "MatchArmList" ], | ||
375 | ), | ||
376 | "MatchArmList": ( | ||
377 | collections: [ ["arms", "MatchArm"] ], | ||
378 | ), | ||
379 | "MatchArm": ( | ||
380 | options: [ | ||
381 | [ "guard", "MatchGuard" ], | ||
382 | "Expr", | ||
383 | ], | ||
384 | collections: [ [ "pats", "Pat" ] ] | ||
385 | ), | ||
386 | "MatchGuard": (), | ||
387 | "StructLit": (), | ||
388 | "NamedFieldList": (), | ||
389 | "NamedField": (), | ||
390 | "CallExpr": ( | ||
391 | traits: ["ArgListOwner"], | ||
392 | options: [ "Expr" ], | ||
393 | ), | ||
394 | "MethodCallExpr": ( | ||
395 | traits: ["ArgListOwner"], | ||
396 | options: [ "Expr" ], | ||
397 | ), | ||
398 | "IndexExpr": (), | ||
399 | "FieldExpr": (), | ||
400 | "TryExpr": (), | ||
401 | "CastExpr": (), | ||
402 | "RefExpr": (), | ||
403 | "PrefixExpr": (), | ||
404 | "RangeExpr": (), | ||
405 | "BinExpr": (), | ||
406 | "Literal": (), | ||
407 | |||
408 | "Expr": ( | ||
409 | enum: [ | ||
410 | "TupleExpr", | ||
411 | "ArrayExpr", | ||
412 | "ParenExpr", | ||
413 | "PathExpr", | ||
414 | "LambdaExpr", | ||
415 | "IfExpr", | ||
416 | "LoopExpr", | ||
417 | "ForExpr", | ||
418 | "WhileExpr", | ||
419 | "ContinueExpr", | ||
420 | "BreakExpr", | ||
421 | "Label", | ||
422 | "BlockExpr", | ||
423 | "ReturnExpr", | ||
424 | "MatchExpr", | ||
425 | "MatchArmList", | ||
426 | "MatchArm", | ||
427 | "MatchGuard", | ||
428 | "StructLit", | ||
429 | "NamedFieldList", | ||
430 | "NamedField", | ||
431 | "CallExpr", | ||
432 | "IndexExpr", | ||
433 | "MethodCallExpr", | ||
434 | "FieldExpr", | ||
435 | "TryExpr", | ||
436 | "CastExpr", | ||
437 | "RefExpr", | ||
438 | "PrefixExpr", | ||
439 | "RangeExpr", | ||
440 | "BinExpr", | ||
441 | "Literal", | ||
442 | ], | ||
443 | ), | ||
444 | |||
445 | "RefPat": (), | ||
446 | "BindPat": ( traits: ["NameOwner"] ), | ||
447 | "PlaceholderPat": (), | ||
448 | "PathPat": (), | ||
449 | "StructPat": (), | ||
450 | "FieldPatList": (), | ||
451 | "TupleStructPat": (), | ||
452 | "TuplePat": (), | ||
453 | "SlicePat": (), | ||
454 | "RangePat": (), | ||
455 | |||
456 | "Pat": ( | ||
457 | enum: [ | ||
458 | "RefPat", | ||
459 | "BindPat", | ||
460 | "PlaceholderPat", | ||
461 | "PathPat", | ||
462 | "StructPat", | ||
463 | "FieldPatList", | ||
464 | "TupleStructPat", | ||
465 | "TuplePat", | ||
466 | "SlicePat", | ||
467 | "RangePat", | ||
468 | ], | ||
469 | ), | ||
470 | |||
471 | "Name": (), | ||
472 | "NameRef": (), | ||
473 | "Attr": ( options: [ ["value", "TokenTree"] ] ), | ||
474 | "TokenTree": (), | ||
475 | "TypeParamList": ( | ||
476 | collections: [ | ||
477 | ["type_params", "TypeParam" ], | ||
478 | ["lifetime_params", "LifetimeParam" ], | ||
479 | ] | ||
480 | ), | ||
481 | "TypeParam": ( traits: ["NameOwner"] ), | ||
482 | "LifetimeParam": ( options: [ "Lifetime" ] ), | ||
483 | "Lifetime": (), | ||
484 | "WhereClause": (), | ||
485 | "ExprStmt": ( | ||
486 | options: [ ["expr", "Expr"] ] | ||
487 | ), | ||
488 | "LetStmt": ( options: [ | ||
489 | ["pat", "Pat"], | ||
490 | ["initializer", "Expr"], | ||
491 | ]), | ||
492 | "Condition": ( | ||
493 | options: [ "Pat", "Expr" ] | ||
494 | ), | ||
495 | "Stmt": ( | ||
496 | enum: ["ExprStmt", "LetStmt"], | ||
497 | ), | ||
498 | "Block": ( | ||
499 | options: [ "Expr" ], | ||
500 | collections: [ | ||
501 | ["statements", "Stmt"], | ||
502 | ] | ||
503 | ), | ||
504 | "ParamList": ( | ||
505 | options: [ "SelfParam" ], | ||
506 | collections: [ | ||
507 | ["params", "Param"] | ||
508 | ] | ||
509 | ), | ||
510 | "SelfParam": (), | ||
511 | "Param": ( | ||
512 | options: [ "Pat" ], | ||
513 | ), | ||
514 | "UseItem": ( | ||
515 | options: [ "UseTree" ] | ||
516 | ), | ||
517 | "UseTree": ( | ||
518 | options: [ "Path", "UseTreeList" ] | ||
519 | ), | ||
520 | "UseTreeList": ( | ||
521 | collections: [["use_trees", "UseTree"]] | ||
522 | ), | ||
523 | "ExternCrateItem": (), | ||
524 | "ArgList": ( | ||
525 | collections: [ | ||
526 | ["args", "Expr"] | ||
527 | ] | ||
528 | ), | ||
529 | "Path": ( | ||
530 | options: [ | ||
531 | ["segment", "PathSegment"] | ||
532 | ] | ||
533 | ), | ||
534 | "PathSegment": ( | ||
535 | options: [ "NameRef" ] | ||
536 | ), | ||
537 | }, | ||
538 | ) | ||
diff --git a/crates/ra_syntax/src/grammar/attributes.rs b/crates/ra_syntax/src/grammar/attributes.rs new file mode 100644 index 000000000..cd30e8a45 --- /dev/null +++ b/crates/ra_syntax/src/grammar/attributes.rs | |||
@@ -0,0 +1,31 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn inner_attributes(p: &mut Parser) { | ||
4 | while p.current() == POUND && p.nth(1) == EXCL { | ||
5 | attribute(p, true) | ||
6 | } | ||
7 | } | ||
8 | |||
9 | pub(super) fn outer_attributes(p: &mut Parser) { | ||
10 | while p.at(POUND) { | ||
11 | attribute(p, false) | ||
12 | } | ||
13 | } | ||
14 | |||
15 | fn attribute(p: &mut Parser, inner: bool) { | ||
16 | let attr = p.start(); | ||
17 | assert!(p.at(POUND)); | ||
18 | p.bump(); | ||
19 | |||
20 | if inner { | ||
21 | assert!(p.at(EXCL)); | ||
22 | p.bump(); | ||
23 | } | ||
24 | |||
25 | if p.at(L_BRACK) { | ||
26 | items::token_tree(p); | ||
27 | } else { | ||
28 | p.error("expected `[`"); | ||
29 | } | ||
30 | attr.complete(p, ATTR); | ||
31 | } | ||
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs new file mode 100644 index 000000000..f01df56bc --- /dev/null +++ b/crates/ra_syntax/src/grammar/expressions/atom.rs | |||
@@ -0,0 +1,400 @@ | |||
1 | use super::*; | ||
2 | |||
3 | // test expr_literals | ||
4 | // fn foo() { | ||
5 | // let _ = true; | ||
6 | // let _ = false; | ||
7 | // let _ = 1; | ||
8 | // let _ = 2.0; | ||
9 | // let _ = b'a'; | ||
10 | // let _ = 'b'; | ||
11 | // let _ = "c"; | ||
12 | // let _ = r"d"; | ||
13 | // let _ = b"e"; | ||
14 | // let _ = br"f"; | ||
15 | // } | ||
16 | pub(crate) const LITERAL_FIRST: TokenSet = | ||
17 | token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, | ||
18 | STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING]; | ||
19 | |||
20 | pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> { | ||
21 | if !p.at_ts(LITERAL_FIRST) { | ||
22 | return None; | ||
23 | } | ||
24 | let m = p.start(); | ||
25 | p.bump(); | ||
26 | Some(m.complete(p, LITERAL)) | ||
27 | } | ||
28 | |||
29 | pub(super) const ATOM_EXPR_FIRST: TokenSet = | ||
30 | token_set_union![ | ||
31 | LITERAL_FIRST, | ||
32 | token_set![L_CURLY, L_PAREN, L_BRACK, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, | ||
33 | RETURN_KW, IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ], | ||
34 | ]; | ||
35 | |||
36 | const EXPR_RECOVERY_SET: TokenSet = | ||
37 | token_set![LET_KW]; | ||
38 | |||
39 | pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | ||
40 | match literal(p) { | ||
41 | Some(m) => return Some(m), | ||
42 | None => (), | ||
43 | } | ||
44 | if paths::is_path_start(p) || p.at(L_ANGLE) { | ||
45 | return Some(path_expr(p, r)); | ||
46 | } | ||
47 | let la = p.nth(1); | ||
48 | let done = match p.current() { | ||
49 | L_PAREN => tuple_expr(p), | ||
50 | L_BRACK => array_expr(p), | ||
51 | PIPE => lambda_expr(p), | ||
52 | MOVE_KW if la == PIPE => lambda_expr(p), | ||
53 | IF_KW => if_expr(p), | ||
54 | |||
55 | LOOP_KW => loop_expr(p, None), | ||
56 | FOR_KW => for_expr(p, None), | ||
57 | WHILE_KW => while_expr(p, None), | ||
58 | LIFETIME if la == COLON => { | ||
59 | let m = p.start(); | ||
60 | label(p); | ||
61 | match p.current() { | ||
62 | LOOP_KW => loop_expr(p, Some(m)), | ||
63 | FOR_KW => for_expr(p, Some(m)), | ||
64 | WHILE_KW => while_expr(p, Some(m)), | ||
65 | L_CURLY => block_expr(p, Some(m)), | ||
66 | _ => { | ||
67 | // test misplaced_label_err | ||
68 | // fn main() { | ||
69 | // 'loop: impl | ||
70 | // } | ||
71 | p.error("expected a loop"); | ||
72 | m.complete(p, ERROR); | ||
73 | return None; | ||
74 | } | ||
75 | } | ||
76 | } | ||
77 | |||
78 | MATCH_KW => match_expr(p), | ||
79 | UNSAFE_KW if la == L_CURLY => { | ||
80 | let m = p.start(); | ||
81 | p.bump(); | ||
82 | block_expr(p, Some(m)) | ||
83 | }, | ||
84 | L_CURLY => block_expr(p, None), | ||
85 | RETURN_KW => return_expr(p), | ||
86 | CONTINUE_KW => continue_expr(p), | ||
87 | BREAK_KW => break_expr(p), | ||
88 | _ => { | ||
89 | p.err_recover("expected expression", EXPR_RECOVERY_SET); | ||
90 | return None; | ||
91 | } | ||
92 | }; | ||
93 | Some(done) | ||
94 | } | ||
95 | |||
96 | // test tuple_expr | ||
97 | // fn foo() { | ||
98 | // (); | ||
99 | // (1); | ||
100 | // (1,); | ||
101 | // } | ||
102 | fn tuple_expr(p: &mut Parser) -> CompletedMarker { | ||
103 | assert!(p.at(L_PAREN)); | ||
104 | let m = p.start(); | ||
105 | p.expect(L_PAREN); | ||
106 | |||
107 | let mut saw_comma = false; | ||
108 | let mut saw_expr = false; | ||
109 | while !p.at(EOF) && !p.at(R_PAREN) { | ||
110 | saw_expr = true; | ||
111 | if !p.at_ts(EXPR_FIRST) { | ||
112 | p.error("expected expression"); | ||
113 | break; | ||
114 | } | ||
115 | expr(p); | ||
116 | if !p.at(R_PAREN) { | ||
117 | saw_comma = true; | ||
118 | p.expect(COMMA); | ||
119 | } | ||
120 | } | ||
121 | p.expect(R_PAREN); | ||
122 | m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR }) | ||
123 | } | ||
124 | |||
125 | // test array_expr | ||
126 | // fn foo() { | ||
127 | // []; | ||
128 | // [1]; | ||
129 | // [1, 2,]; | ||
130 | // [1; 2]; | ||
131 | // } | ||
132 | fn array_expr(p: &mut Parser) -> CompletedMarker { | ||
133 | assert!(p.at(L_BRACK)); | ||
134 | let m = p.start(); | ||
135 | p.bump(); | ||
136 | if p.eat(R_BRACK) { | ||
137 | return m.complete(p, ARRAY_EXPR); | ||
138 | } | ||
139 | expr(p); | ||
140 | if p.eat(SEMI) { | ||
141 | expr(p); | ||
142 | p.expect(R_BRACK); | ||
143 | return m.complete(p, ARRAY_EXPR); | ||
144 | } | ||
145 | while !p.at(EOF) && !p.at(R_BRACK) { | ||
146 | p.expect(COMMA); | ||
147 | if p.at(R_BRACK) { | ||
148 | break; | ||
149 | } | ||
150 | if !p.at_ts(EXPR_FIRST) { | ||
151 | p.error("expected expression"); | ||
152 | break; | ||
153 | } | ||
154 | expr(p); | ||
155 | } | ||
156 | p.expect(R_BRACK); | ||
157 | m.complete(p, ARRAY_EXPR) | ||
158 | } | ||
159 | |||
160 | // test lambda_expr | ||
161 | // fn foo() { | ||
162 | // || (); | ||
163 | // || -> i32 { 92 }; | ||
164 | // |x| x; | ||
165 | // move |x: i32,| x; | ||
166 | // } | ||
167 | fn lambda_expr(p: &mut Parser) -> CompletedMarker { | ||
168 | assert!(p.at(PIPE) || (p.at(MOVE_KW) && p.nth(1) == PIPE)); | ||
169 | let m = p.start(); | ||
170 | p.eat(MOVE_KW); | ||
171 | params::param_list_opt_types(p); | ||
172 | if opt_fn_ret_type(p) { | ||
173 | if !p.at(L_CURLY) { | ||
174 | p.error("expected `{`"); | ||
175 | } | ||
176 | } | ||
177 | expr(p); | ||
178 | m.complete(p, LAMBDA_EXPR) | ||
179 | } | ||
180 | |||
181 | // test if_expr | ||
182 | // fn foo() { | ||
183 | // if true {}; | ||
184 | // if true {} else {}; | ||
185 | // if true {} else if false {} else {}; | ||
186 | // if S {}; | ||
187 | // } | ||
188 | fn if_expr(p: &mut Parser) -> CompletedMarker { | ||
189 | assert!(p.at(IF_KW)); | ||
190 | let m = p.start(); | ||
191 | p.bump(); | ||
192 | cond(p); | ||
193 | block(p); | ||
194 | if p.at(ELSE_KW) { | ||
195 | p.bump(); | ||
196 | if p.at(IF_KW) { | ||
197 | if_expr(p); | ||
198 | } else { | ||
199 | block(p); | ||
200 | } | ||
201 | } | ||
202 | m.complete(p, IF_EXPR) | ||
203 | } | ||
204 | |||
205 | // test label | ||
206 | // fn foo() { | ||
207 | // 'a: loop {} | ||
208 | // 'b: while true {} | ||
209 | // 'c: for x in () {} | ||
210 | // } | ||
211 | fn label(p: &mut Parser) { | ||
212 | assert!(p.at(LIFETIME) && p.nth(1) == COLON); | ||
213 | let m = p.start(); | ||
214 | p.bump(); | ||
215 | p.bump(); | ||
216 | m.complete(p, LABEL); | ||
217 | } | ||
218 | |||
219 | // test loop_expr | ||
220 | // fn foo() { | ||
221 | // loop {}; | ||
222 | // } | ||
223 | fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
224 | assert!(p.at(LOOP_KW)); | ||
225 | let m = m.unwrap_or_else(|| p.start()); | ||
226 | p.bump(); | ||
227 | block(p); | ||
228 | m.complete(p, LOOP_EXPR) | ||
229 | } | ||
230 | |||
231 | // test while_expr | ||
232 | // fn foo() { | ||
233 | // while true {}; | ||
234 | // while let Some(x) = it.next() {}; | ||
235 | // } | ||
236 | fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
237 | assert!(p.at(WHILE_KW)); | ||
238 | let m = m.unwrap_or_else(|| p.start()); | ||
239 | p.bump(); | ||
240 | cond(p); | ||
241 | block(p); | ||
242 | m.complete(p, WHILE_EXPR) | ||
243 | } | ||
244 | |||
245 | // test for_expr | ||
246 | // fn foo() { | ||
247 | // for x in [] {}; | ||
248 | // } | ||
249 | fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
250 | assert!(p.at(FOR_KW)); | ||
251 | let m = m.unwrap_or_else(|| p.start()); | ||
252 | p.bump(); | ||
253 | patterns::pattern(p); | ||
254 | p.expect(IN_KW); | ||
255 | expr_no_struct(p); | ||
256 | block(p); | ||
257 | m.complete(p, FOR_EXPR) | ||
258 | } | ||
259 | |||
260 | // test cond | ||
261 | // fn foo() { if let Some(_) = None {} } | ||
262 | fn cond(p: &mut Parser) { | ||
263 | let m = p.start(); | ||
264 | if p.eat(LET_KW) { | ||
265 | patterns::pattern(p); | ||
266 | p.expect(EQ); | ||
267 | } | ||
268 | expr_no_struct(p); | ||
269 | m.complete(p, CONDITION); | ||
270 | } | ||
271 | |||
272 | // test match_expr | ||
273 | // fn foo() { | ||
274 | // match () { }; | ||
275 | // match S {}; | ||
276 | // } | ||
277 | fn match_expr(p: &mut Parser) -> CompletedMarker { | ||
278 | assert!(p.at(MATCH_KW)); | ||
279 | let m = p.start(); | ||
280 | p.bump(); | ||
281 | expr_no_struct(p); | ||
282 | if p.at(L_CURLY) { | ||
283 | match_arm_list(p); | ||
284 | } else { | ||
285 | p.error("expected `{`") | ||
286 | } | ||
287 | m.complete(p, MATCH_EXPR) | ||
288 | } | ||
289 | |||
290 | pub(crate) fn match_arm_list(p: &mut Parser) { | ||
291 | assert!(p.at(L_CURLY)); | ||
292 | let m = p.start(); | ||
293 | p.eat(L_CURLY); | ||
294 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
295 | if p.at(L_CURLY) { | ||
296 | error_block(p, "expected match arm"); | ||
297 | continue; | ||
298 | } | ||
299 | // test match_arms_commas | ||
300 | // fn foo() { | ||
301 | // match () { | ||
302 | // _ => (), | ||
303 | // _ => {} | ||
304 | // _ => () | ||
305 | // } | ||
306 | // } | ||
307 | if match_arm(p).is_block() { | ||
308 | p.eat(COMMA); | ||
309 | } else if !p.at(R_CURLY) { | ||
310 | p.expect(COMMA); | ||
311 | } | ||
312 | } | ||
313 | p.expect(R_CURLY); | ||
314 | m.complete(p, MATCH_ARM_LIST); | ||
315 | } | ||
316 | |||
317 | // test match_arm | ||
318 | // fn foo() { | ||
319 | // match () { | ||
320 | // _ => (), | ||
321 | // X | Y if Z => (), | ||
322 | // }; | ||
323 | // } | ||
324 | fn match_arm(p: &mut Parser) -> BlockLike { | ||
325 | let m = p.start(); | ||
326 | patterns::pattern_r(p, TokenSet::EMPTY); | ||
327 | while p.eat(PIPE) { | ||
328 | patterns::pattern(p); | ||
329 | } | ||
330 | if p.eat(IF_KW) { | ||
331 | expr_no_struct(p); | ||
332 | } | ||
333 | p.expect(FAT_ARROW); | ||
334 | let ret = expr_stmt(p); | ||
335 | m.complete(p, MATCH_ARM); | ||
336 | ret | ||
337 | } | ||
338 | |||
339 | // test block_expr | ||
340 | // fn foo() { | ||
341 | // {}; | ||
342 | // unsafe {}; | ||
343 | // 'label: {}; | ||
344 | // } | ||
345 | fn block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
346 | assert!(p.at(L_CURLY)); | ||
347 | let m = m.unwrap_or_else(|| p.start()); | ||
348 | block(p); | ||
349 | m.complete(p, BLOCK_EXPR) | ||
350 | } | ||
351 | |||
352 | // test return_expr | ||
353 | // fn foo() { | ||
354 | // return; | ||
355 | // return 92; | ||
356 | // } | ||
357 | fn return_expr(p: &mut Parser) -> CompletedMarker { | ||
358 | assert!(p.at(RETURN_KW)); | ||
359 | let m = p.start(); | ||
360 | p.bump(); | ||
361 | if p.at_ts(EXPR_FIRST) { | ||
362 | expr(p); | ||
363 | } | ||
364 | m.complete(p, RETURN_EXPR) | ||
365 | } | ||
366 | |||
367 | // test continue_expr | ||
368 | // fn foo() { | ||
369 | // loop { | ||
370 | // continue; | ||
371 | // continue 'l; | ||
372 | // } | ||
373 | // } | ||
374 | fn continue_expr(p: &mut Parser) -> CompletedMarker { | ||
375 | assert!(p.at(CONTINUE_KW)); | ||
376 | let m = p.start(); | ||
377 | p.bump(); | ||
378 | p.eat(LIFETIME); | ||
379 | m.complete(p, CONTINUE_EXPR) | ||
380 | } | ||
381 | |||
382 | // test break_expr | ||
383 | // fn foo() { | ||
384 | // loop { | ||
385 | // break; | ||
386 | // break 'l; | ||
387 | // break 92; | ||
388 | // break 'l 92; | ||
389 | // } | ||
390 | // } | ||
391 | fn break_expr(p: &mut Parser) -> CompletedMarker { | ||
392 | assert!(p.at(BREAK_KW)); | ||
393 | let m = p.start(); | ||
394 | p.bump(); | ||
395 | p.eat(LIFETIME); | ||
396 | if p.at_ts(EXPR_FIRST) { | ||
397 | expr(p); | ||
398 | } | ||
399 | m.complete(p, BREAK_EXPR) | ||
400 | } | ||
diff --git a/crates/ra_syntax/src/grammar/expressions/mod.rs b/crates/ra_syntax/src/grammar/expressions/mod.rs new file mode 100644 index 000000000..20e0fa328 --- /dev/null +++ b/crates/ra_syntax/src/grammar/expressions/mod.rs | |||
@@ -0,0 +1,450 @@ | |||
1 | mod atom; | ||
2 | |||
3 | use super::*; | ||
4 | pub(super) use self::atom::{literal, LITERAL_FIRST}; | ||
5 | pub(crate) use self::atom::match_arm_list; | ||
6 | |||
7 | const EXPR_FIRST: TokenSet = LHS_FIRST; | ||
8 | |||
9 | pub(super) fn expr(p: &mut Parser) -> BlockLike { | ||
10 | let r = Restrictions { forbid_structs: false, prefer_stmt: false }; | ||
11 | expr_bp(p, r, 1) | ||
12 | } | ||
13 | |||
14 | pub(super) fn expr_stmt(p: &mut Parser) -> BlockLike { | ||
15 | let r = Restrictions { forbid_structs: false, prefer_stmt: true }; | ||
16 | expr_bp(p, r, 1) | ||
17 | } | ||
18 | |||
19 | fn expr_no_struct(p: &mut Parser) { | ||
20 | let r = Restrictions { forbid_structs: true, prefer_stmt: false }; | ||
21 | expr_bp(p, r, 1); | ||
22 | } | ||
23 | |||
24 | // test block | ||
25 | // fn a() {} | ||
26 | // fn b() { let _ = 1; } | ||
27 | // fn c() { 1; 2; } | ||
28 | // fn d() { 1; 2 } | ||
29 | pub(crate) fn block(p: &mut Parser) { | ||
30 | if !p.at(L_CURLY) { | ||
31 | p.error("expected a block"); | ||
32 | return; | ||
33 | } | ||
34 | let m = p.start(); | ||
35 | p.bump(); | ||
36 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
37 | match p.current() { | ||
38 | LET_KW => let_stmt(p), | ||
39 | _ => { | ||
40 | // test block_items | ||
41 | // fn a() { fn b() {} } | ||
42 | let m = p.start(); | ||
43 | match items::maybe_item(p, items::ItemFlavor::Mod) { | ||
44 | items::MaybeItem::Item(kind) => { | ||
45 | m.complete(p, kind); | ||
46 | } | ||
47 | items::MaybeItem::Modifiers => { | ||
48 | m.abandon(p); | ||
49 | p.error("expected an item"); | ||
50 | } | ||
51 | // test pub_expr | ||
52 | // fn foo() { pub 92; } //FIXME | ||
53 | items::MaybeItem::None => { | ||
54 | let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; | ||
55 | if p.at(R_CURLY) { | ||
56 | m.abandon(p); | ||
57 | } else { | ||
58 | if is_blocklike { | ||
59 | p.eat(SEMI); | ||
60 | } else { | ||
61 | p.expect(SEMI); | ||
62 | } | ||
63 | m.complete(p, EXPR_STMT); | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | } | ||
70 | p.expect(R_CURLY); | ||
71 | m.complete(p, BLOCK); | ||
72 | |||
73 | // test let_stmt; | ||
74 | // fn foo() { | ||
75 | // let a; | ||
76 | // let b: i32; | ||
77 | // let c = 92; | ||
78 | // let d: i32 = 92; | ||
79 | // } | ||
80 | fn let_stmt(p: &mut Parser) { | ||
81 | assert!(p.at(LET_KW)); | ||
82 | let m = p.start(); | ||
83 | p.bump(); | ||
84 | patterns::pattern(p); | ||
85 | if p.at(COLON) { | ||
86 | types::ascription(p); | ||
87 | } | ||
88 | if p.eat(EQ) { | ||
89 | expressions::expr(p); | ||
90 | } | ||
91 | p.expect(SEMI); | ||
92 | m.complete(p, LET_STMT); | ||
93 | } | ||
94 | } | ||
95 | |||
96 | #[derive(Clone, Copy)] | ||
97 | struct Restrictions { | ||
98 | forbid_structs: bool, | ||
99 | prefer_stmt: bool, | ||
100 | } | ||
101 | |||
102 | enum Op { | ||
103 | Simple, | ||
104 | Composite(SyntaxKind, u8), | ||
105 | } | ||
106 | |||
107 | fn current_op(p: &Parser) -> (u8, Op) { | ||
108 | if let Some(t) = p.next3() { | ||
109 | match t { | ||
110 | (L_ANGLE, L_ANGLE, EQ) => | ||
111 | return (1, Op::Composite(SHLEQ, 3)), | ||
112 | (R_ANGLE, R_ANGLE, EQ) => | ||
113 | return (1, Op::Composite(SHREQ, 3)), | ||
114 | _ => (), | ||
115 | } | ||
116 | } | ||
117 | |||
118 | if let Some(t) = p.next2() { | ||
119 | match t { | ||
120 | (PLUS, EQ) => return (1, Op::Composite(PLUSEQ, 2)), | ||
121 | (MINUS, EQ) => return (1, Op::Composite(MINUSEQ, 2)), | ||
122 | (STAR, EQ) => return (1, Op::Composite(STAREQ, 2)), | ||
123 | (SLASH, EQ) => return (1, Op::Composite(SLASHEQ, 2)), | ||
124 | (PIPE, EQ) => return (1, Op::Composite(PIPEEQ, 2)), | ||
125 | (AMP, EQ) => return (1, Op::Composite(AMPEQ, 2)), | ||
126 | (CARET, EQ) => return (1, Op::Composite(CARETEQ, 2)), | ||
127 | (PIPE, PIPE) => return (3, Op::Composite(PIPEPIPE, 2)), | ||
128 | (AMP, AMP) => return (4, Op::Composite(AMPAMP, 2)), | ||
129 | (L_ANGLE, EQ) => return (5, Op::Composite(LTEQ, 2)), | ||
130 | (R_ANGLE, EQ) => return (5, Op::Composite(GTEQ, 2)), | ||
131 | (L_ANGLE, L_ANGLE) => return (9, Op::Composite(SHL, 2)), | ||
132 | (R_ANGLE, R_ANGLE) => return (9, Op::Composite(SHR, 2)), | ||
133 | _ => (), | ||
134 | } | ||
135 | } | ||
136 | |||
137 | let bp = match p.current() { | ||
138 | EQ => 1, | ||
139 | DOTDOT => 2, | ||
140 | EQEQ | NEQ | L_ANGLE | R_ANGLE => 5, | ||
141 | PIPE => 6, | ||
142 | CARET => 7, | ||
143 | AMP => 8, | ||
144 | MINUS | PLUS => 10, | ||
145 | STAR | SLASH | PERCENT => 11, | ||
146 | _ => 0, | ||
147 | }; | ||
148 | (bp, Op::Simple) | ||
149 | } | ||
150 | |||
151 | // Parses expression with binding power of at least bp. | ||
152 | fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike { | ||
153 | let mut lhs = match lhs(p, r) { | ||
154 | Some(lhs) => { | ||
155 | // test stmt_bin_expr_ambiguity | ||
156 | // fn foo() { | ||
157 | // let _ = {1} & 2; | ||
158 | // {1} &2; | ||
159 | // } | ||
160 | if r.prefer_stmt && is_block(lhs.kind()) { | ||
161 | return BlockLike::Block; | ||
162 | } | ||
163 | lhs | ||
164 | } | ||
165 | None => return BlockLike::NotBlock, | ||
166 | }; | ||
167 | |||
168 | loop { | ||
169 | let is_range = p.current() == DOTDOT; | ||
170 | let (op_bp, op) = current_op(p); | ||
171 | if op_bp < bp { | ||
172 | break; | ||
173 | } | ||
174 | let m = lhs.precede(p); | ||
175 | match op { | ||
176 | Op::Simple => p.bump(), | ||
177 | Op::Composite(kind, n) => { | ||
178 | p.bump_compound(kind, n); | ||
179 | } | ||
180 | } | ||
181 | expr_bp(p, r, op_bp + 1); | ||
182 | lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); | ||
183 | } | ||
184 | BlockLike::NotBlock | ||
185 | } | ||
186 | |||
187 | // test no_semi_after_block | ||
188 | // fn foo() { | ||
189 | // if true {} | ||
190 | // loop {} | ||
191 | // match () {} | ||
192 | // while true {} | ||
193 | // for _ in () {} | ||
194 | // {} | ||
195 | // {} | ||
196 | // } | ||
197 | fn is_block(kind: SyntaxKind) -> bool { | ||
198 | match kind { | ||
199 | IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => true, | ||
200 | _ => false, | ||
201 | } | ||
202 | } | ||
203 | |||
204 | const LHS_FIRST: TokenSet = | ||
205 | token_set_union![ | ||
206 | token_set![AMP, STAR, EXCL, DOTDOT, MINUS], | ||
207 | atom::ATOM_EXPR_FIRST, | ||
208 | ]; | ||
209 | |||
210 | fn lhs(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> { | ||
211 | let m; | ||
212 | let kind = match p.current() { | ||
213 | // test ref_expr | ||
214 | // fn foo() { | ||
215 | // let _ = &1; | ||
216 | // let _ = &mut &f(); | ||
217 | // } | ||
218 | AMP => { | ||
219 | m = p.start(); | ||
220 | p.bump(); | ||
221 | p.eat(MUT_KW); | ||
222 | REF_EXPR | ||
223 | } | ||
224 | // test unary_expr | ||
225 | // fn foo() { | ||
226 | // **&1; | ||
227 | // !!true; | ||
228 | // --1; | ||
229 | // } | ||
230 | STAR | EXCL | MINUS => { | ||
231 | m = p.start(); | ||
232 | p.bump(); | ||
233 | PREFIX_EXPR | ||
234 | } | ||
235 | // test full_range_expr | ||
236 | // fn foo() { xs[..]; } | ||
237 | DOTDOT => { | ||
238 | m = p.start(); | ||
239 | p.bump(); | ||
240 | if p.at_ts(EXPR_FIRST) { | ||
241 | expr_bp(p, r, 2); | ||
242 | } | ||
243 | return Some(m.complete(p, RANGE_EXPR)); | ||
244 | } | ||
245 | _ => { | ||
246 | let lhs = atom::atom_expr(p, r)?; | ||
247 | return Some(postfix_expr(p, r, lhs)); | ||
248 | } | ||
249 | }; | ||
250 | expr_bp(p, r, 255); | ||
251 | Some(m.complete(p, kind)) | ||
252 | } | ||
253 | |||
254 | fn postfix_expr(p: &mut Parser, r: Restrictions, mut lhs: CompletedMarker) -> CompletedMarker { | ||
255 | let mut allow_calls = !r.prefer_stmt || !is_block(lhs.kind()); | ||
256 | loop { | ||
257 | lhs = match p.current() { | ||
258 | // test stmt_postfix_expr_ambiguity | ||
259 | // fn foo() { | ||
260 | // match () { | ||
261 | // _ => {} | ||
262 | // () => {} | ||
263 | // [] => {} | ||
264 | // } | ||
265 | // } | ||
266 | L_PAREN if allow_calls => call_expr(p, lhs), | ||
267 | L_BRACK if allow_calls => index_expr(p, lhs), | ||
268 | DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON { | ||
269 | method_call_expr(p, lhs) | ||
270 | } else { | ||
271 | field_expr(p, lhs) | ||
272 | }, | ||
273 | DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), | ||
274 | // test postfix_range | ||
275 | // fn foo() { let x = 1..; } | ||
276 | DOTDOT if !EXPR_FIRST.contains(p.nth(1)) => { | ||
277 | let m = lhs.precede(p); | ||
278 | p.bump(); | ||
279 | m.complete(p, RANGE_EXPR) | ||
280 | } | ||
281 | QUESTION => try_expr(p, lhs), | ||
282 | AS_KW => cast_expr(p, lhs), | ||
283 | _ => break, | ||
284 | }; | ||
285 | allow_calls = true | ||
286 | } | ||
287 | lhs | ||
288 | } | ||
289 | |||
290 | // test call_expr | ||
291 | // fn foo() { | ||
292 | // let _ = f(); | ||
293 | // let _ = f()(1)(1, 2,); | ||
294 | // } | ||
295 | fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
296 | assert!(p.at(L_PAREN)); | ||
297 | let m = lhs.precede(p); | ||
298 | arg_list(p); | ||
299 | m.complete(p, CALL_EXPR) | ||
300 | } | ||
301 | |||
302 | // test index_expr | ||
303 | // fn foo() { | ||
304 | // x[1][2]; | ||
305 | // } | ||
306 | fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
307 | assert!(p.at(L_BRACK)); | ||
308 | let m = lhs.precede(p); | ||
309 | p.bump(); | ||
310 | expr(p); | ||
311 | p.expect(R_BRACK); | ||
312 | m.complete(p, INDEX_EXPR) | ||
313 | } | ||
314 | |||
315 | // test method_call_expr | ||
316 | // fn foo() { | ||
317 | // x.foo(); | ||
318 | // y.bar::<T>(1, 2,); | ||
319 | // } | ||
320 | fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
321 | assert!( | ||
322 | p.at(DOT) && p.nth(1) == IDENT | ||
323 | && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) | ||
324 | ); | ||
325 | let m = lhs.precede(p); | ||
326 | p.bump(); | ||
327 | name_ref(p); | ||
328 | type_args::opt_type_arg_list(p, true); | ||
329 | if p.at(L_PAREN) { | ||
330 | arg_list(p); | ||
331 | } | ||
332 | m.complete(p, METHOD_CALL_EXPR) | ||
333 | } | ||
334 | |||
335 | // test field_expr | ||
336 | // fn foo() { | ||
337 | // x.foo; | ||
338 | // x.0.bar; | ||
339 | // } | ||
340 | fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
341 | assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER)); | ||
342 | let m = lhs.precede(p); | ||
343 | p.bump(); | ||
344 | if p.at(IDENT) { | ||
345 | name_ref(p) | ||
346 | } else { | ||
347 | p.bump() | ||
348 | } | ||
349 | m.complete(p, FIELD_EXPR) | ||
350 | } | ||
351 | |||
352 | // test try_expr | ||
353 | // fn foo() { | ||
354 | // x?; | ||
355 | // } | ||
356 | fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
357 | assert!(p.at(QUESTION)); | ||
358 | let m = lhs.precede(p); | ||
359 | p.bump(); | ||
360 | m.complete(p, TRY_EXPR) | ||
361 | } | ||
362 | |||
363 | // test cast_expr | ||
364 | // fn foo() { | ||
365 | // 82 as i32; | ||
366 | // } | ||
367 | fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | ||
368 | assert!(p.at(AS_KW)); | ||
369 | let m = lhs.precede(p); | ||
370 | p.bump(); | ||
371 | types::type_(p); | ||
372 | m.complete(p, CAST_EXPR) | ||
373 | } | ||
374 | |||
375 | fn arg_list(p: &mut Parser) { | ||
376 | assert!(p.at(L_PAREN)); | ||
377 | let m = p.start(); | ||
378 | p.bump(); | ||
379 | while !p.at(R_PAREN) && !p.at(EOF) { | ||
380 | if !p.at_ts(EXPR_FIRST) { | ||
381 | p.error("expected expression"); | ||
382 | break; | ||
383 | } | ||
384 | expr(p); | ||
385 | if !p.at(R_PAREN) && !p.expect(COMMA) { | ||
386 | break; | ||
387 | } | ||
388 | } | ||
389 | p.eat(R_PAREN); | ||
390 | m.complete(p, ARG_LIST); | ||
391 | } | ||
392 | |||
393 | // test path_expr | ||
394 | // fn foo() { | ||
395 | // let _ = a; | ||
396 | // let _ = a::b; | ||
397 | // let _ = ::a::<b>; | ||
398 | // let _ = format!(); | ||
399 | // } | ||
400 | fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { | ||
401 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); | ||
402 | let m = p.start(); | ||
403 | paths::expr_path(p); | ||
404 | match p.current() { | ||
405 | L_CURLY if !r.forbid_structs => { | ||
406 | named_field_list(p); | ||
407 | m.complete(p, STRUCT_LIT) | ||
408 | } | ||
409 | EXCL => { | ||
410 | items::macro_call_after_excl(p); | ||
411 | m.complete(p, MACRO_CALL) | ||
412 | } | ||
413 | _ => m.complete(p, PATH_EXPR) | ||
414 | } | ||
415 | } | ||
416 | |||
417 | // test struct_lit | ||
418 | // fn foo() { | ||
419 | // S {}; | ||
420 | // S { x, y: 32, }; | ||
421 | // S { x, y: 32, ..Default::default() }; | ||
422 | // } | ||
423 | pub(crate) fn named_field_list(p: &mut Parser) { | ||
424 | assert!(p.at(L_CURLY)); | ||
425 | let m = p.start(); | ||
426 | p.bump(); | ||
427 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
428 | match p.current() { | ||
429 | IDENT => { | ||
430 | let m = p.start(); | ||
431 | name_ref(p); | ||
432 | if p.eat(COLON) { | ||
433 | expr(p); | ||
434 | } | ||
435 | m.complete(p, NAMED_FIELD); | ||
436 | } | ||
437 | DOTDOT => { | ||
438 | p.bump(); | ||
439 | expr(p); | ||
440 | } | ||
441 | L_CURLY => error_block(p, "expected a field"), | ||
442 | _ => p.err_and_bump("expected identifier"), | ||
443 | } | ||
444 | if !p.at(R_CURLY) { | ||
445 | p.expect(COMMA); | ||
446 | } | ||
447 | } | ||
448 | p.expect(R_CURLY); | ||
449 | m.complete(p, NAMED_FIELD_LIST); | ||
450 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/consts.rs b/crates/ra_syntax/src/grammar/items/consts.rs new file mode 100644 index 000000000..5a5852f83 --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/consts.rs | |||
@@ -0,0 +1,21 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn static_def(p: &mut Parser) { | ||
4 | const_or_static(p, STATIC_KW) | ||
5 | } | ||
6 | |||
7 | pub(super) fn const_def(p: &mut Parser) { | ||
8 | const_or_static(p, CONST_KW) | ||
9 | } | ||
10 | |||
11 | fn const_or_static(p: &mut Parser, kw: SyntaxKind) { | ||
12 | assert!(p.at(kw)); | ||
13 | p.bump(); | ||
14 | p.eat(MUT_KW); // TODO: validator to forbid const mut | ||
15 | name(p); | ||
16 | types::ascription(p); | ||
17 | if p.eat(EQ) { | ||
18 | expressions::expr(p); | ||
19 | } | ||
20 | p.expect(SEMI); | ||
21 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/mod.rs b/crates/ra_syntax/src/grammar/items/mod.rs new file mode 100644 index 000000000..2567313ab --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/mod.rs | |||
@@ -0,0 +1,393 @@ | |||
1 | |||
2 | mod consts; | ||
3 | mod nominal; | ||
4 | mod traits; | ||
5 | mod use_item; | ||
6 | |||
7 | use super::*; | ||
8 | pub(crate) use self::{ | ||
9 | expressions::{named_field_list, match_arm_list}, | ||
10 | nominal::{enum_variant_list, named_field_def_list}, | ||
11 | traits::{trait_item_list, impl_item_list}, | ||
12 | use_item::use_tree_list, | ||
13 | }; | ||
14 | |||
15 | // test mod_contents | ||
16 | // fn foo() {} | ||
17 | // macro_rules! foo {} | ||
18 | // foo::bar!(); | ||
19 | // super::baz! {} | ||
20 | // struct S; | ||
21 | pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { | ||
22 | attributes::inner_attributes(p); | ||
23 | while !p.at(EOF) && !(stop_on_r_curly && p.at(R_CURLY)) { | ||
24 | item_or_macro(p, stop_on_r_curly, ItemFlavor::Mod) | ||
25 | } | ||
26 | } | ||
27 | |||
28 | pub(super) enum ItemFlavor { | ||
29 | Mod, Trait | ||
30 | } | ||
31 | |||
32 | const ITEM_RECOVERY_SET: TokenSet = | ||
33 | token_set![FN_KW, STRUCT_KW, ENUM_KW, IMPL_KW, TRAIT_KW, CONST_KW, STATIC_KW, LET_KW, | ||
34 | MOD_KW, PUB_KW, CRATE_KW]; | ||
35 | |||
36 | pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool, flavor: ItemFlavor) { | ||
37 | let m = p.start(); | ||
38 | match maybe_item(p, flavor) { | ||
39 | MaybeItem::Item(kind) => { | ||
40 | m.complete(p, kind); | ||
41 | } | ||
42 | MaybeItem::None => { | ||
43 | if paths::is_path_start(p) { | ||
44 | match macro_call(p) { | ||
45 | BlockLike::Block => (), | ||
46 | BlockLike::NotBlock => { | ||
47 | p.expect(SEMI); | ||
48 | } | ||
49 | } | ||
50 | m.complete(p, MACRO_CALL); | ||
51 | } else { | ||
52 | m.abandon(p); | ||
53 | if p.at(L_CURLY) { | ||
54 | error_block(p, "expected an item"); | ||
55 | } else if p.at(R_CURLY) && !stop_on_r_curly { | ||
56 | let e = p.start(); | ||
57 | p.error("unmatched `}`"); | ||
58 | p.bump(); | ||
59 | e.complete(p, ERROR); | ||
60 | } else if !p.at(EOF) && !p.at(R_CURLY) { | ||
61 | p.err_and_bump("expected an item"); | ||
62 | } else { | ||
63 | p.error("expected an item"); | ||
64 | } | ||
65 | } | ||
66 | } | ||
67 | MaybeItem::Modifiers => { | ||
68 | p.error("expected fn, trait or impl"); | ||
69 | m.complete(p, ERROR); | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | pub(super) enum MaybeItem { | ||
75 | None, | ||
76 | Item(SyntaxKind), | ||
77 | Modifiers, | ||
78 | } | ||
79 | |||
80 | pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { | ||
81 | attributes::outer_attributes(p); | ||
82 | opt_visibility(p); | ||
83 | if let Some(kind) = items_without_modifiers(p) { | ||
84 | return MaybeItem::Item(kind); | ||
85 | } | ||
86 | |||
87 | let mut has_mods = false; | ||
88 | // modifiers | ||
89 | has_mods |= p.eat(CONST_KW); | ||
90 | |||
91 | // test unsafe_block_in_mod | ||
92 | // fn foo(){} unsafe { } fn bar(){} | ||
93 | if p.at(UNSAFE_KW) && p.nth(1) != L_CURLY { | ||
94 | p.eat(UNSAFE_KW); | ||
95 | has_mods = true; | ||
96 | } | ||
97 | if p.at(EXTERN_KW) { | ||
98 | has_mods = true; | ||
99 | abi(p); | ||
100 | } | ||
101 | if p.at(IDENT) && p.at_contextual_kw("auto") && p.nth(1) == TRAIT_KW { | ||
102 | p.bump_remap(AUTO_KW); | ||
103 | has_mods = true; | ||
104 | } | ||
105 | if p.at(IDENT) && p.at_contextual_kw("default") && p.nth(1) == IMPL_KW { | ||
106 | p.bump_remap(DEFAULT_KW); | ||
107 | has_mods = true; | ||
108 | } | ||
109 | |||
110 | // items | ||
111 | let kind = match p.current() { | ||
112 | // test extern_fn | ||
113 | // extern fn foo() {} | ||
114 | |||
115 | // test const_fn | ||
116 | // const fn foo() {} | ||
117 | |||
118 | // test const_unsafe_fn | ||
119 | // const unsafe fn foo() {} | ||
120 | |||
121 | // test unsafe_extern_fn | ||
122 | // unsafe extern "C" fn foo() {} | ||
123 | |||
124 | // test unsafe_fn | ||
125 | // unsafe fn foo() {} | ||
126 | FN_KW => { | ||
127 | fn_def(p, flavor); | ||
128 | FN_DEF | ||
129 | } | ||
130 | |||
131 | // test unsafe_trait | ||
132 | // unsafe trait T {} | ||
133 | |||
134 | // test auto_trait | ||
135 | // auto trait T {} | ||
136 | |||
137 | // test unsafe_auto_trait | ||
138 | // unsafe auto trait T {} | ||
139 | TRAIT_KW => { | ||
140 | traits::trait_def(p); | ||
141 | TRAIT_DEF | ||
142 | } | ||
143 | |||
144 | // test unsafe_impl | ||
145 | // unsafe impl Foo {} | ||
146 | |||
147 | // test default_impl | ||
148 | // default impl Foo {} | ||
149 | |||
150 | // test unsafe_default_impl | ||
151 | // unsafe default impl Foo {} | ||
152 | IMPL_KW => { | ||
153 | traits::impl_item(p); | ||
154 | IMPL_ITEM | ||
155 | } | ||
156 | _ => return if has_mods { | ||
157 | MaybeItem::Modifiers | ||
158 | } else { | ||
159 | MaybeItem::None | ||
160 | } | ||
161 | }; | ||
162 | |||
163 | MaybeItem::Item(kind) | ||
164 | } | ||
165 | |||
166 | fn items_without_modifiers(p: &mut Parser) -> Option<SyntaxKind> { | ||
167 | let la = p.nth(1); | ||
168 | let kind = match p.current() { | ||
169 | // test extern_crate | ||
170 | // extern crate foo; | ||
171 | EXTERN_KW if la == CRATE_KW => { | ||
172 | extern_crate_item(p); | ||
173 | EXTERN_CRATE_ITEM | ||
174 | } | ||
175 | TYPE_KW => { | ||
176 | type_def(p); | ||
177 | TYPE_DEF | ||
178 | } | ||
179 | MOD_KW => { | ||
180 | mod_item(p); | ||
181 | MODULE | ||
182 | } | ||
183 | STRUCT_KW => { | ||
184 | // test struct_items | ||
185 | // struct Foo; | ||
186 | // struct Foo {} | ||
187 | // struct Foo(); | ||
188 | // struct Foo(String, usize); | ||
189 | // struct Foo { | ||
190 | // a: i32, | ||
191 | // b: f32, | ||
192 | // } | ||
193 | nominal::struct_def(p, STRUCT_KW); | ||
194 | if p.at(SEMI) { | ||
195 | p.err_and_bump( | ||
196 | "expected item, found `;`\n\ | ||
197 | consider removing this semicolon" | ||
198 | ); | ||
199 | } | ||
200 | STRUCT_DEF | ||
201 | } | ||
202 | IDENT if p.at_contextual_kw("union") => { | ||
203 | // test union_items | ||
204 | // union Foo {} | ||
205 | // union Foo { | ||
206 | // a: i32, | ||
207 | // b: f32, | ||
208 | // } | ||
209 | nominal::struct_def(p, UNION_KW); | ||
210 | STRUCT_DEF | ||
211 | } | ||
212 | ENUM_KW => { | ||
213 | nominal::enum_def(p); | ||
214 | ENUM_DEF | ||
215 | } | ||
216 | USE_KW => { | ||
217 | use_item::use_item(p); | ||
218 | USE_ITEM | ||
219 | } | ||
220 | CONST_KW if (la == IDENT || la == MUT_KW) => { | ||
221 | consts::const_def(p); | ||
222 | CONST_DEF | ||
223 | } | ||
224 | STATIC_KW => { | ||
225 | consts::static_def(p); | ||
226 | STATIC_DEF | ||
227 | } | ||
228 | // test extern_block | ||
229 | // extern {} | ||
230 | EXTERN_KW if la == L_CURLY || ((la == STRING || la == RAW_STRING) && p.nth(2) == L_CURLY) => { | ||
231 | abi(p); | ||
232 | extern_item_list(p); | ||
233 | EXTERN_BLOCK | ||
234 | } | ||
235 | _ => return None, | ||
236 | }; | ||
237 | Some(kind) | ||
238 | } | ||
239 | |||
240 | fn extern_crate_item(p: &mut Parser) { | ||
241 | assert!(p.at(EXTERN_KW)); | ||
242 | p.bump(); | ||
243 | assert!(p.at(CRATE_KW)); | ||
244 | p.bump(); | ||
245 | name(p); | ||
246 | opt_alias(p); | ||
247 | p.expect(SEMI); | ||
248 | } | ||
249 | |||
250 | pub(crate) fn extern_item_list(p: &mut Parser) { | ||
251 | assert!(p.at(L_CURLY)); | ||
252 | let m = p.start(); | ||
253 | p.bump(); | ||
254 | mod_contents(p, true); | ||
255 | p.expect(R_CURLY); | ||
256 | m.complete(p, EXTERN_ITEM_LIST); | ||
257 | } | ||
258 | |||
259 | fn fn_def(p: &mut Parser, flavor: ItemFlavor) { | ||
260 | assert!(p.at(FN_KW)); | ||
261 | p.bump(); | ||
262 | |||
263 | name_r(p, ITEM_RECOVERY_SET); | ||
264 | // test function_type_params | ||
265 | // fn foo<T: Clone + Copy>(){} | ||
266 | type_params::opt_type_param_list(p); | ||
267 | |||
268 | if p.at(L_PAREN) { | ||
269 | match flavor { | ||
270 | ItemFlavor::Mod => | ||
271 | params::param_list(p), | ||
272 | ItemFlavor::Trait => | ||
273 | params::param_list_opt_patterns(p), | ||
274 | } | ||
275 | } else { | ||
276 | p.error("expected function arguments"); | ||
277 | } | ||
278 | // test function_ret_type | ||
279 | // fn foo() {} | ||
280 | // fn bar() -> () {} | ||
281 | opt_fn_ret_type(p); | ||
282 | |||
283 | // test function_where_clause | ||
284 | // fn foo<T>() where T: Copy {} | ||
285 | type_params::opt_where_clause(p); | ||
286 | |||
287 | // test fn_decl | ||
288 | // trait T { fn foo(); } | ||
289 | if p.at(SEMI) { | ||
290 | p.bump(); | ||
291 | } else { | ||
292 | expressions::block(p) | ||
293 | } | ||
294 | } | ||
295 | |||
296 | // test type_item | ||
297 | // type Foo = Bar; | ||
298 | fn type_def(p: &mut Parser) { | ||
299 | assert!(p.at(TYPE_KW)); | ||
300 | p.bump(); | ||
301 | |||
302 | name(p); | ||
303 | |||
304 | // test type_item_type_params | ||
305 | // type Result<T> = (); | ||
306 | type_params::opt_type_param_list(p); | ||
307 | |||
308 | if p.at(COLON) { | ||
309 | type_params::bounds(p); | ||
310 | } | ||
311 | |||
312 | // test type_item_where_clause | ||
313 | // type Foo where Foo: Copy = (); | ||
314 | type_params::opt_where_clause(p); | ||
315 | |||
316 | if p.eat(EQ) { | ||
317 | types::type_(p); | ||
318 | } | ||
319 | p.expect(SEMI); | ||
320 | } | ||
321 | |||
322 | pub(crate) fn mod_item(p: &mut Parser) { | ||
323 | assert!(p.at(MOD_KW)); | ||
324 | p.bump(); | ||
325 | |||
326 | name(p); | ||
327 | if p.at(L_CURLY) { | ||
328 | mod_item_list(p); | ||
329 | } else if !p.eat(SEMI) { | ||
330 | p.error("expected `;` or `{`"); | ||
331 | } | ||
332 | } | ||
333 | |||
334 | pub(crate) fn mod_item_list(p: &mut Parser) { | ||
335 | assert!(p.at(L_CURLY)); | ||
336 | let m = p.start(); | ||
337 | p.bump(); | ||
338 | mod_contents(p, true); | ||
339 | p.expect(R_CURLY); | ||
340 | m.complete(p, ITEM_LIST); | ||
341 | } | ||
342 | |||
343 | fn macro_call(p: &mut Parser) -> BlockLike { | ||
344 | assert!(paths::is_path_start(p)); | ||
345 | paths::use_path(p); | ||
346 | macro_call_after_excl(p) | ||
347 | } | ||
348 | |||
349 | pub(super) fn macro_call_after_excl(p: &mut Parser) -> BlockLike { | ||
350 | p.expect(EXCL); | ||
351 | p.eat(IDENT); | ||
352 | let flavor = match p.current() { | ||
353 | L_CURLY => { | ||
354 | token_tree(p); | ||
355 | BlockLike::Block | ||
356 | } | ||
357 | L_PAREN | L_BRACK => { | ||
358 | token_tree(p); | ||
359 | BlockLike::NotBlock | ||
360 | } | ||
361 | _ => { | ||
362 | p.error("expected `{`, `[`, `(`"); | ||
363 | BlockLike::NotBlock | ||
364 | }, | ||
365 | }; | ||
366 | |||
367 | flavor | ||
368 | } | ||
369 | |||
370 | pub(crate) fn token_tree(p: &mut Parser) { | ||
371 | let closing_paren_kind = match p.current() { | ||
372 | L_CURLY => R_CURLY, | ||
373 | L_PAREN => R_PAREN, | ||
374 | L_BRACK => R_BRACK, | ||
375 | _ => unreachable!(), | ||
376 | }; | ||
377 | let m = p.start(); | ||
378 | p.bump(); | ||
379 | while !p.at(EOF) && !p.at(closing_paren_kind) { | ||
380 | match p.current() { | ||
381 | L_CURLY | L_PAREN | L_BRACK => token_tree(p), | ||
382 | R_CURLY => { | ||
383 | p.error("unmatched `}`"); | ||
384 | m.complete(p, TOKEN_TREE); | ||
385 | return; | ||
386 | } | ||
387 | R_PAREN | R_BRACK => p.err_and_bump("unmatched brace"), | ||
388 | _ => p.bump() | ||
389 | } | ||
390 | }; | ||
391 | p.expect(closing_paren_kind); | ||
392 | m.complete(p, TOKEN_TREE); | ||
393 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/nominal.rs b/crates/ra_syntax/src/grammar/items/nominal.rs new file mode 100644 index 000000000..8d02ad555 --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/nominal.rs | |||
@@ -0,0 +1,154 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn struct_def(p: &mut Parser, kind: SyntaxKind) { | ||
4 | assert!(p.at(STRUCT_KW) || p.at_contextual_kw("union")); | ||
5 | p.bump_remap(kind); | ||
6 | |||
7 | name_r(p, ITEM_RECOVERY_SET); | ||
8 | type_params::opt_type_param_list(p); | ||
9 | match p.current() { | ||
10 | WHERE_KW => { | ||
11 | type_params::opt_where_clause(p); | ||
12 | match p.current() { | ||
13 | SEMI => { | ||
14 | p.bump(); | ||
15 | return; | ||
16 | } | ||
17 | L_CURLY => named_field_def_list(p), | ||
18 | _ => { | ||
19 | //TODO: special case `(` error message | ||
20 | p.error("expected `;` or `{`"); | ||
21 | return; | ||
22 | } | ||
23 | } | ||
24 | } | ||
25 | SEMI if kind == STRUCT_KW => { | ||
26 | p.bump(); | ||
27 | return; | ||
28 | } | ||
29 | L_CURLY => named_field_def_list(p), | ||
30 | L_PAREN if kind == STRUCT_KW => { | ||
31 | pos_field_list(p); | ||
32 | p.expect(SEMI); | ||
33 | } | ||
34 | _ if kind == STRUCT_KW => { | ||
35 | p.error("expected `;`, `{`, or `(`"); | ||
36 | return; | ||
37 | } | ||
38 | _ => { | ||
39 | p.error("expected `{`"); | ||
40 | return; | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | |||
45 | pub(super) fn enum_def(p: &mut Parser) { | ||
46 | assert!(p.at(ENUM_KW)); | ||
47 | p.bump(); | ||
48 | name_r(p, ITEM_RECOVERY_SET); | ||
49 | type_params::opt_type_param_list(p); | ||
50 | type_params::opt_where_clause(p); | ||
51 | if p.at(L_CURLY) { | ||
52 | enum_variant_list(p); | ||
53 | } else { | ||
54 | p.error("expected `{`") | ||
55 | } | ||
56 | } | ||
57 | |||
58 | pub(crate) fn enum_variant_list(p: &mut Parser) { | ||
59 | assert!(p.at(L_CURLY)); | ||
60 | let m = p.start(); | ||
61 | p.bump(); | ||
62 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
63 | if p.at(L_CURLY) { | ||
64 | error_block(p, "expected enum variant"); | ||
65 | continue; | ||
66 | } | ||
67 | let var = p.start(); | ||
68 | attributes::outer_attributes(p); | ||
69 | if p.at(IDENT) { | ||
70 | name(p); | ||
71 | match p.current() { | ||
72 | L_CURLY => named_field_def_list(p), | ||
73 | L_PAREN => pos_field_list(p), | ||
74 | EQ => { | ||
75 | p.bump(); | ||
76 | expressions::expr(p); | ||
77 | } | ||
78 | _ => (), | ||
79 | } | ||
80 | var.complete(p, ENUM_VARIANT); | ||
81 | } else { | ||
82 | var.abandon(p); | ||
83 | p.err_and_bump("expected enum variant"); | ||
84 | } | ||
85 | if !p.at(R_CURLY) { | ||
86 | p.expect(COMMA); | ||
87 | } | ||
88 | } | ||
89 | p.expect(R_CURLY); | ||
90 | m.complete(p, ENUM_VARIANT_LIST); | ||
91 | } | ||
92 | |||
93 | pub(crate) fn named_field_def_list(p: &mut Parser) { | ||
94 | assert!(p.at(L_CURLY)); | ||
95 | let m = p.start(); | ||
96 | p.bump(); | ||
97 | while !p.at(R_CURLY) && !p.at(EOF) { | ||
98 | if p.at(L_CURLY) { | ||
99 | error_block(p, "expected field"); | ||
100 | continue; | ||
101 | } | ||
102 | named_field_def(p); | ||
103 | if !p.at(R_CURLY) { | ||
104 | p.expect(COMMA); | ||
105 | } | ||
106 | } | ||
107 | p.expect(R_CURLY); | ||
108 | m.complete(p, NAMED_FIELD_DEF_LIST); | ||
109 | |||
110 | fn named_field_def(p: &mut Parser) { | ||
111 | let m = p.start(); | ||
112 | // test field_attrs | ||
113 | // struct S { | ||
114 | // #[serde(with = "url_serde")] | ||
115 | // pub uri: Uri, | ||
116 | // } | ||
117 | attributes::outer_attributes(p); | ||
118 | opt_visibility(p); | ||
119 | if p.at(IDENT) { | ||
120 | name(p); | ||
121 | p.expect(COLON); | ||
122 | types::type_(p); | ||
123 | m.complete(p, NAMED_FIELD_DEF); | ||
124 | } else { | ||
125 | m.abandon(p); | ||
126 | p.err_and_bump("expected field declaration"); | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | |||
131 | fn pos_field_list(p: &mut Parser) { | ||
132 | assert!(p.at(L_PAREN)); | ||
133 | let m = p.start(); | ||
134 | if !p.expect(L_PAREN) { | ||
135 | return; | ||
136 | } | ||
137 | while !p.at(R_PAREN) && !p.at(EOF) { | ||
138 | let m = p.start(); | ||
139 | opt_visibility(p); | ||
140 | if !p.at_ts(types::TYPE_FIRST) { | ||
141 | p.error("expected a type"); | ||
142 | m.complete(p, ERROR); | ||
143 | break; | ||
144 | } | ||
145 | types::type_(p); | ||
146 | m.complete(p, POS_FIELD); | ||
147 | |||
148 | if !p.at(R_PAREN) { | ||
149 | p.expect(COMMA); | ||
150 | } | ||
151 | } | ||
152 | p.expect(R_PAREN); | ||
153 | m.complete(p, POS_FIELD_LIST); | ||
154 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/traits.rs b/crates/ra_syntax/src/grammar/items/traits.rs new file mode 100644 index 000000000..c21cfb1a9 --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/traits.rs | |||
@@ -0,0 +1,117 @@ | |||
1 | use super::*; | ||
2 | |||
3 | // test trait_item | ||
4 | // trait T<U>: Hash + Clone where U: Copy {} | ||
5 | pub(super) fn trait_def(p: &mut Parser) { | ||
6 | assert!(p.at(TRAIT_KW)); | ||
7 | p.bump(); | ||
8 | name_r(p, ITEM_RECOVERY_SET); | ||
9 | type_params::opt_type_param_list(p); | ||
10 | if p.at(COLON) { | ||
11 | type_params::bounds(p); | ||
12 | } | ||
13 | type_params::opt_where_clause(p); | ||
14 | if p.at(L_CURLY) { | ||
15 | trait_item_list(p); | ||
16 | } else { | ||
17 | p.error("expected `{`"); | ||
18 | } | ||
19 | } | ||
20 | |||
21 | // test trait_item_list | ||
22 | // impl F { | ||
23 | // type A: Clone; | ||
24 | // const B: i32; | ||
25 | // fn foo() {} | ||
26 | // fn bar(&self); | ||
27 | // } | ||
28 | pub(crate) fn trait_item_list(p: &mut Parser) { | ||
29 | assert!(p.at(L_CURLY)); | ||
30 | let m = p.start(); | ||
31 | p.bump(); | ||
32 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
33 | if p.at(L_CURLY) { | ||
34 | error_block(p, "expected an item"); | ||
35 | continue; | ||
36 | } | ||
37 | item_or_macro(p, true, ItemFlavor::Trait); | ||
38 | } | ||
39 | p.expect(R_CURLY); | ||
40 | m.complete(p, ITEM_LIST); | ||
41 | } | ||
42 | |||
43 | // test impl_item | ||
44 | // impl Foo {} | ||
45 | pub(super) fn impl_item(p: &mut Parser) { | ||
46 | assert!(p.at(IMPL_KW)); | ||
47 | p.bump(); | ||
48 | if choose_type_params_over_qpath(p) { | ||
49 | type_params::opt_type_param_list(p); | ||
50 | } | ||
51 | |||
52 | // TODO: never type | ||
53 | // impl ! {} | ||
54 | |||
55 | // test impl_item_neg | ||
56 | // impl !Send for X {} | ||
57 | p.eat(EXCL); | ||
58 | types::type_(p); | ||
59 | if p.eat(FOR_KW) { | ||
60 | types::type_(p); | ||
61 | } | ||
62 | type_params::opt_where_clause(p); | ||
63 | if p.at(L_CURLY) { | ||
64 | impl_item_list(p); | ||
65 | } else { | ||
66 | p.error("expected `{`"); | ||
67 | } | ||
68 | } | ||
69 | |||
70 | // test impl_item_list | ||
71 | // impl F { | ||
72 | // type A = i32; | ||
73 | // const B: i32 = 92; | ||
74 | // fn foo() {} | ||
75 | // fn bar(&self) {} | ||
76 | // } | ||
77 | pub(crate) fn impl_item_list(p: &mut Parser) { | ||
78 | assert!(p.at(L_CURLY)); | ||
79 | let m = p.start(); | ||
80 | p.bump(); | ||
81 | |||
82 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
83 | if p.at(L_CURLY) { | ||
84 | error_block(p, "expected an item"); | ||
85 | continue; | ||
86 | } | ||
87 | item_or_macro(p, true, ItemFlavor::Mod); | ||
88 | } | ||
89 | p.expect(R_CURLY); | ||
90 | m.complete(p, ITEM_LIST); | ||
91 | } | ||
92 | |||
93 | fn choose_type_params_over_qpath(p: &Parser) -> bool { | ||
94 | // There's an ambiguity between generic parameters and qualified paths in impls. | ||
95 | // If we see `<` it may start both, so we have to inspect some following tokens. | ||
96 | // The following combinations can only start generics, | ||
97 | // but not qualified paths (with one exception): | ||
98 | // `<` `>` - empty generic parameters | ||
99 | // `<` `#` - generic parameters with attributes | ||
100 | // `<` (LIFETIME|IDENT) `>` - single generic parameter | ||
101 | // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list | ||
102 | // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds | ||
103 | // `<` (LIFETIME|IDENT) `=` - generic parameter with a default | ||
104 | // The only truly ambiguous case is | ||
105 | // `<` IDENT `>` `::` IDENT ... | ||
106 | // we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`) | ||
107 | // because this is what almost always expected in practice, qualified paths in impls | ||
108 | // (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment. | ||
109 | if !p.at(L_ANGLE) { | ||
110 | return false; | ||
111 | } | ||
112 | if p.nth(1) == POUND || p.nth(1) == R_ANGLE { | ||
113 | return true; | ||
114 | } | ||
115 | (p.nth(1) == LIFETIME || p.nth(1) == IDENT) | ||
116 | && (p.nth(2) == R_ANGLE || p.nth(2) == COMMA || p.nth(2) == COLON || p.nth(2) == EQ) | ||
117 | } | ||
diff --git a/crates/ra_syntax/src/grammar/items/use_item.rs b/crates/ra_syntax/src/grammar/items/use_item.rs new file mode 100644 index 000000000..1ee4349fd --- /dev/null +++ b/crates/ra_syntax/src/grammar/items/use_item.rs | |||
@@ -0,0 +1,68 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn use_item(p: &mut Parser) { | ||
4 | assert!(p.at(USE_KW)); | ||
5 | p.bump(); | ||
6 | use_tree(p); | ||
7 | p.expect(SEMI); | ||
8 | } | ||
9 | |||
10 | fn use_tree(p: &mut Parser) { | ||
11 | let la = p.nth(1); | ||
12 | let m = p.start(); | ||
13 | match (p.current(), la) { | ||
14 | (STAR, _) => p.bump(), | ||
15 | (COLONCOLON, STAR) => { | ||
16 | p.bump(); | ||
17 | p.bump(); | ||
18 | } | ||
19 | (L_CURLY, _) | (COLONCOLON, L_CURLY) => { | ||
20 | if p.at(COLONCOLON) { | ||
21 | p.bump(); | ||
22 | } | ||
23 | use_tree_list(p); | ||
24 | } | ||
25 | _ if paths::is_path_start(p) => { | ||
26 | paths::use_path(p); | ||
27 | match p.current() { | ||
28 | AS_KW => { | ||
29 | opt_alias(p); | ||
30 | } | ||
31 | COLONCOLON => { | ||
32 | p.bump(); | ||
33 | match p.current() { | ||
34 | STAR => { | ||
35 | p.bump(); | ||
36 | } | ||
37 | L_CURLY => use_tree_list(p), | ||
38 | _ => { | ||
39 | // is this unreachable? | ||
40 | p.error("expected `{` or `*`"); | ||
41 | } | ||
42 | } | ||
43 | } | ||
44 | _ => (), | ||
45 | } | ||
46 | } | ||
47 | _ => { | ||
48 | m.abandon(p); | ||
49 | p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`"); | ||
50 | return; | ||
51 | } | ||
52 | } | ||
53 | m.complete(p, USE_TREE); | ||
54 | } | ||
55 | |||
56 | pub(crate) fn use_tree_list(p: &mut Parser) { | ||
57 | assert!(p.at(L_CURLY)); | ||
58 | let m = p.start(); | ||
59 | p.bump(); | ||
60 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
61 | use_tree(p); | ||
62 | if !p.at(R_CURLY) { | ||
63 | p.expect(COMMA); | ||
64 | } | ||
65 | } | ||
66 | p.expect(R_CURLY); | ||
67 | m.complete(p, USE_TREE_LIST); | ||
68 | } | ||
diff --git a/crates/ra_syntax/src/grammar/mod.rs b/crates/ra_syntax/src/grammar/mod.rs new file mode 100644 index 000000000..2cb11dc1e --- /dev/null +++ b/crates/ra_syntax/src/grammar/mod.rs | |||
@@ -0,0 +1,188 @@ | |||
1 | //! This is the actual "grammar" of the Rust language. | ||
2 | //! | ||
3 | //! Each function in this module and its children corresponds | ||
4 | //! to a production of the format grammar. Submodules roughly | ||
5 | //! correspond to different *areas* of the grammar. By convention, | ||
6 | //! each submodule starts with `use super::*` import and exports | ||
7 | //! "public" productions via `pub(super)`. | ||
8 | //! | ||
9 | //! See docs for `Parser` to learn about API, available to the grammar, | ||
10 | //! and see docs for `Event` to learn how this actually manages to | ||
11 | //! produce parse trees. | ||
12 | //! | ||
13 | //! Code in this module also contains inline tests, which start with | ||
14 | //! `// test name-of-the-test` comment and look like this: | ||
15 | //! | ||
16 | //! ``` | ||
17 | //! // test function_with_zero_parameters | ||
18 | //! // fn foo() {} | ||
19 | //! ``` | ||
20 | //! | ||
21 | //! After adding a new inline-test, run `cargo collect-tests` to extract | ||
22 | //! it as a standalone text-fixture into `tests/data/parser/inline`, and | ||
23 | //! run `cargo test` once to create the "gold" value. | ||
24 | mod attributes; | ||
25 | mod expressions; | ||
26 | mod items; | ||
27 | mod params; | ||
28 | mod paths; | ||
29 | mod patterns; | ||
30 | mod type_args; | ||
31 | mod type_params; | ||
32 | mod types; | ||
33 | |||
34 | use { | ||
35 | token_set::TokenSet, | ||
36 | parser_api::{Marker, CompletedMarker, Parser}, | ||
37 | SyntaxKind::{self, *}, | ||
38 | }; | ||
39 | pub(crate) use self::{ | ||
40 | expressions::{ | ||
41 | block, | ||
42 | }, | ||
43 | items::{ | ||
44 | enum_variant_list, | ||
45 | extern_item_list, | ||
46 | impl_item_list, | ||
47 | match_arm_list, | ||
48 | mod_item_list, | ||
49 | named_field_def_list, | ||
50 | named_field_list, | ||
51 | token_tree, | ||
52 | trait_item_list, | ||
53 | use_tree_list, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | pub(crate) fn root(p: &mut Parser) { | ||
58 | let m = p.start(); | ||
59 | p.eat(SHEBANG); | ||
60 | items::mod_contents(p, false); | ||
61 | m.complete(p, ROOT); | ||
62 | } | ||
63 | |||
64 | |||
65 | #[derive(Clone, Copy, PartialEq, Eq)] | ||
66 | enum BlockLike { | ||
67 | Block, | ||
68 | NotBlock, | ||
69 | } | ||
70 | |||
71 | impl BlockLike { | ||
72 | fn is_block(self) -> bool { self == BlockLike::Block } | ||
73 | } | ||
74 | |||
75 | fn opt_visibility(p: &mut Parser) { | ||
76 | match p.current() { | ||
77 | PUB_KW => { | ||
78 | let m = p.start(); | ||
79 | p.bump(); | ||
80 | if p.at(L_PAREN) { | ||
81 | match p.nth(1) { | ||
82 | // test crate_visibility | ||
83 | // pub(crate) struct S; | ||
84 | // pub(self) struct S; | ||
85 | // pub(self) struct S; | ||
86 | // pub(self) struct S; | ||
87 | CRATE_KW | SELF_KW | SUPER_KW => { | ||
88 | p.bump(); | ||
89 | p.bump(); | ||
90 | p.expect(R_PAREN); | ||
91 | } | ||
92 | IN_KW => { | ||
93 | p.bump(); | ||
94 | p.bump(); | ||
95 | paths::use_path(p); | ||
96 | p.expect(R_PAREN); | ||
97 | } | ||
98 | _ => (), | ||
99 | } | ||
100 | } | ||
101 | m.complete(p, VISIBILITY); | ||
102 | } | ||
103 | // test crate_keyword_vis | ||
104 | // crate fn main() { } | ||
105 | CRATE_KW => { | ||
106 | let m = p.start(); | ||
107 | p.bump(); | ||
108 | m.complete(p, VISIBILITY); | ||
109 | } | ||
110 | _ => (), | ||
111 | } | ||
112 | } | ||
113 | |||
114 | fn opt_alias(p: &mut Parser) { | ||
115 | if p.at(AS_KW) { | ||
116 | let m = p.start(); | ||
117 | p.bump(); | ||
118 | name(p); | ||
119 | m.complete(p, ALIAS); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | fn abi(p: &mut Parser) { | ||
124 | assert!(p.at(EXTERN_KW)); | ||
125 | let abi = p.start(); | ||
126 | p.bump(); | ||
127 | match p.current() { | ||
128 | STRING | RAW_STRING => p.bump(), | ||
129 | _ => (), | ||
130 | } | ||
131 | abi.complete(p, ABI); | ||
132 | } | ||
133 | |||
134 | fn opt_fn_ret_type(p: &mut Parser) -> bool { | ||
135 | if p.at(THIN_ARROW) { | ||
136 | let m = p.start(); | ||
137 | p.bump(); | ||
138 | types::type_(p); | ||
139 | m.complete(p, RET_TYPE); | ||
140 | true | ||
141 | } else { | ||
142 | false | ||
143 | } | ||
144 | } | ||
145 | |||
146 | fn name_r(p: &mut Parser, recovery: TokenSet) { | ||
147 | if p.at(IDENT) { | ||
148 | let m = p.start(); | ||
149 | p.bump(); | ||
150 | m.complete(p, NAME); | ||
151 | } else { | ||
152 | p.err_recover("expected a name", recovery); | ||
153 | } | ||
154 | } | ||
155 | |||
156 | fn name(p: &mut Parser) { | ||
157 | name_r(p, TokenSet::EMPTY) | ||
158 | } | ||
159 | |||
160 | fn name_ref(p: &mut Parser) { | ||
161 | if p.at(IDENT) { | ||
162 | let m = p.start(); | ||
163 | p.bump(); | ||
164 | m.complete(p, NAME_REF); | ||
165 | } else { | ||
166 | p.err_and_bump("expected identifier"); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | fn error_block(p: &mut Parser, message: &str) { | ||
171 | go(p, Some(message)); | ||
172 | fn go(p: &mut Parser, message: Option<&str>) { | ||
173 | assert!(p.at(L_CURLY)); | ||
174 | let m = p.start(); | ||
175 | if let Some(message) = message { | ||
176 | p.error(message); | ||
177 | } | ||
178 | p.bump(); | ||
179 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
180 | match p.current() { | ||
181 | L_CURLY => go(p, None), | ||
182 | _ => p.bump(), | ||
183 | } | ||
184 | } | ||
185 | p.eat(R_CURLY); | ||
186 | m.complete(p, ERROR); | ||
187 | } | ||
188 | } | ||
diff --git a/crates/ra_syntax/src/grammar/params.rs b/crates/ra_syntax/src/grammar/params.rs new file mode 100644 index 000000000..903c25939 --- /dev/null +++ b/crates/ra_syntax/src/grammar/params.rs | |||
@@ -0,0 +1,142 @@ | |||
1 | use super::*; | ||
2 | |||
3 | // test param_list | ||
4 | // fn a() {} | ||
5 | // fn b(x: i32) {} | ||
6 | // fn c(x: i32, ) {} | ||
7 | // fn d(x: i32, y: ()) {} | ||
8 | pub(super) fn param_list(p: &mut Parser) { | ||
9 | list_(p, Flavor::Normal) | ||
10 | } | ||
11 | |||
12 | // test param_list_opt_patterns | ||
13 | // fn foo<F: FnMut(&mut Foo<'a>)>(){} | ||
14 | pub(super) fn param_list_opt_patterns(p: &mut Parser) { | ||
15 | list_(p, Flavor::OptionalPattern) | ||
16 | } | ||
17 | |||
18 | pub(super) fn param_list_opt_types(p: &mut Parser) { | ||
19 | list_(p, Flavor::OptionalType) | ||
20 | } | ||
21 | |||
22 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
23 | enum Flavor { | ||
24 | OptionalType, | ||
25 | OptionalPattern, | ||
26 | Normal, | ||
27 | } | ||
28 | |||
29 | impl Flavor { | ||
30 | fn type_required(self) -> bool { | ||
31 | match self { | ||
32 | Flavor::OptionalType => false, | ||
33 | _ => true, | ||
34 | } | ||
35 | } | ||
36 | } | ||
37 | |||
38 | fn list_(p: &mut Parser, flavor: Flavor) { | ||
39 | let (bra, ket) = if flavor.type_required() { | ||
40 | (L_PAREN, R_PAREN) | ||
41 | } else { | ||
42 | (PIPE, PIPE) | ||
43 | }; | ||
44 | assert!(p.at(bra)); | ||
45 | let m = p.start(); | ||
46 | p.bump(); | ||
47 | if flavor.type_required() { | ||
48 | opt_self_param(p); | ||
49 | } | ||
50 | while !p.at(EOF) && !p.at(ket) { | ||
51 | if !p.at_ts(VALUE_PARAMETER_FIRST) { | ||
52 | p.error("expected value parameter"); | ||
53 | break; | ||
54 | } | ||
55 | value_parameter(p, flavor); | ||
56 | if !p.at(ket) { | ||
57 | p.expect(COMMA); | ||
58 | } | ||
59 | } | ||
60 | p.expect(ket); | ||
61 | m.complete(p, PARAM_LIST); | ||
62 | } | ||
63 | |||
64 | |||
65 | const VALUE_PARAMETER_FIRST: TokenSet = | ||
66 | token_set_union![ | ||
67 | patterns::PATTERN_FIRST, | ||
68 | types::TYPE_FIRST, | ||
69 | ]; | ||
70 | |||
71 | fn value_parameter(p: &mut Parser, flavor: Flavor) { | ||
72 | let m = p.start(); | ||
73 | match flavor { | ||
74 | Flavor::OptionalType | Flavor::Normal => { | ||
75 | patterns::pattern(p); | ||
76 | if p.at(COLON) || flavor.type_required() { | ||
77 | types::ascription(p) | ||
78 | } | ||
79 | }, | ||
80 | // test value_parameters_no_patterns | ||
81 | // type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>; | ||
82 | Flavor::OptionalPattern => { | ||
83 | let la0 = p.current(); | ||
84 | let la1 = p.nth(1); | ||
85 | let la2 = p.nth(2); | ||
86 | let la3 = p.nth(3); | ||
87 | if la0 == IDENT && la1 == COLON | ||
88 | || la0 == AMP && la1 == IDENT && la2 == COLON | ||
89 | || la0 == AMP && la1 == MUT_KW && la2 == IDENT && la3 == COLON { | ||
90 | patterns::pattern(p); | ||
91 | types::ascription(p); | ||
92 | } else { | ||
93 | types::type_(p); | ||
94 | } | ||
95 | }, | ||
96 | } | ||
97 | m.complete(p, PARAM); | ||
98 | } | ||
99 | |||
100 | // test self_param | ||
101 | // impl S { | ||
102 | // fn a(self) {} | ||
103 | // fn b(&self,) {} | ||
104 | // fn c(&'a self,) {} | ||
105 | // fn d(&'a mut self, x: i32) {} | ||
106 | // fn e(mut self) {} | ||
107 | // } | ||
108 | fn opt_self_param(p: &mut Parser) { | ||
109 | let m; | ||
110 | if p.at(SELF_KW) || p.at(MUT_KW) && p.nth(1) == SELF_KW { | ||
111 | m = p.start(); | ||
112 | p.eat(MUT_KW); | ||
113 | p.eat(SELF_KW); | ||
114 | // test arb_self_types | ||
115 | // impl S { | ||
116 | // fn a(self: &Self) {} | ||
117 | // fn b(mut self: Box<Self>) {} | ||
118 | // } | ||
119 | if p.at(COLON) { | ||
120 | types::ascription(p); | ||
121 | } | ||
122 | } else { | ||
123 | let la1 = p.nth(1); | ||
124 | let la2 = p.nth(2); | ||
125 | let la3 = p.nth(3); | ||
126 | let n_toks = match (p.current(), la1, la2, la3) { | ||
127 | (AMP, SELF_KW, _, _) => 2, | ||
128 | (AMP, MUT_KW, SELF_KW, _) => 3, | ||
129 | (AMP, LIFETIME, SELF_KW, _) => 3, | ||
130 | (AMP, LIFETIME, MUT_KW, SELF_KW) => 4, | ||
131 | _ => return, | ||
132 | }; | ||
133 | m = p.start(); | ||
134 | for _ in 0..n_toks { | ||
135 | p.bump(); | ||
136 | } | ||
137 | } | ||
138 | m.complete(p, SELF_PARAM); | ||
139 | if !p.at(R_PAREN) { | ||
140 | p.expect(COMMA); | ||
141 | } | ||
142 | } | ||
diff --git a/crates/ra_syntax/src/grammar/paths.rs b/crates/ra_syntax/src/grammar/paths.rs new file mode 100644 index 000000000..7c9fb8be2 --- /dev/null +++ b/crates/ra_syntax/src/grammar/paths.rs | |||
@@ -0,0 +1,101 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) const PATH_FIRST: TokenSet = | ||
4 | token_set![IDENT, SELF_KW, SUPER_KW, COLONCOLON, L_ANGLE]; | ||
5 | |||
6 | pub(super) fn is_path_start(p: &Parser) -> bool { | ||
7 | match p.current() { | ||
8 | IDENT | SELF_KW | SUPER_KW | COLONCOLON => true, | ||
9 | _ => false, | ||
10 | } | ||
11 | } | ||
12 | |||
13 | pub(super) fn use_path(p: &mut Parser) { | ||
14 | path(p, Mode::Use) | ||
15 | } | ||
16 | |||
17 | pub(super) fn type_path(p: &mut Parser) { | ||
18 | path(p, Mode::Type) | ||
19 | } | ||
20 | |||
21 | pub(super) fn expr_path(p: &mut Parser) { | ||
22 | path(p, Mode::Expr) | ||
23 | } | ||
24 | |||
25 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
26 | enum Mode { | ||
27 | Use, | ||
28 | Type, | ||
29 | Expr, | ||
30 | } | ||
31 | |||
32 | fn path(p: &mut Parser, mode: Mode) { | ||
33 | let path = p.start(); | ||
34 | path_segment(p, mode, true); | ||
35 | let mut qual = path.complete(p, PATH); | ||
36 | loop { | ||
37 | let use_tree = match p.nth(1) { | ||
38 | STAR | L_CURLY => true, | ||
39 | _ => false, | ||
40 | }; | ||
41 | if p.at(COLONCOLON) && !use_tree { | ||
42 | let path = qual.precede(p); | ||
43 | p.bump(); | ||
44 | path_segment(p, mode, false); | ||
45 | let path = path.complete(p, PATH); | ||
46 | qual = path; | ||
47 | } else { | ||
48 | break; | ||
49 | } | ||
50 | } | ||
51 | } | ||
52 | |||
53 | fn path_segment(p: &mut Parser, mode: Mode, first: bool) { | ||
54 | let m = p.start(); | ||
55 | // test qual_paths | ||
56 | // type X = <A as B>::Output; | ||
57 | // fn foo() { <usize as Default>::default(); } | ||
58 | if first && p.eat(L_ANGLE) { | ||
59 | types::type_(p); | ||
60 | if p.eat(AS_KW) { | ||
61 | if is_path_start(p) { | ||
62 | types::path_type(p); | ||
63 | } else { | ||
64 | p.error("expected a trait"); | ||
65 | } | ||
66 | } | ||
67 | p.expect(R_ANGLE); | ||
68 | } else { | ||
69 | if first { | ||
70 | p.eat(COLONCOLON); | ||
71 | } | ||
72 | match p.current() { | ||
73 | IDENT => { | ||
74 | name_ref(p); | ||
75 | opt_path_type_args(p, mode); | ||
76 | } | ||
77 | SELF_KW | SUPER_KW => p.bump(), | ||
78 | _ => { | ||
79 | p.err_and_bump("expected identifier"); | ||
80 | } | ||
81 | }; | ||
82 | } | ||
83 | m.complete(p, PATH_SEGMENT); | ||
84 | } | ||
85 | |||
86 | fn opt_path_type_args(p: &mut Parser, mode: Mode) { | ||
87 | match mode { | ||
88 | Mode::Use => return, | ||
89 | Mode::Type => { | ||
90 | // test path_fn_trait_args | ||
91 | // type F = Box<Fn(x: i32) -> ()>; | ||
92 | if p.at(L_PAREN) { | ||
93 | params::param_list_opt_patterns(p); | ||
94 | opt_fn_ret_type(p); | ||
95 | } else { | ||
96 | type_args::opt_type_arg_list(p, false) | ||
97 | } | ||
98 | }, | ||
99 | Mode::Expr => type_args::opt_type_arg_list(p, true), | ||
100 | } | ||
101 | } | ||
diff --git a/crates/ra_syntax/src/grammar/patterns.rs b/crates/ra_syntax/src/grammar/patterns.rs new file mode 100644 index 000000000..420bae7a7 --- /dev/null +++ b/crates/ra_syntax/src/grammar/patterns.rs | |||
@@ -0,0 +1,224 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) const PATTERN_FIRST: TokenSet = | ||
4 | token_set_union![ | ||
5 | token_set![REF_KW, MUT_KW, L_PAREN, L_BRACK, AMP, UNDERSCORE], | ||
6 | expressions::LITERAL_FIRST, | ||
7 | paths::PATH_FIRST, | ||
8 | ]; | ||
9 | |||
10 | pub(super) fn pattern(p: &mut Parser) { | ||
11 | pattern_r(p, PAT_RECOVERY_SET) | ||
12 | } | ||
13 | |||
14 | pub(super) fn pattern_r(p: &mut Parser, recovery_set: TokenSet) { | ||
15 | if let Some(lhs) = atom_pat(p, recovery_set) { | ||
16 | // test range_pat | ||
17 | // fn main() { | ||
18 | // match 92 { 0 ... 100 => () } | ||
19 | // } | ||
20 | if p.at(DOTDOTDOT) { | ||
21 | let m = lhs.precede(p); | ||
22 | p.bump(); | ||
23 | atom_pat(p, recovery_set); | ||
24 | m.complete(p, RANGE_PAT); | ||
25 | } | ||
26 | } | ||
27 | } | ||
28 | |||
29 | const PAT_RECOVERY_SET: TokenSet = | ||
30 | token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]; | ||
31 | |||
32 | |||
33 | fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | ||
34 | let la0 = p.nth(0); | ||
35 | let la1 = p.nth(1); | ||
36 | if la0 == REF_KW || la0 == MUT_KW | ||
37 | || (la0 == IDENT && !(la1 == COLONCOLON || la1 == L_PAREN || la1 == L_CURLY)) { | ||
38 | return Some(bind_pat(p, true)); | ||
39 | } | ||
40 | if paths::is_path_start(p) { | ||
41 | return Some(path_pat(p)); | ||
42 | } | ||
43 | |||
44 | // test literal_pattern | ||
45 | // fn main() { | ||
46 | // match () { | ||
47 | // 92 => (), | ||
48 | // 'c' => (), | ||
49 | // "hello" => (), | ||
50 | // } | ||
51 | // } | ||
52 | match expressions::literal(p) { | ||
53 | Some(m) => return Some(m), | ||
54 | None => (), | ||
55 | } | ||
56 | |||
57 | let m = match la0 { | ||
58 | UNDERSCORE => placeholder_pat(p), | ||
59 | AMP => ref_pat(p), | ||
60 | L_PAREN => tuple_pat(p), | ||
61 | L_BRACK => slice_pat(p), | ||
62 | _ => { | ||
63 | p.err_recover("expected pattern", recovery_set); | ||
64 | return None; | ||
65 | } | ||
66 | }; | ||
67 | Some(m) | ||
68 | } | ||
69 | |||
70 | // test path_part | ||
71 | // fn foo() { | ||
72 | // let foo::Bar = (); | ||
73 | // let ::Bar = (); | ||
74 | // let Bar { .. } = (); | ||
75 | // let Bar(..) = (); | ||
76 | // } | ||
77 | fn path_pat(p: &mut Parser) -> CompletedMarker { | ||
78 | assert!(paths::is_path_start(p)); | ||
79 | let m = p.start(); | ||
80 | paths::expr_path(p); | ||
81 | let kind = match p.current() { | ||
82 | L_PAREN => { | ||
83 | tuple_pat_fields(p); | ||
84 | TUPLE_STRUCT_PAT | ||
85 | } | ||
86 | L_CURLY => { | ||
87 | field_pat_list(p); | ||
88 | STRUCT_PAT | ||
89 | } | ||
90 | _ => PATH_PAT | ||
91 | }; | ||
92 | m.complete(p, kind) | ||
93 | } | ||
94 | |||
95 | // test tuple_pat_fields | ||
96 | // fn foo() { | ||
97 | // let S() = (); | ||
98 | // let S(_) = (); | ||
99 | // let S(_,) = (); | ||
100 | // let S(_, .. , x) = (); | ||
101 | // } | ||
102 | fn tuple_pat_fields(p: &mut Parser) { | ||
103 | assert!(p.at(L_PAREN)); | ||
104 | p.bump(); | ||
105 | pat_list(p, R_PAREN); | ||
106 | p.expect(R_PAREN); | ||
107 | } | ||
108 | |||
109 | // test field_pat_list | ||
110 | // fn foo() { | ||
111 | // let S {} = (); | ||
112 | // let S { f, ref mut g } = (); | ||
113 | // let S { h: _, ..} = (); | ||
114 | // let S { h: _, } = (); | ||
115 | // } | ||
116 | fn field_pat_list(p: &mut Parser) { | ||
117 | assert!(p.at(L_CURLY)); | ||
118 | let m = p.start(); | ||
119 | p.bump(); | ||
120 | while !p.at(EOF) && !p.at(R_CURLY) { | ||
121 | match p.current() { | ||
122 | DOTDOT => p.bump(), | ||
123 | IDENT if p.nth(1) == COLON => { | ||
124 | p.bump(); | ||
125 | p.bump(); | ||
126 | pattern(p); | ||
127 | } | ||
128 | L_CURLY => error_block(p, "expected ident"), | ||
129 | _ => { | ||
130 | bind_pat(p, false); | ||
131 | } | ||
132 | } | ||
133 | if !p.at(R_CURLY) { | ||
134 | p.expect(COMMA); | ||
135 | } | ||
136 | } | ||
137 | p.expect(R_CURLY); | ||
138 | m.complete(p, FIELD_PAT_LIST); | ||
139 | } | ||
140 | |||
141 | // test placeholder_pat | ||
142 | // fn main() { let _ = (); } | ||
143 | fn placeholder_pat(p: &mut Parser) -> CompletedMarker { | ||
144 | assert!(p.at(UNDERSCORE)); | ||
145 | let m = p.start(); | ||
146 | p.bump(); | ||
147 | m.complete(p, PLACEHOLDER_PAT) | ||
148 | } | ||
149 | |||
150 | // test ref_pat | ||
151 | // fn main() { | ||
152 | // let &a = (); | ||
153 | // let &mut b = (); | ||
154 | // } | ||
155 | fn ref_pat(p: &mut Parser) -> CompletedMarker { | ||
156 | assert!(p.at(AMP)); | ||
157 | let m = p.start(); | ||
158 | p.bump(); | ||
159 | p.eat(MUT_KW); | ||
160 | pattern(p); | ||
161 | m.complete(p, REF_PAT) | ||
162 | } | ||
163 | |||
164 | // test tuple_pat | ||
165 | // fn main() { | ||
166 | // let (a, b, ..) = (); | ||
167 | // } | ||
168 | fn tuple_pat(p: &mut Parser) -> CompletedMarker { | ||
169 | assert!(p.at(L_PAREN)); | ||
170 | let m = p.start(); | ||
171 | tuple_pat_fields(p); | ||
172 | m.complete(p, TUPLE_PAT) | ||
173 | } | ||
174 | |||
175 | // test slice_pat | ||
176 | // fn main() { | ||
177 | // let [a, b, ..] = []; | ||
178 | // } | ||
179 | fn slice_pat(p: &mut Parser) -> CompletedMarker { | ||
180 | assert!(p.at(L_BRACK)); | ||
181 | let m = p.start(); | ||
182 | p.bump(); | ||
183 | pat_list(p, R_BRACK); | ||
184 | p.expect(R_BRACK); | ||
185 | m.complete(p, SLICE_PAT) | ||
186 | } | ||
187 | |||
188 | fn pat_list(p: &mut Parser, ket: SyntaxKind) { | ||
189 | while !p.at(EOF) && !p.at(ket) { | ||
190 | match p.current() { | ||
191 | DOTDOT => p.bump(), | ||
192 | _ => { | ||
193 | if !p.at_ts(PATTERN_FIRST) { | ||
194 | p.error("expected a pattern"); | ||
195 | break; | ||
196 | } | ||
197 | pattern(p) | ||
198 | }, | ||
199 | } | ||
200 | if !p.at(ket) { | ||
201 | p.expect(COMMA); | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | // test bind_pat | ||
207 | // fn main() { | ||
208 | // let a = (); | ||
209 | // let mut b = (); | ||
210 | // let ref c = (); | ||
211 | // let ref mut d = (); | ||
212 | // let e @ _ = (); | ||
213 | // let ref mut f @ g @ _ = (); | ||
214 | // } | ||
215 | fn bind_pat(p: &mut Parser, with_at: bool) -> CompletedMarker { | ||
216 | let m = p.start(); | ||
217 | p.eat(REF_KW); | ||
218 | p.eat(MUT_KW); | ||
219 | name(p); | ||
220 | if with_at && p.eat(AT) { | ||
221 | pattern(p); | ||
222 | } | ||
223 | m.complete(p, BIND_PAT) | ||
224 | } | ||
diff --git a/crates/ra_syntax/src/grammar/type_args.rs b/crates/ra_syntax/src/grammar/type_args.rs new file mode 100644 index 000000000..29ff6e534 --- /dev/null +++ b/crates/ra_syntax/src/grammar/type_args.rs | |||
@@ -0,0 +1,48 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) { | ||
4 | let m; | ||
5 | match (colon_colon_required, p.nth(0), p.nth(1)) { | ||
6 | (_, COLONCOLON, L_ANGLE) => { | ||
7 | m = p.start(); | ||
8 | p.bump(); | ||
9 | p.bump(); | ||
10 | } | ||
11 | (false, L_ANGLE, _) => { | ||
12 | m = p.start(); | ||
13 | p.bump(); | ||
14 | } | ||
15 | _ => return, | ||
16 | }; | ||
17 | |||
18 | while !p.at(EOF) && !p.at(R_ANGLE) { | ||
19 | type_arg(p); | ||
20 | if !p.at(R_ANGLE) && !p.expect(COMMA) { | ||
21 | break; | ||
22 | } | ||
23 | } | ||
24 | p.expect(R_ANGLE); | ||
25 | m.complete(p, TYPE_ARG_LIST); | ||
26 | } | ||
27 | |||
28 | // test type_arg | ||
29 | // type A = B<'static, i32, Item=u64> | ||
30 | fn type_arg(p: &mut Parser) { | ||
31 | let m = p.start(); | ||
32 | match p.current() { | ||
33 | LIFETIME => { | ||
34 | p.bump(); | ||
35 | m.complete(p, LIFETIME_ARG); | ||
36 | } | ||
37 | IDENT if p.nth(1) == EQ => { | ||
38 | name_ref(p); | ||
39 | p.bump(); | ||
40 | types::type_(p); | ||
41 | m.complete(p, ASSOC_TYPE_ARG); | ||
42 | } | ||
43 | _ => { | ||
44 | types::type_(p); | ||
45 | m.complete(p, TYPE_ARG); | ||
46 | } | ||
47 | } | ||
48 | } | ||
diff --git a/crates/ra_syntax/src/grammar/type_params.rs b/crates/ra_syntax/src/grammar/type_params.rs new file mode 100644 index 000000000..79bc95ce4 --- /dev/null +++ b/crates/ra_syntax/src/grammar/type_params.rs | |||
@@ -0,0 +1,136 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) fn opt_type_param_list(p: &mut Parser) { | ||
4 | if !p.at(L_ANGLE) { | ||
5 | return; | ||
6 | } | ||
7 | let m = p.start(); | ||
8 | p.bump(); | ||
9 | |||
10 | while !p.at(EOF) && !p.at(R_ANGLE) { | ||
11 | match p.current() { | ||
12 | LIFETIME => lifetime_param(p), | ||
13 | IDENT => type_param(p), | ||
14 | _ => p.err_and_bump("expected type parameter"), | ||
15 | } | ||
16 | if !p.at(R_ANGLE) && !p.expect(COMMA) { | ||
17 | break; | ||
18 | } | ||
19 | } | ||
20 | p.expect(R_ANGLE); | ||
21 | m.complete(p, TYPE_PARAM_LIST); | ||
22 | |||
23 | fn lifetime_param(p: &mut Parser) { | ||
24 | assert!(p.at(LIFETIME)); | ||
25 | let m = p.start(); | ||
26 | p.bump(); | ||
27 | if p.at(COLON) { | ||
28 | lifetime_bounds(p); | ||
29 | } | ||
30 | m.complete(p, LIFETIME_PARAM); | ||
31 | } | ||
32 | |||
33 | fn type_param(p: &mut Parser) { | ||
34 | assert!(p.at(IDENT)); | ||
35 | let m = p.start(); | ||
36 | name(p); | ||
37 | if p.at(COLON) { | ||
38 | bounds(p); | ||
39 | } | ||
40 | // test type_param_default | ||
41 | // struct S<T = i32>; | ||
42 | if p.at(EQ) { | ||
43 | p.bump(); | ||
44 | types::type_(p) | ||
45 | } | ||
46 | m.complete(p, TYPE_PARAM); | ||
47 | } | ||
48 | } | ||
49 | |||
50 | // test type_param_bounds | ||
51 | // struct S<T: 'a + ?Sized + (Copy)>; | ||
52 | pub(super) fn bounds(p: &mut Parser) { | ||
53 | assert!(p.at(COLON)); | ||
54 | p.bump(); | ||
55 | bounds_without_colon(p); | ||
56 | } | ||
57 | |||
58 | fn lifetime_bounds(p: &mut Parser) { | ||
59 | assert!(p.at(COLON)); | ||
60 | p.bump(); | ||
61 | while p.at(LIFETIME) { | ||
62 | p.bump(); | ||
63 | if !p.eat(PLUS) { | ||
64 | break; | ||
65 | } | ||
66 | } | ||
67 | } | ||
68 | |||
69 | pub(super) fn bounds_without_colon(p: &mut Parser) { | ||
70 | loop { | ||
71 | let has_paren = p.eat(L_PAREN); | ||
72 | p.eat(QUESTION); | ||
73 | match p.current() { | ||
74 | LIFETIME => p.bump(), | ||
75 | FOR_KW => { | ||
76 | types::for_type(p) | ||
77 | } | ||
78 | _ if paths::is_path_start(p) => { | ||
79 | types::path_type(p) | ||
80 | } | ||
81 | _ => break, | ||
82 | } | ||
83 | if has_paren { | ||
84 | p.expect(R_PAREN); | ||
85 | } | ||
86 | if !p.eat(PLUS) { | ||
87 | break; | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | // test where_clause | ||
93 | // fn foo() | ||
94 | // where | ||
95 | // 'a: 'b + 'c, | ||
96 | // T: Clone + Copy + 'static, | ||
97 | // Iterator::Item: 'a, | ||
98 | // {} | ||
99 | pub(super) fn opt_where_clause(p: &mut Parser) { | ||
100 | if !p.at(WHERE_KW) { | ||
101 | return; | ||
102 | } | ||
103 | let m = p.start(); | ||
104 | p.bump(); | ||
105 | loop { | ||
106 | if !(paths::is_path_start(p) || p.current() == LIFETIME) { | ||
107 | break | ||
108 | } | ||
109 | where_predicate(p); | ||
110 | if p.current() != L_CURLY && p.current() != SEMI { | ||
111 | p.expect(COMMA); | ||
112 | } | ||
113 | } | ||
114 | m.complete(p, WHERE_CLAUSE); | ||
115 | } | ||
116 | |||
117 | fn where_predicate(p: &mut Parser) { | ||
118 | let m = p.start(); | ||
119 | if p.at(LIFETIME) { | ||
120 | p.eat(LIFETIME); | ||
121 | if p.at(COLON) { | ||
122 | lifetime_bounds(p) | ||
123 | } else { | ||
124 | p.error("expected colon") | ||
125 | } | ||
126 | } else { | ||
127 | types::path_type(p); | ||
128 | if p.at(COLON) { | ||
129 | bounds(p); | ||
130 | } else { | ||
131 | p.error("expected colon") | ||
132 | } | ||
133 | |||
134 | } | ||
135 | m.complete(p, WHERE_PRED); | ||
136 | } | ||
diff --git a/crates/ra_syntax/src/grammar/types.rs b/crates/ra_syntax/src/grammar/types.rs new file mode 100644 index 000000000..27e5b086e --- /dev/null +++ b/crates/ra_syntax/src/grammar/types.rs | |||
@@ -0,0 +1,247 @@ | |||
1 | use super::*; | ||
2 | |||
3 | pub(super) const TYPE_FIRST: TokenSet = | ||
4 | token_set_union![ | ||
5 | token_set![ | ||
6 | L_PAREN, EXCL, STAR, L_BRACK, AMP, UNDERSCORE, FN_KW, UNSAFE_KW, EXTERN_KW, FOR_KW, IMPL_KW, DYN_KW, L_ANGLE, | ||
7 | ], | ||
8 | paths::PATH_FIRST, | ||
9 | ]; | ||
10 | |||
11 | const TYPE_RECOVERY_SET: TokenSet = | ||
12 | token_set![R_PAREN, COMMA]; | ||
13 | |||
14 | pub(super) fn type_(p: &mut Parser) { | ||
15 | match p.current() { | ||
16 | L_PAREN => paren_or_tuple_type(p), | ||
17 | EXCL => never_type(p), | ||
18 | STAR => pointer_type(p), | ||
19 | L_BRACK => array_or_slice_type(p), | ||
20 | AMP => reference_type(p), | ||
21 | UNDERSCORE => placeholder_type(p), | ||
22 | FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), | ||
23 | FOR_KW => for_type(p), | ||
24 | IMPL_KW => impl_trait_type(p), | ||
25 | DYN_KW => dyn_trait_type(p), | ||
26 | L_ANGLE => path_type(p), | ||
27 | _ if paths::is_path_start(p) => path_type(p), | ||
28 | _ => { | ||
29 | p.err_recover("expected type", TYPE_RECOVERY_SET); | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | |||
34 | pub(super) fn ascription(p: &mut Parser) { | ||
35 | p.expect(COLON); | ||
36 | type_(p) | ||
37 | } | ||
38 | |||
39 | fn type_no_plus(p: &mut Parser) { | ||
40 | type_(p); | ||
41 | } | ||
42 | |||
43 | fn paren_or_tuple_type(p: &mut Parser) { | ||
44 | assert!(p.at(L_PAREN)); | ||
45 | let m = p.start(); | ||
46 | p.bump(); | ||
47 | let mut n_types: u32 = 0; | ||
48 | let mut trailing_comma: bool = false; | ||
49 | while !p.at(EOF) && !p.at(R_PAREN) { | ||
50 | n_types += 1; | ||
51 | type_(p); | ||
52 | if p.eat(COMMA) { | ||
53 | trailing_comma = true; | ||
54 | } else { | ||
55 | trailing_comma = false; | ||
56 | break; | ||
57 | } | ||
58 | } | ||
59 | p.expect(R_PAREN); | ||
60 | |||
61 | let kind = if n_types == 1 && !trailing_comma { | ||
62 | // test paren_type | ||
63 | // type T = (i32); | ||
64 | PAREN_TYPE | ||
65 | } else { | ||
66 | // test unit_type | ||
67 | // type T = (); | ||
68 | |||
69 | // test singleton_tuple_type | ||
70 | // type T = (i32,); | ||
71 | TUPLE_TYPE | ||
72 | }; | ||
73 | m.complete(p, kind); | ||
74 | } | ||
75 | |||
76 | // test never_type | ||
77 | // type Never = !; | ||
78 | fn never_type(p: &mut Parser) { | ||
79 | assert!(p.at(EXCL)); | ||
80 | let m = p.start(); | ||
81 | p.bump(); | ||
82 | m.complete(p, NEVER_TYPE); | ||
83 | } | ||
84 | |||
85 | fn pointer_type(p: &mut Parser) { | ||
86 | assert!(p.at(STAR)); | ||
87 | let m = p.start(); | ||
88 | p.bump(); | ||
89 | |||
90 | match p.current() { | ||
91 | // test pointer_type_mut | ||
92 | // type M = *mut (); | ||
93 | // type C = *mut (); | ||
94 | MUT_KW | CONST_KW => p.bump(), | ||
95 | _ => { | ||
96 | // test pointer_type_no_mutability | ||
97 | // type T = *(); | ||
98 | p.error( | ||
99 | "expected mut or const in raw pointer type \ | ||
100 | (use `*mut T` or `*const T` as appropriate)", | ||
101 | ); | ||
102 | } | ||
103 | }; | ||
104 | |||
105 | type_no_plus(p); | ||
106 | m.complete(p, POINTER_TYPE); | ||
107 | } | ||
108 | |||
109 | fn array_or_slice_type(p: &mut Parser) { | ||
110 | assert!(p.at(L_BRACK)); | ||
111 | let m = p.start(); | ||
112 | p.bump(); | ||
113 | |||
114 | type_(p); | ||
115 | let kind = match p.current() { | ||
116 | // test slice_type | ||
117 | // type T = [()]; | ||
118 | R_BRACK => { | ||
119 | p.bump(); | ||
120 | SLICE_TYPE | ||
121 | } | ||
122 | |||
123 | // test array_type | ||
124 | // type T = [(); 92]; | ||
125 | SEMI => { | ||
126 | p.bump(); | ||
127 | expressions::expr(p); | ||
128 | p.expect(R_BRACK); | ||
129 | ARRAY_TYPE | ||
130 | } | ||
131 | // test array_type_missing_semi | ||
132 | // type T = [() 92]; | ||
133 | _ => { | ||
134 | p.error("expected `;` or `]`"); | ||
135 | SLICE_TYPE | ||
136 | } | ||
137 | }; | ||
138 | m.complete(p, kind); | ||
139 | } | ||
140 | |||
141 | // test reference_type; | ||
142 | // type A = &(); | ||
143 | // type B = &'static (); | ||
144 | // type C = &mut (); | ||
145 | fn reference_type(p: &mut Parser) { | ||
146 | assert!(p.at(AMP)); | ||
147 | let m = p.start(); | ||
148 | p.bump(); | ||
149 | p.eat(LIFETIME); | ||
150 | p.eat(MUT_KW); | ||
151 | type_no_plus(p); | ||
152 | m.complete(p, REFERENCE_TYPE); | ||
153 | } | ||
154 | |||
155 | // test placeholder_type | ||
156 | // type Placeholder = _; | ||
157 | fn placeholder_type(p: &mut Parser) { | ||
158 | assert!(p.at(UNDERSCORE)); | ||
159 | let m = p.start(); | ||
160 | p.bump(); | ||
161 | m.complete(p, PLACEHOLDER_TYPE); | ||
162 | } | ||
163 | |||
164 | // test fn_pointer_type | ||
165 | // type A = fn(); | ||
166 | // type B = unsafe fn(); | ||
167 | // type C = unsafe extern "C" fn(); | ||
168 | fn fn_pointer_type(p: &mut Parser) { | ||
169 | let m = p.start(); | ||
170 | p.eat(UNSAFE_KW); | ||
171 | if p.at(EXTERN_KW) { | ||
172 | abi(p); | ||
173 | } | ||
174 | // test fn_pointer_type_missing_fn | ||
175 | // type F = unsafe (); | ||
176 | if !p.eat(FN_KW) { | ||
177 | m.abandon(p); | ||
178 | p.error("expected `fn`"); | ||
179 | return; | ||
180 | } | ||
181 | if p.at(L_PAREN) { | ||
182 | params::param_list_opt_patterns(p); | ||
183 | } else { | ||
184 | p.error("expected parameters") | ||
185 | } | ||
186 | // test fn_pointer_type_with_ret | ||
187 | // type F = fn() -> (); | ||
188 | opt_fn_ret_type(p); | ||
189 | m.complete(p, FN_POINTER_TYPE); | ||
190 | } | ||
191 | |||
192 | // test for_type | ||
193 | // type A = for<'a> fn() -> (); | ||
194 | pub(super) fn for_type(p: &mut Parser) { | ||
195 | assert!(p.at(FOR_KW)); | ||
196 | let m = p.start(); | ||
197 | p.bump(); | ||
198 | type_params::opt_type_param_list(p); | ||
199 | match p.current() { | ||
200 | FN_KW | UNSAFE_KW | EXTERN_KW => fn_pointer_type(p), | ||
201 | _ if paths::is_path_start(p) => path_type_(p, false), | ||
202 | _ => p.error("expected a path"), | ||
203 | |||
204 | } | ||
205 | m.complete(p, FOR_TYPE); | ||
206 | } | ||
207 | |||
208 | // test impl_trait_type | ||
209 | // type A = impl Iterator<Item=Foo<'a>> + 'a; | ||
210 | fn impl_trait_type(p: &mut Parser) { | ||
211 | assert!(p.at(IMPL_KW)); | ||
212 | let m = p.start(); | ||
213 | p.bump(); | ||
214 | type_params::bounds_without_colon(p); | ||
215 | m.complete(p, IMPL_TRAIT_TYPE); | ||
216 | } | ||
217 | |||
218 | // test dyn_trait_type | ||
219 | // type A = dyn Iterator<Item=Foo<'a>> + 'a; | ||
220 | fn dyn_trait_type(p: &mut Parser) { | ||
221 | assert!(p.at(DYN_KW)); | ||
222 | let m = p.start(); | ||
223 | p.bump(); | ||
224 | type_params::bounds_without_colon(p); | ||
225 | m.complete(p, DYN_TRAIT_TYPE); | ||
226 | } | ||
227 | |||
228 | // test path_type | ||
229 | // type A = Foo; | ||
230 | // type B = ::Foo; | ||
231 | // type C = self::Foo; | ||
232 | // type D = super::Foo; | ||
233 | pub(super) fn path_type(p: &mut Parser) { | ||
234 | path_type_(p, true) | ||
235 | } | ||
236 | |||
237 | pub(super) fn path_type_(p: &mut Parser, allow_bounds: bool) { | ||
238 | assert!(paths::is_path_start(p) || p.at(L_ANGLE)); | ||
239 | let m = p.start(); | ||
240 | paths::type_path(p); | ||
241 | // test path_type_with_bounds | ||
242 | // fn foo() -> Box<T + 'f> {} | ||
243 | if allow_bounds && p.eat(PLUS) { | ||
244 | type_params::bounds_without_colon(p); | ||
245 | } | ||
246 | m.complete(p, PATH_TYPE); | ||
247 | } | ||
diff --git a/crates/ra_syntax/src/lexer/classes.rs b/crates/ra_syntax/src/lexer/classes.rs new file mode 100644 index 000000000..4235d2648 --- /dev/null +++ b/crates/ra_syntax/src/lexer/classes.rs | |||
@@ -0,0 +1,26 @@ | |||
1 | use unicode_xid::UnicodeXID; | ||
2 | |||
3 | pub fn is_ident_start(c: char) -> bool { | ||
4 | (c >= 'a' && c <= 'z') | ||
5 | || (c >= 'A' && c <= 'Z') | ||
6 | || c == '_' | ||
7 | || (c > '\x7f' && UnicodeXID::is_xid_start(c)) | ||
8 | } | ||
9 | |||
10 | pub fn is_ident_continue(c: char) -> bool { | ||
11 | (c >= 'a' && c <= 'z') | ||
12 | || (c >= 'A' && c <= 'Z') | ||
13 | || (c >= '0' && c <= '9') | ||
14 | || c == '_' | ||
15 | || (c > '\x7f' && UnicodeXID::is_xid_continue(c)) | ||
16 | } | ||
17 | |||
18 | pub fn is_whitespace(c: char) -> bool { | ||
19 | //FIXME: use is_pattern_whitespace | ||
20 | //https://github.com/behnam/rust-unic/issues/192 | ||
21 | c.is_whitespace() | ||
22 | } | ||
23 | |||
24 | pub fn is_dec_digit(c: char) -> bool { | ||
25 | '0' <= c && c <= '9' | ||
26 | } | ||
diff --git a/crates/ra_syntax/src/lexer/comments.rs b/crates/ra_syntax/src/lexer/comments.rs new file mode 100644 index 000000000..eb417c2dc --- /dev/null +++ b/crates/ra_syntax/src/lexer/comments.rs | |||
@@ -0,0 +1,57 @@ | |||
1 | use lexer::ptr::Ptr; | ||
2 | |||
3 | use SyntaxKind::{self, *}; | ||
4 | |||
5 | pub(crate) fn scan_shebang(ptr: &mut Ptr) -> bool { | ||
6 | if ptr.at_str("!/") { | ||
7 | ptr.bump(); | ||
8 | ptr.bump(); | ||
9 | bump_until_eol(ptr); | ||
10 | true | ||
11 | } else { | ||
12 | false | ||
13 | } | ||
14 | } | ||
15 | |||
16 | fn scan_block_comment(ptr: &mut Ptr) -> Option<SyntaxKind> { | ||
17 | if ptr.at('*') { | ||
18 | ptr.bump(); | ||
19 | let mut depth: u32 = 1; | ||
20 | while depth > 0 { | ||
21 | if ptr.at_str("*/") { | ||
22 | depth -= 1; | ||
23 | ptr.bump(); | ||
24 | ptr.bump(); | ||
25 | } else if ptr.at_str("/*") { | ||
26 | depth += 1; | ||
27 | ptr.bump(); | ||
28 | ptr.bump(); | ||
29 | } else if ptr.bump().is_none() { | ||
30 | break; | ||
31 | } | ||
32 | } | ||
33 | Some(COMMENT) | ||
34 | } else { | ||
35 | None | ||
36 | } | ||
37 | } | ||
38 | |||
39 | pub(crate) fn scan_comment(ptr: &mut Ptr) -> Option<SyntaxKind> { | ||
40 | if ptr.at('/') { | ||
41 | bump_until_eol(ptr); | ||
42 | Some(COMMENT) | ||
43 | } else { | ||
44 | scan_block_comment(ptr) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | fn bump_until_eol(ptr: &mut Ptr) { | ||
49 | loop { | ||
50 | if ptr.at('\n') || ptr.at_str("\r\n") { | ||
51 | return; | ||
52 | } | ||
53 | if ptr.bump().is_none() { | ||
54 | break; | ||
55 | } | ||
56 | } | ||
57 | } | ||
diff --git a/crates/ra_syntax/src/lexer/mod.rs b/crates/ra_syntax/src/lexer/mod.rs new file mode 100644 index 000000000..3e11db88b --- /dev/null +++ b/crates/ra_syntax/src/lexer/mod.rs | |||
@@ -0,0 +1,209 @@ | |||
1 | mod classes; | ||
2 | mod comments; | ||
3 | mod numbers; | ||
4 | mod ptr; | ||
5 | mod strings; | ||
6 | |||
7 | use { | ||
8 | SyntaxKind::{self, *}, | ||
9 | TextUnit, | ||
10 | }; | ||
11 | |||
12 | use self::{ | ||
13 | classes::*, | ||
14 | comments::{scan_comment, scan_shebang}, | ||
15 | numbers::scan_number, | ||
16 | ptr::Ptr, | ||
17 | strings::{ | ||
18 | is_string_literal_start, scan_byte_char_or_string, scan_char, scan_raw_string, scan_string, | ||
19 | }, | ||
20 | }; | ||
21 | |||
22 | /// A token of Rust source. | ||
23 | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
24 | pub struct Token { | ||
25 | /// The kind of token. | ||
26 | pub kind: SyntaxKind, | ||
27 | /// The length of the token. | ||
28 | pub len: TextUnit, | ||
29 | } | ||
30 | |||
31 | /// Break a string up into its component tokens | ||
32 | pub fn tokenize(text: &str) -> Vec<Token> { | ||
33 | let mut text = text; | ||
34 | let mut acc = Vec::new(); | ||
35 | while !text.is_empty() { | ||
36 | let token = next_token(text); | ||
37 | acc.push(token); | ||
38 | let len: u32 = token.len.into(); | ||
39 | text = &text[len as usize..]; | ||
40 | } | ||
41 | acc | ||
42 | } | ||
43 | |||
44 | /// Get the next token from a string | ||
45 | pub fn next_token(text: &str) -> Token { | ||
46 | assert!(!text.is_empty()); | ||
47 | let mut ptr = Ptr::new(text); | ||
48 | let c = ptr.bump().unwrap(); | ||
49 | let kind = next_token_inner(c, &mut ptr); | ||
50 | let len = ptr.into_len(); | ||
51 | Token { kind, len } | ||
52 | } | ||
53 | |||
54 | fn next_token_inner(c: char, ptr: &mut Ptr) -> SyntaxKind { | ||
55 | if is_whitespace(c) { | ||
56 | ptr.bump_while(is_whitespace); | ||
57 | return WHITESPACE; | ||
58 | } | ||
59 | |||
60 | match c { | ||
61 | '#' => if scan_shebang(ptr) { | ||
62 | return SHEBANG; | ||
63 | }, | ||
64 | '/' => if let Some(kind) = scan_comment(ptr) { | ||
65 | return kind; | ||
66 | }, | ||
67 | _ => (), | ||
68 | } | ||
69 | |||
70 | let ident_start = is_ident_start(c) && !is_string_literal_start(c, ptr.current(), ptr.nth(1)); | ||
71 | if ident_start { | ||
72 | return scan_ident(c, ptr); | ||
73 | } | ||
74 | |||
75 | if is_dec_digit(c) { | ||
76 | let kind = scan_number(c, ptr); | ||
77 | scan_literal_suffix(ptr); | ||
78 | return kind; | ||
79 | } | ||
80 | |||
81 | // One-byte tokens. | ||
82 | if let Some(kind) = SyntaxKind::from_char(c) { | ||
83 | return kind; | ||
84 | } | ||
85 | |||
86 | match c { | ||
87 | // Multi-byte tokens. | ||
88 | '.' => { | ||
89 | return match (ptr.current(), ptr.nth(1)) { | ||
90 | (Some('.'), Some('.')) => { | ||
91 | ptr.bump(); | ||
92 | ptr.bump(); | ||
93 | DOTDOTDOT | ||
94 | } | ||
95 | (Some('.'), Some('=')) => { | ||
96 | ptr.bump(); | ||
97 | ptr.bump(); | ||
98 | DOTDOTEQ | ||
99 | } | ||
100 | (Some('.'), _) => { | ||
101 | ptr.bump(); | ||
102 | DOTDOT | ||
103 | } | ||
104 | _ => DOT, | ||
105 | }; | ||
106 | } | ||
107 | ':' => { | ||
108 | return match ptr.current() { | ||
109 | Some(':') => { | ||
110 | ptr.bump(); | ||
111 | COLONCOLON | ||
112 | } | ||
113 | _ => COLON, | ||
114 | }; | ||
115 | } | ||
116 | '=' => { | ||
117 | return match ptr.current() { | ||
118 | Some('=') => { | ||
119 | ptr.bump(); | ||
120 | EQEQ | ||
121 | } | ||
122 | Some('>') => { | ||
123 | ptr.bump(); | ||
124 | FAT_ARROW | ||
125 | } | ||
126 | _ => EQ, | ||
127 | }; | ||
128 | } | ||
129 | '!' => { | ||
130 | return match ptr.current() { | ||
131 | Some('=') => { | ||
132 | ptr.bump(); | ||
133 | NEQ | ||
134 | } | ||
135 | _ => EXCL, | ||
136 | }; | ||
137 | } | ||
138 | '-' => { | ||
139 | return if ptr.at('>') { | ||
140 | ptr.bump(); | ||
141 | THIN_ARROW | ||
142 | } else { | ||
143 | MINUS | ||
144 | }; | ||
145 | } | ||
146 | |||
147 | // If the character is an ident start not followed by another single | ||
148 | // quote, then this is a lifetime name: | ||
149 | '\'' => { | ||
150 | return if ptr.at_p(is_ident_start) && !ptr.at_str("''") { | ||
151 | ptr.bump(); | ||
152 | while ptr.at_p(is_ident_continue) { | ||
153 | ptr.bump(); | ||
154 | } | ||
155 | // lifetimes shouldn't end with a single quote | ||
156 | // if we find one, then this is an invalid character literal | ||
157 | if ptr.at('\'') { | ||
158 | ptr.bump(); | ||
159 | return CHAR; // TODO: error reporting | ||
160 | } | ||
161 | LIFETIME | ||
162 | } else { | ||
163 | scan_char(ptr); | ||
164 | scan_literal_suffix(ptr); | ||
165 | CHAR | ||
166 | }; | ||
167 | } | ||
168 | 'b' => { | ||
169 | let kind = scan_byte_char_or_string(ptr); | ||
170 | scan_literal_suffix(ptr); | ||
171 | return kind; | ||
172 | } | ||
173 | '"' => { | ||
174 | scan_string(ptr); | ||
175 | scan_literal_suffix(ptr); | ||
176 | return STRING; | ||
177 | } | ||
178 | 'r' => { | ||
179 | scan_raw_string(ptr); | ||
180 | scan_literal_suffix(ptr); | ||
181 | return RAW_STRING; | ||
182 | } | ||
183 | _ => (), | ||
184 | } | ||
185 | ERROR | ||
186 | } | ||
187 | |||
188 | fn scan_ident(c: char, ptr: &mut Ptr) -> SyntaxKind { | ||
189 | let is_single_letter = match ptr.current() { | ||
190 | None => true, | ||
191 | Some(c) if !is_ident_continue(c) => true, | ||
192 | _ => false, | ||
193 | }; | ||
194 | if is_single_letter { | ||
195 | return if c == '_' { UNDERSCORE } else { IDENT }; | ||
196 | } | ||
197 | ptr.bump_while(is_ident_continue); | ||
198 | if let Some(kind) = SyntaxKind::from_keyword(ptr.current_token_text()) { | ||
199 | return kind; | ||
200 | } | ||
201 | IDENT | ||
202 | } | ||
203 | |||
204 | fn scan_literal_suffix(ptr: &mut Ptr) { | ||
205 | if ptr.at_p(is_ident_start) { | ||
206 | ptr.bump(); | ||
207 | } | ||
208 | ptr.bump_while(is_ident_continue); | ||
209 | } | ||
diff --git a/crates/ra_syntax/src/lexer/numbers.rs b/crates/ra_syntax/src/lexer/numbers.rs new file mode 100644 index 000000000..22e7d4e99 --- /dev/null +++ b/crates/ra_syntax/src/lexer/numbers.rs | |||
@@ -0,0 +1,67 @@ | |||
1 | use lexer::classes::*; | ||
2 | use lexer::ptr::Ptr; | ||
3 | |||
4 | use SyntaxKind::{self, *}; | ||
5 | |||
6 | pub(crate) fn scan_number(c: char, ptr: &mut Ptr) -> SyntaxKind { | ||
7 | if c == '0' { | ||
8 | match ptr.current().unwrap_or('\0') { | ||
9 | 'b' | 'o' => { | ||
10 | ptr.bump(); | ||
11 | scan_digits(ptr, false); | ||
12 | } | ||
13 | 'x' => { | ||
14 | ptr.bump(); | ||
15 | scan_digits(ptr, true); | ||
16 | } | ||
17 | '0'...'9' | '_' | '.' | 'e' | 'E' => { | ||
18 | scan_digits(ptr, true); | ||
19 | } | ||
20 | _ => return INT_NUMBER, | ||
21 | } | ||
22 | } else { | ||
23 | scan_digits(ptr, false); | ||
24 | } | ||
25 | |||
26 | // might be a float, but don't be greedy if this is actually an | ||
27 | // integer literal followed by field/method access or a range pattern | ||
28 | // (`0..2` and `12.foo()`) | ||
29 | if ptr.at('.') && !(ptr.at_str("..") || ptr.nth_is_p(1, is_ident_start)) { | ||
30 | // might have stuff after the ., and if it does, it needs to start | ||
31 | // with a number | ||
32 | ptr.bump(); | ||
33 | scan_digits(ptr, false); | ||
34 | scan_float_exponent(ptr); | ||
35 | return FLOAT_NUMBER; | ||
36 | } | ||
37 | // it might be a float if it has an exponent | ||
38 | if ptr.at('e') || ptr.at('E') { | ||
39 | scan_float_exponent(ptr); | ||
40 | return FLOAT_NUMBER; | ||
41 | } | ||
42 | INT_NUMBER | ||
43 | } | ||
44 | |||
45 | fn scan_digits(ptr: &mut Ptr, allow_hex: bool) { | ||
46 | while let Some(c) = ptr.current() { | ||
47 | match c { | ||
48 | '_' | '0'...'9' => { | ||
49 | ptr.bump(); | ||
50 | } | ||
51 | 'a'...'f' | 'A'...'F' if allow_hex => { | ||
52 | ptr.bump(); | ||
53 | } | ||
54 | _ => return, | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | fn scan_float_exponent(ptr: &mut Ptr) { | ||
60 | if ptr.at('e') || ptr.at('E') { | ||
61 | ptr.bump(); | ||
62 | if ptr.at('-') || ptr.at('+') { | ||
63 | ptr.bump(); | ||
64 | } | ||
65 | scan_digits(ptr, false); | ||
66 | } | ||
67 | } | ||
diff --git a/crates/ra_syntax/src/lexer/ptr.rs b/crates/ra_syntax/src/lexer/ptr.rs new file mode 100644 index 000000000..c9a5354ea --- /dev/null +++ b/crates/ra_syntax/src/lexer/ptr.rs | |||
@@ -0,0 +1,166 @@ | |||
1 | use TextUnit; | ||
2 | |||
3 | use std::str::Chars; | ||
4 | |||
5 | /// A simple view into the characters of a string. | ||
6 | pub(crate) struct Ptr<'s> { | ||
7 | text: &'s str, | ||
8 | len: TextUnit, | ||
9 | } | ||
10 | |||
11 | impl<'s> Ptr<'s> { | ||
12 | /// Creates a new `Ptr` from a string. | ||
13 | pub fn new(text: &'s str) -> Ptr<'s> { | ||
14 | Ptr { | ||
15 | text, | ||
16 | len: 0.into(), | ||
17 | } | ||
18 | } | ||
19 | |||
20 | /// Gets the length of the remaining string. | ||
21 | pub fn into_len(self) -> TextUnit { | ||
22 | self.len | ||
23 | } | ||
24 | |||
25 | /// Gets the current character, if one exists. | ||
26 | pub fn current(&self) -> Option<char> { | ||
27 | self.chars().next() | ||
28 | } | ||
29 | |||
30 | /// Gets the nth character from the current. | ||
31 | /// For example, 0 will return the current token, 1 will return the next, etc. | ||
32 | pub fn nth(&self, n: u32) -> Option<char> { | ||
33 | let mut chars = self.chars().peekable(); | ||
34 | chars.by_ref().skip(n as usize).next() | ||
35 | } | ||
36 | |||
37 | /// Checks whether the current character is `c`. | ||
38 | pub fn at(&self, c: char) -> bool { | ||
39 | self.current() == Some(c) | ||
40 | } | ||
41 | |||
42 | /// Checks whether the next characters match `s`. | ||
43 | pub fn at_str(&self, s: &str) -> bool { | ||
44 | let chars = self.chars(); | ||
45 | chars.as_str().starts_with(s) | ||
46 | } | ||
47 | |||
48 | /// Checks whether the current character satisfies the predicate `p`. | ||
49 | pub fn at_p<P: Fn(char) -> bool>(&self, p: P) -> bool { | ||
50 | self.current().map(p) == Some(true) | ||
51 | } | ||
52 | |||
53 | /// Checks whether the nth character satisfies the predicate `p`. | ||
54 | pub fn nth_is_p<P: Fn(char) -> bool>(&self, n: u32, p: P) -> bool { | ||
55 | self.nth(n).map(p) == Some(true) | ||
56 | } | ||
57 | |||
58 | /// Moves to the next character. | ||
59 | pub fn bump(&mut self) -> Option<char> { | ||
60 | let ch = self.chars().next()?; | ||
61 | self.len += TextUnit::of_char(ch); | ||
62 | Some(ch) | ||
63 | } | ||
64 | |||
65 | /// Moves to the next character as long as `pred` is satisfied. | ||
66 | pub fn bump_while<F: Fn(char) -> bool>(&mut self, pred: F) { | ||
67 | loop { | ||
68 | match self.current() { | ||
69 | Some(c) if pred(c) => { | ||
70 | self.bump(); | ||
71 | } | ||
72 | _ => return, | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | |||
77 | /// Returns the text up to the current point. | ||
78 | pub fn current_token_text(&self) -> &str { | ||
79 | let len: u32 = self.len.into(); | ||
80 | &self.text[..len as usize] | ||
81 | } | ||
82 | |||
83 | /// Returns an iterator over the remaining characters. | ||
84 | fn chars(&self) -> Chars { | ||
85 | let len: u32 = self.len.into(); | ||
86 | self.text[len as usize..].chars() | ||
87 | } | ||
88 | } | ||
89 | |||
90 | #[cfg(test)] | ||
91 | mod tests { | ||
92 | use super::*; | ||
93 | |||
94 | #[test] | ||
95 | fn test_current() { | ||
96 | let ptr = Ptr::new("test"); | ||
97 | assert_eq!(ptr.current(), Some('t')); | ||
98 | } | ||
99 | |||
100 | #[test] | ||
101 | fn test_nth() { | ||
102 | let ptr = Ptr::new("test"); | ||
103 | assert_eq!(ptr.nth(0), Some('t')); | ||
104 | assert_eq!(ptr.nth(1), Some('e')); | ||
105 | assert_eq!(ptr.nth(2), Some('s')); | ||
106 | assert_eq!(ptr.nth(3), Some('t')); | ||
107 | assert_eq!(ptr.nth(4), None); | ||
108 | } | ||
109 | |||
110 | #[test] | ||
111 | fn test_at() { | ||
112 | let ptr = Ptr::new("test"); | ||
113 | assert!(ptr.at('t')); | ||
114 | assert!(!ptr.at('a')); | ||
115 | } | ||
116 | |||
117 | #[test] | ||
118 | fn test_at_str() { | ||
119 | let ptr = Ptr::new("test"); | ||
120 | assert!(ptr.at_str("t")); | ||
121 | assert!(ptr.at_str("te")); | ||
122 | assert!(ptr.at_str("test")); | ||
123 | assert!(!ptr.at_str("tests")); | ||
124 | assert!(!ptr.at_str("rust")); | ||
125 | } | ||
126 | |||
127 | #[test] | ||
128 | fn test_at_p() { | ||
129 | let ptr = Ptr::new("test"); | ||
130 | assert!(ptr.at_p(|c| c == 't')); | ||
131 | assert!(!ptr.at_p(|c| c == 'e')); | ||
132 | } | ||
133 | |||
134 | #[test] | ||
135 | fn test_nth_is_p() { | ||
136 | let ptr = Ptr::new("test"); | ||
137 | assert!(ptr.nth_is_p(0,|c| c == 't')); | ||
138 | assert!(!ptr.nth_is_p(1,|c| c == 't')); | ||
139 | assert!(ptr.nth_is_p(3,|c| c == 't')); | ||
140 | assert!(!ptr.nth_is_p(150,|c| c == 't')); | ||
141 | } | ||
142 | |||
143 | #[test] | ||
144 | fn test_bump() { | ||
145 | let mut ptr = Ptr::new("test"); | ||
146 | assert_eq!(ptr.current(), Some('t')); | ||
147 | ptr.bump(); | ||
148 | assert_eq!(ptr.current(), Some('e')); | ||
149 | ptr.bump(); | ||
150 | assert_eq!(ptr.current(), Some('s')); | ||
151 | ptr.bump(); | ||
152 | assert_eq!(ptr.current(), Some('t')); | ||
153 | ptr.bump(); | ||
154 | assert_eq!(ptr.current(), None); | ||
155 | ptr.bump(); | ||
156 | assert_eq!(ptr.current(), None); | ||
157 | } | ||
158 | |||
159 | #[test] | ||
160 | fn test_bump_while() { | ||
161 | let mut ptr = Ptr::new("test"); | ||
162 | assert_eq!(ptr.current(), Some('t')); | ||
163 | ptr.bump_while(|c| c != 's'); | ||
164 | assert_eq!(ptr.current(), Some('s')); | ||
165 | } | ||
166 | } | ||
diff --git a/crates/ra_syntax/src/lexer/strings.rs b/crates/ra_syntax/src/lexer/strings.rs new file mode 100644 index 000000000..5ff483d14 --- /dev/null +++ b/crates/ra_syntax/src/lexer/strings.rs | |||
@@ -0,0 +1,123 @@ | |||
1 | use SyntaxKind::{self, *}; | ||
2 | |||
3 | use lexer::ptr::Ptr; | ||
4 | |||
5 | pub(crate) fn is_string_literal_start(c: char, c1: Option<char>, c2: Option<char>) -> bool { | ||
6 | match (c, c1, c2) { | ||
7 | ('r', Some('"'), _) | ||
8 | | ('r', Some('#'), _) | ||
9 | | ('b', Some('"'), _) | ||
10 | | ('b', Some('\''), _) | ||
11 | | ('b', Some('r'), Some('"')) | ||
12 | | ('b', Some('r'), Some('#')) => true, | ||
13 | _ => false, | ||
14 | } | ||
15 | } | ||
16 | |||
17 | pub(crate) fn scan_char(ptr: &mut Ptr) { | ||
18 | while let Some(c) = ptr.current() { | ||
19 | match c { | ||
20 | '\\' => { | ||
21 | ptr.bump(); | ||
22 | if ptr.at('\\') || ptr.at('\'') { | ||
23 | ptr.bump(); | ||
24 | } | ||
25 | } | ||
26 | '\'' => { | ||
27 | ptr.bump(); | ||
28 | return; | ||
29 | } | ||
30 | '\n' => return, | ||
31 | _ => { | ||
32 | ptr.bump(); | ||
33 | } | ||
34 | } | ||
35 | } | ||
36 | } | ||
37 | |||
38 | pub(crate) fn scan_byte_char_or_string(ptr: &mut Ptr) -> SyntaxKind { | ||
39 | // unwrapping and not-exhaustive match are ok | ||
40 | // because of string_literal_start | ||
41 | let c = ptr.bump().unwrap(); | ||
42 | match c { | ||
43 | '\'' => { | ||
44 | scan_byte(ptr); | ||
45 | BYTE | ||
46 | } | ||
47 | '"' => { | ||
48 | scan_byte_string(ptr); | ||
49 | BYTE_STRING | ||
50 | } | ||
51 | 'r' => { | ||
52 | scan_raw_byte_string(ptr); | ||
53 | RAW_BYTE_STRING | ||
54 | } | ||
55 | _ => unreachable!(), | ||
56 | } | ||
57 | } | ||
58 | |||
59 | pub(crate) fn scan_string(ptr: &mut Ptr) { | ||
60 | while let Some(c) = ptr.current() { | ||
61 | match c { | ||
62 | '\\' => { | ||
63 | ptr.bump(); | ||
64 | if ptr.at('\\') || ptr.at('"') { | ||
65 | ptr.bump(); | ||
66 | } | ||
67 | } | ||
68 | '"' => { | ||
69 | ptr.bump(); | ||
70 | return; | ||
71 | } | ||
72 | _ => { | ||
73 | ptr.bump(); | ||
74 | }, | ||
75 | } | ||
76 | } | ||
77 | } | ||
78 | |||
79 | pub(crate) fn scan_raw_string(ptr: &mut Ptr) { | ||
80 | let mut hashes = 0; | ||
81 | while ptr.at('#') { | ||
82 | hashes += 1; | ||
83 | ptr.bump(); | ||
84 | } | ||
85 | if !ptr.at('"') { | ||
86 | return; | ||
87 | } | ||
88 | ptr.bump(); | ||
89 | |||
90 | while let Some(c) = ptr.bump() { | ||
91 | if c == '"' { | ||
92 | let mut hashes_left = hashes; | ||
93 | while ptr.at('#') && hashes_left > 0{ | ||
94 | hashes_left -= 1; | ||
95 | ptr.bump(); | ||
96 | } | ||
97 | if hashes_left == 0 { | ||
98 | return; | ||
99 | } | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | fn scan_byte(ptr: &mut Ptr) { | ||
105 | scan_char(ptr) | ||
106 | } | ||
107 | |||
108 | fn scan_byte_string(ptr: &mut Ptr) { | ||
109 | scan_string(ptr) | ||
110 | } | ||
111 | |||
112 | fn scan_raw_byte_string(ptr: &mut Ptr) { | ||
113 | if !ptr.at('"') { | ||
114 | return; | ||
115 | } | ||
116 | ptr.bump(); | ||
117 | |||
118 | while let Some(c) = ptr.bump() { | ||
119 | if c == '"' { | ||
120 | return; | ||
121 | } | ||
122 | } | ||
123 | } | ||
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs new file mode 100644 index 000000000..eb271762e --- /dev/null +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -0,0 +1,105 @@ | |||
1 | //! An experimental implementation of [Rust RFC#2256 libsyntax2.0][rfc#2256]. | ||
2 | //! | ||
3 | //! The intent is to be an IDE-ready parser, i.e. one that offers | ||
4 | //! | ||
5 | //! - easy and fast incremental re-parsing, | ||
6 | //! - graceful handling of errors, and | ||
7 | //! - maintains all information in the source file. | ||
8 | //! | ||
9 | //! For more information, see [the RFC][rfc#2265], or [the working draft][RFC.md]. | ||
10 | //! | ||
11 | //! [rfc#2256]: <https://github.com/rust-lang/rfcs/pull/2256> | ||
12 | //! [RFC.md]: <https://github.com/matklad/libsyntax2/blob/master/docs/RFC.md> | ||
13 | |||
14 | #![forbid( | ||
15 | missing_debug_implementations, | ||
16 | unconditional_recursion, | ||
17 | future_incompatible | ||
18 | )] | ||
19 | #![deny(bad_style, missing_docs)] | ||
20 | #![allow(missing_docs)] | ||
21 | //#![warn(unreachable_pub)] // rust-lang/rust#47816 | ||
22 | |||
23 | extern crate itertools; | ||
24 | extern crate unicode_xid; | ||
25 | extern crate drop_bomb; | ||
26 | extern crate parking_lot; | ||
27 | extern crate smol_str; | ||
28 | extern crate text_unit; | ||
29 | |||
30 | #[cfg(test)] | ||
31 | #[macro_use] | ||
32 | extern crate test_utils; | ||
33 | |||
34 | pub mod algo; | ||
35 | pub mod ast; | ||
36 | mod lexer; | ||
37 | #[macro_use] | ||
38 | mod token_set; | ||
39 | mod parser_api; | ||
40 | mod grammar; | ||
41 | mod parser_impl; | ||
42 | mod reparsing; | ||
43 | |||
44 | mod syntax_kinds; | ||
45 | mod yellow; | ||
46 | /// Utilities for simple uses of the parser. | ||
47 | pub mod utils; | ||
48 | pub mod text_utils; | ||
49 | |||
50 | pub use { | ||
51 | text_unit::{TextRange, TextUnit}, | ||
52 | smol_str::SmolStr, | ||
53 | ast::AstNode, | ||
54 | lexer::{tokenize, Token}, | ||
55 | syntax_kinds::SyntaxKind, | ||
56 | yellow::{SyntaxNode, SyntaxNodeRef, OwnedRoot, RefRoot, TreeRoot, SyntaxError}, | ||
57 | reparsing::AtomEdit, | ||
58 | }; | ||
59 | |||
60 | use { | ||
61 | yellow::{GreenNode, SyntaxRoot}, | ||
62 | }; | ||
63 | |||
64 | #[derive(Clone, Debug, Hash)] | ||
65 | pub struct File { | ||
66 | root: SyntaxNode | ||
67 | } | ||
68 | |||
69 | impl File { | ||
70 | fn new(green: GreenNode, errors: Vec<SyntaxError>) -> File { | ||
71 | let root = SyntaxRoot::new(green, errors); | ||
72 | let root = SyntaxNode::new_owned(root); | ||
73 | if cfg!(debug_assertions) { | ||
74 | utils::validate_block_structure(root.borrowed()); | ||
75 | } | ||
76 | File { root } | ||
77 | } | ||
78 | pub fn parse(text: &str) -> File { | ||
79 | let tokens = tokenize(&text); | ||
80 | let (green, errors) = parser_impl::parse_with::<yellow::GreenBuilder>( | ||
81 | text, &tokens, grammar::root, | ||
82 | ); | ||
83 | File::new(green, errors) | ||
84 | } | ||
85 | pub fn reparse(&self, edit: &AtomEdit) -> File { | ||
86 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | ||
87 | } | ||
88 | pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> { | ||
89 | reparsing::incremental_reparse(self.syntax(), edit, self.errors()) | ||
90 | .map(|(green_node, errors)| File::new(green_node, errors)) | ||
91 | } | ||
92 | fn full_reparse(&self, edit: &AtomEdit) -> File { | ||
93 | let text = text_utils::replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert); | ||
94 | File::parse(&text) | ||
95 | } | ||
96 | pub fn ast(&self) -> ast::Root { | ||
97 | ast::Root::cast(self.syntax()).unwrap() | ||
98 | } | ||
99 | pub fn syntax(&self) -> SyntaxNodeRef { | ||
100 | self.root.borrowed() | ||
101 | } | ||
102 | pub fn errors(&self) -> Vec<SyntaxError> { | ||
103 | self.syntax().root.syntax_root().errors.clone() | ||
104 | } | ||
105 | } | ||
diff --git a/crates/ra_syntax/src/parser_api.rs b/crates/ra_syntax/src/parser_api.rs new file mode 100644 index 000000000..772d753af --- /dev/null +++ b/crates/ra_syntax/src/parser_api.rs | |||
@@ -0,0 +1,178 @@ | |||
1 | use { | ||
2 | token_set::TokenSet, | ||
3 | parser_impl::ParserImpl, | ||
4 | SyntaxKind::{self, ERROR}, | ||
5 | drop_bomb::DropBomb, | ||
6 | }; | ||
7 | |||
8 | /// `Parser` struct provides the low-level API for | ||
9 | /// navigating through the stream of tokens and | ||
10 | /// constructing the parse tree. The actual parsing | ||
11 | /// happens in the `grammar` module. | ||
12 | /// | ||
13 | /// However, the result of this `Parser` is not a real | ||
14 | /// tree, but rather a flat stream of events of the form | ||
15 | /// "start expression, consume number literal, | ||
16 | /// finish expression". See `Event` docs for more. | ||
17 | pub(crate) struct Parser<'t>(pub(super) ParserImpl<'t>); | ||
18 | |||
19 | impl<'t> Parser<'t> { | ||
20 | /// Returns the kind of the current token. | ||
21 | /// If parser has already reached the end of input, | ||
22 | /// the special `EOF` kind is returned. | ||
23 | pub(crate) fn current(&self) -> SyntaxKind { | ||
24 | self.nth(0) | ||
25 | } | ||
26 | |||
27 | /// Lookahead operation: returns the kind of the next nth | ||
28 | /// token. | ||
29 | pub(crate) fn nth(&self, n: u32) -> SyntaxKind { | ||
30 | self.0.nth(n) | ||
31 | } | ||
32 | |||
33 | /// Checks if the current token is `kind`. | ||
34 | pub(crate) fn at(&self, kind: SyntaxKind) -> bool { | ||
35 | self.current() == kind | ||
36 | } | ||
37 | |||
38 | /// Checks if the current token is `kind`. | ||
39 | pub(crate) fn at_ts(&self, kinds: TokenSet) -> bool { | ||
40 | kinds.contains(self.current()) | ||
41 | } | ||
42 | |||
43 | pub(crate) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> { | ||
44 | self.0.next2() | ||
45 | } | ||
46 | |||
47 | pub(crate) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { | ||
48 | self.0.next3() | ||
49 | } | ||
50 | |||
51 | /// Checks if the current token is contextual keyword with text `t`. | ||
52 | pub(crate) fn at_contextual_kw(&self, t: &str) -> bool { | ||
53 | self.0.at_kw(t) | ||
54 | } | ||
55 | |||
56 | /// Starts a new node in the syntax tree. All nodes and tokens | ||
57 | /// consumed between the `start` and the corresponding `Marker::complete` | ||
58 | /// belong to the same node. | ||
59 | pub(crate) fn start(&mut self) -> Marker { | ||
60 | Marker::new(self.0.start()) | ||
61 | } | ||
62 | |||
63 | /// Advances the parser by one token. | ||
64 | pub(crate) fn bump(&mut self) { | ||
65 | self.0.bump(); | ||
66 | } | ||
67 | |||
68 | /// Advances the parser by one token, remapping its kind. | ||
69 | /// This is useful to create contextual keywords from | ||
70 | /// identifiers. For example, the lexer creates an `union` | ||
71 | /// *identifier* token, but the parser remaps it to the | ||
72 | /// `union` keyword, and keyword is what ends up in the | ||
73 | /// final tree. | ||
74 | pub(crate) fn bump_remap(&mut self, kind: SyntaxKind) { | ||
75 | self.0.bump_remap(kind); | ||
76 | } | ||
77 | |||
78 | /// Advances the parser by `n` tokens, remapping its kind. | ||
79 | /// This is useful to create compound tokens from parts. For | ||
80 | /// example, an `<<` token is two consecutive remapped `<` tokens | ||
81 | pub(crate) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) { | ||
82 | self.0.bump_compound(kind, n); | ||
83 | } | ||
84 | |||
85 | /// Emit error with the `message` | ||
86 | /// TODO: this should be much more fancy and support | ||
87 | /// structured errors with spans and notes, like rustc | ||
88 | /// does. | ||
89 | pub(crate) fn error<T: Into<String>>(&mut self, message: T) { | ||
90 | self.0.error(message.into()) | ||
91 | } | ||
92 | |||
93 | /// Consume the next token if it is `kind`. | ||
94 | pub(crate) fn eat(&mut self, kind: SyntaxKind) -> bool { | ||
95 | if !self.at(kind) { | ||
96 | return false; | ||
97 | } | ||
98 | self.bump(); | ||
99 | true | ||
100 | } | ||
101 | |||
102 | /// Consume the next token if it is `kind` or emit an error | ||
103 | /// otherwise. | ||
104 | pub(crate) fn expect(&mut self, kind: SyntaxKind) -> bool { | ||
105 | if self.eat(kind) { | ||
106 | return true; | ||
107 | } | ||
108 | self.error(format!("expected {:?}", kind)); | ||
109 | false | ||
110 | } | ||
111 | |||
112 | /// Create an error node and consume the next token. | ||
113 | pub(crate) fn err_and_bump(&mut self, message: &str) { | ||
114 | self.err_recover(message, TokenSet::EMPTY); | ||
115 | } | ||
116 | |||
117 | /// Create an error node and consume the next token. | ||
118 | pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) { | ||
119 | if self.at(SyntaxKind::L_CURLY) | ||
120 | || self.at(SyntaxKind::R_CURLY) | ||
121 | || self.at_ts(recovery) { | ||
122 | self.error(message); | ||
123 | } else { | ||
124 | let m = self.start(); | ||
125 | self.error(message); | ||
126 | self.bump(); | ||
127 | m.complete(self, ERROR); | ||
128 | }; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | /// See `Parser::start`. | ||
133 | pub(crate) struct Marker { | ||
134 | pos: u32, | ||
135 | bomb: DropBomb, | ||
136 | } | ||
137 | |||
138 | impl Marker { | ||
139 | fn new(pos: u32) -> Marker { | ||
140 | Marker { | ||
141 | pos, | ||
142 | bomb: DropBomb::new("Marker must be either completed or abandoned"), | ||
143 | } | ||
144 | } | ||
145 | |||
146 | /// Finishes the syntax tree node and assigns `kind` to it. | ||
147 | pub(crate) fn complete(mut self, p: &mut Parser, kind: SyntaxKind) -> CompletedMarker { | ||
148 | self.bomb.defuse(); | ||
149 | p.0.complete(self.pos, kind); | ||
150 | CompletedMarker(self.pos, kind) | ||
151 | } | ||
152 | |||
153 | /// Abandons the syntax tree node. All its children | ||
154 | /// are attached to its parent instead. | ||
155 | pub(crate) fn abandon(mut self, p: &mut Parser) { | ||
156 | self.bomb.defuse(); | ||
157 | p.0.abandon(self.pos); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | pub(crate) struct CompletedMarker(u32, SyntaxKind); | ||
162 | |||
163 | impl CompletedMarker { | ||
164 | /// This one is tricky :-) | ||
165 | /// This method allows to create a new node which starts | ||
166 | /// *before* the current one. That is, parser could start | ||
167 | /// node `A`, then complete it, and then after parsing the | ||
168 | /// whole `A`, decide that it should have started some node | ||
169 | /// `B` before starting `A`. `precede` allows to do exactly | ||
170 | /// that. See also docs about `forward_parent` in `Event::Start`. | ||
171 | pub(crate) fn precede(self, p: &mut Parser) -> Marker { | ||
172 | Marker::new(p.0.precede(self.0)) | ||
173 | } | ||
174 | |||
175 | pub(crate) fn kind(&self) -> SyntaxKind { | ||
176 | self.1 | ||
177 | } | ||
178 | } | ||
diff --git a/crates/ra_syntax/src/parser_impl/event.rs b/crates/ra_syntax/src/parser_impl/event.rs new file mode 100644 index 000000000..9fd56b996 --- /dev/null +++ b/crates/ra_syntax/src/parser_impl/event.rs | |||
@@ -0,0 +1,154 @@ | |||
1 | //! This module provides a way to construct a `File`. | ||
2 | //! It is intended to be completely decoupled from the | ||
3 | //! parser, so as to allow to evolve the tree representation | ||
4 | //! and the parser algorithm independently. | ||
5 | //! | ||
6 | //! The `Sink` trait is the bridge between the parser and the | ||
7 | //! tree builder: the parser produces a stream of events like | ||
8 | //! `start node`, `finish node`, and `FileBuilder` converts | ||
9 | //! this stream to a real tree. | ||
10 | use std::mem; | ||
11 | use { | ||
12 | lexer::Token, | ||
13 | parser_impl::Sink, | ||
14 | SyntaxKind::{self, TOMBSTONE}, | ||
15 | }; | ||
16 | |||
17 | |||
18 | /// `Parser` produces a flat list of `Event`s. | ||
19 | /// They are converted to a tree-structure in | ||
20 | /// a separate pass, via `TreeBuilder`. | ||
21 | #[derive(Debug)] | ||
22 | pub(crate) enum Event { | ||
23 | /// This event signifies the start of the node. | ||
24 | /// It should be either abandoned (in which case the | ||
25 | /// `kind` is `TOMBSTONE`, and the event is ignored), | ||
26 | /// or completed via a `Finish` event. | ||
27 | /// | ||
28 | /// All tokens between a `Start` and a `Finish` would | ||
29 | /// become the children of the respective node. | ||
30 | /// | ||
31 | /// For left-recursive syntactic constructs, the parser produces | ||
32 | /// a child node before it sees a parent. `forward_parent` | ||
33 | /// exists to allow to tweak parent-child relationships. | ||
34 | /// | ||
35 | /// Consider this path | ||
36 | /// | ||
37 | /// foo::bar | ||
38 | /// | ||
39 | /// The events for it would look like this: | ||
40 | /// | ||
41 | /// | ||
42 | /// START(PATH) IDENT('foo') FINISH START(PATH) COLONCOLON IDENT('bar') FINISH | ||
43 | /// | /\ | ||
44 | /// | | | ||
45 | /// +------forward-parent------+ | ||
46 | /// | ||
47 | /// And the tree would look like this | ||
48 | /// | ||
49 | /// +--PATH---------+ | ||
50 | /// | | | | ||
51 | /// | | | | ||
52 | /// | '::' 'bar' | ||
53 | /// | | ||
54 | /// PATH | ||
55 | /// | | ||
56 | /// 'foo' | ||
57 | /// | ||
58 | /// See also `CompletedMarker::precede`. | ||
59 | Start { | ||
60 | kind: SyntaxKind, | ||
61 | forward_parent: Option<u32>, | ||
62 | }, | ||
63 | |||
64 | /// Complete the previous `Start` event | ||
65 | Finish, | ||
66 | |||
67 | /// Produce a single leaf-element. | ||
68 | /// `n_raw_tokens` is used to glue complex contextual tokens. | ||
69 | /// For example, lexer tokenizes `>>` as `>`, `>`, and | ||
70 | /// `n_raw_tokens = 2` is used to produced a single `>>`. | ||
71 | Token { | ||
72 | kind: SyntaxKind, | ||
73 | n_raw_tokens: u8, | ||
74 | }, | ||
75 | |||
76 | Error { | ||
77 | msg: String, | ||
78 | }, | ||
79 | } | ||
80 | |||
81 | |||
82 | pub(super) fn process<'a, S: Sink<'a>>(builder: &mut S, tokens: &[Token], mut events: Vec<Event>) { | ||
83 | fn tombstone() -> Event { | ||
84 | Event::Start { kind: TOMBSTONE, forward_parent: None } | ||
85 | } | ||
86 | let eat_ws = |idx: &mut usize, builder: &mut S| { | ||
87 | while let Some(token) = tokens.get(*idx) { | ||
88 | if !token.kind.is_trivia() { | ||
89 | break; | ||
90 | } | ||
91 | builder.leaf(token.kind, token.len); | ||
92 | *idx += 1 | ||
93 | } | ||
94 | }; | ||
95 | |||
96 | let events: &mut [Event] = &mut events; | ||
97 | let mut depth = 0; | ||
98 | let mut forward_parents = Vec::new(); | ||
99 | let mut next_tok_idx = 0; | ||
100 | for i in 0..events.len() { | ||
101 | match mem::replace(&mut events[i], tombstone()) { | ||
102 | Event::Start { | ||
103 | kind: TOMBSTONE, .. | ||
104 | } => (), | ||
105 | |||
106 | Event::Start { kind, forward_parent } => { | ||
107 | forward_parents.push(kind); | ||
108 | let mut idx = i; | ||
109 | let mut fp = forward_parent; | ||
110 | while let Some(fwd) = fp { | ||
111 | idx += fwd as usize; | ||
112 | fp = match mem::replace(&mut events[idx], tombstone()) { | ||
113 | Event::Start { | ||
114 | kind, | ||
115 | forward_parent, | ||
116 | } => { | ||
117 | forward_parents.push(kind); | ||
118 | forward_parent | ||
119 | }, | ||
120 | _ => unreachable!(), | ||
121 | }; | ||
122 | } | ||
123 | for kind in forward_parents.drain(..).rev() { | ||
124 | if depth > 0 { | ||
125 | eat_ws(&mut next_tok_idx, builder); | ||
126 | } | ||
127 | depth += 1; | ||
128 | builder.start_internal(kind); | ||
129 | } | ||
130 | } | ||
131 | Event::Finish => { | ||
132 | depth -= 1; | ||
133 | if depth == 0 { | ||
134 | eat_ws(&mut next_tok_idx, builder); | ||
135 | } | ||
136 | |||
137 | builder.finish_internal(); | ||
138 | } | ||
139 | Event::Token { | ||
140 | kind, | ||
141 | mut n_raw_tokens, | ||
142 | } => { | ||
143 | eat_ws(&mut next_tok_idx, builder); | ||
144 | let mut len = 0.into(); | ||
145 | for _ in 0..n_raw_tokens { | ||
146 | len += tokens[next_tok_idx].len; | ||
147 | next_tok_idx += 1; | ||
148 | } | ||
149 | builder.leaf(kind, len); | ||
150 | } | ||
151 | Event::Error { msg } => builder.error(msg), | ||
152 | } | ||
153 | } | ||
154 | } | ||
diff --git a/crates/ra_syntax/src/parser_impl/input.rs b/crates/ra_syntax/src/parser_impl/input.rs new file mode 100644 index 000000000..c0fe4d488 --- /dev/null +++ b/crates/ra_syntax/src/parser_impl/input.rs | |||
@@ -0,0 +1,86 @@ | |||
1 | use {lexer::Token, SyntaxKind, SyntaxKind::EOF, TextRange, TextUnit}; | ||
2 | |||
3 | use std::ops::{Add, AddAssign}; | ||
4 | |||
5 | pub(crate) struct ParserInput<'t> { | ||
6 | text: &'t str, | ||
7 | start_offsets: Vec<TextUnit>, | ||
8 | tokens: Vec<Token>, // non-whitespace tokens | ||
9 | } | ||
10 | |||
11 | impl<'t> ParserInput<'t> { | ||
12 | pub fn new(text: &'t str, raw_tokens: &'t [Token]) -> ParserInput<'t> { | ||
13 | let mut tokens = Vec::new(); | ||
14 | let mut start_offsets = Vec::new(); | ||
15 | let mut len = 0.into(); | ||
16 | for &token in raw_tokens.iter() { | ||
17 | if !token.kind.is_trivia() { | ||
18 | tokens.push(token); | ||
19 | start_offsets.push(len); | ||
20 | } | ||
21 | len += token.len; | ||
22 | } | ||
23 | |||
24 | ParserInput { | ||
25 | text, | ||
26 | start_offsets, | ||
27 | tokens, | ||
28 | } | ||
29 | } | ||
30 | |||
31 | pub fn kind(&self, pos: InputPosition) -> SyntaxKind { | ||
32 | let idx = pos.0 as usize; | ||
33 | if !(idx < self.tokens.len()) { | ||
34 | return EOF; | ||
35 | } | ||
36 | self.tokens[idx].kind | ||
37 | } | ||
38 | |||
39 | pub fn len(&self, pos: InputPosition) -> TextUnit { | ||
40 | let idx = pos.0 as usize; | ||
41 | if !(idx < self.tokens.len()) { | ||
42 | return 0.into(); | ||
43 | } | ||
44 | self.tokens[idx].len | ||
45 | } | ||
46 | |||
47 | pub fn start(&self, pos: InputPosition) -> TextUnit { | ||
48 | let idx = pos.0 as usize; | ||
49 | if !(idx < self.tokens.len()) { | ||
50 | return 0.into(); | ||
51 | } | ||
52 | self.start_offsets[idx] | ||
53 | } | ||
54 | |||
55 | pub fn text(&self, pos: InputPosition) -> &'t str { | ||
56 | let idx = pos.0 as usize; | ||
57 | if !(idx < self.tokens.len()) { | ||
58 | return ""; | ||
59 | } | ||
60 | let range = TextRange::offset_len(self.start_offsets[idx], self.tokens[idx].len); | ||
61 | &self.text[range] | ||
62 | } | ||
63 | } | ||
64 | |||
65 | #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)] | ||
66 | pub(crate) struct InputPosition(u32); | ||
67 | |||
68 | impl InputPosition { | ||
69 | pub fn new() -> Self { | ||
70 | InputPosition(0) | ||
71 | } | ||
72 | } | ||
73 | |||
74 | impl Add<u32> for InputPosition { | ||
75 | type Output = InputPosition; | ||
76 | |||
77 | fn add(self, rhs: u32) -> InputPosition { | ||
78 | InputPosition(self.0 + rhs) | ||
79 | } | ||
80 | } | ||
81 | |||
82 | impl AddAssign<u32> for InputPosition { | ||
83 | fn add_assign(&mut self, rhs: u32) { | ||
84 | self.0 += rhs | ||
85 | } | ||
86 | } | ||
diff --git a/crates/ra_syntax/src/parser_impl/mod.rs b/crates/ra_syntax/src/parser_impl/mod.rs new file mode 100644 index 000000000..b343b404f --- /dev/null +++ b/crates/ra_syntax/src/parser_impl/mod.rs | |||
@@ -0,0 +1,194 @@ | |||
1 | mod event; | ||
2 | mod input; | ||
3 | |||
4 | use std::cell::Cell; | ||
5 | |||
6 | use { | ||
7 | lexer::Token, | ||
8 | parser_api::Parser, | ||
9 | parser_impl::{ | ||
10 | event::{process, Event}, | ||
11 | input::{InputPosition, ParserInput}, | ||
12 | }, | ||
13 | TextUnit, | ||
14 | }; | ||
15 | |||
16 | use SyntaxKind::{self, EOF, TOMBSTONE}; | ||
17 | |||
18 | pub(crate) trait Sink<'a> { | ||
19 | type Tree; | ||
20 | |||
21 | fn new(text: &'a str) -> Self; | ||
22 | |||
23 | fn leaf(&mut self, kind: SyntaxKind, len: TextUnit); | ||
24 | fn start_internal(&mut self, kind: SyntaxKind); | ||
25 | fn finish_internal(&mut self); | ||
26 | fn error(&mut self, err: String); | ||
27 | fn finish(self) -> Self::Tree; | ||
28 | } | ||
29 | |||
30 | /// Parse a sequence of tokens into the representative node tree | ||
31 | pub(crate) fn parse_with<'a, S: Sink<'a>>( | ||
32 | text: &'a str, | ||
33 | tokens: &[Token], | ||
34 | parser: fn(&mut Parser), | ||
35 | ) -> S::Tree { | ||
36 | let events = { | ||
37 | let input = input::ParserInput::new(text, tokens); | ||
38 | let parser_impl = ParserImpl::new(&input); | ||
39 | let mut parser_api = Parser(parser_impl); | ||
40 | parser(&mut parser_api); | ||
41 | parser_api.0.into_events() | ||
42 | }; | ||
43 | let mut sink = S::new(text); | ||
44 | process(&mut sink, tokens, events); | ||
45 | sink.finish() | ||
46 | } | ||
47 | |||
48 | /// Implementation details of `Parser`, extracted | ||
49 | /// to a separate struct in order not to pollute | ||
50 | /// the public API of the `Parser`. | ||
51 | pub(crate) struct ParserImpl<'t> { | ||
52 | inp: &'t ParserInput<'t>, | ||
53 | |||
54 | pos: InputPosition, | ||
55 | events: Vec<Event>, | ||
56 | steps: Cell<u32>, | ||
57 | } | ||
58 | |||
59 | impl<'t> ParserImpl<'t> { | ||
60 | pub(crate) fn new(inp: &'t ParserInput<'t>) -> ParserImpl<'t> { | ||
61 | ParserImpl { | ||
62 | inp, | ||
63 | |||
64 | pos: InputPosition::new(), | ||
65 | events: Vec::new(), | ||
66 | steps: Cell::new(0), | ||
67 | } | ||
68 | } | ||
69 | |||
70 | pub(crate) fn into_events(self) -> Vec<Event> { | ||
71 | assert_eq!(self.nth(0), EOF); | ||
72 | self.events | ||
73 | } | ||
74 | |||
75 | pub(super) fn next2(&self) -> Option<(SyntaxKind, SyntaxKind)> { | ||
76 | let c1 = self.inp.kind(self.pos); | ||
77 | let c2 = self.inp.kind(self.pos + 1); | ||
78 | if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) { | ||
79 | Some((c1, c2)) | ||
80 | } else { | ||
81 | None | ||
82 | } | ||
83 | } | ||
84 | |||
85 | pub(super) fn next3(&self) -> Option<(SyntaxKind, SyntaxKind, SyntaxKind)> { | ||
86 | let c1 = self.inp.kind(self.pos); | ||
87 | let c2 = self.inp.kind(self.pos + 1); | ||
88 | let c3 = self.inp.kind(self.pos + 2); | ||
89 | if self.inp.start(self.pos + 1) == self.inp.start(self.pos) + self.inp.len(self.pos) | ||
90 | && self.inp.start(self.pos + 2) == self.inp.start(self.pos + 1) + self.inp.len(self.pos + 1){ | ||
91 | Some((c1, c2, c3)) | ||
92 | } else { | ||
93 | None | ||
94 | } | ||
95 | } | ||
96 | |||
97 | pub(super) fn nth(&self, n: u32) -> SyntaxKind { | ||
98 | let steps = self.steps.get(); | ||
99 | if steps > 10_000_000 { | ||
100 | panic!("the parser seems stuck"); | ||
101 | } | ||
102 | self.steps.set(steps + 1); | ||
103 | |||
104 | self.inp.kind(self.pos + n) | ||
105 | } | ||
106 | |||
107 | pub(super) fn at_kw(&self, t: &str) -> bool { | ||
108 | self.inp.text(self.pos) == t | ||
109 | } | ||
110 | |||
111 | pub(super) fn start(&mut self) -> u32 { | ||
112 | let pos = self.events.len() as u32; | ||
113 | self.event(Event::Start { | ||
114 | kind: TOMBSTONE, | ||
115 | forward_parent: None, | ||
116 | }); | ||
117 | pos | ||
118 | } | ||
119 | |||
120 | pub(super) fn bump(&mut self) { | ||
121 | let kind = self.nth(0); | ||
122 | if kind == EOF { | ||
123 | return; | ||
124 | } | ||
125 | self.do_bump(kind, 1); | ||
126 | } | ||
127 | |||
128 | pub(super) fn bump_remap(&mut self, kind: SyntaxKind) { | ||
129 | if self.nth(0) == EOF { | ||
130 | // TODO: panic!? | ||
131 | return; | ||
132 | } | ||
133 | self.do_bump(kind, 1); | ||
134 | } | ||
135 | |||
136 | pub(super) fn bump_compound(&mut self, kind: SyntaxKind, n: u8) { | ||
137 | self.do_bump(kind, n); | ||
138 | } | ||
139 | |||
140 | fn do_bump(&mut self, kind: SyntaxKind, n_raw_tokens: u8) { | ||
141 | self.pos += u32::from(n_raw_tokens); | ||
142 | self.event(Event::Token { | ||
143 | kind, | ||
144 | n_raw_tokens, | ||
145 | }); | ||
146 | } | ||
147 | |||
148 | pub(super) fn error(&mut self, msg: String) { | ||
149 | self.event(Event::Error { msg }) | ||
150 | } | ||
151 | |||
152 | pub(super) fn complete(&mut self, pos: u32, kind: SyntaxKind) { | ||
153 | match self.events[pos as usize] { | ||
154 | Event::Start { | ||
155 | kind: ref mut slot, .. | ||
156 | } => { | ||
157 | *slot = kind; | ||
158 | } | ||
159 | _ => unreachable!(), | ||
160 | } | ||
161 | self.event(Event::Finish); | ||
162 | } | ||
163 | |||
164 | pub(super) fn abandon(&mut self, pos: u32) { | ||
165 | let idx = pos as usize; | ||
166 | if idx == self.events.len() - 1 { | ||
167 | match self.events.pop() { | ||
168 | Some(Event::Start { | ||
169 | kind: TOMBSTONE, | ||
170 | forward_parent: None, | ||
171 | }) => (), | ||
172 | _ => unreachable!(), | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | |||
177 | pub(super) fn precede(&mut self, pos: u32) -> u32 { | ||
178 | let new_pos = self.start(); | ||
179 | match self.events[pos as usize] { | ||
180 | Event::Start { | ||
181 | ref mut forward_parent, | ||
182 | .. | ||
183 | } => { | ||
184 | *forward_parent = Some(new_pos - pos); | ||
185 | } | ||
186 | _ => unreachable!(), | ||
187 | } | ||
188 | new_pos | ||
189 | } | ||
190 | |||
191 | fn event(&mut self, event: Event) { | ||
192 | self.events.push(event) | ||
193 | } | ||
194 | } | ||
diff --git a/crates/ra_syntax/src/reparsing.rs b/crates/ra_syntax/src/reparsing.rs new file mode 100644 index 000000000..da44913c5 --- /dev/null +++ b/crates/ra_syntax/src/reparsing.rs | |||
@@ -0,0 +1,343 @@ | |||
1 | use algo; | ||
2 | use grammar; | ||
3 | use lexer::{tokenize, Token}; | ||
4 | use text_unit::{TextRange, TextUnit}; | ||
5 | use yellow::{self, SyntaxNodeRef, GreenNode, SyntaxError}; | ||
6 | use parser_impl; | ||
7 | use parser_api::Parser; | ||
8 | use { | ||
9 | SyntaxKind::*, | ||
10 | }; | ||
11 | use text_utils::replace_range; | ||
12 | |||
13 | #[derive(Debug, Clone)] | ||
14 | pub struct AtomEdit { | ||
15 | pub delete: TextRange, | ||
16 | pub insert: String, | ||
17 | } | ||
18 | |||
19 | impl AtomEdit { | ||
20 | pub fn replace(range: TextRange, replace_with: String) -> AtomEdit { | ||
21 | AtomEdit { delete: range, insert: replace_with } | ||
22 | } | ||
23 | |||
24 | pub fn delete(range: TextRange) -> AtomEdit { | ||
25 | AtomEdit::replace(range, String::new()) | ||
26 | } | ||
27 | |||
28 | pub fn insert(offset: TextUnit, text: String) -> AtomEdit { | ||
29 | AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text) | ||
30 | } | ||
31 | } | ||
32 | |||
33 | pub(crate) fn incremental_reparse( | ||
34 | node: SyntaxNodeRef, | ||
35 | edit: &AtomEdit, | ||
36 | errors: Vec<SyntaxError>, | ||
37 | ) -> Option<(GreenNode, Vec<SyntaxError>)> { | ||
38 | let (node, green, new_errors) = | ||
39 | reparse_leaf(node, &edit).or_else(|| reparse_block(node, &edit))?; | ||
40 | let green_root = node.replace_with(green); | ||
41 | let errors = merge_errors(errors, new_errors, node, edit); | ||
42 | Some((green_root, errors)) | ||
43 | } | ||
44 | |||
45 | fn reparse_leaf<'node>( | ||
46 | node: SyntaxNodeRef<'node>, | ||
47 | edit: &AtomEdit, | ||
48 | ) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> { | ||
49 | let node = algo::find_covering_node(node, edit.delete); | ||
50 | match node.kind() { | ||
51 | | WHITESPACE | ||
52 | | COMMENT | ||
53 | | DOC_COMMENT | ||
54 | | IDENT | ||
55 | | STRING | ||
56 | | RAW_STRING => { | ||
57 | let text = get_text_after_edit(node, &edit); | ||
58 | let tokens = tokenize(&text); | ||
59 | let token = match tokens[..] { | ||
60 | [token] if token.kind == node.kind() => token, | ||
61 | _ => return None, | ||
62 | }; | ||
63 | |||
64 | if token.kind == IDENT && is_contextual_kw(&text) { | ||
65 | return None; | ||
66 | } | ||
67 | |||
68 | let green = GreenNode::new_leaf(node.kind(), &text); | ||
69 | let new_errors = vec![]; | ||
70 | Some((node, green, new_errors)) | ||
71 | } | ||
72 | _ => None, | ||
73 | } | ||
74 | } | ||
75 | |||
76 | fn reparse_block<'node>( | ||
77 | node: SyntaxNodeRef<'node>, | ||
78 | edit: &AtomEdit, | ||
79 | ) -> Option<(SyntaxNodeRef<'node>, GreenNode, Vec<SyntaxError>)> { | ||
80 | let (node, reparser) = find_reparsable_node(node, edit.delete)?; | ||
81 | let text = get_text_after_edit(node, &edit); | ||
82 | let tokens = tokenize(&text); | ||
83 | if !is_balanced(&tokens) { | ||
84 | return None; | ||
85 | } | ||
86 | let (green, new_errors) = | ||
87 | parser_impl::parse_with::<yellow::GreenBuilder>( | ||
88 | &text, &tokens, reparser, | ||
89 | ); | ||
90 | Some((node, green, new_errors)) | ||
91 | } | ||
92 | |||
93 | fn get_text_after_edit(node: SyntaxNodeRef, edit: &AtomEdit) -> String { | ||
94 | replace_range( | ||
95 | node.text().to_string(), | ||
96 | edit.delete - node.range().start(), | ||
97 | &edit.insert, | ||
98 | ) | ||
99 | } | ||
100 | |||
101 | fn is_contextual_kw(text: &str) -> bool { | ||
102 | match text { | ||
103 | | "auto" | ||
104 | | "default" | ||
105 | | "union" => true, | ||
106 | _ => false, | ||
107 | } | ||
108 | } | ||
109 | |||
110 | fn find_reparsable_node<'node>( | ||
111 | node: SyntaxNodeRef<'node>, | ||
112 | range: TextRange, | ||
113 | ) -> Option<(SyntaxNodeRef<'node>, fn(&mut Parser))> { | ||
114 | let node = algo::find_covering_node(node, range); | ||
115 | return algo::ancestors(node) | ||
116 | .filter_map(|node| reparser(node).map(|r| (node, r))) | ||
117 | .next(); | ||
118 | |||
119 | fn reparser(node: SyntaxNodeRef) -> Option<fn(&mut Parser)> { | ||
120 | let res = match node.kind() { | ||
121 | BLOCK => grammar::block, | ||
122 | NAMED_FIELD_DEF_LIST => grammar::named_field_def_list, | ||
123 | NAMED_FIELD_LIST => grammar::named_field_list, | ||
124 | ENUM_VARIANT_LIST => grammar::enum_variant_list, | ||
125 | MATCH_ARM_LIST => grammar::match_arm_list, | ||
126 | USE_TREE_LIST => grammar::use_tree_list, | ||
127 | EXTERN_ITEM_LIST => grammar::extern_item_list, | ||
128 | TOKEN_TREE if node.first_child().unwrap().kind() == L_CURLY => grammar::token_tree, | ||
129 | ITEM_LIST => { | ||
130 | let parent = node.parent().unwrap(); | ||
131 | match parent.kind() { | ||
132 | IMPL_ITEM => grammar::impl_item_list, | ||
133 | TRAIT_DEF => grammar::trait_item_list, | ||
134 | MODULE => grammar::mod_item_list, | ||
135 | _ => return None, | ||
136 | } | ||
137 | } | ||
138 | _ => return None, | ||
139 | }; | ||
140 | Some(res) | ||
141 | } | ||
142 | } | ||
143 | |||
144 | fn is_balanced(tokens: &[Token]) -> bool { | ||
145 | if tokens.len() == 0 | ||
146 | || tokens.first().unwrap().kind != L_CURLY | ||
147 | || tokens.last().unwrap().kind != R_CURLY { | ||
148 | return false; | ||
149 | } | ||
150 | let mut balance = 0usize; | ||
151 | for t in tokens.iter() { | ||
152 | match t.kind { | ||
153 | L_CURLY => balance += 1, | ||
154 | R_CURLY => balance = match balance.checked_sub(1) { | ||
155 | Some(b) => b, | ||
156 | None => return false, | ||
157 | }, | ||
158 | _ => (), | ||
159 | } | ||
160 | } | ||
161 | balance == 0 | ||
162 | } | ||
163 | |||
164 | fn merge_errors( | ||
165 | old_errors: Vec<SyntaxError>, | ||
166 | new_errors: Vec<SyntaxError>, | ||
167 | old_node: SyntaxNodeRef, | ||
168 | edit: &AtomEdit, | ||
169 | ) -> Vec<SyntaxError> { | ||
170 | let mut res = Vec::new(); | ||
171 | for e in old_errors { | ||
172 | if e.offset <= old_node.range().start() { | ||
173 | res.push(e) | ||
174 | } else if e.offset >= old_node.range().end() { | ||
175 | res.push(SyntaxError { | ||
176 | msg: e.msg, | ||
177 | offset: e.offset + TextUnit::of_str(&edit.insert) - edit.delete.len(), | ||
178 | }) | ||
179 | } | ||
180 | } | ||
181 | for e in new_errors { | ||
182 | res.push(SyntaxError { | ||
183 | msg: e.msg, | ||
184 | offset: e.offset + old_node.range().start(), | ||
185 | }) | ||
186 | } | ||
187 | res | ||
188 | } | ||
189 | |||
190 | #[cfg(test)] | ||
191 | mod tests { | ||
192 | use super::{ | ||
193 | super::{ | ||
194 | File, | ||
195 | test_utils::extract_range, | ||
196 | text_utils::replace_range, | ||
197 | utils::dump_tree, | ||
198 | }, | ||
199 | reparse_leaf, reparse_block, AtomEdit, GreenNode, SyntaxError, SyntaxNodeRef, | ||
200 | }; | ||
201 | |||
202 | fn do_check<F>( | ||
203 | before: &str, | ||
204 | replace_with: &str, | ||
205 | reparser: F, | ||
206 | ) where | ||
207 | for<'a> F: Fn( | ||
208 | SyntaxNodeRef<'a>, | ||
209 | &AtomEdit, | ||
210 | ) -> Option<(SyntaxNodeRef<'a>, GreenNode, Vec<SyntaxError>)> | ||
211 | { | ||
212 | let (range, before) = extract_range(before); | ||
213 | let after = replace_range(before.clone(), range, replace_with); | ||
214 | |||
215 | let fully_reparsed = File::parse(&after); | ||
216 | let incrementally_reparsed = { | ||
217 | let f = File::parse(&before); | ||
218 | let edit = AtomEdit { delete: range, insert: replace_with.to_string() }; | ||
219 | let (node, green, new_errors) = | ||
220 | reparser(f.syntax(), &edit).expect("cannot incrementally reparse"); | ||
221 | let green_root = node.replace_with(green); | ||
222 | let errors = super::merge_errors(f.errors(), new_errors, node, &edit); | ||
223 | File::new(green_root, errors) | ||
224 | }; | ||
225 | |||
226 | assert_eq_text!( | ||
227 | &dump_tree(fully_reparsed.syntax()), | ||
228 | &dump_tree(incrementally_reparsed.syntax()), | ||
229 | ) | ||
230 | } | ||
231 | |||
232 | #[test] | ||
233 | fn reparse_block_tests() { | ||
234 | let do_check = |before, replace_to| | ||
235 | do_check(before, replace_to, reparse_block); | ||
236 | |||
237 | do_check(r" | ||
238 | fn foo() { | ||
239 | let x = foo + <|>bar<|> | ||
240 | } | ||
241 | ", "baz"); | ||
242 | do_check(r" | ||
243 | fn foo() { | ||
244 | let x = foo<|> + bar<|> | ||
245 | } | ||
246 | ", "baz"); | ||
247 | do_check(r" | ||
248 | struct Foo { | ||
249 | f: foo<|><|> | ||
250 | } | ||
251 | ", ",\n g: (),"); | ||
252 | do_check(r" | ||
253 | fn foo { | ||
254 | let; | ||
255 | 1 + 1; | ||
256 | <|>92<|>; | ||
257 | } | ||
258 | ", "62"); | ||
259 | do_check(r" | ||
260 | mod foo { | ||
261 | fn <|><|> | ||
262 | } | ||
263 | ", "bar"); | ||
264 | do_check(r" | ||
265 | trait Foo { | ||
266 | type <|>Foo<|>; | ||
267 | } | ||
268 | ", "Output"); | ||
269 | do_check(r" | ||
270 | impl IntoIterator<Item=i32> for Foo { | ||
271 | f<|><|> | ||
272 | } | ||
273 | ", "n next("); | ||
274 | do_check(r" | ||
275 | use a::b::{foo,<|>,bar<|>}; | ||
276 | ", "baz"); | ||
277 | do_check(r" | ||
278 | pub enum A { | ||
279 | Foo<|><|> | ||
280 | } | ||
281 | ", "\nBar;\n"); | ||
282 | do_check(r" | ||
283 | foo!{a, b<|><|> d} | ||
284 | ", ", c[3]"); | ||
285 | do_check(r" | ||
286 | fn foo() { | ||
287 | vec![<|><|>] | ||
288 | } | ||
289 | ", "123"); | ||
290 | do_check(r" | ||
291 | extern { | ||
292 | fn<|>;<|> | ||
293 | } | ||
294 | ", " exit(code: c_int)"); | ||
295 | } | ||
296 | |||
297 | #[test] | ||
298 | fn reparse_leaf_tests() { | ||
299 | let do_check = |before, replace_to| | ||
300 | do_check(before, replace_to, reparse_leaf); | ||
301 | |||
302 | do_check(r"<|><|> | ||
303 | fn foo() -> i32 { 1 } | ||
304 | ", "\n\n\n \n"); | ||
305 | do_check(r" | ||
306 | fn foo() -> <|><|> {} | ||
307 | ", " \n"); | ||
308 | do_check(r" | ||
309 | fn <|>foo<|>() -> i32 { 1 } | ||
310 | ", "bar"); | ||
311 | do_check(r" | ||
312 | fn foo<|><|>foo() { } | ||
313 | ", "bar"); | ||
314 | do_check(r" | ||
315 | fn foo /* <|><|> */ () {} | ||
316 | ", "some comment"); | ||
317 | do_check(r" | ||
318 | fn baz <|><|> () {} | ||
319 | ", " \t\t\n\n"); | ||
320 | do_check(r" | ||
321 | fn baz <|><|> () {} | ||
322 | ", " \t\t\n\n"); | ||
323 | do_check(r" | ||
324 | /// foo <|><|>omment | ||
325 | mod { } | ||
326 | ", "c"); | ||
327 | do_check(r#" | ||
328 | fn -> &str { "Hello<|><|>" } | ||
329 | "#, ", world"); | ||
330 | do_check(r#" | ||
331 | fn -> &str { // "Hello<|><|>" | ||
332 | "#, ", world"); | ||
333 | do_check(r##" | ||
334 | fn -> &str { r#"Hello<|><|>"# | ||
335 | "##, ", world"); | ||
336 | do_check(r" | ||
337 | #[derive(<|>Copy<|>)] | ||
338 | enum Foo { | ||
339 | |||
340 | } | ||
341 | ", "Clone"); | ||
342 | } | ||
343 | } \ No newline at end of file | ||
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs new file mode 100644 index 000000000..7882bded9 --- /dev/null +++ b/crates/ra_syntax/src/syntax_kinds/generated.rs | |||
@@ -0,0 +1,562 @@ | |||
1 | #![allow(bad_style, missing_docs, unreachable_pub)] | ||
2 | #![cfg_attr(rustfmt, rustfmt_skip)] | ||
3 | use super::SyntaxInfo; | ||
4 | |||
5 | /// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`. | ||
6 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
7 | pub enum SyntaxKind { | ||
8 | // Technical SyntaxKinds: they appear temporally during parsing, | ||
9 | // but never end up in the final tree | ||
10 | #[doc(hidden)] | ||
11 | TOMBSTONE, | ||
12 | #[doc(hidden)] | ||
13 | EOF, | ||
14 | SEMI, | ||
15 | COMMA, | ||
16 | L_PAREN, | ||
17 | R_PAREN, | ||
18 | L_CURLY, | ||
19 | R_CURLY, | ||
20 | L_BRACK, | ||
21 | R_BRACK, | ||
22 | L_ANGLE, | ||
23 | R_ANGLE, | ||
24 | AT, | ||
25 | POUND, | ||
26 | TILDE, | ||
27 | QUESTION, | ||
28 | DOLLAR, | ||
29 | AMP, | ||
30 | PIPE, | ||
31 | PLUS, | ||
32 | STAR, | ||
33 | SLASH, | ||
34 | CARET, | ||
35 | PERCENT, | ||
36 | DOT, | ||
37 | DOTDOT, | ||
38 | DOTDOTDOT, | ||
39 | DOTDOTEQ, | ||
40 | COLON, | ||
41 | COLONCOLON, | ||
42 | EQ, | ||
43 | EQEQ, | ||
44 | FAT_ARROW, | ||
45 | EXCL, | ||
46 | NEQ, | ||
47 | MINUS, | ||
48 | THIN_ARROW, | ||
49 | LTEQ, | ||
50 | GTEQ, | ||
51 | PLUSEQ, | ||
52 | MINUSEQ, | ||
53 | PIPEEQ, | ||
54 | AMPEQ, | ||
55 | CARETEQ, | ||
56 | SLASHEQ, | ||
57 | STAREQ, | ||
58 | AMPAMP, | ||
59 | PIPEPIPE, | ||
60 | SHL, | ||
61 | SHR, | ||
62 | SHLEQ, | ||
63 | SHREQ, | ||
64 | USE_KW, | ||
65 | FN_KW, | ||
66 | STRUCT_KW, | ||
67 | ENUM_KW, | ||
68 | TRAIT_KW, | ||
69 | IMPL_KW, | ||
70 | DYN_KW, | ||
71 | TRUE_KW, | ||
72 | FALSE_KW, | ||
73 | AS_KW, | ||
74 | EXTERN_KW, | ||
75 | CRATE_KW, | ||
76 | MOD_KW, | ||
77 | PUB_KW, | ||
78 | SELF_KW, | ||
79 | SUPER_KW, | ||
80 | IN_KW, | ||
81 | WHERE_KW, | ||
82 | FOR_KW, | ||
83 | LOOP_KW, | ||
84 | WHILE_KW, | ||
85 | CONTINUE_KW, | ||
86 | BREAK_KW, | ||
87 | IF_KW, | ||
88 | ELSE_KW, | ||
89 | MATCH_KW, | ||
90 | CONST_KW, | ||
91 | STATIC_KW, | ||
92 | MUT_KW, | ||
93 | UNSAFE_KW, | ||
94 | TYPE_KW, | ||
95 | REF_KW, | ||
96 | LET_KW, | ||
97 | MOVE_KW, | ||
98 | RETURN_KW, | ||
99 | AUTO_KW, | ||
100 | DEFAULT_KW, | ||
101 | UNION_KW, | ||
102 | ERROR, | ||
103 | IDENT, | ||
104 | UNDERSCORE, | ||
105 | WHITESPACE, | ||
106 | INT_NUMBER, | ||
107 | FLOAT_NUMBER, | ||
108 | LIFETIME, | ||
109 | CHAR, | ||
110 | BYTE, | ||
111 | STRING, | ||
112 | RAW_STRING, | ||
113 | BYTE_STRING, | ||
114 | RAW_BYTE_STRING, | ||
115 | COMMENT, | ||
116 | DOC_COMMENT, | ||
117 | SHEBANG, | ||
118 | ROOT, | ||
119 | STRUCT_DEF, | ||
120 | ENUM_DEF, | ||
121 | FN_DEF, | ||
122 | RET_TYPE, | ||
123 | EXTERN_CRATE_ITEM, | ||
124 | MODULE, | ||
125 | USE_ITEM, | ||
126 | STATIC_DEF, | ||
127 | CONST_DEF, | ||
128 | TRAIT_DEF, | ||
129 | IMPL_ITEM, | ||
130 | TYPE_DEF, | ||
131 | MACRO_CALL, | ||
132 | TOKEN_TREE, | ||
133 | PAREN_TYPE, | ||
134 | TUPLE_TYPE, | ||
135 | NEVER_TYPE, | ||
136 | PATH_TYPE, | ||
137 | POINTER_TYPE, | ||
138 | ARRAY_TYPE, | ||
139 | SLICE_TYPE, | ||
140 | REFERENCE_TYPE, | ||
141 | PLACEHOLDER_TYPE, | ||
142 | FN_POINTER_TYPE, | ||
143 | FOR_TYPE, | ||
144 | IMPL_TRAIT_TYPE, | ||
145 | DYN_TRAIT_TYPE, | ||
146 | REF_PAT, | ||
147 | BIND_PAT, | ||
148 | PLACEHOLDER_PAT, | ||
149 | PATH_PAT, | ||
150 | STRUCT_PAT, | ||
151 | FIELD_PAT_LIST, | ||
152 | TUPLE_STRUCT_PAT, | ||
153 | TUPLE_PAT, | ||
154 | SLICE_PAT, | ||
155 | RANGE_PAT, | ||
156 | TUPLE_EXPR, | ||
157 | ARRAY_EXPR, | ||
158 | PAREN_EXPR, | ||
159 | PATH_EXPR, | ||
160 | LAMBDA_EXPR, | ||
161 | IF_EXPR, | ||
162 | WHILE_EXPR, | ||
163 | CONDITION, | ||
164 | LOOP_EXPR, | ||
165 | FOR_EXPR, | ||
166 | CONTINUE_EXPR, | ||
167 | BREAK_EXPR, | ||
168 | LABEL, | ||
169 | BLOCK_EXPR, | ||
170 | RETURN_EXPR, | ||
171 | MATCH_EXPR, | ||
172 | MATCH_ARM_LIST, | ||
173 | MATCH_ARM, | ||
174 | MATCH_GUARD, | ||
175 | STRUCT_LIT, | ||
176 | NAMED_FIELD_LIST, | ||
177 | NAMED_FIELD, | ||
178 | CALL_EXPR, | ||
179 | INDEX_EXPR, | ||
180 | METHOD_CALL_EXPR, | ||
181 | FIELD_EXPR, | ||
182 | TRY_EXPR, | ||
183 | CAST_EXPR, | ||
184 | REF_EXPR, | ||
185 | PREFIX_EXPR, | ||
186 | RANGE_EXPR, | ||
187 | BIN_EXPR, | ||
188 | BLOCK, | ||
189 | EXTERN_BLOCK, | ||
190 | EXTERN_ITEM_LIST, | ||
191 | ENUM_VARIANT, | ||
192 | NAMED_FIELD_DEF_LIST, | ||
193 | NAMED_FIELD_DEF, | ||
194 | POS_FIELD_LIST, | ||
195 | POS_FIELD, | ||
196 | ENUM_VARIANT_LIST, | ||
197 | ITEM_LIST, | ||
198 | ATTR, | ||
199 | META_ITEM, | ||
200 | USE_TREE, | ||
201 | USE_TREE_LIST, | ||
202 | PATH, | ||
203 | PATH_SEGMENT, | ||
204 | LITERAL, | ||
205 | ALIAS, | ||
206 | VISIBILITY, | ||
207 | WHERE_CLAUSE, | ||
208 | WHERE_PRED, | ||
209 | ABI, | ||
210 | NAME, | ||
211 | NAME_REF, | ||
212 | LET_STMT, | ||
213 | EXPR_STMT, | ||
214 | TYPE_PARAM_LIST, | ||
215 | LIFETIME_PARAM, | ||
216 | TYPE_PARAM, | ||
217 | TYPE_ARG_LIST, | ||
218 | LIFETIME_ARG, | ||
219 | TYPE_ARG, | ||
220 | ASSOC_TYPE_ARG, | ||
221 | PARAM_LIST, | ||
222 | PARAM, | ||
223 | SELF_PARAM, | ||
224 | ARG_LIST, | ||
225 | } | ||
226 | use self::SyntaxKind::*; | ||
227 | |||
228 | impl SyntaxKind { | ||
229 | pub fn is_keyword(self) -> bool { | ||
230 | match self { | ||
231 | | USE_KW | ||
232 | | FN_KW | ||
233 | | STRUCT_KW | ||
234 | | ENUM_KW | ||
235 | | TRAIT_KW | ||
236 | | IMPL_KW | ||
237 | | DYN_KW | ||
238 | | TRUE_KW | ||
239 | | FALSE_KW | ||
240 | | AS_KW | ||
241 | | EXTERN_KW | ||
242 | | CRATE_KW | ||
243 | | MOD_KW | ||
244 | | PUB_KW | ||
245 | | SELF_KW | ||
246 | | SUPER_KW | ||
247 | | IN_KW | ||
248 | | WHERE_KW | ||
249 | | FOR_KW | ||
250 | | LOOP_KW | ||
251 | | WHILE_KW | ||
252 | | CONTINUE_KW | ||
253 | | BREAK_KW | ||
254 | | IF_KW | ||
255 | | ELSE_KW | ||
256 | | MATCH_KW | ||
257 | | CONST_KW | ||
258 | | STATIC_KW | ||
259 | | MUT_KW | ||
260 | | UNSAFE_KW | ||
261 | | TYPE_KW | ||
262 | | REF_KW | ||
263 | | LET_KW | ||
264 | | MOVE_KW | ||
265 | | RETURN_KW | ||
266 | | AUTO_KW | ||
267 | | DEFAULT_KW | ||
268 | | UNION_KW | ||
269 | => true, | ||
270 | _ => false | ||
271 | } | ||
272 | } | ||
273 | |||
274 | pub(crate) fn info(self) -> &'static SyntaxInfo { | ||
275 | match self { | ||
276 | SEMI => &SyntaxInfo { name: "SEMI" }, | ||
277 | COMMA => &SyntaxInfo { name: "COMMA" }, | ||
278 | L_PAREN => &SyntaxInfo { name: "L_PAREN" }, | ||
279 | R_PAREN => &SyntaxInfo { name: "R_PAREN" }, | ||
280 | L_CURLY => &SyntaxInfo { name: "L_CURLY" }, | ||
281 | R_CURLY => &SyntaxInfo { name: "R_CURLY" }, | ||
282 | L_BRACK => &SyntaxInfo { name: "L_BRACK" }, | ||
283 | R_BRACK => &SyntaxInfo { name: "R_BRACK" }, | ||
284 | L_ANGLE => &SyntaxInfo { name: "L_ANGLE" }, | ||
285 | R_ANGLE => &SyntaxInfo { name: "R_ANGLE" }, | ||
286 | AT => &SyntaxInfo { name: "AT" }, | ||
287 | POUND => &SyntaxInfo { name: "POUND" }, | ||
288 | TILDE => &SyntaxInfo { name: "TILDE" }, | ||
289 | QUESTION => &SyntaxInfo { name: "QUESTION" }, | ||
290 | DOLLAR => &SyntaxInfo { name: "DOLLAR" }, | ||
291 | AMP => &SyntaxInfo { name: "AMP" }, | ||
292 | PIPE => &SyntaxInfo { name: "PIPE" }, | ||
293 | PLUS => &SyntaxInfo { name: "PLUS" }, | ||
294 | STAR => &SyntaxInfo { name: "STAR" }, | ||
295 | SLASH => &SyntaxInfo { name: "SLASH" }, | ||
296 | CARET => &SyntaxInfo { name: "CARET" }, | ||
297 | PERCENT => &SyntaxInfo { name: "PERCENT" }, | ||
298 | DOT => &SyntaxInfo { name: "DOT" }, | ||
299 | DOTDOT => &SyntaxInfo { name: "DOTDOT" }, | ||
300 | DOTDOTDOT => &SyntaxInfo { name: "DOTDOTDOT" }, | ||
301 | DOTDOTEQ => &SyntaxInfo { name: "DOTDOTEQ" }, | ||
302 | COLON => &SyntaxInfo { name: "COLON" }, | ||
303 | COLONCOLON => &SyntaxInfo { name: "COLONCOLON" }, | ||
304 | EQ => &SyntaxInfo { name: "EQ" }, | ||
305 | EQEQ => &SyntaxInfo { name: "EQEQ" }, | ||
306 | FAT_ARROW => &SyntaxInfo { name: "FAT_ARROW" }, | ||
307 | EXCL => &SyntaxInfo { name: "EXCL" }, | ||
308 | NEQ => &SyntaxInfo { name: "NEQ" }, | ||
309 | MINUS => &SyntaxInfo { name: "MINUS" }, | ||
310 | THIN_ARROW => &SyntaxInfo { name: "THIN_ARROW" }, | ||
311 | LTEQ => &SyntaxInfo { name: "LTEQ" }, | ||
312 | GTEQ => &SyntaxInfo { name: "GTEQ" }, | ||
313 | PLUSEQ => &SyntaxInfo { name: "PLUSEQ" }, | ||
314 | MINUSEQ => &SyntaxInfo { name: "MINUSEQ" }, | ||
315 | PIPEEQ => &SyntaxInfo { name: "PIPEEQ" }, | ||
316 | AMPEQ => &SyntaxInfo { name: "AMPEQ" }, | ||
317 | CARETEQ => &SyntaxInfo { name: "CARETEQ" }, | ||
318 | SLASHEQ => &SyntaxInfo { name: "SLASHEQ" }, | ||
319 | STAREQ => &SyntaxInfo { name: "STAREQ" }, | ||
320 | AMPAMP => &SyntaxInfo { name: "AMPAMP" }, | ||
321 | PIPEPIPE => &SyntaxInfo { name: "PIPEPIPE" }, | ||
322 | SHL => &SyntaxInfo { name: "SHL" }, | ||
323 | SHR => &SyntaxInfo { name: "SHR" }, | ||
324 | SHLEQ => &SyntaxInfo { name: "SHLEQ" }, | ||
325 | SHREQ => &SyntaxInfo { name: "SHREQ" }, | ||
326 | USE_KW => &SyntaxInfo { name: "USE_KW" }, | ||
327 | FN_KW => &SyntaxInfo { name: "FN_KW" }, | ||
328 | STRUCT_KW => &SyntaxInfo { name: "STRUCT_KW" }, | ||
329 | ENUM_KW => &SyntaxInfo { name: "ENUM_KW" }, | ||
330 | TRAIT_KW => &SyntaxInfo { name: "TRAIT_KW" }, | ||
331 | IMPL_KW => &SyntaxInfo { name: "IMPL_KW" }, | ||
332 | DYN_KW => &SyntaxInfo { name: "DYN_KW" }, | ||
333 | TRUE_KW => &SyntaxInfo { name: "TRUE_KW" }, | ||
334 | FALSE_KW => &SyntaxInfo { name: "FALSE_KW" }, | ||
335 | AS_KW => &SyntaxInfo { name: "AS_KW" }, | ||
336 | EXTERN_KW => &SyntaxInfo { name: "EXTERN_KW" }, | ||
337 | CRATE_KW => &SyntaxInfo { name: "CRATE_KW" }, | ||
338 | MOD_KW => &SyntaxInfo { name: "MOD_KW" }, | ||
339 | PUB_KW => &SyntaxInfo { name: "PUB_KW" }, | ||
340 | SELF_KW => &SyntaxInfo { name: "SELF_KW" }, | ||
341 | SUPER_KW => &SyntaxInfo { name: "SUPER_KW" }, | ||
342 | IN_KW => &SyntaxInfo { name: "IN_KW" }, | ||
343 | WHERE_KW => &SyntaxInfo { name: "WHERE_KW" }, | ||
344 | FOR_KW => &SyntaxInfo { name: "FOR_KW" }, | ||
345 | LOOP_KW => &SyntaxInfo { name: "LOOP_KW" }, | ||
346 | WHILE_KW => &SyntaxInfo { name: "WHILE_KW" }, | ||
347 | CONTINUE_KW => &SyntaxInfo { name: "CONTINUE_KW" }, | ||
348 | BREAK_KW => &SyntaxInfo { name: "BREAK_KW" }, | ||
349 | IF_KW => &SyntaxInfo { name: "IF_KW" }, | ||
350 | ELSE_KW => &SyntaxInfo { name: "ELSE_KW" }, | ||
351 | MATCH_KW => &SyntaxInfo { name: "MATCH_KW" }, | ||
352 | CONST_KW => &SyntaxInfo { name: "CONST_KW" }, | ||
353 | STATIC_KW => &SyntaxInfo { name: "STATIC_KW" }, | ||
354 | MUT_KW => &SyntaxInfo { name: "MUT_KW" }, | ||
355 | UNSAFE_KW => &SyntaxInfo { name: "UNSAFE_KW" }, | ||
356 | TYPE_KW => &SyntaxInfo { name: "TYPE_KW" }, | ||
357 | REF_KW => &SyntaxInfo { name: "REF_KW" }, | ||
358 | LET_KW => &SyntaxInfo { name: "LET_KW" }, | ||
359 | MOVE_KW => &SyntaxInfo { name: "MOVE_KW" }, | ||
360 | RETURN_KW => &SyntaxInfo { name: "RETURN_KW" }, | ||
361 | AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, | ||
362 | DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, | ||
363 | UNION_KW => &SyntaxInfo { name: "UNION_KW" }, | ||
364 | ERROR => &SyntaxInfo { name: "ERROR" }, | ||
365 | IDENT => &SyntaxInfo { name: "IDENT" }, | ||
366 | UNDERSCORE => &SyntaxInfo { name: "UNDERSCORE" }, | ||
367 | WHITESPACE => &SyntaxInfo { name: "WHITESPACE" }, | ||
368 | INT_NUMBER => &SyntaxInfo { name: "INT_NUMBER" }, | ||
369 | FLOAT_NUMBER => &SyntaxInfo { name: "FLOAT_NUMBER" }, | ||
370 | LIFETIME => &SyntaxInfo { name: "LIFETIME" }, | ||
371 | CHAR => &SyntaxInfo { name: "CHAR" }, | ||
372 | BYTE => &SyntaxInfo { name: "BYTE" }, | ||
373 | STRING => &SyntaxInfo { name: "STRING" }, | ||
374 | RAW_STRING => &SyntaxInfo { name: "RAW_STRING" }, | ||
375 | BYTE_STRING => &SyntaxInfo { name: "BYTE_STRING" }, | ||
376 | RAW_BYTE_STRING => &SyntaxInfo { name: "RAW_BYTE_STRING" }, | ||
377 | COMMENT => &SyntaxInfo { name: "COMMENT" }, | ||
378 | DOC_COMMENT => &SyntaxInfo { name: "DOC_COMMENT" }, | ||
379 | SHEBANG => &SyntaxInfo { name: "SHEBANG" }, | ||
380 | ROOT => &SyntaxInfo { name: "ROOT" }, | ||
381 | STRUCT_DEF => &SyntaxInfo { name: "STRUCT_DEF" }, | ||
382 | ENUM_DEF => &SyntaxInfo { name: "ENUM_DEF" }, | ||
383 | FN_DEF => &SyntaxInfo { name: "FN_DEF" }, | ||
384 | RET_TYPE => &SyntaxInfo { name: "RET_TYPE" }, | ||
385 | EXTERN_CRATE_ITEM => &SyntaxInfo { name: "EXTERN_CRATE_ITEM" }, | ||
386 | MODULE => &SyntaxInfo { name: "MODULE" }, | ||
387 | USE_ITEM => &SyntaxInfo { name: "USE_ITEM" }, | ||
388 | STATIC_DEF => &SyntaxInfo { name: "STATIC_DEF" }, | ||
389 | CONST_DEF => &SyntaxInfo { name: "CONST_DEF" }, | ||
390 | TRAIT_DEF => &SyntaxInfo { name: "TRAIT_DEF" }, | ||
391 | IMPL_ITEM => &SyntaxInfo { name: "IMPL_ITEM" }, | ||
392 | TYPE_DEF => &SyntaxInfo { name: "TYPE_DEF" }, | ||
393 | MACRO_CALL => &SyntaxInfo { name: "MACRO_CALL" }, | ||
394 | TOKEN_TREE => &SyntaxInfo { name: "TOKEN_TREE" }, | ||
395 | PAREN_TYPE => &SyntaxInfo { name: "PAREN_TYPE" }, | ||
396 | TUPLE_TYPE => &SyntaxInfo { name: "TUPLE_TYPE" }, | ||
397 | NEVER_TYPE => &SyntaxInfo { name: "NEVER_TYPE" }, | ||
398 | PATH_TYPE => &SyntaxInfo { name: "PATH_TYPE" }, | ||
399 | POINTER_TYPE => &SyntaxInfo { name: "POINTER_TYPE" }, | ||
400 | ARRAY_TYPE => &SyntaxInfo { name: "ARRAY_TYPE" }, | ||
401 | SLICE_TYPE => &SyntaxInfo { name: "SLICE_TYPE" }, | ||
402 | REFERENCE_TYPE => &SyntaxInfo { name: "REFERENCE_TYPE" }, | ||
403 | PLACEHOLDER_TYPE => &SyntaxInfo { name: "PLACEHOLDER_TYPE" }, | ||
404 | FN_POINTER_TYPE => &SyntaxInfo { name: "FN_POINTER_TYPE" }, | ||
405 | FOR_TYPE => &SyntaxInfo { name: "FOR_TYPE" }, | ||
406 | IMPL_TRAIT_TYPE => &SyntaxInfo { name: "IMPL_TRAIT_TYPE" }, | ||
407 | DYN_TRAIT_TYPE => &SyntaxInfo { name: "DYN_TRAIT_TYPE" }, | ||
408 | REF_PAT => &SyntaxInfo { name: "REF_PAT" }, | ||
409 | BIND_PAT => &SyntaxInfo { name: "BIND_PAT" }, | ||
410 | PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" }, | ||
411 | PATH_PAT => &SyntaxInfo { name: "PATH_PAT" }, | ||
412 | STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" }, | ||
413 | FIELD_PAT_LIST => &SyntaxInfo { name: "FIELD_PAT_LIST" }, | ||
414 | TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" }, | ||
415 | TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" }, | ||
416 | SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" }, | ||
417 | RANGE_PAT => &SyntaxInfo { name: "RANGE_PAT" }, | ||
418 | TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" }, | ||
419 | ARRAY_EXPR => &SyntaxInfo { name: "ARRAY_EXPR" }, | ||
420 | PAREN_EXPR => &SyntaxInfo { name: "PAREN_EXPR" }, | ||
421 | PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" }, | ||
422 | LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" }, | ||
423 | IF_EXPR => &SyntaxInfo { name: "IF_EXPR" }, | ||
424 | WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" }, | ||
425 | CONDITION => &SyntaxInfo { name: "CONDITION" }, | ||
426 | LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" }, | ||
427 | FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" }, | ||
428 | CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" }, | ||
429 | BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" }, | ||
430 | LABEL => &SyntaxInfo { name: "LABEL" }, | ||
431 | BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" }, | ||
432 | RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" }, | ||
433 | MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" }, | ||
434 | MATCH_ARM_LIST => &SyntaxInfo { name: "MATCH_ARM_LIST" }, | ||
435 | MATCH_ARM => &SyntaxInfo { name: "MATCH_ARM" }, | ||
436 | MATCH_GUARD => &SyntaxInfo { name: "MATCH_GUARD" }, | ||
437 | STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, | ||
438 | NAMED_FIELD_LIST => &SyntaxInfo { name: "NAMED_FIELD_LIST" }, | ||
439 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, | ||
440 | CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, | ||
441 | INDEX_EXPR => &SyntaxInfo { name: "INDEX_EXPR" }, | ||
442 | METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" }, | ||
443 | FIELD_EXPR => &SyntaxInfo { name: "FIELD_EXPR" }, | ||
444 | TRY_EXPR => &SyntaxInfo { name: "TRY_EXPR" }, | ||
445 | CAST_EXPR => &SyntaxInfo { name: "CAST_EXPR" }, | ||
446 | REF_EXPR => &SyntaxInfo { name: "REF_EXPR" }, | ||
447 | PREFIX_EXPR => &SyntaxInfo { name: "PREFIX_EXPR" }, | ||
448 | RANGE_EXPR => &SyntaxInfo { name: "RANGE_EXPR" }, | ||
449 | BIN_EXPR => &SyntaxInfo { name: "BIN_EXPR" }, | ||
450 | BLOCK => &SyntaxInfo { name: "BLOCK" }, | ||
451 | EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" }, | ||
452 | EXTERN_ITEM_LIST => &SyntaxInfo { name: "EXTERN_ITEM_LIST" }, | ||
453 | ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" }, | ||
454 | NAMED_FIELD_DEF_LIST => &SyntaxInfo { name: "NAMED_FIELD_DEF_LIST" }, | ||
455 | NAMED_FIELD_DEF => &SyntaxInfo { name: "NAMED_FIELD_DEF" }, | ||
456 | POS_FIELD_LIST => &SyntaxInfo { name: "POS_FIELD_LIST" }, | ||
457 | POS_FIELD => &SyntaxInfo { name: "POS_FIELD" }, | ||
458 | ENUM_VARIANT_LIST => &SyntaxInfo { name: "ENUM_VARIANT_LIST" }, | ||
459 | ITEM_LIST => &SyntaxInfo { name: "ITEM_LIST" }, | ||
460 | ATTR => &SyntaxInfo { name: "ATTR" }, | ||
461 | META_ITEM => &SyntaxInfo { name: "META_ITEM" }, | ||
462 | USE_TREE => &SyntaxInfo { name: "USE_TREE" }, | ||
463 | USE_TREE_LIST => &SyntaxInfo { name: "USE_TREE_LIST" }, | ||
464 | PATH => &SyntaxInfo { name: "PATH" }, | ||
465 | PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" }, | ||
466 | LITERAL => &SyntaxInfo { name: "LITERAL" }, | ||
467 | ALIAS => &SyntaxInfo { name: "ALIAS" }, | ||
468 | VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, | ||
469 | WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, | ||
470 | WHERE_PRED => &SyntaxInfo { name: "WHERE_PRED" }, | ||
471 | ABI => &SyntaxInfo { name: "ABI" }, | ||
472 | NAME => &SyntaxInfo { name: "NAME" }, | ||
473 | NAME_REF => &SyntaxInfo { name: "NAME_REF" }, | ||
474 | LET_STMT => &SyntaxInfo { name: "LET_STMT" }, | ||
475 | EXPR_STMT => &SyntaxInfo { name: "EXPR_STMT" }, | ||
476 | TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" }, | ||
477 | LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" }, | ||
478 | TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" }, | ||
479 | TYPE_ARG_LIST => &SyntaxInfo { name: "TYPE_ARG_LIST" }, | ||
480 | LIFETIME_ARG => &SyntaxInfo { name: "LIFETIME_ARG" }, | ||
481 | TYPE_ARG => &SyntaxInfo { name: "TYPE_ARG" }, | ||
482 | ASSOC_TYPE_ARG => &SyntaxInfo { name: "ASSOC_TYPE_ARG" }, | ||
483 | PARAM_LIST => &SyntaxInfo { name: "PARAM_LIST" }, | ||
484 | PARAM => &SyntaxInfo { name: "PARAM" }, | ||
485 | SELF_PARAM => &SyntaxInfo { name: "SELF_PARAM" }, | ||
486 | ARG_LIST => &SyntaxInfo { name: "ARG_LIST" }, | ||
487 | TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, | ||
488 | EOF => &SyntaxInfo { name: "EOF" }, | ||
489 | } | ||
490 | } | ||
491 | pub(crate) fn from_keyword(ident: &str) -> Option<SyntaxKind> { | ||
492 | let kw = match ident { | ||
493 | "use" => USE_KW, | ||
494 | "fn" => FN_KW, | ||
495 | "struct" => STRUCT_KW, | ||
496 | "enum" => ENUM_KW, | ||
497 | "trait" => TRAIT_KW, | ||
498 | "impl" => IMPL_KW, | ||
499 | "dyn" => DYN_KW, | ||
500 | "true" => TRUE_KW, | ||
501 | "false" => FALSE_KW, | ||
502 | "as" => AS_KW, | ||
503 | "extern" => EXTERN_KW, | ||
504 | "crate" => CRATE_KW, | ||
505 | "mod" => MOD_KW, | ||
506 | "pub" => PUB_KW, | ||
507 | "self" => SELF_KW, | ||
508 | "super" => SUPER_KW, | ||
509 | "in" => IN_KW, | ||
510 | "where" => WHERE_KW, | ||
511 | "for" => FOR_KW, | ||
512 | "loop" => LOOP_KW, | ||
513 | "while" => WHILE_KW, | ||
514 | "continue" => CONTINUE_KW, | ||
515 | "break" => BREAK_KW, | ||
516 | "if" => IF_KW, | ||
517 | "else" => ELSE_KW, | ||
518 | "match" => MATCH_KW, | ||
519 | "const" => CONST_KW, | ||
520 | "static" => STATIC_KW, | ||
521 | "mut" => MUT_KW, | ||
522 | "unsafe" => UNSAFE_KW, | ||
523 | "type" => TYPE_KW, | ||
524 | "ref" => REF_KW, | ||
525 | "let" => LET_KW, | ||
526 | "move" => MOVE_KW, | ||
527 | "return" => RETURN_KW, | ||
528 | _ => return None, | ||
529 | }; | ||
530 | Some(kw) | ||
531 | } | ||
532 | |||
533 | pub(crate) fn from_char(c: char) -> Option<SyntaxKind> { | ||
534 | let tok = match c { | ||
535 | ';' => SEMI, | ||
536 | ',' => COMMA, | ||
537 | '(' => L_PAREN, | ||
538 | ')' => R_PAREN, | ||
539 | '{' => L_CURLY, | ||
540 | '}' => R_CURLY, | ||
541 | '[' => L_BRACK, | ||
542 | ']' => R_BRACK, | ||
543 | '<' => L_ANGLE, | ||
544 | '>' => R_ANGLE, | ||
545 | '@' => AT, | ||
546 | '#' => POUND, | ||
547 | '~' => TILDE, | ||
548 | '?' => QUESTION, | ||
549 | '$' => DOLLAR, | ||
550 | '&' => AMP, | ||
551 | '|' => PIPE, | ||
552 | '+' => PLUS, | ||
553 | '*' => STAR, | ||
554 | '/' => SLASH, | ||
555 | '^' => CARET, | ||
556 | '%' => PERCENT, | ||
557 | _ => return None, | ||
558 | }; | ||
559 | Some(tok) | ||
560 | } | ||
561 | } | ||
562 | |||
diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs.tera b/crates/ra_syntax/src/syntax_kinds/generated.rs.tera new file mode 100644 index 000000000..90618721a --- /dev/null +++ b/crates/ra_syntax/src/syntax_kinds/generated.rs.tera | |||
@@ -0,0 +1,73 @@ | |||
1 | #![allow(bad_style, missing_docs, unreachable_pub)] | ||
2 | #![cfg_attr(rustfmt, rustfmt_skip)] | ||
3 | use super::SyntaxInfo; | ||
4 | |||
5 | /// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`. | ||
6 | #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
7 | pub enum SyntaxKind { | ||
8 | // Technical SyntaxKinds: they appear temporally during parsing, | ||
9 | // but never end up in the final tree | ||
10 | #[doc(hidden)] | ||
11 | TOMBSTONE, | ||
12 | #[doc(hidden)] | ||
13 | EOF, | ||
14 | |||
15 | {%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %} | ||
16 | {{t.1}}, | ||
17 | {%- endfor -%} | ||
18 | {% for kw in concat(a=keywords, b=contextual_keywords) %} | ||
19 | {{kw | upper}}_KW, | ||
20 | {%- endfor -%} | ||
21 | {% for t in concat(a=tokens, b=nodes) %} | ||
22 | {{t}}, | ||
23 | {%- endfor %} | ||
24 | } | ||
25 | use self::SyntaxKind::*; | ||
26 | |||
27 | impl SyntaxKind { | ||
28 | pub fn is_keyword(self) -> bool { | ||
29 | match self { | ||
30 | {%- for kw in concat(a=keywords, b=contextual_keywords) %} | ||
31 | | {{kw | upper}}_KW | ||
32 | {%- endfor %} | ||
33 | => true, | ||
34 | _ => false | ||
35 | } | ||
36 | } | ||
37 | |||
38 | pub(crate) fn info(self) -> &'static SyntaxInfo { | ||
39 | match self { | ||
40 | {%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %} | ||
41 | {{t.1}} => &SyntaxInfo { name: "{{t.1}}" }, | ||
42 | {%- endfor -%} | ||
43 | {% for kw in concat(a=keywords, b=contextual_keywords) %} | ||
44 | {{kw | upper}}_KW => &SyntaxInfo { name: "{{kw | upper}}_KW" }, | ||
45 | {%- endfor -%} | ||
46 | {% for t in concat(a=tokens, b=nodes) %} | ||
47 | {{t}} => &SyntaxInfo { name: "{{t}}" }, | ||
48 | {%- endfor %} | ||
49 | TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" }, | ||
50 | EOF => &SyntaxInfo { name: "EOF" }, | ||
51 | } | ||
52 | } | ||
53 | pub(crate) fn from_keyword(ident: &str) -> Option<SyntaxKind> { | ||
54 | let kw = match ident { | ||
55 | {%- for kw in keywords %} | ||
56 | "{{kw}}" => {{kw | upper}}_KW, | ||
57 | {%- endfor %} | ||
58 | _ => return None, | ||
59 | }; | ||
60 | Some(kw) | ||
61 | } | ||
62 | |||
63 | pub(crate) fn from_char(c: char) -> Option<SyntaxKind> { | ||
64 | let tok = match c { | ||
65 | {%- for t in single_byte_tokens %} | ||
66 | '{{t.0}}' => {{t.1}}, | ||
67 | {%- endfor %} | ||
68 | _ => return None, | ||
69 | }; | ||
70 | Some(tok) | ||
71 | } | ||
72 | } | ||
73 | |||
diff --git a/crates/ra_syntax/src/syntax_kinds/mod.rs b/crates/ra_syntax/src/syntax_kinds/mod.rs new file mode 100644 index 000000000..332cd13ac --- /dev/null +++ b/crates/ra_syntax/src/syntax_kinds/mod.rs | |||
@@ -0,0 +1,26 @@ | |||
1 | mod generated; | ||
2 | |||
3 | use std::fmt; | ||
4 | use SyntaxKind::*; | ||
5 | |||
6 | pub use self::generated::SyntaxKind; | ||
7 | |||
8 | impl fmt::Debug for SyntaxKind { | ||
9 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
10 | let name = self.info().name; | ||
11 | f.write_str(name) | ||
12 | } | ||
13 | } | ||
14 | |||
15 | pub(crate) struct SyntaxInfo { | ||
16 | pub name: &'static str, | ||
17 | } | ||
18 | |||
19 | impl SyntaxKind { | ||
20 | pub fn is_trivia(self) -> bool { | ||
21 | match self { | ||
22 | WHITESPACE | COMMENT | DOC_COMMENT => true, | ||
23 | _ => false, | ||
24 | } | ||
25 | } | ||
26 | } | ||
diff --git a/crates/ra_syntax/src/text_utils.rs b/crates/ra_syntax/src/text_utils.rs new file mode 100644 index 000000000..58ae1e43e --- /dev/null +++ b/crates/ra_syntax/src/text_utils.rs | |||
@@ -0,0 +1,26 @@ | |||
1 | use {TextRange, TextUnit}; | ||
2 | |||
3 | pub fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { | ||
4 | range.start() <= offset && offset <= range.end() | ||
5 | } | ||
6 | |||
7 | pub fn is_subrange(range: TextRange, subrange: TextRange) -> bool { | ||
8 | range.start() <= subrange.start() && subrange.end() <= range.end() | ||
9 | } | ||
10 | |||
11 | pub fn intersect(r1: TextRange, r2: TextRange) -> Option<TextRange> { | ||
12 | let start = r1.start().max(r2.start()); | ||
13 | let end = r1.end().min(r2.end()); | ||
14 | if start <= end { | ||
15 | Some(TextRange::from_to(start, end)) | ||
16 | } else { | ||
17 | None | ||
18 | } | ||
19 | } | ||
20 | |||
21 | pub fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String { | ||
22 | let start = u32::from(range.start()) as usize; | ||
23 | let end = u32::from(range.end()) as usize; | ||
24 | text.replace_range(start..end, replace_with); | ||
25 | text | ||
26 | } \ No newline at end of file | ||
diff --git a/crates/ra_syntax/src/token_set.rs b/crates/ra_syntax/src/token_set.rs new file mode 100644 index 000000000..c83fba81b --- /dev/null +++ b/crates/ra_syntax/src/token_set.rs | |||
@@ -0,0 +1,37 @@ | |||
1 | use SyntaxKind; | ||
2 | |||
3 | #[derive(Clone, Copy)] | ||
4 | pub(crate) struct TokenSet(pub(crate) u128); | ||
5 | |||
6 | fn mask(kind: SyntaxKind) -> u128 { | ||
7 | 1u128 << (kind as usize) | ||
8 | } | ||
9 | |||
10 | impl TokenSet { | ||
11 | pub const EMPTY: TokenSet = TokenSet(0); | ||
12 | |||
13 | pub fn contains(&self, kind: SyntaxKind) -> bool { | ||
14 | self.0 & mask(kind) != 0 | ||
15 | } | ||
16 | } | ||
17 | |||
18 | #[macro_export] | ||
19 | macro_rules! token_set { | ||
20 | ($($t:ident),*) => { TokenSet($(1u128 << ($t as usize))|*) }; | ||
21 | ($($t:ident),* ,) => { token_set!($($t),*) }; | ||
22 | } | ||
23 | |||
24 | #[macro_export] | ||
25 | macro_rules! token_set_union { | ||
26 | ($($ts:expr),*) => { TokenSet($($ts.0)|*) }; | ||
27 | ($($ts:expr),* ,) => { token_set_union!($($ts),*) }; | ||
28 | } | ||
29 | |||
30 | #[test] | ||
31 | fn token_set_works_for_tokens() { | ||
32 | use SyntaxKind::*; | ||
33 | let ts = token_set! { EOF, SHEBANG }; | ||
34 | assert!(ts.contains(EOF)); | ||
35 | assert!(ts.contains(SHEBANG)); | ||
36 | assert!(!ts.contains(PLUS)); | ||
37 | } | ||
diff --git a/crates/ra_syntax/src/utils.rs b/crates/ra_syntax/src/utils.rs new file mode 100644 index 000000000..671dd7afa --- /dev/null +++ b/crates/ra_syntax/src/utils.rs | |||
@@ -0,0 +1,85 @@ | |||
1 | use std::fmt::Write; | ||
2 | use { | ||
3 | algo::walk::{preorder, walk, WalkEvent}, | ||
4 | SyntaxKind, File, SyntaxNodeRef, TreeRoot, | ||
5 | }; | ||
6 | |||
7 | /// Parse a file and create a string representation of the resulting parse tree. | ||
8 | pub fn dump_tree(syntax: SyntaxNodeRef) -> String { | ||
9 | let mut errors: Vec<_> = syntax.root.syntax_root().errors.iter().cloned().collect(); | ||
10 | errors.sort_by_key(|e| e.offset); | ||
11 | let mut err_pos = 0; | ||
12 | let mut level = 0; | ||
13 | let mut buf = String::new(); | ||
14 | macro_rules! indent { | ||
15 | () => { | ||
16 | for _ in 0..level { | ||
17 | buf.push_str(" "); | ||
18 | } | ||
19 | }; | ||
20 | } | ||
21 | |||
22 | for event in walk(syntax) { | ||
23 | match event { | ||
24 | WalkEvent::Enter(node) => { | ||
25 | indent!(); | ||
26 | writeln!(buf, "{:?}", node).unwrap(); | ||
27 | if node.first_child().is_none() { | ||
28 | let off = node.range().end(); | ||
29 | while err_pos < errors.len() && errors[err_pos].offset <= off { | ||
30 | indent!(); | ||
31 | writeln!(buf, "err: `{}`", errors[err_pos].msg).unwrap(); | ||
32 | err_pos += 1; | ||
33 | } | ||
34 | } | ||
35 | level += 1; | ||
36 | } | ||
37 | WalkEvent::Exit(_) => level -= 1, | ||
38 | } | ||
39 | } | ||
40 | |||
41 | assert_eq!(level, 0); | ||
42 | for err in errors[err_pos..].iter() { | ||
43 | writeln!(buf, "err: `{}`", err.msg).unwrap(); | ||
44 | } | ||
45 | |||
46 | return buf; | ||
47 | } | ||
48 | |||
49 | pub fn check_fuzz_invariants(text: &str) { | ||
50 | let file = File::parse(text); | ||
51 | let root = file.syntax(); | ||
52 | validate_block_structure(root); | ||
53 | let _ = file.ast(); | ||
54 | let _ = file.errors(); | ||
55 | } | ||
56 | |||
57 | pub(crate) fn validate_block_structure(root: SyntaxNodeRef) { | ||
58 | let mut stack = Vec::new(); | ||
59 | for node in preorder(root) { | ||
60 | match node.kind() { | ||
61 | SyntaxKind::L_CURLY => { | ||
62 | stack.push(node) | ||
63 | } | ||
64 | SyntaxKind::R_CURLY => { | ||
65 | if let Some(pair) = stack.pop() { | ||
66 | assert_eq!( | ||
67 | node.parent(), | ||
68 | pair.parent(), | ||
69 | "\nunpaired curleys:\n{}\n{}\n", | ||
70 | root.text(), | ||
71 | dump_tree(root), | ||
72 | ); | ||
73 | assert!( | ||
74 | node.next_sibling().is_none() && pair.prev_sibling().is_none(), | ||
75 | "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", | ||
76 | node, | ||
77 | root.text(), | ||
78 | node.text(), | ||
79 | ); | ||
80 | } | ||
81 | } | ||
82 | _ => (), | ||
83 | } | ||
84 | } | ||
85 | } | ||
diff --git a/crates/ra_syntax/src/yellow/builder.rs b/crates/ra_syntax/src/yellow/builder.rs new file mode 100644 index 000000000..e4ab37899 --- /dev/null +++ b/crates/ra_syntax/src/yellow/builder.rs | |||
@@ -0,0 +1,64 @@ | |||
1 | use { | ||
2 | parser_impl::Sink, | ||
3 | yellow::{GreenNode, SyntaxError}, | ||
4 | SyntaxKind, TextRange, TextUnit, | ||
5 | }; | ||
6 | |||
7 | pub(crate) struct GreenBuilder<'a> { | ||
8 | text: &'a str, | ||
9 | parents: Vec<(SyntaxKind, usize)>, | ||
10 | children: Vec<GreenNode>, | ||
11 | pos: TextUnit, | ||
12 | errors: Vec<SyntaxError>, | ||
13 | } | ||
14 | |||
15 | impl<'a> Sink<'a> for GreenBuilder<'a> { | ||
16 | type Tree = (GreenNode, Vec<SyntaxError>); | ||
17 | |||
18 | fn new(text: &'a str) -> Self { | ||
19 | GreenBuilder { | ||
20 | text, | ||
21 | parents: Vec::new(), | ||
22 | children: Vec::new(), | ||
23 | pos: 0.into(), | ||
24 | errors: Vec::new(), | ||
25 | } | ||
26 | } | ||
27 | |||
28 | fn leaf(&mut self, kind: SyntaxKind, len: TextUnit) { | ||
29 | let range = TextRange::offset_len(self.pos, len); | ||
30 | self.pos += len; | ||
31 | let text = &self.text[range]; | ||
32 | self.children.push( | ||
33 | GreenNode::new_leaf(kind, text) | ||
34 | ); | ||
35 | } | ||
36 | |||
37 | fn start_internal(&mut self, kind: SyntaxKind) { | ||
38 | let len = self.children.len(); | ||
39 | self.parents.push((kind, len)); | ||
40 | } | ||
41 | |||
42 | fn finish_internal(&mut self) { | ||
43 | let (kind, first_child) = self.parents.pop().unwrap(); | ||
44 | let children: Vec<_> = self.children | ||
45 | .drain(first_child..) | ||
46 | .collect(); | ||
47 | self.children.push( | ||
48 | GreenNode::new_branch(kind, children.into_boxed_slice()) | ||
49 | ); | ||
50 | } | ||
51 | |||
52 | fn error(&mut self, message: String) { | ||
53 | self.errors.push(SyntaxError { | ||
54 | msg: message, | ||
55 | offset: self.pos, | ||
56 | }) | ||
57 | } | ||
58 | |||
59 | fn finish(mut self) -> (GreenNode, Vec<SyntaxError>) { | ||
60 | assert_eq!(self.children.len(), 1); | ||
61 | let root = self.children.pop().unwrap(); | ||
62 | (root, self.errors) | ||
63 | } | ||
64 | } | ||
diff --git a/crates/ra_syntax/src/yellow/green.rs b/crates/ra_syntax/src/yellow/green.rs new file mode 100644 index 000000000..8fb691643 --- /dev/null +++ b/crates/ra_syntax/src/yellow/green.rs | |||
@@ -0,0 +1,90 @@ | |||
1 | use std::sync::Arc; | ||
2 | |||
3 | use smol_str::SmolStr; | ||
4 | |||
5 | use {SyntaxKind, TextUnit}; | ||
6 | |||
7 | #[derive(Clone, Debug)] | ||
8 | pub(crate) enum GreenNode { | ||
9 | Leaf { | ||
10 | kind: SyntaxKind, | ||
11 | text: SmolStr, | ||
12 | }, | ||
13 | Branch(Arc<GreenBranch>), | ||
14 | } | ||
15 | |||
16 | impl GreenNode { | ||
17 | pub(crate) fn new_leaf(kind: SyntaxKind, text: &str) -> GreenNode { | ||
18 | GreenNode::Leaf { kind, text: SmolStr::new(text) } | ||
19 | } | ||
20 | |||
21 | pub(crate) fn new_branch(kind: SyntaxKind, children: Box<[GreenNode]>) -> GreenNode { | ||
22 | GreenNode::Branch(Arc::new(GreenBranch::new(kind, children))) | ||
23 | } | ||
24 | |||
25 | pub fn kind(&self) -> SyntaxKind { | ||
26 | match self { | ||
27 | GreenNode::Leaf { kind, .. } => *kind, | ||
28 | GreenNode::Branch(b) => b.kind(), | ||
29 | } | ||
30 | } | ||
31 | |||
32 | pub fn text_len(&self) -> TextUnit { | ||
33 | match self { | ||
34 | GreenNode::Leaf { text, .. } => TextUnit::from(text.len() as u32), | ||
35 | GreenNode::Branch(b) => b.text_len(), | ||
36 | } | ||
37 | } | ||
38 | |||
39 | pub fn children(&self) -> &[GreenNode] { | ||
40 | match self { | ||
41 | GreenNode::Leaf { .. } => &[], | ||
42 | GreenNode::Branch(b) => b.children(), | ||
43 | } | ||
44 | } | ||
45 | |||
46 | pub fn leaf_text_ref(&self) -> Option<&SmolStr> { | ||
47 | match self { | ||
48 | GreenNode::Leaf { text, .. } => Some(text), | ||
49 | GreenNode::Branch(_) => None, | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
54 | #[derive(Clone, Debug)] | ||
55 | pub(crate) struct GreenBranch { | ||
56 | text_len: TextUnit, | ||
57 | kind: SyntaxKind, | ||
58 | children: Box<[GreenNode]>, | ||
59 | } | ||
60 | |||
61 | impl GreenBranch { | ||
62 | fn new(kind: SyntaxKind, children: Box<[GreenNode]>) -> GreenBranch { | ||
63 | let text_len = children.iter().map(|x| x.text_len()).sum::<TextUnit>(); | ||
64 | GreenBranch { | ||
65 | text_len, | ||
66 | kind, | ||
67 | children, | ||
68 | } | ||
69 | } | ||
70 | |||
71 | pub fn kind(&self) -> SyntaxKind { | ||
72 | self.kind | ||
73 | } | ||
74 | |||
75 | pub fn text_len(&self) -> TextUnit { | ||
76 | self.text_len | ||
77 | } | ||
78 | |||
79 | pub fn children(&self) -> &[GreenNode] { | ||
80 | &*self.children | ||
81 | } | ||
82 | } | ||
83 | |||
84 | #[test] | ||
85 | fn test_sizes() { | ||
86 | use std::mem::size_of; | ||
87 | println!("GreenBranch = {}", size_of::<GreenBranch>()); | ||
88 | println!("GreenNode = {}", size_of::<GreenNode>()); | ||
89 | println!("SmolStr = {}", size_of::<SmolStr>()); | ||
90 | } | ||
diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs new file mode 100644 index 000000000..0596e702f --- /dev/null +++ b/crates/ra_syntax/src/yellow/mod.rs | |||
@@ -0,0 +1,100 @@ | |||
1 | mod builder; | ||
2 | mod green; | ||
3 | mod red; | ||
4 | mod syntax; | ||
5 | mod syntax_text; | ||
6 | |||
7 | use std::{ | ||
8 | sync::Arc, | ||
9 | ptr, | ||
10 | }; | ||
11 | pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren}; | ||
12 | pub(crate) use self::{ | ||
13 | builder::GreenBuilder, | ||
14 | green::GreenNode, | ||
15 | red::RedNode, | ||
16 | syntax_text::SyntaxText, | ||
17 | }; | ||
18 | |||
19 | #[derive(Debug)] | ||
20 | pub struct SyntaxRoot { | ||
21 | red: RedNode, | ||
22 | pub(crate) errors: Vec<SyntaxError>, | ||
23 | } | ||
24 | |||
25 | pub trait TreeRoot: Clone + Send + Sync { | ||
26 | fn borrowed(&self) -> RefRoot; | ||
27 | fn owned(&self) -> OwnedRoot; | ||
28 | |||
29 | #[doc(hidden)] | ||
30 | fn syntax_root(&self) -> &SyntaxRoot; | ||
31 | } | ||
32 | #[derive(Clone, Debug)] | ||
33 | pub struct OwnedRoot(Arc<SyntaxRoot>); | ||
34 | #[derive(Clone, Copy, Debug)] | ||
35 | pub struct RefRoot<'a>(&'a OwnedRoot); // TODO: shared_from_this instead of double indirection | ||
36 | |||
37 | impl<'a> RefRoot<'a> { | ||
38 | fn syntax_root(&self) -> &'a SyntaxRoot { | ||
39 | self.0.syntax_root() | ||
40 | } | ||
41 | } | ||
42 | |||
43 | impl TreeRoot for OwnedRoot { | ||
44 | fn borrowed(&self) -> RefRoot { | ||
45 | RefRoot(&self) | ||
46 | } | ||
47 | fn owned(&self) -> OwnedRoot { | ||
48 | self.clone() | ||
49 | } | ||
50 | |||
51 | fn syntax_root(&self) -> &SyntaxRoot { | ||
52 | &*self.0 | ||
53 | } | ||
54 | } | ||
55 | |||
56 | impl<'a> TreeRoot for RefRoot<'a> { | ||
57 | fn borrowed(&self) -> RefRoot { | ||
58 | *self | ||
59 | } | ||
60 | fn owned(&self) -> OwnedRoot { | ||
61 | self.0.clone() | ||
62 | } | ||
63 | fn syntax_root(&self) -> &SyntaxRoot { | ||
64 | self.0.syntax_root() | ||
65 | } | ||
66 | } | ||
67 | |||
68 | impl SyntaxRoot { | ||
69 | pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxRoot { | ||
70 | SyntaxRoot { | ||
71 | red: RedNode::new_root(green), | ||
72 | errors, | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | |||
77 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
78 | pub(crate) struct RedPtr(ptr::NonNull<RedNode>); | ||
79 | |||
80 | unsafe impl Send for RedPtr {} | ||
81 | |||
82 | unsafe impl Sync for RedPtr {} | ||
83 | |||
84 | impl RedPtr { | ||
85 | fn new(red: &RedNode) -> RedPtr { | ||
86 | RedPtr(red.into()) | ||
87 | } | ||
88 | |||
89 | unsafe fn get<'a>(self, _root: &'a SyntaxRoot) -> &'a RedNode { | ||
90 | &*self.0.as_ptr() | ||
91 | } | ||
92 | } | ||
93 | |||
94 | #[test] | ||
95 | fn assert_send_sync() { | ||
96 | fn f<T: Send + Sync>() {} | ||
97 | f::<GreenNode>(); | ||
98 | f::<RedNode>(); | ||
99 | f::<SyntaxNode>(); | ||
100 | } | ||
diff --git a/crates/ra_syntax/src/yellow/red.rs b/crates/ra_syntax/src/yellow/red.rs new file mode 100644 index 000000000..84cfe4fba --- /dev/null +++ b/crates/ra_syntax/src/yellow/red.rs | |||
@@ -0,0 +1,113 @@ | |||
1 | use parking_lot::RwLock; | ||
2 | use {yellow::{GreenNode, RedPtr}, TextUnit}; | ||
3 | |||
4 | #[derive(Debug)] | ||
5 | pub(crate) struct RedNode { | ||
6 | green: GreenNode, | ||
7 | parent: Option<ParentData>, | ||
8 | children: RwLock<Box<[RedChild]>>, | ||
9 | } | ||
10 | |||
11 | #[derive(Debug)] | ||
12 | enum RedChild { | ||
13 | Zigot(TextUnit), | ||
14 | Child(RedNode) | ||
15 | } | ||
16 | |||
17 | impl RedChild { | ||
18 | fn set(&mut self, node: RedNode) -> &RedNode { | ||
19 | match self { | ||
20 | RedChild::Child(node) => return node, | ||
21 | RedChild::Zigot(_) => { | ||
22 | *self = RedChild::Child(node); | ||
23 | match self { | ||
24 | RedChild::Child(node) => return node, | ||
25 | RedChild::Zigot(_) => unreachable!() | ||
26 | } | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | |||
32 | #[derive(Debug)] | ||
33 | struct ParentData { | ||
34 | parent: RedPtr, | ||
35 | start_offset: TextUnit, | ||
36 | index_in_parent: usize, | ||
37 | } | ||
38 | |||
39 | impl RedNode { | ||
40 | pub fn new_root(green: GreenNode) -> RedNode { | ||
41 | RedNode::new(green, None) | ||
42 | } | ||
43 | |||
44 | fn new_child( | ||
45 | green: GreenNode, | ||
46 | parent: RedPtr, | ||
47 | start_offset: TextUnit, | ||
48 | index_in_parent: usize, | ||
49 | ) -> RedNode { | ||
50 | let parent_data = ParentData { | ||
51 | parent, | ||
52 | start_offset, | ||
53 | index_in_parent, | ||
54 | }; | ||
55 | RedNode::new(green, Some(parent_data)) | ||
56 | } | ||
57 | |||
58 | fn new(green: GreenNode, parent: Option<ParentData>) -> RedNode { | ||
59 | let mut start_offset = parent.as_ref().map(|it| it.start_offset).unwrap_or(0.into()); | ||
60 | let children = green.children() | ||
61 | .iter() | ||
62 | .map(|child| { | ||
63 | let off = start_offset; | ||
64 | start_offset += child.text_len(); | ||
65 | RedChild::Zigot(off) | ||
66 | }) | ||
67 | .collect::<Vec<_>>() | ||
68 | .into_boxed_slice(); | ||
69 | RedNode { | ||
70 | green, | ||
71 | parent, | ||
72 | children: RwLock::new(children), | ||
73 | } | ||
74 | } | ||
75 | |||
76 | pub(crate) fn green(&self) -> &GreenNode { | ||
77 | &self.green | ||
78 | } | ||
79 | |||
80 | pub(crate) fn start_offset(&self) -> TextUnit { | ||
81 | match &self.parent { | ||
82 | None => 0.into(), | ||
83 | Some(p) => p.start_offset, | ||
84 | } | ||
85 | } | ||
86 | |||
87 | pub(crate) fn n_children(&self) -> usize { | ||
88 | self.green.children().len() | ||
89 | } | ||
90 | |||
91 | pub(crate) fn get_child(&self, idx: usize) -> Option<RedPtr> { | ||
92 | if idx >= self.n_children() { | ||
93 | return None; | ||
94 | } | ||
95 | let start_offset = match &self.children.read()[idx] { | ||
96 | RedChild::Child(child) => return Some(RedPtr::new(child)), | ||
97 | RedChild::Zigot(start_offset) => *start_offset, | ||
98 | }; | ||
99 | let green_children = self.green.children(); | ||
100 | let child = | ||
101 | RedNode::new_child(green_children[idx].clone(), RedPtr::new(self), start_offset, idx); | ||
102 | let mut children = self.children.write(); | ||
103 | let child = children[idx].set(child); | ||
104 | Some(RedPtr::new(child)) | ||
105 | } | ||
106 | |||
107 | pub(crate) fn parent(&self) -> Option<RedPtr> { | ||
108 | Some(self.parent.as_ref()?.parent) | ||
109 | } | ||
110 | pub(crate) fn index_in_parent(&self) -> Option<usize> { | ||
111 | Some(self.parent.as_ref()?.index_in_parent) | ||
112 | } | ||
113 | } | ||
diff --git a/crates/ra_syntax/src/yellow/syntax.rs b/crates/ra_syntax/src/yellow/syntax.rs new file mode 100644 index 000000000..1d99cab4a --- /dev/null +++ b/crates/ra_syntax/src/yellow/syntax.rs | |||
@@ -0,0 +1,215 @@ | |||
1 | use std::{ | ||
2 | fmt, sync::Arc, | ||
3 | hash::{Hasher, Hash}, | ||
4 | ops::Range, | ||
5 | }; | ||
6 | |||
7 | use smol_str::SmolStr; | ||
8 | |||
9 | use { | ||
10 | yellow::{GreenNode, RedNode, TreeRoot, SyntaxRoot, RedPtr, RefRoot, OwnedRoot, SyntaxText}, | ||
11 | SyntaxKind::{self, *}, | ||
12 | TextRange, TextUnit, | ||
13 | }; | ||
14 | |||
15 | |||
16 | #[derive(Clone, Copy)] | ||
17 | pub struct SyntaxNode<R: TreeRoot = OwnedRoot> { | ||
18 | pub(crate) root: R, | ||
19 | // Guaranteed to not dangle, because `root` holds a | ||
20 | // strong reference to red's ancestor | ||
21 | red: RedPtr, | ||
22 | } | ||
23 | |||
24 | unsafe impl<R: TreeRoot> Send for SyntaxNode<R> {} | ||
25 | unsafe impl<R: TreeRoot> Sync for SyntaxNode<R> {} | ||
26 | |||
27 | impl<R1: TreeRoot, R2: TreeRoot> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2> { | ||
28 | fn eq(&self, other: &SyntaxNode<R1>) -> bool { | ||
29 | self.red == other.red | ||
30 | } | ||
31 | } | ||
32 | |||
33 | impl<R: TreeRoot> Eq for SyntaxNode<R> {} | ||
34 | impl<R: TreeRoot> Hash for SyntaxNode<R> { | ||
35 | fn hash<H: Hasher>(&self, state: &mut H) { | ||
36 | self.red.hash(state) | ||
37 | } | ||
38 | } | ||
39 | |||
40 | pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>; | ||
41 | |||
42 | #[test] | ||
43 | fn syntax_node_ref_is_copy() { | ||
44 | fn assert_copy<T: Copy>(){} | ||
45 | assert_copy::<SyntaxNodeRef>() | ||
46 | } | ||
47 | |||
48 | #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] | ||
49 | pub struct SyntaxError { | ||
50 | pub msg: String, | ||
51 | pub offset: TextUnit, | ||
52 | } | ||
53 | |||
54 | impl SyntaxNode<OwnedRoot> { | ||
55 | pub(crate) fn new_owned(root: SyntaxRoot) -> Self { | ||
56 | let root = OwnedRoot(Arc::new(root)); | ||
57 | let red = RedPtr::new(&root.syntax_root().red); | ||
58 | SyntaxNode { root, red } | ||
59 | } | ||
60 | } | ||
61 | |||
62 | impl<'a> SyntaxNode<RefRoot<'a>> { | ||
63 | pub(crate) fn leaf_text_ref(self) -> Option<&'a SmolStr> { | ||
64 | let red = unsafe { self.red.get(self.root.syntax_root()) }; | ||
65 | red.green().leaf_text_ref() | ||
66 | } | ||
67 | } | ||
68 | |||
69 | impl<R: TreeRoot> SyntaxNode<R> { | ||
70 | pub fn borrowed<'a>(&'a self) -> SyntaxNodeRef<'a> { | ||
71 | SyntaxNode { | ||
72 | root: self.root.borrowed(), | ||
73 | red: self.red, | ||
74 | } | ||
75 | } | ||
76 | |||
77 | pub fn owned(&self) -> SyntaxNode { | ||
78 | SyntaxNode { | ||
79 | root: self.root.owned(), | ||
80 | red: self.red, | ||
81 | } | ||
82 | } | ||
83 | |||
84 | pub fn kind(&self) -> SyntaxKind { | ||
85 | self.red().green().kind() | ||
86 | } | ||
87 | |||
88 | pub fn range(&self) -> TextRange { | ||
89 | let red = self.red(); | ||
90 | TextRange::offset_len(red.start_offset(), red.green().text_len()) | ||
91 | } | ||
92 | |||
93 | pub fn text(&self) -> SyntaxText { | ||
94 | SyntaxText::new(self.borrowed()) | ||
95 | } | ||
96 | |||
97 | pub fn children(&self) -> SyntaxNodeChildren<R> { | ||
98 | SyntaxNodeChildren { | ||
99 | parent: self.clone(), | ||
100 | iter: (0..self.red().n_children()) | ||
101 | } | ||
102 | } | ||
103 | |||
104 | pub fn parent(&self) -> Option<SyntaxNode<R>> { | ||
105 | let parent = self.red().parent()?; | ||
106 | Some(SyntaxNode { | ||
107 | root: self.root.clone(), | ||
108 | red: parent, | ||
109 | }) | ||
110 | } | ||
111 | |||
112 | pub fn first_child(&self) -> Option<SyntaxNode<R>> { | ||
113 | let red = self.red().get_child(0)?; | ||
114 | Some(SyntaxNode { root: self.root.clone(), red }) | ||
115 | } | ||
116 | |||
117 | pub fn last_child(&self) -> Option<SyntaxNode<R>> { | ||
118 | let n = self.red().n_children(); | ||
119 | let n = n.checked_sub(1)?; | ||
120 | let red = self.red().get_child(n)?; | ||
121 | Some(SyntaxNode { root: self.root.clone(), red }) | ||
122 | } | ||
123 | |||
124 | pub fn next_sibling(&self) -> Option<SyntaxNode<R>> { | ||
125 | let red = self.red(); | ||
126 | let parent = self.parent()?; | ||
127 | let next_sibling_idx = red.index_in_parent()? + 1; | ||
128 | let sibling_red = parent.red().get_child(next_sibling_idx)?; | ||
129 | Some(SyntaxNode { | ||
130 | root: self.root.clone(), | ||
131 | red: sibling_red, | ||
132 | }) | ||
133 | } | ||
134 | |||
135 | pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> { | ||
136 | let red = self.red(); | ||
137 | let parent = self.parent()?; | ||
138 | let prev_sibling_idx = red.index_in_parent()?.checked_sub(1)?; | ||
139 | let sibling_red = parent.red().get_child(prev_sibling_idx)?; | ||
140 | Some(SyntaxNode { | ||
141 | root: self.root.clone(), | ||
142 | red: sibling_red, | ||
143 | }) | ||
144 | } | ||
145 | |||
146 | pub fn is_leaf(&self) -> bool { | ||
147 | self.first_child().is_none() | ||
148 | } | ||
149 | |||
150 | pub fn leaf_text(&self) -> Option<SmolStr> { | ||
151 | self.borrowed().leaf_text_ref().map(|it| it.clone()) | ||
152 | } | ||
153 | |||
154 | pub(crate) fn replace_with(&self, green: GreenNode) -> GreenNode { | ||
155 | assert_eq!(self.kind(), green.kind()); | ||
156 | match self.parent() { | ||
157 | None => green, | ||
158 | Some(parent) => { | ||
159 | let children: Vec<_> = parent.children().map(|child| { | ||
160 | if child == *self { | ||
161 | green.clone() | ||
162 | } else { | ||
163 | child.red().green().clone() | ||
164 | } | ||
165 | }).collect(); | ||
166 | let new_parent = GreenNode::new_branch( | ||
167 | parent.kind(), | ||
168 | children.into_boxed_slice(), | ||
169 | ); | ||
170 | parent.replace_with(new_parent) | ||
171 | }, | ||
172 | } | ||
173 | } | ||
174 | |||
175 | fn red(&self) -> &RedNode { | ||
176 | unsafe { self.red.get(self.root.syntax_root()) } | ||
177 | } | ||
178 | } | ||
179 | |||
180 | impl<R: TreeRoot> fmt::Debug for SyntaxNode<R> { | ||
181 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | ||
182 | write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; | ||
183 | if has_short_text(self.kind()) { | ||
184 | write!(fmt, " \"{}\"", self.text())?; | ||
185 | } | ||
186 | Ok(()) | ||
187 | } | ||
188 | } | ||
189 | |||
190 | #[derive(Debug)] | ||
191 | pub struct SyntaxNodeChildren<R: TreeRoot> { | ||
192 | parent: SyntaxNode<R>, | ||
193 | iter: Range<usize>, | ||
194 | } | ||
195 | |||
196 | impl<R: TreeRoot> Iterator for SyntaxNodeChildren<R> { | ||
197 | type Item = SyntaxNode<R>; | ||
198 | |||
199 | fn next(&mut self) -> Option<SyntaxNode<R>> { | ||
200 | self.iter.next().map(|i| { | ||
201 | let red = self.parent.red(); | ||
202 | SyntaxNode { | ||
203 | root: self.parent.root.clone(), | ||
204 | red: red.get_child(i).unwrap(), | ||
205 | } | ||
206 | }) | ||
207 | } | ||
208 | } | ||
209 | |||
210 | fn has_short_text(kind: SyntaxKind) -> bool { | ||
211 | match kind { | ||
212 | IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true, | ||
213 | _ => false, | ||
214 | } | ||
215 | } | ||
diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs new file mode 100644 index 000000000..280bedd78 --- /dev/null +++ b/crates/ra_syntax/src/yellow/syntax_text.rs | |||
@@ -0,0 +1,122 @@ | |||
1 | use std::{ | ||
2 | fmt, ops, | ||
3 | }; | ||
4 | |||
5 | use { | ||
6 | SyntaxNodeRef, TextRange, TextUnit, | ||
7 | algo::walk::preorder, | ||
8 | text_utils::{intersect, contains_offset_nonstrict}, | ||
9 | }; | ||
10 | |||
11 | #[derive(Clone)] | ||
12 | pub struct SyntaxText<'a> { | ||
13 | node: SyntaxNodeRef<'a>, | ||
14 | range: TextRange, | ||
15 | } | ||
16 | |||
17 | impl<'a> SyntaxText<'a> { | ||
18 | pub(crate) fn new(node: SyntaxNodeRef<'a>) -> SyntaxText<'a> { | ||
19 | SyntaxText { | ||
20 | node, | ||
21 | range: node.range() | ||
22 | } | ||
23 | } | ||
24 | pub fn chunks(&self) -> impl Iterator<Item=&'a str> { | ||
25 | let range = self.range; | ||
26 | preorder(self.node) | ||
27 | .filter_map(move |node| { | ||
28 | let text = node.leaf_text_ref()?; | ||
29 | let range = intersect(range, node.range())?; | ||
30 | let range = range - node.range().start(); | ||
31 | Some(&text[range]) | ||
32 | }) | ||
33 | } | ||
34 | pub fn push_to(&self, buf: &mut String) { | ||
35 | self.chunks().for_each(|it| buf.push_str(it)); | ||
36 | } | ||
37 | pub fn to_string(&self) -> String { | ||
38 | self.chunks().collect() | ||
39 | } | ||
40 | pub fn contains(&self, c: char) -> bool { | ||
41 | self.chunks().any(|it| it.contains(c)) | ||
42 | } | ||
43 | pub fn find(&self, c: char) -> Option<TextUnit> { | ||
44 | let mut acc: TextUnit = 0.into(); | ||
45 | for chunk in self.chunks() { | ||
46 | if let Some(pos) = chunk.find(c) { | ||
47 | let pos: TextUnit = (pos as u32).into(); | ||
48 | return Some(acc + pos); | ||
49 | } | ||
50 | acc += TextUnit::of_str(chunk); | ||
51 | } | ||
52 | None | ||
53 | } | ||
54 | pub fn len(&self) -> TextUnit { | ||
55 | self.range.len() | ||
56 | } | ||
57 | pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> { | ||
58 | let range = range.restrict(self.range) | ||
59 | .unwrap_or_else(|| { | ||
60 | panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) | ||
61 | }); | ||
62 | SyntaxText { node: self.node, range } | ||
63 | } | ||
64 | pub fn char_at(&self, offset: TextUnit) -> Option<char> { | ||
65 | let mut start: TextUnit = 0.into(); | ||
66 | for chunk in self.chunks() { | ||
67 | let end = start + TextUnit::of_str(chunk); | ||
68 | if start <= offset && offset < end { | ||
69 | let off: usize = u32::from(offset - start) as usize; | ||
70 | return Some(chunk[off..].chars().next().unwrap()); | ||
71 | } | ||
72 | start = end; | ||
73 | } | ||
74 | None | ||
75 | } | ||
76 | } | ||
77 | |||
78 | impl<'a> fmt::Debug for SyntaxText<'a> { | ||
79 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
80 | fmt::Debug::fmt(&self.to_string(), f) | ||
81 | } | ||
82 | } | ||
83 | |||
84 | impl<'a> fmt::Display for SyntaxText<'a> { | ||
85 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
86 | fmt::Display::fmt(&self.to_string(), f) | ||
87 | } | ||
88 | } | ||
89 | |||
90 | pub trait SyntaxTextSlice: fmt::Debug { | ||
91 | fn restrict(&self, range: TextRange) -> Option<TextRange>; | ||
92 | } | ||
93 | |||
94 | impl SyntaxTextSlice for TextRange { | ||
95 | fn restrict(&self, range: TextRange) -> Option<TextRange> { | ||
96 | intersect(*self, range) | ||
97 | } | ||
98 | } | ||
99 | |||
100 | impl SyntaxTextSlice for ops::RangeTo<TextUnit> { | ||
101 | fn restrict(&self, range: TextRange) -> Option<TextRange> { | ||
102 | if !contains_offset_nonstrict(range, self.end) { | ||
103 | return None; | ||
104 | } | ||
105 | Some(TextRange::from_to(range.start(), self.end)) | ||
106 | } | ||
107 | } | ||
108 | |||
109 | impl SyntaxTextSlice for ops::RangeFrom<TextUnit> { | ||
110 | fn restrict(&self, range: TextRange) -> Option<TextRange> { | ||
111 | if !contains_offset_nonstrict(range, self.start) { | ||
112 | return None; | ||
113 | } | ||
114 | Some(TextRange::from_to(self.start, range.end())) | ||
115 | } | ||
116 | } | ||
117 | |||
118 | impl SyntaxTextSlice for ops::Range<TextUnit> { | ||
119 | fn restrict(&self, range: TextRange) -> Option<TextRange> { | ||
120 | TextRange::from_to(self.start, self.end).restrict(range) | ||
121 | } | ||
122 | } | ||
diff --git a/crates/ra_syntax/tests/data/lexer/00012_block_comment.rs b/crates/ra_syntax/tests/data/lexer/00012_block_comment.rs new file mode 100644 index 000000000..708aac197 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/00012_block_comment.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | /* */ | ||
2 | /**/ | ||
3 | /* /* */ */ | ||
4 | /* | ||
diff --git a/crates/ra_syntax/tests/data/lexer/00012_block_comment.txt b/crates/ra_syntax/tests/data/lexer/00012_block_comment.txt new file mode 100644 index 000000000..9958b2518 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/00012_block_comment.txt | |||
@@ -0,0 +1,7 @@ | |||
1 | COMMENT 5 "/* */" | ||
2 | WHITESPACE 1 "\n" | ||
3 | COMMENT 4 "/**/" | ||
4 | WHITESPACE 1 "\n" | ||
5 | COMMENT 11 "/* /* */ */" | ||
6 | WHITESPACE 1 "\n" | ||
7 | COMMENT 3 "/*\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0001_hello.rs b/crates/ra_syntax/tests/data/lexer/0001_hello.rs new file mode 100644 index 000000000..95d09f2b1 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0001_hello.rs | |||
@@ -0,0 +1 @@ | |||
hello world \ No newline at end of file | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0001_hello.txt b/crates/ra_syntax/tests/data/lexer/0001_hello.txt new file mode 100644 index 000000000..27a5940a9 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0001_hello.txt | |||
@@ -0,0 +1,3 @@ | |||
1 | IDENT 5 "hello" | ||
2 | WHITESPACE 1 " " | ||
3 | IDENT 5 "world" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0002_whitespace.rs b/crates/ra_syntax/tests/data/lexer/0002_whitespace.rs new file mode 100644 index 000000000..08fce1418 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0002_whitespace.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | a b c | ||
2 | d | ||
3 | |||
4 | e f | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0002_whitespace.txt b/crates/ra_syntax/tests/data/lexer/0002_whitespace.txt new file mode 100644 index 000000000..01d260918 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0002_whitespace.txt | |||
@@ -0,0 +1,12 @@ | |||
1 | IDENT 1 "a" | ||
2 | WHITESPACE 1 " " | ||
3 | IDENT 1 "b" | ||
4 | WHITESPACE 2 " " | ||
5 | IDENT 1 "c" | ||
6 | WHITESPACE 1 "\n" | ||
7 | IDENT 1 "d" | ||
8 | WHITESPACE 2 "\n\n" | ||
9 | IDENT 1 "e" | ||
10 | WHITESPACE 1 "\t" | ||
11 | IDENT 1 "f" | ||
12 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0003_ident.rs b/crates/ra_syntax/tests/data/lexer/0003_ident.rs new file mode 100644 index 000000000..c05c9c009 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0003_ident.rs | |||
@@ -0,0 +1 @@ | |||
foo foo_ _foo _ __ x привет | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0003_ident.txt b/crates/ra_syntax/tests/data/lexer/0003_ident.txt new file mode 100644 index 000000000..4a0d5c053 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0003_ident.txt | |||
@@ -0,0 +1,14 @@ | |||
1 | IDENT 3 "foo" | ||
2 | WHITESPACE 1 " " | ||
3 | IDENT 4 "foo_" | ||
4 | WHITESPACE 1 " " | ||
5 | IDENT 4 "_foo" | ||
6 | WHITESPACE 1 " " | ||
7 | UNDERSCORE 1 "_" | ||
8 | WHITESPACE 1 " " | ||
9 | IDENT 2 "__" | ||
10 | WHITESPACE 1 " " | ||
11 | IDENT 1 "x" | ||
12 | WHITESPACE 1 " " | ||
13 | IDENT 12 "привет" | ||
14 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0004_numbers.rs b/crates/ra_syntax/tests/data/lexer/0004_numbers.rs new file mode 100644 index 000000000..dc974b553 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0004_numbers.rs | |||
@@ -0,0 +1,9 @@ | |||
1 | 0 0b 0o 0x 00 0_ 0. 0e 0E 0z | ||
2 | 01790 0b1790 0o1790 0x1790aAbBcCdDeEfF 001279 0_1279 0.1279 0e1279 0E1279 | ||
3 | 0..2 | ||
4 | 0.foo() | ||
5 | 0e+1 | ||
6 | 0.e+1 | ||
7 | 0.0E-2 | ||
8 | 0___0.10000____0000e+111__ | ||
9 | 1i64 92.0f32 11__s \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0004_numbers.txt b/crates/ra_syntax/tests/data/lexer/0004_numbers.txt new file mode 100644 index 000000000..4b5fd9f71 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0004_numbers.txt | |||
@@ -0,0 +1,67 @@ | |||
1 | INT_NUMBER 1 "0" | ||
2 | WHITESPACE 1 " " | ||
3 | INT_NUMBER 2 "0b" | ||
4 | WHITESPACE 1 " " | ||
5 | INT_NUMBER 2 "0o" | ||
6 | WHITESPACE 1 " " | ||
7 | INT_NUMBER 2 "0x" | ||
8 | WHITESPACE 1 " " | ||
9 | INT_NUMBER 2 "00" | ||
10 | WHITESPACE 1 " " | ||
11 | INT_NUMBER 2 "0_" | ||
12 | WHITESPACE 1 " " | ||
13 | FLOAT_NUMBER 2 "0." | ||
14 | WHITESPACE 1 " " | ||
15 | INT_NUMBER 2 "0e" | ||
16 | WHITESPACE 1 " " | ||
17 | INT_NUMBER 2 "0E" | ||
18 | WHITESPACE 1 " " | ||
19 | INT_NUMBER 2 "0z" | ||
20 | WHITESPACE 1 "\n" | ||
21 | INT_NUMBER 5 "01790" | ||
22 | WHITESPACE 1 " " | ||
23 | INT_NUMBER 6 "0b1790" | ||
24 | WHITESPACE 1 " " | ||
25 | INT_NUMBER 6 "0o1790" | ||
26 | WHITESPACE 1 " " | ||
27 | INT_NUMBER 18 "0x1790aAbBcCdDeEfF" | ||
28 | WHITESPACE 1 " " | ||
29 | INT_NUMBER 6 "001279" | ||
30 | WHITESPACE 1 " " | ||
31 | INT_NUMBER 6 "0_1279" | ||
32 | WHITESPACE 1 " " | ||
33 | FLOAT_NUMBER 6 "0.1279" | ||
34 | WHITESPACE 1 " " | ||
35 | INT_NUMBER 6 "0e1279" | ||
36 | WHITESPACE 1 " " | ||
37 | INT_NUMBER 6 "0E1279" | ||
38 | WHITESPACE 1 "\n" | ||
39 | INT_NUMBER 1 "0" | ||
40 | DOTDOT 2 ".." | ||
41 | INT_NUMBER 1 "2" | ||
42 | WHITESPACE 1 "\n" | ||
43 | INT_NUMBER 1 "0" | ||
44 | DOT 1 "." | ||
45 | IDENT 3 "foo" | ||
46 | L_PAREN 1 "(" | ||
47 | R_PAREN 1 ")" | ||
48 | WHITESPACE 1 "\n" | ||
49 | INT_NUMBER 2 "0e" | ||
50 | PLUS 1 "+" | ||
51 | INT_NUMBER 1 "1" | ||
52 | WHITESPACE 1 "\n" | ||
53 | INT_NUMBER 1 "0" | ||
54 | DOT 1 "." | ||
55 | IDENT 1 "e" | ||
56 | PLUS 1 "+" | ||
57 | INT_NUMBER 1 "1" | ||
58 | WHITESPACE 1 "\n" | ||
59 | FLOAT_NUMBER 6 "0.0E-2" | ||
60 | WHITESPACE 1 "\n" | ||
61 | FLOAT_NUMBER 26 "0___0.10000____0000e+111__" | ||
62 | WHITESPACE 1 "\n" | ||
63 | INT_NUMBER 4 "1i64" | ||
64 | WHITESPACE 1 " " | ||
65 | FLOAT_NUMBER 7 "92.0f32" | ||
66 | WHITESPACE 1 " " | ||
67 | INT_NUMBER 5 "11__s" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0005_symbols.rs b/crates/ra_syntax/tests/data/lexer/0005_symbols.rs new file mode 100644 index 000000000..487569b5a --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0005_symbols.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | ; , ( ) { } [ ] < > @ # ~ ? $ & | + * / ^ % | ||
2 | . .. ... ..= | ||
3 | : :: | ||
4 | = => | ||
5 | ! != | ||
6 | - -> | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0005_symbols.txt b/crates/ra_syntax/tests/data/lexer/0005_symbols.txt new file mode 100644 index 000000000..a6bc83a6f --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0005_symbols.txt | |||
@@ -0,0 +1,68 @@ | |||
1 | SEMI 1 ";" | ||
2 | WHITESPACE 1 " " | ||
3 | COMMA 1 "," | ||
4 | WHITESPACE 1 " " | ||
5 | L_PAREN 1 "(" | ||
6 | WHITESPACE 1 " " | ||
7 | R_PAREN 1 ")" | ||
8 | WHITESPACE 1 " " | ||
9 | L_CURLY 1 "{" | ||
10 | WHITESPACE 1 " " | ||
11 | R_CURLY 1 "}" | ||
12 | WHITESPACE 1 " " | ||
13 | L_BRACK 1 "[" | ||
14 | WHITESPACE 1 " " | ||
15 | R_BRACK 1 "]" | ||
16 | WHITESPACE 1 " " | ||
17 | L_ANGLE 1 "<" | ||
18 | WHITESPACE 1 " " | ||
19 | R_ANGLE 1 ">" | ||
20 | WHITESPACE 1 " " | ||
21 | AT 1 "@" | ||
22 | WHITESPACE 1 " " | ||
23 | POUND 1 "#" | ||
24 | WHITESPACE 1 " " | ||
25 | TILDE 1 "~" | ||
26 | WHITESPACE 1 " " | ||
27 | QUESTION 1 "?" | ||
28 | WHITESPACE 1 " " | ||
29 | DOLLAR 1 "$" | ||
30 | WHITESPACE 1 " " | ||
31 | AMP 1 "&" | ||
32 | WHITESPACE 1 " " | ||
33 | PIPE 1 "|" | ||
34 | WHITESPACE 1 " " | ||
35 | PLUS 1 "+" | ||
36 | WHITESPACE 1 " " | ||
37 | STAR 1 "*" | ||
38 | WHITESPACE 1 " " | ||
39 | SLASH 1 "/" | ||
40 | WHITESPACE 1 " " | ||
41 | CARET 1 "^" | ||
42 | WHITESPACE 1 " " | ||
43 | PERCENT 1 "%" | ||
44 | WHITESPACE 1 "\n" | ||
45 | DOT 1 "." | ||
46 | WHITESPACE 1 " " | ||
47 | DOTDOT 2 ".." | ||
48 | WHITESPACE 1 " " | ||
49 | DOTDOTDOT 3 "..." | ||
50 | WHITESPACE 1 " " | ||
51 | DOTDOTEQ 3 "..=" | ||
52 | WHITESPACE 1 "\n" | ||
53 | COLON 1 ":" | ||
54 | WHITESPACE 1 " " | ||
55 | COLONCOLON 2 "::" | ||
56 | WHITESPACE 1 "\n" | ||
57 | EQ 1 "=" | ||
58 | WHITESPACE 1 " " | ||
59 | FAT_ARROW 2 "=>" | ||
60 | WHITESPACE 1 "\n" | ||
61 | EXCL 1 "!" | ||
62 | WHITESPACE 1 " " | ||
63 | NEQ 2 "!=" | ||
64 | WHITESPACE 1 "\n" | ||
65 | MINUS 1 "-" | ||
66 | WHITESPACE 1 " " | ||
67 | THIN_ARROW 2 "->" | ||
68 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0006_chars.rs b/crates/ra_syntax/tests/data/lexer/0006_chars.rs new file mode 100644 index 000000000..454ee0a5f --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0006_chars.rs | |||
@@ -0,0 +1 @@ | |||
'x' ' ' '0' 'hello' '\x7f' '\n' '\\' '\'' | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0006_chars.txt b/crates/ra_syntax/tests/data/lexer/0006_chars.txt new file mode 100644 index 000000000..950954fbc --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0006_chars.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | CHAR 3 "\'x\'" | ||
2 | WHITESPACE 1 " " | ||
3 | CHAR 3 "\' \'" | ||
4 | WHITESPACE 1 " " | ||
5 | CHAR 3 "\'0\'" | ||
6 | WHITESPACE 1 " " | ||
7 | CHAR 7 "\'hello\'" | ||
8 | WHITESPACE 1 " " | ||
9 | CHAR 6 "\'\\x7f\'" | ||
10 | WHITESPACE 1 " " | ||
11 | CHAR 4 "\'\\n\'" | ||
12 | WHITESPACE 1 " " | ||
13 | CHAR 4 "\'\\\\\'" | ||
14 | WHITESPACE 1 " " | ||
15 | CHAR 4 "\'\\\'\'" | ||
16 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0007_lifetimes.rs b/crates/ra_syntax/tests/data/lexer/0007_lifetimes.rs new file mode 100644 index 000000000..b764f1dce --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0007_lifetimes.rs | |||
@@ -0,0 +1 @@ | |||
'a 'foo 'foo_bar_baz '_ | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0007_lifetimes.txt b/crates/ra_syntax/tests/data/lexer/0007_lifetimes.txt new file mode 100644 index 000000000..005c29100 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0007_lifetimes.txt | |||
@@ -0,0 +1,8 @@ | |||
1 | LIFETIME 2 "\'a" | ||
2 | WHITESPACE 1 " " | ||
3 | LIFETIME 4 "\'foo" | ||
4 | WHITESPACE 1 " " | ||
5 | LIFETIME 12 "\'foo_bar_baz" | ||
6 | WHITESPACE 1 " " | ||
7 | LIFETIME 2 "\'_" | ||
8 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0008_byte_strings.rs b/crates/ra_syntax/tests/data/lexer/0008_byte_strings.rs new file mode 100644 index 000000000..b54930f5e --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0008_byte_strings.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | b'' b'x' b"foo" br"" | ||
2 | b''suf b""ix br""br | ||
3 | b'\n' b'\\' b'\'' b'hello' | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0008_byte_strings.txt b/crates/ra_syntax/tests/data/lexer/0008_byte_strings.txt new file mode 100644 index 000000000..bc03b51a8 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0008_byte_strings.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | BYTE 3 "b\'\'" | ||
2 | WHITESPACE 1 " " | ||
3 | BYTE 4 "b\'x\'" | ||
4 | WHITESPACE 1 " " | ||
5 | BYTE_STRING 6 "b\"foo\"" | ||
6 | WHITESPACE 1 " " | ||
7 | RAW_BYTE_STRING 4 "br\"\"" | ||
8 | WHITESPACE 1 "\n" | ||
9 | BYTE 6 "b\'\'suf" | ||
10 | WHITESPACE 1 " " | ||
11 | BYTE_STRING 5 "b\"\"ix" | ||
12 | WHITESPACE 1 " " | ||
13 | RAW_BYTE_STRING 6 "br\"\"br" | ||
14 | WHITESPACE 1 "\n" | ||
15 | BYTE 5 "b\'\\n\'" | ||
16 | WHITESPACE 1 " " | ||
17 | BYTE 5 "b\'\\\\\'" | ||
18 | WHITESPACE 1 " " | ||
19 | BYTE 5 "b\'\\\'\'" | ||
20 | WHITESPACE 1 " " | ||
21 | BYTE 8 "b\'hello\'" | ||
22 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0009_strings.rs b/crates/ra_syntax/tests/data/lexer/0009_strings.rs new file mode 100644 index 000000000..4ddb5bffc --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0009_strings.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | "hello" r"world" "\n\"\\no escape" "multi | ||
2 | line" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0009_strings.txt b/crates/ra_syntax/tests/data/lexer/0009_strings.txt new file mode 100644 index 000000000..4cb4d711d --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0009_strings.txt | |||
@@ -0,0 +1,8 @@ | |||
1 | STRING 7 "\"hello\"" | ||
2 | WHITESPACE 1 " " | ||
3 | RAW_STRING 8 "r\"world\"" | ||
4 | WHITESPACE 1 " " | ||
5 | STRING 17 "\"\\n\\\"\\\\no escape\"" | ||
6 | WHITESPACE 1 " " | ||
7 | STRING 12 "\"multi\nline\"" | ||
8 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0010_comments.rs b/crates/ra_syntax/tests/data/lexer/0010_comments.rs new file mode 100644 index 000000000..71bdd1f9c --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0010_comments.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | #!/usr/bin/env bash | ||
2 | // hello | ||
3 | //! World | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0010_comments.txt b/crates/ra_syntax/tests/data/lexer/0010_comments.txt new file mode 100644 index 000000000..3c997de3f --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0010_comments.txt | |||
@@ -0,0 +1,6 @@ | |||
1 | SHEBANG 19 "#!/usr/bin/env bash" | ||
2 | WHITESPACE 1 "\n" | ||
3 | COMMENT 8 "// hello" | ||
4 | WHITESPACE 1 "\n" | ||
5 | COMMENT 9 "//! World" | ||
6 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0011_keywords.rs b/crates/ra_syntax/tests/data/lexer/0011_keywords.rs new file mode 100644 index 000000000..e6bf64d4d --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0011_keywords.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn use struct trait enum impl true false as extern crate | ||
2 | mod pub self super in where for loop while if match const | ||
3 | static mut type ref let else move return | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0011_keywords.txt b/crates/ra_syntax/tests/data/lexer/0011_keywords.txt new file mode 100644 index 000000000..d6a1abe8a --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0011_keywords.txt | |||
@@ -0,0 +1,62 @@ | |||
1 | FN_KW 2 "fn" | ||
2 | WHITESPACE 1 " " | ||
3 | USE_KW 3 "use" | ||
4 | WHITESPACE 1 " " | ||
5 | STRUCT_KW 6 "struct" | ||
6 | WHITESPACE 1 " " | ||
7 | TRAIT_KW 5 "trait" | ||
8 | WHITESPACE 1 " " | ||
9 | ENUM_KW 4 "enum" | ||
10 | WHITESPACE 1 " " | ||
11 | IMPL_KW 4 "impl" | ||
12 | WHITESPACE 1 " " | ||
13 | TRUE_KW 4 "true" | ||
14 | WHITESPACE 1 " " | ||
15 | FALSE_KW 5 "false" | ||
16 | WHITESPACE 1 " " | ||
17 | AS_KW 2 "as" | ||
18 | WHITESPACE 1 " " | ||
19 | EXTERN_KW 6 "extern" | ||
20 | WHITESPACE 1 " " | ||
21 | CRATE_KW 5 "crate" | ||
22 | WHITESPACE 1 "\n" | ||
23 | MOD_KW 3 "mod" | ||
24 | WHITESPACE 1 " " | ||
25 | PUB_KW 3 "pub" | ||
26 | WHITESPACE 1 " " | ||
27 | SELF_KW 4 "self" | ||
28 | WHITESPACE 1 " " | ||
29 | SUPER_KW 5 "super" | ||
30 | WHITESPACE 1 " " | ||
31 | IN_KW 2 "in" | ||
32 | WHITESPACE 1 " " | ||
33 | WHERE_KW 5 "where" | ||
34 | WHITESPACE 1 " " | ||
35 | FOR_KW 3 "for" | ||
36 | WHITESPACE 1 " " | ||
37 | LOOP_KW 4 "loop" | ||
38 | WHITESPACE 1 " " | ||
39 | WHILE_KW 5 "while" | ||
40 | WHITESPACE 1 " " | ||
41 | IF_KW 2 "if" | ||
42 | WHITESPACE 1 " " | ||
43 | MATCH_KW 5 "match" | ||
44 | WHITESPACE 1 " " | ||
45 | CONST_KW 5 "const" | ||
46 | WHITESPACE 1 "\n" | ||
47 | STATIC_KW 6 "static" | ||
48 | WHITESPACE 1 " " | ||
49 | MUT_KW 3 "mut" | ||
50 | WHITESPACE 1 " " | ||
51 | TYPE_KW 4 "type" | ||
52 | WHITESPACE 1 " " | ||
53 | REF_KW 3 "ref" | ||
54 | WHITESPACE 1 " " | ||
55 | LET_KW 3 "let" | ||
56 | WHITESPACE 1 " " | ||
57 | ELSE_KW 4 "else" | ||
58 | WHITESPACE 1 " " | ||
59 | MOVE_KW 4 "move" | ||
60 | WHITESPACE 1 " " | ||
61 | RETURN_KW 6 "return" | ||
62 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0013_raw_strings.rs b/crates/ra_syntax/tests/data/lexer/0013_raw_strings.rs new file mode 100644 index 000000000..e5ed0b693 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0013_raw_strings.rs | |||
@@ -0,0 +1 @@ | |||
r###"this is a r##"raw"## string"### | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0013_raw_strings.txt b/crates/ra_syntax/tests/data/lexer/0013_raw_strings.txt new file mode 100644 index 000000000..9cf0957d1 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0013_raw_strings.txt | |||
@@ -0,0 +1,2 @@ | |||
1 | RAW_STRING 36 "r###\"this is a r##\"raw\"## string\"###" | ||
2 | WHITESPACE 1 "\n" | ||
diff --git a/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.rs b/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.rs new file mode 100644 index 000000000..9c0007077 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.rs | |||
@@ -0,0 +1 @@ | |||
'1 \ No newline at end of file | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.txt b/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.txt new file mode 100644 index 000000000..812dfbc18 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0014_unclosed_char.txt | |||
@@ -0,0 +1 @@ | |||
CHAR 2 "\'1" | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.rs b/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.rs new file mode 100644 index 000000000..d771a26d4 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.rs | |||
@@ -0,0 +1 @@ | |||
"hello | |||
diff --git a/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.txt b/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.txt new file mode 100644 index 000000000..728c40b66 --- /dev/null +++ b/crates/ra_syntax/tests/data/lexer/0015_unclosed_string.txt | |||
@@ -0,0 +1 @@ | |||
STRING 7 "\"hello\n" | |||
diff --git a/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.rs b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.rs new file mode 100644 index 000000000..fe5030d89 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | struct S { | ||
2 | a: u32 | ||
3 | b: u32 | ||
4 | } \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt new file mode 100644 index 000000000..aa375fe8a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0000_struct_field_missing_comma.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | ROOT@[0; 34) | ||
2 | STRUCT_DEF@[0; 34) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | WHITESPACE@[8; 9) | ||
8 | NAMED_FIELD_DEF_LIST@[9; 34) | ||
9 | L_CURLY@[9; 10) | ||
10 | WHITESPACE@[10; 15) | ||
11 | NAMED_FIELD_DEF@[15; 21) | ||
12 | NAME@[15; 16) | ||
13 | IDENT@[15; 16) "a" | ||
14 | COLON@[16; 17) | ||
15 | WHITESPACE@[17; 18) | ||
16 | PATH_TYPE@[18; 21) | ||
17 | PATH@[18; 21) | ||
18 | PATH_SEGMENT@[18; 21) | ||
19 | NAME_REF@[18; 21) | ||
20 | IDENT@[18; 21) "u32" | ||
21 | err: `expected COMMA` | ||
22 | WHITESPACE@[21; 26) | ||
23 | NAMED_FIELD_DEF@[26; 32) | ||
24 | NAME@[26; 27) | ||
25 | IDENT@[26; 27) "b" | ||
26 | COLON@[27; 28) | ||
27 | WHITESPACE@[28; 29) | ||
28 | PATH_TYPE@[29; 32) | ||
29 | PATH@[29; 32) | ||
30 | PATH_SEGMENT@[29; 32) | ||
31 | NAME_REF@[29; 32) | ||
32 | IDENT@[29; 32) "u32" | ||
33 | WHITESPACE@[32; 33) | ||
34 | R_CURLY@[33; 34) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.rs b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.rs new file mode 100644 index 000000000..98f23de1f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | if match | ||
2 | |||
3 | struct S {} \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt new file mode 100644 index 000000000..771d6e1ef --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0001_item_recovery_in_file.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | ROOT@[0; 21) | ||
2 | ERROR@[0; 2) | ||
3 | IF_KW@[0; 2) | ||
4 | err: `expected an item` | ||
5 | WHITESPACE@[2; 3) | ||
6 | err: `expected an item` | ||
7 | ERROR@[3; 8) | ||
8 | MATCH_KW@[3; 8) | ||
9 | WHITESPACE@[8; 10) | ||
10 | STRUCT_DEF@[10; 21) | ||
11 | STRUCT_KW@[10; 16) | ||
12 | WHITESPACE@[16; 17) | ||
13 | NAME@[17; 18) | ||
14 | IDENT@[17; 18) "S" | ||
15 | WHITESPACE@[18; 19) | ||
16 | NAMED_FIELD_DEF_LIST@[19; 21) | ||
17 | L_CURLY@[19; 20) | ||
18 | R_CURLY@[20; 21) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.rs b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.rs new file mode 100644 index 000000000..48a3a3980 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | #!/use/bin/env rusti | ||
2 | #!/use/bin/env rusti | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt new file mode 100644 index 000000000..57fb48420 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0002_duplicate_shebang.txt | |||
@@ -0,0 +1,7 @@ | |||
1 | ROOT@[0; 42) | ||
2 | SHEBANG@[0; 20) | ||
3 | WHITESPACE@[20; 21) | ||
4 | err: `expected an item` | ||
5 | ERROR@[21; 41) | ||
6 | SHEBANG@[21; 41) | ||
7 | WHITESPACE@[41; 42) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.rs b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.rs new file mode 100644 index 000000000..009312270 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | struct S { | ||
2 | a: i32, | ||
3 | b: String, | ||
4 | }; \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt new file mode 100644 index 000000000..b51c0573a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0003_C++_semicolon.txt | |||
@@ -0,0 +1,39 @@ | |||
1 | ROOT@[0; 40) | ||
2 | STRUCT_DEF@[0; 40) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | WHITESPACE@[8; 9) | ||
8 | NAMED_FIELD_DEF_LIST@[9; 39) | ||
9 | L_CURLY@[9; 10) | ||
10 | WHITESPACE@[10; 15) | ||
11 | NAMED_FIELD_DEF@[15; 21) | ||
12 | NAME@[15; 16) | ||
13 | IDENT@[15; 16) "a" | ||
14 | COLON@[16; 17) | ||
15 | WHITESPACE@[17; 18) | ||
16 | PATH_TYPE@[18; 21) | ||
17 | PATH@[18; 21) | ||
18 | PATH_SEGMENT@[18; 21) | ||
19 | NAME_REF@[18; 21) | ||
20 | IDENT@[18; 21) "i32" | ||
21 | COMMA@[21; 22) | ||
22 | WHITESPACE@[22; 27) | ||
23 | NAMED_FIELD_DEF@[27; 36) | ||
24 | NAME@[27; 28) | ||
25 | IDENT@[27; 28) "b" | ||
26 | COLON@[28; 29) | ||
27 | WHITESPACE@[29; 30) | ||
28 | PATH_TYPE@[30; 36) | ||
29 | PATH@[30; 36) | ||
30 | PATH_SEGMENT@[30; 36) | ||
31 | NAME_REF@[30; 36) | ||
32 | IDENT@[30; 36) "String" | ||
33 | COMMA@[36; 37) | ||
34 | WHITESPACE@[37; 38) | ||
35 | R_CURLY@[38; 39) | ||
36 | err: `expected item, found `;` | ||
37 | consider removing this semicolon` | ||
38 | ERROR@[39; 40) | ||
39 | SEMI@[39; 40) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.rs b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.rs new file mode 100644 index 000000000..060e65d06 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.rs | |||
@@ -0,0 +1 @@ | |||
use foo::92; \ No newline at end of file | |||
diff --git a/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt new file mode 100644 index 000000000..646c84534 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0004_use_path_bad_segment.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | ROOT@[0; 12) | ||
2 | USE_ITEM@[0; 12) | ||
3 | USE_KW@[0; 3) | ||
4 | WHITESPACE@[3; 4) | ||
5 | USE_TREE@[4; 11) | ||
6 | PATH@[4; 11) | ||
7 | PATH@[4; 7) | ||
8 | PATH_SEGMENT@[4; 7) | ||
9 | NAME_REF@[4; 7) | ||
10 | IDENT@[4; 7) "foo" | ||
11 | COLONCOLON@[7; 9) | ||
12 | err: `expected identifier` | ||
13 | PATH_SEGMENT@[9; 11) | ||
14 | ERROR@[9; 11) | ||
15 | INT_NUMBER@[9; 11) "92" | ||
16 | SEMI@[11; 12) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.rs b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.rs new file mode 100644 index 000000000..de7f81628 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | #[foo(foo, +, 92)] | ||
2 | fn foo() { | ||
3 | } | ||
4 | |||
5 | |||
6 | #[foo( | ||
7 | fn foo() { | ||
8 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt new file mode 100644 index 000000000..b3cf9b889 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0005_attribute_recover.txt | |||
@@ -0,0 +1,55 @@ | |||
1 | ROOT@[0; 54) | ||
2 | FN_DEF@[0; 31) | ||
3 | ATTR@[0; 18) | ||
4 | POUND@[0; 1) | ||
5 | TOKEN_TREE@[1; 18) | ||
6 | L_BRACK@[1; 2) | ||
7 | IDENT@[2; 5) "foo" | ||
8 | TOKEN_TREE@[5; 17) | ||
9 | L_PAREN@[5; 6) | ||
10 | IDENT@[6; 9) "foo" | ||
11 | COMMA@[9; 10) | ||
12 | WHITESPACE@[10; 11) | ||
13 | PLUS@[11; 12) | ||
14 | COMMA@[12; 13) | ||
15 | WHITESPACE@[13; 14) | ||
16 | INT_NUMBER@[14; 16) "92" | ||
17 | R_PAREN@[16; 17) | ||
18 | R_BRACK@[17; 18) | ||
19 | WHITESPACE@[18; 19) | ||
20 | FN_KW@[19; 21) | ||
21 | WHITESPACE@[21; 22) | ||
22 | NAME@[22; 25) | ||
23 | IDENT@[22; 25) "foo" | ||
24 | PARAM_LIST@[25; 27) | ||
25 | L_PAREN@[25; 26) | ||
26 | R_PAREN@[26; 27) | ||
27 | WHITESPACE@[27; 28) | ||
28 | BLOCK@[28; 31) | ||
29 | L_CURLY@[28; 29) | ||
30 | WHITESPACE@[29; 30) | ||
31 | R_CURLY@[30; 31) | ||
32 | WHITESPACE@[31; 34) | ||
33 | ATTR@[34; 53) | ||
34 | POUND@[34; 35) | ||
35 | TOKEN_TREE@[35; 53) | ||
36 | L_BRACK@[35; 36) | ||
37 | IDENT@[36; 39) "foo" | ||
38 | TOKEN_TREE@[39; 53) | ||
39 | L_PAREN@[39; 40) | ||
40 | WHITESPACE@[40; 41) | ||
41 | FN_KW@[41; 43) | ||
42 | WHITESPACE@[43; 44) | ||
43 | IDENT@[44; 47) "foo" | ||
44 | TOKEN_TREE@[47; 49) | ||
45 | L_PAREN@[47; 48) | ||
46 | R_PAREN@[48; 49) | ||
47 | WHITESPACE@[49; 50) | ||
48 | TOKEN_TREE@[50; 53) | ||
49 | L_CURLY@[50; 51) | ||
50 | WHITESPACE@[51; 52) | ||
51 | R_CURLY@[52; 53) | ||
52 | err: `expected R_PAREN` | ||
53 | err: `expected R_BRACK` | ||
54 | err: `expected an item` | ||
55 | WHITESPACE@[53; 54) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.rs b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.rs new file mode 100644 index 000000000..8069c111b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | struct S { | ||
2 | f: u32, | ||
3 | pub 92 | ||
4 | + - * | ||
5 | pub x: u32, | ||
6 | z: f64, | ||
7 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt new file mode 100644 index 000000000..9abda7099 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0006_named_field_recovery.txt | |||
@@ -0,0 +1,74 @@ | |||
1 | ROOT@[0; 74) | ||
2 | STRUCT_DEF@[0; 73) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | WHITESPACE@[8; 9) | ||
8 | NAMED_FIELD_DEF_LIST@[9; 73) | ||
9 | L_CURLY@[9; 10) | ||
10 | WHITESPACE@[10; 15) | ||
11 | NAMED_FIELD_DEF@[15; 21) | ||
12 | NAME@[15; 16) | ||
13 | IDENT@[15; 16) "f" | ||
14 | COLON@[16; 17) | ||
15 | WHITESPACE@[17; 18) | ||
16 | PATH_TYPE@[18; 21) | ||
17 | PATH@[18; 21) | ||
18 | PATH_SEGMENT@[18; 21) | ||
19 | NAME_REF@[18; 21) | ||
20 | IDENT@[18; 21) "u32" | ||
21 | COMMA@[21; 22) | ||
22 | WHITESPACE@[22; 27) | ||
23 | VISIBILITY@[27; 30) | ||
24 | PUB_KW@[27; 30) | ||
25 | WHITESPACE@[30; 31) | ||
26 | err: `expected field declaration` | ||
27 | ERROR@[31; 33) | ||
28 | INT_NUMBER@[31; 33) "92" | ||
29 | err: `expected COMMA` | ||
30 | WHITESPACE@[33; 38) | ||
31 | err: `expected field declaration` | ||
32 | ERROR@[38; 39) | ||
33 | PLUS@[38; 39) | ||
34 | err: `expected COMMA` | ||
35 | WHITESPACE@[39; 40) | ||
36 | err: `expected field declaration` | ||
37 | ERROR@[40; 41) | ||
38 | MINUS@[40; 41) | ||
39 | err: `expected COMMA` | ||
40 | WHITESPACE@[41; 42) | ||
41 | err: `expected field declaration` | ||
42 | ERROR@[42; 43) | ||
43 | STAR@[42; 43) | ||
44 | err: `expected COMMA` | ||
45 | WHITESPACE@[43; 48) | ||
46 | NAMED_FIELD_DEF@[48; 58) | ||
47 | VISIBILITY@[48; 51) | ||
48 | PUB_KW@[48; 51) | ||
49 | WHITESPACE@[51; 52) | ||
50 | NAME@[52; 53) | ||
51 | IDENT@[52; 53) "x" | ||
52 | COLON@[53; 54) | ||
53 | WHITESPACE@[54; 55) | ||
54 | PATH_TYPE@[55; 58) | ||
55 | PATH@[55; 58) | ||
56 | PATH_SEGMENT@[55; 58) | ||
57 | NAME_REF@[55; 58) | ||
58 | IDENT@[55; 58) "u32" | ||
59 | COMMA@[58; 59) | ||
60 | WHITESPACE@[59; 64) | ||
61 | NAMED_FIELD_DEF@[64; 70) | ||
62 | NAME@[64; 65) | ||
63 | IDENT@[64; 65) "z" | ||
64 | COLON@[65; 66) | ||
65 | WHITESPACE@[66; 67) | ||
66 | PATH_TYPE@[67; 70) | ||
67 | PATH@[67; 70) | ||
68 | PATH_SEGMENT@[67; 70) | ||
69 | NAME_REF@[67; 70) | ||
70 | IDENT@[67; 70) "f64" | ||
71 | COMMA@[70; 71) | ||
72 | WHITESPACE@[71; 72) | ||
73 | R_CURLY@[72; 73) | ||
74 | WHITESPACE@[73; 74) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.rs b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.rs new file mode 100644 index 000000000..dc869fb78 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.rs | |||
@@ -0,0 +1,9 @@ | |||
1 | } | ||
2 | |||
3 | struct S; | ||
4 | |||
5 | } | ||
6 | |||
7 | fn foo(){} | ||
8 | |||
9 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt new file mode 100644 index 000000000..802c69b31 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0007_stray_curly_in_file.txt | |||
@@ -0,0 +1,32 @@ | |||
1 | ROOT@[0; 31) | ||
2 | ERROR@[0; 1) | ||
3 | R_CURLY@[0; 1) | ||
4 | err: `unmatched `}`` | ||
5 | WHITESPACE@[1; 3) | ||
6 | STRUCT_DEF@[3; 12) | ||
7 | STRUCT_KW@[3; 9) | ||
8 | WHITESPACE@[9; 10) | ||
9 | NAME@[10; 11) | ||
10 | IDENT@[10; 11) "S" | ||
11 | SEMI@[11; 12) | ||
12 | WHITESPACE@[12; 14) | ||
13 | err: `unmatched `}`` | ||
14 | ERROR@[14; 15) | ||
15 | R_CURLY@[14; 15) | ||
16 | WHITESPACE@[15; 17) | ||
17 | FN_DEF@[17; 27) | ||
18 | FN_KW@[17; 19) | ||
19 | WHITESPACE@[19; 20) | ||
20 | NAME@[20; 23) | ||
21 | IDENT@[20; 23) "foo" | ||
22 | PARAM_LIST@[23; 25) | ||
23 | L_PAREN@[23; 24) | ||
24 | R_PAREN@[24; 25) | ||
25 | BLOCK@[25; 27) | ||
26 | L_CURLY@[25; 26) | ||
27 | R_CURLY@[26; 27) | ||
28 | WHITESPACE@[27; 29) | ||
29 | err: `unmatched `}`` | ||
30 | ERROR@[29; 30) | ||
31 | R_CURLY@[29; 30) | ||
32 | WHITESPACE@[30; 31) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.rs b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.rs new file mode 100644 index 000000000..9fcac19b5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.rs | |||
@@ -0,0 +1,13 @@ | |||
1 | fn foo() { | ||
2 | } | ||
3 | |||
4 | bar() { | ||
5 | if true { | ||
6 | 1 | ||
7 | } else { | ||
8 | 2 + 3 | ||
9 | } | ||
10 | } | ||
11 | |||
12 | fn baz() { | ||
13 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt new file mode 100644 index 000000000..95a34333b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0008_item_block_recovery.txt | |||
@@ -0,0 +1,70 @@ | |||
1 | ROOT@[0; 95) | ||
2 | FN_DEF@[0; 12) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 12) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 11) | ||
14 | R_CURLY@[11; 12) | ||
15 | WHITESPACE@[12; 14) | ||
16 | MACRO_CALL@[14; 19) | ||
17 | PATH@[14; 17) | ||
18 | PATH_SEGMENT@[14; 17) | ||
19 | NAME_REF@[14; 17) | ||
20 | IDENT@[14; 17) "bar" | ||
21 | err: `expected EXCL` | ||
22 | TOKEN_TREE@[17; 19) | ||
23 | L_PAREN@[17; 18) | ||
24 | R_PAREN@[18; 19) | ||
25 | err: `expected SEMI` | ||
26 | WHITESPACE@[19; 20) | ||
27 | err: `expected an item` | ||
28 | ERROR@[20; 80) | ||
29 | L_CURLY@[20; 21) | ||
30 | WHITESPACE@[21; 26) | ||
31 | IF_KW@[26; 28) | ||
32 | WHITESPACE@[28; 29) | ||
33 | TRUE_KW@[29; 33) | ||
34 | WHITESPACE@[33; 34) | ||
35 | ERROR@[34; 51) | ||
36 | L_CURLY@[34; 35) | ||
37 | WHITESPACE@[35; 44) | ||
38 | INT_NUMBER@[44; 45) "1" | ||
39 | WHITESPACE@[45; 50) | ||
40 | R_CURLY@[50; 51) | ||
41 | WHITESPACE@[51; 52) | ||
42 | ELSE_KW@[52; 56) | ||
43 | WHITESPACE@[56; 57) | ||
44 | ERROR@[57; 78) | ||
45 | L_CURLY@[57; 58) | ||
46 | WHITESPACE@[58; 67) | ||
47 | INT_NUMBER@[67; 68) "2" | ||
48 | WHITESPACE@[68; 69) | ||
49 | PLUS@[69; 70) | ||
50 | WHITESPACE@[70; 71) | ||
51 | INT_NUMBER@[71; 72) "3" | ||
52 | WHITESPACE@[72; 77) | ||
53 | R_CURLY@[77; 78) | ||
54 | WHITESPACE@[78; 79) | ||
55 | R_CURLY@[79; 80) | ||
56 | WHITESPACE@[80; 82) | ||
57 | FN_DEF@[82; 94) | ||
58 | FN_KW@[82; 84) | ||
59 | WHITESPACE@[84; 85) | ||
60 | NAME@[85; 88) | ||
61 | IDENT@[85; 88) "baz" | ||
62 | PARAM_LIST@[88; 90) | ||
63 | L_PAREN@[88; 89) | ||
64 | R_PAREN@[89; 90) | ||
65 | WHITESPACE@[90; 91) | ||
66 | BLOCK@[91; 94) | ||
67 | L_CURLY@[91; 92) | ||
68 | WHITESPACE@[92; 93) | ||
69 | R_CURLY@[93; 94) | ||
70 | WHITESPACE@[94; 95) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.rs b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.rs new file mode 100644 index 000000000..0dd30d0bd --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | struct S<90 + 2> { | ||
2 | f: u32 | ||
3 | } | ||
4 | |||
5 | struct T; | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt new file mode 100644 index 000000000..fa8adf881 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0009_broken_struct_type_parameter.txt | |||
@@ -0,0 +1,44 @@ | |||
1 | ROOT@[0; 43) | ||
2 | STRUCT_DEF@[0; 11) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | TYPE_PARAM_LIST@[8; 11) | ||
8 | L_ANGLE@[8; 9) | ||
9 | err: `expected type parameter` | ||
10 | ERROR@[9; 11) | ||
11 | INT_NUMBER@[9; 11) "90" | ||
12 | err: `expected COMMA` | ||
13 | err: `expected R_ANGLE` | ||
14 | err: `expected `;`, `{`, or `(`` | ||
15 | WHITESPACE@[11; 12) | ||
16 | err: `expected an item` | ||
17 | ERROR@[12; 13) | ||
18 | PLUS@[12; 13) | ||
19 | WHITESPACE@[13; 14) | ||
20 | err: `expected an item` | ||
21 | ERROR@[14; 15) | ||
22 | INT_NUMBER@[14; 15) "2" | ||
23 | err: `expected an item` | ||
24 | ERROR@[15; 16) | ||
25 | R_ANGLE@[15; 16) | ||
26 | WHITESPACE@[16; 17) | ||
27 | err: `expected an item` | ||
28 | ERROR@[17; 31) | ||
29 | L_CURLY@[17; 18) | ||
30 | WHITESPACE@[18; 23) | ||
31 | IDENT@[23; 24) "f" | ||
32 | COLON@[24; 25) | ||
33 | WHITESPACE@[25; 26) | ||
34 | IDENT@[26; 29) "u32" | ||
35 | WHITESPACE@[29; 30) | ||
36 | R_CURLY@[30; 31) | ||
37 | WHITESPACE@[31; 33) | ||
38 | STRUCT_DEF@[33; 42) | ||
39 | STRUCT_KW@[33; 39) | ||
40 | WHITESPACE@[39; 40) | ||
41 | NAME@[40; 41) | ||
42 | IDENT@[40; 41) "T" | ||
43 | SEMI@[41; 42) | ||
44 | WHITESPACE@[42; 43) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.rs b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.rs new file mode 100644 index 000000000..985775282 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn main() { | ||
2 | || -> () unsafe { () }; | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt new file mode 100644 index 000000000..38667e030 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0010_unsafe_lambda_block.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | ROOT@[0; 42) | ||
2 | FN_DEF@[0; 41) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 41) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | EXPR_STMT@[16; 39) | ||
15 | LAMBDA_EXPR@[16; 38) | ||
16 | PARAM_LIST@[16; 18) | ||
17 | PIPE@[16; 17) | ||
18 | PIPE@[17; 18) | ||
19 | WHITESPACE@[18; 19) | ||
20 | RET_TYPE@[19; 24) | ||
21 | THIN_ARROW@[19; 21) | ||
22 | WHITESPACE@[21; 22) | ||
23 | TUPLE_TYPE@[22; 24) | ||
24 | L_PAREN@[22; 23) | ||
25 | R_PAREN@[23; 24) | ||
26 | err: `expected `{`` | ||
27 | WHITESPACE@[24; 25) | ||
28 | BLOCK_EXPR@[25; 38) | ||
29 | UNSAFE_KW@[25; 31) | ||
30 | WHITESPACE@[31; 32) | ||
31 | BLOCK@[32; 38) | ||
32 | L_CURLY@[32; 33) | ||
33 | WHITESPACE@[33; 34) | ||
34 | TUPLE_EXPR@[34; 36) | ||
35 | L_PAREN@[34; 35) | ||
36 | R_PAREN@[35; 36) | ||
37 | WHITESPACE@[36; 37) | ||
38 | R_CURLY@[37; 38) | ||
39 | SEMI@[38; 39) | ||
40 | WHITESPACE@[39; 40) | ||
41 | R_CURLY@[40; 41) | ||
42 | WHITESPACE@[41; 42) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.rs b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.rs new file mode 100644 index 000000000..c1bd0a2d1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.rs | |||
@@ -0,0 +1 @@ | |||
extern struct Foo; | |||
diff --git a/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt new file mode 100644 index 000000000..0cb7447c4 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0011_extern_struct.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | ROOT@[0; 19) | ||
2 | ERROR@[0; 6) | ||
3 | ABI@[0; 6) | ||
4 | EXTERN_KW@[0; 6) | ||
5 | err: `expected fn, trait or impl` | ||
6 | WHITESPACE@[6; 7) | ||
7 | STRUCT_DEF@[7; 18) | ||
8 | STRUCT_KW@[7; 13) | ||
9 | WHITESPACE@[13; 14) | ||
10 | NAME@[14; 17) | ||
11 | IDENT@[14; 17) "Foo" | ||
12 | SEMI@[17; 18) | ||
13 | WHITESPACE@[18; 19) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0012_broken_lambda.txt b/crates/ra_syntax/tests/data/parser/err/0012_broken_lambda.txt new file mode 100644 index 000000000..a03aa05e3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0012_broken_lambda.txt | |||
@@ -0,0 +1,387 @@ | |||
1 | ROOT@[0; 389) | ||
2 | FN_DEF@[0; 389) | ||
3 | VISIBILITY@[0; 10) | ||
4 | PUB_KW@[0; 3) | ||
5 | L_PAREN@[3; 4) | ||
6 | SUPER_KW@[4; 9) | ||
7 | R_PAREN@[9; 10) | ||
8 | WHITESPACE@[10; 11) | ||
9 | FN_KW@[11; 13) | ||
10 | WHITESPACE@[13; 14) | ||
11 | NAME@[14; 21) | ||
12 | IDENT@[14; 21) "process" | ||
13 | TYPE_PARAM_LIST@[21; 38) | ||
14 | L_ANGLE@[21; 22) | ||
15 | LIFETIME_PARAM@[22; 24) | ||
16 | LIFETIME@[22; 24) "'a" | ||
17 | COMMA@[24; 25) | ||
18 | WHITESPACE@[25; 26) | ||
19 | TYPE_PARAM@[26; 37) | ||
20 | NAME@[26; 27) | ||
21 | IDENT@[26; 27) "S" | ||
22 | COLON@[27; 28) | ||
23 | WHITESPACE@[28; 29) | ||
24 | PATH@[29; 37) | ||
25 | PATH_SEGMENT@[29; 37) | ||
26 | NAME_REF@[29; 33) | ||
27 | IDENT@[29; 33) "Sink" | ||
28 | TYPE_ARG_LIST@[33; 37) | ||
29 | L_ANGLE@[33; 34) | ||
30 | LIFETIME_ARG@[34; 36) | ||
31 | LIFETIME@[34; 36) "'a" | ||
32 | R_ANGLE@[36; 37) | ||
33 | R_ANGLE@[37; 38) | ||
34 | PARAM_LIST@[38; 93) | ||
35 | L_PAREN@[38; 39) | ||
36 | PARAM@[39; 54) | ||
37 | BIND_PAT@[39; 46) | ||
38 | NAME@[39; 46) | ||
39 | IDENT@[39; 46) "builder" | ||
40 | COLON@[46; 47) | ||
41 | WHITESPACE@[47; 48) | ||
42 | REFERENCE_TYPE@[48; 54) | ||
43 | AMP@[48; 49) | ||
44 | MUT_KW@[49; 52) | ||
45 | WHITESPACE@[52; 53) | ||
46 | PATH_TYPE@[53; 54) | ||
47 | PATH@[53; 54) | ||
48 | PATH_SEGMENT@[53; 54) | ||
49 | NAME_REF@[53; 54) | ||
50 | IDENT@[53; 54) "S" | ||
51 | COMMA@[54; 55) | ||
52 | WHITESPACE@[55; 56) | ||
53 | PARAM@[56; 72) | ||
54 | BIND_PAT@[56; 62) | ||
55 | NAME@[56; 62) | ||
56 | IDENT@[56; 62) "tokens" | ||
57 | COLON@[62; 63) | ||
58 | WHITESPACE@[63; 64) | ||
59 | REFERENCE_TYPE@[64; 72) | ||
60 | AMP@[64; 65) | ||
61 | SLICE_TYPE@[65; 72) | ||
62 | L_BRACK@[65; 66) | ||
63 | PATH_TYPE@[66; 71) | ||
64 | PATH@[66; 71) | ||
65 | PATH_SEGMENT@[66; 71) | ||
66 | NAME_REF@[66; 71) | ||
67 | IDENT@[66; 71) "Token" | ||
68 | R_BRACK@[71; 72) | ||
69 | COMMA@[72; 73) | ||
70 | WHITESPACE@[73; 74) | ||
71 | PARAM@[74; 92) | ||
72 | BIND_PAT@[74; 80) | ||
73 | NAME@[74; 80) | ||
74 | IDENT@[74; 80) "events" | ||
75 | COLON@[80; 81) | ||
76 | WHITESPACE@[81; 82) | ||
77 | PATH_TYPE@[82; 92) | ||
78 | PATH@[82; 92) | ||
79 | PATH_SEGMENT@[82; 92) | ||
80 | NAME_REF@[82; 85) | ||
81 | IDENT@[82; 85) "Vec" | ||
82 | TYPE_ARG_LIST@[85; 92) | ||
83 | L_ANGLE@[85; 86) | ||
84 | TYPE_ARG@[86; 91) | ||
85 | PATH_TYPE@[86; 91) | ||
86 | PATH@[86; 91) | ||
87 | PATH_SEGMENT@[86; 91) | ||
88 | NAME_REF@[86; 91) | ||
89 | IDENT@[86; 91) "Event" | ||
90 | R_ANGLE@[91; 92) | ||
91 | R_PAREN@[92; 93) | ||
92 | WHITESPACE@[93; 94) | ||
93 | BLOCK_EXPR@[94; 389) | ||
94 | L_CURLY@[94; 95) | ||
95 | WHITESPACE@[95; 100) | ||
96 | LET_STMT@[100; 125) | ||
97 | LET_KW@[100; 103) | ||
98 | WHITESPACE@[103; 104) | ||
99 | BIND_PAT@[104; 120) | ||
100 | MUT_KW@[104; 107) | ||
101 | WHITESPACE@[107; 108) | ||
102 | NAME@[108; 120) | ||
103 | IDENT@[108; 120) "next_tok_idx" | ||
104 | WHITESPACE@[120; 121) | ||
105 | EQ@[121; 122) | ||
106 | WHITESPACE@[122; 123) | ||
107 | LITERAL@[123; 124) | ||
108 | INT_NUMBER@[123; 124) "0" | ||
109 | SEMI@[124; 125) | ||
110 | WHITESPACE@[125; 130) | ||
111 | LET_STMT@[130; 389) | ||
112 | LET_KW@[130; 133) | ||
113 | WHITESPACE@[133; 134) | ||
114 | BIND_PAT@[134; 140) | ||
115 | NAME@[134; 140) | ||
116 | IDENT@[134; 140) "eat_ws" | ||
117 | WHITESPACE@[140; 141) | ||
118 | EQ@[141; 142) | ||
119 | WHITESPACE@[142; 143) | ||
120 | LAMBDA_EXPR@[143; 389) | ||
121 | PARAM_LIST@[143; 388) | ||
122 | PIPE@[143; 144) | ||
123 | PARAM@[144; 159) | ||
124 | BIND_PAT@[144; 147) | ||
125 | NAME@[144; 147) | ||
126 | IDENT@[144; 147) "idx" | ||
127 | COLON@[147; 148) | ||
128 | WHITESPACE@[148; 149) | ||
129 | REFERENCE_TYPE@[149; 159) | ||
130 | AMP@[149; 150) | ||
131 | MUT_KW@[150; 153) | ||
132 | WHITESPACE@[153; 154) | ||
133 | PATH_TYPE@[154; 159) | ||
134 | PATH@[154; 159) | ||
135 | PATH_SEGMENT@[154; 159) | ||
136 | NAME_REF@[154; 159) | ||
137 | IDENT@[154; 159) "usize" | ||
138 | COMMA@[159; 160) | ||
139 | WHITESPACE@[160; 161) | ||
140 | PARAM@[161; 167) | ||
141 | REF_PAT@[161; 167) | ||
142 | AMP@[161; 162) | ||
143 | MUT_KW@[162; 165) | ||
144 | WHITESPACE@[165; 166) | ||
145 | err: `expected pattern` | ||
146 | ERROR@[166; 167) | ||
147 | PIPE@[166; 167) | ||
148 | err: `expected COMMA` | ||
149 | WHITESPACE@[167; 168) | ||
150 | err: `expected pattern` | ||
151 | PARAM@[168; 169) | ||
152 | ERROR@[168; 169) | ||
153 | L_CURLY@[168; 169) | ||
154 | err: `expected COMMA` | ||
155 | WHITESPACE@[169; 178) | ||
156 | err: `expected pattern` | ||
157 | PARAM@[178; 183) | ||
158 | ERROR@[178; 183) | ||
159 | WHILE_KW@[178; 183) | ||
160 | err: `expected COMMA` | ||
161 | WHITESPACE@[183; 184) | ||
162 | err: `expected pattern` | ||
163 | PARAM@[184; 187) | ||
164 | ERROR@[184; 187) | ||
165 | LET_KW@[184; 187) | ||
166 | err: `expected COMMA` | ||
167 | WHITESPACE@[187; 188) | ||
168 | PARAM@[188; 199) | ||
169 | TUPLE_STRUCT_PAT@[188; 199) | ||
170 | PATH@[188; 192) | ||
171 | PATH_SEGMENT@[188; 192) | ||
172 | NAME_REF@[188; 192) | ||
173 | IDENT@[188; 192) "Some" | ||
174 | L_PAREN@[192; 193) | ||
175 | BIND_PAT@[193; 198) | ||
176 | NAME@[193; 198) | ||
177 | IDENT@[193; 198) "token" | ||
178 | R_PAREN@[198; 199) | ||
179 | err: `expected COMMA` | ||
180 | WHITESPACE@[199; 200) | ||
181 | err: `expected pattern` | ||
182 | PARAM@[200; 201) | ||
183 | ERROR@[200; 201) | ||
184 | EQ@[200; 201) | ||
185 | err: `expected COMMA` | ||
186 | WHITESPACE@[201; 202) | ||
187 | PARAM@[202; 208) | ||
188 | BIND_PAT@[202; 208) | ||
189 | NAME@[202; 208) | ||
190 | IDENT@[202; 208) "tokens" | ||
191 | err: `expected COMMA` | ||
192 | err: `expected pattern` | ||
193 | PARAM@[208; 209) | ||
194 | ERROR@[208; 209) | ||
195 | DOT@[208; 209) | ||
196 | err: `expected COMMA` | ||
197 | PARAM@[209; 218) | ||
198 | TUPLE_STRUCT_PAT@[209; 218) | ||
199 | PATH@[209; 212) | ||
200 | PATH_SEGMENT@[209; 212) | ||
201 | NAME_REF@[209; 212) | ||
202 | IDENT@[209; 212) "get" | ||
203 | L_PAREN@[212; 213) | ||
204 | err: `expected pattern` | ||
205 | ERROR@[213; 214) | ||
206 | STAR@[213; 214) | ||
207 | err: `expected COMMA` | ||
208 | BIND_PAT@[214; 217) | ||
209 | NAME@[214; 217) | ||
210 | IDENT@[214; 217) "idx" | ||
211 | R_PAREN@[217; 218) | ||
212 | err: `expected COMMA` | ||
213 | WHITESPACE@[218; 219) | ||
214 | err: `expected pattern` | ||
215 | PARAM@[219; 220) | ||
216 | ERROR@[219; 220) | ||
217 | L_CURLY@[219; 220) | ||
218 | err: `expected COMMA` | ||
219 | WHITESPACE@[220; 233) | ||
220 | err: `expected pattern` | ||
221 | PARAM@[233; 235) | ||
222 | ERROR@[233; 235) | ||
223 | IF_KW@[233; 235) | ||
224 | err: `expected COMMA` | ||
225 | WHITESPACE@[235; 236) | ||
226 | err: `expected pattern` | ||
227 | PARAM@[236; 237) | ||
228 | ERROR@[236; 237) | ||
229 | EXCL@[236; 237) | ||
230 | err: `expected COMMA` | ||
231 | PARAM@[237; 242) | ||
232 | BIND_PAT@[237; 242) | ||
233 | NAME@[237; 242) | ||
234 | IDENT@[237; 242) "token" | ||
235 | err: `expected COMMA` | ||
236 | err: `expected pattern` | ||
237 | PARAM@[242; 243) | ||
238 | ERROR@[242; 243) | ||
239 | DOT@[242; 243) | ||
240 | err: `expected COMMA` | ||
241 | PARAM@[243; 247) | ||
242 | BIND_PAT@[243; 247) | ||
243 | NAME@[243; 247) | ||
244 | IDENT@[243; 247) "kind" | ||
245 | err: `expected COMMA` | ||
246 | err: `expected pattern` | ||
247 | PARAM@[247; 248) | ||
248 | ERROR@[247; 248) | ||
249 | DOT@[247; 248) | ||
250 | err: `expected COMMA` | ||
251 | PARAM@[248; 259) | ||
252 | TUPLE_STRUCT_PAT@[248; 259) | ||
253 | PATH@[248; 257) | ||
254 | PATH_SEGMENT@[248; 257) | ||
255 | NAME_REF@[248; 257) | ||
256 | IDENT@[248; 257) "is_trivia" | ||
257 | L_PAREN@[257; 258) | ||
258 | R_PAREN@[258; 259) | ||
259 | err: `expected COMMA` | ||
260 | WHITESPACE@[259; 260) | ||
261 | err: `expected pattern` | ||
262 | PARAM@[260; 261) | ||
263 | ERROR@[260; 261) | ||
264 | L_CURLY@[260; 261) | ||
265 | err: `expected COMMA` | ||
266 | WHITESPACE@[261; 278) | ||
267 | PARAM@[278; 283) | ||
268 | BIND_PAT@[278; 283) | ||
269 | NAME@[278; 283) | ||
270 | IDENT@[278; 283) "break" | ||
271 | err: `expected COMMA` | ||
272 | err: `expected pattern` | ||
273 | PARAM@[283; 284) | ||
274 | ERROR@[283; 284) | ||
275 | SEMI@[283; 284) | ||
276 | err: `expected COMMA` | ||
277 | WHITESPACE@[284; 297) | ||
278 | err: `expected pattern` | ||
279 | PARAM@[297; 298) | ||
280 | ERROR@[297; 298) | ||
281 | R_CURLY@[297; 298) | ||
282 | err: `expected COMMA` | ||
283 | WHITESPACE@[298; 311) | ||
284 | PARAM@[311; 318) | ||
285 | BIND_PAT@[311; 318) | ||
286 | NAME@[311; 318) | ||
287 | IDENT@[311; 318) "builder" | ||
288 | err: `expected COMMA` | ||
289 | err: `expected pattern` | ||
290 | PARAM@[318; 319) | ||
291 | ERROR@[318; 319) | ||
292 | DOT@[318; 319) | ||
293 | err: `expected COMMA` | ||
294 | PARAM@[319; 346) | ||
295 | TUPLE_STRUCT_PAT@[319; 346) | ||
296 | PATH@[319; 323) | ||
297 | PATH_SEGMENT@[319; 323) | ||
298 | NAME_REF@[319; 323) | ||
299 | IDENT@[319; 323) "leaf" | ||
300 | L_PAREN@[323; 324) | ||
301 | BIND_PAT@[324; 329) | ||
302 | NAME@[324; 329) | ||
303 | IDENT@[324; 329) "token" | ||
304 | err: `expected COMMA` | ||
305 | err: `expected pattern` | ||
306 | ERROR@[329; 330) | ||
307 | DOT@[329; 330) | ||
308 | err: `expected COMMA` | ||
309 | BIND_PAT@[330; 334) | ||
310 | NAME@[330; 334) | ||
311 | IDENT@[330; 334) "kind" | ||
312 | COMMA@[334; 335) | ||
313 | WHITESPACE@[335; 336) | ||
314 | BIND_PAT@[336; 341) | ||
315 | NAME@[336; 341) | ||
316 | IDENT@[336; 341) "token" | ||
317 | err: `expected COMMA` | ||
318 | err: `expected pattern` | ||
319 | ERROR@[341; 342) | ||
320 | DOT@[341; 342) | ||
321 | err: `expected COMMA` | ||
322 | BIND_PAT@[342; 345) | ||
323 | NAME@[342; 345) | ||
324 | IDENT@[342; 345) "len" | ||
325 | R_PAREN@[345; 346) | ||
326 | err: `expected COMMA` | ||
327 | err: `expected pattern` | ||
328 | PARAM@[346; 347) | ||
329 | ERROR@[346; 347) | ||
330 | SEMI@[346; 347) | ||
331 | err: `expected COMMA` | ||
332 | WHITESPACE@[347; 360) | ||
333 | err: `expected pattern` | ||
334 | PARAM@[360; 361) | ||
335 | ERROR@[360; 361) | ||
336 | STAR@[360; 361) | ||
337 | err: `expected COMMA` | ||
338 | PARAM@[361; 364) | ||
339 | BIND_PAT@[361; 364) | ||
340 | NAME@[361; 364) | ||
341 | IDENT@[361; 364) "idx" | ||
342 | err: `expected COMMA` | ||
343 | WHITESPACE@[364; 365) | ||
344 | err: `expected pattern` | ||
345 | PARAM@[365; 366) | ||
346 | ERROR@[365; 366) | ||
347 | PLUS@[365; 366) | ||
348 | err: `expected COMMA` | ||
349 | err: `expected pattern` | ||
350 | PARAM@[366; 367) | ||
351 | ERROR@[366; 367) | ||
352 | EQ@[366; 367) | ||
353 | err: `expected COMMA` | ||
354 | WHITESPACE@[367; 368) | ||
355 | PARAM@[368; 369) | ||
356 | LITERAL@[368; 369) | ||
357 | INT_NUMBER@[368; 369) "1" | ||
358 | err: `expected COMMA` | ||
359 | WHITESPACE@[369; 378) | ||
360 | err: `expected pattern` | ||
361 | PARAM@[378; 379) | ||
362 | ERROR@[378; 379) | ||
363 | R_CURLY@[378; 379) | ||
364 | err: `expected COMMA` | ||
365 | WHITESPACE@[379; 384) | ||
366 | err: `expected pattern` | ||
367 | PARAM@[384; 385) | ||
368 | ERROR@[384; 385) | ||
369 | R_CURLY@[384; 385) | ||
370 | err: `expected COMMA` | ||
371 | err: `expected pattern` | ||
372 | PARAM@[385; 386) | ||
373 | ERROR@[385; 386) | ||
374 | SEMI@[385; 386) | ||
375 | err: `expected COMMA` | ||
376 | WHITESPACE@[386; 387) | ||
377 | err: `expected pattern` | ||
378 | PARAM@[387; 388) | ||
379 | ERROR@[387; 388) | ||
380 | R_CURLY@[387; 388) | ||
381 | err: `expected COMMA` | ||
382 | err: `expected PIPE` | ||
383 | WHITESPACE@[388; 389) | ||
384 | err: `expected expression` | ||
385 | err: `expected SEMI` | ||
386 | err: `expected R_CURLY` | ||
387 | ERROR@[389; 389) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.rs b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.rs new file mode 100644 index 000000000..20dde3bc3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | pub struct Cache( | ||
2 | RefCell<HashMap< | ||
3 | TypeId, | ||
4 | Box<@ Any>, | ||
5 | >> | ||
6 | ); | ||
7 | |||
diff --git a/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt new file mode 100644 index 000000000..e1a6b6432 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0013_invalid_type.txt | |||
@@ -0,0 +1,89 @@ | |||
1 | ROOT@[0; 86) | ||
2 | STRUCT_DEF@[0; 72) | ||
3 | VISIBILITY@[0; 3) | ||
4 | PUB_KW@[0; 3) | ||
5 | WHITESPACE@[3; 4) | ||
6 | STRUCT_KW@[4; 10) | ||
7 | WHITESPACE@[10; 11) | ||
8 | NAME@[11; 16) | ||
9 | IDENT@[11; 16) "Cache" | ||
10 | POS_FIELD_LIST@[16; 72) | ||
11 | L_PAREN@[16; 17) | ||
12 | WHITESPACE@[17; 22) | ||
13 | POS_FIELD@[22; 68) | ||
14 | PATH_TYPE@[22; 68) | ||
15 | PATH@[22; 68) | ||
16 | PATH_SEGMENT@[22; 68) | ||
17 | NAME_REF@[22; 29) | ||
18 | IDENT@[22; 29) "RefCell" | ||
19 | TYPE_ARG_LIST@[29; 68) | ||
20 | L_ANGLE@[29; 30) | ||
21 | TYPE_ARG@[30; 68) | ||
22 | PATH_TYPE@[30; 68) | ||
23 | PATH@[30; 68) | ||
24 | PATH_SEGMENT@[30; 68) | ||
25 | NAME_REF@[30; 37) | ||
26 | IDENT@[30; 37) "HashMap" | ||
27 | TYPE_ARG_LIST@[37; 68) | ||
28 | L_ANGLE@[37; 38) | ||
29 | WHITESPACE@[38; 47) | ||
30 | TYPE_ARG@[47; 53) | ||
31 | PATH_TYPE@[47; 53) | ||
32 | PATH@[47; 53) | ||
33 | PATH_SEGMENT@[47; 53) | ||
34 | NAME_REF@[47; 53) | ||
35 | IDENT@[47; 53) "TypeId" | ||
36 | COMMA@[53; 54) | ||
37 | WHITESPACE@[54; 63) | ||
38 | TYPE_ARG@[63; 68) | ||
39 | PATH_TYPE@[63; 68) | ||
40 | PATH@[63; 68) | ||
41 | PATH_SEGMENT@[63; 68) | ||
42 | NAME_REF@[63; 66) | ||
43 | IDENT@[63; 66) "Box" | ||
44 | TYPE_ARG_LIST@[66; 68) | ||
45 | L_ANGLE@[66; 67) | ||
46 | err: `expected type` | ||
47 | TYPE_ARG@[67; 68) | ||
48 | ERROR@[67; 68) | ||
49 | AT@[67; 68) | ||
50 | err: `expected COMMA` | ||
51 | err: `expected R_ANGLE` | ||
52 | err: `expected COMMA` | ||
53 | err: `expected R_ANGLE` | ||
54 | err: `expected COMMA` | ||
55 | err: `expected R_ANGLE` | ||
56 | err: `expected COMMA` | ||
57 | WHITESPACE@[68; 69) | ||
58 | POS_FIELD@[69; 72) | ||
59 | PATH_TYPE@[69; 72) | ||
60 | PATH@[69; 72) | ||
61 | PATH_SEGMENT@[69; 72) | ||
62 | NAME_REF@[69; 72) | ||
63 | IDENT@[69; 72) "Any" | ||
64 | err: `expected COMMA` | ||
65 | err: `expected a type` | ||
66 | err: `expected R_PAREN` | ||
67 | err: `expected SEMI` | ||
68 | err: `expected an item` | ||
69 | ERROR@[72; 72) | ||
70 | ERROR@[72; 73) | ||
71 | R_ANGLE@[72; 73) | ||
72 | err: `expected an item` | ||
73 | ERROR@[73; 74) | ||
74 | COMMA@[73; 74) | ||
75 | WHITESPACE@[74; 79) | ||
76 | err: `expected an item` | ||
77 | ERROR@[79; 80) | ||
78 | R_ANGLE@[79; 80) | ||
79 | err: `expected an item` | ||
80 | ERROR@[80; 81) | ||
81 | R_ANGLE@[80; 81) | ||
82 | WHITESPACE@[81; 82) | ||
83 | err: `expected an item` | ||
84 | ERROR@[82; 83) | ||
85 | R_PAREN@[82; 83) | ||
86 | err: `expected an item` | ||
87 | ERROR@[83; 84) | ||
88 | SEMI@[83; 84) | ||
89 | WHITESPACE@[84; 86) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.rs b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.rs new file mode 100644 index 000000000..75c1d2f98 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.rs | |||
@@ -0,0 +1 @@ | |||
fn foo<T>() where T {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt new file mode 100644 index 000000000..37826ce86 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0014_where_no_bounds.txt | |||
@@ -0,0 +1,31 @@ | |||
1 | ROOT@[0; 23) | ||
2 | FN_DEF@[0; 22) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | TYPE_PARAM_LIST@[6; 9) | ||
8 | L_ANGLE@[6; 7) | ||
9 | TYPE_PARAM@[7; 8) | ||
10 | NAME@[7; 8) | ||
11 | IDENT@[7; 8) "T" | ||
12 | R_ANGLE@[8; 9) | ||
13 | PARAM_LIST@[9; 11) | ||
14 | L_PAREN@[9; 10) | ||
15 | R_PAREN@[10; 11) | ||
16 | WHITESPACE@[11; 12) | ||
17 | WHERE_CLAUSE@[12; 19) | ||
18 | WHERE_KW@[12; 17) | ||
19 | WHITESPACE@[17; 18) | ||
20 | WHERE_PRED@[18; 19) | ||
21 | PATH_TYPE@[18; 19) | ||
22 | PATH@[18; 19) | ||
23 | PATH_SEGMENT@[18; 19) | ||
24 | NAME_REF@[18; 19) | ||
25 | IDENT@[18; 19) "T" | ||
26 | err: `expected colon` | ||
27 | WHITESPACE@[19; 20) | ||
28 | BLOCK@[20; 22) | ||
29 | L_CURLY@[20; 21) | ||
30 | R_CURLY@[21; 22) | ||
31 | WHITESPACE@[22; 23) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.rs b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.rs new file mode 100644 index 000000000..156e70251 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | fn foo(}) { | ||
2 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt new file mode 100644 index 000000000..5f736a978 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0015_curly_in_params.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | ROOT@[0; 14) | ||
2 | FN_DEF@[0; 7) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 7) | ||
8 | L_PAREN@[6; 7) | ||
9 | err: `expected value parameter` | ||
10 | err: `expected R_PAREN` | ||
11 | err: `expected a block` | ||
12 | err: `unmatched `}`` | ||
13 | ERROR@[7; 8) | ||
14 | R_CURLY@[7; 8) | ||
15 | err: `expected an item` | ||
16 | ERROR@[8; 9) | ||
17 | R_PAREN@[8; 9) | ||
18 | WHITESPACE@[9; 10) | ||
19 | err: `expected an item` | ||
20 | ERROR@[10; 13) | ||
21 | L_CURLY@[10; 11) | ||
22 | WHITESPACE@[11; 12) | ||
23 | R_CURLY@[12; 13) | ||
24 | WHITESPACE@[13; 14) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.rs b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.rs new file mode 100644 index 000000000..9ae857686 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | foo( | ||
3 | 1, 2 | ||
4 | ) | ||
5 | return 92; | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt new file mode 100644 index 000000000..a3163adcb --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0016_missing_semi.txt | |||
@@ -0,0 +1,43 @@ | |||
1 | ROOT@[0; 56) | ||
2 | FN_DEF@[0; 55) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 55) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 38) | ||
15 | CALL_EXPR@[15; 38) | ||
16 | PATH_EXPR@[15; 18) | ||
17 | PATH@[15; 18) | ||
18 | PATH_SEGMENT@[15; 18) | ||
19 | NAME_REF@[15; 18) | ||
20 | IDENT@[15; 18) "foo" | ||
21 | ARG_LIST@[18; 38) | ||
22 | L_PAREN@[18; 19) | ||
23 | WHITESPACE@[19; 28) | ||
24 | LITERAL@[28; 29) | ||
25 | INT_NUMBER@[28; 29) "1" | ||
26 | COMMA@[29; 30) | ||
27 | WHITESPACE@[30; 31) | ||
28 | LITERAL@[31; 32) | ||
29 | INT_NUMBER@[31; 32) "2" | ||
30 | WHITESPACE@[32; 37) | ||
31 | R_PAREN@[37; 38) | ||
32 | err: `expected SEMI` | ||
33 | WHITESPACE@[38; 43) | ||
34 | EXPR_STMT@[43; 53) | ||
35 | RETURN_EXPR@[43; 52) | ||
36 | RETURN_KW@[43; 49) | ||
37 | WHITESPACE@[49; 50) | ||
38 | LITERAL@[50; 52) | ||
39 | INT_NUMBER@[50; 52) "92" | ||
40 | SEMI@[52; 53) | ||
41 | WHITESPACE@[53; 54) | ||
42 | R_CURLY@[54; 55) | ||
43 | WHITESPACE@[55; 56) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.rs b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.rs new file mode 100644 index 000000000..17bd49777 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo(foo: i32) { | ||
2 | let bar = 92; | ||
3 | 1 + | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt new file mode 100644 index 000000000..f0be287ad --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0017_incomplete_binexpr.txt | |||
@@ -0,0 +1,46 @@ | |||
1 | ROOT@[0; 47) | ||
2 | FN_DEF@[0; 46) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 16) | ||
8 | L_PAREN@[6; 7) | ||
9 | PARAM@[7; 15) | ||
10 | BIND_PAT@[7; 10) | ||
11 | NAME@[7; 10) | ||
12 | IDENT@[7; 10) "foo" | ||
13 | COLON@[10; 11) | ||
14 | WHITESPACE@[11; 12) | ||
15 | PATH_TYPE@[12; 15) | ||
16 | PATH@[12; 15) | ||
17 | PATH_SEGMENT@[12; 15) | ||
18 | NAME_REF@[12; 15) | ||
19 | IDENT@[12; 15) "i32" | ||
20 | R_PAREN@[15; 16) | ||
21 | WHITESPACE@[16; 17) | ||
22 | BLOCK@[17; 46) | ||
23 | L_CURLY@[17; 18) | ||
24 | WHITESPACE@[18; 23) | ||
25 | LET_STMT@[23; 36) | ||
26 | LET_KW@[23; 26) | ||
27 | WHITESPACE@[26; 27) | ||
28 | BIND_PAT@[27; 30) | ||
29 | NAME@[27; 30) | ||
30 | IDENT@[27; 30) "bar" | ||
31 | WHITESPACE@[30; 31) | ||
32 | EQ@[31; 32) | ||
33 | WHITESPACE@[32; 33) | ||
34 | LITERAL@[33; 35) | ||
35 | INT_NUMBER@[33; 35) "92" | ||
36 | SEMI@[35; 36) | ||
37 | WHITESPACE@[36; 41) | ||
38 | BIN_EXPR@[41; 44) | ||
39 | LITERAL@[41; 42) | ||
40 | INT_NUMBER@[41; 42) "1" | ||
41 | WHITESPACE@[42; 43) | ||
42 | PLUS@[43; 44) | ||
43 | err: `expected expression` | ||
44 | WHITESPACE@[44; 45) | ||
45 | R_CURLY@[45; 46) | ||
46 | WHITESPACE@[46; 47) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.rs b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.rs new file mode 100644 index 000000000..fe604006c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | impl FnScopes { | ||
2 | fn new_scope(&) -> ScopeId { | ||
3 | let res = self.scopes.len(); | ||
4 | self.scopes.push(ScopeData { parent: None, entries: vec![] }) | ||
5 | } | ||
6 | |||
7 | fn set_parent | ||
8 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt new file mode 100644 index 000000000..c4d9f5e7e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0018_incomplete_fn.txt | |||
@@ -0,0 +1,131 @@ | |||
1 | ROOT@[0; 183) | ||
2 | IMPL_ITEM@[0; 182) | ||
3 | IMPL_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | PATH_TYPE@[5; 13) | ||
6 | PATH@[5; 13) | ||
7 | PATH_SEGMENT@[5; 13) | ||
8 | NAME_REF@[5; 13) | ||
9 | IDENT@[5; 13) "FnScopes" | ||
10 | WHITESPACE@[13; 14) | ||
11 | ITEM_LIST@[14; 182) | ||
12 | L_CURLY@[14; 15) | ||
13 | WHITESPACE@[15; 20) | ||
14 | FN_DEF@[20; 161) | ||
15 | FN_KW@[20; 22) | ||
16 | WHITESPACE@[22; 23) | ||
17 | NAME@[23; 32) | ||
18 | IDENT@[23; 32) "new_scope" | ||
19 | PARAM_LIST@[32; 35) | ||
20 | L_PAREN@[32; 33) | ||
21 | PARAM@[33; 34) | ||
22 | REF_PAT@[33; 34) | ||
23 | AMP@[33; 34) | ||
24 | err: `expected pattern` | ||
25 | err: `expected COLON` | ||
26 | err: `expected type` | ||
27 | R_PAREN@[34; 35) | ||
28 | WHITESPACE@[35; 36) | ||
29 | RET_TYPE@[36; 46) | ||
30 | THIN_ARROW@[36; 38) | ||
31 | WHITESPACE@[38; 39) | ||
32 | PATH_TYPE@[39; 46) | ||
33 | PATH@[39; 46) | ||
34 | PATH_SEGMENT@[39; 46) | ||
35 | NAME_REF@[39; 46) | ||
36 | IDENT@[39; 46) "ScopeId" | ||
37 | WHITESPACE@[46; 47) | ||
38 | BLOCK@[47; 161) | ||
39 | L_CURLY@[47; 48) | ||
40 | WHITESPACE@[48; 57) | ||
41 | LET_STMT@[57; 85) | ||
42 | LET_KW@[57; 60) | ||
43 | WHITESPACE@[60; 61) | ||
44 | BIND_PAT@[61; 64) | ||
45 | NAME@[61; 64) | ||
46 | IDENT@[61; 64) "res" | ||
47 | WHITESPACE@[64; 65) | ||
48 | EQ@[65; 66) | ||
49 | WHITESPACE@[66; 67) | ||
50 | METHOD_CALL_EXPR@[67; 84) | ||
51 | FIELD_EXPR@[67; 78) | ||
52 | PATH_EXPR@[67; 71) | ||
53 | PATH@[67; 71) | ||
54 | PATH_SEGMENT@[67; 71) | ||
55 | SELF_KW@[67; 71) | ||
56 | DOT@[71; 72) | ||
57 | NAME_REF@[72; 78) | ||
58 | IDENT@[72; 78) "scopes" | ||
59 | DOT@[78; 79) | ||
60 | NAME_REF@[79; 82) | ||
61 | IDENT@[79; 82) "len" | ||
62 | ARG_LIST@[82; 84) | ||
63 | L_PAREN@[82; 83) | ||
64 | R_PAREN@[83; 84) | ||
65 | SEMI@[84; 85) | ||
66 | WHITESPACE@[85; 94) | ||
67 | METHOD_CALL_EXPR@[94; 155) | ||
68 | FIELD_EXPR@[94; 105) | ||
69 | PATH_EXPR@[94; 98) | ||
70 | PATH@[94; 98) | ||
71 | PATH_SEGMENT@[94; 98) | ||
72 | SELF_KW@[94; 98) | ||
73 | DOT@[98; 99) | ||
74 | NAME_REF@[99; 105) | ||
75 | IDENT@[99; 105) "scopes" | ||
76 | DOT@[105; 106) | ||
77 | NAME_REF@[106; 110) | ||
78 | IDENT@[106; 110) "push" | ||
79 | ARG_LIST@[110; 155) | ||
80 | L_PAREN@[110; 111) | ||
81 | STRUCT_LIT@[111; 154) | ||
82 | PATH@[111; 120) | ||
83 | PATH_SEGMENT@[111; 120) | ||
84 | NAME_REF@[111; 120) | ||
85 | IDENT@[111; 120) "ScopeData" | ||
86 | WHITESPACE@[120; 121) | ||
87 | NAMED_FIELD_LIST@[121; 154) | ||
88 | L_CURLY@[121; 122) | ||
89 | WHITESPACE@[122; 123) | ||
90 | NAMED_FIELD@[123; 135) | ||
91 | NAME_REF@[123; 129) | ||
92 | IDENT@[123; 129) "parent" | ||
93 | COLON@[129; 130) | ||
94 | WHITESPACE@[130; 131) | ||
95 | PATH_EXPR@[131; 135) | ||
96 | PATH@[131; 135) | ||
97 | PATH_SEGMENT@[131; 135) | ||
98 | NAME_REF@[131; 135) | ||
99 | IDENT@[131; 135) "None" | ||
100 | COMMA@[135; 136) | ||
101 | WHITESPACE@[136; 137) | ||
102 | NAMED_FIELD@[137; 152) | ||
103 | NAME_REF@[137; 144) | ||
104 | IDENT@[137; 144) "entries" | ||
105 | COLON@[144; 145) | ||
106 | WHITESPACE@[145; 146) | ||
107 | MACRO_CALL@[146; 152) | ||
108 | PATH@[146; 149) | ||
109 | PATH_SEGMENT@[146; 149) | ||
110 | NAME_REF@[146; 149) | ||
111 | IDENT@[146; 149) "vec" | ||
112 | EXCL@[149; 150) | ||
113 | TOKEN_TREE@[150; 152) | ||
114 | L_BRACK@[150; 151) | ||
115 | R_BRACK@[151; 152) | ||
116 | WHITESPACE@[152; 153) | ||
117 | R_CURLY@[153; 154) | ||
118 | R_PAREN@[154; 155) | ||
119 | WHITESPACE@[155; 160) | ||
120 | R_CURLY@[160; 161) | ||
121 | WHITESPACE@[161; 167) | ||
122 | FN_DEF@[167; 180) | ||
123 | FN_KW@[167; 169) | ||
124 | WHITESPACE@[169; 170) | ||
125 | NAME@[170; 180) | ||
126 | IDENT@[170; 180) "set_parent" | ||
127 | err: `expected function arguments` | ||
128 | err: `expected a block` | ||
129 | WHITESPACE@[180; 181) | ||
130 | R_CURLY@[181; 182) | ||
131 | WHITESPACE@[182; 183) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0019_let_recover.rs b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.rs new file mode 100644 index 000000000..48bf3d68b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.rs | |||
@@ -0,0 +1,12 @@ | |||
1 | fn foo() { | ||
2 | let foo = | ||
3 | let bar = 1; | ||
4 | let | ||
5 | let baz = 92; | ||
6 | let | ||
7 | if true {} | ||
8 | let | ||
9 | while true {} | ||
10 | let | ||
11 | loop {} | ||
12 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt new file mode 100644 index 000000000..6e74771f1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0019_let_recover.txt | |||
@@ -0,0 +1,103 @@ | |||
1 | ROOT@[0; 139) | ||
2 | FN_DEF@[0; 138) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 138) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 24) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | BIND_PAT@[19; 22) | ||
18 | NAME@[19; 22) | ||
19 | IDENT@[19; 22) "foo" | ||
20 | WHITESPACE@[22; 23) | ||
21 | EQ@[23; 24) | ||
22 | err: `expected expression` | ||
23 | err: `expected SEMI` | ||
24 | WHITESPACE@[24; 29) | ||
25 | LET_STMT@[29; 41) | ||
26 | LET_KW@[29; 32) | ||
27 | WHITESPACE@[32; 33) | ||
28 | BIND_PAT@[33; 36) | ||
29 | NAME@[33; 36) | ||
30 | IDENT@[33; 36) "bar" | ||
31 | WHITESPACE@[36; 37) | ||
32 | EQ@[37; 38) | ||
33 | WHITESPACE@[38; 39) | ||
34 | LITERAL@[39; 40) | ||
35 | INT_NUMBER@[39; 40) "1" | ||
36 | SEMI@[40; 41) | ||
37 | WHITESPACE@[41; 46) | ||
38 | LET_STMT@[46; 49) | ||
39 | LET_KW@[46; 49) | ||
40 | err: `expected pattern` | ||
41 | err: `expected SEMI` | ||
42 | WHITESPACE@[49; 54) | ||
43 | LET_STMT@[54; 67) | ||
44 | LET_KW@[54; 57) | ||
45 | WHITESPACE@[57; 58) | ||
46 | BIND_PAT@[58; 61) | ||
47 | NAME@[58; 61) | ||
48 | IDENT@[58; 61) "baz" | ||
49 | WHITESPACE@[61; 62) | ||
50 | EQ@[62; 63) | ||
51 | WHITESPACE@[63; 64) | ||
52 | LITERAL@[64; 66) | ||
53 | INT_NUMBER@[64; 66) "92" | ||
54 | SEMI@[66; 67) | ||
55 | WHITESPACE@[67; 72) | ||
56 | LET_STMT@[72; 75) | ||
57 | LET_KW@[72; 75) | ||
58 | err: `expected pattern` | ||
59 | err: `expected SEMI` | ||
60 | WHITESPACE@[75; 80) | ||
61 | EXPR_STMT@[80; 90) | ||
62 | IF_EXPR@[80; 90) | ||
63 | IF_KW@[80; 82) | ||
64 | WHITESPACE@[82; 83) | ||
65 | CONDITION@[83; 87) | ||
66 | LITERAL@[83; 87) | ||
67 | TRUE_KW@[83; 87) | ||
68 | WHITESPACE@[87; 88) | ||
69 | BLOCK@[88; 90) | ||
70 | L_CURLY@[88; 89) | ||
71 | R_CURLY@[89; 90) | ||
72 | WHITESPACE@[90; 95) | ||
73 | LET_STMT@[95; 98) | ||
74 | LET_KW@[95; 98) | ||
75 | err: `expected pattern` | ||
76 | err: `expected SEMI` | ||
77 | WHITESPACE@[98; 103) | ||
78 | EXPR_STMT@[103; 116) | ||
79 | WHILE_EXPR@[103; 116) | ||
80 | WHILE_KW@[103; 108) | ||
81 | WHITESPACE@[108; 109) | ||
82 | CONDITION@[109; 113) | ||
83 | LITERAL@[109; 113) | ||
84 | TRUE_KW@[109; 113) | ||
85 | WHITESPACE@[113; 114) | ||
86 | BLOCK@[114; 116) | ||
87 | L_CURLY@[114; 115) | ||
88 | R_CURLY@[115; 116) | ||
89 | WHITESPACE@[116; 121) | ||
90 | LET_STMT@[121; 124) | ||
91 | LET_KW@[121; 124) | ||
92 | err: `expected pattern` | ||
93 | err: `expected SEMI` | ||
94 | WHITESPACE@[124; 129) | ||
95 | LOOP_EXPR@[129; 136) | ||
96 | LOOP_KW@[129; 133) | ||
97 | WHITESPACE@[133; 134) | ||
98 | BLOCK@[134; 136) | ||
99 | L_CURLY@[134; 135) | ||
100 | R_CURLY@[135; 136) | ||
101 | WHITESPACE@[136; 137) | ||
102 | R_CURLY@[137; 138) | ||
103 | WHITESPACE@[138; 139) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.rs b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.rs new file mode 100644 index 000000000..3393b668b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn | ||
2 | |||
3 | fn foo() {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt new file mode 100644 index 000000000..b5218b0fa --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0020_fn_recover.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | ROOT@[0; 16) | ||
2 | FN_DEF@[0; 2) | ||
3 | FN_KW@[0; 2) | ||
4 | err: `expected a name` | ||
5 | err: `expected function arguments` | ||
6 | err: `expected a block` | ||
7 | WHITESPACE@[2; 4) | ||
8 | FN_DEF@[4; 15) | ||
9 | FN_KW@[4; 6) | ||
10 | WHITESPACE@[6; 7) | ||
11 | NAME@[7; 10) | ||
12 | IDENT@[7; 10) "foo" | ||
13 | PARAM_LIST@[10; 12) | ||
14 | L_PAREN@[10; 11) | ||
15 | R_PAREN@[11; 12) | ||
16 | WHITESPACE@[12; 13) | ||
17 | BLOCK@[13; 15) | ||
18 | L_CURLY@[13; 14) | ||
19 | R_CURLY@[14; 15) | ||
20 | WHITESPACE@[15; 16) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.rs b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.rs new file mode 100644 index 000000000..7a6c264f6 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | fn foo(x: i32, y) { | ||
2 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt new file mode 100644 index 000000000..8dcb58ae2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0021_incomplete_param.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | ROOT@[0; 22) | ||
2 | FN_DEF@[0; 21) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 17) | ||
8 | L_PAREN@[6; 7) | ||
9 | PARAM@[7; 13) | ||
10 | BIND_PAT@[7; 8) | ||
11 | NAME@[7; 8) | ||
12 | IDENT@[7; 8) "x" | ||
13 | COLON@[8; 9) | ||
14 | WHITESPACE@[9; 10) | ||
15 | PATH_TYPE@[10; 13) | ||
16 | PATH@[10; 13) | ||
17 | PATH_SEGMENT@[10; 13) | ||
18 | NAME_REF@[10; 13) | ||
19 | IDENT@[10; 13) "i32" | ||
20 | COMMA@[13; 14) | ||
21 | WHITESPACE@[14; 15) | ||
22 | PARAM@[15; 16) | ||
23 | BIND_PAT@[15; 16) | ||
24 | NAME@[15; 16) | ||
25 | IDENT@[15; 16) "y" | ||
26 | err: `expected COLON` | ||
27 | err: `expected type` | ||
28 | R_PAREN@[16; 17) | ||
29 | WHITESPACE@[17; 18) | ||
30 | BLOCK@[18; 21) | ||
31 | L_CURLY@[18; 19) | ||
32 | WHITESPACE@[19; 20) | ||
33 | R_CURLY@[20; 21) | ||
34 | WHITESPACE@[21; 22) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.rs b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.rs new file mode 100644 index 000000000..cd2d493a1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn a() { [1, 2, @, struct, let] } | ||
2 | fn b() { foo(1, 2, @, impl, let) } | ||
3 | fn c() { foo.bar(1, 2, @, ], trait, let) } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt new file mode 100644 index 000000000..287e56ac4 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0022_bad_exprs.txt | |||
@@ -0,0 +1,189 @@ | |||
1 | ROOT@[0; 112) | ||
2 | FN_DEF@[0; 33) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 4) | ||
6 | IDENT@[3; 4) "a" | ||
7 | PARAM_LIST@[4; 6) | ||
8 | L_PAREN@[4; 5) | ||
9 | R_PAREN@[5; 6) | ||
10 | WHITESPACE@[6; 7) | ||
11 | BLOCK@[7; 33) | ||
12 | L_CURLY@[7; 8) | ||
13 | WHITESPACE@[8; 9) | ||
14 | EXPR_STMT@[9; 15) | ||
15 | ARRAY_EXPR@[9; 15) | ||
16 | L_BRACK@[9; 10) | ||
17 | LITERAL@[10; 11) | ||
18 | INT_NUMBER@[10; 11) "1" | ||
19 | COMMA@[11; 12) | ||
20 | WHITESPACE@[12; 13) | ||
21 | LITERAL@[13; 14) | ||
22 | INT_NUMBER@[13; 14) "2" | ||
23 | COMMA@[14; 15) | ||
24 | err: `expected expression` | ||
25 | err: `expected R_BRACK` | ||
26 | err: `expected SEMI` | ||
27 | WHITESPACE@[15; 16) | ||
28 | err: `expected expression` | ||
29 | EXPR_STMT@[16; 17) | ||
30 | ERROR@[16; 17) | ||
31 | AT@[16; 17) | ||
32 | err: `expected SEMI` | ||
33 | err: `expected expression` | ||
34 | EXPR_STMT@[17; 18) | ||
35 | ERROR@[17; 18) | ||
36 | COMMA@[17; 18) | ||
37 | err: `expected SEMI` | ||
38 | WHITESPACE@[18; 19) | ||
39 | STRUCT_DEF@[19; 26) | ||
40 | STRUCT_KW@[19; 25) | ||
41 | err: `expected a name` | ||
42 | ERROR@[25; 26) | ||
43 | COMMA@[25; 26) | ||
44 | err: `expected `;`, `{`, or `(`` | ||
45 | WHITESPACE@[26; 27) | ||
46 | LET_STMT@[27; 31) | ||
47 | LET_KW@[27; 30) | ||
48 | err: `expected pattern` | ||
49 | ERROR@[30; 31) | ||
50 | R_BRACK@[30; 31) | ||
51 | err: `expected SEMI` | ||
52 | WHITESPACE@[31; 32) | ||
53 | R_CURLY@[32; 33) | ||
54 | WHITESPACE@[33; 34) | ||
55 | FN_DEF@[34; 68) | ||
56 | FN_KW@[34; 36) | ||
57 | WHITESPACE@[36; 37) | ||
58 | NAME@[37; 38) | ||
59 | IDENT@[37; 38) "b" | ||
60 | PARAM_LIST@[38; 40) | ||
61 | L_PAREN@[38; 39) | ||
62 | R_PAREN@[39; 40) | ||
63 | WHITESPACE@[40; 41) | ||
64 | BLOCK@[41; 68) | ||
65 | L_CURLY@[41; 42) | ||
66 | WHITESPACE@[42; 43) | ||
67 | EXPR_STMT@[43; 52) | ||
68 | CALL_EXPR@[43; 52) | ||
69 | PATH_EXPR@[43; 46) | ||
70 | PATH@[43; 46) | ||
71 | PATH_SEGMENT@[43; 46) | ||
72 | NAME_REF@[43; 46) | ||
73 | IDENT@[43; 46) "foo" | ||
74 | ARG_LIST@[46; 52) | ||
75 | L_PAREN@[46; 47) | ||
76 | LITERAL@[47; 48) | ||
77 | INT_NUMBER@[47; 48) "1" | ||
78 | COMMA@[48; 49) | ||
79 | WHITESPACE@[49; 50) | ||
80 | LITERAL@[50; 51) | ||
81 | INT_NUMBER@[50; 51) "2" | ||
82 | COMMA@[51; 52) | ||
83 | err: `expected expression` | ||
84 | err: `expected SEMI` | ||
85 | WHITESPACE@[52; 53) | ||
86 | err: `expected expression` | ||
87 | EXPR_STMT@[53; 54) | ||
88 | ERROR@[53; 54) | ||
89 | AT@[53; 54) | ||
90 | err: `expected SEMI` | ||
91 | err: `expected expression` | ||
92 | EXPR_STMT@[54; 55) | ||
93 | ERROR@[54; 55) | ||
94 | COMMA@[54; 55) | ||
95 | err: `expected SEMI` | ||
96 | WHITESPACE@[55; 56) | ||
97 | IMPL_ITEM@[56; 60) | ||
98 | IMPL_KW@[56; 60) | ||
99 | err: `expected type` | ||
100 | err: `expected `{`` | ||
101 | err: `expected expression` | ||
102 | EXPR_STMT@[60; 61) | ||
103 | ERROR@[60; 61) | ||
104 | COMMA@[60; 61) | ||
105 | err: `expected SEMI` | ||
106 | WHITESPACE@[61; 62) | ||
107 | LET_STMT@[62; 65) | ||
108 | LET_KW@[62; 65) | ||
109 | err: `expected pattern` | ||
110 | err: `expected SEMI` | ||
111 | err: `expected expression` | ||
112 | ERROR@[65; 66) | ||
113 | R_PAREN@[65; 66) | ||
114 | WHITESPACE@[66; 67) | ||
115 | R_CURLY@[67; 68) | ||
116 | WHITESPACE@[68; 69) | ||
117 | FN_DEF@[69; 111) | ||
118 | FN_KW@[69; 71) | ||
119 | WHITESPACE@[71; 72) | ||
120 | NAME@[72; 73) | ||
121 | IDENT@[72; 73) "c" | ||
122 | PARAM_LIST@[73; 75) | ||
123 | L_PAREN@[73; 74) | ||
124 | R_PAREN@[74; 75) | ||
125 | WHITESPACE@[75; 76) | ||
126 | BLOCK@[76; 111) | ||
127 | L_CURLY@[76; 77) | ||
128 | WHITESPACE@[77; 78) | ||
129 | EXPR_STMT@[78; 91) | ||
130 | METHOD_CALL_EXPR@[78; 91) | ||
131 | PATH_EXPR@[78; 81) | ||
132 | PATH@[78; 81) | ||
133 | PATH_SEGMENT@[78; 81) | ||
134 | NAME_REF@[78; 81) | ||
135 | IDENT@[78; 81) "foo" | ||
136 | DOT@[81; 82) | ||
137 | NAME_REF@[82; 85) | ||
138 | IDENT@[82; 85) "bar" | ||
139 | ARG_LIST@[85; 91) | ||
140 | L_PAREN@[85; 86) | ||
141 | LITERAL@[86; 87) | ||
142 | INT_NUMBER@[86; 87) "1" | ||
143 | COMMA@[87; 88) | ||
144 | WHITESPACE@[88; 89) | ||
145 | LITERAL@[89; 90) | ||
146 | INT_NUMBER@[89; 90) "2" | ||
147 | COMMA@[90; 91) | ||
148 | err: `expected expression` | ||
149 | err: `expected SEMI` | ||
150 | WHITESPACE@[91; 92) | ||
151 | err: `expected expression` | ||
152 | EXPR_STMT@[92; 93) | ||
153 | ERROR@[92; 93) | ||
154 | AT@[92; 93) | ||
155 | err: `expected SEMI` | ||
156 | err: `expected expression` | ||
157 | EXPR_STMT@[93; 94) | ||
158 | ERROR@[93; 94) | ||
159 | COMMA@[93; 94) | ||
160 | err: `expected SEMI` | ||
161 | WHITESPACE@[94; 95) | ||
162 | err: `expected expression` | ||
163 | EXPR_STMT@[95; 96) | ||
164 | ERROR@[95; 96) | ||
165 | R_BRACK@[95; 96) | ||
166 | err: `expected SEMI` | ||
167 | err: `expected expression` | ||
168 | EXPR_STMT@[96; 97) | ||
169 | ERROR@[96; 97) | ||
170 | COMMA@[96; 97) | ||
171 | err: `expected SEMI` | ||
172 | WHITESPACE@[97; 98) | ||
173 | TRAIT_DEF@[98; 104) | ||
174 | TRAIT_KW@[98; 103) | ||
175 | err: `expected a name` | ||
176 | ERROR@[103; 104) | ||
177 | COMMA@[103; 104) | ||
178 | err: `expected `{`` | ||
179 | WHITESPACE@[104; 105) | ||
180 | LET_STMT@[105; 108) | ||
181 | LET_KW@[105; 108) | ||
182 | err: `expected pattern` | ||
183 | err: `expected SEMI` | ||
184 | err: `expected expression` | ||
185 | ERROR@[108; 109) | ||
186 | R_PAREN@[108; 109) | ||
187 | WHITESPACE@[109; 110) | ||
188 | R_CURLY@[110; 111) | ||
189 | WHITESPACE@[111; 112) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.rs b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.rs new file mode 100644 index 000000000..0206d563e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn main() { | ||
2 | foo! ( | ||
3 | bar, "baz", 1, 2.0 | ||
4 | } //~ ERROR incorrect close delimiter | ||
5 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt new file mode 100644 index 000000000..2df81b12b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0023_mismatched_paren.txt | |||
@@ -0,0 +1,43 @@ | |||
1 | ROOT@[0; 94) | ||
2 | FN_DEF@[0; 55) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 55) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | MACRO_CALL@[16; 49) | ||
15 | PATH@[16; 19) | ||
16 | PATH_SEGMENT@[16; 19) | ||
17 | NAME_REF@[16; 19) | ||
18 | IDENT@[16; 19) "foo" | ||
19 | EXCL@[19; 20) | ||
20 | WHITESPACE@[20; 21) | ||
21 | TOKEN_TREE@[21; 49) | ||
22 | L_PAREN@[21; 22) | ||
23 | WHITESPACE@[22; 31) | ||
24 | IDENT@[31; 34) "bar" | ||
25 | COMMA@[34; 35) | ||
26 | WHITESPACE@[35; 36) | ||
27 | STRING@[36; 41) | ||
28 | COMMA@[41; 42) | ||
29 | WHITESPACE@[42; 43) | ||
30 | INT_NUMBER@[43; 44) "1" | ||
31 | COMMA@[44; 45) | ||
32 | WHITESPACE@[45; 46) | ||
33 | FLOAT_NUMBER@[46; 49) "2.0" | ||
34 | err: `unmatched `}`` | ||
35 | WHITESPACE@[49; 54) | ||
36 | R_CURLY@[54; 55) | ||
37 | WHITESPACE@[55; 56) | ||
38 | COMMENT@[56; 91) | ||
39 | WHITESPACE@[91; 92) | ||
40 | err: `unmatched `}`` | ||
41 | ERROR@[92; 93) | ||
42 | R_CURLY@[92; 93) | ||
43 | WHITESPACE@[93; 94) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.rs b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.rs new file mode 100644 index 000000000..6c2e95c02 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | fn f<T: (Copy) + (?Sized) + (for<'a> Trait<'a>)>() {} | ||
2 | |||
3 | fn main() { | ||
4 | let _: Box<(Copy) + (?Sized) + (for<'a> Trait<'a>)>; | ||
5 | let _: Box<(?Sized) + (for<'a> Trait<'a>) + (Copy)>; | ||
6 | let _: Box<(for<'a> Trait<'a>) + (Copy) + (?Sized)>; | ||
7 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt new file mode 100644 index 000000000..195c12e08 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0024_many_type_parens.txt | |||
@@ -0,0 +1,310 @@ | |||
1 | ROOT@[0; 240) | ||
2 | FN_DEF@[0; 53) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 4) | ||
6 | IDENT@[3; 4) "f" | ||
7 | TYPE_PARAM_LIST@[4; 48) | ||
8 | L_ANGLE@[4; 5) | ||
9 | TYPE_PARAM@[5; 47) | ||
10 | NAME@[5; 6) | ||
11 | IDENT@[5; 6) "T" | ||
12 | COLON@[6; 7) | ||
13 | WHITESPACE@[7; 8) | ||
14 | L_PAREN@[8; 9) | ||
15 | PATH_TYPE@[9; 13) | ||
16 | PATH@[9; 13) | ||
17 | PATH_SEGMENT@[9; 13) | ||
18 | NAME_REF@[9; 13) | ||
19 | IDENT@[9; 13) "Copy" | ||
20 | R_PAREN@[13; 14) | ||
21 | WHITESPACE@[14; 15) | ||
22 | PLUS@[15; 16) | ||
23 | WHITESPACE@[16; 17) | ||
24 | L_PAREN@[17; 18) | ||
25 | QUESTION@[18; 19) | ||
26 | PATH_TYPE@[19; 24) | ||
27 | PATH@[19; 24) | ||
28 | PATH_SEGMENT@[19; 24) | ||
29 | NAME_REF@[19; 24) | ||
30 | IDENT@[19; 24) "Sized" | ||
31 | R_PAREN@[24; 25) | ||
32 | WHITESPACE@[25; 26) | ||
33 | PLUS@[26; 27) | ||
34 | WHITESPACE@[27; 28) | ||
35 | L_PAREN@[28; 29) | ||
36 | FOR_TYPE@[29; 46) | ||
37 | FOR_KW@[29; 32) | ||
38 | TYPE_PARAM_LIST@[32; 36) | ||
39 | L_ANGLE@[32; 33) | ||
40 | LIFETIME_PARAM@[33; 35) | ||
41 | LIFETIME@[33; 35) "'a" | ||
42 | R_ANGLE@[35; 36) | ||
43 | WHITESPACE@[36; 37) | ||
44 | PATH_TYPE@[37; 46) | ||
45 | PATH@[37; 46) | ||
46 | PATH_SEGMENT@[37; 46) | ||
47 | NAME_REF@[37; 42) | ||
48 | IDENT@[37; 42) "Trait" | ||
49 | TYPE_ARG_LIST@[42; 46) | ||
50 | L_ANGLE@[42; 43) | ||
51 | LIFETIME_ARG@[43; 45) | ||
52 | LIFETIME@[43; 45) "'a" | ||
53 | R_ANGLE@[45; 46) | ||
54 | R_PAREN@[46; 47) | ||
55 | R_ANGLE@[47; 48) | ||
56 | PARAM_LIST@[48; 50) | ||
57 | L_PAREN@[48; 49) | ||
58 | R_PAREN@[49; 50) | ||
59 | WHITESPACE@[50; 51) | ||
60 | BLOCK@[51; 53) | ||
61 | L_CURLY@[51; 52) | ||
62 | R_CURLY@[52; 53) | ||
63 | WHITESPACE@[53; 55) | ||
64 | FN_DEF@[55; 239) | ||
65 | FN_KW@[55; 57) | ||
66 | WHITESPACE@[57; 58) | ||
67 | NAME@[58; 62) | ||
68 | IDENT@[58; 62) "main" | ||
69 | PARAM_LIST@[62; 64) | ||
70 | L_PAREN@[62; 63) | ||
71 | R_PAREN@[63; 64) | ||
72 | WHITESPACE@[64; 65) | ||
73 | BLOCK@[65; 239) | ||
74 | L_CURLY@[65; 66) | ||
75 | WHITESPACE@[66; 71) | ||
76 | LET_STMT@[71; 121) | ||
77 | LET_KW@[71; 74) | ||
78 | WHITESPACE@[74; 75) | ||
79 | PLACEHOLDER_PAT@[75; 76) | ||
80 | UNDERSCORE@[75; 76) | ||
81 | COLON@[76; 77) | ||
82 | WHITESPACE@[77; 78) | ||
83 | PATH_TYPE@[78; 121) | ||
84 | PATH@[78; 88) | ||
85 | PATH_SEGMENT@[78; 88) | ||
86 | NAME_REF@[78; 81) | ||
87 | IDENT@[78; 81) "Box" | ||
88 | TYPE_ARG_LIST@[81; 88) | ||
89 | L_ANGLE@[81; 82) | ||
90 | TYPE_ARG@[82; 88) | ||
91 | PAREN_TYPE@[82; 88) | ||
92 | L_PAREN@[82; 83) | ||
93 | PATH_TYPE@[83; 87) | ||
94 | PATH@[83; 87) | ||
95 | PATH_SEGMENT@[83; 87) | ||
96 | NAME_REF@[83; 87) | ||
97 | IDENT@[83; 87) "Copy" | ||
98 | R_PAREN@[87; 88) | ||
99 | err: `expected COMMA` | ||
100 | err: `expected R_ANGLE` | ||
101 | WHITESPACE@[88; 89) | ||
102 | PLUS@[89; 90) | ||
103 | WHITESPACE@[90; 91) | ||
104 | L_PAREN@[91; 92) | ||
105 | QUESTION@[92; 93) | ||
106 | PATH_TYPE@[93; 98) | ||
107 | PATH@[93; 98) | ||
108 | PATH_SEGMENT@[93; 98) | ||
109 | NAME_REF@[93; 98) | ||
110 | IDENT@[93; 98) "Sized" | ||
111 | R_PAREN@[98; 99) | ||
112 | WHITESPACE@[99; 100) | ||
113 | PLUS@[100; 101) | ||
114 | WHITESPACE@[101; 102) | ||
115 | L_PAREN@[102; 103) | ||
116 | FOR_TYPE@[103; 120) | ||
117 | FOR_KW@[103; 106) | ||
118 | TYPE_PARAM_LIST@[106; 110) | ||
119 | L_ANGLE@[106; 107) | ||
120 | LIFETIME_PARAM@[107; 109) | ||
121 | LIFETIME@[107; 109) "'a" | ||
122 | R_ANGLE@[109; 110) | ||
123 | WHITESPACE@[110; 111) | ||
124 | PATH_TYPE@[111; 120) | ||
125 | PATH@[111; 120) | ||
126 | PATH_SEGMENT@[111; 120) | ||
127 | NAME_REF@[111; 116) | ||
128 | IDENT@[111; 116) "Trait" | ||
129 | TYPE_ARG_LIST@[116; 120) | ||
130 | L_ANGLE@[116; 117) | ||
131 | LIFETIME_ARG@[117; 119) | ||
132 | LIFETIME@[117; 119) "'a" | ||
133 | R_ANGLE@[119; 120) | ||
134 | R_PAREN@[120; 121) | ||
135 | err: `expected SEMI` | ||
136 | err: `expected expression` | ||
137 | EXPR_STMT@[121; 123) | ||
138 | ERROR@[121; 122) | ||
139 | R_ANGLE@[121; 122) | ||
140 | SEMI@[122; 123) | ||
141 | WHITESPACE@[123; 128) | ||
142 | LET_STMT@[128; 141) | ||
143 | LET_KW@[128; 131) | ||
144 | WHITESPACE@[131; 132) | ||
145 | PLACEHOLDER_PAT@[132; 133) | ||
146 | UNDERSCORE@[132; 133) | ||
147 | COLON@[133; 134) | ||
148 | WHITESPACE@[134; 135) | ||
149 | PATH_TYPE@[135; 141) | ||
150 | PATH@[135; 141) | ||
151 | PATH_SEGMENT@[135; 141) | ||
152 | NAME_REF@[135; 138) | ||
153 | IDENT@[135; 138) "Box" | ||
154 | TYPE_ARG_LIST@[138; 141) | ||
155 | L_ANGLE@[138; 139) | ||
156 | TYPE_ARG@[139; 141) | ||
157 | PAREN_TYPE@[139; 141) | ||
158 | L_PAREN@[139; 140) | ||
159 | err: `expected type` | ||
160 | ERROR@[140; 141) | ||
161 | QUESTION@[140; 141) | ||
162 | err: `expected R_PAREN` | ||
163 | err: `expected COMMA` | ||
164 | err: `expected R_ANGLE` | ||
165 | err: `expected SEMI` | ||
166 | EXPR_STMT@[141; 146) | ||
167 | PATH_EXPR@[141; 146) | ||
168 | PATH@[141; 146) | ||
169 | PATH_SEGMENT@[141; 146) | ||
170 | NAME_REF@[141; 146) | ||
171 | IDENT@[141; 146) "Sized" | ||
172 | err: `expected SEMI` | ||
173 | err: `expected expression` | ||
174 | EXPR_STMT@[146; 147) | ||
175 | ERROR@[146; 147) | ||
176 | R_PAREN@[146; 147) | ||
177 | err: `expected SEMI` | ||
178 | WHITESPACE@[147; 148) | ||
179 | err: `expected expression` | ||
180 | EXPR_STMT@[148; 149) | ||
181 | ERROR@[148; 149) | ||
182 | PLUS@[148; 149) | ||
183 | err: `expected SEMI` | ||
184 | WHITESPACE@[149; 150) | ||
185 | EXPR_STMT@[150; 151) | ||
186 | PAREN_EXPR@[150; 151) | ||
187 | L_PAREN@[150; 151) | ||
188 | err: `expected expression` | ||
189 | err: `expected R_PAREN` | ||
190 | err: `expected SEMI` | ||
191 | EXPR_STMT@[151; 157) | ||
192 | FOR_EXPR@[151; 157) | ||
193 | FOR_KW@[151; 154) | ||
194 | err: `expected pattern` | ||
195 | ERROR@[154; 155) | ||
196 | L_ANGLE@[154; 155) | ||
197 | err: `expected IN_KW` | ||
198 | err: `expected expression` | ||
199 | ERROR@[155; 157) | ||
200 | LIFETIME@[155; 157) "'a" | ||
201 | err: `expected a block` | ||
202 | err: `expected expression` | ||
203 | EXPR_STMT@[157; 158) | ||
204 | ERROR@[157; 158) | ||
205 | R_ANGLE@[157; 158) | ||
206 | err: `expected SEMI` | ||
207 | WHITESPACE@[158; 159) | ||
208 | EXPR_STMT@[159; 180) | ||
209 | BIN_EXPR@[159; 180) | ||
210 | BIN_EXPR@[159; 178) | ||
211 | BIN_EXPR@[159; 169) | ||
212 | BIN_EXPR@[159; 167) | ||
213 | PATH_EXPR@[159; 164) | ||
214 | PATH@[159; 164) | ||
215 | PATH_SEGMENT@[159; 164) | ||
216 | NAME_REF@[159; 164) | ||
217 | IDENT@[159; 164) "Trait" | ||
218 | L_ANGLE@[164; 165) | ||
219 | err: `expected expression` | ||
220 | ERROR@[165; 167) | ||
221 | LIFETIME@[165; 167) "'a" | ||
222 | R_ANGLE@[167; 168) | ||
223 | err: `expected expression` | ||
224 | ERROR@[168; 169) | ||
225 | R_PAREN@[168; 169) | ||
226 | WHITESPACE@[169; 170) | ||
227 | PLUS@[170; 171) | ||
228 | WHITESPACE@[171; 172) | ||
229 | PAREN_EXPR@[172; 178) | ||
230 | L_PAREN@[172; 173) | ||
231 | PATH_EXPR@[173; 177) | ||
232 | PATH@[173; 177) | ||
233 | PATH_SEGMENT@[173; 177) | ||
234 | NAME_REF@[173; 177) | ||
235 | IDENT@[173; 177) "Copy" | ||
236 | R_PAREN@[177; 178) | ||
237 | R_ANGLE@[178; 179) | ||
238 | err: `expected expression` | ||
239 | ERROR@[179; 180) | ||
240 | SEMI@[179; 180) | ||
241 | err: `expected SEMI` | ||
242 | WHITESPACE@[180; 185) | ||
243 | LET_STMT@[185; 235) | ||
244 | LET_KW@[185; 188) | ||
245 | WHITESPACE@[188; 189) | ||
246 | PLACEHOLDER_PAT@[189; 190) | ||
247 | UNDERSCORE@[189; 190) | ||
248 | COLON@[190; 191) | ||
249 | WHITESPACE@[191; 192) | ||
250 | PATH_TYPE@[192; 235) | ||
251 | PATH@[192; 215) | ||
252 | PATH_SEGMENT@[192; 215) | ||
253 | NAME_REF@[192; 195) | ||
254 | IDENT@[192; 195) "Box" | ||
255 | TYPE_ARG_LIST@[195; 215) | ||
256 | L_ANGLE@[195; 196) | ||
257 | TYPE_ARG@[196; 215) | ||
258 | PAREN_TYPE@[196; 215) | ||
259 | L_PAREN@[196; 197) | ||
260 | FOR_TYPE@[197; 214) | ||
261 | FOR_KW@[197; 200) | ||
262 | TYPE_PARAM_LIST@[200; 204) | ||
263 | L_ANGLE@[200; 201) | ||
264 | LIFETIME_PARAM@[201; 203) | ||
265 | LIFETIME@[201; 203) "'a" | ||
266 | R_ANGLE@[203; 204) | ||
267 | WHITESPACE@[204; 205) | ||
268 | PATH_TYPE@[205; 214) | ||
269 | PATH@[205; 214) | ||
270 | PATH_SEGMENT@[205; 214) | ||
271 | NAME_REF@[205; 210) | ||
272 | IDENT@[205; 210) "Trait" | ||
273 | TYPE_ARG_LIST@[210; 214) | ||
274 | L_ANGLE@[210; 211) | ||
275 | LIFETIME_ARG@[211; 213) | ||
276 | LIFETIME@[211; 213) "'a" | ||
277 | R_ANGLE@[213; 214) | ||
278 | R_PAREN@[214; 215) | ||
279 | err: `expected COMMA` | ||
280 | err: `expected R_ANGLE` | ||
281 | WHITESPACE@[215; 216) | ||
282 | PLUS@[216; 217) | ||
283 | WHITESPACE@[217; 218) | ||
284 | L_PAREN@[218; 219) | ||
285 | PATH_TYPE@[219; 223) | ||
286 | PATH@[219; 223) | ||
287 | PATH_SEGMENT@[219; 223) | ||
288 | NAME_REF@[219; 223) | ||
289 | IDENT@[219; 223) "Copy" | ||
290 | R_PAREN@[223; 224) | ||
291 | WHITESPACE@[224; 225) | ||
292 | PLUS@[225; 226) | ||
293 | WHITESPACE@[226; 227) | ||
294 | L_PAREN@[227; 228) | ||
295 | QUESTION@[228; 229) | ||
296 | PATH_TYPE@[229; 234) | ||
297 | PATH@[229; 234) | ||
298 | PATH_SEGMENT@[229; 234) | ||
299 | NAME_REF@[229; 234) | ||
300 | IDENT@[229; 234) "Sized" | ||
301 | R_PAREN@[234; 235) | ||
302 | err: `expected SEMI` | ||
303 | err: `expected expression` | ||
304 | EXPR_STMT@[235; 237) | ||
305 | ERROR@[235; 236) | ||
306 | R_ANGLE@[235; 236) | ||
307 | SEMI@[236; 237) | ||
308 | WHITESPACE@[237; 238) | ||
309 | R_CURLY@[238; 239) | ||
310 | WHITESPACE@[239; 240) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0025_nope.rs b/crates/ra_syntax/tests/data/parser/err/0025_nope.rs new file mode 100644 index 000000000..28726ed51 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0025_nope.rs | |||
@@ -0,0 +1,31 @@ | |||
1 | fn main() { | ||
2 | enum Test { | ||
3 | Var1, | ||
4 | Var2(String), | ||
5 | Var3 { | ||
6 | abc: {}, //~ ERROR: expected type, found `{` | ||
7 | }, | ||
8 | } | ||
9 | |||
10 | // recover... | ||
11 | let a = 1; | ||
12 | enum Test2 { | ||
13 | Fine, | ||
14 | } | ||
15 | |||
16 | enum Test3 { | ||
17 | StillFine { | ||
18 | def: i32, | ||
19 | }, | ||
20 | } | ||
21 | |||
22 | { | ||
23 | // fail again | ||
24 | enum Test4 { | ||
25 | Nope(i32 {}) //~ ERROR: found `{` | ||
26 | //~^ ERROR: found `{` | ||
27 | } | ||
28 | } | ||
29 | // still recover later | ||
30 | let bad_syntax = _; //~ ERROR: expected expression, found reserved identifier `_` | ||
31 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0025_nope.txt b/crates/ra_syntax/tests/data/parser/err/0025_nope.txt new file mode 100644 index 000000000..c30b8585f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0025_nope.txt | |||
@@ -0,0 +1,203 @@ | |||
1 | ROOT@[0; 575) | ||
2 | FN_DEF@[0; 574) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 574) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | ENUM_DEF@[16; 152) | ||
15 | ENUM_KW@[16; 20) | ||
16 | WHITESPACE@[20; 21) | ||
17 | NAME@[21; 25) | ||
18 | IDENT@[21; 25) "Test" | ||
19 | WHITESPACE@[25; 26) | ||
20 | ENUM_VARIANT_LIST@[26; 152) | ||
21 | L_CURLY@[26; 27) | ||
22 | WHITESPACE@[27; 36) | ||
23 | ENUM_VARIANT@[36; 40) | ||
24 | NAME@[36; 40) | ||
25 | IDENT@[36; 40) "Var1" | ||
26 | COMMA@[40; 41) | ||
27 | WHITESPACE@[41; 50) | ||
28 | ENUM_VARIANT@[50; 62) | ||
29 | NAME@[50; 54) | ||
30 | IDENT@[50; 54) "Var2" | ||
31 | POS_FIELD_LIST@[54; 62) | ||
32 | L_PAREN@[54; 55) | ||
33 | POS_FIELD@[55; 61) | ||
34 | PATH_TYPE@[55; 61) | ||
35 | PATH@[55; 61) | ||
36 | PATH_SEGMENT@[55; 61) | ||
37 | NAME_REF@[55; 61) | ||
38 | IDENT@[55; 61) "String" | ||
39 | R_PAREN@[61; 62) | ||
40 | COMMA@[62; 63) | ||
41 | WHITESPACE@[63; 72) | ||
42 | ENUM_VARIANT@[72; 145) | ||
43 | NAME@[72; 76) | ||
44 | IDENT@[72; 76) "Var3" | ||
45 | WHITESPACE@[76; 77) | ||
46 | NAMED_FIELD_DEF_LIST@[77; 145) | ||
47 | L_CURLY@[77; 78) | ||
48 | WHITESPACE@[78; 91) | ||
49 | NAMED_FIELD_DEF@[91; 95) | ||
50 | NAME@[91; 94) | ||
51 | IDENT@[91; 94) "abc" | ||
52 | COLON@[94; 95) | ||
53 | err: `expected type` | ||
54 | err: `expected COMMA` | ||
55 | WHITESPACE@[95; 96) | ||
56 | err: `expected field` | ||
57 | ERROR@[96; 98) | ||
58 | L_CURLY@[96; 97) | ||
59 | R_CURLY@[97; 98) | ||
60 | err: `expected field declaration` | ||
61 | ERROR@[98; 99) | ||
62 | COMMA@[98; 99) | ||
63 | WHITESPACE@[99; 100) | ||
64 | COMMENT@[100; 135) | ||
65 | WHITESPACE@[135; 144) | ||
66 | R_CURLY@[144; 145) | ||
67 | COMMA@[145; 146) | ||
68 | WHITESPACE@[146; 151) | ||
69 | R_CURLY@[151; 152) | ||
70 | WHITESPACE@[152; 158) | ||
71 | COMMENT@[158; 171) | ||
72 | WHITESPACE@[171; 176) | ||
73 | LET_STMT@[176; 186) | ||
74 | LET_KW@[176; 179) | ||
75 | WHITESPACE@[179; 180) | ||
76 | BIND_PAT@[180; 181) | ||
77 | NAME@[180; 181) | ||
78 | IDENT@[180; 181) "a" | ||
79 | WHITESPACE@[181; 182) | ||
80 | EQ@[182; 183) | ||
81 | WHITESPACE@[183; 184) | ||
82 | LITERAL@[184; 185) | ||
83 | INT_NUMBER@[184; 185) "1" | ||
84 | SEMI@[185; 186) | ||
85 | WHITESPACE@[186; 191) | ||
86 | ENUM_DEF@[191; 223) | ||
87 | ENUM_KW@[191; 195) | ||
88 | WHITESPACE@[195; 196) | ||
89 | NAME@[196; 201) | ||
90 | IDENT@[196; 201) "Test2" | ||
91 | WHITESPACE@[201; 202) | ||
92 | ENUM_VARIANT_LIST@[202; 223) | ||
93 | L_CURLY@[202; 203) | ||
94 | WHITESPACE@[203; 212) | ||
95 | ENUM_VARIANT@[212; 216) | ||
96 | NAME@[212; 216) | ||
97 | IDENT@[212; 216) "Fine" | ||
98 | COMMA@[216; 217) | ||
99 | WHITESPACE@[217; 222) | ||
100 | R_CURLY@[222; 223) | ||
101 | WHITESPACE@[223; 229) | ||
102 | ENUM_DEF@[229; 300) | ||
103 | ENUM_KW@[229; 233) | ||
104 | WHITESPACE@[233; 234) | ||
105 | NAME@[234; 239) | ||
106 | IDENT@[234; 239) "Test3" | ||
107 | WHITESPACE@[239; 240) | ||
108 | ENUM_VARIANT_LIST@[240; 300) | ||
109 | L_CURLY@[240; 241) | ||
110 | WHITESPACE@[241; 250) | ||
111 | ENUM_VARIANT@[250; 293) | ||
112 | NAME@[250; 259) | ||
113 | IDENT@[250; 259) "StillFine" | ||
114 | WHITESPACE@[259; 260) | ||
115 | NAMED_FIELD_DEF_LIST@[260; 293) | ||
116 | L_CURLY@[260; 261) | ||
117 | WHITESPACE@[261; 274) | ||
118 | NAMED_FIELD_DEF@[274; 282) | ||
119 | NAME@[274; 277) | ||
120 | IDENT@[274; 277) "def" | ||
121 | COLON@[277; 278) | ||
122 | WHITESPACE@[278; 279) | ||
123 | PATH_TYPE@[279; 282) | ||
124 | PATH@[279; 282) | ||
125 | PATH_SEGMENT@[279; 282) | ||
126 | NAME_REF@[279; 282) | ||
127 | IDENT@[279; 282) "i32" | ||
128 | COMMA@[282; 283) | ||
129 | WHITESPACE@[283; 292) | ||
130 | R_CURLY@[292; 293) | ||
131 | COMMA@[293; 294) | ||
132 | WHITESPACE@[294; 299) | ||
133 | R_CURLY@[299; 300) | ||
134 | WHITESPACE@[300; 306) | ||
135 | EXPR_STMT@[306; 459) | ||
136 | BLOCK_EXPR@[306; 459) | ||
137 | BLOCK@[306; 459) | ||
138 | L_CURLY@[306; 307) | ||
139 | WHITESPACE@[307; 316) | ||
140 | COMMENT@[316; 329) | ||
141 | WHITESPACE@[329; 338) | ||
142 | ENUM_DEF@[338; 453) | ||
143 | ENUM_KW@[338; 342) | ||
144 | WHITESPACE@[342; 343) | ||
145 | NAME@[343; 348) | ||
146 | IDENT@[343; 348) "Test4" | ||
147 | WHITESPACE@[348; 349) | ||
148 | ENUM_VARIANT_LIST@[349; 453) | ||
149 | L_CURLY@[349; 350) | ||
150 | WHITESPACE@[350; 363) | ||
151 | ENUM_VARIANT@[363; 372) | ||
152 | NAME@[363; 367) | ||
153 | IDENT@[363; 367) "Nope" | ||
154 | POS_FIELD_LIST@[367; 372) | ||
155 | L_PAREN@[367; 368) | ||
156 | POS_FIELD@[368; 371) | ||
157 | PATH_TYPE@[368; 371) | ||
158 | PATH@[368; 371) | ||
159 | PATH_SEGMENT@[368; 371) | ||
160 | NAME_REF@[368; 371) | ||
161 | IDENT@[368; 371) "i32" | ||
162 | err: `expected COMMA` | ||
163 | WHITESPACE@[371; 372) | ||
164 | err: `expected a type` | ||
165 | err: `expected R_PAREN` | ||
166 | err: `expected COMMA` | ||
167 | err: `expected enum variant` | ||
168 | ERROR@[372; 372) | ||
169 | ERROR@[372; 374) | ||
170 | L_CURLY@[372; 373) | ||
171 | R_CURLY@[373; 374) | ||
172 | err: `expected enum variant` | ||
173 | ERROR@[374; 375) | ||
174 | R_PAREN@[374; 375) | ||
175 | WHITESPACE@[375; 376) | ||
176 | COMMENT@[376; 396) | ||
177 | WHITESPACE@[396; 422) | ||
178 | COMMENT@[422; 443) | ||
179 | WHITESPACE@[443; 452) | ||
180 | R_CURLY@[452; 453) | ||
181 | WHITESPACE@[453; 458) | ||
182 | R_CURLY@[458; 459) | ||
183 | WHITESPACE@[459; 464) | ||
184 | COMMENT@[464; 486) | ||
185 | WHITESPACE@[486; 491) | ||
186 | LET_STMT@[491; 510) | ||
187 | LET_KW@[491; 494) | ||
188 | WHITESPACE@[494; 495) | ||
189 | BIND_PAT@[495; 505) | ||
190 | NAME@[495; 505) | ||
191 | IDENT@[495; 505) "bad_syntax" | ||
192 | WHITESPACE@[505; 506) | ||
193 | EQ@[506; 507) | ||
194 | WHITESPACE@[507; 508) | ||
195 | err: `expected expression` | ||
196 | ERROR@[508; 509) | ||
197 | UNDERSCORE@[508; 509) | ||
198 | SEMI@[509; 510) | ||
199 | WHITESPACE@[510; 511) | ||
200 | COMMENT@[511; 572) | ||
201 | WHITESPACE@[572; 573) | ||
202 | R_CURLY@[573; 574) | ||
203 | WHITESPACE@[574; 575) | ||
diff --git a/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs b/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs new file mode 100644 index 000000000..53c93d9e9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/fuzz-failures/0000.rs | |||
@@ -0,0 +1,199 @@ | |||
1 | //! An experimental implementation of [Rust RFC#2256 lrs); | ||
2 | let root = SyntaxNode::new_owned(root); | ||
3 | validate_block_structure(root.borrowed()); | ||
4 | File { root } | ||
5 | } | ||
6 | pub fn parse(text: &str) -> File { | ||
7 | let tokens = tokenize(&text); | ||
8 | let (green, errors) = parser_impl::parse_with::<yellow::GreenBuilder>( | ||
9 | text, &tokens, grammar::root, | ||
10 | ); | ||
11 | File::new(green, errors) | ||
12 | } | ||
13 | pub fn reparse(&self, edit: &AtomEdit) -> File { | ||
14 | self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | ||
15 | } | ||
16 | pub fn incremental_reparse(&self, edit: &AtomEdit) -> Option<File> { | ||
17 | let (node, reparser) = find_reparsable_node(self.syntax(), edit.delete)?; | ||
18 | let text = replace_range( | ||
19 | node.text().to_string(), | ||
20 | edit.delete - node.range().start(), | ||
21 | &edit.insert, | ||
22 | ); | ||
23 | let tokens = tokenize(&text); | ||
24 | if !is_balanced(&tokens) { | ||
25 | return None; | ||
26 | } | ||
27 | let (green, new_errors) = parser_impl::parse_with::<yellow::GreenBuilder>( | ||
28 | &te2t, &tokens, reparser, | ||
29 | ); | ||
30 | let green_root = node.replace_with(green); | ||
31 | let errors = merge_errors(self.errors(), new_errors, node, edit); | ||
32 | Some(File::new(green_root, errors)) | ||
33 | } | ||
34 | fn full_reparse(&self, edit: &AtomEdit) -> File { | ||
35 | let text = replace_range(self.syntax().text().to_string(), edit.delete, &edit.insert); | ||
36 | File::parse(&text) | ||
37 | } | ||
38 | pub fn ast(&self) -> ast::Root { | ||
39 | ast::Root::cast(self.syntax()).unwrap() | ||
40 | } | ||
41 | pub fn syntax(&self) -> SyntaxNodeRef { | ||
42 | self.root.brroowed() | ||
43 | } | ||
44 | mp_tree(root), | ||
45 | ); | ||
46 | assert!( | ||
47 | node.next_sibling().is_none() && pair.prev_sibling().is_none(), | ||
48 | "\nfloating curlys at {:?}\nfile:\n{}\nerror:\n{}\n", | ||
49 | node, | ||
50 | root.text(), | ||
51 | node.text(), | ||
52 | ); | ||
53 | } | ||
54 | } | ||
55 | _ => (), | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | |||
60 | #[derive(Debug, Clone)] | ||
61 | pub struct AtomEdit { | ||
62 | pub delete: TextRange, | ||
63 | pub insert: String, | ||
64 | } | ||
65 | |||
66 | impl AtomEdit { | ||
67 | pub fn replace(range: TextRange, replace_with: String) -> AtomEdit { | ||
68 | AtomEdit { delete: range, insert: replace_with } | ||
69 | } | ||
70 | |||
71 | pub fn delete(range: TextRange) -> AtomEdit { | ||
72 | AtomEdit::replace(range, String::new()) | ||
73 | } | ||
74 | |||
75 | pub fn insert(offset: TextUnit, text: String) -> AtomEdit { | ||
76 | AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text) | ||
77 | } | ||
78 | } | ||
79 | |||
80 | fn find_reparsable_node(node: SyntaxNodeRef, range: TextRange) -> Option<(SyntaxNodeRef, fn(&mut Parser))> { | ||
81 | let node = algo::find_covering_node(node, range); | ||
82 | return algo::ancestors(node) | ||
83 | .filter_map(|node| reparser(node).map(|r| (node, r))) | ||
84 | .next(); | ||
85 | |||
86 | fn reparser(node: SyntaxNodeRef) -> Option<fn(&mut Parser)> { | ||
87 | let res = match node.kind() { | ||
88 | BLOCK => grammar::block, | ||
89 | NAMED_FIELD_DEF_LIST => grammar::named_field_def_list, | ||
90 | _ => return None, | ||
91 | }; | ||
92 | Some(res) | ||
93 | } | ||
94 | } | ||
95 | |||
96 | pub /*(meh)*/ fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String { | ||
97 | let start = u32::from(range.start()) as usize; | ||
98 | let end = u32::from(range.end()) as usize; | ||
99 | text.replace_range(start..end, replace_with); | ||
100 | text | ||
101 | } | ||
102 | |||
103 | fn is_balanced(tokens: &[Token]) -> bool { | ||
104 | if tokens.len() == 0 | ||
105 | || tokens.first().unwrap().kind != L_CURLY | ||
106 | || tokens.last().unwrap().kind != R_CURLY { | ||
107 | return false | ||
108 | } | ||
109 | let mut balance = 0usize; | ||
110 | for t in tokens.iter() { | ||
111 | match t.kind { | ||
112 | L_CURLYt { | ||
113 | pub delete: TextRange, | ||
114 | pub insert: String, | ||
115 | } | ||
116 | |||
117 | impl AtomEdit { | ||
118 | pub fn replace(range: TextRange, replace_with: String) -> AtomEdit { | ||
119 | AtomEdit { delete: range, insert: replace_with } | ||
120 | } | ||
121 | |||
122 | pub fn delete(range: TextRange) -> AtomEdit { | ||
123 | AtomEdit::replace(range, String::new()) | ||
124 | } | ||
125 | |||
126 | pub fn insert(offset: TextUnit, text: String) -> AtomEdit { | ||
127 | AtomEdit::replace(TextRange::offset_len(offset, 0.into()), text) | ||
128 | } | ||
129 | } | ||
130 | |||
131 | fn find_reparsable_node(node: SyntaxNodeRef, range: TextRange) -> Option<(SyntaxNodeRef, fn(&mut Parser))> { | ||
132 | let node = algo::find_covering_node(node, range); | ||
133 | return algo::ancestors(node) | ||
134 | .filter_map(|node| reparser(node).map(|r| (node, r))) | ||
135 | .next(); | ||
136 | |||
137 | fn reparser(node: SyntaxNodeRef) -> Option<fn(&mut Parser)> { | ||
138 | let res = match node.kind() { | ||
139 | ; | ||
140 | let end = u32::from(range.end()) as usize; | ||
141 | text.replaT => grammar::named_field_def_list, | ||
142 | _ => return None, | ||
143 | }; | ||
144 | Some(res) | ||
145 | } | ||
146 | } | ||
147 | |||
148 | pub /*(meh)*/ fn replace_range(mut text: String, range: TextRange, replace_with: &str) -> String { | ||
149 | let start = u32::from(range.start()) as usize; | ||
150 | let end = u32::from(range.end()) as usize; | ||
151 | text.replace_range(start..end, replace_with); | ||
152 | text | ||
153 | } | ||
154 | |||
155 | fn is_balanced(tokens: &[Token]) -> bool { | ||
156 | if tokens.len() == 0 | ||
157 | || tokens.first().unwrap().kind != L_CURLY | ||
158 | || tokens.last().unwrap().kind != R_CURLY { | ||
159 | return false | ||
160 | } | ||
161 | let mut balance = 0usize; | ||
162 | for t in tokens.iter() { | ||
163 | match t.kind { | ||
164 | L_CURLY => balance += 1, | ||
165 | R_CURLY => balance = match balance.checked_sub(1) { | ||
166 | Some(b) => b, | ||
167 | None => return false, | ||
168 | }, | ||
169 | _ => (), | ||
170 | } | ||
171 | } | ||
172 | balance == 0 | ||
173 | } | ||
174 | |||
175 | fn merge_errors( | ||
176 | old_errors: Vec<SyntaxError>, | ||
177 | new_errors: Vec<SyntaxError>, | ||
178 | old_node: SyntaxNodeRef, | ||
179 | edit: &AtomEdit, | ||
180 | ) -> Vec<SyntaxError> { | ||
181 | let mut res = Vec::new(); | ||
182 | for e in old_errors { | ||
183 | if e.offset < old_node.range().start() { | ||
184 | res.push(e) | ||
185 | } else if e.offset > old_node.range().end() { | ||
186 | res.push(SyntaxError { | ||
187 | msg: e.msg, | ||
188 | offset: e.offset + TextUnit::of_str(&edit.insert) - edit.delete.len(), | ||
189 | }) | ||
190 | } | ||
191 | } | ||
192 | for e in new_errors { | ||
193 | res.push(SyntaxError { | ||
194 | msg: e.msg, | ||
195 | offset: e.offset + old_node.range().start(), | ||
196 | }) | ||
197 | } | ||
198 | res | ||
199 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/fuzz-failures/0001.rs b/crates/ra_syntax/tests/data/parser/fuzz-failures/0001.rs new file mode 100644 index 000000000..099cc5f84 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/fuzz-failures/0001.rs | |||
@@ -0,0 +1,106 @@ | |||
1 | use ra_syntax::{ | ||
2 | File, TextRange, SyntaxNodeRef, TextUnit, | ||
3 | SyntaxKind::*, | ||
4 | algo::{find_leaf_at_offset, LeafAtOffset, find_covering_node, ancestors, Direction, siblings}, | ||
5 | }; | ||
6 | |||
7 | pub fn extend_selection(file: &File, range: TextRange) -> Option<TextRange> { | ||
8 | let syntax = file.syntax(); | ||
9 | extend(syntax.borrowed(), range) | ||
10 | } | ||
11 | |||
12 | pub(crate) fn extend(root: SyntaxNodeRef, range: TextRange) -> Option<TextRange> { | ||
13 | if range.is_empty() { | ||
14 | let offset = range.start(); | ||
15 | let mut leaves = find_leaf_at_offset(root, offset); | ||
16 | if leaves.clone().all(|it| it.kind() == WHITESPACE) { | ||
17 | return Some(extend_ws(root, leaves.next()?, offset)); | ||
18 | } | ||
19 | let leaf = match leaves { | ||
20 | LeafAtOffset::None => return None, | ||
21 | LeafAtOffset::Single(l) => l, | ||
22 | LeafAtOffset::Between(l, r) => pick_best(l, r), | ||
23 | }; | ||
24 | return Some(leaf.range()); | ||
25 | }; | ||
26 | let node = find_covering_node(root, range); | ||
27 | if node.kind() == COMMENT && range == node.range() { | ||
28 | if let Some(range) = extend_comments(node) { | ||
29 | return Some(range); | ||
30 | } | ||
31 | } | ||
32 | |||
33 | match ancestors(node).skip_while(|n| n.range() == range).next() { | ||
34 | None => None, | ||
35 | Some(parent) => Some(parent.range()), | ||
36 | } | ||
37 | } | ||
38 | |||
39 | fn extend_ws(root: SyntaxNodeRef, ws: SyntaxNodeRef, offset: TextUnit) -> TextRange { | ||
40 | let ws_text = ws.leaf_text().unwrap(); | ||
41 | let suffix = TextRange::from_to(offset, ws.range().end()) - ws.range().start(); | ||
42 | let prefix = TextRange::from_to(ws.range().start(), offset) - ws.range().start(); | ||
43 | let ws_suffix = &ws_text.as_str()[suffix]; | ||
44 | let ws_prefix = &ws_text.as_str()[prefix]; | ||
45 | if ws_text.contains("\n") && !ws_suffix.contains("\n") { | ||
46 | if let Some(node) = ws.next_sibling() { | ||
47 | let start = match ws_prefix.rfind('\n') { | ||
48 | Some(idx) => ws.range().start() + TextUnit::from((idx + 1) as u32), | ||
49 | None => node.range().start() | ||
50 | }; | ||
51 | let end = if root.text().char_at(node.range().end()) == Some('\n') { | ||
52 | node.range().end() + TextUnit::of_char('\n') | ||
53 | } else { | ||
54 | node.range().end() | ||
55 | }; | ||
56 | return TextRange::from_to(start, end); | ||
57 | } | ||
58 | } | ||
59 | ws.range() | ||
60 | } | ||
61 | |||
62 | fn pick_best<'a>(l: SyntaxNodeRef<'a>, r: Syntd[axNodeRef<'a>) -> SyntaxNodeRef<'a> { | ||
63 | return if priority(r) > priority(l) { r } else { l }; | ||
64 | fn priority(n: SyntaxNodeRef) -> usize { | ||
65 | match n.kind() { | ||
66 | WHITESPACE => 0, | ||
67 | IDENT | SELF_KW | SUPER_KW | CRATE_KW => 2, | ||
68 | _ => 1, | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | |||
73 | fn extend_comments(node: SyntaxNodeRef) -> Option<TextRange> { | ||
74 | let left = adj_com[ments(node, Direction::Backward); | ||
75 | let right = adj_comments(node, Direction::Forward); | ||
76 | if left != right { | ||
77 | Some(TextRange::from_to( | ||
78 | left.range().start(), | ||
79 | right.range().end(), | ||
80 | )) | ||
81 | } else { | ||
82 | None | ||
83 | } | ||
84 | } | ||
85 | |||
86 | fn adj_comments(node: SyntaxNodeRef, dir: Direction) -> SyntaxNodeRef { | ||
87 | let mut res = node; | ||
88 | for node in siblings(node, dir) { | ||
89 | match node.kind() { | ||
90 | COMMENT => res = node, | ||
91 | WHITESPACE if !node.leaf_text().unwrap().as_str().contains("\n\n") => (), | ||
92 | _ => break | ||
93 | } | ||
94 | } | ||
95 | res | ||
96 | } | ||
97 | |||
98 | #[cfg(test)] | ||
99 | mod tests { | ||
100 | use super::*; | ||
101 | use test_utils::extract_offset; | ||
102 | |||
103 | fn do_check(before: &str, afters: &[&str]) { | ||
104 | let (cursor, before) = extract_offset(before); | ||
105 | let file = File::parse(&before); | ||
106 | let mut range = TextRange::of | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.rs new file mode 100644 index 000000000..31a1e435f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.rs | |||
@@ -0,0 +1 @@ | |||
const unsafe fn foo() {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.txt new file mode 100644 index 000000000..956532981 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0001_const_unsafe_fn.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | ROOT@[0; 25) | ||
2 | FN_DEF@[0; 24) | ||
3 | CONST_KW@[0; 5) | ||
4 | WHITESPACE@[5; 6) | ||
5 | UNSAFE_KW@[6; 12) | ||
6 | WHITESPACE@[12; 13) | ||
7 | FN_KW@[13; 15) | ||
8 | WHITESPACE@[15; 16) | ||
9 | NAME@[16; 19) | ||
10 | IDENT@[16; 19) "foo" | ||
11 | PARAM_LIST@[19; 21) | ||
12 | L_PAREN@[19; 20) | ||
13 | R_PAREN@[20; 21) | ||
14 | WHITESPACE@[21; 22) | ||
15 | BLOCK@[22; 24) | ||
16 | L_CURLY@[22; 23) | ||
17 | R_CURLY@[23; 24) | ||
18 | WHITESPACE@[24; 25) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.rs new file mode 100644 index 000000000..8c84d9cd7 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.rs | |||
@@ -0,0 +1 @@ | |||
const fn foo() {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.txt new file mode 100644 index 000000000..bda875fc5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0002_const_fn.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | ROOT@[0; 18) | ||
2 | FN_DEF@[0; 17) | ||
3 | CONST_KW@[0; 5) | ||
4 | WHITESPACE@[5; 6) | ||
5 | FN_KW@[6; 8) | ||
6 | WHITESPACE@[8; 9) | ||
7 | NAME@[9; 12) | ||
8 | IDENT@[9; 12) "foo" | ||
9 | PARAM_LIST@[12; 14) | ||
10 | L_PAREN@[12; 13) | ||
11 | R_PAREN@[13; 14) | ||
12 | WHITESPACE@[14; 15) | ||
13 | BLOCK@[15; 17) | ||
14 | L_CURLY@[15; 16) | ||
15 | R_CURLY@[16; 17) | ||
16 | WHITESPACE@[17; 18) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.rs b/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.rs new file mode 100644 index 000000000..26a9ccd1e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.rs | |||
@@ -0,0 +1 @@ | |||
extern {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.txt b/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.txt new file mode 100644 index 000000000..2c2bbd035 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0003_extern_block.txt | |||
@@ -0,0 +1,9 @@ | |||
1 | ROOT@[0; 10) | ||
2 | EXTERN_BLOCK@[0; 9) | ||
3 | ABI@[0; 6) | ||
4 | EXTERN_KW@[0; 6) | ||
5 | WHITESPACE@[6; 7) | ||
6 | EXTERN_ITEM_LIST@[7; 9) | ||
7 | L_CURLY@[7; 8) | ||
8 | R_CURLY@[8; 9) | ||
9 | WHITESPACE@[9; 10) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.rs new file mode 100644 index 000000000..394a049f0 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.rs | |||
@@ -0,0 +1 @@ | |||
extern fn foo() {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.txt new file mode 100644 index 000000000..f6e769475 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0004_extern_fn.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | ROOT@[0; 19) | ||
2 | FN_DEF@[0; 18) | ||
3 | ABI@[0; 6) | ||
4 | EXTERN_KW@[0; 6) | ||
5 | WHITESPACE@[6; 7) | ||
6 | FN_KW@[7; 9) | ||
7 | WHITESPACE@[9; 10) | ||
8 | NAME@[10; 13) | ||
9 | IDENT@[10; 13) "foo" | ||
10 | PARAM_LIST@[13; 15) | ||
11 | L_PAREN@[13; 14) | ||
12 | R_PAREN@[14; 15) | ||
13 | WHITESPACE@[15; 16) | ||
14 | BLOCK@[16; 18) | ||
15 | L_CURLY@[16; 17) | ||
16 | R_CURLY@[17; 18) | ||
17 | WHITESPACE@[18; 19) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.rs b/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.rs new file mode 100644 index 000000000..49af74e1b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.rs | |||
@@ -0,0 +1 @@ | |||
extern crate foo; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.txt b/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.txt new file mode 100644 index 000000000..fc025b0f3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0005_extern_crate.txt | |||
@@ -0,0 +1,10 @@ | |||
1 | ROOT@[0; 18) | ||
2 | EXTERN_CRATE_ITEM@[0; 17) | ||
3 | EXTERN_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | CRATE_KW@[7; 12) | ||
6 | WHITESPACE@[12; 13) | ||
7 | NAME@[13; 16) | ||
8 | IDENT@[13; 16) "foo" | ||
9 | SEMI@[16; 17) | ||
10 | WHITESPACE@[17; 18) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.rs b/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.rs new file mode 100644 index 000000000..04e021550 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.rs | |||
@@ -0,0 +1 @@ | |||
unsafe trait T {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.txt b/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.txt new file mode 100644 index 000000000..fb97cc042 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0007_unsafe_trait.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | ROOT@[0; 18) | ||
2 | TRAIT_DEF@[0; 17) | ||
3 | UNSAFE_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | TRAIT_KW@[7; 12) | ||
6 | WHITESPACE@[12; 13) | ||
7 | NAME@[13; 14) | ||
8 | IDENT@[13; 14) "T" | ||
9 | WHITESPACE@[14; 15) | ||
10 | ITEM_LIST@[15; 17) | ||
11 | L_CURLY@[15; 16) | ||
12 | R_CURLY@[16; 17) | ||
13 | WHITESPACE@[17; 18) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.rs b/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.rs new file mode 100644 index 000000000..41055f41d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.rs | |||
@@ -0,0 +1 @@ | |||
unsafe impl Foo {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.txt b/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.txt new file mode 100644 index 000000000..fa596394f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0008_unsafe_impl.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | ROOT@[0; 19) | ||
2 | IMPL_ITEM@[0; 18) | ||
3 | UNSAFE_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | IMPL_KW@[7; 11) | ||
6 | WHITESPACE@[11; 12) | ||
7 | PATH_TYPE@[12; 15) | ||
8 | PATH@[12; 15) | ||
9 | PATH_SEGMENT@[12; 15) | ||
10 | NAME_REF@[12; 15) | ||
11 | IDENT@[12; 15) "Foo" | ||
12 | WHITESPACE@[15; 16) | ||
13 | ITEM_LIST@[16; 18) | ||
14 | L_CURLY@[16; 17) | ||
15 | R_CURLY@[17; 18) | ||
16 | WHITESPACE@[18; 19) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.rs b/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.rs new file mode 100644 index 000000000..03d29f324 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.rs | |||
@@ -0,0 +1 @@ | |||
unsafe auto trait T {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.txt b/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.txt new file mode 100644 index 000000000..e642bbf80 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0009_unsafe_auto_trait.txt | |||
@@ -0,0 +1,15 @@ | |||
1 | ROOT@[0; 23) | ||
2 | TRAIT_DEF@[0; 22) | ||
3 | UNSAFE_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | AUTO_KW@[7; 11) | ||
6 | WHITESPACE@[11; 12) | ||
7 | TRAIT_KW@[12; 17) | ||
8 | WHITESPACE@[17; 18) | ||
9 | NAME@[18; 19) | ||
10 | IDENT@[18; 19) "T" | ||
11 | WHITESPACE@[19; 20) | ||
12 | ITEM_LIST@[20; 22) | ||
13 | L_CURLY@[20; 21) | ||
14 | R_CURLY@[21; 22) | ||
15 | WHITESPACE@[22; 23) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.rs b/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.rs new file mode 100644 index 000000000..9cd6c57bd --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.rs | |||
@@ -0,0 +1 @@ | |||
unsafe default impl Foo {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.txt b/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.txt new file mode 100644 index 000000000..99d33a902 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0010_unsafe_default_impl.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | ROOT@[0; 27) | ||
2 | IMPL_ITEM@[0; 26) | ||
3 | UNSAFE_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | DEFAULT_KW@[7; 14) | ||
6 | WHITESPACE@[14; 15) | ||
7 | IMPL_KW@[15; 19) | ||
8 | WHITESPACE@[19; 20) | ||
9 | PATH_TYPE@[20; 23) | ||
10 | PATH@[20; 23) | ||
11 | PATH_SEGMENT@[20; 23) | ||
12 | NAME_REF@[20; 23) | ||
13 | IDENT@[20; 23) "Foo" | ||
14 | WHITESPACE@[23; 24) | ||
15 | ITEM_LIST@[24; 26) | ||
16 | L_CURLY@[24; 25) | ||
17 | R_CURLY@[25; 26) | ||
18 | WHITESPACE@[26; 27) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.rs new file mode 100644 index 000000000..33cfc4cd7 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.rs | |||
@@ -0,0 +1 @@ | |||
unsafe fn foo() {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.txt new file mode 100644 index 000000000..39ec53b26 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0011_unsafe_fn.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | ROOT@[0; 19) | ||
2 | FN_DEF@[0; 18) | ||
3 | UNSAFE_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | FN_KW@[7; 9) | ||
6 | WHITESPACE@[9; 10) | ||
7 | NAME@[10; 13) | ||
8 | IDENT@[10; 13) "foo" | ||
9 | PARAM_LIST@[13; 15) | ||
10 | L_PAREN@[13; 14) | ||
11 | R_PAREN@[14; 15) | ||
12 | WHITESPACE@[15; 16) | ||
13 | BLOCK@[16; 18) | ||
14 | L_CURLY@[16; 17) | ||
15 | R_CURLY@[17; 18) | ||
16 | WHITESPACE@[18; 19) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.rs new file mode 100644 index 000000000..1295c2cd2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.rs | |||
@@ -0,0 +1 @@ | |||
unsafe extern "C" fn foo() {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.txt new file mode 100644 index 000000000..54e296ed6 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0012_unsafe_extern_fn.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | ROOT@[0; 30) | ||
2 | FN_DEF@[0; 29) | ||
3 | UNSAFE_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | ABI@[7; 17) | ||
6 | EXTERN_KW@[7; 13) | ||
7 | WHITESPACE@[13; 14) | ||
8 | STRING@[14; 17) | ||
9 | WHITESPACE@[17; 18) | ||
10 | FN_KW@[18; 20) | ||
11 | WHITESPACE@[20; 21) | ||
12 | NAME@[21; 24) | ||
13 | IDENT@[21; 24) "foo" | ||
14 | PARAM_LIST@[24; 26) | ||
15 | L_PAREN@[24; 25) | ||
16 | R_PAREN@[25; 26) | ||
17 | WHITESPACE@[26; 27) | ||
18 | BLOCK@[27; 29) | ||
19 | L_CURLY@[27; 28) | ||
20 | R_CURLY@[28; 29) | ||
21 | WHITESPACE@[29; 30) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.rs b/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.rs new file mode 100644 index 000000000..26141e904 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.rs | |||
@@ -0,0 +1 @@ | |||
fn foo(){} unsafe { } fn bar(){} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.txt b/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.txt new file mode 100644 index 000000000..9825e5ace --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0013_unsafe_block_in_mod.txt | |||
@@ -0,0 +1,35 @@ | |||
1 | ROOT@[0; 33) | ||
2 | FN_DEF@[0; 10) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | BLOCK@[8; 10) | ||
11 | L_CURLY@[8; 9) | ||
12 | R_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 11) | ||
14 | err: `expected an item` | ||
15 | ERROR@[11; 17) | ||
16 | UNSAFE_KW@[11; 17) | ||
17 | WHITESPACE@[17; 18) | ||
18 | err: `expected an item` | ||
19 | ERROR@[18; 21) | ||
20 | L_CURLY@[18; 19) | ||
21 | WHITESPACE@[19; 20) | ||
22 | R_CURLY@[20; 21) | ||
23 | WHITESPACE@[21; 22) | ||
24 | FN_DEF@[22; 32) | ||
25 | FN_KW@[22; 24) | ||
26 | WHITESPACE@[24; 25) | ||
27 | NAME@[25; 28) | ||
28 | IDENT@[25; 28) "bar" | ||
29 | PARAM_LIST@[28; 30) | ||
30 | L_PAREN@[28; 29) | ||
31 | R_PAREN@[29; 30) | ||
32 | BLOCK@[30; 32) | ||
33 | L_CURLY@[30; 31) | ||
34 | R_CURLY@[31; 32) | ||
35 | WHITESPACE@[32; 33) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.rs b/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.rs new file mode 100644 index 000000000..defd110c4 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.rs | |||
@@ -0,0 +1 @@ | |||
type Result<T> = (); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.txt b/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.txt new file mode 100644 index 000000000..bf65e8a37 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0014_type_item_type_params.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | ROOT@[0; 21) | ||
2 | TYPE_DEF@[0; 20) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 11) | ||
6 | IDENT@[5; 11) "Result" | ||
7 | TYPE_PARAM_LIST@[11; 14) | ||
8 | L_ANGLE@[11; 12) | ||
9 | TYPE_PARAM@[12; 13) | ||
10 | NAME@[12; 13) | ||
11 | IDENT@[12; 13) "T" | ||
12 | R_ANGLE@[13; 14) | ||
13 | WHITESPACE@[14; 15) | ||
14 | EQ@[15; 16) | ||
15 | WHITESPACE@[16; 17) | ||
16 | TUPLE_TYPE@[17; 19) | ||
17 | L_PAREN@[17; 18) | ||
18 | R_PAREN@[18; 19) | ||
19 | SEMI@[19; 20) | ||
20 | WHITESPACE@[20; 21) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0015_type_item.rs b/crates/ra_syntax/tests/data/parser/inline/0015_type_item.rs new file mode 100644 index 000000000..04c0344fa --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0015_type_item.rs | |||
@@ -0,0 +1 @@ | |||
type Foo = Bar; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0015_type_item.txt b/crates/ra_syntax/tests/data/parser/inline/0015_type_item.txt new file mode 100644 index 000000000..71048bcc5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0015_type_item.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | ROOT@[0; 16) | ||
2 | TYPE_DEF@[0; 15) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 8) | ||
6 | IDENT@[5; 8) "Foo" | ||
7 | WHITESPACE@[8; 9) | ||
8 | EQ@[9; 10) | ||
9 | WHITESPACE@[10; 11) | ||
10 | PATH_TYPE@[11; 14) | ||
11 | PATH@[11; 14) | ||
12 | PATH_SEGMENT@[11; 14) | ||
13 | NAME_REF@[11; 14) | ||
14 | IDENT@[11; 14) "Bar" | ||
15 | SEMI@[14; 15) | ||
16 | WHITESPACE@[15; 16) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.rs b/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.rs new file mode 100644 index 000000000..a602d07f0 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.rs | |||
@@ -0,0 +1 @@ | |||
type Foo where Foo: Copy = (); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.txt b/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.txt new file mode 100644 index 000000000..c3fca013e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0016_type_item_where_clause.txt | |||
@@ -0,0 +1,32 @@ | |||
1 | ROOT@[0; 31) | ||
2 | TYPE_DEF@[0; 30) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 8) | ||
6 | IDENT@[5; 8) "Foo" | ||
7 | WHITESPACE@[8; 9) | ||
8 | WHERE_CLAUSE@[9; 24) | ||
9 | WHERE_KW@[9; 14) | ||
10 | WHITESPACE@[14; 15) | ||
11 | WHERE_PRED@[15; 24) | ||
12 | PATH_TYPE@[15; 18) | ||
13 | PATH@[15; 18) | ||
14 | PATH_SEGMENT@[15; 18) | ||
15 | NAME_REF@[15; 18) | ||
16 | IDENT@[15; 18) "Foo" | ||
17 | COLON@[18; 19) | ||
18 | WHITESPACE@[19; 20) | ||
19 | PATH_TYPE@[20; 24) | ||
20 | PATH@[20; 24) | ||
21 | PATH_SEGMENT@[20; 24) | ||
22 | NAME_REF@[20; 24) | ||
23 | IDENT@[20; 24) "Copy" | ||
24 | err: `expected COMMA` | ||
25 | WHITESPACE@[24; 25) | ||
26 | EQ@[25; 26) | ||
27 | WHITESPACE@[26; 27) | ||
28 | TUPLE_TYPE@[27; 29) | ||
29 | L_PAREN@[27; 28) | ||
30 | R_PAREN@[28; 29) | ||
31 | SEMI@[29; 30) | ||
32 | WHITESPACE@[30; 31) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.rs b/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.rs new file mode 100644 index 000000000..6e1b25101 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.rs | |||
@@ -0,0 +1 @@ | |||
type T = (i32); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.txt b/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.txt new file mode 100644 index 000000000..97e73fea1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0017_paren_type.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | ROOT@[0; 16) | ||
2 | TYPE_DEF@[0; 15) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "T" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | PAREN_TYPE@[9; 14) | ||
11 | L_PAREN@[9; 10) | ||
12 | PATH_TYPE@[10; 13) | ||
13 | PATH@[10; 13) | ||
14 | PATH_SEGMENT@[10; 13) | ||
15 | NAME_REF@[10; 13) | ||
16 | IDENT@[10; 13) "i32" | ||
17 | R_PAREN@[13; 14) | ||
18 | SEMI@[14; 15) | ||
19 | WHITESPACE@[15; 16) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.rs b/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.rs new file mode 100644 index 000000000..c039cf7d3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.rs | |||
@@ -0,0 +1 @@ | |||
type T = (); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.txt b/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.txt new file mode 100644 index 000000000..5d04d42fc --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0018_unit_type.txt | |||
@@ -0,0 +1,14 @@ | |||
1 | ROOT@[0; 13) | ||
2 | TYPE_DEF@[0; 12) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "T" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | TUPLE_TYPE@[9; 11) | ||
11 | L_PAREN@[9; 10) | ||
12 | R_PAREN@[10; 11) | ||
13 | SEMI@[11; 12) | ||
14 | WHITESPACE@[12; 13) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.rs b/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.rs new file mode 100644 index 000000000..cb66bad24 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.rs | |||
@@ -0,0 +1 @@ | |||
type T = (i32,); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.txt b/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.txt new file mode 100644 index 000000000..2cd8be9ab --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0019_singleton_tuple_type.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | ROOT@[0; 17) | ||
2 | TYPE_DEF@[0; 16) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "T" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | TUPLE_TYPE@[9; 15) | ||
11 | L_PAREN@[9; 10) | ||
12 | PATH_TYPE@[10; 13) | ||
13 | PATH@[10; 13) | ||
14 | PATH_SEGMENT@[10; 13) | ||
15 | NAME_REF@[10; 13) | ||
16 | IDENT@[10; 13) "i32" | ||
17 | COMMA@[13; 14) | ||
18 | R_PAREN@[14; 15) | ||
19 | SEMI@[15; 16) | ||
20 | WHITESPACE@[16; 17) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0020_never_type.rs b/crates/ra_syntax/tests/data/parser/inline/0020_never_type.rs new file mode 100644 index 000000000..de399fcf4 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0020_never_type.rs | |||
@@ -0,0 +1 @@ | |||
type Never = !; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0020_never_type.txt b/crates/ra_syntax/tests/data/parser/inline/0020_never_type.txt new file mode 100644 index 000000000..6205d9669 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0020_never_type.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | ROOT@[0; 16) | ||
2 | TYPE_DEF@[0; 15) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 10) | ||
6 | IDENT@[5; 10) "Never" | ||
7 | WHITESPACE@[10; 11) | ||
8 | EQ@[11; 12) | ||
9 | WHITESPACE@[12; 13) | ||
10 | NEVER_TYPE@[13; 14) | ||
11 | EXCL@[13; 14) | ||
12 | SEMI@[14; 15) | ||
13 | WHITESPACE@[15; 16) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.rs b/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.rs new file mode 100644 index 000000000..fae705131 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.rs | |||
@@ -0,0 +1 @@ | |||
type T = *(); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.txt b/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.txt new file mode 100644 index 000000000..23e68557a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0021_pointer_type_no_mutability.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | ROOT@[0; 14) | ||
2 | TYPE_DEF@[0; 13) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "T" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | POINTER_TYPE@[9; 12) | ||
11 | STAR@[9; 10) | ||
12 | err: `expected mut or const in raw pointer type (use `*mut T` or `*const T` as appropriate)` | ||
13 | TUPLE_TYPE@[10; 12) | ||
14 | L_PAREN@[10; 11) | ||
15 | R_PAREN@[11; 12) | ||
16 | SEMI@[12; 13) | ||
17 | WHITESPACE@[13; 14) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.rs b/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.rs new file mode 100644 index 000000000..04b2bb9ba --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | type M = *mut (); | ||
2 | type C = *mut (); | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.txt b/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.txt new file mode 100644 index 000000000..33f5ad8b4 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0022_pointer_type_mut.txt | |||
@@ -0,0 +1,35 @@ | |||
1 | ROOT@[0; 36) | ||
2 | TYPE_DEF@[0; 17) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "M" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | POINTER_TYPE@[9; 16) | ||
11 | STAR@[9; 10) | ||
12 | MUT_KW@[10; 13) | ||
13 | WHITESPACE@[13; 14) | ||
14 | TUPLE_TYPE@[14; 16) | ||
15 | L_PAREN@[14; 15) | ||
16 | R_PAREN@[15; 16) | ||
17 | SEMI@[16; 17) | ||
18 | WHITESPACE@[17; 18) | ||
19 | TYPE_DEF@[18; 35) | ||
20 | TYPE_KW@[18; 22) | ||
21 | WHITESPACE@[22; 23) | ||
22 | NAME@[23; 24) | ||
23 | IDENT@[23; 24) "C" | ||
24 | WHITESPACE@[24; 25) | ||
25 | EQ@[25; 26) | ||
26 | WHITESPACE@[26; 27) | ||
27 | POINTER_TYPE@[27; 34) | ||
28 | STAR@[27; 28) | ||
29 | MUT_KW@[28; 31) | ||
30 | WHITESPACE@[31; 32) | ||
31 | TUPLE_TYPE@[32; 34) | ||
32 | L_PAREN@[32; 33) | ||
33 | R_PAREN@[33; 34) | ||
34 | SEMI@[34; 35) | ||
35 | WHITESPACE@[35; 36) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.rs b/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.rs new file mode 100644 index 000000000..a94851443 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.rs | |||
@@ -0,0 +1 @@ | |||
type T = [() 92]; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.txt b/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.txt new file mode 100644 index 000000000..90bdc5d2e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0023_array_type_missing_semi.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | ROOT@[0; 18) | ||
2 | TYPE_DEF@[0; 12) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "T" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | SLICE_TYPE@[9; 12) | ||
11 | L_BRACK@[9; 10) | ||
12 | TUPLE_TYPE@[10; 12) | ||
13 | L_PAREN@[10; 11) | ||
14 | R_PAREN@[11; 12) | ||
15 | err: `expected `;` or `]`` | ||
16 | err: `expected SEMI` | ||
17 | WHITESPACE@[12; 13) | ||
18 | err: `expected an item` | ||
19 | ERROR@[13; 15) | ||
20 | INT_NUMBER@[13; 15) "92" | ||
21 | err: `expected an item` | ||
22 | ERROR@[15; 16) | ||
23 | R_BRACK@[15; 16) | ||
24 | err: `expected an item` | ||
25 | ERROR@[16; 17) | ||
26 | SEMI@[16; 17) | ||
27 | WHITESPACE@[17; 18) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0024_array_type.rs b/crates/ra_syntax/tests/data/parser/inline/0024_array_type.rs new file mode 100644 index 000000000..27eb22f22 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0024_array_type.rs | |||
@@ -0,0 +1 @@ | |||
type T = [(); 92]; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0024_array_type.txt b/crates/ra_syntax/tests/data/parser/inline/0024_array_type.txt new file mode 100644 index 000000000..809c86974 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0024_array_type.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | ROOT@[0; 19) | ||
2 | TYPE_DEF@[0; 18) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "T" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | ARRAY_TYPE@[9; 17) | ||
11 | L_BRACK@[9; 10) | ||
12 | TUPLE_TYPE@[10; 12) | ||
13 | L_PAREN@[10; 11) | ||
14 | R_PAREN@[11; 12) | ||
15 | SEMI@[12; 13) | ||
16 | WHITESPACE@[13; 14) | ||
17 | LITERAL@[14; 16) | ||
18 | INT_NUMBER@[14; 16) "92" | ||
19 | R_BRACK@[16; 17) | ||
20 | SEMI@[17; 18) | ||
21 | WHITESPACE@[18; 19) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.rs b/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.rs new file mode 100644 index 000000000..4da1af827 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.rs | |||
@@ -0,0 +1 @@ | |||
type T = [()]; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.txt b/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.txt new file mode 100644 index 000000000..978530a6a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0025_slice_type.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | ROOT@[0; 15) | ||
2 | TYPE_DEF@[0; 14) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "T" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | SLICE_TYPE@[9; 13) | ||
11 | L_BRACK@[9; 10) | ||
12 | TUPLE_TYPE@[10; 12) | ||
13 | L_PAREN@[10; 11) | ||
14 | R_PAREN@[11; 12) | ||
15 | R_BRACK@[12; 13) | ||
16 | SEMI@[13; 14) | ||
17 | WHITESPACE@[14; 15) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.rs b/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.rs new file mode 100644 index 000000000..3ac0badab --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | type A = &(); | ||
2 | type B = &'static (); | ||
3 | type C = &mut (); | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.txt b/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.txt new file mode 100644 index 000000000..ff27ce5dd --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0026_reference_type;.txt | |||
@@ -0,0 +1,50 @@ | |||
1 | ROOT@[0; 54) | ||
2 | TYPE_DEF@[0; 13) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | REFERENCE_TYPE@[9; 12) | ||
11 | AMP@[9; 10) | ||
12 | TUPLE_TYPE@[10; 12) | ||
13 | L_PAREN@[10; 11) | ||
14 | R_PAREN@[11; 12) | ||
15 | SEMI@[12; 13) | ||
16 | WHITESPACE@[13; 14) | ||
17 | TYPE_DEF@[14; 35) | ||
18 | TYPE_KW@[14; 18) | ||
19 | WHITESPACE@[18; 19) | ||
20 | NAME@[19; 20) | ||
21 | IDENT@[19; 20) "B" | ||
22 | WHITESPACE@[20; 21) | ||
23 | EQ@[21; 22) | ||
24 | WHITESPACE@[22; 23) | ||
25 | REFERENCE_TYPE@[23; 34) | ||
26 | AMP@[23; 24) | ||
27 | LIFETIME@[24; 31) "'static" | ||
28 | WHITESPACE@[31; 32) | ||
29 | TUPLE_TYPE@[32; 34) | ||
30 | L_PAREN@[32; 33) | ||
31 | R_PAREN@[33; 34) | ||
32 | SEMI@[34; 35) | ||
33 | WHITESPACE@[35; 36) | ||
34 | TYPE_DEF@[36; 53) | ||
35 | TYPE_KW@[36; 40) | ||
36 | WHITESPACE@[40; 41) | ||
37 | NAME@[41; 42) | ||
38 | IDENT@[41; 42) "C" | ||
39 | WHITESPACE@[42; 43) | ||
40 | EQ@[43; 44) | ||
41 | WHITESPACE@[44; 45) | ||
42 | REFERENCE_TYPE@[45; 52) | ||
43 | AMP@[45; 46) | ||
44 | MUT_KW@[46; 49) | ||
45 | WHITESPACE@[49; 50) | ||
46 | TUPLE_TYPE@[50; 52) | ||
47 | L_PAREN@[50; 51) | ||
48 | R_PAREN@[51; 52) | ||
49 | SEMI@[52; 53) | ||
50 | WHITESPACE@[53; 54) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.rs b/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.rs new file mode 100644 index 000000000..7952dbd57 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.rs | |||
@@ -0,0 +1 @@ | |||
type Placeholder = _; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.txt b/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.txt new file mode 100644 index 000000000..538e4e69c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0027_placeholder_type.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | ROOT@[0; 22) | ||
2 | TYPE_DEF@[0; 21) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 16) | ||
6 | IDENT@[5; 16) "Placeholder" | ||
7 | WHITESPACE@[16; 17) | ||
8 | EQ@[17; 18) | ||
9 | WHITESPACE@[18; 19) | ||
10 | PLACEHOLDER_TYPE@[19; 20) | ||
11 | UNDERSCORE@[19; 20) | ||
12 | SEMI@[20; 21) | ||
13 | WHITESPACE@[21; 22) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.rs b/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.rs new file mode 100644 index 000000000..c9bf3bdb4 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | type A = fn(); | ||
2 | type B = unsafe fn(); | ||
3 | type C = unsafe extern "C" fn(); | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.txt b/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.txt new file mode 100644 index 000000000..4dba83eb5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0028_fn_pointer_type.txt | |||
@@ -0,0 +1,55 @@ | |||
1 | ROOT@[0; 70) | ||
2 | TYPE_DEF@[0; 14) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | FN_POINTER_TYPE@[9; 13) | ||
11 | FN_KW@[9; 11) | ||
12 | PARAM_LIST@[11; 13) | ||
13 | L_PAREN@[11; 12) | ||
14 | R_PAREN@[12; 13) | ||
15 | SEMI@[13; 14) | ||
16 | WHITESPACE@[14; 15) | ||
17 | TYPE_DEF@[15; 36) | ||
18 | TYPE_KW@[15; 19) | ||
19 | WHITESPACE@[19; 20) | ||
20 | NAME@[20; 21) | ||
21 | IDENT@[20; 21) "B" | ||
22 | WHITESPACE@[21; 22) | ||
23 | EQ@[22; 23) | ||
24 | WHITESPACE@[23; 24) | ||
25 | FN_POINTER_TYPE@[24; 35) | ||
26 | UNSAFE_KW@[24; 30) | ||
27 | WHITESPACE@[30; 31) | ||
28 | FN_KW@[31; 33) | ||
29 | PARAM_LIST@[33; 35) | ||
30 | L_PAREN@[33; 34) | ||
31 | R_PAREN@[34; 35) | ||
32 | SEMI@[35; 36) | ||
33 | WHITESPACE@[36; 37) | ||
34 | TYPE_DEF@[37; 69) | ||
35 | TYPE_KW@[37; 41) | ||
36 | WHITESPACE@[41; 42) | ||
37 | NAME@[42; 43) | ||
38 | IDENT@[42; 43) "C" | ||
39 | WHITESPACE@[43; 44) | ||
40 | EQ@[44; 45) | ||
41 | WHITESPACE@[45; 46) | ||
42 | FN_POINTER_TYPE@[46; 68) | ||
43 | UNSAFE_KW@[46; 52) | ||
44 | WHITESPACE@[52; 53) | ||
45 | ABI@[53; 63) | ||
46 | EXTERN_KW@[53; 59) | ||
47 | WHITESPACE@[59; 60) | ||
48 | STRING@[60; 63) | ||
49 | WHITESPACE@[63; 64) | ||
50 | FN_KW@[64; 66) | ||
51 | PARAM_LIST@[66; 68) | ||
52 | L_PAREN@[66; 67) | ||
53 | R_PAREN@[67; 68) | ||
54 | SEMI@[68; 69) | ||
55 | WHITESPACE@[69; 70) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs b/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs new file mode 100644 index 000000000..f014914ff --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.rs | |||
@@ -0,0 +1 @@ | |||
type F = unsafe (); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt b/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt new file mode 100644 index 000000000..fa0771ab1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0029_fn_pointer_type_missing_fn.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | ROOT@[0; 20) | ||
2 | TYPE_DEF@[0; 15) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "F" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | UNSAFE_KW@[9; 15) | ||
11 | err: `expected `fn`` | ||
12 | err: `expected SEMI` | ||
13 | WHITESPACE@[15; 16) | ||
14 | err: `expected an item` | ||
15 | ERROR@[16; 17) | ||
16 | L_PAREN@[16; 17) | ||
17 | err: `expected an item` | ||
18 | ERROR@[17; 18) | ||
19 | R_PAREN@[17; 18) | ||
20 | err: `expected an item` | ||
21 | ERROR@[18; 19) | ||
22 | SEMI@[18; 19) | ||
23 | WHITESPACE@[19; 20) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs b/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs new file mode 100644 index 000000000..e3ba5e87f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.rs | |||
@@ -0,0 +1 @@ | |||
type F = fn() -> (); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt b/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt new file mode 100644 index 000000000..203839636 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0030_fn_pointer_type_with_ret.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | ROOT@[0; 21) | ||
2 | TYPE_DEF@[0; 20) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "F" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | FN_POINTER_TYPE@[9; 19) | ||
11 | FN_KW@[9; 11) | ||
12 | PARAM_LIST@[11; 13) | ||
13 | L_PAREN@[11; 12) | ||
14 | R_PAREN@[12; 13) | ||
15 | WHITESPACE@[13; 14) | ||
16 | RET_TYPE@[14; 19) | ||
17 | THIN_ARROW@[14; 16) | ||
18 | WHITESPACE@[16; 17) | ||
19 | TUPLE_TYPE@[17; 19) | ||
20 | L_PAREN@[17; 18) | ||
21 | R_PAREN@[18; 19) | ||
22 | SEMI@[19; 20) | ||
23 | WHITESPACE@[20; 21) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0031_for_type.rs b/crates/ra_syntax/tests/data/parser/inline/0031_for_type.rs new file mode 100644 index 000000000..4d6a18c6b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0031_for_type.rs | |||
@@ -0,0 +1 @@ | |||
type A = for<'a> fn() -> (); | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0031_for_type.txt b/crates/ra_syntax/tests/data/parser/inline/0031_for_type.txt new file mode 100644 index 000000000..f6b962b2c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0031_for_type.txt | |||
@@ -0,0 +1,31 @@ | |||
1 | ROOT@[0; 29) | ||
2 | TYPE_DEF@[0; 28) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | FOR_TYPE@[9; 27) | ||
11 | FOR_KW@[9; 12) | ||
12 | TYPE_PARAM_LIST@[12; 16) | ||
13 | L_ANGLE@[12; 13) | ||
14 | LIFETIME_PARAM@[13; 15) | ||
15 | LIFETIME@[13; 15) "'a" | ||
16 | R_ANGLE@[15; 16) | ||
17 | WHITESPACE@[16; 17) | ||
18 | FN_POINTER_TYPE@[17; 27) | ||
19 | FN_KW@[17; 19) | ||
20 | PARAM_LIST@[19; 21) | ||
21 | L_PAREN@[19; 20) | ||
22 | R_PAREN@[20; 21) | ||
23 | WHITESPACE@[21; 22) | ||
24 | RET_TYPE@[22; 27) | ||
25 | THIN_ARROW@[22; 24) | ||
26 | WHITESPACE@[24; 25) | ||
27 | TUPLE_TYPE@[25; 27) | ||
28 | L_PAREN@[25; 26) | ||
29 | R_PAREN@[26; 27) | ||
30 | SEMI@[27; 28) | ||
31 | WHITESPACE@[28; 29) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0032_path_type.rs b/crates/ra_syntax/tests/data/parser/inline/0032_path_type.rs new file mode 100644 index 000000000..bf94f32e1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0032_path_type.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | type A = Foo; | ||
2 | type B = ::Foo; | ||
3 | type C = self::Foo; | ||
4 | type D = super::Foo; | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0032_path_type.txt b/crates/ra_syntax/tests/data/parser/inline/0032_path_type.txt new file mode 100644 index 000000000..b0a110a2c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0032_path_type.txt | |||
@@ -0,0 +1,70 @@ | |||
1 | ROOT@[0; 71) | ||
2 | TYPE_DEF@[0; 13) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | PATH_TYPE@[9; 12) | ||
11 | PATH@[9; 12) | ||
12 | PATH_SEGMENT@[9; 12) | ||
13 | NAME_REF@[9; 12) | ||
14 | IDENT@[9; 12) "Foo" | ||
15 | SEMI@[12; 13) | ||
16 | WHITESPACE@[13; 14) | ||
17 | TYPE_DEF@[14; 29) | ||
18 | TYPE_KW@[14; 18) | ||
19 | WHITESPACE@[18; 19) | ||
20 | NAME@[19; 20) | ||
21 | IDENT@[19; 20) "B" | ||
22 | WHITESPACE@[20; 21) | ||
23 | EQ@[21; 22) | ||
24 | WHITESPACE@[22; 23) | ||
25 | PATH_TYPE@[23; 28) | ||
26 | PATH@[23; 28) | ||
27 | PATH_SEGMENT@[23; 28) | ||
28 | COLONCOLON@[23; 25) | ||
29 | NAME_REF@[25; 28) | ||
30 | IDENT@[25; 28) "Foo" | ||
31 | SEMI@[28; 29) | ||
32 | WHITESPACE@[29; 30) | ||
33 | TYPE_DEF@[30; 49) | ||
34 | TYPE_KW@[30; 34) | ||
35 | WHITESPACE@[34; 35) | ||
36 | NAME@[35; 36) | ||
37 | IDENT@[35; 36) "C" | ||
38 | WHITESPACE@[36; 37) | ||
39 | EQ@[37; 38) | ||
40 | WHITESPACE@[38; 39) | ||
41 | PATH_TYPE@[39; 48) | ||
42 | PATH@[39; 48) | ||
43 | PATH@[39; 43) | ||
44 | PATH_SEGMENT@[39; 43) | ||
45 | SELF_KW@[39; 43) | ||
46 | COLONCOLON@[43; 45) | ||
47 | PATH_SEGMENT@[45; 48) | ||
48 | NAME_REF@[45; 48) | ||
49 | IDENT@[45; 48) "Foo" | ||
50 | SEMI@[48; 49) | ||
51 | WHITESPACE@[49; 50) | ||
52 | TYPE_DEF@[50; 70) | ||
53 | TYPE_KW@[50; 54) | ||
54 | WHITESPACE@[54; 55) | ||
55 | NAME@[55; 56) | ||
56 | IDENT@[55; 56) "D" | ||
57 | WHITESPACE@[56; 57) | ||
58 | EQ@[57; 58) | ||
59 | WHITESPACE@[58; 59) | ||
60 | PATH_TYPE@[59; 69) | ||
61 | PATH@[59; 69) | ||
62 | PATH@[59; 64) | ||
63 | PATH_SEGMENT@[59; 64) | ||
64 | SUPER_KW@[59; 64) | ||
65 | COLONCOLON@[64; 66) | ||
66 | PATH_SEGMENT@[66; 69) | ||
67 | NAME_REF@[66; 69) | ||
68 | IDENT@[66; 69) "Foo" | ||
69 | SEMI@[69; 70) | ||
70 | WHITESPACE@[70; 71) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.rs new file mode 100644 index 000000000..820a9e72c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | fn main() { | ||
2 | let a = (); | ||
3 | let mut b = (); | ||
4 | let ref c = (); | ||
5 | let ref mut d = (); | ||
6 | let e @ _ = (); | ||
7 | let ref mut f @ g @ _ = (); | ||
8 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.txt new file mode 100644 index 000000000..9adc89b7c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0034_bind_pat.txt | |||
@@ -0,0 +1,127 @@ | |||
1 | ROOT@[0; 146) | ||
2 | FN_DEF@[0; 145) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 145) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | LET_STMT@[16; 27) | ||
15 | LET_KW@[16; 19) | ||
16 | WHITESPACE@[19; 20) | ||
17 | BIND_PAT@[20; 21) | ||
18 | NAME@[20; 21) | ||
19 | IDENT@[20; 21) "a" | ||
20 | WHITESPACE@[21; 22) | ||
21 | EQ@[22; 23) | ||
22 | WHITESPACE@[23; 24) | ||
23 | TUPLE_EXPR@[24; 26) | ||
24 | L_PAREN@[24; 25) | ||
25 | R_PAREN@[25; 26) | ||
26 | SEMI@[26; 27) | ||
27 | WHITESPACE@[27; 32) | ||
28 | LET_STMT@[32; 47) | ||
29 | LET_KW@[32; 35) | ||
30 | WHITESPACE@[35; 36) | ||
31 | BIND_PAT@[36; 41) | ||
32 | MUT_KW@[36; 39) | ||
33 | WHITESPACE@[39; 40) | ||
34 | NAME@[40; 41) | ||
35 | IDENT@[40; 41) "b" | ||
36 | WHITESPACE@[41; 42) | ||
37 | EQ@[42; 43) | ||
38 | WHITESPACE@[43; 44) | ||
39 | TUPLE_EXPR@[44; 46) | ||
40 | L_PAREN@[44; 45) | ||
41 | R_PAREN@[45; 46) | ||
42 | SEMI@[46; 47) | ||
43 | WHITESPACE@[47; 52) | ||
44 | LET_STMT@[52; 67) | ||
45 | LET_KW@[52; 55) | ||
46 | WHITESPACE@[55; 56) | ||
47 | BIND_PAT@[56; 61) | ||
48 | REF_KW@[56; 59) | ||
49 | WHITESPACE@[59; 60) | ||
50 | NAME@[60; 61) | ||
51 | IDENT@[60; 61) "c" | ||
52 | WHITESPACE@[61; 62) | ||
53 | EQ@[62; 63) | ||
54 | WHITESPACE@[63; 64) | ||
55 | TUPLE_EXPR@[64; 66) | ||
56 | L_PAREN@[64; 65) | ||
57 | R_PAREN@[65; 66) | ||
58 | SEMI@[66; 67) | ||
59 | WHITESPACE@[67; 72) | ||
60 | LET_STMT@[72; 91) | ||
61 | LET_KW@[72; 75) | ||
62 | WHITESPACE@[75; 76) | ||
63 | BIND_PAT@[76; 85) | ||
64 | REF_KW@[76; 79) | ||
65 | WHITESPACE@[79; 80) | ||
66 | MUT_KW@[80; 83) | ||
67 | WHITESPACE@[83; 84) | ||
68 | NAME@[84; 85) | ||
69 | IDENT@[84; 85) "d" | ||
70 | WHITESPACE@[85; 86) | ||
71 | EQ@[86; 87) | ||
72 | WHITESPACE@[87; 88) | ||
73 | TUPLE_EXPR@[88; 90) | ||
74 | L_PAREN@[88; 89) | ||
75 | R_PAREN@[89; 90) | ||
76 | SEMI@[90; 91) | ||
77 | WHITESPACE@[91; 96) | ||
78 | LET_STMT@[96; 111) | ||
79 | LET_KW@[96; 99) | ||
80 | WHITESPACE@[99; 100) | ||
81 | BIND_PAT@[100; 105) | ||
82 | NAME@[100; 101) | ||
83 | IDENT@[100; 101) "e" | ||
84 | WHITESPACE@[101; 102) | ||
85 | AT@[102; 103) | ||
86 | WHITESPACE@[103; 104) | ||
87 | PLACEHOLDER_PAT@[104; 105) | ||
88 | UNDERSCORE@[104; 105) | ||
89 | WHITESPACE@[105; 106) | ||
90 | EQ@[106; 107) | ||
91 | WHITESPACE@[107; 108) | ||
92 | TUPLE_EXPR@[108; 110) | ||
93 | L_PAREN@[108; 109) | ||
94 | R_PAREN@[109; 110) | ||
95 | SEMI@[110; 111) | ||
96 | WHITESPACE@[111; 116) | ||
97 | LET_STMT@[116; 143) | ||
98 | LET_KW@[116; 119) | ||
99 | WHITESPACE@[119; 120) | ||
100 | BIND_PAT@[120; 137) | ||
101 | REF_KW@[120; 123) | ||
102 | WHITESPACE@[123; 124) | ||
103 | MUT_KW@[124; 127) | ||
104 | WHITESPACE@[127; 128) | ||
105 | NAME@[128; 129) | ||
106 | IDENT@[128; 129) "f" | ||
107 | WHITESPACE@[129; 130) | ||
108 | AT@[130; 131) | ||
109 | WHITESPACE@[131; 132) | ||
110 | BIND_PAT@[132; 137) | ||
111 | NAME@[132; 133) | ||
112 | IDENT@[132; 133) "g" | ||
113 | WHITESPACE@[133; 134) | ||
114 | AT@[134; 135) | ||
115 | WHITESPACE@[135; 136) | ||
116 | PLACEHOLDER_PAT@[136; 137) | ||
117 | UNDERSCORE@[136; 137) | ||
118 | WHITESPACE@[137; 138) | ||
119 | EQ@[138; 139) | ||
120 | WHITESPACE@[139; 140) | ||
121 | TUPLE_EXPR@[140; 142) | ||
122 | L_PAREN@[140; 141) | ||
123 | R_PAREN@[141; 142) | ||
124 | SEMI@[142; 143) | ||
125 | WHITESPACE@[143; 144) | ||
126 | R_CURLY@[144; 145) | ||
127 | WHITESPACE@[145; 146) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.rs new file mode 100644 index 000000000..de41f5cae --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn main() { | ||
2 | let &a = (); | ||
3 | let &mut b = (); | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.txt new file mode 100644 index 000000000..a625637cd --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0035_ref_pat.txt | |||
@@ -0,0 +1,49 @@ | |||
1 | ROOT@[0; 52) | ||
2 | FN_DEF@[0; 51) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 51) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | LET_STMT@[16; 28) | ||
15 | LET_KW@[16; 19) | ||
16 | WHITESPACE@[19; 20) | ||
17 | REF_PAT@[20; 22) | ||
18 | AMP@[20; 21) | ||
19 | BIND_PAT@[21; 22) | ||
20 | NAME@[21; 22) | ||
21 | IDENT@[21; 22) "a" | ||
22 | WHITESPACE@[22; 23) | ||
23 | EQ@[23; 24) | ||
24 | WHITESPACE@[24; 25) | ||
25 | TUPLE_EXPR@[25; 27) | ||
26 | L_PAREN@[25; 26) | ||
27 | R_PAREN@[26; 27) | ||
28 | SEMI@[27; 28) | ||
29 | WHITESPACE@[28; 33) | ||
30 | LET_STMT@[33; 49) | ||
31 | LET_KW@[33; 36) | ||
32 | WHITESPACE@[36; 37) | ||
33 | REF_PAT@[37; 43) | ||
34 | AMP@[37; 38) | ||
35 | MUT_KW@[38; 41) | ||
36 | WHITESPACE@[41; 42) | ||
37 | BIND_PAT@[42; 43) | ||
38 | NAME@[42; 43) | ||
39 | IDENT@[42; 43) "b" | ||
40 | WHITESPACE@[43; 44) | ||
41 | EQ@[44; 45) | ||
42 | WHITESPACE@[45; 46) | ||
43 | TUPLE_EXPR@[46; 48) | ||
44 | L_PAREN@[46; 47) | ||
45 | R_PAREN@[47; 48) | ||
46 | SEMI@[48; 49) | ||
47 | WHITESPACE@[49; 50) | ||
48 | R_CURLY@[50; 51) | ||
49 | WHITESPACE@[51; 52) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.rs new file mode 100644 index 000000000..4d719c433 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.rs | |||
@@ -0,0 +1 @@ | |||
fn main() { let _ = (); } | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.txt new file mode 100644 index 000000000..e89ff4e7c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0036_placeholder_pat.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | ROOT@[0; 26) | ||
2 | FN_DEF@[0; 25) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 25) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 12) | ||
14 | LET_STMT@[12; 23) | ||
15 | LET_KW@[12; 15) | ||
16 | WHITESPACE@[15; 16) | ||
17 | PLACEHOLDER_PAT@[16; 17) | ||
18 | UNDERSCORE@[16; 17) | ||
19 | WHITESPACE@[17; 18) | ||
20 | EQ@[18; 19) | ||
21 | WHITESPACE@[19; 20) | ||
22 | TUPLE_EXPR@[20; 22) | ||
23 | L_PAREN@[20; 21) | ||
24 | R_PAREN@[21; 22) | ||
25 | SEMI@[22; 23) | ||
26 | WHITESPACE@[23; 24) | ||
27 | R_CURLY@[24; 25) | ||
28 | WHITESPACE@[25; 26) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.rs b/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.rs new file mode 100644 index 000000000..faeefde94 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | pub(crate) struct S; | ||
2 | pub(self) struct S; | ||
3 | pub(self) struct S; | ||
4 | pub(self) struct S; | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.txt b/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.txt new file mode 100644 index 000000000..3b5fbf95d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0037_crate_visibility.txt | |||
@@ -0,0 +1,53 @@ | |||
1 | ROOT@[0; 81) | ||
2 | STRUCT_DEF@[0; 20) | ||
3 | VISIBILITY@[0; 10) | ||
4 | PUB_KW@[0; 3) | ||
5 | L_PAREN@[3; 4) | ||
6 | CRATE_KW@[4; 9) | ||
7 | R_PAREN@[9; 10) | ||
8 | WHITESPACE@[10; 11) | ||
9 | STRUCT_KW@[11; 17) | ||
10 | WHITESPACE@[17; 18) | ||
11 | NAME@[18; 19) | ||
12 | IDENT@[18; 19) "S" | ||
13 | SEMI@[19; 20) | ||
14 | WHITESPACE@[20; 21) | ||
15 | STRUCT_DEF@[21; 40) | ||
16 | VISIBILITY@[21; 30) | ||
17 | PUB_KW@[21; 24) | ||
18 | L_PAREN@[24; 25) | ||
19 | SELF_KW@[25; 29) | ||
20 | R_PAREN@[29; 30) | ||
21 | WHITESPACE@[30; 31) | ||
22 | STRUCT_KW@[31; 37) | ||
23 | WHITESPACE@[37; 38) | ||
24 | NAME@[38; 39) | ||
25 | IDENT@[38; 39) "S" | ||
26 | SEMI@[39; 40) | ||
27 | WHITESPACE@[40; 41) | ||
28 | STRUCT_DEF@[41; 60) | ||
29 | VISIBILITY@[41; 50) | ||
30 | PUB_KW@[41; 44) | ||
31 | L_PAREN@[44; 45) | ||
32 | SELF_KW@[45; 49) | ||
33 | R_PAREN@[49; 50) | ||
34 | WHITESPACE@[50; 51) | ||
35 | STRUCT_KW@[51; 57) | ||
36 | WHITESPACE@[57; 58) | ||
37 | NAME@[58; 59) | ||
38 | IDENT@[58; 59) "S" | ||
39 | SEMI@[59; 60) | ||
40 | WHITESPACE@[60; 61) | ||
41 | STRUCT_DEF@[61; 80) | ||
42 | VISIBILITY@[61; 70) | ||
43 | PUB_KW@[61; 64) | ||
44 | L_PAREN@[64; 65) | ||
45 | SELF_KW@[65; 69) | ||
46 | R_PAREN@[69; 70) | ||
47 | WHITESPACE@[70; 71) | ||
48 | STRUCT_KW@[71; 77) | ||
49 | WHITESPACE@[77; 78) | ||
50 | NAME@[78; 79) | ||
51 | IDENT@[78; 79) "S" | ||
52 | SEMI@[79; 80) | ||
53 | WHITESPACE@[80; 81) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.rs b/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.rs new file mode 100644 index 000000000..d22d8cada --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | fn foo() {} | ||
2 | fn bar() -> () {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.txt b/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.txt new file mode 100644 index 000000000..a3d235ce1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0038_function_ret_type.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | ROOT@[0; 30) | ||
2 | FN_DEF@[0; 11) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 11) | ||
12 | L_CURLY@[9; 10) | ||
13 | R_CURLY@[10; 11) | ||
14 | WHITESPACE@[11; 12) | ||
15 | FN_DEF@[12; 29) | ||
16 | FN_KW@[12; 14) | ||
17 | WHITESPACE@[14; 15) | ||
18 | NAME@[15; 18) | ||
19 | IDENT@[15; 18) "bar" | ||
20 | PARAM_LIST@[18; 20) | ||
21 | L_PAREN@[18; 19) | ||
22 | R_PAREN@[19; 20) | ||
23 | WHITESPACE@[20; 21) | ||
24 | RET_TYPE@[21; 26) | ||
25 | THIN_ARROW@[21; 23) | ||
26 | WHITESPACE@[23; 24) | ||
27 | TUPLE_TYPE@[24; 26) | ||
28 | L_PAREN@[24; 25) | ||
29 | R_PAREN@[25; 26) | ||
30 | WHITESPACE@[26; 27) | ||
31 | BLOCK@[27; 29) | ||
32 | L_CURLY@[27; 28) | ||
33 | R_CURLY@[28; 29) | ||
34 | WHITESPACE@[29; 30) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.rs new file mode 100644 index 000000000..333ebabef --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | let _ = a; | ||
3 | let _ = a::b; | ||
4 | let _ = ::a::<b>; | ||
5 | let _ = format!(); | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.txt new file mode 100644 index 000000000..618afc0a9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0039_path_expr.txt | |||
@@ -0,0 +1,95 @@ | |||
1 | ROOT@[0; 91) | ||
2 | FN_DEF@[0; 90) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 90) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 25) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | PLACEHOLDER_PAT@[19; 20) | ||
18 | UNDERSCORE@[19; 20) | ||
19 | WHITESPACE@[20; 21) | ||
20 | EQ@[21; 22) | ||
21 | WHITESPACE@[22; 23) | ||
22 | PATH_EXPR@[23; 24) | ||
23 | PATH@[23; 24) | ||
24 | PATH_SEGMENT@[23; 24) | ||
25 | NAME_REF@[23; 24) | ||
26 | IDENT@[23; 24) "a" | ||
27 | SEMI@[24; 25) | ||
28 | WHITESPACE@[25; 30) | ||
29 | LET_STMT@[30; 43) | ||
30 | LET_KW@[30; 33) | ||
31 | WHITESPACE@[33; 34) | ||
32 | PLACEHOLDER_PAT@[34; 35) | ||
33 | UNDERSCORE@[34; 35) | ||
34 | WHITESPACE@[35; 36) | ||
35 | EQ@[36; 37) | ||
36 | WHITESPACE@[37; 38) | ||
37 | PATH_EXPR@[38; 42) | ||
38 | PATH@[38; 42) | ||
39 | PATH@[38; 39) | ||
40 | PATH_SEGMENT@[38; 39) | ||
41 | NAME_REF@[38; 39) | ||
42 | IDENT@[38; 39) "a" | ||
43 | COLONCOLON@[39; 41) | ||
44 | PATH_SEGMENT@[41; 42) | ||
45 | NAME_REF@[41; 42) | ||
46 | IDENT@[41; 42) "b" | ||
47 | SEMI@[42; 43) | ||
48 | WHITESPACE@[43; 48) | ||
49 | LET_STMT@[48; 65) | ||
50 | LET_KW@[48; 51) | ||
51 | WHITESPACE@[51; 52) | ||
52 | PLACEHOLDER_PAT@[52; 53) | ||
53 | UNDERSCORE@[52; 53) | ||
54 | WHITESPACE@[53; 54) | ||
55 | EQ@[54; 55) | ||
56 | WHITESPACE@[55; 56) | ||
57 | PATH_EXPR@[56; 64) | ||
58 | PATH@[56; 64) | ||
59 | PATH_SEGMENT@[56; 64) | ||
60 | COLONCOLON@[56; 58) | ||
61 | NAME_REF@[58; 59) | ||
62 | IDENT@[58; 59) "a" | ||
63 | TYPE_ARG_LIST@[59; 64) | ||
64 | COLONCOLON@[59; 61) | ||
65 | L_ANGLE@[61; 62) | ||
66 | TYPE_ARG@[62; 63) | ||
67 | PATH_TYPE@[62; 63) | ||
68 | PATH@[62; 63) | ||
69 | PATH_SEGMENT@[62; 63) | ||
70 | NAME_REF@[62; 63) | ||
71 | IDENT@[62; 63) "b" | ||
72 | R_ANGLE@[63; 64) | ||
73 | SEMI@[64; 65) | ||
74 | WHITESPACE@[65; 70) | ||
75 | LET_STMT@[70; 88) | ||
76 | LET_KW@[70; 73) | ||
77 | WHITESPACE@[73; 74) | ||
78 | PLACEHOLDER_PAT@[74; 75) | ||
79 | UNDERSCORE@[74; 75) | ||
80 | WHITESPACE@[75; 76) | ||
81 | EQ@[76; 77) | ||
82 | WHITESPACE@[77; 78) | ||
83 | MACRO_CALL@[78; 87) | ||
84 | PATH@[78; 84) | ||
85 | PATH_SEGMENT@[78; 84) | ||
86 | NAME_REF@[78; 84) | ||
87 | IDENT@[78; 84) "format" | ||
88 | EXCL@[84; 85) | ||
89 | TOKEN_TREE@[85; 87) | ||
90 | L_PAREN@[85; 86) | ||
91 | R_PAREN@[86; 87) | ||
92 | SEMI@[87; 88) | ||
93 | WHITESPACE@[88; 89) | ||
94 | R_CURLY@[89; 90) | ||
95 | WHITESPACE@[90; 91) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.rs b/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.rs new file mode 100644 index 000000000..2e11a5a6e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.rs | |||
@@ -0,0 +1,12 @@ | |||
1 | fn foo() { | ||
2 | let _ = true; | ||
3 | let _ = false; | ||
4 | let _ = 1; | ||
5 | let _ = 2.0; | ||
6 | let _ = b'a'; | ||
7 | let _ = 'b'; | ||
8 | let _ = "c"; | ||
9 | let _ = r"d"; | ||
10 | let _ = b"e"; | ||
11 | let _ = br"f"; | ||
12 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.txt b/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.txt new file mode 100644 index 000000000..8105ee25a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0040_expr_literals.txt | |||
@@ -0,0 +1,135 @@ | |||
1 | ROOT@[0; 189) | ||
2 | FN_DEF@[0; 188) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 188) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 28) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | PLACEHOLDER_PAT@[19; 20) | ||
18 | UNDERSCORE@[19; 20) | ||
19 | WHITESPACE@[20; 21) | ||
20 | EQ@[21; 22) | ||
21 | WHITESPACE@[22; 23) | ||
22 | LITERAL@[23; 27) | ||
23 | TRUE_KW@[23; 27) | ||
24 | SEMI@[27; 28) | ||
25 | WHITESPACE@[28; 33) | ||
26 | LET_STMT@[33; 47) | ||
27 | LET_KW@[33; 36) | ||
28 | WHITESPACE@[36; 37) | ||
29 | PLACEHOLDER_PAT@[37; 38) | ||
30 | UNDERSCORE@[37; 38) | ||
31 | WHITESPACE@[38; 39) | ||
32 | EQ@[39; 40) | ||
33 | WHITESPACE@[40; 41) | ||
34 | LITERAL@[41; 46) | ||
35 | FALSE_KW@[41; 46) | ||
36 | SEMI@[46; 47) | ||
37 | WHITESPACE@[47; 52) | ||
38 | LET_STMT@[52; 62) | ||
39 | LET_KW@[52; 55) | ||
40 | WHITESPACE@[55; 56) | ||
41 | PLACEHOLDER_PAT@[56; 57) | ||
42 | UNDERSCORE@[56; 57) | ||
43 | WHITESPACE@[57; 58) | ||
44 | EQ@[58; 59) | ||
45 | WHITESPACE@[59; 60) | ||
46 | LITERAL@[60; 61) | ||
47 | INT_NUMBER@[60; 61) "1" | ||
48 | SEMI@[61; 62) | ||
49 | WHITESPACE@[62; 67) | ||
50 | LET_STMT@[67; 79) | ||
51 | LET_KW@[67; 70) | ||
52 | WHITESPACE@[70; 71) | ||
53 | PLACEHOLDER_PAT@[71; 72) | ||
54 | UNDERSCORE@[71; 72) | ||
55 | WHITESPACE@[72; 73) | ||
56 | EQ@[73; 74) | ||
57 | WHITESPACE@[74; 75) | ||
58 | LITERAL@[75; 78) | ||
59 | FLOAT_NUMBER@[75; 78) "2.0" | ||
60 | SEMI@[78; 79) | ||
61 | WHITESPACE@[79; 84) | ||
62 | LET_STMT@[84; 97) | ||
63 | LET_KW@[84; 87) | ||
64 | WHITESPACE@[87; 88) | ||
65 | PLACEHOLDER_PAT@[88; 89) | ||
66 | UNDERSCORE@[88; 89) | ||
67 | WHITESPACE@[89; 90) | ||
68 | EQ@[90; 91) | ||
69 | WHITESPACE@[91; 92) | ||
70 | LITERAL@[92; 96) | ||
71 | BYTE@[92; 96) | ||
72 | SEMI@[96; 97) | ||
73 | WHITESPACE@[97; 102) | ||
74 | LET_STMT@[102; 114) | ||
75 | LET_KW@[102; 105) | ||
76 | WHITESPACE@[105; 106) | ||
77 | PLACEHOLDER_PAT@[106; 107) | ||
78 | UNDERSCORE@[106; 107) | ||
79 | WHITESPACE@[107; 108) | ||
80 | EQ@[108; 109) | ||
81 | WHITESPACE@[109; 110) | ||
82 | LITERAL@[110; 113) | ||
83 | CHAR@[110; 113) | ||
84 | SEMI@[113; 114) | ||
85 | WHITESPACE@[114; 119) | ||
86 | LET_STMT@[119; 131) | ||
87 | LET_KW@[119; 122) | ||
88 | WHITESPACE@[122; 123) | ||
89 | PLACEHOLDER_PAT@[123; 124) | ||
90 | UNDERSCORE@[123; 124) | ||
91 | WHITESPACE@[124; 125) | ||
92 | EQ@[125; 126) | ||
93 | WHITESPACE@[126; 127) | ||
94 | LITERAL@[127; 130) | ||
95 | STRING@[127; 130) | ||
96 | SEMI@[130; 131) | ||
97 | WHITESPACE@[131; 136) | ||
98 | LET_STMT@[136; 149) | ||
99 | LET_KW@[136; 139) | ||
100 | WHITESPACE@[139; 140) | ||
101 | PLACEHOLDER_PAT@[140; 141) | ||
102 | UNDERSCORE@[140; 141) | ||
103 | WHITESPACE@[141; 142) | ||
104 | EQ@[142; 143) | ||
105 | WHITESPACE@[143; 144) | ||
106 | LITERAL@[144; 148) | ||
107 | RAW_STRING@[144; 148) | ||
108 | SEMI@[148; 149) | ||
109 | WHITESPACE@[149; 154) | ||
110 | LET_STMT@[154; 167) | ||
111 | LET_KW@[154; 157) | ||
112 | WHITESPACE@[157; 158) | ||
113 | PLACEHOLDER_PAT@[158; 159) | ||
114 | UNDERSCORE@[158; 159) | ||
115 | WHITESPACE@[159; 160) | ||
116 | EQ@[160; 161) | ||
117 | WHITESPACE@[161; 162) | ||
118 | LITERAL@[162; 166) | ||
119 | BYTE_STRING@[162; 166) | ||
120 | SEMI@[166; 167) | ||
121 | WHITESPACE@[167; 172) | ||
122 | LET_STMT@[172; 186) | ||
123 | LET_KW@[172; 175) | ||
124 | WHITESPACE@[175; 176) | ||
125 | PLACEHOLDER_PAT@[176; 177) | ||
126 | UNDERSCORE@[176; 177) | ||
127 | WHITESPACE@[177; 178) | ||
128 | EQ@[178; 179) | ||
129 | WHITESPACE@[179; 180) | ||
130 | LITERAL@[180; 185) | ||
131 | RAW_BYTE_STRING@[180; 185) | ||
132 | SEMI@[185; 186) | ||
133 | WHITESPACE@[186; 187) | ||
134 | R_CURLY@[187; 188) | ||
135 | WHITESPACE@[188; 189) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.rs b/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.rs new file mode 100644 index 000000000..919bde0ee --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.rs | |||
@@ -0,0 +1 @@ | |||
struct S<T: 'a + ?Sized + (Copy)>; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.txt b/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.txt new file mode 100644 index 000000000..549b571c2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0041_type_param_bounds.txt | |||
@@ -0,0 +1,36 @@ | |||
1 | ROOT@[0; 35) | ||
2 | STRUCT_DEF@[0; 34) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | TYPE_PARAM_LIST@[8; 33) | ||
8 | L_ANGLE@[8; 9) | ||
9 | TYPE_PARAM@[9; 32) | ||
10 | NAME@[9; 10) | ||
11 | IDENT@[9; 10) "T" | ||
12 | COLON@[10; 11) | ||
13 | WHITESPACE@[11; 12) | ||
14 | LIFETIME@[12; 14) "'a" | ||
15 | WHITESPACE@[14; 15) | ||
16 | PLUS@[15; 16) | ||
17 | WHITESPACE@[16; 17) | ||
18 | QUESTION@[17; 18) | ||
19 | PATH_TYPE@[18; 32) | ||
20 | PATH@[18; 23) | ||
21 | PATH_SEGMENT@[18; 23) | ||
22 | NAME_REF@[18; 23) | ||
23 | IDENT@[18; 23) "Sized" | ||
24 | WHITESPACE@[23; 24) | ||
25 | PLUS@[24; 25) | ||
26 | WHITESPACE@[25; 26) | ||
27 | L_PAREN@[26; 27) | ||
28 | PATH_TYPE@[27; 31) | ||
29 | PATH@[27; 31) | ||
30 | PATH_SEGMENT@[27; 31) | ||
31 | NAME_REF@[27; 31) | ||
32 | IDENT@[27; 31) "Copy" | ||
33 | R_PAREN@[31; 32) | ||
34 | R_ANGLE@[32; 33) | ||
35 | SEMI@[33; 34) | ||
36 | WHITESPACE@[34; 35) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.rs b/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.rs new file mode 100644 index 000000000..540eacb02 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.rs | |||
@@ -0,0 +1 @@ | |||
struct S<T = i32>; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.txt b/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.txt new file mode 100644 index 000000000..a75b7ed0a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0042_type_param_default.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | ROOT@[0; 19) | ||
2 | STRUCT_DEF@[0; 18) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | TYPE_PARAM_LIST@[8; 17) | ||
8 | L_ANGLE@[8; 9) | ||
9 | TYPE_PARAM@[9; 16) | ||
10 | NAME@[9; 10) | ||
11 | IDENT@[9; 10) "T" | ||
12 | WHITESPACE@[10; 11) | ||
13 | EQ@[11; 12) | ||
14 | WHITESPACE@[12; 13) | ||
15 | PATH_TYPE@[13; 16) | ||
16 | PATH@[13; 16) | ||
17 | PATH_SEGMENT@[13; 16) | ||
18 | NAME_REF@[13; 16) | ||
19 | IDENT@[13; 16) "i32" | ||
20 | R_ANGLE@[16; 17) | ||
21 | SEMI@[17; 18) | ||
22 | WHITESPACE@[18; 19) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.rs new file mode 100644 index 000000000..0c9a20718 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | let _ = f(); | ||
3 | let _ = f()(1)(1, 2,); | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.txt new file mode 100644 index 000000000..f8e31045a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0043_call_expr.txt | |||
@@ -0,0 +1,70 @@ | |||
1 | ROOT@[0; 57) | ||
2 | FN_DEF@[0; 56) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 56) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 27) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | PLACEHOLDER_PAT@[19; 20) | ||
18 | UNDERSCORE@[19; 20) | ||
19 | WHITESPACE@[20; 21) | ||
20 | EQ@[21; 22) | ||
21 | WHITESPACE@[22; 23) | ||
22 | CALL_EXPR@[23; 26) | ||
23 | PATH_EXPR@[23; 24) | ||
24 | PATH@[23; 24) | ||
25 | PATH_SEGMENT@[23; 24) | ||
26 | NAME_REF@[23; 24) | ||
27 | IDENT@[23; 24) "f" | ||
28 | ARG_LIST@[24; 26) | ||
29 | L_PAREN@[24; 25) | ||
30 | R_PAREN@[25; 26) | ||
31 | SEMI@[26; 27) | ||
32 | WHITESPACE@[27; 32) | ||
33 | LET_STMT@[32; 54) | ||
34 | LET_KW@[32; 35) | ||
35 | WHITESPACE@[35; 36) | ||
36 | PLACEHOLDER_PAT@[36; 37) | ||
37 | UNDERSCORE@[36; 37) | ||
38 | WHITESPACE@[37; 38) | ||
39 | EQ@[38; 39) | ||
40 | WHITESPACE@[39; 40) | ||
41 | CALL_EXPR@[40; 53) | ||
42 | CALL_EXPR@[40; 46) | ||
43 | CALL_EXPR@[40; 43) | ||
44 | PATH_EXPR@[40; 41) | ||
45 | PATH@[40; 41) | ||
46 | PATH_SEGMENT@[40; 41) | ||
47 | NAME_REF@[40; 41) | ||
48 | IDENT@[40; 41) "f" | ||
49 | ARG_LIST@[41; 43) | ||
50 | L_PAREN@[41; 42) | ||
51 | R_PAREN@[42; 43) | ||
52 | ARG_LIST@[43; 46) | ||
53 | L_PAREN@[43; 44) | ||
54 | LITERAL@[44; 45) | ||
55 | INT_NUMBER@[44; 45) "1" | ||
56 | R_PAREN@[45; 46) | ||
57 | ARG_LIST@[46; 53) | ||
58 | L_PAREN@[46; 47) | ||
59 | LITERAL@[47; 48) | ||
60 | INT_NUMBER@[47; 48) "1" | ||
61 | COMMA@[48; 49) | ||
62 | WHITESPACE@[49; 50) | ||
63 | LITERAL@[50; 51) | ||
64 | INT_NUMBER@[50; 51) "2" | ||
65 | COMMA@[51; 52) | ||
66 | R_PAREN@[52; 53) | ||
67 | SEMI@[53; 54) | ||
68 | WHITESPACE@[54; 55) | ||
69 | R_CURLY@[55; 56) | ||
70 | WHITESPACE@[56; 57) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.rs new file mode 100644 index 000000000..2dac6be95 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | let _ = &1; | ||
3 | let _ = &mut &f(); | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.txt new file mode 100644 index 000000000..77f2ca22c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0044_ref_expr.txt | |||
@@ -0,0 +1,54 @@ | |||
1 | ROOT@[0; 52) | ||
2 | FN_DEF@[0; 51) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 51) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 26) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | PLACEHOLDER_PAT@[19; 20) | ||
18 | UNDERSCORE@[19; 20) | ||
19 | WHITESPACE@[20; 21) | ||
20 | EQ@[21; 22) | ||
21 | WHITESPACE@[22; 23) | ||
22 | REF_EXPR@[23; 25) | ||
23 | AMP@[23; 24) | ||
24 | LITERAL@[24; 25) | ||
25 | INT_NUMBER@[24; 25) "1" | ||
26 | SEMI@[25; 26) | ||
27 | WHITESPACE@[26; 31) | ||
28 | LET_STMT@[31; 49) | ||
29 | LET_KW@[31; 34) | ||
30 | WHITESPACE@[34; 35) | ||
31 | PLACEHOLDER_PAT@[35; 36) | ||
32 | UNDERSCORE@[35; 36) | ||
33 | WHITESPACE@[36; 37) | ||
34 | EQ@[37; 38) | ||
35 | WHITESPACE@[38; 39) | ||
36 | REF_EXPR@[39; 48) | ||
37 | AMP@[39; 40) | ||
38 | MUT_KW@[40; 43) | ||
39 | WHITESPACE@[43; 44) | ||
40 | REF_EXPR@[44; 48) | ||
41 | AMP@[44; 45) | ||
42 | CALL_EXPR@[45; 48) | ||
43 | PATH_EXPR@[45; 46) | ||
44 | PATH@[45; 46) | ||
45 | PATH_SEGMENT@[45; 46) | ||
46 | NAME_REF@[45; 46) | ||
47 | IDENT@[45; 46) "f" | ||
48 | ARG_LIST@[46; 48) | ||
49 | L_PAREN@[46; 47) | ||
50 | R_PAREN@[47; 48) | ||
51 | SEMI@[48; 49) | ||
52 | WHITESPACE@[49; 50) | ||
53 | R_CURLY@[50; 51) | ||
54 | WHITESPACE@[51; 52) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0045_block.rs b/crates/ra_syntax/tests/data/parser/inline/0045_block.rs new file mode 100644 index 000000000..81f44c533 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0045_block.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn a() {} | ||
2 | fn b() { let _ = 1; } | ||
3 | fn c() { 1; 2; } | ||
4 | fn d() { 1; 2 } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0045_block.txt b/crates/ra_syntax/tests/data/parser/inline/0045_block.txt new file mode 100644 index 000000000..e6c841f21 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0045_block.txt | |||
@@ -0,0 +1,86 @@ | |||
1 | ROOT@[0; 65) | ||
2 | FN_DEF@[0; 9) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 4) | ||
6 | IDENT@[3; 4) "a" | ||
7 | PARAM_LIST@[4; 6) | ||
8 | L_PAREN@[4; 5) | ||
9 | R_PAREN@[5; 6) | ||
10 | WHITESPACE@[6; 7) | ||
11 | BLOCK@[7; 9) | ||
12 | L_CURLY@[7; 8) | ||
13 | R_CURLY@[8; 9) | ||
14 | WHITESPACE@[9; 10) | ||
15 | FN_DEF@[10; 31) | ||
16 | FN_KW@[10; 12) | ||
17 | WHITESPACE@[12; 13) | ||
18 | NAME@[13; 14) | ||
19 | IDENT@[13; 14) "b" | ||
20 | PARAM_LIST@[14; 16) | ||
21 | L_PAREN@[14; 15) | ||
22 | R_PAREN@[15; 16) | ||
23 | WHITESPACE@[16; 17) | ||
24 | BLOCK@[17; 31) | ||
25 | L_CURLY@[17; 18) | ||
26 | WHITESPACE@[18; 19) | ||
27 | LET_STMT@[19; 29) | ||
28 | LET_KW@[19; 22) | ||
29 | WHITESPACE@[22; 23) | ||
30 | PLACEHOLDER_PAT@[23; 24) | ||
31 | UNDERSCORE@[23; 24) | ||
32 | WHITESPACE@[24; 25) | ||
33 | EQ@[25; 26) | ||
34 | WHITESPACE@[26; 27) | ||
35 | LITERAL@[27; 28) | ||
36 | INT_NUMBER@[27; 28) "1" | ||
37 | SEMI@[28; 29) | ||
38 | WHITESPACE@[29; 30) | ||
39 | R_CURLY@[30; 31) | ||
40 | WHITESPACE@[31; 32) | ||
41 | FN_DEF@[32; 48) | ||
42 | FN_KW@[32; 34) | ||
43 | WHITESPACE@[34; 35) | ||
44 | NAME@[35; 36) | ||
45 | IDENT@[35; 36) "c" | ||
46 | PARAM_LIST@[36; 38) | ||
47 | L_PAREN@[36; 37) | ||
48 | R_PAREN@[37; 38) | ||
49 | WHITESPACE@[38; 39) | ||
50 | BLOCK@[39; 48) | ||
51 | L_CURLY@[39; 40) | ||
52 | WHITESPACE@[40; 41) | ||
53 | EXPR_STMT@[41; 43) | ||
54 | LITERAL@[41; 42) | ||
55 | INT_NUMBER@[41; 42) "1" | ||
56 | SEMI@[42; 43) | ||
57 | WHITESPACE@[43; 44) | ||
58 | EXPR_STMT@[44; 46) | ||
59 | LITERAL@[44; 45) | ||
60 | INT_NUMBER@[44; 45) "2" | ||
61 | SEMI@[45; 46) | ||
62 | WHITESPACE@[46; 47) | ||
63 | R_CURLY@[47; 48) | ||
64 | WHITESPACE@[48; 49) | ||
65 | FN_DEF@[49; 64) | ||
66 | FN_KW@[49; 51) | ||
67 | WHITESPACE@[51; 52) | ||
68 | NAME@[52; 53) | ||
69 | IDENT@[52; 53) "d" | ||
70 | PARAM_LIST@[53; 55) | ||
71 | L_PAREN@[53; 54) | ||
72 | R_PAREN@[54; 55) | ||
73 | WHITESPACE@[55; 56) | ||
74 | BLOCK@[56; 64) | ||
75 | L_CURLY@[56; 57) | ||
76 | WHITESPACE@[57; 58) | ||
77 | EXPR_STMT@[58; 60) | ||
78 | LITERAL@[58; 59) | ||
79 | INT_NUMBER@[58; 59) "1" | ||
80 | SEMI@[59; 60) | ||
81 | WHITESPACE@[60; 61) | ||
82 | LITERAL@[61; 62) | ||
83 | INT_NUMBER@[61; 62) "2" | ||
84 | WHITESPACE@[62; 63) | ||
85 | R_CURLY@[63; 64) | ||
86 | WHITESPACE@[64; 65) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.rs b/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.rs new file mode 100644 index 000000000..ef6aa84a2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.rs | |||
@@ -0,0 +1 @@ | |||
default impl Foo {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.txt b/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.txt new file mode 100644 index 000000000..19fe5ca85 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0046_default_impl.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | ROOT@[0; 20) | ||
2 | IMPL_ITEM@[0; 19) | ||
3 | DEFAULT_KW@[0; 7) | ||
4 | WHITESPACE@[7; 8) | ||
5 | IMPL_KW@[8; 12) | ||
6 | WHITESPACE@[12; 13) | ||
7 | PATH_TYPE@[13; 16) | ||
8 | PATH@[13; 16) | ||
9 | PATH_SEGMENT@[13; 16) | ||
10 | NAME_REF@[13; 16) | ||
11 | IDENT@[13; 16) "Foo" | ||
12 | WHITESPACE@[16; 17) | ||
13 | ITEM_LIST@[17; 19) | ||
14 | L_CURLY@[17; 18) | ||
15 | R_CURLY@[18; 19) | ||
16 | WHITESPACE@[19; 20) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.rs b/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.rs new file mode 100644 index 000000000..d6337f6b3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.rs | |||
@@ -0,0 +1 @@ | |||
impl Foo {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.txt b/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.txt new file mode 100644 index 000000000..6419243e2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0047_impl_item.txt | |||
@@ -0,0 +1,14 @@ | |||
1 | ROOT@[0; 12) | ||
2 | IMPL_ITEM@[0; 11) | ||
3 | IMPL_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | PATH_TYPE@[5; 8) | ||
6 | PATH@[5; 8) | ||
7 | PATH_SEGMENT@[5; 8) | ||
8 | NAME_REF@[5; 8) | ||
9 | IDENT@[5; 8) "Foo" | ||
10 | WHITESPACE@[8; 9) | ||
11 | ITEM_LIST@[9; 11) | ||
12 | L_CURLY@[9; 10) | ||
13 | R_CURLY@[10; 11) | ||
14 | WHITESPACE@[11; 12) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.rs b/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.rs new file mode 100644 index 000000000..b7527c870 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.rs | |||
@@ -0,0 +1 @@ | |||
impl !Send for X {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.txt b/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.txt new file mode 100644 index 000000000..6739f9c55 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0048_impl_item_neg.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | ROOT@[0; 20) | ||
2 | IMPL_ITEM@[0; 19) | ||
3 | IMPL_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | EXCL@[5; 6) | ||
6 | PATH_TYPE@[6; 10) | ||
7 | PATH@[6; 10) | ||
8 | PATH_SEGMENT@[6; 10) | ||
9 | NAME_REF@[6; 10) | ||
10 | IDENT@[6; 10) "Send" | ||
11 | WHITESPACE@[10; 11) | ||
12 | FOR_KW@[11; 14) | ||
13 | WHITESPACE@[14; 15) | ||
14 | PATH_TYPE@[15; 16) | ||
15 | PATH@[15; 16) | ||
16 | PATH_SEGMENT@[15; 16) | ||
17 | NAME_REF@[15; 16) | ||
18 | IDENT@[15; 16) "X" | ||
19 | WHITESPACE@[16; 17) | ||
20 | ITEM_LIST@[17; 19) | ||
21 | L_CURLY@[17; 18) | ||
22 | R_CURLY@[18; 19) | ||
23 | WHITESPACE@[19; 20) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.rs b/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.rs new file mode 100644 index 000000000..a5ec3239f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | impl F { | ||
2 | type A: Clone; | ||
3 | const B: i32; | ||
4 | fn foo() {} | ||
5 | fn bar(&self); | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.txt b/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.txt new file mode 100644 index 000000000..72d9220e8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0049_trait_item_list.txt | |||
@@ -0,0 +1,69 @@ | |||
1 | ROOT@[0; 83) | ||
2 | IMPL_ITEM@[0; 82) | ||
3 | IMPL_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | PATH_TYPE@[5; 6) | ||
6 | PATH@[5; 6) | ||
7 | PATH_SEGMENT@[5; 6) | ||
8 | NAME_REF@[5; 6) | ||
9 | IDENT@[5; 6) "F" | ||
10 | WHITESPACE@[6; 7) | ||
11 | ITEM_LIST@[7; 82) | ||
12 | L_CURLY@[7; 8) | ||
13 | WHITESPACE@[8; 13) | ||
14 | TYPE_DEF@[13; 27) | ||
15 | TYPE_KW@[13; 17) | ||
16 | WHITESPACE@[17; 18) | ||
17 | NAME@[18; 19) | ||
18 | IDENT@[18; 19) "A" | ||
19 | COLON@[19; 20) | ||
20 | WHITESPACE@[20; 21) | ||
21 | PATH_TYPE@[21; 26) | ||
22 | PATH@[21; 26) | ||
23 | PATH_SEGMENT@[21; 26) | ||
24 | NAME_REF@[21; 26) | ||
25 | IDENT@[21; 26) "Clone" | ||
26 | SEMI@[26; 27) | ||
27 | WHITESPACE@[27; 32) | ||
28 | CONST_DEF@[32; 45) | ||
29 | CONST_KW@[32; 37) | ||
30 | WHITESPACE@[37; 38) | ||
31 | NAME@[38; 39) | ||
32 | IDENT@[38; 39) "B" | ||
33 | COLON@[39; 40) | ||
34 | WHITESPACE@[40; 41) | ||
35 | PATH_TYPE@[41; 44) | ||
36 | PATH@[41; 44) | ||
37 | PATH_SEGMENT@[41; 44) | ||
38 | NAME_REF@[41; 44) | ||
39 | IDENT@[41; 44) "i32" | ||
40 | SEMI@[44; 45) | ||
41 | WHITESPACE@[45; 50) | ||
42 | FN_DEF@[50; 61) | ||
43 | FN_KW@[50; 52) | ||
44 | WHITESPACE@[52; 53) | ||
45 | NAME@[53; 56) | ||
46 | IDENT@[53; 56) "foo" | ||
47 | PARAM_LIST@[56; 58) | ||
48 | L_PAREN@[56; 57) | ||
49 | R_PAREN@[57; 58) | ||
50 | WHITESPACE@[58; 59) | ||
51 | BLOCK@[59; 61) | ||
52 | L_CURLY@[59; 60) | ||
53 | R_CURLY@[60; 61) | ||
54 | WHITESPACE@[61; 66) | ||
55 | FN_DEF@[66; 80) | ||
56 | FN_KW@[66; 68) | ||
57 | WHITESPACE@[68; 69) | ||
58 | NAME@[69; 72) | ||
59 | IDENT@[69; 72) "bar" | ||
60 | PARAM_LIST@[72; 79) | ||
61 | L_PAREN@[72; 73) | ||
62 | SELF_PARAM@[73; 78) | ||
63 | AMP@[73; 74) | ||
64 | SELF_KW@[74; 78) | ||
65 | R_PAREN@[78; 79) | ||
66 | SEMI@[79; 80) | ||
67 | WHITESPACE@[80; 81) | ||
68 | R_CURLY@[81; 82) | ||
69 | WHITESPACE@[82; 83) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.rs b/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.rs new file mode 100644 index 000000000..0a9af907f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | let a; | ||
3 | let b: i32; | ||
4 | let c = 92; | ||
5 | let d: i32 = 92; | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.txt b/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.txt new file mode 100644 index 000000000..30dc83454 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0050_let_stmt;.txt | |||
@@ -0,0 +1,71 @@ | |||
1 | ROOT@[0; 77) | ||
2 | FN_DEF@[0; 76) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 76) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 21) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | BIND_PAT@[19; 20) | ||
18 | NAME@[19; 20) | ||
19 | IDENT@[19; 20) "a" | ||
20 | SEMI@[20; 21) | ||
21 | WHITESPACE@[21; 26) | ||
22 | LET_STMT@[26; 37) | ||
23 | LET_KW@[26; 29) | ||
24 | WHITESPACE@[29; 30) | ||
25 | BIND_PAT@[30; 31) | ||
26 | NAME@[30; 31) | ||
27 | IDENT@[30; 31) "b" | ||
28 | COLON@[31; 32) | ||
29 | WHITESPACE@[32; 33) | ||
30 | PATH_TYPE@[33; 36) | ||
31 | PATH@[33; 36) | ||
32 | PATH_SEGMENT@[33; 36) | ||
33 | NAME_REF@[33; 36) | ||
34 | IDENT@[33; 36) "i32" | ||
35 | SEMI@[36; 37) | ||
36 | WHITESPACE@[37; 42) | ||
37 | LET_STMT@[42; 53) | ||
38 | LET_KW@[42; 45) | ||
39 | WHITESPACE@[45; 46) | ||
40 | BIND_PAT@[46; 47) | ||
41 | NAME@[46; 47) | ||
42 | IDENT@[46; 47) "c" | ||
43 | WHITESPACE@[47; 48) | ||
44 | EQ@[48; 49) | ||
45 | WHITESPACE@[49; 50) | ||
46 | LITERAL@[50; 52) | ||
47 | INT_NUMBER@[50; 52) "92" | ||
48 | SEMI@[52; 53) | ||
49 | WHITESPACE@[53; 58) | ||
50 | LET_STMT@[58; 74) | ||
51 | LET_KW@[58; 61) | ||
52 | WHITESPACE@[61; 62) | ||
53 | BIND_PAT@[62; 63) | ||
54 | NAME@[62; 63) | ||
55 | IDENT@[62; 63) "d" | ||
56 | COLON@[63; 64) | ||
57 | WHITESPACE@[64; 65) | ||
58 | PATH_TYPE@[65; 68) | ||
59 | PATH@[65; 68) | ||
60 | PATH_SEGMENT@[65; 68) | ||
61 | NAME_REF@[65; 68) | ||
62 | IDENT@[65; 68) "i32" | ||
63 | WHITESPACE@[68; 69) | ||
64 | EQ@[69; 70) | ||
65 | WHITESPACE@[70; 71) | ||
66 | LITERAL@[71; 73) | ||
67 | INT_NUMBER@[71; 73) "92" | ||
68 | SEMI@[73; 74) | ||
69 | WHITESPACE@[74; 75) | ||
70 | R_CURLY@[75; 76) | ||
71 | WHITESPACE@[76; 77) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.rs new file mode 100644 index 000000000..1a3aa35ae --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | x.foo(); | ||
3 | y.bar::<T>(1, 2,); | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.txt new file mode 100644 index 000000000..530c80fa8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0051_method_call_expr.txt | |||
@@ -0,0 +1,62 @@ | |||
1 | ROOT@[0; 49) | ||
2 | FN_DEF@[0; 48) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 48) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 23) | ||
15 | METHOD_CALL_EXPR@[15; 22) | ||
16 | PATH_EXPR@[15; 16) | ||
17 | PATH@[15; 16) | ||
18 | PATH_SEGMENT@[15; 16) | ||
19 | NAME_REF@[15; 16) | ||
20 | IDENT@[15; 16) "x" | ||
21 | DOT@[16; 17) | ||
22 | NAME_REF@[17; 20) | ||
23 | IDENT@[17; 20) "foo" | ||
24 | ARG_LIST@[20; 22) | ||
25 | L_PAREN@[20; 21) | ||
26 | R_PAREN@[21; 22) | ||
27 | SEMI@[22; 23) | ||
28 | WHITESPACE@[23; 28) | ||
29 | EXPR_STMT@[28; 46) | ||
30 | METHOD_CALL_EXPR@[28; 45) | ||
31 | PATH_EXPR@[28; 29) | ||
32 | PATH@[28; 29) | ||
33 | PATH_SEGMENT@[28; 29) | ||
34 | NAME_REF@[28; 29) | ||
35 | IDENT@[28; 29) "y" | ||
36 | DOT@[29; 30) | ||
37 | NAME_REF@[30; 33) | ||
38 | IDENT@[30; 33) "bar" | ||
39 | TYPE_ARG_LIST@[33; 38) | ||
40 | COLONCOLON@[33; 35) | ||
41 | L_ANGLE@[35; 36) | ||
42 | TYPE_ARG@[36; 37) | ||
43 | PATH_TYPE@[36; 37) | ||
44 | PATH@[36; 37) | ||
45 | PATH_SEGMENT@[36; 37) | ||
46 | NAME_REF@[36; 37) | ||
47 | IDENT@[36; 37) "T" | ||
48 | R_ANGLE@[37; 38) | ||
49 | ARG_LIST@[38; 45) | ||
50 | L_PAREN@[38; 39) | ||
51 | LITERAL@[39; 40) | ||
52 | INT_NUMBER@[39; 40) "1" | ||
53 | COMMA@[40; 41) | ||
54 | WHITESPACE@[41; 42) | ||
55 | LITERAL@[42; 43) | ||
56 | INT_NUMBER@[42; 43) "2" | ||
57 | COMMA@[43; 44) | ||
58 | R_PAREN@[44; 45) | ||
59 | SEMI@[45; 46) | ||
60 | WHITESPACE@[46; 47) | ||
61 | R_CURLY@[47; 48) | ||
62 | WHITESPACE@[48; 49) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.rs new file mode 100644 index 000000000..3e69538e5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | x.foo; | ||
3 | x.0.bar; | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.txt new file mode 100644 index 000000000..9086219ca --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0052_field_expr.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | ROOT@[0; 37) | ||
2 | FN_DEF@[0; 36) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 36) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 21) | ||
15 | FIELD_EXPR@[15; 20) | ||
16 | PATH_EXPR@[15; 16) | ||
17 | PATH@[15; 16) | ||
18 | PATH_SEGMENT@[15; 16) | ||
19 | NAME_REF@[15; 16) | ||
20 | IDENT@[15; 16) "x" | ||
21 | DOT@[16; 17) | ||
22 | NAME_REF@[17; 20) | ||
23 | IDENT@[17; 20) "foo" | ||
24 | SEMI@[20; 21) | ||
25 | WHITESPACE@[21; 26) | ||
26 | EXPR_STMT@[26; 34) | ||
27 | FIELD_EXPR@[26; 33) | ||
28 | FIELD_EXPR@[26; 29) | ||
29 | PATH_EXPR@[26; 27) | ||
30 | PATH@[26; 27) | ||
31 | PATH_SEGMENT@[26; 27) | ||
32 | NAME_REF@[26; 27) | ||
33 | IDENT@[26; 27) "x" | ||
34 | DOT@[27; 28) | ||
35 | INT_NUMBER@[28; 29) "0" | ||
36 | DOT@[29; 30) | ||
37 | NAME_REF@[30; 33) | ||
38 | IDENT@[30; 33) "bar" | ||
39 | SEMI@[33; 34) | ||
40 | WHITESPACE@[34; 35) | ||
41 | R_CURLY@[35; 36) | ||
42 | WHITESPACE@[36; 37) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0053_block_items.rs b/crates/ra_syntax/tests/data/parser/inline/0053_block_items.rs new file mode 100644 index 000000000..d9868718c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0053_block_items.rs | |||
@@ -0,0 +1 @@ | |||
fn a() { fn b() {} } | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0053_block_items.txt b/crates/ra_syntax/tests/data/parser/inline/0053_block_items.txt new file mode 100644 index 000000000..20122d763 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0053_block_items.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | ROOT@[0; 21) | ||
2 | FN_DEF@[0; 20) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 4) | ||
6 | IDENT@[3; 4) "a" | ||
7 | PARAM_LIST@[4; 6) | ||
8 | L_PAREN@[4; 5) | ||
9 | R_PAREN@[5; 6) | ||
10 | WHITESPACE@[6; 7) | ||
11 | BLOCK@[7; 20) | ||
12 | L_CURLY@[7; 8) | ||
13 | WHITESPACE@[8; 9) | ||
14 | FN_DEF@[9; 18) | ||
15 | FN_KW@[9; 11) | ||
16 | WHITESPACE@[11; 12) | ||
17 | NAME@[12; 13) | ||
18 | IDENT@[12; 13) "b" | ||
19 | PARAM_LIST@[13; 15) | ||
20 | L_PAREN@[13; 14) | ||
21 | R_PAREN@[14; 15) | ||
22 | WHITESPACE@[15; 16) | ||
23 | BLOCK@[16; 18) | ||
24 | L_CURLY@[16; 17) | ||
25 | R_CURLY@[17; 18) | ||
26 | WHITESPACE@[18; 19) | ||
27 | R_CURLY@[19; 20) | ||
28 | WHITESPACE@[20; 21) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.rs b/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.rs new file mode 100644 index 000000000..da3412fa8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | let S {} = (); | ||
3 | let S { f, ref mut g } = (); | ||
4 | let S { h: _, ..} = (); | ||
5 | let S { h: _, } = (); | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.txt b/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.txt new file mode 100644 index 000000000..4df4ca35b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0054_field_pat_list.txt | |||
@@ -0,0 +1,126 @@ | |||
1 | ROOT@[0; 119) | ||
2 | FN_DEF@[0; 118) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 118) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 29) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | STRUCT_PAT@[19; 23) | ||
18 | PATH@[19; 20) | ||
19 | PATH_SEGMENT@[19; 20) | ||
20 | NAME_REF@[19; 20) | ||
21 | IDENT@[19; 20) "S" | ||
22 | WHITESPACE@[20; 21) | ||
23 | FIELD_PAT_LIST@[21; 23) | ||
24 | L_CURLY@[21; 22) | ||
25 | R_CURLY@[22; 23) | ||
26 | WHITESPACE@[23; 24) | ||
27 | EQ@[24; 25) | ||
28 | WHITESPACE@[25; 26) | ||
29 | TUPLE_EXPR@[26; 28) | ||
30 | L_PAREN@[26; 27) | ||
31 | R_PAREN@[27; 28) | ||
32 | SEMI@[28; 29) | ||
33 | WHITESPACE@[29; 34) | ||
34 | LET_STMT@[34; 62) | ||
35 | LET_KW@[34; 37) | ||
36 | WHITESPACE@[37; 38) | ||
37 | STRUCT_PAT@[38; 56) | ||
38 | PATH@[38; 39) | ||
39 | PATH_SEGMENT@[38; 39) | ||
40 | NAME_REF@[38; 39) | ||
41 | IDENT@[38; 39) "S" | ||
42 | WHITESPACE@[39; 40) | ||
43 | FIELD_PAT_LIST@[40; 56) | ||
44 | L_CURLY@[40; 41) | ||
45 | WHITESPACE@[41; 42) | ||
46 | BIND_PAT@[42; 43) | ||
47 | NAME@[42; 43) | ||
48 | IDENT@[42; 43) "f" | ||
49 | COMMA@[43; 44) | ||
50 | WHITESPACE@[44; 45) | ||
51 | BIND_PAT@[45; 54) | ||
52 | REF_KW@[45; 48) | ||
53 | WHITESPACE@[48; 49) | ||
54 | MUT_KW@[49; 52) | ||
55 | WHITESPACE@[52; 53) | ||
56 | NAME@[53; 54) | ||
57 | IDENT@[53; 54) "g" | ||
58 | WHITESPACE@[54; 55) | ||
59 | R_CURLY@[55; 56) | ||
60 | WHITESPACE@[56; 57) | ||
61 | EQ@[57; 58) | ||
62 | WHITESPACE@[58; 59) | ||
63 | TUPLE_EXPR@[59; 61) | ||
64 | L_PAREN@[59; 60) | ||
65 | R_PAREN@[60; 61) | ||
66 | SEMI@[61; 62) | ||
67 | WHITESPACE@[62; 67) | ||
68 | LET_STMT@[67; 90) | ||
69 | LET_KW@[67; 70) | ||
70 | WHITESPACE@[70; 71) | ||
71 | STRUCT_PAT@[71; 84) | ||
72 | PATH@[71; 72) | ||
73 | PATH_SEGMENT@[71; 72) | ||
74 | NAME_REF@[71; 72) | ||
75 | IDENT@[71; 72) "S" | ||
76 | WHITESPACE@[72; 73) | ||
77 | FIELD_PAT_LIST@[73; 84) | ||
78 | L_CURLY@[73; 74) | ||
79 | WHITESPACE@[74; 75) | ||
80 | IDENT@[75; 76) "h" | ||
81 | COLON@[76; 77) | ||
82 | WHITESPACE@[77; 78) | ||
83 | PLACEHOLDER_PAT@[78; 79) | ||
84 | UNDERSCORE@[78; 79) | ||
85 | COMMA@[79; 80) | ||
86 | WHITESPACE@[80; 81) | ||
87 | DOTDOT@[81; 83) | ||
88 | R_CURLY@[83; 84) | ||
89 | WHITESPACE@[84; 85) | ||
90 | EQ@[85; 86) | ||
91 | WHITESPACE@[86; 87) | ||
92 | TUPLE_EXPR@[87; 89) | ||
93 | L_PAREN@[87; 88) | ||
94 | R_PAREN@[88; 89) | ||
95 | SEMI@[89; 90) | ||
96 | WHITESPACE@[90; 95) | ||
97 | LET_STMT@[95; 116) | ||
98 | LET_KW@[95; 98) | ||
99 | WHITESPACE@[98; 99) | ||
100 | STRUCT_PAT@[99; 110) | ||
101 | PATH@[99; 100) | ||
102 | PATH_SEGMENT@[99; 100) | ||
103 | NAME_REF@[99; 100) | ||
104 | IDENT@[99; 100) "S" | ||
105 | WHITESPACE@[100; 101) | ||
106 | FIELD_PAT_LIST@[101; 110) | ||
107 | L_CURLY@[101; 102) | ||
108 | WHITESPACE@[102; 103) | ||
109 | IDENT@[103; 104) "h" | ||
110 | COLON@[104; 105) | ||
111 | WHITESPACE@[105; 106) | ||
112 | PLACEHOLDER_PAT@[106; 107) | ||
113 | UNDERSCORE@[106; 107) | ||
114 | COMMA@[107; 108) | ||
115 | WHITESPACE@[108; 109) | ||
116 | R_CURLY@[109; 110) | ||
117 | WHITESPACE@[110; 111) | ||
118 | EQ@[111; 112) | ||
119 | WHITESPACE@[112; 113) | ||
120 | TUPLE_EXPR@[113; 115) | ||
121 | L_PAREN@[113; 114) | ||
122 | R_PAREN@[114; 115) | ||
123 | SEMI@[115; 116) | ||
124 | WHITESPACE@[116; 117) | ||
125 | R_CURLY@[117; 118) | ||
126 | WHITESPACE@[118; 119) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0055_self_param.rs b/crates/ra_syntax/tests/data/parser/inline/0055_self_param.rs new file mode 100644 index 000000000..80c0a43f5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0055_self_param.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | impl S { | ||
2 | fn a(self) {} | ||
3 | fn b(&self,) {} | ||
4 | fn c(&'a self,) {} | ||
5 | fn d(&'a mut self, x: i32) {} | ||
6 | fn e(mut self) {} | ||
7 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0055_self_param.txt b/crates/ra_syntax/tests/data/parser/inline/0055_self_param.txt new file mode 100644 index 000000000..f0e47c2dc --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0055_self_param.txt | |||
@@ -0,0 +1,116 @@ | |||
1 | ROOT@[0; 128) | ||
2 | IMPL_ITEM@[0; 127) | ||
3 | IMPL_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | PATH_TYPE@[5; 6) | ||
6 | PATH@[5; 6) | ||
7 | PATH_SEGMENT@[5; 6) | ||
8 | NAME_REF@[5; 6) | ||
9 | IDENT@[5; 6) "S" | ||
10 | WHITESPACE@[6; 7) | ||
11 | ITEM_LIST@[7; 127) | ||
12 | L_CURLY@[7; 8) | ||
13 | WHITESPACE@[8; 13) | ||
14 | FN_DEF@[13; 26) | ||
15 | FN_KW@[13; 15) | ||
16 | WHITESPACE@[15; 16) | ||
17 | NAME@[16; 17) | ||
18 | IDENT@[16; 17) "a" | ||
19 | PARAM_LIST@[17; 23) | ||
20 | L_PAREN@[17; 18) | ||
21 | SELF_PARAM@[18; 22) | ||
22 | SELF_KW@[18; 22) | ||
23 | R_PAREN@[22; 23) | ||
24 | WHITESPACE@[23; 24) | ||
25 | BLOCK@[24; 26) | ||
26 | L_CURLY@[24; 25) | ||
27 | R_CURLY@[25; 26) | ||
28 | WHITESPACE@[26; 31) | ||
29 | FN_DEF@[31; 46) | ||
30 | FN_KW@[31; 33) | ||
31 | WHITESPACE@[33; 34) | ||
32 | NAME@[34; 35) | ||
33 | IDENT@[34; 35) "b" | ||
34 | PARAM_LIST@[35; 43) | ||
35 | L_PAREN@[35; 36) | ||
36 | SELF_PARAM@[36; 41) | ||
37 | AMP@[36; 37) | ||
38 | SELF_KW@[37; 41) | ||
39 | COMMA@[41; 42) | ||
40 | R_PAREN@[42; 43) | ||
41 | WHITESPACE@[43; 44) | ||
42 | BLOCK@[44; 46) | ||
43 | L_CURLY@[44; 45) | ||
44 | R_CURLY@[45; 46) | ||
45 | WHITESPACE@[46; 51) | ||
46 | FN_DEF@[51; 69) | ||
47 | FN_KW@[51; 53) | ||
48 | WHITESPACE@[53; 54) | ||
49 | NAME@[54; 55) | ||
50 | IDENT@[54; 55) "c" | ||
51 | PARAM_LIST@[55; 66) | ||
52 | L_PAREN@[55; 56) | ||
53 | SELF_PARAM@[56; 64) | ||
54 | AMP@[56; 57) | ||
55 | LIFETIME@[57; 59) "'a" | ||
56 | WHITESPACE@[59; 60) | ||
57 | SELF_KW@[60; 64) | ||
58 | COMMA@[64; 65) | ||
59 | R_PAREN@[65; 66) | ||
60 | WHITESPACE@[66; 67) | ||
61 | BLOCK@[67; 69) | ||
62 | L_CURLY@[67; 68) | ||
63 | R_CURLY@[68; 69) | ||
64 | WHITESPACE@[69; 74) | ||
65 | FN_DEF@[74; 103) | ||
66 | FN_KW@[74; 76) | ||
67 | WHITESPACE@[76; 77) | ||
68 | NAME@[77; 78) | ||
69 | IDENT@[77; 78) "d" | ||
70 | PARAM_LIST@[78; 100) | ||
71 | L_PAREN@[78; 79) | ||
72 | SELF_PARAM@[79; 91) | ||
73 | AMP@[79; 80) | ||
74 | LIFETIME@[80; 82) "'a" | ||
75 | WHITESPACE@[82; 83) | ||
76 | MUT_KW@[83; 86) | ||
77 | WHITESPACE@[86; 87) | ||
78 | SELF_KW@[87; 91) | ||
79 | COMMA@[91; 92) | ||
80 | WHITESPACE@[92; 93) | ||
81 | PARAM@[93; 99) | ||
82 | BIND_PAT@[93; 94) | ||
83 | NAME@[93; 94) | ||
84 | IDENT@[93; 94) "x" | ||
85 | COLON@[94; 95) | ||
86 | WHITESPACE@[95; 96) | ||
87 | PATH_TYPE@[96; 99) | ||
88 | PATH@[96; 99) | ||
89 | PATH_SEGMENT@[96; 99) | ||
90 | NAME_REF@[96; 99) | ||
91 | IDENT@[96; 99) "i32" | ||
92 | R_PAREN@[99; 100) | ||
93 | WHITESPACE@[100; 101) | ||
94 | BLOCK@[101; 103) | ||
95 | L_CURLY@[101; 102) | ||
96 | R_CURLY@[102; 103) | ||
97 | WHITESPACE@[103; 108) | ||
98 | FN_DEF@[108; 125) | ||
99 | FN_KW@[108; 110) | ||
100 | WHITESPACE@[110; 111) | ||
101 | NAME@[111; 112) | ||
102 | IDENT@[111; 112) "e" | ||
103 | PARAM_LIST@[112; 122) | ||
104 | L_PAREN@[112; 113) | ||
105 | SELF_PARAM@[113; 121) | ||
106 | MUT_KW@[113; 116) | ||
107 | WHITESPACE@[116; 117) | ||
108 | SELF_KW@[117; 121) | ||
109 | R_PAREN@[121; 122) | ||
110 | WHITESPACE@[122; 123) | ||
111 | BLOCK@[123; 125) | ||
112 | L_CURLY@[123; 124) | ||
113 | R_CURLY@[124; 125) | ||
114 | WHITESPACE@[125; 126) | ||
115 | R_CURLY@[126; 127) | ||
116 | WHITESPACE@[127; 128) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.rs b/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.rs new file mode 100644 index 000000000..4385afca9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.rs | |||
@@ -0,0 +1 @@ | |||
trait T<U>: Hash + Clone where U: Copy {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.txt b/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.txt new file mode 100644 index 000000000..40c77db4b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0056_trait_item.txt | |||
@@ -0,0 +1,49 @@ | |||
1 | ROOT@[0; 42) | ||
2 | TRAIT_DEF@[0; 41) | ||
3 | TRAIT_KW@[0; 5) | ||
4 | WHITESPACE@[5; 6) | ||
5 | NAME@[6; 7) | ||
6 | IDENT@[6; 7) "T" | ||
7 | TYPE_PARAM_LIST@[7; 10) | ||
8 | L_ANGLE@[7; 8) | ||
9 | TYPE_PARAM@[8; 9) | ||
10 | NAME@[8; 9) | ||
11 | IDENT@[8; 9) "U" | ||
12 | R_ANGLE@[9; 10) | ||
13 | COLON@[10; 11) | ||
14 | WHITESPACE@[11; 12) | ||
15 | PATH_TYPE@[12; 24) | ||
16 | PATH@[12; 16) | ||
17 | PATH_SEGMENT@[12; 16) | ||
18 | NAME_REF@[12; 16) | ||
19 | IDENT@[12; 16) "Hash" | ||
20 | WHITESPACE@[16; 17) | ||
21 | PLUS@[17; 18) | ||
22 | WHITESPACE@[18; 19) | ||
23 | PATH_TYPE@[19; 24) | ||
24 | PATH@[19; 24) | ||
25 | PATH_SEGMENT@[19; 24) | ||
26 | NAME_REF@[19; 24) | ||
27 | IDENT@[19; 24) "Clone" | ||
28 | WHITESPACE@[24; 25) | ||
29 | WHERE_CLAUSE@[25; 38) | ||
30 | WHERE_KW@[25; 30) | ||
31 | WHITESPACE@[30; 31) | ||
32 | WHERE_PRED@[31; 38) | ||
33 | PATH_TYPE@[31; 32) | ||
34 | PATH@[31; 32) | ||
35 | PATH_SEGMENT@[31; 32) | ||
36 | NAME_REF@[31; 32) | ||
37 | IDENT@[31; 32) "U" | ||
38 | COLON@[32; 33) | ||
39 | WHITESPACE@[33; 34) | ||
40 | PATH_TYPE@[34; 38) | ||
41 | PATH@[34; 38) | ||
42 | PATH_SEGMENT@[34; 38) | ||
43 | NAME_REF@[34; 38) | ||
44 | IDENT@[34; 38) "Copy" | ||
45 | WHITESPACE@[38; 39) | ||
46 | ITEM_LIST@[39; 41) | ||
47 | L_CURLY@[39; 40) | ||
48 | R_CURLY@[40; 41) | ||
49 | WHITESPACE@[41; 42) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.rs b/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.rs new file mode 100644 index 000000000..72adf6035 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.rs | |||
@@ -0,0 +1 @@ | |||
auto trait T {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.txt b/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.txt new file mode 100644 index 000000000..0303d76bd --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0057_auto_trait.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | ROOT@[0; 16) | ||
2 | TRAIT_DEF@[0; 15) | ||
3 | AUTO_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | TRAIT_KW@[5; 10) | ||
6 | WHITESPACE@[10; 11) | ||
7 | NAME@[11; 12) | ||
8 | IDENT@[11; 12) "T" | ||
9 | WHITESPACE@[12; 13) | ||
10 | ITEM_LIST@[13; 15) | ||
11 | L_CURLY@[13; 14) | ||
12 | R_CURLY@[14; 15) | ||
13 | WHITESPACE@[15; 16) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.rs b/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.rs new file mode 100644 index 000000000..f0c8cc3a8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.rs | |||
@@ -0,0 +1 @@ | |||
type A = B<'static, i32, Item=u64> | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.txt b/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.txt new file mode 100644 index 000000000..aaf2924ba --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0058_type_arg.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | ROOT@[0; 35) | ||
2 | TYPE_DEF@[0; 34) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | PATH_TYPE@[9; 34) | ||
11 | PATH@[9; 34) | ||
12 | PATH_SEGMENT@[9; 34) | ||
13 | NAME_REF@[9; 10) | ||
14 | IDENT@[9; 10) "B" | ||
15 | TYPE_ARG_LIST@[10; 34) | ||
16 | L_ANGLE@[10; 11) | ||
17 | LIFETIME_ARG@[11; 18) | ||
18 | LIFETIME@[11; 18) "'static" | ||
19 | COMMA@[18; 19) | ||
20 | WHITESPACE@[19; 20) | ||
21 | TYPE_ARG@[20; 23) | ||
22 | PATH_TYPE@[20; 23) | ||
23 | PATH@[20; 23) | ||
24 | PATH_SEGMENT@[20; 23) | ||
25 | NAME_REF@[20; 23) | ||
26 | IDENT@[20; 23) "i32" | ||
27 | COMMA@[23; 24) | ||
28 | WHITESPACE@[24; 25) | ||
29 | ASSOC_TYPE_ARG@[25; 33) | ||
30 | NAME_REF@[25; 29) | ||
31 | IDENT@[25; 29) "Item" | ||
32 | EQ@[29; 30) | ||
33 | PATH_TYPE@[30; 33) | ||
34 | PATH@[30; 33) | ||
35 | PATH_SEGMENT@[30; 33) | ||
36 | NAME_REF@[30; 33) | ||
37 | IDENT@[30; 33) "u64" | ||
38 | R_ANGLE@[33; 34) | ||
39 | err: `expected SEMI` | ||
40 | WHITESPACE@[34; 35) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.rs b/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.rs new file mode 100644 index 000000000..f0920b2a8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.rs | |||
@@ -0,0 +1 @@ | |||
fn foo<T>() where T: Copy {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.txt b/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.txt new file mode 100644 index 000000000..281e79deb --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0059_function_where_clause.txt | |||
@@ -0,0 +1,37 @@ | |||
1 | ROOT@[0; 29) | ||
2 | FN_DEF@[0; 28) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | TYPE_PARAM_LIST@[6; 9) | ||
8 | L_ANGLE@[6; 7) | ||
9 | TYPE_PARAM@[7; 8) | ||
10 | NAME@[7; 8) | ||
11 | IDENT@[7; 8) "T" | ||
12 | R_ANGLE@[8; 9) | ||
13 | PARAM_LIST@[9; 11) | ||
14 | L_PAREN@[9; 10) | ||
15 | R_PAREN@[10; 11) | ||
16 | WHITESPACE@[11; 12) | ||
17 | WHERE_CLAUSE@[12; 25) | ||
18 | WHERE_KW@[12; 17) | ||
19 | WHITESPACE@[17; 18) | ||
20 | WHERE_PRED@[18; 25) | ||
21 | PATH_TYPE@[18; 19) | ||
22 | PATH@[18; 19) | ||
23 | PATH_SEGMENT@[18; 19) | ||
24 | NAME_REF@[18; 19) | ||
25 | IDENT@[18; 19) "T" | ||
26 | COLON@[19; 20) | ||
27 | WHITESPACE@[20; 21) | ||
28 | PATH_TYPE@[21; 25) | ||
29 | PATH@[21; 25) | ||
30 | PATH_SEGMENT@[21; 25) | ||
31 | NAME_REF@[21; 25) | ||
32 | IDENT@[21; 25) "Copy" | ||
33 | WHITESPACE@[25; 26) | ||
34 | BLOCK@[26; 28) | ||
35 | L_CURLY@[26; 27) | ||
36 | R_CURLY@[27; 28) | ||
37 | WHITESPACE@[28; 29) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.rs b/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.rs new file mode 100644 index 000000000..9df40ed39 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.rs | |||
@@ -0,0 +1 @@ | |||
fn foo<T: Clone + Copy>(){} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.txt b/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.txt new file mode 100644 index 000000000..b6fea5ab2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0060_function_type_params.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | ROOT@[0; 28) | ||
2 | FN_DEF@[0; 27) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | TYPE_PARAM_LIST@[6; 23) | ||
8 | L_ANGLE@[6; 7) | ||
9 | TYPE_PARAM@[7; 22) | ||
10 | NAME@[7; 8) | ||
11 | IDENT@[7; 8) "T" | ||
12 | COLON@[8; 9) | ||
13 | WHITESPACE@[9; 10) | ||
14 | PATH_TYPE@[10; 22) | ||
15 | PATH@[10; 15) | ||
16 | PATH_SEGMENT@[10; 15) | ||
17 | NAME_REF@[10; 15) | ||
18 | IDENT@[10; 15) "Clone" | ||
19 | WHITESPACE@[15; 16) | ||
20 | PLUS@[16; 17) | ||
21 | WHITESPACE@[17; 18) | ||
22 | PATH_TYPE@[18; 22) | ||
23 | PATH@[18; 22) | ||
24 | PATH_SEGMENT@[18; 22) | ||
25 | NAME_REF@[18; 22) | ||
26 | IDENT@[18; 22) "Copy" | ||
27 | R_ANGLE@[22; 23) | ||
28 | PARAM_LIST@[23; 25) | ||
29 | L_PAREN@[23; 24) | ||
30 | R_PAREN@[24; 25) | ||
31 | BLOCK@[25; 27) | ||
32 | L_CURLY@[25; 26) | ||
33 | R_CURLY@[26; 27) | ||
34 | WHITESPACE@[27; 28) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.rs b/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.rs new file mode 100644 index 000000000..eb711f68a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn foo() { | ||
2 | S {}; | ||
3 | S { x, y: 32, }; | ||
4 | S { x, y: 32, ..Default::default() }; | ||
5 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.txt b/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.txt new file mode 100644 index 000000000..cf6e881b2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0061_struct_lit.txt | |||
@@ -0,0 +1,97 @@ | |||
1 | ROOT@[0; 86) | ||
2 | FN_DEF@[0; 85) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 85) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 20) | ||
15 | STRUCT_LIT@[15; 19) | ||
16 | PATH@[15; 16) | ||
17 | PATH_SEGMENT@[15; 16) | ||
18 | NAME_REF@[15; 16) | ||
19 | IDENT@[15; 16) "S" | ||
20 | WHITESPACE@[16; 17) | ||
21 | NAMED_FIELD_LIST@[17; 19) | ||
22 | L_CURLY@[17; 18) | ||
23 | R_CURLY@[18; 19) | ||
24 | SEMI@[19; 20) | ||
25 | WHITESPACE@[20; 25) | ||
26 | EXPR_STMT@[25; 41) | ||
27 | STRUCT_LIT@[25; 40) | ||
28 | PATH@[25; 26) | ||
29 | PATH_SEGMENT@[25; 26) | ||
30 | NAME_REF@[25; 26) | ||
31 | IDENT@[25; 26) "S" | ||
32 | WHITESPACE@[26; 27) | ||
33 | NAMED_FIELD_LIST@[27; 40) | ||
34 | L_CURLY@[27; 28) | ||
35 | WHITESPACE@[28; 29) | ||
36 | NAMED_FIELD@[29; 30) | ||
37 | NAME_REF@[29; 30) | ||
38 | IDENT@[29; 30) "x" | ||
39 | COMMA@[30; 31) | ||
40 | WHITESPACE@[31; 32) | ||
41 | NAMED_FIELD@[32; 37) | ||
42 | NAME_REF@[32; 33) | ||
43 | IDENT@[32; 33) "y" | ||
44 | COLON@[33; 34) | ||
45 | WHITESPACE@[34; 35) | ||
46 | LITERAL@[35; 37) | ||
47 | INT_NUMBER@[35; 37) "32" | ||
48 | COMMA@[37; 38) | ||
49 | WHITESPACE@[38; 39) | ||
50 | R_CURLY@[39; 40) | ||
51 | SEMI@[40; 41) | ||
52 | WHITESPACE@[41; 46) | ||
53 | EXPR_STMT@[46; 83) | ||
54 | STRUCT_LIT@[46; 82) | ||
55 | PATH@[46; 47) | ||
56 | PATH_SEGMENT@[46; 47) | ||
57 | NAME_REF@[46; 47) | ||
58 | IDENT@[46; 47) "S" | ||
59 | WHITESPACE@[47; 48) | ||
60 | NAMED_FIELD_LIST@[48; 82) | ||
61 | L_CURLY@[48; 49) | ||
62 | WHITESPACE@[49; 50) | ||
63 | NAMED_FIELD@[50; 51) | ||
64 | NAME_REF@[50; 51) | ||
65 | IDENT@[50; 51) "x" | ||
66 | COMMA@[51; 52) | ||
67 | WHITESPACE@[52; 53) | ||
68 | NAMED_FIELD@[53; 58) | ||
69 | NAME_REF@[53; 54) | ||
70 | IDENT@[53; 54) "y" | ||
71 | COLON@[54; 55) | ||
72 | WHITESPACE@[55; 56) | ||
73 | LITERAL@[56; 58) | ||
74 | INT_NUMBER@[56; 58) "32" | ||
75 | COMMA@[58; 59) | ||
76 | WHITESPACE@[59; 60) | ||
77 | DOTDOT@[60; 62) | ||
78 | CALL_EXPR@[62; 80) | ||
79 | PATH_EXPR@[62; 78) | ||
80 | PATH@[62; 78) | ||
81 | PATH@[62; 69) | ||
82 | PATH_SEGMENT@[62; 69) | ||
83 | NAME_REF@[62; 69) | ||
84 | IDENT@[62; 69) "Default" | ||
85 | COLONCOLON@[69; 71) | ||
86 | PATH_SEGMENT@[71; 78) | ||
87 | NAME_REF@[71; 78) | ||
88 | IDENT@[71; 78) "default" | ||
89 | ARG_LIST@[78; 80) | ||
90 | L_PAREN@[78; 79) | ||
91 | R_PAREN@[79; 80) | ||
92 | WHITESPACE@[80; 81) | ||
93 | R_CURLY@[81; 82) | ||
94 | SEMI@[82; 83) | ||
95 | WHITESPACE@[83; 84) | ||
96 | R_CURLY@[84; 85) | ||
97 | WHITESPACE@[85; 86) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.rs b/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.rs new file mode 100644 index 000000000..54c5a7c46 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.rs | |||
@@ -0,0 +1 @@ | |||
type A = impl Iterator<Item=Foo<'a>> + 'a; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.txt b/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.txt new file mode 100644 index 000000000..68fce58ee --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0063_impl_trait_type.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | ROOT@[0; 43) | ||
2 | TYPE_DEF@[0; 42) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | IMPL_TRAIT_TYPE@[9; 41) | ||
11 | IMPL_KW@[9; 13) | ||
12 | WHITESPACE@[13; 14) | ||
13 | PATH_TYPE@[14; 41) | ||
14 | PATH@[14; 36) | ||
15 | PATH_SEGMENT@[14; 36) | ||
16 | NAME_REF@[14; 22) | ||
17 | IDENT@[14; 22) "Iterator" | ||
18 | TYPE_ARG_LIST@[22; 36) | ||
19 | L_ANGLE@[22; 23) | ||
20 | ASSOC_TYPE_ARG@[23; 35) | ||
21 | NAME_REF@[23; 27) | ||
22 | IDENT@[23; 27) "Item" | ||
23 | EQ@[27; 28) | ||
24 | PATH_TYPE@[28; 35) | ||
25 | PATH@[28; 35) | ||
26 | PATH_SEGMENT@[28; 35) | ||
27 | NAME_REF@[28; 31) | ||
28 | IDENT@[28; 31) "Foo" | ||
29 | TYPE_ARG_LIST@[31; 35) | ||
30 | L_ANGLE@[31; 32) | ||
31 | LIFETIME_ARG@[32; 34) | ||
32 | LIFETIME@[32; 34) "'a" | ||
33 | R_ANGLE@[34; 35) | ||
34 | R_ANGLE@[35; 36) | ||
35 | WHITESPACE@[36; 37) | ||
36 | PLUS@[37; 38) | ||
37 | WHITESPACE@[38; 39) | ||
38 | LIFETIME@[39; 41) "'a" | ||
39 | SEMI@[41; 42) | ||
40 | WHITESPACE@[42; 43) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0063_lambda_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0063_lambda_expr.txt new file mode 100644 index 000000000..93f6285ac --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0063_lambda_expr.txt | |||
@@ -0,0 +1,91 @@ | |||
1 | ROOT@[0; 74) | ||
2 | FN_DEF@[0; 74) | ||
3 | FN_KW@[0; 2) | ||
4 | NAME@[2; 6) | ||
5 | WHITESPACE@[2; 3) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 9) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK_EXPR@[9; 74) | ||
12 | L_CURLY@[9; 10) | ||
13 | EXPR_STMT@[10; 26) | ||
14 | LAMBDA_EXPR@[10; 20) | ||
15 | PARAM_LIST@[10; 18) | ||
16 | WHITESPACE@[10; 15) | ||
17 | PIPE@[15; 16) | ||
18 | PIPE@[16; 17) | ||
19 | WHITESPACE@[17; 18) | ||
20 | TUPLE_EXPR@[18; 20) | ||
21 | L_PAREN@[18; 19) | ||
22 | R_PAREN@[19; 20) | ||
23 | SEMI@[20; 21) | ||
24 | WHITESPACE@[21; 26) | ||
25 | EXPR_STMT@[26; 48) | ||
26 | LAMBDA_EXPR@[26; 42) | ||
27 | PARAM_LIST@[26; 29) | ||
28 | PIPE@[26; 27) | ||
29 | PIPE@[27; 28) | ||
30 | WHITESPACE@[28; 29) | ||
31 | THIN_ARROW@[29; 31) | ||
32 | PATH_TYPE@[31; 36) | ||
33 | PATH@[31; 36) | ||
34 | PATH_SEGMENT@[31; 36) | ||
35 | NAME_REF@[31; 36) | ||
36 | WHITESPACE@[31; 32) | ||
37 | IDENT@[32; 35) "i32" | ||
38 | WHITESPACE@[35; 36) | ||
39 | BLOCK_EXPR@[36; 42) | ||
40 | L_CURLY@[36; 37) | ||
41 | LITERAL@[37; 41) | ||
42 | WHITESPACE@[37; 38) | ||
43 | INT_NUMBER@[38; 40) "92" | ||
44 | WHITESPACE@[40; 41) | ||
45 | R_CURLY@[41; 42) | ||
46 | SEMI@[42; 43) | ||
47 | WHITESPACE@[43; 48) | ||
48 | EXPR_STMT@[48; 59) | ||
49 | LAMBDA_EXPR@[48; 53) | ||
50 | PARAM_LIST@[48; 52) | ||
51 | PIPE@[48; 49) | ||
52 | PARAM@[49; 50) | ||
53 | BIND_PAT@[49; 50) | ||
54 | NAME@[49; 50) | ||
55 | IDENT@[49; 50) "x" | ||
56 | PIPE@[50; 51) | ||
57 | WHITESPACE@[51; 52) | ||
58 | PATH_EXPR@[52; 53) | ||
59 | PATH@[52; 53) | ||
60 | PATH_SEGMENT@[52; 53) | ||
61 | NAME_REF@[52; 53) | ||
62 | IDENT@[52; 53) "x" | ||
63 | SEMI@[53; 54) | ||
64 | WHITESPACE@[54; 59) | ||
65 | EXPR_STMT@[59; 72) | ||
66 | LAMBDA_EXPR@[59; 70) | ||
67 | PARAM_LIST@[59; 69) | ||
68 | PIPE@[59; 60) | ||
69 | PARAM@[60; 66) | ||
70 | BIND_PAT@[60; 61) | ||
71 | NAME@[60; 61) | ||
72 | IDENT@[60; 61) "x" | ||
73 | COLON@[61; 62) | ||
74 | PATH_TYPE@[62; 66) | ||
75 | PATH@[62; 66) | ||
76 | PATH_SEGMENT@[62; 66) | ||
77 | NAME_REF@[62; 66) | ||
78 | WHITESPACE@[62; 63) | ||
79 | IDENT@[63; 66) "i32" | ||
80 | COMMA@[66; 67) | ||
81 | PIPE@[67; 68) | ||
82 | WHITESPACE@[68; 69) | ||
83 | PATH_EXPR@[69; 70) | ||
84 | PATH@[69; 70) | ||
85 | PATH_SEGMENT@[69; 70) | ||
86 | NAME_REF@[69; 70) | ||
87 | IDENT@[69; 70) "x" | ||
88 | SEMI@[70; 71) | ||
89 | WHITESPACE@[71; 72) | ||
90 | R_CURLY@[72; 73) | ||
91 | WHITESPACE@[73; 74) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0064_param_list.rs b/crates/ra_syntax/tests/data/parser/inline/0064_param_list.rs new file mode 100644 index 000000000..9d55bedbb --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0064_param_list.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn a() {} | ||
2 | fn b(x: i32) {} | ||
3 | fn c(x: i32, ) {} | ||
4 | fn d(x: i32, y: ()) {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0064_param_list.txt b/crates/ra_syntax/tests/data/parser/inline/0064_param_list.txt new file mode 100644 index 000000000..de547d699 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0064_param_list.txt | |||
@@ -0,0 +1,99 @@ | |||
1 | ROOT@[0; 67) | ||
2 | FN_DEF@[0; 9) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 4) | ||
6 | IDENT@[3; 4) "a" | ||
7 | PARAM_LIST@[4; 6) | ||
8 | L_PAREN@[4; 5) | ||
9 | R_PAREN@[5; 6) | ||
10 | WHITESPACE@[6; 7) | ||
11 | BLOCK@[7; 9) | ||
12 | L_CURLY@[7; 8) | ||
13 | R_CURLY@[8; 9) | ||
14 | WHITESPACE@[9; 10) | ||
15 | FN_DEF@[10; 25) | ||
16 | FN_KW@[10; 12) | ||
17 | WHITESPACE@[12; 13) | ||
18 | NAME@[13; 14) | ||
19 | IDENT@[13; 14) "b" | ||
20 | PARAM_LIST@[14; 22) | ||
21 | L_PAREN@[14; 15) | ||
22 | PARAM@[15; 21) | ||
23 | BIND_PAT@[15; 16) | ||
24 | NAME@[15; 16) | ||
25 | IDENT@[15; 16) "x" | ||
26 | COLON@[16; 17) | ||
27 | WHITESPACE@[17; 18) | ||
28 | PATH_TYPE@[18; 21) | ||
29 | PATH@[18; 21) | ||
30 | PATH_SEGMENT@[18; 21) | ||
31 | NAME_REF@[18; 21) | ||
32 | IDENT@[18; 21) "i32" | ||
33 | R_PAREN@[21; 22) | ||
34 | WHITESPACE@[22; 23) | ||
35 | BLOCK@[23; 25) | ||
36 | L_CURLY@[23; 24) | ||
37 | R_CURLY@[24; 25) | ||
38 | WHITESPACE@[25; 26) | ||
39 | FN_DEF@[26; 43) | ||
40 | FN_KW@[26; 28) | ||
41 | WHITESPACE@[28; 29) | ||
42 | NAME@[29; 30) | ||
43 | IDENT@[29; 30) "c" | ||
44 | PARAM_LIST@[30; 40) | ||
45 | L_PAREN@[30; 31) | ||
46 | PARAM@[31; 37) | ||
47 | BIND_PAT@[31; 32) | ||
48 | NAME@[31; 32) | ||
49 | IDENT@[31; 32) "x" | ||
50 | COLON@[32; 33) | ||
51 | WHITESPACE@[33; 34) | ||
52 | PATH_TYPE@[34; 37) | ||
53 | PATH@[34; 37) | ||
54 | PATH_SEGMENT@[34; 37) | ||
55 | NAME_REF@[34; 37) | ||
56 | IDENT@[34; 37) "i32" | ||
57 | COMMA@[37; 38) | ||
58 | WHITESPACE@[38; 39) | ||
59 | R_PAREN@[39; 40) | ||
60 | WHITESPACE@[40; 41) | ||
61 | BLOCK@[41; 43) | ||
62 | L_CURLY@[41; 42) | ||
63 | R_CURLY@[42; 43) | ||
64 | WHITESPACE@[43; 44) | ||
65 | FN_DEF@[44; 66) | ||
66 | FN_KW@[44; 46) | ||
67 | WHITESPACE@[46; 47) | ||
68 | NAME@[47; 48) | ||
69 | IDENT@[47; 48) "d" | ||
70 | PARAM_LIST@[48; 63) | ||
71 | L_PAREN@[48; 49) | ||
72 | PARAM@[49; 55) | ||
73 | BIND_PAT@[49; 50) | ||
74 | NAME@[49; 50) | ||
75 | IDENT@[49; 50) "x" | ||
76 | COLON@[50; 51) | ||
77 | WHITESPACE@[51; 52) | ||
78 | PATH_TYPE@[52; 55) | ||
79 | PATH@[52; 55) | ||
80 | PATH_SEGMENT@[52; 55) | ||
81 | NAME_REF@[52; 55) | ||
82 | IDENT@[52; 55) "i32" | ||
83 | COMMA@[55; 56) | ||
84 | WHITESPACE@[56; 57) | ||
85 | PARAM@[57; 62) | ||
86 | BIND_PAT@[57; 58) | ||
87 | NAME@[57; 58) | ||
88 | IDENT@[57; 58) "y" | ||
89 | COLON@[58; 59) | ||
90 | WHITESPACE@[59; 60) | ||
91 | TUPLE_TYPE@[60; 62) | ||
92 | L_PAREN@[60; 61) | ||
93 | R_PAREN@[61; 62) | ||
94 | R_PAREN@[62; 63) | ||
95 | WHITESPACE@[63; 64) | ||
96 | BLOCK@[64; 66) | ||
97 | L_CURLY@[64; 65) | ||
98 | R_CURLY@[65; 66) | ||
99 | WHITESPACE@[66; 67) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.rs new file mode 100644 index 000000000..4b0d9af89 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | if true {}; | ||
3 | if true {} else {}; | ||
4 | if true {} else if false {} else {}; | ||
5 | if S {}; | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.txt new file mode 100644 index 000000000..ae1a8101e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0065_if_expr.txt | |||
@@ -0,0 +1,95 @@ | |||
1 | ROOT@[0; 107) | ||
2 | FN_DEF@[0; 106) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 106) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 26) | ||
15 | IF_EXPR@[15; 25) | ||
16 | IF_KW@[15; 17) | ||
17 | WHITESPACE@[17; 18) | ||
18 | CONDITION@[18; 22) | ||
19 | LITERAL@[18; 22) | ||
20 | TRUE_KW@[18; 22) | ||
21 | WHITESPACE@[22; 23) | ||
22 | BLOCK@[23; 25) | ||
23 | L_CURLY@[23; 24) | ||
24 | R_CURLY@[24; 25) | ||
25 | SEMI@[25; 26) | ||
26 | WHITESPACE@[26; 31) | ||
27 | EXPR_STMT@[31; 50) | ||
28 | IF_EXPR@[31; 49) | ||
29 | IF_KW@[31; 33) | ||
30 | WHITESPACE@[33; 34) | ||
31 | CONDITION@[34; 38) | ||
32 | LITERAL@[34; 38) | ||
33 | TRUE_KW@[34; 38) | ||
34 | WHITESPACE@[38; 39) | ||
35 | BLOCK@[39; 41) | ||
36 | L_CURLY@[39; 40) | ||
37 | R_CURLY@[40; 41) | ||
38 | WHITESPACE@[41; 42) | ||
39 | ELSE_KW@[42; 46) | ||
40 | WHITESPACE@[46; 47) | ||
41 | BLOCK@[47; 49) | ||
42 | L_CURLY@[47; 48) | ||
43 | R_CURLY@[48; 49) | ||
44 | SEMI@[49; 50) | ||
45 | WHITESPACE@[50; 55) | ||
46 | EXPR_STMT@[55; 91) | ||
47 | IF_EXPR@[55; 90) | ||
48 | IF_KW@[55; 57) | ||
49 | WHITESPACE@[57; 58) | ||
50 | CONDITION@[58; 62) | ||
51 | LITERAL@[58; 62) | ||
52 | TRUE_KW@[58; 62) | ||
53 | WHITESPACE@[62; 63) | ||
54 | BLOCK@[63; 65) | ||
55 | L_CURLY@[63; 64) | ||
56 | R_CURLY@[64; 65) | ||
57 | WHITESPACE@[65; 66) | ||
58 | ELSE_KW@[66; 70) | ||
59 | WHITESPACE@[70; 71) | ||
60 | IF_EXPR@[71; 90) | ||
61 | IF_KW@[71; 73) | ||
62 | WHITESPACE@[73; 74) | ||
63 | CONDITION@[74; 79) | ||
64 | LITERAL@[74; 79) | ||
65 | FALSE_KW@[74; 79) | ||
66 | WHITESPACE@[79; 80) | ||
67 | BLOCK@[80; 82) | ||
68 | L_CURLY@[80; 81) | ||
69 | R_CURLY@[81; 82) | ||
70 | WHITESPACE@[82; 83) | ||
71 | ELSE_KW@[83; 87) | ||
72 | WHITESPACE@[87; 88) | ||
73 | BLOCK@[88; 90) | ||
74 | L_CURLY@[88; 89) | ||
75 | R_CURLY@[89; 90) | ||
76 | SEMI@[90; 91) | ||
77 | WHITESPACE@[91; 96) | ||
78 | EXPR_STMT@[96; 104) | ||
79 | IF_EXPR@[96; 103) | ||
80 | IF_KW@[96; 98) | ||
81 | WHITESPACE@[98; 99) | ||
82 | CONDITION@[99; 100) | ||
83 | PATH_EXPR@[99; 100) | ||
84 | PATH@[99; 100) | ||
85 | PATH_SEGMENT@[99; 100) | ||
86 | NAME_REF@[99; 100) | ||
87 | IDENT@[99; 100) "S" | ||
88 | WHITESPACE@[100; 101) | ||
89 | BLOCK@[101; 103) | ||
90 | L_CURLY@[101; 102) | ||
91 | R_CURLY@[102; 103) | ||
92 | SEMI@[103; 104) | ||
93 | WHITESPACE@[104; 105) | ||
94 | R_CURLY@[105; 106) | ||
95 | WHITESPACE@[106; 107) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.rs new file mode 100644 index 000000000..c20d29751 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | || (); | ||
3 | || -> i32 { 92 }; | ||
4 | |x| x; | ||
5 | move |x: i32,| x; | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.txt new file mode 100644 index 000000000..82aaf3897 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0066_lambda_expr.txt | |||
@@ -0,0 +1,95 @@ | |||
1 | ROOT@[0; 79) | ||
2 | FN_DEF@[0; 78) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 78) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 21) | ||
15 | LAMBDA_EXPR@[15; 20) | ||
16 | PARAM_LIST@[15; 17) | ||
17 | PIPE@[15; 16) | ||
18 | PIPE@[16; 17) | ||
19 | WHITESPACE@[17; 18) | ||
20 | TUPLE_EXPR@[18; 20) | ||
21 | L_PAREN@[18; 19) | ||
22 | R_PAREN@[19; 20) | ||
23 | SEMI@[20; 21) | ||
24 | WHITESPACE@[21; 26) | ||
25 | EXPR_STMT@[26; 43) | ||
26 | LAMBDA_EXPR@[26; 42) | ||
27 | PARAM_LIST@[26; 28) | ||
28 | PIPE@[26; 27) | ||
29 | PIPE@[27; 28) | ||
30 | WHITESPACE@[28; 29) | ||
31 | RET_TYPE@[29; 35) | ||
32 | THIN_ARROW@[29; 31) | ||
33 | WHITESPACE@[31; 32) | ||
34 | PATH_TYPE@[32; 35) | ||
35 | PATH@[32; 35) | ||
36 | PATH_SEGMENT@[32; 35) | ||
37 | NAME_REF@[32; 35) | ||
38 | IDENT@[32; 35) "i32" | ||
39 | WHITESPACE@[35; 36) | ||
40 | BLOCK_EXPR@[36; 42) | ||
41 | BLOCK@[36; 42) | ||
42 | L_CURLY@[36; 37) | ||
43 | WHITESPACE@[37; 38) | ||
44 | LITERAL@[38; 40) | ||
45 | INT_NUMBER@[38; 40) "92" | ||
46 | WHITESPACE@[40; 41) | ||
47 | R_CURLY@[41; 42) | ||
48 | SEMI@[42; 43) | ||
49 | WHITESPACE@[43; 48) | ||
50 | EXPR_STMT@[48; 54) | ||
51 | LAMBDA_EXPR@[48; 53) | ||
52 | PARAM_LIST@[48; 51) | ||
53 | PIPE@[48; 49) | ||
54 | PARAM@[49; 50) | ||
55 | BIND_PAT@[49; 50) | ||
56 | NAME@[49; 50) | ||
57 | IDENT@[49; 50) "x" | ||
58 | PIPE@[50; 51) | ||
59 | WHITESPACE@[51; 52) | ||
60 | PATH_EXPR@[52; 53) | ||
61 | PATH@[52; 53) | ||
62 | PATH_SEGMENT@[52; 53) | ||
63 | NAME_REF@[52; 53) | ||
64 | IDENT@[52; 53) "x" | ||
65 | SEMI@[53; 54) | ||
66 | WHITESPACE@[54; 59) | ||
67 | EXPR_STMT@[59; 76) | ||
68 | LAMBDA_EXPR@[59; 75) | ||
69 | MOVE_KW@[59; 63) | ||
70 | WHITESPACE@[63; 64) | ||
71 | PARAM_LIST@[64; 73) | ||
72 | PIPE@[64; 65) | ||
73 | PARAM@[65; 71) | ||
74 | BIND_PAT@[65; 66) | ||
75 | NAME@[65; 66) | ||
76 | IDENT@[65; 66) "x" | ||
77 | COLON@[66; 67) | ||
78 | WHITESPACE@[67; 68) | ||
79 | PATH_TYPE@[68; 71) | ||
80 | PATH@[68; 71) | ||
81 | PATH_SEGMENT@[68; 71) | ||
82 | NAME_REF@[68; 71) | ||
83 | IDENT@[68; 71) "i32" | ||
84 | COMMA@[71; 72) | ||
85 | PIPE@[72; 73) | ||
86 | WHITESPACE@[73; 74) | ||
87 | PATH_EXPR@[74; 75) | ||
88 | PATH@[74; 75) | ||
89 | PATH_SEGMENT@[74; 75) | ||
90 | NAME_REF@[74; 75) | ||
91 | IDENT@[74; 75) "x" | ||
92 | SEMI@[75; 76) | ||
93 | WHITESPACE@[76; 77) | ||
94 | R_CURLY@[77; 78) | ||
95 | WHITESPACE@[78; 79) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.rs new file mode 100644 index 000000000..2fed74c5e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn foo() { | ||
2 | {}; | ||
3 | unsafe {}; | ||
4 | 'label: {}; | ||
5 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.txt new file mode 100644 index 000000000..12a1ff49a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0067_block_expr.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | ROOT@[0; 52) | ||
2 | FN_DEF@[0; 51) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 51) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 18) | ||
15 | BLOCK_EXPR@[15; 17) | ||
16 | BLOCK@[15; 17) | ||
17 | L_CURLY@[15; 16) | ||
18 | R_CURLY@[16; 17) | ||
19 | SEMI@[17; 18) | ||
20 | WHITESPACE@[18; 23) | ||
21 | EXPR_STMT@[23; 33) | ||
22 | BLOCK_EXPR@[23; 32) | ||
23 | UNSAFE_KW@[23; 29) | ||
24 | WHITESPACE@[29; 30) | ||
25 | BLOCK@[30; 32) | ||
26 | L_CURLY@[30; 31) | ||
27 | R_CURLY@[31; 32) | ||
28 | SEMI@[32; 33) | ||
29 | WHITESPACE@[33; 38) | ||
30 | EXPR_STMT@[38; 49) | ||
31 | BLOCK_EXPR@[38; 48) | ||
32 | LABEL@[38; 45) | ||
33 | LIFETIME@[38; 44) "'label" | ||
34 | COLON@[44; 45) | ||
35 | WHITESPACE@[45; 46) | ||
36 | BLOCK@[46; 48) | ||
37 | L_CURLY@[46; 47) | ||
38 | R_CURLY@[47; 48) | ||
39 | SEMI@[48; 49) | ||
40 | WHITESPACE@[49; 50) | ||
41 | R_CURLY@[50; 51) | ||
42 | WHITESPACE@[51; 52) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.rs new file mode 100644 index 000000000..d9d99d2d3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.rs | |||
@@ -0,0 +1 @@ | |||
fn foo() { pub 92; } //FIXME | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.txt new file mode 100644 index 000000000..5f179c3ca --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0068_pub_expr.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | ROOT@[0; 29) | ||
2 | FN_DEF@[0; 20) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 20) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 11) | ||
14 | EXPR_STMT@[11; 18) | ||
15 | VISIBILITY@[11; 14) | ||
16 | PUB_KW@[11; 14) | ||
17 | WHITESPACE@[14; 15) | ||
18 | LITERAL@[15; 17) | ||
19 | INT_NUMBER@[15; 17) "92" | ||
20 | SEMI@[17; 18) | ||
21 | WHITESPACE@[18; 19) | ||
22 | R_CURLY@[19; 20) | ||
23 | WHITESPACE@[20; 21) | ||
24 | COMMENT@[21; 28) | ||
25 | WHITESPACE@[28; 29) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.rs new file mode 100644 index 000000000..5733666b6 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | return; | ||
3 | return 92; | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.txt new file mode 100644 index 000000000..ead1ada96 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0068_return_expr.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | ROOT@[0; 40) | ||
2 | FN_DEF@[0; 39) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 39) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 22) | ||
15 | RETURN_EXPR@[15; 21) | ||
16 | RETURN_KW@[15; 21) | ||
17 | SEMI@[21; 22) | ||
18 | WHITESPACE@[22; 27) | ||
19 | EXPR_STMT@[27; 37) | ||
20 | RETURN_EXPR@[27; 36) | ||
21 | RETURN_KW@[27; 33) | ||
22 | WHITESPACE@[33; 34) | ||
23 | LITERAL@[34; 36) | ||
24 | INT_NUMBER@[34; 36) "92" | ||
25 | SEMI@[36; 37) | ||
26 | WHITESPACE@[37; 38) | ||
27 | R_CURLY@[38; 39) | ||
28 | WHITESPACE@[39; 40) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.rs b/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.rs new file mode 100644 index 000000000..2c0e88414 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | match () { | ||
3 | _ => (), | ||
4 | X | Y if Z => (), | ||
5 | }; | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.txt b/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.txt new file mode 100644 index 000000000..013d1716a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0069_match_arm.txt | |||
@@ -0,0 +1,66 @@ | |||
1 | ROOT@[0; 78) | ||
2 | FN_DEF@[0; 77) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 77) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 75) | ||
15 | MATCH_EXPR@[15; 74) | ||
16 | MATCH_KW@[15; 20) | ||
17 | WHITESPACE@[20; 21) | ||
18 | TUPLE_EXPR@[21; 23) | ||
19 | L_PAREN@[21; 22) | ||
20 | R_PAREN@[22; 23) | ||
21 | WHITESPACE@[23; 24) | ||
22 | MATCH_ARM_LIST@[24; 74) | ||
23 | L_CURLY@[24; 25) | ||
24 | WHITESPACE@[25; 34) | ||
25 | MATCH_ARM@[34; 41) | ||
26 | PLACEHOLDER_PAT@[34; 35) | ||
27 | UNDERSCORE@[34; 35) | ||
28 | WHITESPACE@[35; 36) | ||
29 | FAT_ARROW@[36; 38) | ||
30 | WHITESPACE@[38; 39) | ||
31 | TUPLE_EXPR@[39; 41) | ||
32 | L_PAREN@[39; 40) | ||
33 | R_PAREN@[40; 41) | ||
34 | COMMA@[41; 42) | ||
35 | WHITESPACE@[42; 51) | ||
36 | MATCH_ARM@[51; 67) | ||
37 | BIND_PAT@[51; 52) | ||
38 | NAME@[51; 52) | ||
39 | IDENT@[51; 52) "X" | ||
40 | WHITESPACE@[52; 53) | ||
41 | PIPE@[53; 54) | ||
42 | WHITESPACE@[54; 55) | ||
43 | BIND_PAT@[55; 56) | ||
44 | NAME@[55; 56) | ||
45 | IDENT@[55; 56) "Y" | ||
46 | WHITESPACE@[56; 57) | ||
47 | IF_KW@[57; 59) | ||
48 | WHITESPACE@[59; 60) | ||
49 | PATH_EXPR@[60; 61) | ||
50 | PATH@[60; 61) | ||
51 | PATH_SEGMENT@[60; 61) | ||
52 | NAME_REF@[60; 61) | ||
53 | IDENT@[60; 61) "Z" | ||
54 | WHITESPACE@[61; 62) | ||
55 | FAT_ARROW@[62; 64) | ||
56 | WHITESPACE@[64; 65) | ||
57 | TUPLE_EXPR@[65; 67) | ||
58 | L_PAREN@[65; 66) | ||
59 | R_PAREN@[66; 67) | ||
60 | COMMA@[67; 68) | ||
61 | WHITESPACE@[68; 73) | ||
62 | R_CURLY@[73; 74) | ||
63 | SEMI@[74; 75) | ||
64 | WHITESPACE@[75; 76) | ||
65 | R_CURLY@[76; 77) | ||
66 | WHITESPACE@[77; 78) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.rs new file mode 100644 index 000000000..c9205dfa3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | match () { }; | ||
3 | match S {}; | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.txt new file mode 100644 index 000000000..d7740e3cc --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0070_match_expr.txt | |||
@@ -0,0 +1,44 @@ | |||
1 | ROOT@[0; 47) | ||
2 | FN_DEF@[0; 46) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 46) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 28) | ||
15 | MATCH_EXPR@[15; 27) | ||
16 | MATCH_KW@[15; 20) | ||
17 | WHITESPACE@[20; 21) | ||
18 | TUPLE_EXPR@[21; 23) | ||
19 | L_PAREN@[21; 22) | ||
20 | R_PAREN@[22; 23) | ||
21 | WHITESPACE@[23; 24) | ||
22 | MATCH_ARM_LIST@[24; 27) | ||
23 | L_CURLY@[24; 25) | ||
24 | WHITESPACE@[25; 26) | ||
25 | R_CURLY@[26; 27) | ||
26 | SEMI@[27; 28) | ||
27 | WHITESPACE@[28; 33) | ||
28 | EXPR_STMT@[33; 44) | ||
29 | MATCH_EXPR@[33; 43) | ||
30 | MATCH_KW@[33; 38) | ||
31 | WHITESPACE@[38; 39) | ||
32 | PATH_EXPR@[39; 40) | ||
33 | PATH@[39; 40) | ||
34 | PATH_SEGMENT@[39; 40) | ||
35 | NAME_REF@[39; 40) | ||
36 | IDENT@[39; 40) "S" | ||
37 | WHITESPACE@[40; 41) | ||
38 | MATCH_ARM_LIST@[41; 43) | ||
39 | L_CURLY@[41; 42) | ||
40 | R_CURLY@[42; 43) | ||
41 | SEMI@[43; 44) | ||
42 | WHITESPACE@[44; 45) | ||
43 | R_CURLY@[45; 46) | ||
44 | WHITESPACE@[46; 47) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.rs b/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.rs new file mode 100644 index 000000000..0dfe63629 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | let S() = (); | ||
3 | let S(_) = (); | ||
4 | let S(_,) = (); | ||
5 | let S(_, .. , x) = (); | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.txt b/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.txt new file mode 100644 index 000000000..734e0726c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0071_tuple_pat_fields.txt | |||
@@ -0,0 +1,103 @@ | |||
1 | ROOT@[0; 97) | ||
2 | FN_DEF@[0; 96) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 96) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 28) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | TUPLE_STRUCT_PAT@[19; 22) | ||
18 | PATH@[19; 20) | ||
19 | PATH_SEGMENT@[19; 20) | ||
20 | NAME_REF@[19; 20) | ||
21 | IDENT@[19; 20) "S" | ||
22 | L_PAREN@[20; 21) | ||
23 | R_PAREN@[21; 22) | ||
24 | WHITESPACE@[22; 23) | ||
25 | EQ@[23; 24) | ||
26 | WHITESPACE@[24; 25) | ||
27 | TUPLE_EXPR@[25; 27) | ||
28 | L_PAREN@[25; 26) | ||
29 | R_PAREN@[26; 27) | ||
30 | SEMI@[27; 28) | ||
31 | WHITESPACE@[28; 33) | ||
32 | LET_STMT@[33; 47) | ||
33 | LET_KW@[33; 36) | ||
34 | WHITESPACE@[36; 37) | ||
35 | TUPLE_STRUCT_PAT@[37; 41) | ||
36 | PATH@[37; 38) | ||
37 | PATH_SEGMENT@[37; 38) | ||
38 | NAME_REF@[37; 38) | ||
39 | IDENT@[37; 38) "S" | ||
40 | L_PAREN@[38; 39) | ||
41 | PLACEHOLDER_PAT@[39; 40) | ||
42 | UNDERSCORE@[39; 40) | ||
43 | R_PAREN@[40; 41) | ||
44 | WHITESPACE@[41; 42) | ||
45 | EQ@[42; 43) | ||
46 | WHITESPACE@[43; 44) | ||
47 | TUPLE_EXPR@[44; 46) | ||
48 | L_PAREN@[44; 45) | ||
49 | R_PAREN@[45; 46) | ||
50 | SEMI@[46; 47) | ||
51 | WHITESPACE@[47; 52) | ||
52 | LET_STMT@[52; 67) | ||
53 | LET_KW@[52; 55) | ||
54 | WHITESPACE@[55; 56) | ||
55 | TUPLE_STRUCT_PAT@[56; 61) | ||
56 | PATH@[56; 57) | ||
57 | PATH_SEGMENT@[56; 57) | ||
58 | NAME_REF@[56; 57) | ||
59 | IDENT@[56; 57) "S" | ||
60 | L_PAREN@[57; 58) | ||
61 | PLACEHOLDER_PAT@[58; 59) | ||
62 | UNDERSCORE@[58; 59) | ||
63 | COMMA@[59; 60) | ||
64 | R_PAREN@[60; 61) | ||
65 | WHITESPACE@[61; 62) | ||
66 | EQ@[62; 63) | ||
67 | WHITESPACE@[63; 64) | ||
68 | TUPLE_EXPR@[64; 66) | ||
69 | L_PAREN@[64; 65) | ||
70 | R_PAREN@[65; 66) | ||
71 | SEMI@[66; 67) | ||
72 | WHITESPACE@[67; 72) | ||
73 | LET_STMT@[72; 94) | ||
74 | LET_KW@[72; 75) | ||
75 | WHITESPACE@[75; 76) | ||
76 | TUPLE_STRUCT_PAT@[76; 88) | ||
77 | PATH@[76; 77) | ||
78 | PATH_SEGMENT@[76; 77) | ||
79 | NAME_REF@[76; 77) | ||
80 | IDENT@[76; 77) "S" | ||
81 | L_PAREN@[77; 78) | ||
82 | PLACEHOLDER_PAT@[78; 79) | ||
83 | UNDERSCORE@[78; 79) | ||
84 | COMMA@[79; 80) | ||
85 | WHITESPACE@[80; 81) | ||
86 | DOTDOT@[81; 83) | ||
87 | WHITESPACE@[83; 84) | ||
88 | COMMA@[84; 85) | ||
89 | WHITESPACE@[85; 86) | ||
90 | BIND_PAT@[86; 87) | ||
91 | NAME@[86; 87) | ||
92 | IDENT@[86; 87) "x" | ||
93 | R_PAREN@[87; 88) | ||
94 | WHITESPACE@[88; 89) | ||
95 | EQ@[89; 90) | ||
96 | WHITESPACE@[90; 91) | ||
97 | TUPLE_EXPR@[91; 93) | ||
98 | L_PAREN@[91; 92) | ||
99 | R_PAREN@[92; 93) | ||
100 | SEMI@[93; 94) | ||
101 | WHITESPACE@[94; 95) | ||
102 | R_CURLY@[95; 96) | ||
103 | WHITESPACE@[96; 97) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0072_path_part.rs b/crates/ra_syntax/tests/data/parser/inline/0072_path_part.rs new file mode 100644 index 000000000..f6e32c7c1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0072_path_part.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | let foo::Bar = (); | ||
3 | let ::Bar = (); | ||
4 | let Bar { .. } = (); | ||
5 | let Bar(..) = (); | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0072_path_part.txt b/crates/ra_syntax/tests/data/parser/inline/0072_path_part.txt new file mode 100644 index 000000000..1a8d1546d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0072_path_part.txt | |||
@@ -0,0 +1,95 @@ | |||
1 | ROOT@[0; 103) | ||
2 | FN_DEF@[0; 102) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 102) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 33) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | PATH_PAT@[19; 27) | ||
18 | PATH@[19; 27) | ||
19 | PATH@[19; 22) | ||
20 | PATH_SEGMENT@[19; 22) | ||
21 | NAME_REF@[19; 22) | ||
22 | IDENT@[19; 22) "foo" | ||
23 | COLONCOLON@[22; 24) | ||
24 | PATH_SEGMENT@[24; 27) | ||
25 | NAME_REF@[24; 27) | ||
26 | IDENT@[24; 27) "Bar" | ||
27 | WHITESPACE@[27; 28) | ||
28 | EQ@[28; 29) | ||
29 | WHITESPACE@[29; 30) | ||
30 | TUPLE_EXPR@[30; 32) | ||
31 | L_PAREN@[30; 31) | ||
32 | R_PAREN@[31; 32) | ||
33 | SEMI@[32; 33) | ||
34 | WHITESPACE@[33; 38) | ||
35 | LET_STMT@[38; 53) | ||
36 | LET_KW@[38; 41) | ||
37 | WHITESPACE@[41; 42) | ||
38 | PATH_PAT@[42; 47) | ||
39 | PATH@[42; 47) | ||
40 | PATH_SEGMENT@[42; 47) | ||
41 | COLONCOLON@[42; 44) | ||
42 | NAME_REF@[44; 47) | ||
43 | IDENT@[44; 47) "Bar" | ||
44 | WHITESPACE@[47; 48) | ||
45 | EQ@[48; 49) | ||
46 | WHITESPACE@[49; 50) | ||
47 | TUPLE_EXPR@[50; 52) | ||
48 | L_PAREN@[50; 51) | ||
49 | R_PAREN@[51; 52) | ||
50 | SEMI@[52; 53) | ||
51 | WHITESPACE@[53; 58) | ||
52 | LET_STMT@[58; 78) | ||
53 | LET_KW@[58; 61) | ||
54 | WHITESPACE@[61; 62) | ||
55 | STRUCT_PAT@[62; 72) | ||
56 | PATH@[62; 65) | ||
57 | PATH_SEGMENT@[62; 65) | ||
58 | NAME_REF@[62; 65) | ||
59 | IDENT@[62; 65) "Bar" | ||
60 | WHITESPACE@[65; 66) | ||
61 | FIELD_PAT_LIST@[66; 72) | ||
62 | L_CURLY@[66; 67) | ||
63 | WHITESPACE@[67; 68) | ||
64 | DOTDOT@[68; 70) | ||
65 | WHITESPACE@[70; 71) | ||
66 | R_CURLY@[71; 72) | ||
67 | WHITESPACE@[72; 73) | ||
68 | EQ@[73; 74) | ||
69 | WHITESPACE@[74; 75) | ||
70 | TUPLE_EXPR@[75; 77) | ||
71 | L_PAREN@[75; 76) | ||
72 | R_PAREN@[76; 77) | ||
73 | SEMI@[77; 78) | ||
74 | WHITESPACE@[78; 83) | ||
75 | LET_STMT@[83; 100) | ||
76 | LET_KW@[83; 86) | ||
77 | WHITESPACE@[86; 87) | ||
78 | TUPLE_STRUCT_PAT@[87; 94) | ||
79 | PATH@[87; 90) | ||
80 | PATH_SEGMENT@[87; 90) | ||
81 | NAME_REF@[87; 90) | ||
82 | IDENT@[87; 90) "Bar" | ||
83 | L_PAREN@[90; 91) | ||
84 | DOTDOT@[91; 93) | ||
85 | R_PAREN@[93; 94) | ||
86 | WHITESPACE@[94; 95) | ||
87 | EQ@[95; 96) | ||
88 | WHITESPACE@[96; 97) | ||
89 | TUPLE_EXPR@[97; 99) | ||
90 | L_PAREN@[97; 98) | ||
91 | R_PAREN@[98; 99) | ||
92 | SEMI@[99; 100) | ||
93 | WHITESPACE@[100; 101) | ||
94 | R_CURLY@[101; 102) | ||
95 | WHITESPACE@[102; 103) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.rs b/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.rs new file mode 100644 index 000000000..f10851487 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | impl F { | ||
2 | type A = i32; | ||
3 | const B: i32 = 92; | ||
4 | fn foo() {} | ||
5 | fn bar(&self) {} | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.txt b/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.txt new file mode 100644 index 000000000..1f524f34a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0073_impl_item_list.txt | |||
@@ -0,0 +1,78 @@ | |||
1 | ROOT@[0; 89) | ||
2 | IMPL_ITEM@[0; 88) | ||
3 | IMPL_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | PATH_TYPE@[5; 6) | ||
6 | PATH@[5; 6) | ||
7 | PATH_SEGMENT@[5; 6) | ||
8 | NAME_REF@[5; 6) | ||
9 | IDENT@[5; 6) "F" | ||
10 | WHITESPACE@[6; 7) | ||
11 | ITEM_LIST@[7; 88) | ||
12 | L_CURLY@[7; 8) | ||
13 | WHITESPACE@[8; 13) | ||
14 | TYPE_DEF@[13; 26) | ||
15 | TYPE_KW@[13; 17) | ||
16 | WHITESPACE@[17; 18) | ||
17 | NAME@[18; 19) | ||
18 | IDENT@[18; 19) "A" | ||
19 | WHITESPACE@[19; 20) | ||
20 | EQ@[20; 21) | ||
21 | WHITESPACE@[21; 22) | ||
22 | PATH_TYPE@[22; 25) | ||
23 | PATH@[22; 25) | ||
24 | PATH_SEGMENT@[22; 25) | ||
25 | NAME_REF@[22; 25) | ||
26 | IDENT@[22; 25) "i32" | ||
27 | SEMI@[25; 26) | ||
28 | WHITESPACE@[26; 31) | ||
29 | CONST_DEF@[31; 49) | ||
30 | CONST_KW@[31; 36) | ||
31 | WHITESPACE@[36; 37) | ||
32 | NAME@[37; 38) | ||
33 | IDENT@[37; 38) "B" | ||
34 | COLON@[38; 39) | ||
35 | WHITESPACE@[39; 40) | ||
36 | PATH_TYPE@[40; 43) | ||
37 | PATH@[40; 43) | ||
38 | PATH_SEGMENT@[40; 43) | ||
39 | NAME_REF@[40; 43) | ||
40 | IDENT@[40; 43) "i32" | ||
41 | WHITESPACE@[43; 44) | ||
42 | EQ@[44; 45) | ||
43 | WHITESPACE@[45; 46) | ||
44 | LITERAL@[46; 48) | ||
45 | INT_NUMBER@[46; 48) "92" | ||
46 | SEMI@[48; 49) | ||
47 | WHITESPACE@[49; 54) | ||
48 | FN_DEF@[54; 65) | ||
49 | FN_KW@[54; 56) | ||
50 | WHITESPACE@[56; 57) | ||
51 | NAME@[57; 60) | ||
52 | IDENT@[57; 60) "foo" | ||
53 | PARAM_LIST@[60; 62) | ||
54 | L_PAREN@[60; 61) | ||
55 | R_PAREN@[61; 62) | ||
56 | WHITESPACE@[62; 63) | ||
57 | BLOCK@[63; 65) | ||
58 | L_CURLY@[63; 64) | ||
59 | R_CURLY@[64; 65) | ||
60 | WHITESPACE@[65; 70) | ||
61 | FN_DEF@[70; 86) | ||
62 | FN_KW@[70; 72) | ||
63 | WHITESPACE@[72; 73) | ||
64 | NAME@[73; 76) | ||
65 | IDENT@[73; 76) "bar" | ||
66 | PARAM_LIST@[76; 83) | ||
67 | L_PAREN@[76; 77) | ||
68 | SELF_PARAM@[77; 82) | ||
69 | AMP@[77; 78) | ||
70 | SELF_KW@[78; 82) | ||
71 | R_PAREN@[82; 83) | ||
72 | WHITESPACE@[83; 84) | ||
73 | BLOCK@[84; 86) | ||
74 | L_CURLY@[84; 85) | ||
75 | R_CURLY@[85; 86) | ||
76 | WHITESPACE@[86; 87) | ||
77 | R_CURLY@[87; 88) | ||
78 | WHITESPACE@[88; 89) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.rs new file mode 100644 index 000000000..f1c3f7118 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn foo() { | ||
2 | **&1; | ||
3 | !!true; | ||
4 | --1; | ||
5 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.txt new file mode 100644 index 000000000..4d77c8c11 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0074_unary_expr.txt | |||
@@ -0,0 +1,44 @@ | |||
1 | ROOT@[0; 44) | ||
2 | FN_DEF@[0; 43) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 43) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 20) | ||
15 | PREFIX_EXPR@[15; 19) | ||
16 | STAR@[15; 16) | ||
17 | PREFIX_EXPR@[16; 19) | ||
18 | STAR@[16; 17) | ||
19 | REF_EXPR@[17; 19) | ||
20 | AMP@[17; 18) | ||
21 | LITERAL@[18; 19) | ||
22 | INT_NUMBER@[18; 19) "1" | ||
23 | SEMI@[19; 20) | ||
24 | WHITESPACE@[20; 25) | ||
25 | EXPR_STMT@[25; 32) | ||
26 | PREFIX_EXPR@[25; 31) | ||
27 | EXCL@[25; 26) | ||
28 | PREFIX_EXPR@[26; 31) | ||
29 | EXCL@[26; 27) | ||
30 | LITERAL@[27; 31) | ||
31 | TRUE_KW@[27; 31) | ||
32 | SEMI@[31; 32) | ||
33 | WHITESPACE@[32; 37) | ||
34 | EXPR_STMT@[37; 41) | ||
35 | PREFIX_EXPR@[37; 40) | ||
36 | MINUS@[37; 38) | ||
37 | PREFIX_EXPR@[38; 40) | ||
38 | MINUS@[38; 39) | ||
39 | LITERAL@[39; 40) | ||
40 | INT_NUMBER@[39; 40) "1" | ||
41 | SEMI@[40; 41) | ||
42 | WHITESPACE@[41; 42) | ||
43 | R_CURLY@[42; 43) | ||
44 | WHITESPACE@[43; 44) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.rs new file mode 100644 index 000000000..8b74f7bc8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn foo() { | ||
2 | x?; | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.txt new file mode 100644 index 000000000..b80235146 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0075_try_expr.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | ROOT@[0; 21) | ||
2 | FN_DEF@[0; 20) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 20) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 18) | ||
15 | TRY_EXPR@[15; 17) | ||
16 | PATH_EXPR@[15; 16) | ||
17 | PATH@[15; 16) | ||
18 | PATH_SEGMENT@[15; 16) | ||
19 | NAME_REF@[15; 16) | ||
20 | IDENT@[15; 16) "x" | ||
21 | QUESTION@[16; 17) | ||
22 | SEMI@[17; 18) | ||
23 | WHITESPACE@[18; 19) | ||
24 | R_CURLY@[19; 20) | ||
25 | WHITESPACE@[20; 21) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0076_cond.rs b/crates/ra_syntax/tests/data/parser/inline/0076_cond.rs new file mode 100644 index 000000000..fdb37ee6f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0076_cond.rs | |||
@@ -0,0 +1 @@ | |||
fn foo() { if let Some(_) = None {} } | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0076_cond.txt b/crates/ra_syntax/tests/data/parser/inline/0076_cond.txt new file mode 100644 index 000000000..1808f10fb --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0076_cond.txt | |||
@@ -0,0 +1,43 @@ | |||
1 | ROOT@[0; 38) | ||
2 | FN_DEF@[0; 37) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 37) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 11) | ||
14 | IF_EXPR@[11; 35) | ||
15 | IF_KW@[11; 13) | ||
16 | WHITESPACE@[13; 14) | ||
17 | CONDITION@[14; 32) | ||
18 | LET_KW@[14; 17) | ||
19 | WHITESPACE@[17; 18) | ||
20 | TUPLE_STRUCT_PAT@[18; 25) | ||
21 | PATH@[18; 22) | ||
22 | PATH_SEGMENT@[18; 22) | ||
23 | NAME_REF@[18; 22) | ||
24 | IDENT@[18; 22) "Some" | ||
25 | L_PAREN@[22; 23) | ||
26 | PLACEHOLDER_PAT@[23; 24) | ||
27 | UNDERSCORE@[23; 24) | ||
28 | R_PAREN@[24; 25) | ||
29 | WHITESPACE@[25; 26) | ||
30 | EQ@[26; 27) | ||
31 | WHITESPACE@[27; 28) | ||
32 | PATH_EXPR@[28; 32) | ||
33 | PATH@[28; 32) | ||
34 | PATH_SEGMENT@[28; 32) | ||
35 | NAME_REF@[28; 32) | ||
36 | IDENT@[28; 32) "None" | ||
37 | WHITESPACE@[32; 33) | ||
38 | BLOCK@[33; 35) | ||
39 | L_CURLY@[33; 34) | ||
40 | R_CURLY@[34; 35) | ||
41 | WHITESPACE@[35; 36) | ||
42 | R_CURLY@[36; 37) | ||
43 | WHITESPACE@[37; 38) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.rs new file mode 100644 index 000000000..293046a04 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | while true {}; | ||
3 | while let Some(x) = it.next() {}; | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.txt new file mode 100644 index 000000000..c73157c04 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0077_while_expr.txt | |||
@@ -0,0 +1,66 @@ | |||
1 | ROOT@[0; 70) | ||
2 | FN_DEF@[0; 69) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 69) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 29) | ||
15 | WHILE_EXPR@[15; 28) | ||
16 | WHILE_KW@[15; 20) | ||
17 | WHITESPACE@[20; 21) | ||
18 | CONDITION@[21; 25) | ||
19 | LITERAL@[21; 25) | ||
20 | TRUE_KW@[21; 25) | ||
21 | WHITESPACE@[25; 26) | ||
22 | BLOCK@[26; 28) | ||
23 | L_CURLY@[26; 27) | ||
24 | R_CURLY@[27; 28) | ||
25 | SEMI@[28; 29) | ||
26 | WHITESPACE@[29; 34) | ||
27 | EXPR_STMT@[34; 67) | ||
28 | WHILE_EXPR@[34; 66) | ||
29 | WHILE_KW@[34; 39) | ||
30 | WHITESPACE@[39; 40) | ||
31 | CONDITION@[40; 63) | ||
32 | LET_KW@[40; 43) | ||
33 | WHITESPACE@[43; 44) | ||
34 | TUPLE_STRUCT_PAT@[44; 51) | ||
35 | PATH@[44; 48) | ||
36 | PATH_SEGMENT@[44; 48) | ||
37 | NAME_REF@[44; 48) | ||
38 | IDENT@[44; 48) "Some" | ||
39 | L_PAREN@[48; 49) | ||
40 | BIND_PAT@[49; 50) | ||
41 | NAME@[49; 50) | ||
42 | IDENT@[49; 50) "x" | ||
43 | R_PAREN@[50; 51) | ||
44 | WHITESPACE@[51; 52) | ||
45 | EQ@[52; 53) | ||
46 | WHITESPACE@[53; 54) | ||
47 | METHOD_CALL_EXPR@[54; 63) | ||
48 | PATH_EXPR@[54; 56) | ||
49 | PATH@[54; 56) | ||
50 | PATH_SEGMENT@[54; 56) | ||
51 | NAME_REF@[54; 56) | ||
52 | IDENT@[54; 56) "it" | ||
53 | DOT@[56; 57) | ||
54 | NAME_REF@[57; 61) | ||
55 | IDENT@[57; 61) "next" | ||
56 | ARG_LIST@[61; 63) | ||
57 | L_PAREN@[61; 62) | ||
58 | R_PAREN@[62; 63) | ||
59 | WHITESPACE@[63; 64) | ||
60 | BLOCK@[64; 66) | ||
61 | L_CURLY@[64; 65) | ||
62 | R_CURLY@[65; 66) | ||
63 | SEMI@[66; 67) | ||
64 | WHITESPACE@[67; 68) | ||
65 | R_CURLY@[68; 69) | ||
66 | WHITESPACE@[69; 70) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.rs b/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.rs new file mode 100644 index 000000000..24a15c5c5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn foo() {} | ||
2 | macro_rules! foo {} | ||
3 | foo::bar!(); | ||
4 | super::baz! {} | ||
5 | struct S; | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.txt b/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.txt new file mode 100644 index 000000000..57b2b9372 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0078_mod_contents.txt | |||
@@ -0,0 +1,65 @@ | |||
1 | ROOT@[0; 70) | ||
2 | FN_DEF@[0; 11) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 11) | ||
12 | L_CURLY@[9; 10) | ||
13 | R_CURLY@[10; 11) | ||
14 | WHITESPACE@[11; 12) | ||
15 | MACRO_CALL@[12; 31) | ||
16 | PATH@[12; 23) | ||
17 | PATH_SEGMENT@[12; 23) | ||
18 | NAME_REF@[12; 23) | ||
19 | IDENT@[12; 23) "macro_rules" | ||
20 | EXCL@[23; 24) | ||
21 | WHITESPACE@[24; 25) | ||
22 | IDENT@[25; 28) "foo" | ||
23 | WHITESPACE@[28; 29) | ||
24 | TOKEN_TREE@[29; 31) | ||
25 | L_CURLY@[29; 30) | ||
26 | R_CURLY@[30; 31) | ||
27 | WHITESPACE@[31; 32) | ||
28 | MACRO_CALL@[32; 44) | ||
29 | PATH@[32; 40) | ||
30 | PATH@[32; 35) | ||
31 | PATH_SEGMENT@[32; 35) | ||
32 | NAME_REF@[32; 35) | ||
33 | IDENT@[32; 35) "foo" | ||
34 | COLONCOLON@[35; 37) | ||
35 | PATH_SEGMENT@[37; 40) | ||
36 | NAME_REF@[37; 40) | ||
37 | IDENT@[37; 40) "bar" | ||
38 | EXCL@[40; 41) | ||
39 | TOKEN_TREE@[41; 43) | ||
40 | L_PAREN@[41; 42) | ||
41 | R_PAREN@[42; 43) | ||
42 | SEMI@[43; 44) | ||
43 | WHITESPACE@[44; 45) | ||
44 | MACRO_CALL@[45; 59) | ||
45 | PATH@[45; 55) | ||
46 | PATH@[45; 50) | ||
47 | PATH_SEGMENT@[45; 50) | ||
48 | SUPER_KW@[45; 50) | ||
49 | COLONCOLON@[50; 52) | ||
50 | PATH_SEGMENT@[52; 55) | ||
51 | NAME_REF@[52; 55) | ||
52 | IDENT@[52; 55) "baz" | ||
53 | EXCL@[55; 56) | ||
54 | WHITESPACE@[56; 57) | ||
55 | TOKEN_TREE@[57; 59) | ||
56 | L_CURLY@[57; 58) | ||
57 | R_CURLY@[58; 59) | ||
58 | WHITESPACE@[59; 60) | ||
59 | STRUCT_DEF@[60; 69) | ||
60 | STRUCT_KW@[60; 66) | ||
61 | WHITESPACE@[66; 67) | ||
62 | NAME@[67; 68) | ||
63 | IDENT@[67; 68) "S" | ||
64 | SEMI@[68; 69) | ||
65 | WHITESPACE@[69; 70) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs new file mode 100644 index 000000000..3e53d56d6 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn foo() { | ||
2 | 82 as i32; | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt new file mode 100644 index 000000000..6d57078b3 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0079_cast_expr.txt | |||
@@ -0,0 +1,29 @@ | |||
1 | ROOT@[0; 28) | ||
2 | FN_DEF@[0; 27) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 27) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 25) | ||
15 | CAST_EXPR@[15; 24) | ||
16 | LITERAL@[15; 17) | ||
17 | INT_NUMBER@[15; 17) "82" | ||
18 | WHITESPACE@[17; 18) | ||
19 | AS_KW@[18; 20) | ||
20 | WHITESPACE@[20; 21) | ||
21 | PATH_TYPE@[21; 24) | ||
22 | PATH@[21; 24) | ||
23 | PATH_SEGMENT@[21; 24) | ||
24 | NAME_REF@[21; 24) | ||
25 | IDENT@[21; 24) "i32" | ||
26 | SEMI@[24; 25) | ||
27 | WHITESPACE@[25; 26) | ||
28 | R_CURLY@[26; 27) | ||
29 | WHITESPACE@[27; 28) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.rs new file mode 100644 index 000000000..e4f774280 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn foo() { | ||
2 | (); | ||
3 | (1); | ||
4 | (1,); | ||
5 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.txt new file mode 100644 index 000000000..cf541411f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0080_tuple_expr.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | ROOT@[0; 40) | ||
2 | FN_DEF@[0; 39) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 39) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 18) | ||
15 | TUPLE_EXPR@[15; 17) | ||
16 | L_PAREN@[15; 16) | ||
17 | R_PAREN@[16; 17) | ||
18 | SEMI@[17; 18) | ||
19 | WHITESPACE@[18; 23) | ||
20 | EXPR_STMT@[23; 27) | ||
21 | PAREN_EXPR@[23; 26) | ||
22 | L_PAREN@[23; 24) | ||
23 | LITERAL@[24; 25) | ||
24 | INT_NUMBER@[24; 25) "1" | ||
25 | R_PAREN@[25; 26) | ||
26 | SEMI@[26; 27) | ||
27 | WHITESPACE@[27; 32) | ||
28 | EXPR_STMT@[32; 37) | ||
29 | TUPLE_EXPR@[32; 36) | ||
30 | L_PAREN@[32; 33) | ||
31 | LITERAL@[33; 34) | ||
32 | INT_NUMBER@[33; 34) "1" | ||
33 | COMMA@[34; 35) | ||
34 | R_PAREN@[35; 36) | ||
35 | SEMI@[36; 37) | ||
36 | WHITESPACE@[37; 38) | ||
37 | R_CURLY@[38; 39) | ||
38 | WHITESPACE@[39; 40) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.rs new file mode 100644 index 000000000..b9ba78a6c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn foo() { | ||
2 | x[1][2]; | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.txt new file mode 100644 index 000000000..4624aab23 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0081_index_expr.txt | |||
@@ -0,0 +1,33 @@ | |||
1 | ROOT@[0; 26) | ||
2 | FN_DEF@[0; 25) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 25) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 23) | ||
15 | INDEX_EXPR@[15; 22) | ||
16 | INDEX_EXPR@[15; 19) | ||
17 | PATH_EXPR@[15; 16) | ||
18 | PATH@[15; 16) | ||
19 | PATH_SEGMENT@[15; 16) | ||
20 | NAME_REF@[15; 16) | ||
21 | IDENT@[15; 16) "x" | ||
22 | L_BRACK@[16; 17) | ||
23 | LITERAL@[17; 18) | ||
24 | INT_NUMBER@[17; 18) "1" | ||
25 | R_BRACK@[18; 19) | ||
26 | L_BRACK@[19; 20) | ||
27 | LITERAL@[20; 21) | ||
28 | INT_NUMBER@[20; 21) "2" | ||
29 | R_BRACK@[21; 22) | ||
30 | SEMI@[22; 23) | ||
31 | WHITESPACE@[23; 24) | ||
32 | R_CURLY@[24; 25) | ||
33 | WHITESPACE@[25; 26) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.rs new file mode 100644 index 000000000..f785acd36 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn main() { | ||
2 | let (a, b, ..) = (); | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.txt new file mode 100644 index 000000000..2d68a5ff2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0082_tuple_pat.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | ROOT@[0; 39) | ||
2 | FN_DEF@[0; 38) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 38) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | LET_STMT@[16; 36) | ||
15 | LET_KW@[16; 19) | ||
16 | WHITESPACE@[19; 20) | ||
17 | TUPLE_PAT@[20; 30) | ||
18 | L_PAREN@[20; 21) | ||
19 | BIND_PAT@[21; 22) | ||
20 | NAME@[21; 22) | ||
21 | IDENT@[21; 22) "a" | ||
22 | COMMA@[22; 23) | ||
23 | WHITESPACE@[23; 24) | ||
24 | BIND_PAT@[24; 25) | ||
25 | NAME@[24; 25) | ||
26 | IDENT@[24; 25) "b" | ||
27 | COMMA@[25; 26) | ||
28 | WHITESPACE@[26; 27) | ||
29 | DOTDOT@[27; 29) | ||
30 | R_PAREN@[29; 30) | ||
31 | WHITESPACE@[30; 31) | ||
32 | EQ@[31; 32) | ||
33 | WHITESPACE@[32; 33) | ||
34 | TUPLE_EXPR@[33; 35) | ||
35 | L_PAREN@[33; 34) | ||
36 | R_PAREN@[34; 35) | ||
37 | SEMI@[35; 36) | ||
38 | WHITESPACE@[36; 37) | ||
39 | R_CURLY@[37; 38) | ||
40 | WHITESPACE@[38; 39) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.rs b/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.rs new file mode 100644 index 000000000..c39fe8e68 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.rs | |||
@@ -0,0 +1 @@ | |||
fn foo() { let x = 1..; } | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.txt b/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.txt new file mode 100644 index 000000000..475251ea7 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0083_postfix_range.txt | |||
@@ -0,0 +1,30 @@ | |||
1 | ROOT@[0; 26) | ||
2 | FN_DEF@[0; 25) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 25) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 11) | ||
14 | LET_STMT@[11; 23) | ||
15 | LET_KW@[11; 14) | ||
16 | WHITESPACE@[14; 15) | ||
17 | BIND_PAT@[15; 16) | ||
18 | NAME@[15; 16) | ||
19 | IDENT@[15; 16) "x" | ||
20 | WHITESPACE@[16; 17) | ||
21 | EQ@[17; 18) | ||
22 | WHITESPACE@[18; 19) | ||
23 | RANGE_EXPR@[19; 22) | ||
24 | LITERAL@[19; 20) | ||
25 | INT_NUMBER@[19; 20) "1" | ||
26 | DOTDOT@[20; 22) | ||
27 | SEMI@[22; 23) | ||
28 | WHITESPACE@[23; 24) | ||
29 | R_CURLY@[24; 25) | ||
30 | WHITESPACE@[25; 26) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.rs new file mode 100644 index 000000000..9f078fa48 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn foo() { | ||
2 | loop {}; | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.txt new file mode 100644 index 000000000..5321fade9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0084_loop_expr.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | ROOT@[0; 26) | ||
2 | FN_DEF@[0; 25) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 25) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 23) | ||
15 | LOOP_EXPR@[15; 22) | ||
16 | LOOP_KW@[15; 19) | ||
17 | WHITESPACE@[19; 20) | ||
18 | BLOCK@[20; 22) | ||
19 | L_CURLY@[20; 21) | ||
20 | R_CURLY@[21; 22) | ||
21 | SEMI@[22; 23) | ||
22 | WHITESPACE@[23; 24) | ||
23 | R_CURLY@[24; 25) | ||
24 | WHITESPACE@[25; 26) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.rs new file mode 100644 index 000000000..972197d2a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn foo() { | ||
2 | for x in [] {}; | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.txt new file mode 100644 index 000000000..7ddf8122f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0085_for_expr.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | ROOT@[0; 33) | ||
2 | FN_DEF@[0; 32) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 32) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 30) | ||
15 | FOR_EXPR@[15; 29) | ||
16 | FOR_KW@[15; 18) | ||
17 | WHITESPACE@[18; 19) | ||
18 | BIND_PAT@[19; 20) | ||
19 | NAME@[19; 20) | ||
20 | IDENT@[19; 20) "x" | ||
21 | WHITESPACE@[20; 21) | ||
22 | IN_KW@[21; 23) | ||
23 | WHITESPACE@[23; 24) | ||
24 | ARRAY_EXPR@[24; 26) | ||
25 | L_BRACK@[24; 25) | ||
26 | R_BRACK@[25; 26) | ||
27 | WHITESPACE@[26; 27) | ||
28 | BLOCK@[27; 29) | ||
29 | L_CURLY@[27; 28) | ||
30 | R_CURLY@[28; 29) | ||
31 | SEMI@[29; 30) | ||
32 | WHITESPACE@[30; 31) | ||
33 | R_CURLY@[31; 32) | ||
34 | WHITESPACE@[32; 33) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.rs b/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.rs new file mode 100644 index 000000000..1f25d577a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | fn foo() { | ||
2 | match () { | ||
3 | _ => (), | ||
4 | _ => {} | ||
5 | _ => () | ||
6 | } | ||
7 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.txt b/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.txt new file mode 100644 index 000000000..560931645 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0085_match_arms_commas.txt | |||
@@ -0,0 +1,59 @@ | |||
1 | ROOT@[0; 83) | ||
2 | FN_DEF@[0; 82) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 82) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | MATCH_EXPR@[15; 80) | ||
15 | MATCH_KW@[15; 20) | ||
16 | WHITESPACE@[20; 21) | ||
17 | TUPLE_EXPR@[21; 23) | ||
18 | L_PAREN@[21; 22) | ||
19 | R_PAREN@[22; 23) | ||
20 | WHITESPACE@[23; 24) | ||
21 | MATCH_ARM_LIST@[24; 80) | ||
22 | L_CURLY@[24; 25) | ||
23 | WHITESPACE@[25; 34) | ||
24 | MATCH_ARM@[34; 41) | ||
25 | PLACEHOLDER_PAT@[34; 35) | ||
26 | UNDERSCORE@[34; 35) | ||
27 | WHITESPACE@[35; 36) | ||
28 | FAT_ARROW@[36; 38) | ||
29 | WHITESPACE@[38; 39) | ||
30 | TUPLE_EXPR@[39; 41) | ||
31 | L_PAREN@[39; 40) | ||
32 | R_PAREN@[40; 41) | ||
33 | COMMA@[41; 42) | ||
34 | WHITESPACE@[42; 51) | ||
35 | MATCH_ARM@[51; 58) | ||
36 | PLACEHOLDER_PAT@[51; 52) | ||
37 | UNDERSCORE@[51; 52) | ||
38 | WHITESPACE@[52; 53) | ||
39 | FAT_ARROW@[53; 55) | ||
40 | WHITESPACE@[55; 56) | ||
41 | BLOCK_EXPR@[56; 58) | ||
42 | BLOCK@[56; 58) | ||
43 | L_CURLY@[56; 57) | ||
44 | R_CURLY@[57; 58) | ||
45 | WHITESPACE@[58; 67) | ||
46 | MATCH_ARM@[67; 74) | ||
47 | PLACEHOLDER_PAT@[67; 68) | ||
48 | UNDERSCORE@[67; 68) | ||
49 | WHITESPACE@[68; 69) | ||
50 | FAT_ARROW@[69; 71) | ||
51 | WHITESPACE@[71; 72) | ||
52 | TUPLE_EXPR@[72; 74) | ||
53 | L_PAREN@[72; 73) | ||
54 | R_PAREN@[73; 74) | ||
55 | WHITESPACE@[74; 79) | ||
56 | R_CURLY@[79; 80) | ||
57 | WHITESPACE@[80; 81) | ||
58 | R_CURLY@[81; 82) | ||
59 | WHITESPACE@[82; 83) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.rs new file mode 100644 index 000000000..4dc1999d1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | []; | ||
3 | [1]; | ||
4 | [1, 2,]; | ||
5 | [1; 2]; | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.txt new file mode 100644 index 000000000..dcdeff609 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0086_array_expr.txt | |||
@@ -0,0 +1,54 @@ | |||
1 | ROOT@[0; 55) | ||
2 | FN_DEF@[0; 54) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 54) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 18) | ||
15 | ARRAY_EXPR@[15; 17) | ||
16 | L_BRACK@[15; 16) | ||
17 | R_BRACK@[16; 17) | ||
18 | SEMI@[17; 18) | ||
19 | WHITESPACE@[18; 23) | ||
20 | EXPR_STMT@[23; 27) | ||
21 | ARRAY_EXPR@[23; 26) | ||
22 | L_BRACK@[23; 24) | ||
23 | LITERAL@[24; 25) | ||
24 | INT_NUMBER@[24; 25) "1" | ||
25 | R_BRACK@[25; 26) | ||
26 | SEMI@[26; 27) | ||
27 | WHITESPACE@[27; 32) | ||
28 | EXPR_STMT@[32; 40) | ||
29 | ARRAY_EXPR@[32; 39) | ||
30 | L_BRACK@[32; 33) | ||
31 | LITERAL@[33; 34) | ||
32 | INT_NUMBER@[33; 34) "1" | ||
33 | COMMA@[34; 35) | ||
34 | WHITESPACE@[35; 36) | ||
35 | LITERAL@[36; 37) | ||
36 | INT_NUMBER@[36; 37) "2" | ||
37 | COMMA@[37; 38) | ||
38 | R_BRACK@[38; 39) | ||
39 | SEMI@[39; 40) | ||
40 | WHITESPACE@[40; 45) | ||
41 | EXPR_STMT@[45; 52) | ||
42 | ARRAY_EXPR@[45; 51) | ||
43 | L_BRACK@[45; 46) | ||
44 | LITERAL@[46; 47) | ||
45 | INT_NUMBER@[46; 47) "1" | ||
46 | SEMI@[47; 48) | ||
47 | WHITESPACE@[48; 49) | ||
48 | LITERAL@[49; 50) | ||
49 | INT_NUMBER@[49; 50) "2" | ||
50 | R_BRACK@[50; 51) | ||
51 | SEMI@[51; 52) | ||
52 | WHITESPACE@[52; 53) | ||
53 | R_CURLY@[53; 54) | ||
54 | WHITESPACE@[54; 55) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.rs b/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.rs new file mode 100644 index 000000000..d769da43d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.rs | |||
@@ -0,0 +1,9 @@ | |||
1 | fn foo() { | ||
2 | if true {} | ||
3 | loop {} | ||
4 | match () {} | ||
5 | while true {} | ||
6 | for _ in () {} | ||
7 | {} | ||
8 | {} | ||
9 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.txt b/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.txt new file mode 100644 index 000000000..f1b0e2787 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0086_no_semi_after_block.txt | |||
@@ -0,0 +1,87 @@ | |||
1 | ROOT@[0; 107) | ||
2 | FN_DEF@[0; 106) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 106) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 25) | ||
15 | IF_EXPR@[15; 25) | ||
16 | IF_KW@[15; 17) | ||
17 | WHITESPACE@[17; 18) | ||
18 | CONDITION@[18; 22) | ||
19 | LITERAL@[18; 22) | ||
20 | TRUE_KW@[18; 22) | ||
21 | WHITESPACE@[22; 23) | ||
22 | BLOCK@[23; 25) | ||
23 | L_CURLY@[23; 24) | ||
24 | R_CURLY@[24; 25) | ||
25 | WHITESPACE@[25; 30) | ||
26 | EXPR_STMT@[30; 37) | ||
27 | LOOP_EXPR@[30; 37) | ||
28 | LOOP_KW@[30; 34) | ||
29 | WHITESPACE@[34; 35) | ||
30 | BLOCK@[35; 37) | ||
31 | L_CURLY@[35; 36) | ||
32 | R_CURLY@[36; 37) | ||
33 | WHITESPACE@[37; 42) | ||
34 | EXPR_STMT@[42; 53) | ||
35 | MATCH_EXPR@[42; 53) | ||
36 | MATCH_KW@[42; 47) | ||
37 | WHITESPACE@[47; 48) | ||
38 | TUPLE_EXPR@[48; 50) | ||
39 | L_PAREN@[48; 49) | ||
40 | R_PAREN@[49; 50) | ||
41 | WHITESPACE@[50; 51) | ||
42 | MATCH_ARM_LIST@[51; 53) | ||
43 | L_CURLY@[51; 52) | ||
44 | R_CURLY@[52; 53) | ||
45 | WHITESPACE@[53; 58) | ||
46 | EXPR_STMT@[58; 71) | ||
47 | WHILE_EXPR@[58; 71) | ||
48 | WHILE_KW@[58; 63) | ||
49 | WHITESPACE@[63; 64) | ||
50 | CONDITION@[64; 68) | ||
51 | LITERAL@[64; 68) | ||
52 | TRUE_KW@[64; 68) | ||
53 | WHITESPACE@[68; 69) | ||
54 | BLOCK@[69; 71) | ||
55 | L_CURLY@[69; 70) | ||
56 | R_CURLY@[70; 71) | ||
57 | WHITESPACE@[71; 76) | ||
58 | EXPR_STMT@[76; 90) | ||
59 | FOR_EXPR@[76; 90) | ||
60 | FOR_KW@[76; 79) | ||
61 | WHITESPACE@[79; 80) | ||
62 | PLACEHOLDER_PAT@[80; 81) | ||
63 | UNDERSCORE@[80; 81) | ||
64 | WHITESPACE@[81; 82) | ||
65 | IN_KW@[82; 84) | ||
66 | WHITESPACE@[84; 85) | ||
67 | TUPLE_EXPR@[85; 87) | ||
68 | L_PAREN@[85; 86) | ||
69 | R_PAREN@[86; 87) | ||
70 | WHITESPACE@[87; 88) | ||
71 | BLOCK@[88; 90) | ||
72 | L_CURLY@[88; 89) | ||
73 | R_CURLY@[89; 90) | ||
74 | WHITESPACE@[90; 95) | ||
75 | EXPR_STMT@[95; 97) | ||
76 | BLOCK_EXPR@[95; 97) | ||
77 | BLOCK@[95; 97) | ||
78 | L_CURLY@[95; 96) | ||
79 | R_CURLY@[96; 97) | ||
80 | WHITESPACE@[97; 102) | ||
81 | BLOCK_EXPR@[102; 104) | ||
82 | BLOCK@[102; 104) | ||
83 | L_CURLY@[102; 103) | ||
84 | R_CURLY@[103; 104) | ||
85 | WHITESPACE@[104; 105) | ||
86 | R_CURLY@[105; 106) | ||
87 | WHITESPACE@[106; 107) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.rs b/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.rs new file mode 100644 index 000000000..2edd578f9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | fn foo() { | ||
2 | match () { | ||
3 | _ => {} | ||
4 | () => {} | ||
5 | [] => {} | ||
6 | } | ||
7 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.txt b/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.txt new file mode 100644 index 000000000..91edf3f84 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0087_stmt_postfix_expr_ambiguity.txt | |||
@@ -0,0 +1,62 @@ | |||
1 | ROOT@[0; 84) | ||
2 | FN_DEF@[0; 83) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 83) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | MATCH_EXPR@[15; 81) | ||
15 | MATCH_KW@[15; 20) | ||
16 | WHITESPACE@[20; 21) | ||
17 | TUPLE_EXPR@[21; 23) | ||
18 | L_PAREN@[21; 22) | ||
19 | R_PAREN@[22; 23) | ||
20 | WHITESPACE@[23; 24) | ||
21 | MATCH_ARM_LIST@[24; 81) | ||
22 | L_CURLY@[24; 25) | ||
23 | WHITESPACE@[25; 34) | ||
24 | MATCH_ARM@[34; 41) | ||
25 | PLACEHOLDER_PAT@[34; 35) | ||
26 | UNDERSCORE@[34; 35) | ||
27 | WHITESPACE@[35; 36) | ||
28 | FAT_ARROW@[36; 38) | ||
29 | WHITESPACE@[38; 39) | ||
30 | BLOCK_EXPR@[39; 41) | ||
31 | BLOCK@[39; 41) | ||
32 | L_CURLY@[39; 40) | ||
33 | R_CURLY@[40; 41) | ||
34 | WHITESPACE@[41; 50) | ||
35 | MATCH_ARM@[50; 58) | ||
36 | TUPLE_PAT@[50; 52) | ||
37 | L_PAREN@[50; 51) | ||
38 | R_PAREN@[51; 52) | ||
39 | WHITESPACE@[52; 53) | ||
40 | FAT_ARROW@[53; 55) | ||
41 | WHITESPACE@[55; 56) | ||
42 | BLOCK_EXPR@[56; 58) | ||
43 | BLOCK@[56; 58) | ||
44 | L_CURLY@[56; 57) | ||
45 | R_CURLY@[57; 58) | ||
46 | WHITESPACE@[58; 67) | ||
47 | MATCH_ARM@[67; 75) | ||
48 | SLICE_PAT@[67; 69) | ||
49 | L_BRACK@[67; 68) | ||
50 | R_BRACK@[68; 69) | ||
51 | WHITESPACE@[69; 70) | ||
52 | FAT_ARROW@[70; 72) | ||
53 | WHITESPACE@[72; 73) | ||
54 | BLOCK_EXPR@[73; 75) | ||
55 | BLOCK@[73; 75) | ||
56 | L_CURLY@[73; 74) | ||
57 | R_CURLY@[74; 75) | ||
58 | WHITESPACE@[75; 80) | ||
59 | R_CURLY@[80; 81) | ||
60 | WHITESPACE@[81; 82) | ||
61 | R_CURLY@[82; 83) | ||
62 | WHITESPACE@[83; 84) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs b/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs new file mode 100644 index 000000000..37b843742 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | let _ = {1} & 2; | ||
3 | {1} &2; | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt b/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt new file mode 100644 index 000000000..ff1298acb --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0088_stmt_bin_expr_ambiguity.txt | |||
@@ -0,0 +1,52 @@ | |||
1 | ROOT@[0; 46) | ||
2 | FN_DEF@[0; 45) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 45) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LET_STMT@[15; 31) | ||
15 | LET_KW@[15; 18) | ||
16 | WHITESPACE@[18; 19) | ||
17 | PLACEHOLDER_PAT@[19; 20) | ||
18 | UNDERSCORE@[19; 20) | ||
19 | WHITESPACE@[20; 21) | ||
20 | EQ@[21; 22) | ||
21 | WHITESPACE@[22; 23) | ||
22 | BIN_EXPR@[23; 30) | ||
23 | BLOCK_EXPR@[23; 26) | ||
24 | BLOCK@[23; 26) | ||
25 | L_CURLY@[23; 24) | ||
26 | LITERAL@[24; 25) | ||
27 | INT_NUMBER@[24; 25) "1" | ||
28 | R_CURLY@[25; 26) | ||
29 | WHITESPACE@[26; 27) | ||
30 | AMP@[27; 28) | ||
31 | WHITESPACE@[28; 29) | ||
32 | LITERAL@[29; 30) | ||
33 | INT_NUMBER@[29; 30) "2" | ||
34 | SEMI@[30; 31) | ||
35 | WHITESPACE@[31; 36) | ||
36 | EXPR_STMT@[36; 39) | ||
37 | BLOCK_EXPR@[36; 39) | ||
38 | BLOCK@[36; 39) | ||
39 | L_CURLY@[36; 37) | ||
40 | LITERAL@[37; 38) | ||
41 | INT_NUMBER@[37; 38) "1" | ||
42 | R_CURLY@[38; 39) | ||
43 | WHITESPACE@[39; 40) | ||
44 | EXPR_STMT@[40; 43) | ||
45 | REF_EXPR@[40; 42) | ||
46 | AMP@[40; 41) | ||
47 | LITERAL@[41; 42) | ||
48 | INT_NUMBER@[41; 42) "2" | ||
49 | SEMI@[42; 43) | ||
50 | WHITESPACE@[43; 44) | ||
51 | R_CURLY@[44; 45) | ||
52 | WHITESPACE@[45; 46) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.rs new file mode 100644 index 000000000..7955973b9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn main() { | ||
2 | let [a, b, ..] = []; | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.txt new file mode 100644 index 000000000..99e8dd427 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0089_slice_pat.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | ROOT@[0; 39) | ||
2 | FN_DEF@[0; 38) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 38) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | LET_STMT@[16; 36) | ||
15 | LET_KW@[16; 19) | ||
16 | WHITESPACE@[19; 20) | ||
17 | SLICE_PAT@[20; 30) | ||
18 | L_BRACK@[20; 21) | ||
19 | BIND_PAT@[21; 22) | ||
20 | NAME@[21; 22) | ||
21 | IDENT@[21; 22) "a" | ||
22 | COMMA@[22; 23) | ||
23 | WHITESPACE@[23; 24) | ||
24 | BIND_PAT@[24; 25) | ||
25 | NAME@[24; 25) | ||
26 | IDENT@[24; 25) "b" | ||
27 | COMMA@[25; 26) | ||
28 | WHITESPACE@[26; 27) | ||
29 | DOTDOT@[27; 29) | ||
30 | R_BRACK@[29; 30) | ||
31 | WHITESPACE@[30; 31) | ||
32 | EQ@[31; 32) | ||
33 | WHITESPACE@[32; 33) | ||
34 | ARRAY_EXPR@[33; 35) | ||
35 | L_BRACK@[33; 34) | ||
36 | R_BRACK@[34; 35) | ||
37 | SEMI@[35; 36) | ||
38 | WHITESPACE@[36; 37) | ||
39 | R_CURLY@[37; 38) | ||
40 | WHITESPACE@[38; 39) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.rs b/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.rs new file mode 100644 index 000000000..c9f74f7f5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.rs | |||
@@ -0,0 +1 @@ | |||
trait T { fn foo(); } | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.txt b/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.txt new file mode 100644 index 000000000..c35bc8428 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0091_fn_decl.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | ROOT@[0; 22) | ||
2 | TRAIT_DEF@[0; 21) | ||
3 | TRAIT_KW@[0; 5) | ||
4 | WHITESPACE@[5; 6) | ||
5 | NAME@[6; 7) | ||
6 | IDENT@[6; 7) "T" | ||
7 | WHITESPACE@[7; 8) | ||
8 | ITEM_LIST@[8; 21) | ||
9 | L_CURLY@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | FN_DEF@[10; 19) | ||
12 | FN_KW@[10; 12) | ||
13 | WHITESPACE@[12; 13) | ||
14 | NAME@[13; 16) | ||
15 | IDENT@[13; 16) "foo" | ||
16 | PARAM_LIST@[16; 18) | ||
17 | L_PAREN@[16; 17) | ||
18 | R_PAREN@[17; 18) | ||
19 | SEMI@[18; 19) | ||
20 | WHITESPACE@[19; 20) | ||
21 | R_CURLY@[20; 21) | ||
22 | WHITESPACE@[21; 22) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.rs b/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.rs new file mode 100644 index 000000000..16f674d9d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | fn main() { | ||
2 | match () { | ||
3 | 92 => (), | ||
4 | 'c' => (), | ||
5 | "hello" => (), | ||
6 | } | ||
7 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.txt b/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.txt new file mode 100644 index 000000000..3128bfd7d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0092_literal_pattern.txt | |||
@@ -0,0 +1,60 @@ | |||
1 | ROOT@[0; 95) | ||
2 | FN_DEF@[0; 94) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 94) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | MATCH_EXPR@[16; 92) | ||
15 | MATCH_KW@[16; 21) | ||
16 | WHITESPACE@[21; 22) | ||
17 | TUPLE_EXPR@[22; 24) | ||
18 | L_PAREN@[22; 23) | ||
19 | R_PAREN@[23; 24) | ||
20 | WHITESPACE@[24; 25) | ||
21 | MATCH_ARM_LIST@[25; 92) | ||
22 | L_CURLY@[25; 26) | ||
23 | WHITESPACE@[26; 35) | ||
24 | MATCH_ARM@[35; 43) | ||
25 | LITERAL@[35; 37) | ||
26 | INT_NUMBER@[35; 37) "92" | ||
27 | WHITESPACE@[37; 38) | ||
28 | FAT_ARROW@[38; 40) | ||
29 | WHITESPACE@[40; 41) | ||
30 | TUPLE_EXPR@[41; 43) | ||
31 | L_PAREN@[41; 42) | ||
32 | R_PAREN@[42; 43) | ||
33 | COMMA@[43; 44) | ||
34 | WHITESPACE@[44; 53) | ||
35 | MATCH_ARM@[53; 62) | ||
36 | LITERAL@[53; 56) | ||
37 | CHAR@[53; 56) | ||
38 | WHITESPACE@[56; 57) | ||
39 | FAT_ARROW@[57; 59) | ||
40 | WHITESPACE@[59; 60) | ||
41 | TUPLE_EXPR@[60; 62) | ||
42 | L_PAREN@[60; 61) | ||
43 | R_PAREN@[61; 62) | ||
44 | COMMA@[62; 63) | ||
45 | WHITESPACE@[63; 72) | ||
46 | MATCH_ARM@[72; 85) | ||
47 | LITERAL@[72; 79) | ||
48 | STRING@[72; 79) | ||
49 | WHITESPACE@[79; 80) | ||
50 | FAT_ARROW@[80; 82) | ||
51 | WHITESPACE@[82; 83) | ||
52 | TUPLE_EXPR@[83; 85) | ||
53 | L_PAREN@[83; 84) | ||
54 | R_PAREN@[84; 85) | ||
55 | COMMA@[85; 86) | ||
56 | WHITESPACE@[86; 91) | ||
57 | R_CURLY@[91; 92) | ||
58 | WHITESPACE@[92; 93) | ||
59 | R_CURLY@[93; 94) | ||
60 | WHITESPACE@[94; 95) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.rs b/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.rs new file mode 100644 index 000000000..aef45e561 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.rs | |||
@@ -0,0 +1 @@ | |||
type F = Box<Fn(x: i32) -> ()>; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.txt b/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.txt new file mode 100644 index 000000000..26a690d3a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0093_path_fn_trait_args.txt | |||
@@ -0,0 +1,46 @@ | |||
1 | ROOT@[0; 32) | ||
2 | TYPE_DEF@[0; 31) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "F" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | PATH_TYPE@[9; 30) | ||
11 | PATH@[9; 30) | ||
12 | PATH_SEGMENT@[9; 30) | ||
13 | NAME_REF@[9; 12) | ||
14 | IDENT@[9; 12) "Box" | ||
15 | TYPE_ARG_LIST@[12; 30) | ||
16 | L_ANGLE@[12; 13) | ||
17 | TYPE_ARG@[13; 29) | ||
18 | PATH_TYPE@[13; 29) | ||
19 | PATH@[13; 29) | ||
20 | PATH_SEGMENT@[13; 29) | ||
21 | NAME_REF@[13; 15) | ||
22 | IDENT@[13; 15) "Fn" | ||
23 | PARAM_LIST@[15; 23) | ||
24 | L_PAREN@[15; 16) | ||
25 | PARAM@[16; 22) | ||
26 | BIND_PAT@[16; 17) | ||
27 | NAME@[16; 17) | ||
28 | IDENT@[16; 17) "x" | ||
29 | COLON@[17; 18) | ||
30 | WHITESPACE@[18; 19) | ||
31 | PATH_TYPE@[19; 22) | ||
32 | PATH@[19; 22) | ||
33 | PATH_SEGMENT@[19; 22) | ||
34 | NAME_REF@[19; 22) | ||
35 | IDENT@[19; 22) "i32" | ||
36 | R_PAREN@[22; 23) | ||
37 | WHITESPACE@[23; 24) | ||
38 | RET_TYPE@[24; 29) | ||
39 | THIN_ARROW@[24; 26) | ||
40 | WHITESPACE@[26; 27) | ||
41 | TUPLE_TYPE@[27; 29) | ||
42 | L_PAREN@[27; 28) | ||
43 | R_PAREN@[28; 29) | ||
44 | R_ANGLE@[29; 30) | ||
45 | SEMI@[30; 31) | ||
46 | WHITESPACE@[31; 32) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs new file mode 100644 index 000000000..657467e75 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn main() { | ||
2 | match 92 { 0 ... 100 => () } | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt new file mode 100644 index 000000000..4f14d5431 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0094_range_pat.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | ROOT@[0; 47) | ||
2 | FN_DEF@[0; 46) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 46) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | MATCH_EXPR@[16; 44) | ||
15 | MATCH_KW@[16; 21) | ||
16 | WHITESPACE@[21; 22) | ||
17 | LITERAL@[22; 24) | ||
18 | INT_NUMBER@[22; 24) "92" | ||
19 | WHITESPACE@[24; 25) | ||
20 | MATCH_ARM_LIST@[25; 44) | ||
21 | L_CURLY@[25; 26) | ||
22 | WHITESPACE@[26; 27) | ||
23 | MATCH_ARM@[27; 42) | ||
24 | RANGE_PAT@[27; 36) | ||
25 | LITERAL@[27; 28) | ||
26 | INT_NUMBER@[27; 28) "0" | ||
27 | WHITESPACE@[28; 29) | ||
28 | DOTDOTDOT@[29; 32) | ||
29 | WHITESPACE@[32; 33) | ||
30 | LITERAL@[33; 36) | ||
31 | INT_NUMBER@[33; 36) "100" | ||
32 | WHITESPACE@[36; 37) | ||
33 | FAT_ARROW@[37; 39) | ||
34 | WHITESPACE@[39; 40) | ||
35 | TUPLE_EXPR@[40; 42) | ||
36 | L_PAREN@[40; 41) | ||
37 | R_PAREN@[41; 42) | ||
38 | WHITESPACE@[42; 43) | ||
39 | R_CURLY@[43; 44) | ||
40 | WHITESPACE@[44; 45) | ||
41 | R_CURLY@[45; 46) | ||
42 | WHITESPACE@[46; 47) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.rs b/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.rs new file mode 100644 index 000000000..215210e27 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.rs | |||
@@ -0,0 +1 @@ | |||
fn foo() -> Box<T + 'f> {} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.txt b/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.txt new file mode 100644 index 000000000..4b864f741 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0095_path_type_with_bounds.txt | |||
@@ -0,0 +1,36 @@ | |||
1 | ROOT@[0; 27) | ||
2 | FN_DEF@[0; 26) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | RET_TYPE@[9; 23) | ||
12 | THIN_ARROW@[9; 11) | ||
13 | WHITESPACE@[11; 12) | ||
14 | PATH_TYPE@[12; 23) | ||
15 | PATH@[12; 23) | ||
16 | PATH_SEGMENT@[12; 23) | ||
17 | NAME_REF@[12; 15) | ||
18 | IDENT@[12; 15) "Box" | ||
19 | TYPE_ARG_LIST@[15; 23) | ||
20 | L_ANGLE@[15; 16) | ||
21 | TYPE_ARG@[16; 22) | ||
22 | PATH_TYPE@[16; 22) | ||
23 | PATH@[16; 17) | ||
24 | PATH_SEGMENT@[16; 17) | ||
25 | NAME_REF@[16; 17) | ||
26 | IDENT@[16; 17) "T" | ||
27 | WHITESPACE@[17; 18) | ||
28 | PLUS@[18; 19) | ||
29 | WHITESPACE@[19; 20) | ||
30 | LIFETIME@[20; 22) "'f" | ||
31 | R_ANGLE@[22; 23) | ||
32 | WHITESPACE@[23; 24) | ||
33 | BLOCK@[24; 26) | ||
34 | L_CURLY@[24; 25) | ||
35 | R_CURLY@[25; 26) | ||
36 | WHITESPACE@[26; 27) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.rs b/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.rs new file mode 100644 index 000000000..d8c23c76a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.rs | |||
@@ -0,0 +1 @@ | |||
type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.txt b/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.txt new file mode 100644 index 000000000..3c8352067 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0096_value_parameters_no_patterns.txt | |||
@@ -0,0 +1,81 @@ | |||
1 | ROOT@[0; 54) | ||
2 | TYPE_DEF@[0; 53) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "F" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | PATH_TYPE@[9; 52) | ||
11 | PATH@[9; 52) | ||
12 | PATH_SEGMENT@[9; 52) | ||
13 | NAME_REF@[9; 12) | ||
14 | IDENT@[9; 12) "Box" | ||
15 | TYPE_ARG_LIST@[12; 52) | ||
16 | L_ANGLE@[12; 13) | ||
17 | TYPE_ARG@[13; 51) | ||
18 | PATH_TYPE@[13; 51) | ||
19 | PATH@[13; 51) | ||
20 | PATH_SEGMENT@[13; 51) | ||
21 | NAME_REF@[13; 15) | ||
22 | IDENT@[13; 15) "Fn" | ||
23 | PARAM_LIST@[15; 51) | ||
24 | L_PAREN@[15; 16) | ||
25 | PARAM@[16; 22) | ||
26 | BIND_PAT@[16; 17) | ||
27 | NAME@[16; 17) | ||
28 | IDENT@[16; 17) "a" | ||
29 | COLON@[17; 18) | ||
30 | WHITESPACE@[18; 19) | ||
31 | PATH_TYPE@[19; 22) | ||
32 | PATH@[19; 22) | ||
33 | PATH_SEGMENT@[19; 22) | ||
34 | NAME_REF@[19; 22) | ||
35 | IDENT@[19; 22) "i32" | ||
36 | COMMA@[22; 23) | ||
37 | WHITESPACE@[23; 24) | ||
38 | PARAM@[24; 32) | ||
39 | REF_PAT@[24; 26) | ||
40 | AMP@[24; 25) | ||
41 | BIND_PAT@[25; 26) | ||
42 | NAME@[25; 26) | ||
43 | IDENT@[25; 26) "b" | ||
44 | COLON@[26; 27) | ||
45 | WHITESPACE@[27; 28) | ||
46 | REFERENCE_TYPE@[28; 32) | ||
47 | AMP@[28; 29) | ||
48 | PATH_TYPE@[29; 32) | ||
49 | PATH@[29; 32) | ||
50 | PATH_SEGMENT@[29; 32) | ||
51 | NAME_REF@[29; 32) | ||
52 | IDENT@[29; 32) "i32" | ||
53 | COMMA@[32; 33) | ||
54 | WHITESPACE@[33; 34) | ||
55 | PARAM@[34; 46) | ||
56 | REF_PAT@[34; 40) | ||
57 | AMP@[34; 35) | ||
58 | MUT_KW@[35; 38) | ||
59 | WHITESPACE@[38; 39) | ||
60 | BIND_PAT@[39; 40) | ||
61 | NAME@[39; 40) | ||
62 | IDENT@[39; 40) "c" | ||
63 | COLON@[40; 41) | ||
64 | WHITESPACE@[41; 42) | ||
65 | REFERENCE_TYPE@[42; 46) | ||
66 | AMP@[42; 43) | ||
67 | PATH_TYPE@[43; 46) | ||
68 | PATH@[43; 46) | ||
69 | PATH_SEGMENT@[43; 46) | ||
70 | NAME_REF@[43; 46) | ||
71 | IDENT@[43; 46) "i32" | ||
72 | COMMA@[46; 47) | ||
73 | WHITESPACE@[47; 48) | ||
74 | PARAM@[48; 50) | ||
75 | TUPLE_TYPE@[48; 50) | ||
76 | L_PAREN@[48; 49) | ||
77 | R_PAREN@[49; 50) | ||
78 | R_PAREN@[50; 51) | ||
79 | R_ANGLE@[51; 52) | ||
80 | SEMI@[52; 53) | ||
81 | WHITESPACE@[53; 54) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.rs b/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.rs new file mode 100644 index 000000000..9b93442c0 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.rs | |||
@@ -0,0 +1 @@ | |||
fn foo<F: FnMut(&mut Foo<'a>)>(){} | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.txt b/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.txt new file mode 100644 index 000000000..39bab8dd2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0097_param_list_opt_patterns.txt | |||
@@ -0,0 +1,44 @@ | |||
1 | ROOT@[0; 35) | ||
2 | FN_DEF@[0; 34) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | TYPE_PARAM_LIST@[6; 30) | ||
8 | L_ANGLE@[6; 7) | ||
9 | TYPE_PARAM@[7; 29) | ||
10 | NAME@[7; 8) | ||
11 | IDENT@[7; 8) "F" | ||
12 | COLON@[8; 9) | ||
13 | WHITESPACE@[9; 10) | ||
14 | PATH_TYPE@[10; 29) | ||
15 | PATH@[10; 29) | ||
16 | PATH_SEGMENT@[10; 29) | ||
17 | NAME_REF@[10; 15) | ||
18 | IDENT@[10; 15) "FnMut" | ||
19 | PARAM_LIST@[15; 29) | ||
20 | L_PAREN@[15; 16) | ||
21 | PARAM@[16; 28) | ||
22 | REFERENCE_TYPE@[16; 28) | ||
23 | AMP@[16; 17) | ||
24 | MUT_KW@[17; 20) | ||
25 | WHITESPACE@[20; 21) | ||
26 | PATH_TYPE@[21; 28) | ||
27 | PATH@[21; 28) | ||
28 | PATH_SEGMENT@[21; 28) | ||
29 | NAME_REF@[21; 24) | ||
30 | IDENT@[21; 24) "Foo" | ||
31 | TYPE_ARG_LIST@[24; 28) | ||
32 | L_ANGLE@[24; 25) | ||
33 | LIFETIME_ARG@[25; 27) | ||
34 | LIFETIME@[25; 27) "'a" | ||
35 | R_ANGLE@[27; 28) | ||
36 | R_PAREN@[28; 29) | ||
37 | R_ANGLE@[29; 30) | ||
38 | PARAM_LIST@[30; 32) | ||
39 | L_PAREN@[30; 31) | ||
40 | R_PAREN@[31; 32) | ||
41 | BLOCK@[32; 34) | ||
42 | L_CURLY@[32; 33) | ||
43 | R_CURLY@[33; 34) | ||
44 | WHITESPACE@[34; 35) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.rs b/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.rs new file mode 100644 index 000000000..592a005f9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() | ||
2 | where | ||
3 | 'a: 'b + 'c, | ||
4 | T: Clone + Copy + 'static, | ||
5 | Iterator::Item: 'a, | ||
6 | {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.txt b/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.txt new file mode 100644 index 000000000..9fe803554 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0098_where_clause.txt | |||
@@ -0,0 +1,71 @@ | |||
1 | ROOT@[0; 87) | ||
2 | FN_DEF@[0; 86) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | WHERE_CLAUSE@[9; 83) | ||
12 | WHERE_KW@[9; 14) | ||
13 | WHITESPACE@[14; 18) | ||
14 | WHERE_PRED@[18; 29) | ||
15 | LIFETIME@[18; 20) "'a" | ||
16 | COLON@[20; 21) | ||
17 | WHITESPACE@[21; 22) | ||
18 | LIFETIME@[22; 24) "'b" | ||
19 | WHITESPACE@[24; 25) | ||
20 | PLUS@[25; 26) | ||
21 | WHITESPACE@[26; 27) | ||
22 | LIFETIME@[27; 29) "'c" | ||
23 | COMMA@[29; 30) | ||
24 | WHITESPACE@[30; 34) | ||
25 | WHERE_PRED@[34; 59) | ||
26 | PATH_TYPE@[34; 35) | ||
27 | PATH@[34; 35) | ||
28 | PATH_SEGMENT@[34; 35) | ||
29 | NAME_REF@[34; 35) | ||
30 | IDENT@[34; 35) "T" | ||
31 | COLON@[35; 36) | ||
32 | WHITESPACE@[36; 37) | ||
33 | PATH_TYPE@[37; 59) | ||
34 | PATH@[37; 42) | ||
35 | PATH_SEGMENT@[37; 42) | ||
36 | NAME_REF@[37; 42) | ||
37 | IDENT@[37; 42) "Clone" | ||
38 | WHITESPACE@[42; 43) | ||
39 | PLUS@[43; 44) | ||
40 | WHITESPACE@[44; 45) | ||
41 | PATH_TYPE@[45; 59) | ||
42 | PATH@[45; 49) | ||
43 | PATH_SEGMENT@[45; 49) | ||
44 | NAME_REF@[45; 49) | ||
45 | IDENT@[45; 49) "Copy" | ||
46 | WHITESPACE@[49; 50) | ||
47 | PLUS@[50; 51) | ||
48 | WHITESPACE@[51; 52) | ||
49 | LIFETIME@[52; 59) "'static" | ||
50 | COMMA@[59; 60) | ||
51 | WHITESPACE@[60; 64) | ||
52 | WHERE_PRED@[64; 82) | ||
53 | PATH_TYPE@[64; 78) | ||
54 | PATH@[64; 78) | ||
55 | PATH@[64; 72) | ||
56 | PATH_SEGMENT@[64; 72) | ||
57 | NAME_REF@[64; 72) | ||
58 | IDENT@[64; 72) "Iterator" | ||
59 | COLONCOLON@[72; 74) | ||
60 | PATH_SEGMENT@[74; 78) | ||
61 | NAME_REF@[74; 78) | ||
62 | IDENT@[74; 78) "Item" | ||
63 | COLON@[78; 79) | ||
64 | WHITESPACE@[79; 80) | ||
65 | LIFETIME@[80; 82) "'a" | ||
66 | COMMA@[82; 83) | ||
67 | WHITESPACE@[83; 84) | ||
68 | BLOCK@[84; 86) | ||
69 | L_CURLY@[84; 85) | ||
70 | R_CURLY@[85; 86) | ||
71 | WHITESPACE@[86; 87) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.rs b/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.rs new file mode 100644 index 000000000..660d927cf --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.rs | |||
@@ -0,0 +1 @@ | |||
crate fn main() { } | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.txt b/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.txt new file mode 100644 index 000000000..96a4e9162 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0099_crate_keyword_vis.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | ROOT@[0; 20) | ||
2 | FN_DEF@[0; 19) | ||
3 | VISIBILITY@[0; 5) | ||
4 | CRATE_KW@[0; 5) | ||
5 | WHITESPACE@[5; 6) | ||
6 | FN_KW@[6; 8) | ||
7 | WHITESPACE@[8; 9) | ||
8 | NAME@[9; 13) | ||
9 | IDENT@[9; 13) "main" | ||
10 | PARAM_LIST@[13; 15) | ||
11 | L_PAREN@[13; 14) | ||
12 | R_PAREN@[14; 15) | ||
13 | WHITESPACE@[15; 16) | ||
14 | BLOCK@[16; 19) | ||
15 | L_CURLY@[16; 17) | ||
16 | WHITESPACE@[17; 18) | ||
17 | R_CURLY@[18; 19) | ||
18 | WHITESPACE@[19; 20) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.rs b/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.rs new file mode 100644 index 000000000..c3ecabb99 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.rs | |||
@@ -0,0 +1 @@ | |||
type A = dyn Iterator<Item=Foo<'a>> + 'a; | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.txt b/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.txt new file mode 100644 index 000000000..c81ae5545 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0100_dyn_trait_type.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | ROOT@[0; 42) | ||
2 | TYPE_DEF@[0; 41) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "A" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | DYN_TRAIT_TYPE@[9; 40) | ||
11 | DYN_KW@[9; 12) | ||
12 | WHITESPACE@[12; 13) | ||
13 | PATH_TYPE@[13; 40) | ||
14 | PATH@[13; 35) | ||
15 | PATH_SEGMENT@[13; 35) | ||
16 | NAME_REF@[13; 21) | ||
17 | IDENT@[13; 21) "Iterator" | ||
18 | TYPE_ARG_LIST@[21; 35) | ||
19 | L_ANGLE@[21; 22) | ||
20 | ASSOC_TYPE_ARG@[22; 34) | ||
21 | NAME_REF@[22; 26) | ||
22 | IDENT@[22; 26) "Item" | ||
23 | EQ@[26; 27) | ||
24 | PATH_TYPE@[27; 34) | ||
25 | PATH@[27; 34) | ||
26 | PATH_SEGMENT@[27; 34) | ||
27 | NAME_REF@[27; 30) | ||
28 | IDENT@[27; 30) "Foo" | ||
29 | TYPE_ARG_LIST@[30; 34) | ||
30 | L_ANGLE@[30; 31) | ||
31 | LIFETIME_ARG@[31; 33) | ||
32 | LIFETIME@[31; 33) "'a" | ||
33 | R_ANGLE@[33; 34) | ||
34 | R_ANGLE@[34; 35) | ||
35 | WHITESPACE@[35; 36) | ||
36 | PLUS@[36; 37) | ||
37 | WHITESPACE@[37; 38) | ||
38 | LIFETIME@[38; 40) "'a" | ||
39 | SEMI@[40; 41) | ||
40 | WHITESPACE@[41; 42) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.rs b/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.rs new file mode 100644 index 000000000..d140692e2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | type X = <A as B>::Output; | ||
2 | fn foo() { <usize as Default>::default(); } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.txt b/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.txt new file mode 100644 index 000000000..99516bf15 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0101_qual_paths.txt | |||
@@ -0,0 +1,78 @@ | |||
1 | ROOT@[0; 71) | ||
2 | TYPE_DEF@[0; 26) | ||
3 | TYPE_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 6) | ||
6 | IDENT@[5; 6) "X" | ||
7 | WHITESPACE@[6; 7) | ||
8 | EQ@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | PATH_TYPE@[9; 25) | ||
11 | PATH@[9; 25) | ||
12 | PATH@[9; 17) | ||
13 | PATH_SEGMENT@[9; 17) | ||
14 | L_ANGLE@[9; 10) | ||
15 | PATH_TYPE@[10; 11) | ||
16 | PATH@[10; 11) | ||
17 | PATH_SEGMENT@[10; 11) | ||
18 | NAME_REF@[10; 11) | ||
19 | IDENT@[10; 11) "A" | ||
20 | WHITESPACE@[11; 12) | ||
21 | AS_KW@[12; 14) | ||
22 | WHITESPACE@[14; 15) | ||
23 | PATH_TYPE@[15; 16) | ||
24 | PATH@[15; 16) | ||
25 | PATH_SEGMENT@[15; 16) | ||
26 | NAME_REF@[15; 16) | ||
27 | IDENT@[15; 16) "B" | ||
28 | R_ANGLE@[16; 17) | ||
29 | COLONCOLON@[17; 19) | ||
30 | PATH_SEGMENT@[19; 25) | ||
31 | NAME_REF@[19; 25) | ||
32 | IDENT@[19; 25) "Output" | ||
33 | SEMI@[25; 26) | ||
34 | WHITESPACE@[26; 27) | ||
35 | FN_DEF@[27; 70) | ||
36 | FN_KW@[27; 29) | ||
37 | WHITESPACE@[29; 30) | ||
38 | NAME@[30; 33) | ||
39 | IDENT@[30; 33) "foo" | ||
40 | PARAM_LIST@[33; 35) | ||
41 | L_PAREN@[33; 34) | ||
42 | R_PAREN@[34; 35) | ||
43 | WHITESPACE@[35; 36) | ||
44 | BLOCK@[36; 70) | ||
45 | L_CURLY@[36; 37) | ||
46 | WHITESPACE@[37; 38) | ||
47 | EXPR_STMT@[38; 68) | ||
48 | CALL_EXPR@[38; 67) | ||
49 | PATH_EXPR@[38; 65) | ||
50 | PATH@[38; 65) | ||
51 | PATH@[38; 56) | ||
52 | PATH_SEGMENT@[38; 56) | ||
53 | L_ANGLE@[38; 39) | ||
54 | PATH_TYPE@[39; 44) | ||
55 | PATH@[39; 44) | ||
56 | PATH_SEGMENT@[39; 44) | ||
57 | NAME_REF@[39; 44) | ||
58 | IDENT@[39; 44) "usize" | ||
59 | WHITESPACE@[44; 45) | ||
60 | AS_KW@[45; 47) | ||
61 | WHITESPACE@[47; 48) | ||
62 | PATH_TYPE@[48; 55) | ||
63 | PATH@[48; 55) | ||
64 | PATH_SEGMENT@[48; 55) | ||
65 | NAME_REF@[48; 55) | ||
66 | IDENT@[48; 55) "Default" | ||
67 | R_ANGLE@[55; 56) | ||
68 | COLONCOLON@[56; 58) | ||
69 | PATH_SEGMENT@[58; 65) | ||
70 | NAME_REF@[58; 65) | ||
71 | IDENT@[58; 65) "default" | ||
72 | ARG_LIST@[65; 67) | ||
73 | L_PAREN@[65; 66) | ||
74 | R_PAREN@[66; 67) | ||
75 | SEMI@[67; 68) | ||
76 | WHITESPACE@[68; 69) | ||
77 | R_CURLY@[69; 70) | ||
78 | WHITESPACE@[70; 71) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.rs new file mode 100644 index 000000000..ae21ad94c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.rs | |||
@@ -0,0 +1 @@ | |||
fn foo() { xs[..]; } | |||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.txt new file mode 100644 index 000000000..19f77fb73 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0102_full_range_expr.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | ROOT@[0; 21) | ||
2 | FN_DEF@[0; 20) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 20) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 11) | ||
14 | EXPR_STMT@[11; 18) | ||
15 | INDEX_EXPR@[11; 17) | ||
16 | PATH_EXPR@[11; 13) | ||
17 | PATH@[11; 13) | ||
18 | PATH_SEGMENT@[11; 13) | ||
19 | NAME_REF@[11; 13) | ||
20 | IDENT@[11; 13) "xs" | ||
21 | L_BRACK@[13; 14) | ||
22 | RANGE_EXPR@[14; 16) | ||
23 | DOTDOT@[14; 16) | ||
24 | R_BRACK@[16; 17) | ||
25 | SEMI@[17; 18) | ||
26 | WHITESPACE@[18; 19) | ||
27 | R_CURLY@[19; 20) | ||
28 | WHITESPACE@[20; 21) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.rs b/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.rs new file mode 100644 index 000000000..4744d8ac0 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | struct S { | ||
2 | #[serde(with = "url_serde")] | ||
3 | pub uri: Uri, | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.txt b/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.txt new file mode 100644 index 000000000..420712e89 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0103_field_attrs.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | ROOT@[0; 64) | ||
2 | STRUCT_DEF@[0; 63) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | WHITESPACE@[8; 9) | ||
8 | NAMED_FIELD_DEF_LIST@[9; 63) | ||
9 | L_CURLY@[9; 10) | ||
10 | WHITESPACE@[10; 15) | ||
11 | NAMED_FIELD_DEF@[15; 60) | ||
12 | ATTR@[15; 43) | ||
13 | POUND@[15; 16) | ||
14 | TOKEN_TREE@[16; 43) | ||
15 | L_BRACK@[16; 17) | ||
16 | IDENT@[17; 22) "serde" | ||
17 | TOKEN_TREE@[22; 42) | ||
18 | L_PAREN@[22; 23) | ||
19 | IDENT@[23; 27) "with" | ||
20 | WHITESPACE@[27; 28) | ||
21 | EQ@[28; 29) | ||
22 | WHITESPACE@[29; 30) | ||
23 | STRING@[30; 41) | ||
24 | R_PAREN@[41; 42) | ||
25 | R_BRACK@[42; 43) | ||
26 | WHITESPACE@[43; 48) | ||
27 | VISIBILITY@[48; 51) | ||
28 | PUB_KW@[48; 51) | ||
29 | WHITESPACE@[51; 52) | ||
30 | NAME@[52; 55) | ||
31 | IDENT@[52; 55) "uri" | ||
32 | COLON@[55; 56) | ||
33 | WHITESPACE@[56; 57) | ||
34 | PATH_TYPE@[57; 60) | ||
35 | PATH@[57; 60) | ||
36 | PATH_SEGMENT@[57; 60) | ||
37 | NAME_REF@[57; 60) | ||
38 | IDENT@[57; 60) "Uri" | ||
39 | COMMA@[60; 61) | ||
40 | WHITESPACE@[61; 62) | ||
41 | R_CURLY@[62; 63) | ||
42 | WHITESPACE@[63; 64) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.rs b/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.rs new file mode 100644 index 000000000..6a170d5ac --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | impl S { | ||
2 | fn a(self: &Self) {} | ||
3 | fn b(mut self: Box<Self>) {} | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.txt b/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.txt new file mode 100644 index 000000000..9a306921e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0104_arb_self_types.txt | |||
@@ -0,0 +1,72 @@ | |||
1 | ROOT@[0; 69) | ||
2 | IMPL_ITEM@[0; 68) | ||
3 | IMPL_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | PATH_TYPE@[5; 6) | ||
6 | PATH@[5; 6) | ||
7 | PATH_SEGMENT@[5; 6) | ||
8 | NAME_REF@[5; 6) | ||
9 | IDENT@[5; 6) "S" | ||
10 | WHITESPACE@[6; 7) | ||
11 | ITEM_LIST@[7; 68) | ||
12 | L_CURLY@[7; 8) | ||
13 | WHITESPACE@[8; 13) | ||
14 | FN_DEF@[13; 33) | ||
15 | FN_KW@[13; 15) | ||
16 | WHITESPACE@[15; 16) | ||
17 | NAME@[16; 17) | ||
18 | IDENT@[16; 17) "a" | ||
19 | PARAM_LIST@[17; 30) | ||
20 | L_PAREN@[17; 18) | ||
21 | SELF_PARAM@[18; 29) | ||
22 | SELF_KW@[18; 22) | ||
23 | COLON@[22; 23) | ||
24 | WHITESPACE@[23; 24) | ||
25 | REFERENCE_TYPE@[24; 29) | ||
26 | AMP@[24; 25) | ||
27 | PATH_TYPE@[25; 29) | ||
28 | PATH@[25; 29) | ||
29 | PATH_SEGMENT@[25; 29) | ||
30 | NAME_REF@[25; 29) | ||
31 | IDENT@[25; 29) "Self" | ||
32 | R_PAREN@[29; 30) | ||
33 | WHITESPACE@[30; 31) | ||
34 | BLOCK@[31; 33) | ||
35 | L_CURLY@[31; 32) | ||
36 | R_CURLY@[32; 33) | ||
37 | WHITESPACE@[33; 38) | ||
38 | FN_DEF@[38; 66) | ||
39 | FN_KW@[38; 40) | ||
40 | WHITESPACE@[40; 41) | ||
41 | NAME@[41; 42) | ||
42 | IDENT@[41; 42) "b" | ||
43 | PARAM_LIST@[42; 63) | ||
44 | L_PAREN@[42; 43) | ||
45 | SELF_PARAM@[43; 62) | ||
46 | MUT_KW@[43; 46) | ||
47 | WHITESPACE@[46; 47) | ||
48 | SELF_KW@[47; 51) | ||
49 | COLON@[51; 52) | ||
50 | WHITESPACE@[52; 53) | ||
51 | PATH_TYPE@[53; 62) | ||
52 | PATH@[53; 62) | ||
53 | PATH_SEGMENT@[53; 62) | ||
54 | NAME_REF@[53; 56) | ||
55 | IDENT@[53; 56) "Box" | ||
56 | TYPE_ARG_LIST@[56; 62) | ||
57 | L_ANGLE@[56; 57) | ||
58 | TYPE_ARG@[57; 61) | ||
59 | PATH_TYPE@[57; 61) | ||
60 | PATH@[57; 61) | ||
61 | PATH_SEGMENT@[57; 61) | ||
62 | NAME_REF@[57; 61) | ||
63 | IDENT@[57; 61) "Self" | ||
64 | R_ANGLE@[61; 62) | ||
65 | R_PAREN@[62; 63) | ||
66 | WHITESPACE@[63; 64) | ||
67 | BLOCK@[64; 66) | ||
68 | L_CURLY@[64; 65) | ||
69 | R_CURLY@[65; 66) | ||
70 | WHITESPACE@[66; 67) | ||
71 | R_CURLY@[67; 68) | ||
72 | WHITESPACE@[68; 69) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.rs new file mode 100644 index 000000000..474cc3f0e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | loop { | ||
3 | continue; | ||
4 | continue 'l; | ||
5 | } | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.txt new file mode 100644 index 000000000..1c78704fa --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0105_continue_expr.txt | |||
@@ -0,0 +1,35 @@ | |||
1 | ROOT@[0; 69) | ||
2 | FN_DEF@[0; 68) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 68) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LOOP_EXPR@[15; 66) | ||
15 | LOOP_KW@[15; 19) | ||
16 | WHITESPACE@[19; 20) | ||
17 | BLOCK@[20; 66) | ||
18 | L_CURLY@[20; 21) | ||
19 | WHITESPACE@[21; 30) | ||
20 | EXPR_STMT@[30; 39) | ||
21 | CONTINUE_EXPR@[30; 38) | ||
22 | CONTINUE_KW@[30; 38) | ||
23 | SEMI@[38; 39) | ||
24 | WHITESPACE@[39; 48) | ||
25 | EXPR_STMT@[48; 60) | ||
26 | CONTINUE_EXPR@[48; 59) | ||
27 | CONTINUE_KW@[48; 56) | ||
28 | WHITESPACE@[56; 57) | ||
29 | LIFETIME@[57; 59) "'l" | ||
30 | SEMI@[59; 60) | ||
31 | WHITESPACE@[60; 65) | ||
32 | R_CURLY@[65; 66) | ||
33 | WHITESPACE@[66; 67) | ||
34 | R_CURLY@[67; 68) | ||
35 | WHITESPACE@[68; 69) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.rs b/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.rs new file mode 100644 index 000000000..1b4094636 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | fn foo() { | ||
2 | loop { | ||
3 | break; | ||
4 | break 'l; | ||
5 | break 92; | ||
6 | break 'l 92; | ||
7 | } | ||
8 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.txt b/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.txt new file mode 100644 index 000000000..92b6b8bea --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0106_break_expr.txt | |||
@@ -0,0 +1,53 @@ | |||
1 | ROOT@[0; 102) | ||
2 | FN_DEF@[0; 101) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 101) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | LOOP_EXPR@[15; 99) | ||
15 | LOOP_KW@[15; 19) | ||
16 | WHITESPACE@[19; 20) | ||
17 | BLOCK@[20; 99) | ||
18 | L_CURLY@[20; 21) | ||
19 | WHITESPACE@[21; 30) | ||
20 | EXPR_STMT@[30; 36) | ||
21 | BREAK_EXPR@[30; 35) | ||
22 | BREAK_KW@[30; 35) | ||
23 | SEMI@[35; 36) | ||
24 | WHITESPACE@[36; 45) | ||
25 | EXPR_STMT@[45; 54) | ||
26 | BREAK_EXPR@[45; 53) | ||
27 | BREAK_KW@[45; 50) | ||
28 | WHITESPACE@[50; 51) | ||
29 | LIFETIME@[51; 53) "'l" | ||
30 | SEMI@[53; 54) | ||
31 | WHITESPACE@[54; 63) | ||
32 | EXPR_STMT@[63; 72) | ||
33 | BREAK_EXPR@[63; 71) | ||
34 | BREAK_KW@[63; 68) | ||
35 | WHITESPACE@[68; 69) | ||
36 | LITERAL@[69; 71) | ||
37 | INT_NUMBER@[69; 71) "92" | ||
38 | SEMI@[71; 72) | ||
39 | WHITESPACE@[72; 81) | ||
40 | EXPR_STMT@[81; 93) | ||
41 | BREAK_EXPR@[81; 92) | ||
42 | BREAK_KW@[81; 86) | ||
43 | WHITESPACE@[86; 87) | ||
44 | LIFETIME@[87; 89) "'l" | ||
45 | WHITESPACE@[89; 90) | ||
46 | LITERAL@[90; 92) | ||
47 | INT_NUMBER@[90; 92) "92" | ||
48 | SEMI@[92; 93) | ||
49 | WHITESPACE@[93; 98) | ||
50 | R_CURLY@[98; 99) | ||
51 | WHITESPACE@[99; 100) | ||
52 | R_CURLY@[100; 101) | ||
53 | WHITESPACE@[101; 102) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0107_label.rs b/crates/ra_syntax/tests/data/parser/inline/0107_label.rs new file mode 100644 index 000000000..48e83f263 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0107_label.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn foo() { | ||
2 | 'a: loop {} | ||
3 | 'b: while true {} | ||
4 | 'c: for x in () {} | ||
5 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0107_label.txt b/crates/ra_syntax/tests/data/parser/inline/0107_label.txt new file mode 100644 index 000000000..768515595 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0107_label.txt | |||
@@ -0,0 +1,64 @@ | |||
1 | ROOT@[0; 74) | ||
2 | FN_DEF@[0; 73) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 73) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 26) | ||
15 | LOOP_EXPR@[15; 26) | ||
16 | LABEL@[15; 18) | ||
17 | LIFETIME@[15; 17) "'a" | ||
18 | COLON@[17; 18) | ||
19 | WHITESPACE@[18; 19) | ||
20 | LOOP_KW@[19; 23) | ||
21 | WHITESPACE@[23; 24) | ||
22 | BLOCK@[24; 26) | ||
23 | L_CURLY@[24; 25) | ||
24 | R_CURLY@[25; 26) | ||
25 | WHITESPACE@[26; 31) | ||
26 | EXPR_STMT@[31; 48) | ||
27 | WHILE_EXPR@[31; 48) | ||
28 | LABEL@[31; 34) | ||
29 | LIFETIME@[31; 33) "'b" | ||
30 | COLON@[33; 34) | ||
31 | WHITESPACE@[34; 35) | ||
32 | WHILE_KW@[35; 40) | ||
33 | WHITESPACE@[40; 41) | ||
34 | CONDITION@[41; 45) | ||
35 | LITERAL@[41; 45) | ||
36 | TRUE_KW@[41; 45) | ||
37 | WHITESPACE@[45; 46) | ||
38 | BLOCK@[46; 48) | ||
39 | L_CURLY@[46; 47) | ||
40 | R_CURLY@[47; 48) | ||
41 | WHITESPACE@[48; 53) | ||
42 | FOR_EXPR@[53; 71) | ||
43 | LABEL@[53; 56) | ||
44 | LIFETIME@[53; 55) "'c" | ||
45 | COLON@[55; 56) | ||
46 | WHITESPACE@[56; 57) | ||
47 | FOR_KW@[57; 60) | ||
48 | WHITESPACE@[60; 61) | ||
49 | BIND_PAT@[61; 62) | ||
50 | NAME@[61; 62) | ||
51 | IDENT@[61; 62) "x" | ||
52 | WHITESPACE@[62; 63) | ||
53 | IN_KW@[63; 65) | ||
54 | WHITESPACE@[65; 66) | ||
55 | TUPLE_EXPR@[66; 68) | ||
56 | L_PAREN@[66; 67) | ||
57 | R_PAREN@[67; 68) | ||
58 | WHITESPACE@[68; 69) | ||
59 | BLOCK@[69; 71) | ||
60 | L_CURLY@[69; 70) | ||
61 | R_CURLY@[70; 71) | ||
62 | WHITESPACE@[71; 72) | ||
63 | R_CURLY@[72; 73) | ||
64 | WHITESPACE@[73; 74) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.rs b/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.rs new file mode 100644 index 000000000..a2164c510 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn main() { | ||
2 | 'loop: impl | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.txt b/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.txt new file mode 100644 index 000000000..d00305b97 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0108_misplaced_label_err.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | ROOT@[0; 30) | ||
2 | FN_DEF@[0; 29) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 29) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | EXPR_STMT@[16; 22) | ||
15 | ERROR@[16; 22) | ||
16 | LABEL@[16; 22) | ||
17 | LIFETIME@[16; 21) "'loop" | ||
18 | COLON@[21; 22) | ||
19 | err: `expected a loop` | ||
20 | err: `expected SEMI` | ||
21 | WHITESPACE@[22; 23) | ||
22 | IMPL_ITEM@[23; 27) | ||
23 | IMPL_KW@[23; 27) | ||
24 | err: `expected type` | ||
25 | err: `expected `{`` | ||
26 | WHITESPACE@[27; 28) | ||
27 | R_CURLY@[28; 29) | ||
28 | WHITESPACE@[29; 30) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.rs b/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.rs new file mode 100644 index 000000000..693e3f3ee --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | struct Foo; | ||
2 | struct Foo {} | ||
3 | struct Foo(); | ||
4 | struct Foo(String, usize); | ||
5 | struct Foo { | ||
6 | a: i32, | ||
7 | b: f32, | ||
8 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.txt b/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.txt new file mode 100644 index 000000000..f9b34cc5e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0109_struct_items.txt | |||
@@ -0,0 +1,87 @@ | |||
1 | ROOT@[0; 106) | ||
2 | STRUCT_DEF@[0; 11) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 10) | ||
6 | IDENT@[7; 10) "Foo" | ||
7 | SEMI@[10; 11) | ||
8 | WHITESPACE@[11; 12) | ||
9 | STRUCT_DEF@[12; 25) | ||
10 | STRUCT_KW@[12; 18) | ||
11 | WHITESPACE@[18; 19) | ||
12 | NAME@[19; 22) | ||
13 | IDENT@[19; 22) "Foo" | ||
14 | WHITESPACE@[22; 23) | ||
15 | NAMED_FIELD_DEF_LIST@[23; 25) | ||
16 | L_CURLY@[23; 24) | ||
17 | R_CURLY@[24; 25) | ||
18 | WHITESPACE@[25; 26) | ||
19 | STRUCT_DEF@[26; 39) | ||
20 | STRUCT_KW@[26; 32) | ||
21 | WHITESPACE@[32; 33) | ||
22 | NAME@[33; 36) | ||
23 | IDENT@[33; 36) "Foo" | ||
24 | POS_FIELD_LIST@[36; 38) | ||
25 | L_PAREN@[36; 37) | ||
26 | R_PAREN@[37; 38) | ||
27 | SEMI@[38; 39) | ||
28 | WHITESPACE@[39; 40) | ||
29 | STRUCT_DEF@[40; 66) | ||
30 | STRUCT_KW@[40; 46) | ||
31 | WHITESPACE@[46; 47) | ||
32 | NAME@[47; 50) | ||
33 | IDENT@[47; 50) "Foo" | ||
34 | POS_FIELD_LIST@[50; 65) | ||
35 | L_PAREN@[50; 51) | ||
36 | POS_FIELD@[51; 57) | ||
37 | PATH_TYPE@[51; 57) | ||
38 | PATH@[51; 57) | ||
39 | PATH_SEGMENT@[51; 57) | ||
40 | NAME_REF@[51; 57) | ||
41 | IDENT@[51; 57) "String" | ||
42 | COMMA@[57; 58) | ||
43 | WHITESPACE@[58; 59) | ||
44 | POS_FIELD@[59; 64) | ||
45 | PATH_TYPE@[59; 64) | ||
46 | PATH@[59; 64) | ||
47 | PATH_SEGMENT@[59; 64) | ||
48 | NAME_REF@[59; 64) | ||
49 | IDENT@[59; 64) "usize" | ||
50 | R_PAREN@[64; 65) | ||
51 | SEMI@[65; 66) | ||
52 | WHITESPACE@[66; 67) | ||
53 | STRUCT_DEF@[67; 105) | ||
54 | STRUCT_KW@[67; 73) | ||
55 | WHITESPACE@[73; 74) | ||
56 | NAME@[74; 77) | ||
57 | IDENT@[74; 77) "Foo" | ||
58 | WHITESPACE@[77; 78) | ||
59 | NAMED_FIELD_DEF_LIST@[78; 105) | ||
60 | L_CURLY@[78; 79) | ||
61 | WHITESPACE@[79; 84) | ||
62 | NAMED_FIELD_DEF@[84; 90) | ||
63 | NAME@[84; 85) | ||
64 | IDENT@[84; 85) "a" | ||
65 | COLON@[85; 86) | ||
66 | WHITESPACE@[86; 87) | ||
67 | PATH_TYPE@[87; 90) | ||
68 | PATH@[87; 90) | ||
69 | PATH_SEGMENT@[87; 90) | ||
70 | NAME_REF@[87; 90) | ||
71 | IDENT@[87; 90) "i32" | ||
72 | COMMA@[90; 91) | ||
73 | WHITESPACE@[91; 96) | ||
74 | NAMED_FIELD_DEF@[96; 102) | ||
75 | NAME@[96; 97) | ||
76 | IDENT@[96; 97) "b" | ||
77 | COLON@[97; 98) | ||
78 | WHITESPACE@[98; 99) | ||
79 | PATH_TYPE@[99; 102) | ||
80 | PATH@[99; 102) | ||
81 | PATH_SEGMENT@[99; 102) | ||
82 | NAME_REF@[99; 102) | ||
83 | IDENT@[99; 102) "f32" | ||
84 | COMMA@[102; 103) | ||
85 | WHITESPACE@[103; 104) | ||
86 | R_CURLY@[104; 105) | ||
87 | WHITESPACE@[105; 106) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0110_union_items.rs b/crates/ra_syntax/tests/data/parser/inline/0110_union_items.rs new file mode 100644 index 000000000..b7dd610d8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0110_union_items.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | union Foo {} | ||
2 | union Foo { | ||
3 | a: i32, | ||
4 | b: f32, | ||
5 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/0110_union_items.txt b/crates/ra_syntax/tests/data/parser/inline/0110_union_items.txt new file mode 100644 index 000000000..e2e755414 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/0110_union_items.txt | |||
@@ -0,0 +1,46 @@ | |||
1 | ROOT@[0; 51) | ||
2 | STRUCT_DEF@[0; 12) | ||
3 | UNION_KW@[0; 5) | ||
4 | WHITESPACE@[5; 6) | ||
5 | NAME@[6; 9) | ||
6 | IDENT@[6; 9) "Foo" | ||
7 | WHITESPACE@[9; 10) | ||
8 | NAMED_FIELD_DEF_LIST@[10; 12) | ||
9 | L_CURLY@[10; 11) | ||
10 | R_CURLY@[11; 12) | ||
11 | WHITESPACE@[12; 13) | ||
12 | STRUCT_DEF@[13; 50) | ||
13 | UNION_KW@[13; 18) | ||
14 | WHITESPACE@[18; 19) | ||
15 | NAME@[19; 22) | ||
16 | IDENT@[19; 22) "Foo" | ||
17 | WHITESPACE@[22; 23) | ||
18 | NAMED_FIELD_DEF_LIST@[23; 50) | ||
19 | L_CURLY@[23; 24) | ||
20 | WHITESPACE@[24; 29) | ||
21 | NAMED_FIELD_DEF@[29; 35) | ||
22 | NAME@[29; 30) | ||
23 | IDENT@[29; 30) "a" | ||
24 | COLON@[30; 31) | ||
25 | WHITESPACE@[31; 32) | ||
26 | PATH_TYPE@[32; 35) | ||
27 | PATH@[32; 35) | ||
28 | PATH_SEGMENT@[32; 35) | ||
29 | NAME_REF@[32; 35) | ||
30 | IDENT@[32; 35) "i32" | ||
31 | COMMA@[35; 36) | ||
32 | WHITESPACE@[36; 41) | ||
33 | NAMED_FIELD_DEF@[41; 47) | ||
34 | NAME@[41; 42) | ||
35 | IDENT@[41; 42) "b" | ||
36 | COLON@[42; 43) | ||
37 | WHITESPACE@[43; 44) | ||
38 | PATH_TYPE@[44; 47) | ||
39 | PATH@[44; 47) | ||
40 | PATH_SEGMENT@[44; 47) | ||
41 | NAME_REF@[44; 47) | ||
42 | IDENT@[44; 47) "f32" | ||
43 | COMMA@[47; 48) | ||
44 | WHITESPACE@[48; 49) | ||
45 | R_CURLY@[49; 50) | ||
46 | WHITESPACE@[50; 51) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0000_empty.rs b/crates/ra_syntax/tests/data/parser/ok/0000_empty.rs new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0000_empty.rs | |||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0000_empty.txt b/crates/ra_syntax/tests/data/parser/ok/0000_empty.txt new file mode 100644 index 000000000..9f505ee96 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0000_empty.txt | |||
@@ -0,0 +1 @@ | |||
ROOT@[0; 0) | |||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.rs b/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.rs new file mode 100644 index 000000000..512aeb3e7 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | struct S<T: Copy> { | ||
2 | f: T, | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.txt b/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.txt new file mode 100644 index 000000000..aa2f1b712 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0001_struct_item.txt | |||
@@ -0,0 +1,37 @@ | |||
1 | ROOT@[0; 32) | ||
2 | STRUCT_DEF@[0; 31) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | TYPE_PARAM_LIST@[8; 17) | ||
8 | L_ANGLE@[8; 9) | ||
9 | TYPE_PARAM@[9; 16) | ||
10 | NAME@[9; 10) | ||
11 | IDENT@[9; 10) "T" | ||
12 | COLON@[10; 11) | ||
13 | WHITESPACE@[11; 12) | ||
14 | PATH_TYPE@[12; 16) | ||
15 | PATH@[12; 16) | ||
16 | PATH_SEGMENT@[12; 16) | ||
17 | NAME_REF@[12; 16) | ||
18 | IDENT@[12; 16) "Copy" | ||
19 | R_ANGLE@[16; 17) | ||
20 | WHITESPACE@[17; 18) | ||
21 | NAMED_FIELD_DEF_LIST@[18; 31) | ||
22 | L_CURLY@[18; 19) | ||
23 | WHITESPACE@[19; 24) | ||
24 | NAMED_FIELD_DEF@[24; 28) | ||
25 | NAME@[24; 25) | ||
26 | IDENT@[24; 25) "f" | ||
27 | COLON@[25; 26) | ||
28 | WHITESPACE@[26; 27) | ||
29 | PATH_TYPE@[27; 28) | ||
30 | PATH@[27; 28) | ||
31 | PATH_SEGMENT@[27; 28) | ||
32 | NAME_REF@[27; 28) | ||
33 | IDENT@[27; 28) "T" | ||
34 | COMMA@[28; 29) | ||
35 | WHITESPACE@[29; 30) | ||
36 | R_CURLY@[30; 31) | ||
37 | WHITESPACE@[31; 32) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.rs b/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.rs new file mode 100644 index 000000000..cc3866d25 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | struct S { | ||
2 | foo: u32 | ||
3 | } \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.txt b/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.txt new file mode 100644 index 000000000..0b65387ef --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0002_struct_item_field.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | ROOT@[0; 25) | ||
2 | STRUCT_DEF@[0; 25) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "S" | ||
7 | WHITESPACE@[8; 9) | ||
8 | NAMED_FIELD_DEF_LIST@[9; 25) | ||
9 | L_CURLY@[9; 10) | ||
10 | WHITESPACE@[10; 15) | ||
11 | NAMED_FIELD_DEF@[15; 23) | ||
12 | NAME@[15; 18) | ||
13 | IDENT@[15; 18) "foo" | ||
14 | COLON@[18; 19) | ||
15 | WHITESPACE@[19; 20) | ||
16 | PATH_TYPE@[20; 23) | ||
17 | PATH@[20; 23) | ||
18 | PATH_SEGMENT@[20; 23) | ||
19 | NAME_REF@[20; 23) | ||
20 | IDENT@[20; 23) "u32" | ||
21 | WHITESPACE@[23; 24) | ||
22 | R_CURLY@[24; 25) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.rs b/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.rs new file mode 100644 index 000000000..53dc9e617 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.rs | |||
@@ -0,0 +1 @@ | |||
#!/use/bin/env rusti \ No newline at end of file | |||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.txt b/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.txt new file mode 100644 index 000000000..bb8874ead --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0004_file_shebang.txt | |||
@@ -0,0 +1,2 @@ | |||
1 | ROOT@[0; 20) | ||
2 | SHEBANG@[0; 20) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.rs b/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.rs new file mode 100644 index 000000000..03210551c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | fn foo() { | ||
2 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.txt b/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.txt new file mode 100644 index 000000000..8ed92f2a4 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0005_fn_item.txt | |||
@@ -0,0 +1,15 @@ | |||
1 | ROOT@[0; 13) | ||
2 | FN_DEF@[0; 12) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 12) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 11) | ||
14 | R_CURLY@[11; 12) | ||
15 | WHITESPACE@[12; 13) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.rs b/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.rs new file mode 100644 index 000000000..e81f8b1e8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.rs | |||
@@ -0,0 +1,10 @@ | |||
1 | #![attr] | ||
2 | #![attr(true)] | ||
3 | #![attr(ident)] | ||
4 | #![attr(ident, 100, true, "true", ident = 100, ident = "hello", ident(100))] | ||
5 | #![attr(100)] | ||
6 | #![attr(enabled = true)] | ||
7 | #![enabled(true)] | ||
8 | #![attr("hello")] | ||
9 | #![repr(C, align = 4)] | ||
10 | #![repr(C, align(4))] \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.txt b/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.txt new file mode 100644 index 000000000..2b64c497f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0006_inner_attributes.txt | |||
@@ -0,0 +1,164 @@ | |||
1 | ROOT@[0; 236) | ||
2 | ATTR@[0; 8) | ||
3 | POUND@[0; 1) | ||
4 | EXCL@[1; 2) | ||
5 | TOKEN_TREE@[2; 8) | ||
6 | L_BRACK@[2; 3) | ||
7 | IDENT@[3; 7) "attr" | ||
8 | R_BRACK@[7; 8) | ||
9 | WHITESPACE@[8; 9) | ||
10 | ATTR@[9; 23) | ||
11 | POUND@[9; 10) | ||
12 | EXCL@[10; 11) | ||
13 | TOKEN_TREE@[11; 23) | ||
14 | L_BRACK@[11; 12) | ||
15 | IDENT@[12; 16) "attr" | ||
16 | TOKEN_TREE@[16; 22) | ||
17 | L_PAREN@[16; 17) | ||
18 | TRUE_KW@[17; 21) | ||
19 | R_PAREN@[21; 22) | ||
20 | R_BRACK@[22; 23) | ||
21 | WHITESPACE@[23; 24) | ||
22 | ATTR@[24; 39) | ||
23 | POUND@[24; 25) | ||
24 | EXCL@[25; 26) | ||
25 | TOKEN_TREE@[26; 39) | ||
26 | L_BRACK@[26; 27) | ||
27 | IDENT@[27; 31) "attr" | ||
28 | TOKEN_TREE@[31; 38) | ||
29 | L_PAREN@[31; 32) | ||
30 | IDENT@[32; 37) "ident" | ||
31 | R_PAREN@[37; 38) | ||
32 | R_BRACK@[38; 39) | ||
33 | WHITESPACE@[39; 40) | ||
34 | ATTR@[40; 116) | ||
35 | POUND@[40; 41) | ||
36 | EXCL@[41; 42) | ||
37 | TOKEN_TREE@[42; 116) | ||
38 | L_BRACK@[42; 43) | ||
39 | IDENT@[43; 47) "attr" | ||
40 | TOKEN_TREE@[47; 115) | ||
41 | L_PAREN@[47; 48) | ||
42 | IDENT@[48; 53) "ident" | ||
43 | COMMA@[53; 54) | ||
44 | WHITESPACE@[54; 55) | ||
45 | INT_NUMBER@[55; 58) "100" | ||
46 | COMMA@[58; 59) | ||
47 | WHITESPACE@[59; 60) | ||
48 | TRUE_KW@[60; 64) | ||
49 | COMMA@[64; 65) | ||
50 | WHITESPACE@[65; 66) | ||
51 | STRING@[66; 72) | ||
52 | COMMA@[72; 73) | ||
53 | WHITESPACE@[73; 74) | ||
54 | IDENT@[74; 79) "ident" | ||
55 | WHITESPACE@[79; 80) | ||
56 | EQ@[80; 81) | ||
57 | WHITESPACE@[81; 82) | ||
58 | INT_NUMBER@[82; 85) "100" | ||
59 | COMMA@[85; 86) | ||
60 | WHITESPACE@[86; 87) | ||
61 | IDENT@[87; 92) "ident" | ||
62 | WHITESPACE@[92; 93) | ||
63 | EQ@[93; 94) | ||
64 | WHITESPACE@[94; 95) | ||
65 | STRING@[95; 102) | ||
66 | COMMA@[102; 103) | ||
67 | WHITESPACE@[103; 104) | ||
68 | IDENT@[104; 109) "ident" | ||
69 | TOKEN_TREE@[109; 114) | ||
70 | L_PAREN@[109; 110) | ||
71 | INT_NUMBER@[110; 113) "100" | ||
72 | R_PAREN@[113; 114) | ||
73 | R_PAREN@[114; 115) | ||
74 | R_BRACK@[115; 116) | ||
75 | WHITESPACE@[116; 117) | ||
76 | ATTR@[117; 130) | ||
77 | POUND@[117; 118) | ||
78 | EXCL@[118; 119) | ||
79 | TOKEN_TREE@[119; 130) | ||
80 | L_BRACK@[119; 120) | ||
81 | IDENT@[120; 124) "attr" | ||
82 | TOKEN_TREE@[124; 129) | ||
83 | L_PAREN@[124; 125) | ||
84 | INT_NUMBER@[125; 128) "100" | ||
85 | R_PAREN@[128; 129) | ||
86 | R_BRACK@[129; 130) | ||
87 | WHITESPACE@[130; 131) | ||
88 | ATTR@[131; 155) | ||
89 | POUND@[131; 132) | ||
90 | EXCL@[132; 133) | ||
91 | TOKEN_TREE@[133; 155) | ||
92 | L_BRACK@[133; 134) | ||
93 | IDENT@[134; 138) "attr" | ||
94 | TOKEN_TREE@[138; 154) | ||
95 | L_PAREN@[138; 139) | ||
96 | IDENT@[139; 146) "enabled" | ||
97 | WHITESPACE@[146; 147) | ||
98 | EQ@[147; 148) | ||
99 | WHITESPACE@[148; 149) | ||
100 | TRUE_KW@[149; 153) | ||
101 | R_PAREN@[153; 154) | ||
102 | R_BRACK@[154; 155) | ||
103 | WHITESPACE@[155; 156) | ||
104 | ATTR@[156; 173) | ||
105 | POUND@[156; 157) | ||
106 | EXCL@[157; 158) | ||
107 | TOKEN_TREE@[158; 173) | ||
108 | L_BRACK@[158; 159) | ||
109 | IDENT@[159; 166) "enabled" | ||
110 | TOKEN_TREE@[166; 172) | ||
111 | L_PAREN@[166; 167) | ||
112 | TRUE_KW@[167; 171) | ||
113 | R_PAREN@[171; 172) | ||
114 | R_BRACK@[172; 173) | ||
115 | WHITESPACE@[173; 174) | ||
116 | ATTR@[174; 191) | ||
117 | POUND@[174; 175) | ||
118 | EXCL@[175; 176) | ||
119 | TOKEN_TREE@[176; 191) | ||
120 | L_BRACK@[176; 177) | ||
121 | IDENT@[177; 181) "attr" | ||
122 | TOKEN_TREE@[181; 190) | ||
123 | L_PAREN@[181; 182) | ||
124 | STRING@[182; 189) | ||
125 | R_PAREN@[189; 190) | ||
126 | R_BRACK@[190; 191) | ||
127 | WHITESPACE@[191; 192) | ||
128 | ATTR@[192; 214) | ||
129 | POUND@[192; 193) | ||
130 | EXCL@[193; 194) | ||
131 | TOKEN_TREE@[194; 214) | ||
132 | L_BRACK@[194; 195) | ||
133 | IDENT@[195; 199) "repr" | ||
134 | TOKEN_TREE@[199; 213) | ||
135 | L_PAREN@[199; 200) | ||
136 | IDENT@[200; 201) "C" | ||
137 | COMMA@[201; 202) | ||
138 | WHITESPACE@[202; 203) | ||
139 | IDENT@[203; 208) "align" | ||
140 | WHITESPACE@[208; 209) | ||
141 | EQ@[209; 210) | ||
142 | WHITESPACE@[210; 211) | ||
143 | INT_NUMBER@[211; 212) "4" | ||
144 | R_PAREN@[212; 213) | ||
145 | R_BRACK@[213; 214) | ||
146 | WHITESPACE@[214; 215) | ||
147 | ATTR@[215; 236) | ||
148 | POUND@[215; 216) | ||
149 | EXCL@[216; 217) | ||
150 | TOKEN_TREE@[217; 236) | ||
151 | L_BRACK@[217; 218) | ||
152 | IDENT@[218; 222) "repr" | ||
153 | TOKEN_TREE@[222; 235) | ||
154 | L_PAREN@[222; 223) | ||
155 | IDENT@[223; 224) "C" | ||
156 | COMMA@[224; 225) | ||
157 | WHITESPACE@[225; 226) | ||
158 | IDENT@[226; 231) "align" | ||
159 | TOKEN_TREE@[231; 234) | ||
160 | L_PAREN@[231; 232) | ||
161 | INT_NUMBER@[232; 233) "4" | ||
162 | R_PAREN@[233; 234) | ||
163 | R_PAREN@[234; 235) | ||
164 | R_BRACK@[235; 236) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.rs b/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.rs new file mode 100644 index 000000000..3ce336676 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | extern crate foo; | ||
2 | extern crate foo as bar; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.txt b/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.txt new file mode 100644 index 000000000..12193397e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0007_extern_crate.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | ROOT@[0; 43) | ||
2 | EXTERN_CRATE_ITEM@[0; 17) | ||
3 | EXTERN_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | CRATE_KW@[7; 12) | ||
6 | WHITESPACE@[12; 13) | ||
7 | NAME@[13; 16) | ||
8 | IDENT@[13; 16) "foo" | ||
9 | SEMI@[16; 17) | ||
10 | WHITESPACE@[17; 18) | ||
11 | EXTERN_CRATE_ITEM@[18; 42) | ||
12 | EXTERN_KW@[18; 24) | ||
13 | WHITESPACE@[24; 25) | ||
14 | CRATE_KW@[25; 30) | ||
15 | WHITESPACE@[30; 31) | ||
16 | NAME@[31; 34) | ||
17 | IDENT@[31; 34) "foo" | ||
18 | WHITESPACE@[34; 35) | ||
19 | ALIAS@[35; 41) | ||
20 | AS_KW@[35; 37) | ||
21 | WHITESPACE@[37; 38) | ||
22 | NAME@[38; 41) | ||
23 | IDENT@[38; 41) "bar" | ||
24 | SEMI@[41; 42) | ||
25 | WHITESPACE@[42; 43) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.rs b/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.rs new file mode 100644 index 000000000..d22993bc1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.rs | |||
@@ -0,0 +1,17 @@ | |||
1 | mod a; | ||
2 | |||
3 | mod b { | ||
4 | } | ||
5 | |||
6 | mod c { | ||
7 | fn foo() { | ||
8 | } | ||
9 | struct S {} | ||
10 | } | ||
11 | |||
12 | mod d { | ||
13 | #![attr] | ||
14 | mod e; | ||
15 | mod f { | ||
16 | } | ||
17 | } \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.txt b/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.txt new file mode 100644 index 000000000..c790f8431 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0008_mod_item.txt | |||
@@ -0,0 +1,90 @@ | |||
1 | ROOT@[0; 118) | ||
2 | MODULE@[0; 6) | ||
3 | MOD_KW@[0; 3) | ||
4 | WHITESPACE@[3; 4) | ||
5 | NAME@[4; 5) | ||
6 | IDENT@[4; 5) "a" | ||
7 | SEMI@[5; 6) | ||
8 | WHITESPACE@[6; 8) | ||
9 | MODULE@[8; 17) | ||
10 | MOD_KW@[8; 11) | ||
11 | WHITESPACE@[11; 12) | ||
12 | NAME@[12; 13) | ||
13 | IDENT@[12; 13) "b" | ||
14 | WHITESPACE@[13; 14) | ||
15 | ITEM_LIST@[14; 17) | ||
16 | L_CURLY@[14; 15) | ||
17 | WHITESPACE@[15; 16) | ||
18 | R_CURLY@[16; 17) | ||
19 | WHITESPACE@[17; 19) | ||
20 | MODULE@[19; 65) | ||
21 | MOD_KW@[19; 22) | ||
22 | WHITESPACE@[22; 23) | ||
23 | NAME@[23; 24) | ||
24 | IDENT@[23; 24) "c" | ||
25 | WHITESPACE@[24; 25) | ||
26 | ITEM_LIST@[25; 65) | ||
27 | L_CURLY@[25; 26) | ||
28 | WHITESPACE@[26; 31) | ||
29 | FN_DEF@[31; 47) | ||
30 | FN_KW@[31; 33) | ||
31 | WHITESPACE@[33; 34) | ||
32 | NAME@[34; 37) | ||
33 | IDENT@[34; 37) "foo" | ||
34 | PARAM_LIST@[37; 39) | ||
35 | L_PAREN@[37; 38) | ||
36 | R_PAREN@[38; 39) | ||
37 | WHITESPACE@[39; 40) | ||
38 | BLOCK@[40; 47) | ||
39 | L_CURLY@[40; 41) | ||
40 | WHITESPACE@[41; 46) | ||
41 | R_CURLY@[46; 47) | ||
42 | WHITESPACE@[47; 52) | ||
43 | STRUCT_DEF@[52; 63) | ||
44 | STRUCT_KW@[52; 58) | ||
45 | WHITESPACE@[58; 59) | ||
46 | NAME@[59; 60) | ||
47 | IDENT@[59; 60) "S" | ||
48 | WHITESPACE@[60; 61) | ||
49 | NAMED_FIELD_DEF_LIST@[61; 63) | ||
50 | L_CURLY@[61; 62) | ||
51 | R_CURLY@[62; 63) | ||
52 | WHITESPACE@[63; 64) | ||
53 | R_CURLY@[64; 65) | ||
54 | WHITESPACE@[65; 67) | ||
55 | MODULE@[67; 118) | ||
56 | MOD_KW@[67; 70) | ||
57 | WHITESPACE@[70; 71) | ||
58 | NAME@[71; 72) | ||
59 | IDENT@[71; 72) "d" | ||
60 | WHITESPACE@[72; 73) | ||
61 | ITEM_LIST@[73; 118) | ||
62 | L_CURLY@[73; 74) | ||
63 | WHITESPACE@[74; 79) | ||
64 | ATTR@[79; 87) | ||
65 | POUND@[79; 80) | ||
66 | EXCL@[80; 81) | ||
67 | TOKEN_TREE@[81; 87) | ||
68 | L_BRACK@[81; 82) | ||
69 | IDENT@[82; 86) "attr" | ||
70 | R_BRACK@[86; 87) | ||
71 | WHITESPACE@[87; 92) | ||
72 | MODULE@[92; 98) | ||
73 | MOD_KW@[92; 95) | ||
74 | WHITESPACE@[95; 96) | ||
75 | NAME@[96; 97) | ||
76 | IDENT@[96; 97) "e" | ||
77 | SEMI@[97; 98) | ||
78 | WHITESPACE@[98; 103) | ||
79 | MODULE@[103; 116) | ||
80 | MOD_KW@[103; 106) | ||
81 | WHITESPACE@[106; 107) | ||
82 | NAME@[107; 108) | ||
83 | IDENT@[107; 108) "f" | ||
84 | WHITESPACE@[108; 109) | ||
85 | ITEM_LIST@[109; 116) | ||
86 | L_CURLY@[109; 110) | ||
87 | WHITESPACE@[110; 115) | ||
88 | R_CURLY@[115; 116) | ||
89 | WHITESPACE@[116; 117) | ||
90 | R_CURLY@[117; 118) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0009_use_item.rs b/crates/ra_syntax/tests/data/parser/ok/0009_use_item.rs new file mode 100644 index 000000000..05a6aff83 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0009_use_item.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | use foo; | ||
2 | use ::bar; \ No newline at end of file | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0009_use_item.txt b/crates/ra_syntax/tests/data/parser/ok/0009_use_item.txt new file mode 100644 index 000000000..4bcd15357 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0009_use_item.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | ROOT@[0; 19) | ||
2 | USE_ITEM@[0; 8) | ||
3 | USE_KW@[0; 3) | ||
4 | WHITESPACE@[3; 4) | ||
5 | USE_TREE@[4; 7) | ||
6 | PATH@[4; 7) | ||
7 | PATH_SEGMENT@[4; 7) | ||
8 | NAME_REF@[4; 7) | ||
9 | IDENT@[4; 7) "foo" | ||
10 | SEMI@[7; 8) | ||
11 | WHITESPACE@[8; 9) | ||
12 | USE_ITEM@[9; 19) | ||
13 | USE_KW@[9; 12) | ||
14 | WHITESPACE@[12; 13) | ||
15 | USE_TREE@[13; 18) | ||
16 | PATH@[13; 18) | ||
17 | PATH_SEGMENT@[13; 18) | ||
18 | COLONCOLON@[13; 15) | ||
19 | NAME_REF@[15; 18) | ||
20 | IDENT@[15; 18) "bar" | ||
21 | SEMI@[18; 19) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.rs b/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.rs new file mode 100644 index 000000000..1e71b7a6c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | use ::foo::bar::baz; | ||
2 | use foo::bar::baz; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.txt b/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.txt new file mode 100644 index 000000000..f76ea1a35 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0010_use_path_segments.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | ROOT@[0; 40) | ||
2 | USE_ITEM@[0; 20) | ||
3 | USE_KW@[0; 3) | ||
4 | WHITESPACE@[3; 4) | ||
5 | USE_TREE@[4; 19) | ||
6 | PATH@[4; 19) | ||
7 | PATH@[4; 14) | ||
8 | PATH@[4; 9) | ||
9 | PATH_SEGMENT@[4; 9) | ||
10 | COLONCOLON@[4; 6) | ||
11 | NAME_REF@[6; 9) | ||
12 | IDENT@[6; 9) "foo" | ||
13 | COLONCOLON@[9; 11) | ||
14 | PATH_SEGMENT@[11; 14) | ||
15 | NAME_REF@[11; 14) | ||
16 | IDENT@[11; 14) "bar" | ||
17 | COLONCOLON@[14; 16) | ||
18 | PATH_SEGMENT@[16; 19) | ||
19 | NAME_REF@[16; 19) | ||
20 | IDENT@[16; 19) "baz" | ||
21 | SEMI@[19; 20) | ||
22 | WHITESPACE@[20; 21) | ||
23 | USE_ITEM@[21; 39) | ||
24 | USE_KW@[21; 24) | ||
25 | WHITESPACE@[24; 25) | ||
26 | USE_TREE@[25; 38) | ||
27 | PATH@[25; 38) | ||
28 | PATH@[25; 33) | ||
29 | PATH@[25; 28) | ||
30 | PATH_SEGMENT@[25; 28) | ||
31 | NAME_REF@[25; 28) | ||
32 | IDENT@[25; 28) "foo" | ||
33 | COLONCOLON@[28; 30) | ||
34 | PATH_SEGMENT@[30; 33) | ||
35 | NAME_REF@[30; 33) | ||
36 | IDENT@[30; 33) "bar" | ||
37 | COLONCOLON@[33; 35) | ||
38 | PATH_SEGMENT@[35; 38) | ||
39 | NAME_REF@[35; 38) | ||
40 | IDENT@[35; 38) "baz" | ||
41 | SEMI@[38; 39) | ||
42 | WHITESPACE@[39; 40) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.rs b/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.rs new file mode 100644 index 000000000..8b80c0d90 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | #[cfg(test)] | ||
2 | #[ignore] | ||
3 | fn foo() {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.txt b/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.txt new file mode 100644 index 000000000..203a07193 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0011_outer_attribute.txt | |||
@@ -0,0 +1,32 @@ | |||
1 | ROOT@[0; 35) | ||
2 | FN_DEF@[0; 34) | ||
3 | ATTR@[0; 12) | ||
4 | POUND@[0; 1) | ||
5 | TOKEN_TREE@[1; 12) | ||
6 | L_BRACK@[1; 2) | ||
7 | IDENT@[2; 5) "cfg" | ||
8 | TOKEN_TREE@[5; 11) | ||
9 | L_PAREN@[5; 6) | ||
10 | IDENT@[6; 10) "test" | ||
11 | R_PAREN@[10; 11) | ||
12 | R_BRACK@[11; 12) | ||
13 | WHITESPACE@[12; 13) | ||
14 | ATTR@[13; 22) | ||
15 | POUND@[13; 14) | ||
16 | TOKEN_TREE@[14; 22) | ||
17 | L_BRACK@[14; 15) | ||
18 | IDENT@[15; 21) "ignore" | ||
19 | R_BRACK@[21; 22) | ||
20 | WHITESPACE@[22; 23) | ||
21 | FN_KW@[23; 25) | ||
22 | WHITESPACE@[25; 26) | ||
23 | NAME@[26; 29) | ||
24 | IDENT@[26; 29) "foo" | ||
25 | PARAM_LIST@[29; 31) | ||
26 | L_PAREN@[29; 30) | ||
27 | R_PAREN@[30; 31) | ||
28 | WHITESPACE@[31; 32) | ||
29 | BLOCK@[32; 34) | ||
30 | L_CURLY@[32; 33) | ||
31 | R_CURLY@[33; 34) | ||
32 | WHITESPACE@[34; 35) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0012_visibility.rs b/crates/ra_syntax/tests/data/parser/ok/0012_visibility.rs new file mode 100644 index 000000000..75b1db121 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0012_visibility.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn a() {} | ||
2 | pub fn b() {} | ||
3 | pub(crate) fn c() {} | ||
4 | pub(super) fn d() {} | ||
5 | pub(in foo::bar::baz) fn e() {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0012_visibility.txt b/crates/ra_syntax/tests/data/parser/ok/0012_visibility.txt new file mode 100644 index 000000000..66901af54 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0012_visibility.txt | |||
@@ -0,0 +1,102 @@ | |||
1 | ROOT@[0; 98) | ||
2 | FN_DEF@[0; 9) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 4) | ||
6 | IDENT@[3; 4) "a" | ||
7 | PARAM_LIST@[4; 6) | ||
8 | L_PAREN@[4; 5) | ||
9 | R_PAREN@[5; 6) | ||
10 | WHITESPACE@[6; 7) | ||
11 | BLOCK@[7; 9) | ||
12 | L_CURLY@[7; 8) | ||
13 | R_CURLY@[8; 9) | ||
14 | WHITESPACE@[9; 10) | ||
15 | FN_DEF@[10; 23) | ||
16 | VISIBILITY@[10; 13) | ||
17 | PUB_KW@[10; 13) | ||
18 | WHITESPACE@[13; 14) | ||
19 | FN_KW@[14; 16) | ||
20 | WHITESPACE@[16; 17) | ||
21 | NAME@[17; 18) | ||
22 | IDENT@[17; 18) "b" | ||
23 | PARAM_LIST@[18; 20) | ||
24 | L_PAREN@[18; 19) | ||
25 | R_PAREN@[19; 20) | ||
26 | WHITESPACE@[20; 21) | ||
27 | BLOCK@[21; 23) | ||
28 | L_CURLY@[21; 22) | ||
29 | R_CURLY@[22; 23) | ||
30 | WHITESPACE@[23; 24) | ||
31 | FN_DEF@[24; 44) | ||
32 | VISIBILITY@[24; 34) | ||
33 | PUB_KW@[24; 27) | ||
34 | L_PAREN@[27; 28) | ||
35 | CRATE_KW@[28; 33) | ||
36 | R_PAREN@[33; 34) | ||
37 | WHITESPACE@[34; 35) | ||
38 | FN_KW@[35; 37) | ||
39 | WHITESPACE@[37; 38) | ||
40 | NAME@[38; 39) | ||
41 | IDENT@[38; 39) "c" | ||
42 | PARAM_LIST@[39; 41) | ||
43 | L_PAREN@[39; 40) | ||
44 | R_PAREN@[40; 41) | ||
45 | WHITESPACE@[41; 42) | ||
46 | BLOCK@[42; 44) | ||
47 | L_CURLY@[42; 43) | ||
48 | R_CURLY@[43; 44) | ||
49 | WHITESPACE@[44; 45) | ||
50 | FN_DEF@[45; 65) | ||
51 | VISIBILITY@[45; 55) | ||
52 | PUB_KW@[45; 48) | ||
53 | L_PAREN@[48; 49) | ||
54 | SUPER_KW@[49; 54) | ||
55 | R_PAREN@[54; 55) | ||
56 | WHITESPACE@[55; 56) | ||
57 | FN_KW@[56; 58) | ||
58 | WHITESPACE@[58; 59) | ||
59 | NAME@[59; 60) | ||
60 | IDENT@[59; 60) "d" | ||
61 | PARAM_LIST@[60; 62) | ||
62 | L_PAREN@[60; 61) | ||
63 | R_PAREN@[61; 62) | ||
64 | WHITESPACE@[62; 63) | ||
65 | BLOCK@[63; 65) | ||
66 | L_CURLY@[63; 64) | ||
67 | R_CURLY@[64; 65) | ||
68 | WHITESPACE@[65; 66) | ||
69 | FN_DEF@[66; 97) | ||
70 | VISIBILITY@[66; 87) | ||
71 | PUB_KW@[66; 69) | ||
72 | L_PAREN@[69; 70) | ||
73 | IN_KW@[70; 72) | ||
74 | WHITESPACE@[72; 73) | ||
75 | PATH@[73; 86) | ||
76 | PATH@[73; 81) | ||
77 | PATH@[73; 76) | ||
78 | PATH_SEGMENT@[73; 76) | ||
79 | NAME_REF@[73; 76) | ||
80 | IDENT@[73; 76) "foo" | ||
81 | COLONCOLON@[76; 78) | ||
82 | PATH_SEGMENT@[78; 81) | ||
83 | NAME_REF@[78; 81) | ||
84 | IDENT@[78; 81) "bar" | ||
85 | COLONCOLON@[81; 83) | ||
86 | PATH_SEGMENT@[83; 86) | ||
87 | NAME_REF@[83; 86) | ||
88 | IDENT@[83; 86) "baz" | ||
89 | R_PAREN@[86; 87) | ||
90 | WHITESPACE@[87; 88) | ||
91 | FN_KW@[88; 90) | ||
92 | WHITESPACE@[90; 91) | ||
93 | NAME@[91; 92) | ||
94 | IDENT@[91; 92) "e" | ||
95 | PARAM_LIST@[92; 94) | ||
96 | L_PAREN@[92; 93) | ||
97 | R_PAREN@[93; 94) | ||
98 | WHITESPACE@[94; 95) | ||
99 | BLOCK@[95; 97) | ||
100 | L_CURLY@[95; 96) | ||
101 | R_CURLY@[96; 97) | ||
102 | WHITESPACE@[97; 98) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.rs b/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.rs new file mode 100644 index 000000000..faf6a42c7 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | use self::foo; | ||
2 | use super::super::bar; | ||
3 | use ::self::a::super::bar; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.txt b/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.txt new file mode 100644 index 000000000..95be4f75d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0013_use_path_self_super.txt | |||
@@ -0,0 +1,57 @@ | |||
1 | ROOT@[0; 65) | ||
2 | USE_ITEM@[0; 14) | ||
3 | USE_KW@[0; 3) | ||
4 | WHITESPACE@[3; 4) | ||
5 | USE_TREE@[4; 13) | ||
6 | PATH@[4; 13) | ||
7 | PATH@[4; 8) | ||
8 | PATH_SEGMENT@[4; 8) | ||
9 | SELF_KW@[4; 8) | ||
10 | COLONCOLON@[8; 10) | ||
11 | PATH_SEGMENT@[10; 13) | ||
12 | NAME_REF@[10; 13) | ||
13 | IDENT@[10; 13) "foo" | ||
14 | SEMI@[13; 14) | ||
15 | WHITESPACE@[14; 15) | ||
16 | USE_ITEM@[15; 37) | ||
17 | USE_KW@[15; 18) | ||
18 | WHITESPACE@[18; 19) | ||
19 | USE_TREE@[19; 36) | ||
20 | PATH@[19; 36) | ||
21 | PATH@[19; 31) | ||
22 | PATH@[19; 24) | ||
23 | PATH_SEGMENT@[19; 24) | ||
24 | SUPER_KW@[19; 24) | ||
25 | COLONCOLON@[24; 26) | ||
26 | PATH_SEGMENT@[26; 31) | ||
27 | SUPER_KW@[26; 31) | ||
28 | COLONCOLON@[31; 33) | ||
29 | PATH_SEGMENT@[33; 36) | ||
30 | NAME_REF@[33; 36) | ||
31 | IDENT@[33; 36) "bar" | ||
32 | SEMI@[36; 37) | ||
33 | WHITESPACE@[37; 38) | ||
34 | USE_ITEM@[38; 64) | ||
35 | USE_KW@[38; 41) | ||
36 | WHITESPACE@[41; 42) | ||
37 | USE_TREE@[42; 63) | ||
38 | PATH@[42; 63) | ||
39 | PATH@[42; 58) | ||
40 | PATH@[42; 51) | ||
41 | PATH@[42; 48) | ||
42 | PATH_SEGMENT@[42; 48) | ||
43 | COLONCOLON@[42; 44) | ||
44 | SELF_KW@[44; 48) | ||
45 | COLONCOLON@[48; 50) | ||
46 | PATH_SEGMENT@[50; 51) | ||
47 | NAME_REF@[50; 51) | ||
48 | IDENT@[50; 51) "a" | ||
49 | COLONCOLON@[51; 53) | ||
50 | PATH_SEGMENT@[53; 58) | ||
51 | SUPER_KW@[53; 58) | ||
52 | COLONCOLON@[58; 60) | ||
53 | PATH_SEGMENT@[60; 63) | ||
54 | NAME_REF@[60; 63) | ||
55 | IDENT@[60; 63) "bar" | ||
56 | SEMI@[63; 64) | ||
57 | WHITESPACE@[64; 65) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.rs b/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.rs new file mode 100644 index 000000000..5e4aa3a33 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | use *; | ||
2 | use ::*; | ||
3 | use ::{}; | ||
4 | use {}; | ||
5 | use foo::*; | ||
6 | use foo::{}; | ||
7 | use ::foo::{a, b, c}; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.txt b/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.txt new file mode 100644 index 000000000..4aa539159 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0014_use_tree.txt | |||
@@ -0,0 +1,95 @@ | |||
1 | ROOT@[0; 81) | ||
2 | USE_ITEM@[0; 6) | ||
3 | USE_KW@[0; 3) | ||
4 | WHITESPACE@[3; 4) | ||
5 | USE_TREE@[4; 5) | ||
6 | STAR@[4; 5) | ||
7 | SEMI@[5; 6) | ||
8 | WHITESPACE@[6; 7) | ||
9 | USE_ITEM@[7; 15) | ||
10 | USE_KW@[7; 10) | ||
11 | WHITESPACE@[10; 11) | ||
12 | USE_TREE@[11; 14) | ||
13 | COLONCOLON@[11; 13) | ||
14 | STAR@[13; 14) | ||
15 | SEMI@[14; 15) | ||
16 | WHITESPACE@[15; 16) | ||
17 | USE_ITEM@[16; 25) | ||
18 | USE_KW@[16; 19) | ||
19 | WHITESPACE@[19; 20) | ||
20 | USE_TREE@[20; 24) | ||
21 | COLONCOLON@[20; 22) | ||
22 | USE_TREE_LIST@[22; 24) | ||
23 | L_CURLY@[22; 23) | ||
24 | R_CURLY@[23; 24) | ||
25 | SEMI@[24; 25) | ||
26 | WHITESPACE@[25; 26) | ||
27 | USE_ITEM@[26; 33) | ||
28 | USE_KW@[26; 29) | ||
29 | WHITESPACE@[29; 30) | ||
30 | USE_TREE@[30; 32) | ||
31 | USE_TREE_LIST@[30; 32) | ||
32 | L_CURLY@[30; 31) | ||
33 | R_CURLY@[31; 32) | ||
34 | SEMI@[32; 33) | ||
35 | WHITESPACE@[33; 34) | ||
36 | USE_ITEM@[34; 45) | ||
37 | USE_KW@[34; 37) | ||
38 | WHITESPACE@[37; 38) | ||
39 | USE_TREE@[38; 44) | ||
40 | PATH@[38; 41) | ||
41 | PATH_SEGMENT@[38; 41) | ||
42 | NAME_REF@[38; 41) | ||
43 | IDENT@[38; 41) "foo" | ||
44 | COLONCOLON@[41; 43) | ||
45 | STAR@[43; 44) | ||
46 | SEMI@[44; 45) | ||
47 | WHITESPACE@[45; 46) | ||
48 | USE_ITEM@[46; 58) | ||
49 | USE_KW@[46; 49) | ||
50 | WHITESPACE@[49; 50) | ||
51 | USE_TREE@[50; 57) | ||
52 | PATH@[50; 53) | ||
53 | PATH_SEGMENT@[50; 53) | ||
54 | NAME_REF@[50; 53) | ||
55 | IDENT@[50; 53) "foo" | ||
56 | COLONCOLON@[53; 55) | ||
57 | USE_TREE_LIST@[55; 57) | ||
58 | L_CURLY@[55; 56) | ||
59 | R_CURLY@[56; 57) | ||
60 | SEMI@[57; 58) | ||
61 | WHITESPACE@[58; 59) | ||
62 | USE_ITEM@[59; 80) | ||
63 | USE_KW@[59; 62) | ||
64 | WHITESPACE@[62; 63) | ||
65 | USE_TREE@[63; 79) | ||
66 | PATH@[63; 68) | ||
67 | PATH_SEGMENT@[63; 68) | ||
68 | COLONCOLON@[63; 65) | ||
69 | NAME_REF@[65; 68) | ||
70 | IDENT@[65; 68) "foo" | ||
71 | COLONCOLON@[68; 70) | ||
72 | USE_TREE_LIST@[70; 79) | ||
73 | L_CURLY@[70; 71) | ||
74 | USE_TREE@[71; 72) | ||
75 | PATH@[71; 72) | ||
76 | PATH_SEGMENT@[71; 72) | ||
77 | NAME_REF@[71; 72) | ||
78 | IDENT@[71; 72) "a" | ||
79 | COMMA@[72; 73) | ||
80 | WHITESPACE@[73; 74) | ||
81 | USE_TREE@[74; 75) | ||
82 | PATH@[74; 75) | ||
83 | PATH_SEGMENT@[74; 75) | ||
84 | NAME_REF@[74; 75) | ||
85 | IDENT@[74; 75) "b" | ||
86 | COMMA@[75; 76) | ||
87 | WHITESPACE@[76; 77) | ||
88 | USE_TREE@[77; 78) | ||
89 | PATH@[77; 78) | ||
90 | PATH_SEGMENT@[77; 78) | ||
91 | NAME_REF@[77; 78) | ||
92 | IDENT@[77; 78) "c" | ||
93 | R_CURLY@[78; 79) | ||
94 | SEMI@[79; 80) | ||
95 | WHITESPACE@[80; 81) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.rs b/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.rs new file mode 100644 index 000000000..46a0783a2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | use foo as bar; | ||
2 | use foo::{a as b, *, ::*, ::foo as x}; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.txt b/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.txt new file mode 100644 index 000000000..aa4ef3715 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0015_use_tree.txt | |||
@@ -0,0 +1,65 @@ | |||
1 | ROOT@[0; 55) | ||
2 | USE_ITEM@[0; 15) | ||
3 | USE_KW@[0; 3) | ||
4 | WHITESPACE@[3; 4) | ||
5 | USE_TREE@[4; 14) | ||
6 | PATH@[4; 7) | ||
7 | PATH_SEGMENT@[4; 7) | ||
8 | NAME_REF@[4; 7) | ||
9 | IDENT@[4; 7) "foo" | ||
10 | WHITESPACE@[7; 8) | ||
11 | ALIAS@[8; 14) | ||
12 | AS_KW@[8; 10) | ||
13 | WHITESPACE@[10; 11) | ||
14 | NAME@[11; 14) | ||
15 | IDENT@[11; 14) "bar" | ||
16 | SEMI@[14; 15) | ||
17 | WHITESPACE@[15; 16) | ||
18 | USE_ITEM@[16; 54) | ||
19 | USE_KW@[16; 19) | ||
20 | WHITESPACE@[19; 20) | ||
21 | USE_TREE@[20; 53) | ||
22 | PATH@[20; 23) | ||
23 | PATH_SEGMENT@[20; 23) | ||
24 | NAME_REF@[20; 23) | ||
25 | IDENT@[20; 23) "foo" | ||
26 | COLONCOLON@[23; 25) | ||
27 | USE_TREE_LIST@[25; 53) | ||
28 | L_CURLY@[25; 26) | ||
29 | USE_TREE@[26; 32) | ||
30 | PATH@[26; 27) | ||
31 | PATH_SEGMENT@[26; 27) | ||
32 | NAME_REF@[26; 27) | ||
33 | IDENT@[26; 27) "a" | ||
34 | WHITESPACE@[27; 28) | ||
35 | ALIAS@[28; 32) | ||
36 | AS_KW@[28; 30) | ||
37 | WHITESPACE@[30; 31) | ||
38 | NAME@[31; 32) | ||
39 | IDENT@[31; 32) "b" | ||
40 | COMMA@[32; 33) | ||
41 | WHITESPACE@[33; 34) | ||
42 | USE_TREE@[34; 35) | ||
43 | STAR@[34; 35) | ||
44 | COMMA@[35; 36) | ||
45 | WHITESPACE@[36; 37) | ||
46 | USE_TREE@[37; 40) | ||
47 | COLONCOLON@[37; 39) | ||
48 | STAR@[39; 40) | ||
49 | COMMA@[40; 41) | ||
50 | WHITESPACE@[41; 42) | ||
51 | USE_TREE@[42; 52) | ||
52 | PATH@[42; 47) | ||
53 | PATH_SEGMENT@[42; 47) | ||
54 | COLONCOLON@[42; 44) | ||
55 | NAME_REF@[44; 47) | ||
56 | IDENT@[44; 47) "foo" | ||
57 | WHITESPACE@[47; 48) | ||
58 | ALIAS@[48; 52) | ||
59 | AS_KW@[48; 50) | ||
60 | WHITESPACE@[50; 51) | ||
61 | NAME@[51; 52) | ||
62 | IDENT@[51; 52) "x" | ||
63 | R_CURLY@[52; 53) | ||
64 | SEMI@[53; 54) | ||
65 | WHITESPACE@[54; 55) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.rs b/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.rs new file mode 100644 index 000000000..69638350c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.rs | |||
@@ -0,0 +1,10 @@ | |||
1 | struct A; | ||
2 | struct B {} | ||
3 | struct C(); | ||
4 | |||
5 | struct D { | ||
6 | a: u32, | ||
7 | pub b: u32 | ||
8 | } | ||
9 | |||
10 | struct E(pub x, y,); | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.txt b/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.txt new file mode 100644 index 000000000..349481157 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0016_struct_flavors.txt | |||
@@ -0,0 +1,93 @@ | |||
1 | ROOT@[0; 97) | ||
2 | STRUCT_DEF@[0; 9) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "A" | ||
7 | SEMI@[8; 9) | ||
8 | WHITESPACE@[9; 10) | ||
9 | STRUCT_DEF@[10; 21) | ||
10 | STRUCT_KW@[10; 16) | ||
11 | WHITESPACE@[16; 17) | ||
12 | NAME@[17; 18) | ||
13 | IDENT@[17; 18) "B" | ||
14 | WHITESPACE@[18; 19) | ||
15 | NAMED_FIELD_DEF_LIST@[19; 21) | ||
16 | L_CURLY@[19; 20) | ||
17 | R_CURLY@[20; 21) | ||
18 | WHITESPACE@[21; 22) | ||
19 | STRUCT_DEF@[22; 33) | ||
20 | STRUCT_KW@[22; 28) | ||
21 | WHITESPACE@[28; 29) | ||
22 | NAME@[29; 30) | ||
23 | IDENT@[29; 30) "C" | ||
24 | POS_FIELD_LIST@[30; 32) | ||
25 | L_PAREN@[30; 31) | ||
26 | R_PAREN@[31; 32) | ||
27 | SEMI@[32; 33) | ||
28 | WHITESPACE@[33; 35) | ||
29 | STRUCT_DEF@[35; 74) | ||
30 | STRUCT_KW@[35; 41) | ||
31 | WHITESPACE@[41; 42) | ||
32 | NAME@[42; 43) | ||
33 | IDENT@[42; 43) "D" | ||
34 | WHITESPACE@[43; 44) | ||
35 | NAMED_FIELD_DEF_LIST@[44; 74) | ||
36 | L_CURLY@[44; 45) | ||
37 | WHITESPACE@[45; 50) | ||
38 | NAMED_FIELD_DEF@[50; 56) | ||
39 | NAME@[50; 51) | ||
40 | IDENT@[50; 51) "a" | ||
41 | COLON@[51; 52) | ||
42 | WHITESPACE@[52; 53) | ||
43 | PATH_TYPE@[53; 56) | ||
44 | PATH@[53; 56) | ||
45 | PATH_SEGMENT@[53; 56) | ||
46 | NAME_REF@[53; 56) | ||
47 | IDENT@[53; 56) "u32" | ||
48 | COMMA@[56; 57) | ||
49 | WHITESPACE@[57; 62) | ||
50 | NAMED_FIELD_DEF@[62; 72) | ||
51 | VISIBILITY@[62; 65) | ||
52 | PUB_KW@[62; 65) | ||
53 | WHITESPACE@[65; 66) | ||
54 | NAME@[66; 67) | ||
55 | IDENT@[66; 67) "b" | ||
56 | COLON@[67; 68) | ||
57 | WHITESPACE@[68; 69) | ||
58 | PATH_TYPE@[69; 72) | ||
59 | PATH@[69; 72) | ||
60 | PATH_SEGMENT@[69; 72) | ||
61 | NAME_REF@[69; 72) | ||
62 | IDENT@[69; 72) "u32" | ||
63 | WHITESPACE@[72; 73) | ||
64 | R_CURLY@[73; 74) | ||
65 | WHITESPACE@[74; 76) | ||
66 | STRUCT_DEF@[76; 96) | ||
67 | STRUCT_KW@[76; 82) | ||
68 | WHITESPACE@[82; 83) | ||
69 | NAME@[83; 84) | ||
70 | IDENT@[83; 84) "E" | ||
71 | POS_FIELD_LIST@[84; 95) | ||
72 | L_PAREN@[84; 85) | ||
73 | POS_FIELD@[85; 90) | ||
74 | VISIBILITY@[85; 88) | ||
75 | PUB_KW@[85; 88) | ||
76 | WHITESPACE@[88; 89) | ||
77 | PATH_TYPE@[89; 90) | ||
78 | PATH@[89; 90) | ||
79 | PATH_SEGMENT@[89; 90) | ||
80 | NAME_REF@[89; 90) | ||
81 | IDENT@[89; 90) "x" | ||
82 | COMMA@[90; 91) | ||
83 | WHITESPACE@[91; 92) | ||
84 | POS_FIELD@[92; 93) | ||
85 | PATH_TYPE@[92; 93) | ||
86 | PATH@[92; 93) | ||
87 | PATH_SEGMENT@[92; 93) | ||
88 | NAME_REF@[92; 93) | ||
89 | IDENT@[92; 93) "y" | ||
90 | COMMA@[93; 94) | ||
91 | R_PAREN@[94; 95) | ||
92 | SEMI@[95; 96) | ||
93 | WHITESPACE@[96; 97) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.rs b/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.rs new file mode 100644 index 000000000..fe0a7bb97 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | #[foo(a,)] | ||
2 | fn foo() {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.txt b/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.txt new file mode 100644 index 000000000..8cfd77256 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0017_attr_trailing_comma.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | ROOT@[0; 23) | ||
2 | FN_DEF@[0; 22) | ||
3 | ATTR@[0; 10) | ||
4 | POUND@[0; 1) | ||
5 | TOKEN_TREE@[1; 10) | ||
6 | L_BRACK@[1; 2) | ||
7 | IDENT@[2; 5) "foo" | ||
8 | TOKEN_TREE@[5; 9) | ||
9 | L_PAREN@[5; 6) | ||
10 | IDENT@[6; 7) "a" | ||
11 | COMMA@[7; 8) | ||
12 | R_PAREN@[8; 9) | ||
13 | R_BRACK@[9; 10) | ||
14 | WHITESPACE@[10; 11) | ||
15 | FN_KW@[11; 13) | ||
16 | WHITESPACE@[13; 14) | ||
17 | NAME@[14; 17) | ||
18 | IDENT@[14; 17) "foo" | ||
19 | PARAM_LIST@[17; 19) | ||
20 | L_PAREN@[17; 18) | ||
21 | R_PAREN@[18; 19) | ||
22 | WHITESPACE@[19; 20) | ||
23 | BLOCK@[20; 22) | ||
24 | L_CURLY@[20; 21) | ||
25 | R_CURLY@[21; 22) | ||
26 | WHITESPACE@[22; 23) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.rs b/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.rs new file mode 100644 index 000000000..88c544923 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.rs | |||
@@ -0,0 +1,17 @@ | |||
1 | struct S1<T>; | ||
2 | struct S2<T>(u32); | ||
3 | struct S3<T> { u: u32 } | ||
4 | |||
5 | struct S4<>; | ||
6 | struct S5<'a>; | ||
7 | struct S6<'a:>; | ||
8 | struct S7<'a: 'b>; | ||
9 | struct S8<'a: 'b + >; | ||
10 | struct S9<'a: 'b + 'c>; | ||
11 | struct S10<'a,>; | ||
12 | struct S11<'a, 'b>; | ||
13 | struct S12<'a: 'b+, 'b: 'c,>; | ||
14 | |||
15 | struct S13<T>; | ||
16 | struct S14<T, U>; | ||
17 | struct S15<'a, T, U>; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.txt b/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.txt new file mode 100644 index 000000000..a98e823f6 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0018_struct_type_params.txt | |||
@@ -0,0 +1,257 @@ | |||
1 | ROOT@[0; 290) | ||
2 | STRUCT_DEF@[0; 13) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 9) | ||
6 | IDENT@[7; 9) "S1" | ||
7 | TYPE_PARAM_LIST@[9; 12) | ||
8 | L_ANGLE@[9; 10) | ||
9 | TYPE_PARAM@[10; 11) | ||
10 | NAME@[10; 11) | ||
11 | IDENT@[10; 11) "T" | ||
12 | R_ANGLE@[11; 12) | ||
13 | SEMI@[12; 13) | ||
14 | WHITESPACE@[13; 14) | ||
15 | STRUCT_DEF@[14; 32) | ||
16 | STRUCT_KW@[14; 20) | ||
17 | WHITESPACE@[20; 21) | ||
18 | NAME@[21; 23) | ||
19 | IDENT@[21; 23) "S2" | ||
20 | TYPE_PARAM_LIST@[23; 26) | ||
21 | L_ANGLE@[23; 24) | ||
22 | TYPE_PARAM@[24; 25) | ||
23 | NAME@[24; 25) | ||
24 | IDENT@[24; 25) "T" | ||
25 | R_ANGLE@[25; 26) | ||
26 | POS_FIELD_LIST@[26; 31) | ||
27 | L_PAREN@[26; 27) | ||
28 | POS_FIELD@[27; 30) | ||
29 | PATH_TYPE@[27; 30) | ||
30 | PATH@[27; 30) | ||
31 | PATH_SEGMENT@[27; 30) | ||
32 | NAME_REF@[27; 30) | ||
33 | IDENT@[27; 30) "u32" | ||
34 | R_PAREN@[30; 31) | ||
35 | SEMI@[31; 32) | ||
36 | WHITESPACE@[32; 33) | ||
37 | STRUCT_DEF@[33; 56) | ||
38 | STRUCT_KW@[33; 39) | ||
39 | WHITESPACE@[39; 40) | ||
40 | NAME@[40; 42) | ||
41 | IDENT@[40; 42) "S3" | ||
42 | TYPE_PARAM_LIST@[42; 45) | ||
43 | L_ANGLE@[42; 43) | ||
44 | TYPE_PARAM@[43; 44) | ||
45 | NAME@[43; 44) | ||
46 | IDENT@[43; 44) "T" | ||
47 | R_ANGLE@[44; 45) | ||
48 | WHITESPACE@[45; 46) | ||
49 | NAMED_FIELD_DEF_LIST@[46; 56) | ||
50 | L_CURLY@[46; 47) | ||
51 | WHITESPACE@[47; 48) | ||
52 | NAMED_FIELD_DEF@[48; 54) | ||
53 | NAME@[48; 49) | ||
54 | IDENT@[48; 49) "u" | ||
55 | COLON@[49; 50) | ||
56 | WHITESPACE@[50; 51) | ||
57 | PATH_TYPE@[51; 54) | ||
58 | PATH@[51; 54) | ||
59 | PATH_SEGMENT@[51; 54) | ||
60 | NAME_REF@[51; 54) | ||
61 | IDENT@[51; 54) "u32" | ||
62 | WHITESPACE@[54; 55) | ||
63 | R_CURLY@[55; 56) | ||
64 | WHITESPACE@[56; 58) | ||
65 | STRUCT_DEF@[58; 70) | ||
66 | STRUCT_KW@[58; 64) | ||
67 | WHITESPACE@[64; 65) | ||
68 | NAME@[65; 67) | ||
69 | IDENT@[65; 67) "S4" | ||
70 | TYPE_PARAM_LIST@[67; 69) | ||
71 | L_ANGLE@[67; 68) | ||
72 | R_ANGLE@[68; 69) | ||
73 | SEMI@[69; 70) | ||
74 | WHITESPACE@[70; 71) | ||
75 | STRUCT_DEF@[71; 85) | ||
76 | STRUCT_KW@[71; 77) | ||
77 | WHITESPACE@[77; 78) | ||
78 | NAME@[78; 80) | ||
79 | IDENT@[78; 80) "S5" | ||
80 | TYPE_PARAM_LIST@[80; 84) | ||
81 | L_ANGLE@[80; 81) | ||
82 | LIFETIME_PARAM@[81; 83) | ||
83 | LIFETIME@[81; 83) "'a" | ||
84 | R_ANGLE@[83; 84) | ||
85 | SEMI@[84; 85) | ||
86 | WHITESPACE@[85; 86) | ||
87 | STRUCT_DEF@[86; 101) | ||
88 | STRUCT_KW@[86; 92) | ||
89 | WHITESPACE@[92; 93) | ||
90 | NAME@[93; 95) | ||
91 | IDENT@[93; 95) "S6" | ||
92 | TYPE_PARAM_LIST@[95; 100) | ||
93 | L_ANGLE@[95; 96) | ||
94 | LIFETIME_PARAM@[96; 99) | ||
95 | LIFETIME@[96; 98) "'a" | ||
96 | COLON@[98; 99) | ||
97 | R_ANGLE@[99; 100) | ||
98 | SEMI@[100; 101) | ||
99 | WHITESPACE@[101; 102) | ||
100 | STRUCT_DEF@[102; 120) | ||
101 | STRUCT_KW@[102; 108) | ||
102 | WHITESPACE@[108; 109) | ||
103 | NAME@[109; 111) | ||
104 | IDENT@[109; 111) "S7" | ||
105 | TYPE_PARAM_LIST@[111; 119) | ||
106 | L_ANGLE@[111; 112) | ||
107 | LIFETIME_PARAM@[112; 118) | ||
108 | LIFETIME@[112; 114) "'a" | ||
109 | COLON@[114; 115) | ||
110 | WHITESPACE@[115; 116) | ||
111 | LIFETIME@[116; 118) "'b" | ||
112 | R_ANGLE@[118; 119) | ||
113 | SEMI@[119; 120) | ||
114 | WHITESPACE@[120; 121) | ||
115 | STRUCT_DEF@[121; 142) | ||
116 | STRUCT_KW@[121; 127) | ||
117 | WHITESPACE@[127; 128) | ||
118 | NAME@[128; 130) | ||
119 | IDENT@[128; 130) "S8" | ||
120 | TYPE_PARAM_LIST@[130; 141) | ||
121 | L_ANGLE@[130; 131) | ||
122 | LIFETIME_PARAM@[131; 139) | ||
123 | LIFETIME@[131; 133) "'a" | ||
124 | COLON@[133; 134) | ||
125 | WHITESPACE@[134; 135) | ||
126 | LIFETIME@[135; 137) "'b" | ||
127 | WHITESPACE@[137; 138) | ||
128 | PLUS@[138; 139) | ||
129 | WHITESPACE@[139; 140) | ||
130 | R_ANGLE@[140; 141) | ||
131 | SEMI@[141; 142) | ||
132 | WHITESPACE@[142; 143) | ||
133 | STRUCT_DEF@[143; 166) | ||
134 | STRUCT_KW@[143; 149) | ||
135 | WHITESPACE@[149; 150) | ||
136 | NAME@[150; 152) | ||
137 | IDENT@[150; 152) "S9" | ||
138 | TYPE_PARAM_LIST@[152; 165) | ||
139 | L_ANGLE@[152; 153) | ||
140 | LIFETIME_PARAM@[153; 164) | ||
141 | LIFETIME@[153; 155) "'a" | ||
142 | COLON@[155; 156) | ||
143 | WHITESPACE@[156; 157) | ||
144 | LIFETIME@[157; 159) "'b" | ||
145 | WHITESPACE@[159; 160) | ||
146 | PLUS@[160; 161) | ||
147 | WHITESPACE@[161; 162) | ||
148 | LIFETIME@[162; 164) "'c" | ||
149 | R_ANGLE@[164; 165) | ||
150 | SEMI@[165; 166) | ||
151 | WHITESPACE@[166; 167) | ||
152 | STRUCT_DEF@[167; 183) | ||
153 | STRUCT_KW@[167; 173) | ||
154 | WHITESPACE@[173; 174) | ||
155 | NAME@[174; 177) | ||
156 | IDENT@[174; 177) "S10" | ||
157 | TYPE_PARAM_LIST@[177; 182) | ||
158 | L_ANGLE@[177; 178) | ||
159 | LIFETIME_PARAM@[178; 180) | ||
160 | LIFETIME@[178; 180) "'a" | ||
161 | COMMA@[180; 181) | ||
162 | R_ANGLE@[181; 182) | ||
163 | SEMI@[182; 183) | ||
164 | WHITESPACE@[183; 184) | ||
165 | STRUCT_DEF@[184; 203) | ||
166 | STRUCT_KW@[184; 190) | ||
167 | WHITESPACE@[190; 191) | ||
168 | NAME@[191; 194) | ||
169 | IDENT@[191; 194) "S11" | ||
170 | TYPE_PARAM_LIST@[194; 202) | ||
171 | L_ANGLE@[194; 195) | ||
172 | LIFETIME_PARAM@[195; 197) | ||
173 | LIFETIME@[195; 197) "'a" | ||
174 | COMMA@[197; 198) | ||
175 | WHITESPACE@[198; 199) | ||
176 | LIFETIME_PARAM@[199; 201) | ||
177 | LIFETIME@[199; 201) "'b" | ||
178 | R_ANGLE@[201; 202) | ||
179 | SEMI@[202; 203) | ||
180 | WHITESPACE@[203; 204) | ||
181 | STRUCT_DEF@[204; 233) | ||
182 | STRUCT_KW@[204; 210) | ||
183 | WHITESPACE@[210; 211) | ||
184 | NAME@[211; 214) | ||
185 | IDENT@[211; 214) "S12" | ||
186 | TYPE_PARAM_LIST@[214; 232) | ||
187 | L_ANGLE@[214; 215) | ||
188 | LIFETIME_PARAM@[215; 222) | ||
189 | LIFETIME@[215; 217) "'a" | ||
190 | COLON@[217; 218) | ||
191 | WHITESPACE@[218; 219) | ||
192 | LIFETIME@[219; 221) "'b" | ||
193 | PLUS@[221; 222) | ||
194 | COMMA@[222; 223) | ||
195 | WHITESPACE@[223; 224) | ||
196 | LIFETIME_PARAM@[224; 230) | ||
197 | LIFETIME@[224; 226) "'b" | ||
198 | COLON@[226; 227) | ||
199 | WHITESPACE@[227; 228) | ||
200 | LIFETIME@[228; 230) "'c" | ||
201 | COMMA@[230; 231) | ||
202 | R_ANGLE@[231; 232) | ||
203 | SEMI@[232; 233) | ||
204 | WHITESPACE@[233; 235) | ||
205 | STRUCT_DEF@[235; 249) | ||
206 | STRUCT_KW@[235; 241) | ||
207 | WHITESPACE@[241; 242) | ||
208 | NAME@[242; 245) | ||
209 | IDENT@[242; 245) "S13" | ||
210 | TYPE_PARAM_LIST@[245; 248) | ||
211 | L_ANGLE@[245; 246) | ||
212 | TYPE_PARAM@[246; 247) | ||
213 | NAME@[246; 247) | ||
214 | IDENT@[246; 247) "T" | ||
215 | R_ANGLE@[247; 248) | ||
216 | SEMI@[248; 249) | ||
217 | WHITESPACE@[249; 250) | ||
218 | STRUCT_DEF@[250; 267) | ||
219 | STRUCT_KW@[250; 256) | ||
220 | WHITESPACE@[256; 257) | ||
221 | NAME@[257; 260) | ||
222 | IDENT@[257; 260) "S14" | ||
223 | TYPE_PARAM_LIST@[260; 266) | ||
224 | L_ANGLE@[260; 261) | ||
225 | TYPE_PARAM@[261; 262) | ||
226 | NAME@[261; 262) | ||
227 | IDENT@[261; 262) "T" | ||
228 | COMMA@[262; 263) | ||
229 | WHITESPACE@[263; 264) | ||
230 | TYPE_PARAM@[264; 265) | ||
231 | NAME@[264; 265) | ||
232 | IDENT@[264; 265) "U" | ||
233 | R_ANGLE@[265; 266) | ||
234 | SEMI@[266; 267) | ||
235 | WHITESPACE@[267; 268) | ||
236 | STRUCT_DEF@[268; 289) | ||
237 | STRUCT_KW@[268; 274) | ||
238 | WHITESPACE@[274; 275) | ||
239 | NAME@[275; 278) | ||
240 | IDENT@[275; 278) "S15" | ||
241 | TYPE_PARAM_LIST@[278; 288) | ||
242 | L_ANGLE@[278; 279) | ||
243 | LIFETIME_PARAM@[279; 281) | ||
244 | LIFETIME@[279; 281) "'a" | ||
245 | COMMA@[281; 282) | ||
246 | WHITESPACE@[282; 283) | ||
247 | TYPE_PARAM@[283; 284) | ||
248 | NAME@[283; 284) | ||
249 | IDENT@[283; 284) "T" | ||
250 | COMMA@[284; 285) | ||
251 | WHITESPACE@[285; 286) | ||
252 | TYPE_PARAM@[286; 287) | ||
253 | NAME@[286; 287) | ||
254 | IDENT@[286; 287) "U" | ||
255 | R_ANGLE@[287; 288) | ||
256 | SEMI@[288; 289) | ||
257 | WHITESPACE@[289; 290) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0019_enums.rs b/crates/ra_syntax/tests/data/parser/ok/0019_enums.rs new file mode 100644 index 000000000..7a1afa0e6 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0019_enums.rs | |||
@@ -0,0 +1,25 @@ | |||
1 | enum E1 { | ||
2 | } | ||
3 | |||
4 | enum E2<T> { | ||
5 | } | ||
6 | |||
7 | enum E3 { | ||
8 | X | ||
9 | } | ||
10 | |||
11 | enum E4 { | ||
12 | X, | ||
13 | } | ||
14 | |||
15 | enum E5 { | ||
16 | A, | ||
17 | B = 92, | ||
18 | C { | ||
19 | a: u32, | ||
20 | pub b: f64, | ||
21 | }, | ||
22 | F {}, | ||
23 | D(u32,), | ||
24 | E(), | ||
25 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0019_enums.txt b/crates/ra_syntax/tests/data/parser/ok/0019_enums.txt new file mode 100644 index 000000000..6333e47c5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0019_enums.txt | |||
@@ -0,0 +1,155 @@ | |||
1 | ROOT@[0; 182) | ||
2 | ENUM_DEF@[0; 11) | ||
3 | ENUM_KW@[0; 4) | ||
4 | WHITESPACE@[4; 5) | ||
5 | NAME@[5; 7) | ||
6 | IDENT@[5; 7) "E1" | ||
7 | WHITESPACE@[7; 8) | ||
8 | ENUM_VARIANT_LIST@[8; 11) | ||
9 | L_CURLY@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | R_CURLY@[10; 11) | ||
12 | WHITESPACE@[11; 13) | ||
13 | ENUM_DEF@[13; 27) | ||
14 | ENUM_KW@[13; 17) | ||
15 | WHITESPACE@[17; 18) | ||
16 | NAME@[18; 20) | ||
17 | IDENT@[18; 20) "E2" | ||
18 | TYPE_PARAM_LIST@[20; 23) | ||
19 | L_ANGLE@[20; 21) | ||
20 | TYPE_PARAM@[21; 22) | ||
21 | NAME@[21; 22) | ||
22 | IDENT@[21; 22) "T" | ||
23 | R_ANGLE@[22; 23) | ||
24 | WHITESPACE@[23; 24) | ||
25 | ENUM_VARIANT_LIST@[24; 27) | ||
26 | L_CURLY@[24; 25) | ||
27 | WHITESPACE@[25; 26) | ||
28 | R_CURLY@[26; 27) | ||
29 | WHITESPACE@[27; 29) | ||
30 | ENUM_DEF@[29; 46) | ||
31 | ENUM_KW@[29; 33) | ||
32 | WHITESPACE@[33; 34) | ||
33 | NAME@[34; 36) | ||
34 | IDENT@[34; 36) "E3" | ||
35 | WHITESPACE@[36; 37) | ||
36 | ENUM_VARIANT_LIST@[37; 46) | ||
37 | L_CURLY@[37; 38) | ||
38 | WHITESPACE@[38; 43) | ||
39 | ENUM_VARIANT@[43; 44) | ||
40 | NAME@[43; 44) | ||
41 | IDENT@[43; 44) "X" | ||
42 | WHITESPACE@[44; 45) | ||
43 | R_CURLY@[45; 46) | ||
44 | WHITESPACE@[46; 48) | ||
45 | ENUM_DEF@[48; 66) | ||
46 | ENUM_KW@[48; 52) | ||
47 | WHITESPACE@[52; 53) | ||
48 | NAME@[53; 55) | ||
49 | IDENT@[53; 55) "E4" | ||
50 | WHITESPACE@[55; 56) | ||
51 | ENUM_VARIANT_LIST@[56; 66) | ||
52 | L_CURLY@[56; 57) | ||
53 | WHITESPACE@[57; 62) | ||
54 | ENUM_VARIANT@[62; 63) | ||
55 | NAME@[62; 63) | ||
56 | IDENT@[62; 63) "X" | ||
57 | COMMA@[63; 64) | ||
58 | WHITESPACE@[64; 65) | ||
59 | R_CURLY@[65; 66) | ||
60 | WHITESPACE@[66; 68) | ||
61 | ENUM_DEF@[68; 181) | ||
62 | ENUM_KW@[68; 72) | ||
63 | WHITESPACE@[72; 73) | ||
64 | NAME@[73; 75) | ||
65 | IDENT@[73; 75) "E5" | ||
66 | WHITESPACE@[75; 76) | ||
67 | ENUM_VARIANT_LIST@[76; 181) | ||
68 | L_CURLY@[76; 77) | ||
69 | WHITESPACE@[77; 82) | ||
70 | ENUM_VARIANT@[82; 83) | ||
71 | NAME@[82; 83) | ||
72 | IDENT@[82; 83) "A" | ||
73 | COMMA@[83; 84) | ||
74 | WHITESPACE@[84; 89) | ||
75 | ENUM_VARIANT@[89; 95) | ||
76 | NAME@[89; 90) | ||
77 | IDENT@[89; 90) "B" | ||
78 | WHITESPACE@[90; 91) | ||
79 | EQ@[91; 92) | ||
80 | WHITESPACE@[92; 93) | ||
81 | LITERAL@[93; 95) | ||
82 | INT_NUMBER@[93; 95) "92" | ||
83 | COMMA@[95; 96) | ||
84 | WHITESPACE@[96; 101) | ||
85 | ENUM_VARIANT@[101; 146) | ||
86 | NAME@[101; 102) | ||
87 | IDENT@[101; 102) "C" | ||
88 | WHITESPACE@[102; 103) | ||
89 | NAMED_FIELD_DEF_LIST@[103; 146) | ||
90 | L_CURLY@[103; 104) | ||
91 | WHITESPACE@[104; 113) | ||
92 | NAMED_FIELD_DEF@[113; 119) | ||
93 | NAME@[113; 114) | ||
94 | IDENT@[113; 114) "a" | ||
95 | COLON@[114; 115) | ||
96 | WHITESPACE@[115; 116) | ||
97 | PATH_TYPE@[116; 119) | ||
98 | PATH@[116; 119) | ||
99 | PATH_SEGMENT@[116; 119) | ||
100 | NAME_REF@[116; 119) | ||
101 | IDENT@[116; 119) "u32" | ||
102 | COMMA@[119; 120) | ||
103 | WHITESPACE@[120; 129) | ||
104 | NAMED_FIELD_DEF@[129; 139) | ||
105 | VISIBILITY@[129; 132) | ||
106 | PUB_KW@[129; 132) | ||
107 | WHITESPACE@[132; 133) | ||
108 | NAME@[133; 134) | ||
109 | IDENT@[133; 134) "b" | ||
110 | COLON@[134; 135) | ||
111 | WHITESPACE@[135; 136) | ||
112 | PATH_TYPE@[136; 139) | ||
113 | PATH@[136; 139) | ||
114 | PATH_SEGMENT@[136; 139) | ||
115 | NAME_REF@[136; 139) | ||
116 | IDENT@[136; 139) "f64" | ||
117 | COMMA@[139; 140) | ||
118 | WHITESPACE@[140; 145) | ||
119 | R_CURLY@[145; 146) | ||
120 | COMMA@[146; 147) | ||
121 | WHITESPACE@[147; 152) | ||
122 | ENUM_VARIANT@[152; 156) | ||
123 | NAME@[152; 153) | ||
124 | IDENT@[152; 153) "F" | ||
125 | WHITESPACE@[153; 154) | ||
126 | NAMED_FIELD_DEF_LIST@[154; 156) | ||
127 | L_CURLY@[154; 155) | ||
128 | R_CURLY@[155; 156) | ||
129 | COMMA@[156; 157) | ||
130 | WHITESPACE@[157; 162) | ||
131 | ENUM_VARIANT@[162; 169) | ||
132 | NAME@[162; 163) | ||
133 | IDENT@[162; 163) "D" | ||
134 | POS_FIELD_LIST@[163; 169) | ||
135 | L_PAREN@[163; 164) | ||
136 | POS_FIELD@[164; 167) | ||
137 | PATH_TYPE@[164; 167) | ||
138 | PATH@[164; 167) | ||
139 | PATH_SEGMENT@[164; 167) | ||
140 | NAME_REF@[164; 167) | ||
141 | IDENT@[164; 167) "u32" | ||
142 | COMMA@[167; 168) | ||
143 | R_PAREN@[168; 169) | ||
144 | COMMA@[169; 170) | ||
145 | WHITESPACE@[170; 175) | ||
146 | ENUM_VARIANT@[175; 178) | ||
147 | NAME@[175; 176) | ||
148 | IDENT@[175; 176) "E" | ||
149 | POS_FIELD_LIST@[176; 178) | ||
150 | L_PAREN@[176; 177) | ||
151 | R_PAREN@[177; 178) | ||
152 | COMMA@[178; 179) | ||
153 | WHITESPACE@[179; 180) | ||
154 | R_CURLY@[180; 181) | ||
155 | WHITESPACE@[181; 182) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.rs b/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.rs new file mode 100644 index 000000000..a1b9f00a4 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.rs | |||
@@ -0,0 +1,9 @@ | |||
1 | struct A<T>; | ||
2 | struct B<T:>; | ||
3 | struct C<T: 'a>; | ||
4 | struct D<T: 'a + >; | ||
5 | struct E<T: 'a + 'd >; | ||
6 | struct F<T: 'a + 'd + Clone>; | ||
7 | struct G<T: Clone + Copy>; | ||
8 | struct H<T: ::Foo + self::Bar + 'a>; | ||
9 | struct I<T:, U:,>; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.txt b/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.txt new file mode 100644 index 000000000..ac1a58e9a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0020_type_param_bounds.txt | |||
@@ -0,0 +1,198 @@ | |||
1 | ROOT@[0; 200) | ||
2 | STRUCT_DEF@[0; 12) | ||
3 | STRUCT_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 8) | ||
6 | IDENT@[7; 8) "A" | ||
7 | TYPE_PARAM_LIST@[8; 11) | ||
8 | L_ANGLE@[8; 9) | ||
9 | TYPE_PARAM@[9; 10) | ||
10 | NAME@[9; 10) | ||
11 | IDENT@[9; 10) "T" | ||
12 | R_ANGLE@[10; 11) | ||
13 | SEMI@[11; 12) | ||
14 | WHITESPACE@[12; 13) | ||
15 | STRUCT_DEF@[13; 26) | ||
16 | STRUCT_KW@[13; 19) | ||
17 | WHITESPACE@[19; 20) | ||
18 | NAME@[20; 21) | ||
19 | IDENT@[20; 21) "B" | ||
20 | TYPE_PARAM_LIST@[21; 25) | ||
21 | L_ANGLE@[21; 22) | ||
22 | TYPE_PARAM@[22; 24) | ||
23 | NAME@[22; 23) | ||
24 | IDENT@[22; 23) "T" | ||
25 | COLON@[23; 24) | ||
26 | R_ANGLE@[24; 25) | ||
27 | SEMI@[25; 26) | ||
28 | WHITESPACE@[26; 27) | ||
29 | STRUCT_DEF@[27; 43) | ||
30 | STRUCT_KW@[27; 33) | ||
31 | WHITESPACE@[33; 34) | ||
32 | NAME@[34; 35) | ||
33 | IDENT@[34; 35) "C" | ||
34 | TYPE_PARAM_LIST@[35; 42) | ||
35 | L_ANGLE@[35; 36) | ||
36 | TYPE_PARAM@[36; 41) | ||
37 | NAME@[36; 37) | ||
38 | IDENT@[36; 37) "T" | ||
39 | COLON@[37; 38) | ||
40 | WHITESPACE@[38; 39) | ||
41 | LIFETIME@[39; 41) "'a" | ||
42 | R_ANGLE@[41; 42) | ||
43 | SEMI@[42; 43) | ||
44 | WHITESPACE@[43; 44) | ||
45 | STRUCT_DEF@[44; 63) | ||
46 | STRUCT_KW@[44; 50) | ||
47 | WHITESPACE@[50; 51) | ||
48 | NAME@[51; 52) | ||
49 | IDENT@[51; 52) "D" | ||
50 | TYPE_PARAM_LIST@[52; 62) | ||
51 | L_ANGLE@[52; 53) | ||
52 | TYPE_PARAM@[53; 60) | ||
53 | NAME@[53; 54) | ||
54 | IDENT@[53; 54) "T" | ||
55 | COLON@[54; 55) | ||
56 | WHITESPACE@[55; 56) | ||
57 | LIFETIME@[56; 58) "'a" | ||
58 | WHITESPACE@[58; 59) | ||
59 | PLUS@[59; 60) | ||
60 | WHITESPACE@[60; 61) | ||
61 | R_ANGLE@[61; 62) | ||
62 | SEMI@[62; 63) | ||
63 | WHITESPACE@[63; 64) | ||
64 | STRUCT_DEF@[64; 86) | ||
65 | STRUCT_KW@[64; 70) | ||
66 | WHITESPACE@[70; 71) | ||
67 | NAME@[71; 72) | ||
68 | IDENT@[71; 72) "E" | ||
69 | TYPE_PARAM_LIST@[72; 85) | ||
70 | L_ANGLE@[72; 73) | ||
71 | TYPE_PARAM@[73; 83) | ||
72 | NAME@[73; 74) | ||
73 | IDENT@[73; 74) "T" | ||
74 | COLON@[74; 75) | ||
75 | WHITESPACE@[75; 76) | ||
76 | LIFETIME@[76; 78) "'a" | ||
77 | WHITESPACE@[78; 79) | ||
78 | PLUS@[79; 80) | ||
79 | WHITESPACE@[80; 81) | ||
80 | LIFETIME@[81; 83) "'d" | ||
81 | WHITESPACE@[83; 84) | ||
82 | R_ANGLE@[84; 85) | ||
83 | SEMI@[85; 86) | ||
84 | WHITESPACE@[86; 87) | ||
85 | STRUCT_DEF@[87; 116) | ||
86 | STRUCT_KW@[87; 93) | ||
87 | WHITESPACE@[93; 94) | ||
88 | NAME@[94; 95) | ||
89 | IDENT@[94; 95) "F" | ||
90 | TYPE_PARAM_LIST@[95; 115) | ||
91 | L_ANGLE@[95; 96) | ||
92 | TYPE_PARAM@[96; 114) | ||
93 | NAME@[96; 97) | ||
94 | IDENT@[96; 97) "T" | ||
95 | COLON@[97; 98) | ||
96 | WHITESPACE@[98; 99) | ||
97 | LIFETIME@[99; 101) "'a" | ||
98 | WHITESPACE@[101; 102) | ||
99 | PLUS@[102; 103) | ||
100 | WHITESPACE@[103; 104) | ||
101 | LIFETIME@[104; 106) "'d" | ||
102 | WHITESPACE@[106; 107) | ||
103 | PLUS@[107; 108) | ||
104 | WHITESPACE@[108; 109) | ||
105 | PATH_TYPE@[109; 114) | ||
106 | PATH@[109; 114) | ||
107 | PATH_SEGMENT@[109; 114) | ||
108 | NAME_REF@[109; 114) | ||
109 | IDENT@[109; 114) "Clone" | ||
110 | R_ANGLE@[114; 115) | ||
111 | SEMI@[115; 116) | ||
112 | WHITESPACE@[116; 117) | ||
113 | STRUCT_DEF@[117; 143) | ||
114 | STRUCT_KW@[117; 123) | ||
115 | WHITESPACE@[123; 124) | ||
116 | NAME@[124; 125) | ||
117 | IDENT@[124; 125) "G" | ||
118 | TYPE_PARAM_LIST@[125; 142) | ||
119 | L_ANGLE@[125; 126) | ||
120 | TYPE_PARAM@[126; 141) | ||
121 | NAME@[126; 127) | ||
122 | IDENT@[126; 127) "T" | ||
123 | COLON@[127; 128) | ||
124 | WHITESPACE@[128; 129) | ||
125 | PATH_TYPE@[129; 141) | ||
126 | PATH@[129; 134) | ||
127 | PATH_SEGMENT@[129; 134) | ||
128 | NAME_REF@[129; 134) | ||
129 | IDENT@[129; 134) "Clone" | ||
130 | WHITESPACE@[134; 135) | ||
131 | PLUS@[135; 136) | ||
132 | WHITESPACE@[136; 137) | ||
133 | PATH_TYPE@[137; 141) | ||
134 | PATH@[137; 141) | ||
135 | PATH_SEGMENT@[137; 141) | ||
136 | NAME_REF@[137; 141) | ||
137 | IDENT@[137; 141) "Copy" | ||
138 | R_ANGLE@[141; 142) | ||
139 | SEMI@[142; 143) | ||
140 | WHITESPACE@[143; 144) | ||
141 | STRUCT_DEF@[144; 180) | ||
142 | STRUCT_KW@[144; 150) | ||
143 | WHITESPACE@[150; 151) | ||
144 | NAME@[151; 152) | ||
145 | IDENT@[151; 152) "H" | ||
146 | TYPE_PARAM_LIST@[152; 179) | ||
147 | L_ANGLE@[152; 153) | ||
148 | TYPE_PARAM@[153; 178) | ||
149 | NAME@[153; 154) | ||
150 | IDENT@[153; 154) "T" | ||
151 | COLON@[154; 155) | ||
152 | WHITESPACE@[155; 156) | ||
153 | PATH_TYPE@[156; 178) | ||
154 | PATH@[156; 161) | ||
155 | PATH_SEGMENT@[156; 161) | ||
156 | COLONCOLON@[156; 158) | ||
157 | NAME_REF@[158; 161) | ||
158 | IDENT@[158; 161) "Foo" | ||
159 | WHITESPACE@[161; 162) | ||
160 | PLUS@[162; 163) | ||
161 | WHITESPACE@[163; 164) | ||
162 | PATH_TYPE@[164; 178) | ||
163 | PATH@[164; 173) | ||
164 | PATH@[164; 168) | ||
165 | PATH_SEGMENT@[164; 168) | ||
166 | SELF_KW@[164; 168) | ||
167 | COLONCOLON@[168; 170) | ||
168 | PATH_SEGMENT@[170; 173) | ||
169 | NAME_REF@[170; 173) | ||
170 | IDENT@[170; 173) "Bar" | ||
171 | WHITESPACE@[173; 174) | ||
172 | PLUS@[174; 175) | ||
173 | WHITESPACE@[175; 176) | ||
174 | LIFETIME@[176; 178) "'a" | ||
175 | R_ANGLE@[178; 179) | ||
176 | SEMI@[179; 180) | ||
177 | WHITESPACE@[180; 181) | ||
178 | STRUCT_DEF@[181; 199) | ||
179 | STRUCT_KW@[181; 187) | ||
180 | WHITESPACE@[187; 188) | ||
181 | NAME@[188; 189) | ||
182 | IDENT@[188; 189) "I" | ||
183 | TYPE_PARAM_LIST@[189; 198) | ||
184 | L_ANGLE@[189; 190) | ||
185 | TYPE_PARAM@[190; 192) | ||
186 | NAME@[190; 191) | ||
187 | IDENT@[190; 191) "T" | ||
188 | COLON@[191; 192) | ||
189 | COMMA@[192; 193) | ||
190 | WHITESPACE@[193; 194) | ||
191 | TYPE_PARAM@[194; 196) | ||
192 | NAME@[194; 195) | ||
193 | IDENT@[194; 195) "U" | ||
194 | COLON@[195; 196) | ||
195 | COMMA@[196; 197) | ||
196 | R_ANGLE@[197; 198) | ||
197 | SEMI@[198; 199) | ||
198 | WHITESPACE@[199; 200) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.rs b/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.rs new file mode 100644 index 000000000..e929eef74 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | extern fn foo() { | ||
2 | } | ||
3 | |||
4 | extern "C" fn bar() { | ||
5 | } | ||
6 | |||
7 | extern r"D" fn baz() { | ||
8 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.txt b/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.txt new file mode 100644 index 000000000..5ceef46e0 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0021_extern_fn.txt | |||
@@ -0,0 +1,56 @@ | |||
1 | ROOT@[0; 71) | ||
2 | FN_DEF@[0; 19) | ||
3 | ABI@[0; 6) | ||
4 | EXTERN_KW@[0; 6) | ||
5 | WHITESPACE@[6; 7) | ||
6 | FN_KW@[7; 9) | ||
7 | WHITESPACE@[9; 10) | ||
8 | NAME@[10; 13) | ||
9 | IDENT@[10; 13) "foo" | ||
10 | PARAM_LIST@[13; 15) | ||
11 | L_PAREN@[13; 14) | ||
12 | R_PAREN@[14; 15) | ||
13 | WHITESPACE@[15; 16) | ||
14 | BLOCK@[16; 19) | ||
15 | L_CURLY@[16; 17) | ||
16 | WHITESPACE@[17; 18) | ||
17 | R_CURLY@[18; 19) | ||
18 | WHITESPACE@[19; 21) | ||
19 | FN_DEF@[21; 44) | ||
20 | ABI@[21; 31) | ||
21 | EXTERN_KW@[21; 27) | ||
22 | WHITESPACE@[27; 28) | ||
23 | STRING@[28; 31) | ||
24 | WHITESPACE@[31; 32) | ||
25 | FN_KW@[32; 34) | ||
26 | WHITESPACE@[34; 35) | ||
27 | NAME@[35; 38) | ||
28 | IDENT@[35; 38) "bar" | ||
29 | PARAM_LIST@[38; 40) | ||
30 | L_PAREN@[38; 39) | ||
31 | R_PAREN@[39; 40) | ||
32 | WHITESPACE@[40; 41) | ||
33 | BLOCK@[41; 44) | ||
34 | L_CURLY@[41; 42) | ||
35 | WHITESPACE@[42; 43) | ||
36 | R_CURLY@[43; 44) | ||
37 | WHITESPACE@[44; 46) | ||
38 | FN_DEF@[46; 70) | ||
39 | ABI@[46; 57) | ||
40 | EXTERN_KW@[46; 52) | ||
41 | WHITESPACE@[52; 53) | ||
42 | RAW_STRING@[53; 57) | ||
43 | WHITESPACE@[57; 58) | ||
44 | FN_KW@[58; 60) | ||
45 | WHITESPACE@[60; 61) | ||
46 | NAME@[61; 64) | ||
47 | IDENT@[61; 64) "baz" | ||
48 | PARAM_LIST@[64; 66) | ||
49 | L_PAREN@[64; 65) | ||
50 | R_PAREN@[65; 66) | ||
51 | WHITESPACE@[66; 67) | ||
52 | BLOCK@[67; 70) | ||
53 | L_CURLY@[67; 68) | ||
54 | WHITESPACE@[68; 69) | ||
55 | R_CURLY@[69; 70) | ||
56 | WHITESPACE@[70; 71) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.rs b/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.rs new file mode 100644 index 000000000..f5fe0e6ef --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | extern { | ||
2 | } | ||
3 | |||
4 | extern "C" { | ||
5 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.txt b/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.txt new file mode 100644 index 000000000..2099e2433 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0022_empty_extern_block.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | ROOT@[0; 27) | ||
2 | EXTERN_BLOCK@[0; 10) | ||
3 | ABI@[0; 6) | ||
4 | EXTERN_KW@[0; 6) | ||
5 | WHITESPACE@[6; 7) | ||
6 | EXTERN_ITEM_LIST@[7; 10) | ||
7 | L_CURLY@[7; 8) | ||
8 | WHITESPACE@[8; 9) | ||
9 | R_CURLY@[9; 10) | ||
10 | WHITESPACE@[10; 12) | ||
11 | EXTERN_BLOCK@[12; 26) | ||
12 | ABI@[12; 22) | ||
13 | EXTERN_KW@[12; 18) | ||
14 | WHITESPACE@[18; 19) | ||
15 | STRING@[19; 22) | ||
16 | WHITESPACE@[22; 23) | ||
17 | EXTERN_ITEM_LIST@[23; 26) | ||
18 | L_CURLY@[23; 24) | ||
19 | WHITESPACE@[24; 25) | ||
20 | R_CURLY@[25; 26) | ||
21 | WHITESPACE@[26; 27) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0023_static_items.rs b/crates/ra_syntax/tests/data/parser/ok/0023_static_items.rs new file mode 100644 index 000000000..5fb92ce33 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0023_static_items.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | static FOO: u32 = 1; | ||
2 | static mut BAR: i32 = 92; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0023_static_items.txt b/crates/ra_syntax/tests/data/parser/ok/0023_static_items.txt new file mode 100644 index 000000000..5c1a3a7a5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0023_static_items.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | ROOT@[0; 47) | ||
2 | STATIC_DEF@[0; 20) | ||
3 | STATIC_KW@[0; 6) | ||
4 | WHITESPACE@[6; 7) | ||
5 | NAME@[7; 10) | ||
6 | IDENT@[7; 10) "FOO" | ||
7 | COLON@[10; 11) | ||
8 | WHITESPACE@[11; 12) | ||
9 | PATH_TYPE@[12; 15) | ||
10 | PATH@[12; 15) | ||
11 | PATH_SEGMENT@[12; 15) | ||
12 | NAME_REF@[12; 15) | ||
13 | IDENT@[12; 15) "u32" | ||
14 | WHITESPACE@[15; 16) | ||
15 | EQ@[16; 17) | ||
16 | WHITESPACE@[17; 18) | ||
17 | LITERAL@[18; 19) | ||
18 | INT_NUMBER@[18; 19) "1" | ||
19 | SEMI@[19; 20) | ||
20 | WHITESPACE@[20; 21) | ||
21 | STATIC_DEF@[21; 46) | ||
22 | STATIC_KW@[21; 27) | ||
23 | WHITESPACE@[27; 28) | ||
24 | MUT_KW@[28; 31) | ||
25 | WHITESPACE@[31; 32) | ||
26 | NAME@[32; 35) | ||
27 | IDENT@[32; 35) "BAR" | ||
28 | COLON@[35; 36) | ||
29 | WHITESPACE@[36; 37) | ||
30 | PATH_TYPE@[37; 40) | ||
31 | PATH@[37; 40) | ||
32 | PATH_SEGMENT@[37; 40) | ||
33 | NAME_REF@[37; 40) | ||
34 | IDENT@[37; 40) "i32" | ||
35 | WHITESPACE@[40; 41) | ||
36 | EQ@[41; 42) | ||
37 | WHITESPACE@[42; 43) | ||
38 | LITERAL@[43; 45) | ||
39 | INT_NUMBER@[43; 45) "92" | ||
40 | SEMI@[45; 46) | ||
41 | WHITESPACE@[46; 47) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0024_const_item.rs b/crates/ra_syntax/tests/data/parser/ok/0024_const_item.rs new file mode 100644 index 000000000..7446859b5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0024_const_item.rs | |||
@@ -0,0 +1,2 @@ | |||
1 | const FOO: u32 = 92; | ||
2 | const mut BAR: u32 = 62; | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0024_const_item.txt b/crates/ra_syntax/tests/data/parser/ok/0024_const_item.txt new file mode 100644 index 000000000..d0e5842da --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0024_const_item.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | ROOT@[0; 46) | ||
2 | CONST_DEF@[0; 20) | ||
3 | CONST_KW@[0; 5) | ||
4 | WHITESPACE@[5; 6) | ||
5 | NAME@[6; 9) | ||
6 | IDENT@[6; 9) "FOO" | ||
7 | COLON@[9; 10) | ||
8 | WHITESPACE@[10; 11) | ||
9 | PATH_TYPE@[11; 14) | ||
10 | PATH@[11; 14) | ||
11 | PATH_SEGMENT@[11; 14) | ||
12 | NAME_REF@[11; 14) | ||
13 | IDENT@[11; 14) "u32" | ||
14 | WHITESPACE@[14; 15) | ||
15 | EQ@[15; 16) | ||
16 | WHITESPACE@[16; 17) | ||
17 | LITERAL@[17; 19) | ||
18 | INT_NUMBER@[17; 19) "92" | ||
19 | SEMI@[19; 20) | ||
20 | WHITESPACE@[20; 21) | ||
21 | CONST_DEF@[21; 45) | ||
22 | CONST_KW@[21; 26) | ||
23 | WHITESPACE@[26; 27) | ||
24 | MUT_KW@[27; 30) | ||
25 | WHITESPACE@[30; 31) | ||
26 | NAME@[31; 34) | ||
27 | IDENT@[31; 34) "BAR" | ||
28 | COLON@[34; 35) | ||
29 | WHITESPACE@[35; 36) | ||
30 | PATH_TYPE@[36; 39) | ||
31 | PATH@[36; 39) | ||
32 | PATH_SEGMENT@[36; 39) | ||
33 | NAME_REF@[36; 39) | ||
34 | IDENT@[36; 39) "u32" | ||
35 | WHITESPACE@[39; 40) | ||
36 | EQ@[40; 41) | ||
37 | WHITESPACE@[41; 42) | ||
38 | LITERAL@[42; 44) | ||
39 | INT_NUMBER@[42; 44) "62" | ||
40 | SEMI@[44; 45) | ||
41 | WHITESPACE@[45; 46) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.rs b/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.rs new file mode 100644 index 000000000..289809809 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn main() { | ||
2 | extern fn f() {} | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.txt b/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.txt new file mode 100644 index 000000000..363b3576e --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0025_extern_fn_in_block.txt | |||
@@ -0,0 +1,31 @@ | |||
1 | ROOT@[0; 35) | ||
2 | FN_DEF@[0; 34) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 34) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | FN_DEF@[16; 32) | ||
15 | ABI@[16; 22) | ||
16 | EXTERN_KW@[16; 22) | ||
17 | WHITESPACE@[22; 23) | ||
18 | FN_KW@[23; 25) | ||
19 | WHITESPACE@[25; 26) | ||
20 | NAME@[26; 27) | ||
21 | IDENT@[26; 27) "f" | ||
22 | PARAM_LIST@[27; 29) | ||
23 | L_PAREN@[27; 28) | ||
24 | R_PAREN@[28; 29) | ||
25 | WHITESPACE@[29; 30) | ||
26 | BLOCK@[30; 32) | ||
27 | L_CURLY@[30; 31) | ||
28 | R_CURLY@[31; 32) | ||
29 | WHITESPACE@[32; 33) | ||
30 | R_CURLY@[33; 34) | ||
31 | WHITESPACE@[34; 35) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.rs b/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.rs new file mode 100644 index 000000000..7641a3d28 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn main() { | ||
2 | const fn f() {} | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.txt b/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.txt new file mode 100644 index 000000000..d45fc2559 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0026_const_fn_in_block.txt | |||
@@ -0,0 +1,30 @@ | |||
1 | ROOT@[0; 34) | ||
2 | FN_DEF@[0; 33) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 33) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | FN_DEF@[16; 31) | ||
15 | CONST_KW@[16; 21) | ||
16 | WHITESPACE@[21; 22) | ||
17 | FN_KW@[22; 24) | ||
18 | WHITESPACE@[24; 25) | ||
19 | NAME@[25; 26) | ||
20 | IDENT@[25; 26) "f" | ||
21 | PARAM_LIST@[26; 28) | ||
22 | L_PAREN@[26; 27) | ||
23 | R_PAREN@[27; 28) | ||
24 | WHITESPACE@[28; 29) | ||
25 | BLOCK@[29; 31) | ||
26 | L_CURLY@[29; 30) | ||
27 | R_CURLY@[30; 31) | ||
28 | WHITESPACE@[31; 32) | ||
29 | R_CURLY@[32; 33) | ||
30 | WHITESPACE@[33; 34) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.rs b/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.rs new file mode 100644 index 000000000..f3c5ff938 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn main() { | ||
2 | unsafe fn f() {} | ||
3 | unsafe { 92 } | ||
4 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.txt b/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.txt new file mode 100644 index 000000000..5a39fa98c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0027_unsafe_fn_in_block.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | ROOT@[0; 53) | ||
2 | FN_DEF@[0; 52) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 7) | ||
6 | IDENT@[3; 7) "main" | ||
7 | PARAM_LIST@[7; 9) | ||
8 | L_PAREN@[7; 8) | ||
9 | R_PAREN@[8; 9) | ||
10 | WHITESPACE@[9; 10) | ||
11 | BLOCK@[10; 52) | ||
12 | L_CURLY@[10; 11) | ||
13 | WHITESPACE@[11; 16) | ||
14 | FN_DEF@[16; 32) | ||
15 | UNSAFE_KW@[16; 22) | ||
16 | WHITESPACE@[22; 23) | ||
17 | FN_KW@[23; 25) | ||
18 | WHITESPACE@[25; 26) | ||
19 | NAME@[26; 27) | ||
20 | IDENT@[26; 27) "f" | ||
21 | PARAM_LIST@[27; 29) | ||
22 | L_PAREN@[27; 28) | ||
23 | R_PAREN@[28; 29) | ||
24 | WHITESPACE@[29; 30) | ||
25 | BLOCK@[30; 32) | ||
26 | L_CURLY@[30; 31) | ||
27 | R_CURLY@[31; 32) | ||
28 | WHITESPACE@[32; 37) | ||
29 | BLOCK_EXPR@[37; 50) | ||
30 | UNSAFE_KW@[37; 43) | ||
31 | WHITESPACE@[43; 44) | ||
32 | BLOCK@[44; 50) | ||
33 | L_CURLY@[44; 45) | ||
34 | WHITESPACE@[45; 46) | ||
35 | LITERAL@[46; 48) | ||
36 | INT_NUMBER@[46; 48) "92" | ||
37 | WHITESPACE@[48; 49) | ||
38 | R_CURLY@[49; 50) | ||
39 | WHITESPACE@[50; 51) | ||
40 | R_CURLY@[51; 52) | ||
41 | WHITESPACE@[52; 53) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.rs b/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.rs new file mode 100644 index 000000000..cc9598470 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.rs | |||
@@ -0,0 +1,14 @@ | |||
1 | fn binding_power() { | ||
2 | let x = 1 + 2 * 3 % 4 - 5 / 6; | ||
3 | 1 + 2 * 3; | ||
4 | 1 << 2 + 3; | ||
5 | 1 & 2 >> 3; | ||
6 | 1 ^ 2 & 3; | ||
7 | 1 | 2 ^ 3; | ||
8 | 1 == 2 | 3; | ||
9 | 1 && 2 == 3; | ||
10 | //1 || 2 && 2; | ||
11 | //1 .. 2 || 3; | ||
12 | //1 = 2 .. 3; | ||
13 | //---&*1 - --2 * 9; | ||
14 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.txt b/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.txt new file mode 100644 index 000000000..27efd180f --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0028_operator_binding_power.txt | |||
@@ -0,0 +1,185 @@ | |||
1 | ROOT@[0; 248) | ||
2 | FN_DEF@[0; 247) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 16) | ||
6 | IDENT@[3; 16) "binding_power" | ||
7 | PARAM_LIST@[16; 18) | ||
8 | L_PAREN@[16; 17) | ||
9 | R_PAREN@[17; 18) | ||
10 | WHITESPACE@[18; 19) | ||
11 | BLOCK@[19; 247) | ||
12 | L_CURLY@[19; 20) | ||
13 | WHITESPACE@[20; 25) | ||
14 | LET_STMT@[25; 55) | ||
15 | LET_KW@[25; 28) | ||
16 | WHITESPACE@[28; 29) | ||
17 | BIND_PAT@[29; 30) | ||
18 | NAME@[29; 30) | ||
19 | IDENT@[29; 30) "x" | ||
20 | WHITESPACE@[30; 31) | ||
21 | EQ@[31; 32) | ||
22 | WHITESPACE@[32; 33) | ||
23 | BIN_EXPR@[33; 54) | ||
24 | BIN_EXPR@[33; 46) | ||
25 | LITERAL@[33; 34) | ||
26 | INT_NUMBER@[33; 34) "1" | ||
27 | WHITESPACE@[34; 35) | ||
28 | PLUS@[35; 36) | ||
29 | WHITESPACE@[36; 37) | ||
30 | BIN_EXPR@[37; 46) | ||
31 | BIN_EXPR@[37; 42) | ||
32 | LITERAL@[37; 38) | ||
33 | INT_NUMBER@[37; 38) "2" | ||
34 | WHITESPACE@[38; 39) | ||
35 | STAR@[39; 40) | ||
36 | WHITESPACE@[40; 41) | ||
37 | LITERAL@[41; 42) | ||
38 | INT_NUMBER@[41; 42) "3" | ||
39 | WHITESPACE@[42; 43) | ||
40 | PERCENT@[43; 44) | ||
41 | WHITESPACE@[44; 45) | ||
42 | LITERAL@[45; 46) | ||
43 | INT_NUMBER@[45; 46) "4" | ||
44 | WHITESPACE@[46; 47) | ||
45 | MINUS@[47; 48) | ||
46 | WHITESPACE@[48; 49) | ||
47 | BIN_EXPR@[49; 54) | ||
48 | LITERAL@[49; 50) | ||
49 | INT_NUMBER@[49; 50) "5" | ||
50 | WHITESPACE@[50; 51) | ||
51 | SLASH@[51; 52) | ||
52 | WHITESPACE@[52; 53) | ||
53 | LITERAL@[53; 54) | ||
54 | INT_NUMBER@[53; 54) "6" | ||
55 | SEMI@[54; 55) | ||
56 | WHITESPACE@[55; 60) | ||
57 | EXPR_STMT@[60; 70) | ||
58 | BIN_EXPR@[60; 69) | ||
59 | LITERAL@[60; 61) | ||
60 | INT_NUMBER@[60; 61) "1" | ||
61 | WHITESPACE@[61; 62) | ||
62 | PLUS@[62; 63) | ||
63 | WHITESPACE@[63; 64) | ||
64 | BIN_EXPR@[64; 69) | ||
65 | LITERAL@[64; 65) | ||
66 | INT_NUMBER@[64; 65) "2" | ||
67 | WHITESPACE@[65; 66) | ||
68 | STAR@[66; 67) | ||
69 | WHITESPACE@[67; 68) | ||
70 | LITERAL@[68; 69) | ||
71 | INT_NUMBER@[68; 69) "3" | ||
72 | SEMI@[69; 70) | ||
73 | WHITESPACE@[70; 75) | ||
74 | EXPR_STMT@[75; 86) | ||
75 | BIN_EXPR@[75; 85) | ||
76 | LITERAL@[75; 76) | ||
77 | INT_NUMBER@[75; 76) "1" | ||
78 | WHITESPACE@[76; 77) | ||
79 | SHL@[77; 79) | ||
80 | WHITESPACE@[79; 80) | ||
81 | BIN_EXPR@[80; 85) | ||
82 | LITERAL@[80; 81) | ||
83 | INT_NUMBER@[80; 81) "2" | ||
84 | WHITESPACE@[81; 82) | ||
85 | PLUS@[82; 83) | ||
86 | WHITESPACE@[83; 84) | ||
87 | LITERAL@[84; 85) | ||
88 | INT_NUMBER@[84; 85) "3" | ||
89 | SEMI@[85; 86) | ||
90 | WHITESPACE@[86; 91) | ||
91 | EXPR_STMT@[91; 102) | ||
92 | BIN_EXPR@[91; 101) | ||
93 | LITERAL@[91; 92) | ||
94 | INT_NUMBER@[91; 92) "1" | ||
95 | WHITESPACE@[92; 93) | ||
96 | AMP@[93; 94) | ||
97 | WHITESPACE@[94; 95) | ||
98 | BIN_EXPR@[95; 101) | ||
99 | LITERAL@[95; 96) | ||
100 | INT_NUMBER@[95; 96) "2" | ||
101 | WHITESPACE@[96; 97) | ||
102 | SHR@[97; 99) | ||
103 | WHITESPACE@[99; 100) | ||
104 | LITERAL@[100; 101) | ||
105 | INT_NUMBER@[100; 101) "3" | ||
106 | SEMI@[101; 102) | ||
107 | WHITESPACE@[102; 107) | ||
108 | EXPR_STMT@[107; 117) | ||
109 | BIN_EXPR@[107; 116) | ||
110 | LITERAL@[107; 108) | ||
111 | INT_NUMBER@[107; 108) "1" | ||
112 | WHITESPACE@[108; 109) | ||
113 | CARET@[109; 110) | ||
114 | WHITESPACE@[110; 111) | ||
115 | BIN_EXPR@[111; 116) | ||
116 | LITERAL@[111; 112) | ||
117 | INT_NUMBER@[111; 112) "2" | ||
118 | WHITESPACE@[112; 113) | ||
119 | AMP@[113; 114) | ||
120 | WHITESPACE@[114; 115) | ||
121 | LITERAL@[115; 116) | ||
122 | INT_NUMBER@[115; 116) "3" | ||
123 | SEMI@[116; 117) | ||
124 | WHITESPACE@[117; 122) | ||
125 | EXPR_STMT@[122; 132) | ||
126 | BIN_EXPR@[122; 131) | ||
127 | LITERAL@[122; 123) | ||
128 | INT_NUMBER@[122; 123) "1" | ||
129 | WHITESPACE@[123; 124) | ||
130 | PIPE@[124; 125) | ||
131 | WHITESPACE@[125; 126) | ||
132 | BIN_EXPR@[126; 131) | ||
133 | LITERAL@[126; 127) | ||
134 | INT_NUMBER@[126; 127) "2" | ||
135 | WHITESPACE@[127; 128) | ||
136 | CARET@[128; 129) | ||
137 | WHITESPACE@[129; 130) | ||
138 | LITERAL@[130; 131) | ||
139 | INT_NUMBER@[130; 131) "3" | ||
140 | SEMI@[131; 132) | ||
141 | WHITESPACE@[132; 137) | ||
142 | EXPR_STMT@[137; 148) | ||
143 | BIN_EXPR@[137; 147) | ||
144 | LITERAL@[137; 138) | ||
145 | INT_NUMBER@[137; 138) "1" | ||
146 | WHITESPACE@[138; 139) | ||
147 | EQEQ@[139; 141) | ||
148 | WHITESPACE@[141; 142) | ||
149 | BIN_EXPR@[142; 147) | ||
150 | LITERAL@[142; 143) | ||
151 | INT_NUMBER@[142; 143) "2" | ||
152 | WHITESPACE@[143; 144) | ||
153 | PIPE@[144; 145) | ||
154 | WHITESPACE@[145; 146) | ||
155 | LITERAL@[146; 147) | ||
156 | INT_NUMBER@[146; 147) "3" | ||
157 | SEMI@[147; 148) | ||
158 | WHITESPACE@[148; 153) | ||
159 | EXPR_STMT@[153; 165) | ||
160 | BIN_EXPR@[153; 164) | ||
161 | LITERAL@[153; 154) | ||
162 | INT_NUMBER@[153; 154) "1" | ||
163 | WHITESPACE@[154; 155) | ||
164 | AMPAMP@[155; 157) | ||
165 | WHITESPACE@[157; 158) | ||
166 | BIN_EXPR@[158; 164) | ||
167 | LITERAL@[158; 159) | ||
168 | INT_NUMBER@[158; 159) "2" | ||
169 | WHITESPACE@[159; 160) | ||
170 | EQEQ@[160; 162) | ||
171 | WHITESPACE@[162; 163) | ||
172 | LITERAL@[163; 164) | ||
173 | INT_NUMBER@[163; 164) "3" | ||
174 | SEMI@[164; 165) | ||
175 | WHITESPACE@[165; 170) | ||
176 | COMMENT@[170; 184) | ||
177 | WHITESPACE@[184; 189) | ||
178 | COMMENT@[189; 203) | ||
179 | WHITESPACE@[203; 208) | ||
180 | COMMENT@[208; 221) | ||
181 | WHITESPACE@[221; 226) | ||
182 | COMMENT@[226; 245) | ||
183 | WHITESPACE@[245; 246) | ||
184 | R_CURLY@[246; 247) | ||
185 | WHITESPACE@[247; 248) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs new file mode 100644 index 000000000..03f4ae7b2 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.rs | |||
@@ -0,0 +1,6 @@ | |||
1 | fn foo() { | ||
2 | ..1 + 1; | ||
3 | ..z = 2; | ||
4 | x = false..1 == 1; | ||
5 | let x = 1..; | ||
6 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt new file mode 100644 index 000000000..6d6d2f4d0 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0029_range_forms.txt | |||
@@ -0,0 +1,83 @@ | |||
1 | ROOT@[0; 79) | ||
2 | FN_DEF@[0; 78) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 78) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 23) | ||
15 | RANGE_EXPR@[15; 22) | ||
16 | DOTDOT@[15; 17) | ||
17 | BIN_EXPR@[17; 22) | ||
18 | LITERAL@[17; 18) | ||
19 | INT_NUMBER@[17; 18) "1" | ||
20 | WHITESPACE@[18; 19) | ||
21 | PLUS@[19; 20) | ||
22 | WHITESPACE@[20; 21) | ||
23 | LITERAL@[21; 22) | ||
24 | INT_NUMBER@[21; 22) "1" | ||
25 | SEMI@[22; 23) | ||
26 | WHITESPACE@[23; 28) | ||
27 | EXPR_STMT@[28; 36) | ||
28 | BIN_EXPR@[28; 35) | ||
29 | RANGE_EXPR@[28; 31) | ||
30 | DOTDOT@[28; 30) | ||
31 | PATH_EXPR@[30; 31) | ||
32 | PATH@[30; 31) | ||
33 | PATH_SEGMENT@[30; 31) | ||
34 | NAME_REF@[30; 31) | ||
35 | IDENT@[30; 31) "z" | ||
36 | WHITESPACE@[31; 32) | ||
37 | EQ@[32; 33) | ||
38 | WHITESPACE@[33; 34) | ||
39 | LITERAL@[34; 35) | ||
40 | INT_NUMBER@[34; 35) "2" | ||
41 | SEMI@[35; 36) | ||
42 | WHITESPACE@[36; 41) | ||
43 | EXPR_STMT@[41; 59) | ||
44 | BIN_EXPR@[41; 58) | ||
45 | PATH_EXPR@[41; 42) | ||
46 | PATH@[41; 42) | ||
47 | PATH_SEGMENT@[41; 42) | ||
48 | NAME_REF@[41; 42) | ||
49 | IDENT@[41; 42) "x" | ||
50 | WHITESPACE@[42; 43) | ||
51 | EQ@[43; 44) | ||
52 | WHITESPACE@[44; 45) | ||
53 | RANGE_EXPR@[45; 58) | ||
54 | LITERAL@[45; 50) | ||
55 | FALSE_KW@[45; 50) | ||
56 | DOTDOT@[50; 52) | ||
57 | BIN_EXPR@[52; 58) | ||
58 | LITERAL@[52; 53) | ||
59 | INT_NUMBER@[52; 53) "1" | ||
60 | WHITESPACE@[53; 54) | ||
61 | EQEQ@[54; 56) | ||
62 | WHITESPACE@[56; 57) | ||
63 | LITERAL@[57; 58) | ||
64 | INT_NUMBER@[57; 58) "1" | ||
65 | SEMI@[58; 59) | ||
66 | WHITESPACE@[59; 64) | ||
67 | LET_STMT@[64; 76) | ||
68 | LET_KW@[64; 67) | ||
69 | WHITESPACE@[67; 68) | ||
70 | BIND_PAT@[68; 69) | ||
71 | NAME@[68; 69) | ||
72 | IDENT@[68; 69) "x" | ||
73 | WHITESPACE@[69; 70) | ||
74 | EQ@[70; 71) | ||
75 | WHITESPACE@[71; 72) | ||
76 | RANGE_EXPR@[72; 75) | ||
77 | LITERAL@[72; 73) | ||
78 | INT_NUMBER@[72; 73) "1" | ||
79 | DOTDOT@[73; 75) | ||
80 | SEMI@[75; 76) | ||
81 | WHITESPACE@[76; 77) | ||
82 | R_CURLY@[77; 78) | ||
83 | WHITESPACE@[78; 79) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0030_traits.rs b/crates/ra_syntax/tests/data/parser/ok/0030_traits.rs new file mode 100644 index 000000000..23c4be0e1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0030_traits.rs | |||
@@ -0,0 +1,11 @@ | |||
1 | pub trait WriteMessage { | ||
2 | fn write_message(&FrontendMessage); | ||
3 | } | ||
4 | |||
5 | trait Runnable { | ||
6 | fn handler(); | ||
7 | } | ||
8 | |||
9 | trait TraitWithExpr { | ||
10 | fn fn_with_expr(x: [i32; 1]); | ||
11 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0030_traits.txt b/crates/ra_syntax/tests/data/parser/ok/0030_traits.txt new file mode 100644 index 000000000..ddd666407 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0030_traits.txt | |||
@@ -0,0 +1,93 @@ | |||
1 | ROOT@[0; 164) | ||
2 | TRAIT_DEF@[0; 66) | ||
3 | VISIBILITY@[0; 3) | ||
4 | PUB_KW@[0; 3) | ||
5 | WHITESPACE@[3; 4) | ||
6 | TRAIT_KW@[4; 9) | ||
7 | WHITESPACE@[9; 10) | ||
8 | NAME@[10; 22) | ||
9 | IDENT@[10; 22) "WriteMessage" | ||
10 | WHITESPACE@[22; 23) | ||
11 | ITEM_LIST@[23; 66) | ||
12 | L_CURLY@[23; 24) | ||
13 | WHITESPACE@[24; 29) | ||
14 | FN_DEF@[29; 64) | ||
15 | FN_KW@[29; 31) | ||
16 | WHITESPACE@[31; 32) | ||
17 | NAME@[32; 45) | ||
18 | IDENT@[32; 45) "write_message" | ||
19 | PARAM_LIST@[45; 63) | ||
20 | L_PAREN@[45; 46) | ||
21 | PARAM@[46; 62) | ||
22 | REFERENCE_TYPE@[46; 62) | ||
23 | AMP@[46; 47) | ||
24 | PATH_TYPE@[47; 62) | ||
25 | PATH@[47; 62) | ||
26 | PATH_SEGMENT@[47; 62) | ||
27 | NAME_REF@[47; 62) | ||
28 | IDENT@[47; 62) "FrontendMessage" | ||
29 | R_PAREN@[62; 63) | ||
30 | SEMI@[63; 64) | ||
31 | WHITESPACE@[64; 65) | ||
32 | R_CURLY@[65; 66) | ||
33 | WHITESPACE@[66; 68) | ||
34 | TRAIT_DEF@[68; 104) | ||
35 | TRAIT_KW@[68; 73) | ||
36 | WHITESPACE@[73; 74) | ||
37 | NAME@[74; 82) | ||
38 | IDENT@[74; 82) "Runnable" | ||
39 | WHITESPACE@[82; 83) | ||
40 | ITEM_LIST@[83; 104) | ||
41 | L_CURLY@[83; 84) | ||
42 | WHITESPACE@[84; 89) | ||
43 | FN_DEF@[89; 102) | ||
44 | FN_KW@[89; 91) | ||
45 | WHITESPACE@[91; 92) | ||
46 | NAME@[92; 99) | ||
47 | IDENT@[92; 99) "handler" | ||
48 | PARAM_LIST@[99; 101) | ||
49 | L_PAREN@[99; 100) | ||
50 | R_PAREN@[100; 101) | ||
51 | SEMI@[101; 102) | ||
52 | WHITESPACE@[102; 103) | ||
53 | R_CURLY@[103; 104) | ||
54 | WHITESPACE@[104; 106) | ||
55 | TRAIT_DEF@[106; 163) | ||
56 | TRAIT_KW@[106; 111) | ||
57 | WHITESPACE@[111; 112) | ||
58 | NAME@[112; 125) | ||
59 | IDENT@[112; 125) "TraitWithExpr" | ||
60 | WHITESPACE@[125; 126) | ||
61 | ITEM_LIST@[126; 163) | ||
62 | L_CURLY@[126; 127) | ||
63 | WHITESPACE@[127; 132) | ||
64 | FN_DEF@[132; 161) | ||
65 | FN_KW@[132; 134) | ||
66 | WHITESPACE@[134; 135) | ||
67 | NAME@[135; 147) | ||
68 | IDENT@[135; 147) "fn_with_expr" | ||
69 | PARAM_LIST@[147; 160) | ||
70 | L_PAREN@[147; 148) | ||
71 | PARAM@[148; 159) | ||
72 | BIND_PAT@[148; 149) | ||
73 | NAME@[148; 149) | ||
74 | IDENT@[148; 149) "x" | ||
75 | COLON@[149; 150) | ||
76 | WHITESPACE@[150; 151) | ||
77 | ARRAY_TYPE@[151; 159) | ||
78 | L_BRACK@[151; 152) | ||
79 | PATH_TYPE@[152; 155) | ||
80 | PATH@[152; 155) | ||
81 | PATH_SEGMENT@[152; 155) | ||
82 | NAME_REF@[152; 155) | ||
83 | IDENT@[152; 155) "i32" | ||
84 | SEMI@[155; 156) | ||
85 | WHITESPACE@[156; 157) | ||
86 | LITERAL@[157; 158) | ||
87 | INT_NUMBER@[157; 158) "1" | ||
88 | R_BRACK@[158; 159) | ||
89 | R_PAREN@[159; 160) | ||
90 | SEMI@[160; 161) | ||
91 | WHITESPACE@[161; 162) | ||
92 | R_CURLY@[162; 163) | ||
93 | WHITESPACE@[163; 164) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0031_extern.rs b/crates/ra_syntax/tests/data/parser/ok/0031_extern.rs new file mode 100644 index 000000000..b33ac273c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0031_extern.rs | |||
@@ -0,0 +1,29 @@ | |||
1 | extern { | ||
2 | pub fn socket(domain: ::c_int, ty: ::c_int, protocol: ::c_int) -> ::c_int; | ||
3 | pub fn bind(fd: ::c_int, addr: *const sockaddr, len: socklen_t) -> ::c_int; | ||
4 | pub fn connect(socket: ::c_int, address: *const sockaddr, | ||
5 | len: socklen_t) -> ::c_int; | ||
6 | pub fn listen(socket: ::c_int, backlog: ::c_int) -> ::c_int; | ||
7 | pub fn getsockname(socket: ::c_int, address: *mut sockaddr, | ||
8 | address_len: *mut socklen_t) -> ::c_int; | ||
9 | pub fn getsockopt(sockfd: ::c_int, | ||
10 | level: ::c_int, | ||
11 | optname: ::c_int, | ||
12 | optval: *mut ::c_void, | ||
13 | optlen: *mut ::socklen_t) -> ::c_int; | ||
14 | pub fn setsockopt(socket: ::c_int, level: ::c_int, name: ::c_int, | ||
15 | value: *const ::c_void, | ||
16 | option_len: socklen_t) -> ::c_int; | ||
17 | pub fn getpeername(socket: ::c_int, address: *mut sockaddr, | ||
18 | address_len: *mut socklen_t) -> ::c_int; | ||
19 | pub fn sendto(socket: ::c_int, buf: *const ::c_void, len: ::size_t, | ||
20 | flags: ::c_int, addr: *const sockaddr, | ||
21 | addrlen: socklen_t) -> ::ssize_t; | ||
22 | pub fn send(socket: ::c_int, buf: *const ::c_void, len: ::size_t, | ||
23 | flags: ::c_int) -> ::ssize_t; | ||
24 | pub fn recvfrom(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, | ||
25 | flags: ::c_int, addr: *mut ::sockaddr, | ||
26 | addrlen: *mut ::socklen_t) -> ::ssize_t; | ||
27 | pub fn recv(socket: ::c_int, buf: *mut ::c_void, len: ::size_t, | ||
28 | flags: ::c_int) -> ::ssize_t; | ||
29 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0031_extern.txt b/crates/ra_syntax/tests/data/parser/ok/0031_extern.txt new file mode 100644 index 000000000..f3f1c25a9 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0031_extern.txt | |||
@@ -0,0 +1,973 @@ | |||
1 | ROOT@[0; 1598) | ||
2 | EXTERN_BLOCK@[0; 1597) | ||
3 | ABI@[0; 6) | ||
4 | EXTERN_KW@[0; 6) | ||
5 | WHITESPACE@[6; 7) | ||
6 | EXTERN_ITEM_LIST@[7; 1597) | ||
7 | L_CURLY@[7; 8) | ||
8 | WHITESPACE@[8; 13) | ||
9 | FN_DEF@[13; 87) | ||
10 | VISIBILITY@[13; 16) | ||
11 | PUB_KW@[13; 16) | ||
12 | WHITESPACE@[16; 17) | ||
13 | FN_KW@[17; 19) | ||
14 | WHITESPACE@[19; 20) | ||
15 | NAME@[20; 26) | ||
16 | IDENT@[20; 26) "socket" | ||
17 | PARAM_LIST@[26; 75) | ||
18 | L_PAREN@[26; 27) | ||
19 | PARAM@[27; 42) | ||
20 | BIND_PAT@[27; 33) | ||
21 | NAME@[27; 33) | ||
22 | IDENT@[27; 33) "domain" | ||
23 | COLON@[33; 34) | ||
24 | WHITESPACE@[34; 35) | ||
25 | PATH_TYPE@[35; 42) | ||
26 | PATH@[35; 42) | ||
27 | PATH_SEGMENT@[35; 42) | ||
28 | COLONCOLON@[35; 37) | ||
29 | NAME_REF@[37; 42) | ||
30 | IDENT@[37; 42) "c_int" | ||
31 | COMMA@[42; 43) | ||
32 | WHITESPACE@[43; 44) | ||
33 | PARAM@[44; 55) | ||
34 | BIND_PAT@[44; 46) | ||
35 | NAME@[44; 46) | ||
36 | IDENT@[44; 46) "ty" | ||
37 | COLON@[46; 47) | ||
38 | WHITESPACE@[47; 48) | ||
39 | PATH_TYPE@[48; 55) | ||
40 | PATH@[48; 55) | ||
41 | PATH_SEGMENT@[48; 55) | ||
42 | COLONCOLON@[48; 50) | ||
43 | NAME_REF@[50; 55) | ||
44 | IDENT@[50; 55) "c_int" | ||
45 | COMMA@[55; 56) | ||
46 | WHITESPACE@[56; 57) | ||
47 | PARAM@[57; 74) | ||
48 | BIND_PAT@[57; 65) | ||
49 | NAME@[57; 65) | ||
50 | IDENT@[57; 65) "protocol" | ||
51 | COLON@[65; 66) | ||
52 | WHITESPACE@[66; 67) | ||
53 | PATH_TYPE@[67; 74) | ||
54 | PATH@[67; 74) | ||
55 | PATH_SEGMENT@[67; 74) | ||
56 | COLONCOLON@[67; 69) | ||
57 | NAME_REF@[69; 74) | ||
58 | IDENT@[69; 74) "c_int" | ||
59 | R_PAREN@[74; 75) | ||
60 | WHITESPACE@[75; 76) | ||
61 | RET_TYPE@[76; 86) | ||
62 | THIN_ARROW@[76; 78) | ||
63 | WHITESPACE@[78; 79) | ||
64 | PATH_TYPE@[79; 86) | ||
65 | PATH@[79; 86) | ||
66 | PATH_SEGMENT@[79; 86) | ||
67 | COLONCOLON@[79; 81) | ||
68 | NAME_REF@[81; 86) | ||
69 | IDENT@[81; 86) "c_int" | ||
70 | SEMI@[86; 87) | ||
71 | WHITESPACE@[87; 92) | ||
72 | FN_DEF@[92; 167) | ||
73 | VISIBILITY@[92; 95) | ||
74 | PUB_KW@[92; 95) | ||
75 | WHITESPACE@[95; 96) | ||
76 | FN_KW@[96; 98) | ||
77 | WHITESPACE@[98; 99) | ||
78 | NAME@[99; 103) | ||
79 | IDENT@[99; 103) "bind" | ||
80 | PARAM_LIST@[103; 155) | ||
81 | L_PAREN@[103; 104) | ||
82 | PARAM@[104; 115) | ||
83 | BIND_PAT@[104; 106) | ||
84 | NAME@[104; 106) | ||
85 | IDENT@[104; 106) "fd" | ||
86 | COLON@[106; 107) | ||
87 | WHITESPACE@[107; 108) | ||
88 | PATH_TYPE@[108; 115) | ||
89 | PATH@[108; 115) | ||
90 | PATH_SEGMENT@[108; 115) | ||
91 | COLONCOLON@[108; 110) | ||
92 | NAME_REF@[110; 115) | ||
93 | IDENT@[110; 115) "c_int" | ||
94 | COMMA@[115; 116) | ||
95 | WHITESPACE@[116; 117) | ||
96 | PARAM@[117; 138) | ||
97 | BIND_PAT@[117; 121) | ||
98 | NAME@[117; 121) | ||
99 | IDENT@[117; 121) "addr" | ||
100 | COLON@[121; 122) | ||
101 | WHITESPACE@[122; 123) | ||
102 | POINTER_TYPE@[123; 138) | ||
103 | STAR@[123; 124) | ||
104 | CONST_KW@[124; 129) | ||
105 | WHITESPACE@[129; 130) | ||
106 | PATH_TYPE@[130; 138) | ||
107 | PATH@[130; 138) | ||
108 | PATH_SEGMENT@[130; 138) | ||
109 | NAME_REF@[130; 138) | ||
110 | IDENT@[130; 138) "sockaddr" | ||
111 | COMMA@[138; 139) | ||
112 | WHITESPACE@[139; 140) | ||
113 | PARAM@[140; 154) | ||
114 | BIND_PAT@[140; 143) | ||
115 | NAME@[140; 143) | ||
116 | IDENT@[140; 143) "len" | ||
117 | COLON@[143; 144) | ||
118 | WHITESPACE@[144; 145) | ||
119 | PATH_TYPE@[145; 154) | ||
120 | PATH@[145; 154) | ||
121 | PATH_SEGMENT@[145; 154) | ||
122 | NAME_REF@[145; 154) | ||
123 | IDENT@[145; 154) "socklen_t" | ||
124 | R_PAREN@[154; 155) | ||
125 | WHITESPACE@[155; 156) | ||
126 | RET_TYPE@[156; 166) | ||
127 | THIN_ARROW@[156; 158) | ||
128 | WHITESPACE@[158; 159) | ||
129 | PATH_TYPE@[159; 166) | ||
130 | PATH@[159; 166) | ||
131 | PATH_SEGMENT@[159; 166) | ||
132 | COLONCOLON@[159; 161) | ||
133 | NAME_REF@[161; 166) | ||
134 | IDENT@[161; 166) "c_int" | ||
135 | SEMI@[166; 167) | ||
136 | WHITESPACE@[167; 172) | ||
137 | FN_DEF@[172; 276) | ||
138 | VISIBILITY@[172; 175) | ||
139 | PUB_KW@[172; 175) | ||
140 | WHITESPACE@[175; 176) | ||
141 | FN_KW@[176; 178) | ||
142 | WHITESPACE@[178; 179) | ||
143 | NAME@[179; 186) | ||
144 | IDENT@[179; 186) "connect" | ||
145 | PARAM_LIST@[186; 264) | ||
146 | L_PAREN@[186; 187) | ||
147 | PARAM@[187; 202) | ||
148 | BIND_PAT@[187; 193) | ||
149 | NAME@[187; 193) | ||
150 | IDENT@[187; 193) "socket" | ||
151 | COLON@[193; 194) | ||
152 | WHITESPACE@[194; 195) | ||
153 | PATH_TYPE@[195; 202) | ||
154 | PATH@[195; 202) | ||
155 | PATH_SEGMENT@[195; 202) | ||
156 | COLONCOLON@[195; 197) | ||
157 | NAME_REF@[197; 202) | ||
158 | IDENT@[197; 202) "c_int" | ||
159 | COMMA@[202; 203) | ||
160 | WHITESPACE@[203; 204) | ||
161 | PARAM@[204; 228) | ||
162 | BIND_PAT@[204; 211) | ||
163 | NAME@[204; 211) | ||
164 | IDENT@[204; 211) "address" | ||
165 | COLON@[211; 212) | ||
166 | WHITESPACE@[212; 213) | ||
167 | POINTER_TYPE@[213; 228) | ||
168 | STAR@[213; 214) | ||
169 | CONST_KW@[214; 219) | ||
170 | WHITESPACE@[219; 220) | ||
171 | PATH_TYPE@[220; 228) | ||
172 | PATH@[220; 228) | ||
173 | PATH_SEGMENT@[220; 228) | ||
174 | NAME_REF@[220; 228) | ||
175 | IDENT@[220; 228) "sockaddr" | ||
176 | COMMA@[228; 229) | ||
177 | WHITESPACE@[229; 249) | ||
178 | PARAM@[249; 263) | ||
179 | BIND_PAT@[249; 252) | ||
180 | NAME@[249; 252) | ||
181 | IDENT@[249; 252) "len" | ||
182 | COLON@[252; 253) | ||
183 | WHITESPACE@[253; 254) | ||
184 | PATH_TYPE@[254; 263) | ||
185 | PATH@[254; 263) | ||
186 | PATH_SEGMENT@[254; 263) | ||
187 | NAME_REF@[254; 263) | ||
188 | IDENT@[254; 263) "socklen_t" | ||
189 | R_PAREN@[263; 264) | ||
190 | WHITESPACE@[264; 265) | ||
191 | RET_TYPE@[265; 275) | ||
192 | THIN_ARROW@[265; 267) | ||
193 | WHITESPACE@[267; 268) | ||
194 | PATH_TYPE@[268; 275) | ||
195 | PATH@[268; 275) | ||
196 | PATH_SEGMENT@[268; 275) | ||
197 | COLONCOLON@[268; 270) | ||
198 | NAME_REF@[270; 275) | ||
199 | IDENT@[270; 275) "c_int" | ||
200 | SEMI@[275; 276) | ||
201 | WHITESPACE@[276; 281) | ||
202 | FN_DEF@[281; 341) | ||
203 | VISIBILITY@[281; 284) | ||
204 | PUB_KW@[281; 284) | ||
205 | WHITESPACE@[284; 285) | ||
206 | FN_KW@[285; 287) | ||
207 | WHITESPACE@[287; 288) | ||
208 | NAME@[288; 294) | ||
209 | IDENT@[288; 294) "listen" | ||
210 | PARAM_LIST@[294; 329) | ||
211 | L_PAREN@[294; 295) | ||
212 | PARAM@[295; 310) | ||
213 | BIND_PAT@[295; 301) | ||
214 | NAME@[295; 301) | ||
215 | IDENT@[295; 301) "socket" | ||
216 | COLON@[301; 302) | ||
217 | WHITESPACE@[302; 303) | ||
218 | PATH_TYPE@[303; 310) | ||
219 | PATH@[303; 310) | ||
220 | PATH_SEGMENT@[303; 310) | ||
221 | COLONCOLON@[303; 305) | ||
222 | NAME_REF@[305; 310) | ||
223 | IDENT@[305; 310) "c_int" | ||
224 | COMMA@[310; 311) | ||
225 | WHITESPACE@[311; 312) | ||
226 | PARAM@[312; 328) | ||
227 | BIND_PAT@[312; 319) | ||
228 | NAME@[312; 319) | ||
229 | IDENT@[312; 319) "backlog" | ||
230 | COLON@[319; 320) | ||
231 | WHITESPACE@[320; 321) | ||
232 | PATH_TYPE@[321; 328) | ||
233 | PATH@[321; 328) | ||
234 | PATH_SEGMENT@[321; 328) | ||
235 | COLONCOLON@[321; 323) | ||
236 | NAME_REF@[323; 328) | ||
237 | IDENT@[323; 328) "c_int" | ||
238 | R_PAREN@[328; 329) | ||
239 | WHITESPACE@[329; 330) | ||
240 | RET_TYPE@[330; 340) | ||
241 | THIN_ARROW@[330; 332) | ||
242 | WHITESPACE@[332; 333) | ||
243 | PATH_TYPE@[333; 340) | ||
244 | PATH@[333; 340) | ||
245 | PATH_SEGMENT@[333; 340) | ||
246 | COLONCOLON@[333; 335) | ||
247 | NAME_REF@[335; 340) | ||
248 | IDENT@[335; 340) "c_int" | ||
249 | SEMI@[340; 341) | ||
250 | WHITESPACE@[341; 346) | ||
251 | FN_DEF@[346; 469) | ||
252 | VISIBILITY@[346; 349) | ||
253 | PUB_KW@[346; 349) | ||
254 | WHITESPACE@[349; 350) | ||
255 | FN_KW@[350; 352) | ||
256 | WHITESPACE@[352; 353) | ||
257 | NAME@[353; 364) | ||
258 | IDENT@[353; 364) "getsockname" | ||
259 | PARAM_LIST@[364; 457) | ||
260 | L_PAREN@[364; 365) | ||
261 | PARAM@[365; 380) | ||
262 | BIND_PAT@[365; 371) | ||
263 | NAME@[365; 371) | ||
264 | IDENT@[365; 371) "socket" | ||
265 | COLON@[371; 372) | ||
266 | WHITESPACE@[372; 373) | ||
267 | PATH_TYPE@[373; 380) | ||
268 | PATH@[373; 380) | ||
269 | PATH_SEGMENT@[373; 380) | ||
270 | COLONCOLON@[373; 375) | ||
271 | NAME_REF@[375; 380) | ||
272 | IDENT@[375; 380) "c_int" | ||
273 | COMMA@[380; 381) | ||
274 | WHITESPACE@[381; 382) | ||
275 | PARAM@[382; 404) | ||
276 | BIND_PAT@[382; 389) | ||
277 | NAME@[382; 389) | ||
278 | IDENT@[382; 389) "address" | ||
279 | COLON@[389; 390) | ||
280 | WHITESPACE@[390; 391) | ||
281 | POINTER_TYPE@[391; 404) | ||
282 | STAR@[391; 392) | ||
283 | MUT_KW@[392; 395) | ||
284 | WHITESPACE@[395; 396) | ||
285 | PATH_TYPE@[396; 404) | ||
286 | PATH@[396; 404) | ||
287 | PATH_SEGMENT@[396; 404) | ||
288 | NAME_REF@[396; 404) | ||
289 | IDENT@[396; 404) "sockaddr" | ||
290 | COMMA@[404; 405) | ||
291 | WHITESPACE@[405; 429) | ||
292 | PARAM@[429; 456) | ||
293 | BIND_PAT@[429; 440) | ||
294 | NAME@[429; 440) | ||
295 | IDENT@[429; 440) "address_len" | ||
296 | COLON@[440; 441) | ||
297 | WHITESPACE@[441; 442) | ||
298 | POINTER_TYPE@[442; 456) | ||
299 | STAR@[442; 443) | ||
300 | MUT_KW@[443; 446) | ||
301 | WHITESPACE@[446; 447) | ||
302 | PATH_TYPE@[447; 456) | ||
303 | PATH@[447; 456) | ||
304 | PATH_SEGMENT@[447; 456) | ||
305 | NAME_REF@[447; 456) | ||
306 | IDENT@[447; 456) "socklen_t" | ||
307 | R_PAREN@[456; 457) | ||
308 | WHITESPACE@[457; 458) | ||
309 | RET_TYPE@[458; 468) | ||
310 | THIN_ARROW@[458; 460) | ||
311 | WHITESPACE@[460; 461) | ||
312 | PATH_TYPE@[461; 468) | ||
313 | PATH@[461; 468) | ||
314 | PATH_SEGMENT@[461; 468) | ||
315 | COLONCOLON@[461; 463) | ||
316 | NAME_REF@[463; 468) | ||
317 | IDENT@[463; 468) "c_int" | ||
318 | SEMI@[468; 469) | ||
319 | WHITESPACE@[469; 474) | ||
320 | FN_DEF@[474; 691) | ||
321 | VISIBILITY@[474; 477) | ||
322 | PUB_KW@[474; 477) | ||
323 | WHITESPACE@[477; 478) | ||
324 | FN_KW@[478; 480) | ||
325 | WHITESPACE@[480; 481) | ||
326 | NAME@[481; 491) | ||
327 | IDENT@[481; 491) "getsockopt" | ||
328 | PARAM_LIST@[491; 679) | ||
329 | L_PAREN@[491; 492) | ||
330 | PARAM@[492; 507) | ||
331 | BIND_PAT@[492; 498) | ||
332 | NAME@[492; 498) | ||
333 | IDENT@[492; 498) "sockfd" | ||
334 | COLON@[498; 499) | ||
335 | WHITESPACE@[499; 500) | ||
336 | PATH_TYPE@[500; 507) | ||
337 | PATH@[500; 507) | ||
338 | PATH_SEGMENT@[500; 507) | ||
339 | COLONCOLON@[500; 502) | ||
340 | NAME_REF@[502; 507) | ||
341 | IDENT@[502; 507) "c_int" | ||
342 | COMMA@[507; 508) | ||
343 | WHITESPACE@[508; 531) | ||
344 | PARAM@[531; 545) | ||
345 | BIND_PAT@[531; 536) | ||
346 | NAME@[531; 536) | ||
347 | IDENT@[531; 536) "level" | ||
348 | COLON@[536; 537) | ||
349 | WHITESPACE@[537; 538) | ||
350 | PATH_TYPE@[538; 545) | ||
351 | PATH@[538; 545) | ||
352 | PATH_SEGMENT@[538; 545) | ||
353 | COLONCOLON@[538; 540) | ||
354 | NAME_REF@[540; 545) | ||
355 | IDENT@[540; 545) "c_int" | ||
356 | COMMA@[545; 546) | ||
357 | WHITESPACE@[546; 569) | ||
358 | PARAM@[569; 585) | ||
359 | BIND_PAT@[569; 576) | ||
360 | NAME@[569; 576) | ||
361 | IDENT@[569; 576) "optname" | ||
362 | COLON@[576; 577) | ||
363 | WHITESPACE@[577; 578) | ||
364 | PATH_TYPE@[578; 585) | ||
365 | PATH@[578; 585) | ||
366 | PATH_SEGMENT@[578; 585) | ||
367 | COLONCOLON@[578; 580) | ||
368 | NAME_REF@[580; 585) | ||
369 | IDENT@[580; 585) "c_int" | ||
370 | COMMA@[585; 586) | ||
371 | WHITESPACE@[586; 609) | ||
372 | PARAM@[609; 630) | ||
373 | BIND_PAT@[609; 615) | ||
374 | NAME@[609; 615) | ||
375 | IDENT@[609; 615) "optval" | ||
376 | COLON@[615; 616) | ||
377 | WHITESPACE@[616; 617) | ||
378 | POINTER_TYPE@[617; 630) | ||
379 | STAR@[617; 618) | ||
380 | MUT_KW@[618; 621) | ||
381 | WHITESPACE@[621; 622) | ||
382 | PATH_TYPE@[622; 630) | ||
383 | PATH@[622; 630) | ||
384 | PATH_SEGMENT@[622; 630) | ||
385 | COLONCOLON@[622; 624) | ||
386 | NAME_REF@[624; 630) | ||
387 | IDENT@[624; 630) "c_void" | ||
388 | COMMA@[630; 631) | ||
389 | WHITESPACE@[631; 654) | ||
390 | PARAM@[654; 678) | ||
391 | BIND_PAT@[654; 660) | ||
392 | NAME@[654; 660) | ||
393 | IDENT@[654; 660) "optlen" | ||
394 | COLON@[660; 661) | ||
395 | WHITESPACE@[661; 662) | ||
396 | POINTER_TYPE@[662; 678) | ||
397 | STAR@[662; 663) | ||
398 | MUT_KW@[663; 666) | ||
399 | WHITESPACE@[666; 667) | ||
400 | PATH_TYPE@[667; 678) | ||
401 | PATH@[667; 678) | ||
402 | PATH_SEGMENT@[667; 678) | ||
403 | COLONCOLON@[667; 669) | ||
404 | NAME_REF@[669; 678) | ||
405 | IDENT@[669; 678) "socklen_t" | ||
406 | R_PAREN@[678; 679) | ||
407 | WHITESPACE@[679; 680) | ||
408 | RET_TYPE@[680; 690) | ||
409 | THIN_ARROW@[680; 682) | ||
410 | WHITESPACE@[682; 683) | ||
411 | PATH_TYPE@[683; 690) | ||
412 | PATH@[683; 690) | ||
413 | PATH_SEGMENT@[683; 690) | ||
414 | COLONCOLON@[683; 685) | ||
415 | NAME_REF@[685; 690) | ||
416 | IDENT@[685; 690) "c_int" | ||
417 | SEMI@[690; 691) | ||
418 | WHITESPACE@[691; 696) | ||
419 | FN_DEF@[696; 864) | ||
420 | VISIBILITY@[696; 699) | ||
421 | PUB_KW@[696; 699) | ||
422 | WHITESPACE@[699; 700) | ||
423 | FN_KW@[700; 702) | ||
424 | WHITESPACE@[702; 703) | ||
425 | NAME@[703; 713) | ||
426 | IDENT@[703; 713) "setsockopt" | ||
427 | PARAM_LIST@[713; 852) | ||
428 | L_PAREN@[713; 714) | ||
429 | PARAM@[714; 729) | ||
430 | BIND_PAT@[714; 720) | ||
431 | NAME@[714; 720) | ||
432 | IDENT@[714; 720) "socket" | ||
433 | COLON@[720; 721) | ||
434 | WHITESPACE@[721; 722) | ||
435 | PATH_TYPE@[722; 729) | ||
436 | PATH@[722; 729) | ||
437 | PATH_SEGMENT@[722; 729) | ||
438 | COLONCOLON@[722; 724) | ||
439 | NAME_REF@[724; 729) | ||
440 | IDENT@[724; 729) "c_int" | ||
441 | COMMA@[729; 730) | ||
442 | WHITESPACE@[730; 731) | ||
443 | PARAM@[731; 745) | ||
444 | BIND_PAT@[731; 736) | ||
445 | NAME@[731; 736) | ||
446 | IDENT@[731; 736) "level" | ||
447 | COLON@[736; 737) | ||
448 | WHITESPACE@[737; 738) | ||
449 | PATH_TYPE@[738; 745) | ||
450 | PATH@[738; 745) | ||
451 | PATH_SEGMENT@[738; 745) | ||
452 | COLONCOLON@[738; 740) | ||
453 | NAME_REF@[740; 745) | ||
454 | IDENT@[740; 745) "c_int" | ||
455 | COMMA@[745; 746) | ||
456 | WHITESPACE@[746; 747) | ||
457 | PARAM@[747; 760) | ||
458 | BIND_PAT@[747; 751) | ||
459 | NAME@[747; 751) | ||
460 | IDENT@[747; 751) "name" | ||
461 | COLON@[751; 752) | ||
462 | WHITESPACE@[752; 753) | ||
463 | PATH_TYPE@[753; 760) | ||
464 | PATH@[753; 760) | ||
465 | PATH_SEGMENT@[753; 760) | ||
466 | COLONCOLON@[753; 755) | ||
467 | NAME_REF@[755; 760) | ||
468 | IDENT@[755; 760) "c_int" | ||
469 | COMMA@[760; 761) | ||
470 | WHITESPACE@[761; 784) | ||
471 | PARAM@[784; 806) | ||
472 | BIND_PAT@[784; 789) | ||
473 | NAME@[784; 789) | ||
474 | IDENT@[784; 789) "value" | ||
475 | COLON@[789; 790) | ||
476 | WHITESPACE@[790; 791) | ||
477 | POINTER_TYPE@[791; 806) | ||
478 | STAR@[791; 792) | ||
479 | CONST_KW@[792; 797) | ||
480 | WHITESPACE@[797; 798) | ||
481 | PATH_TYPE@[798; 806) | ||
482 | PATH@[798; 806) | ||
483 | PATH_SEGMENT@[798; 806) | ||
484 | COLONCOLON@[798; 800) | ||
485 | NAME_REF@[800; 806) | ||
486 | IDENT@[800; 806) "c_void" | ||
487 | COMMA@[806; 807) | ||
488 | WHITESPACE@[807; 830) | ||
489 | PARAM@[830; 851) | ||
490 | BIND_PAT@[830; 840) | ||
491 | NAME@[830; 840) | ||
492 | IDENT@[830; 840) "option_len" | ||
493 | COLON@[840; 841) | ||
494 | WHITESPACE@[841; 842) | ||
495 | PATH_TYPE@[842; 851) | ||
496 | PATH@[842; 851) | ||
497 | PATH_SEGMENT@[842; 851) | ||
498 | NAME_REF@[842; 851) | ||
499 | IDENT@[842; 851) "socklen_t" | ||
500 | R_PAREN@[851; 852) | ||
501 | WHITESPACE@[852; 853) | ||
502 | RET_TYPE@[853; 863) | ||
503 | THIN_ARROW@[853; 855) | ||
504 | WHITESPACE@[855; 856) | ||
505 | PATH_TYPE@[856; 863) | ||
506 | PATH@[856; 863) | ||
507 | PATH_SEGMENT@[856; 863) | ||
508 | COLONCOLON@[856; 858) | ||
509 | NAME_REF@[858; 863) | ||
510 | IDENT@[858; 863) "c_int" | ||
511 | SEMI@[863; 864) | ||
512 | WHITESPACE@[864; 869) | ||
513 | FN_DEF@[869; 992) | ||
514 | VISIBILITY@[869; 872) | ||
515 | PUB_KW@[869; 872) | ||
516 | WHITESPACE@[872; 873) | ||
517 | FN_KW@[873; 875) | ||
518 | WHITESPACE@[875; 876) | ||
519 | NAME@[876; 887) | ||
520 | IDENT@[876; 887) "getpeername" | ||
521 | PARAM_LIST@[887; 980) | ||
522 | L_PAREN@[887; 888) | ||
523 | PARAM@[888; 903) | ||
524 | BIND_PAT@[888; 894) | ||
525 | NAME@[888; 894) | ||
526 | IDENT@[888; 894) "socket" | ||
527 | COLON@[894; 895) | ||
528 | WHITESPACE@[895; 896) | ||
529 | PATH_TYPE@[896; 903) | ||
530 | PATH@[896; 903) | ||
531 | PATH_SEGMENT@[896; 903) | ||
532 | COLONCOLON@[896; 898) | ||
533 | NAME_REF@[898; 903) | ||
534 | IDENT@[898; 903) "c_int" | ||
535 | COMMA@[903; 904) | ||
536 | WHITESPACE@[904; 905) | ||
537 | PARAM@[905; 927) | ||
538 | BIND_PAT@[905; 912) | ||
539 | NAME@[905; 912) | ||
540 | IDENT@[905; 912) "address" | ||
541 | COLON@[912; 913) | ||
542 | WHITESPACE@[913; 914) | ||
543 | POINTER_TYPE@[914; 927) | ||
544 | STAR@[914; 915) | ||
545 | MUT_KW@[915; 918) | ||
546 | WHITESPACE@[918; 919) | ||
547 | PATH_TYPE@[919; 927) | ||
548 | PATH@[919; 927) | ||
549 | PATH_SEGMENT@[919; 927) | ||
550 | NAME_REF@[919; 927) | ||
551 | IDENT@[919; 927) "sockaddr" | ||
552 | COMMA@[927; 928) | ||
553 | WHITESPACE@[928; 952) | ||
554 | PARAM@[952; 979) | ||
555 | BIND_PAT@[952; 963) | ||
556 | NAME@[952; 963) | ||
557 | IDENT@[952; 963) "address_len" | ||
558 | COLON@[963; 964) | ||
559 | WHITESPACE@[964; 965) | ||
560 | POINTER_TYPE@[965; 979) | ||
561 | STAR@[965; 966) | ||
562 | MUT_KW@[966; 969) | ||
563 | WHITESPACE@[969; 970) | ||
564 | PATH_TYPE@[970; 979) | ||
565 | PATH@[970; 979) | ||
566 | PATH_SEGMENT@[970; 979) | ||
567 | NAME_REF@[970; 979) | ||
568 | IDENT@[970; 979) "socklen_t" | ||
569 | R_PAREN@[979; 980) | ||
570 | WHITESPACE@[980; 981) | ||
571 | RET_TYPE@[981; 991) | ||
572 | THIN_ARROW@[981; 983) | ||
573 | WHITESPACE@[983; 984) | ||
574 | PATH_TYPE@[984; 991) | ||
575 | PATH@[984; 991) | ||
576 | PATH_SEGMENT@[984; 991) | ||
577 | COLONCOLON@[984; 986) | ||
578 | NAME_REF@[986; 991) | ||
579 | IDENT@[986; 991) "c_int" | ||
580 | SEMI@[991; 992) | ||
581 | WHITESPACE@[992; 997) | ||
582 | FN_DEF@[997; 1173) | ||
583 | VISIBILITY@[997; 1000) | ||
584 | PUB_KW@[997; 1000) | ||
585 | WHITESPACE@[1000; 1001) | ||
586 | FN_KW@[1001; 1003) | ||
587 | WHITESPACE@[1003; 1004) | ||
588 | NAME@[1004; 1010) | ||
589 | IDENT@[1004; 1010) "sendto" | ||
590 | PARAM_LIST@[1010; 1159) | ||
591 | L_PAREN@[1010; 1011) | ||
592 | PARAM@[1011; 1026) | ||
593 | BIND_PAT@[1011; 1017) | ||
594 | NAME@[1011; 1017) | ||
595 | IDENT@[1011; 1017) "socket" | ||
596 | COLON@[1017; 1018) | ||
597 | WHITESPACE@[1018; 1019) | ||
598 | PATH_TYPE@[1019; 1026) | ||
599 | PATH@[1019; 1026) | ||
600 | PATH_SEGMENT@[1019; 1026) | ||
601 | COLONCOLON@[1019; 1021) | ||
602 | NAME_REF@[1021; 1026) | ||
603 | IDENT@[1021; 1026) "c_int" | ||
604 | COMMA@[1026; 1027) | ||
605 | WHITESPACE@[1027; 1028) | ||
606 | PARAM@[1028; 1048) | ||
607 | BIND_PAT@[1028; 1031) | ||
608 | NAME@[1028; 1031) | ||
609 | IDENT@[1028; 1031) "buf" | ||
610 | COLON@[1031; 1032) | ||
611 | WHITESPACE@[1032; 1033) | ||
612 | POINTER_TYPE@[1033; 1048) | ||
613 | STAR@[1033; 1034) | ||
614 | CONST_KW@[1034; 1039) | ||
615 | WHITESPACE@[1039; 1040) | ||
616 | PATH_TYPE@[1040; 1048) | ||
617 | PATH@[1040; 1048) | ||
618 | PATH_SEGMENT@[1040; 1048) | ||
619 | COLONCOLON@[1040; 1042) | ||
620 | NAME_REF@[1042; 1048) | ||
621 | IDENT@[1042; 1048) "c_void" | ||
622 | COMMA@[1048; 1049) | ||
623 | WHITESPACE@[1049; 1050) | ||
624 | PARAM@[1050; 1063) | ||
625 | BIND_PAT@[1050; 1053) | ||
626 | NAME@[1050; 1053) | ||
627 | IDENT@[1050; 1053) "len" | ||
628 | COLON@[1053; 1054) | ||
629 | WHITESPACE@[1054; 1055) | ||
630 | PATH_TYPE@[1055; 1063) | ||
631 | PATH@[1055; 1063) | ||
632 | PATH_SEGMENT@[1055; 1063) | ||
633 | COLONCOLON@[1055; 1057) | ||
634 | NAME_REF@[1057; 1063) | ||
635 | IDENT@[1057; 1063) "size_t" | ||
636 | COMMA@[1063; 1064) | ||
637 | WHITESPACE@[1064; 1083) | ||
638 | PARAM@[1083; 1097) | ||
639 | BIND_PAT@[1083; 1088) | ||
640 | NAME@[1083; 1088) | ||
641 | IDENT@[1083; 1088) "flags" | ||
642 | COLON@[1088; 1089) | ||
643 | WHITESPACE@[1089; 1090) | ||
644 | PATH_TYPE@[1090; 1097) | ||
645 | PATH@[1090; 1097) | ||
646 | PATH_SEGMENT@[1090; 1097) | ||
647 | COLONCOLON@[1090; 1092) | ||
648 | NAME_REF@[1092; 1097) | ||
649 | IDENT@[1092; 1097) "c_int" | ||
650 | COMMA@[1097; 1098) | ||
651 | WHITESPACE@[1098; 1099) | ||
652 | PARAM@[1099; 1120) | ||
653 | BIND_PAT@[1099; 1103) | ||
654 | NAME@[1099; 1103) | ||
655 | IDENT@[1099; 1103) "addr" | ||
656 | COLON@[1103; 1104) | ||
657 | WHITESPACE@[1104; 1105) | ||
658 | POINTER_TYPE@[1105; 1120) | ||
659 | STAR@[1105; 1106) | ||
660 | CONST_KW@[1106; 1111) | ||
661 | WHITESPACE@[1111; 1112) | ||
662 | PATH_TYPE@[1112; 1120) | ||
663 | PATH@[1112; 1120) | ||
664 | PATH_SEGMENT@[1112; 1120) | ||
665 | NAME_REF@[1112; 1120) | ||
666 | IDENT@[1112; 1120) "sockaddr" | ||
667 | COMMA@[1120; 1121) | ||
668 | WHITESPACE@[1121; 1140) | ||
669 | PARAM@[1140; 1158) | ||
670 | BIND_PAT@[1140; 1147) | ||
671 | NAME@[1140; 1147) | ||
672 | IDENT@[1140; 1147) "addrlen" | ||
673 | COLON@[1147; 1148) | ||
674 | WHITESPACE@[1148; 1149) | ||
675 | PATH_TYPE@[1149; 1158) | ||
676 | PATH@[1149; 1158) | ||
677 | PATH_SEGMENT@[1149; 1158) | ||
678 | NAME_REF@[1149; 1158) | ||
679 | IDENT@[1149; 1158) "socklen_t" | ||
680 | R_PAREN@[1158; 1159) | ||
681 | WHITESPACE@[1159; 1160) | ||
682 | RET_TYPE@[1160; 1172) | ||
683 | THIN_ARROW@[1160; 1162) | ||
684 | WHITESPACE@[1162; 1163) | ||
685 | PATH_TYPE@[1163; 1172) | ||
686 | PATH@[1163; 1172) | ||
687 | PATH_SEGMENT@[1163; 1172) | ||
688 | COLONCOLON@[1163; 1165) | ||
689 | NAME_REF@[1165; 1172) | ||
690 | IDENT@[1165; 1172) "ssize_t" | ||
691 | SEMI@[1172; 1173) | ||
692 | WHITESPACE@[1173; 1178) | ||
693 | FN_DEF@[1178; 1289) | ||
694 | VISIBILITY@[1178; 1181) | ||
695 | PUB_KW@[1178; 1181) | ||
696 | WHITESPACE@[1181; 1182) | ||
697 | FN_KW@[1182; 1184) | ||
698 | WHITESPACE@[1184; 1185) | ||
699 | NAME@[1185; 1189) | ||
700 | IDENT@[1185; 1189) "send" | ||
701 | PARAM_LIST@[1189; 1275) | ||
702 | L_PAREN@[1189; 1190) | ||
703 | PARAM@[1190; 1205) | ||
704 | BIND_PAT@[1190; 1196) | ||
705 | NAME@[1190; 1196) | ||
706 | IDENT@[1190; 1196) "socket" | ||
707 | COLON@[1196; 1197) | ||
708 | WHITESPACE@[1197; 1198) | ||
709 | PATH_TYPE@[1198; 1205) | ||
710 | PATH@[1198; 1205) | ||
711 | PATH_SEGMENT@[1198; 1205) | ||
712 | COLONCOLON@[1198; 1200) | ||
713 | NAME_REF@[1200; 1205) | ||
714 | IDENT@[1200; 1205) "c_int" | ||
715 | COMMA@[1205; 1206) | ||
716 | WHITESPACE@[1206; 1207) | ||
717 | PARAM@[1207; 1227) | ||
718 | BIND_PAT@[1207; 1210) | ||
719 | NAME@[1207; 1210) | ||
720 | IDENT@[1207; 1210) "buf" | ||
721 | COLON@[1210; 1211) | ||
722 | WHITESPACE@[1211; 1212) | ||
723 | POINTER_TYPE@[1212; 1227) | ||
724 | STAR@[1212; 1213) | ||
725 | CONST_KW@[1213; 1218) | ||
726 | WHITESPACE@[1218; 1219) | ||
727 | PATH_TYPE@[1219; 1227) | ||
728 | PATH@[1219; 1227) | ||
729 | PATH_SEGMENT@[1219; 1227) | ||
730 | COLONCOLON@[1219; 1221) | ||
731 | NAME_REF@[1221; 1227) | ||
732 | IDENT@[1221; 1227) "c_void" | ||
733 | COMMA@[1227; 1228) | ||
734 | WHITESPACE@[1228; 1229) | ||
735 | PARAM@[1229; 1242) | ||
736 | BIND_PAT@[1229; 1232) | ||
737 | NAME@[1229; 1232) | ||
738 | IDENT@[1229; 1232) "len" | ||
739 | COLON@[1232; 1233) | ||
740 | WHITESPACE@[1233; 1234) | ||
741 | PATH_TYPE@[1234; 1242) | ||
742 | PATH@[1234; 1242) | ||
743 | PATH_SEGMENT@[1234; 1242) | ||
744 | COLONCOLON@[1234; 1236) | ||
745 | NAME_REF@[1236; 1242) | ||
746 | IDENT@[1236; 1242) "size_t" | ||
747 | COMMA@[1242; 1243) | ||
748 | WHITESPACE@[1243; 1260) | ||
749 | PARAM@[1260; 1274) | ||
750 | BIND_PAT@[1260; 1265) | ||
751 | NAME@[1260; 1265) | ||
752 | IDENT@[1260; 1265) "flags" | ||
753 | COLON@[1265; 1266) | ||
754 | WHITESPACE@[1266; 1267) | ||
755 | PATH_TYPE@[1267; 1274) | ||
756 | PATH@[1267; 1274) | ||
757 | PATH_SEGMENT@[1267; 1274) | ||
758 | COLONCOLON@[1267; 1269) | ||
759 | NAME_REF@[1269; 1274) | ||
760 | IDENT@[1269; 1274) "c_int" | ||
761 | R_PAREN@[1274; 1275) | ||
762 | WHITESPACE@[1275; 1276) | ||
763 | RET_TYPE@[1276; 1288) | ||
764 | THIN_ARROW@[1276; 1278) | ||
765 | WHITESPACE@[1278; 1279) | ||
766 | PATH_TYPE@[1279; 1288) | ||
767 | PATH@[1279; 1288) | ||
768 | PATH_SEGMENT@[1279; 1288) | ||
769 | COLONCOLON@[1279; 1281) | ||
770 | NAME_REF@[1281; 1288) | ||
771 | IDENT@[1281; 1288) "ssize_t" | ||
772 | SEMI@[1288; 1289) | ||
773 | WHITESPACE@[1289; 1294) | ||
774 | FN_DEF@[1294; 1481) | ||
775 | VISIBILITY@[1294; 1297) | ||
776 | PUB_KW@[1294; 1297) | ||
777 | WHITESPACE@[1297; 1298) | ||
778 | FN_KW@[1298; 1300) | ||
779 | WHITESPACE@[1300; 1301) | ||
780 | NAME@[1301; 1309) | ||
781 | IDENT@[1301; 1309) "recvfrom" | ||
782 | PARAM_LIST@[1309; 1467) | ||
783 | L_PAREN@[1309; 1310) | ||
784 | PARAM@[1310; 1325) | ||
785 | BIND_PAT@[1310; 1316) | ||
786 | NAME@[1310; 1316) | ||
787 | IDENT@[1310; 1316) "socket" | ||
788 | COLON@[1316; 1317) | ||
789 | WHITESPACE@[1317; 1318) | ||
790 | PATH_TYPE@[1318; 1325) | ||
791 | PATH@[1318; 1325) | ||
792 | PATH_SEGMENT@[1318; 1325) | ||
793 | COLONCOLON@[1318; 1320) | ||
794 | NAME_REF@[1320; 1325) | ||
795 | IDENT@[1320; 1325) "c_int" | ||
796 | COMMA@[1325; 1326) | ||
797 | WHITESPACE@[1326; 1327) | ||
798 | PARAM@[1327; 1345) | ||
799 | BIND_PAT@[1327; 1330) | ||
800 | NAME@[1327; 1330) | ||
801 | IDENT@[1327; 1330) "buf" | ||
802 | COLON@[1330; 1331) | ||
803 | WHITESPACE@[1331; 1332) | ||
804 | POINTER_TYPE@[1332; 1345) | ||
805 | STAR@[1332; 1333) | ||
806 | MUT_KW@[1333; 1336) | ||
807 | WHITESPACE@[1336; 1337) | ||
808 | PATH_TYPE@[1337; 1345) | ||
809 | PATH@[1337; 1345) | ||
810 | PATH_SEGMENT@[1337; 1345) | ||
811 | COLONCOLON@[1337; 1339) | ||
812 | NAME_REF@[1339; 1345) | ||
813 | IDENT@[1339; 1345) "c_void" | ||
814 | COMMA@[1345; 1346) | ||
815 | WHITESPACE@[1346; 1347) | ||
816 | PARAM@[1347; 1360) | ||
817 | BIND_PAT@[1347; 1350) | ||
818 | NAME@[1347; 1350) | ||
819 | IDENT@[1347; 1350) "len" | ||
820 | COLON@[1350; 1351) | ||
821 | WHITESPACE@[1351; 1352) | ||
822 | PATH_TYPE@[1352; 1360) | ||
823 | PATH@[1352; 1360) | ||
824 | PATH_SEGMENT@[1352; 1360) | ||
825 | COLONCOLON@[1352; 1354) | ||
826 | NAME_REF@[1354; 1360) | ||
827 | IDENT@[1354; 1360) "size_t" | ||
828 | COMMA@[1360; 1361) | ||
829 | WHITESPACE@[1361; 1382) | ||
830 | PARAM@[1382; 1396) | ||
831 | BIND_PAT@[1382; 1387) | ||
832 | NAME@[1382; 1387) | ||
833 | IDENT@[1382; 1387) "flags" | ||
834 | COLON@[1387; 1388) | ||
835 | WHITESPACE@[1388; 1389) | ||
836 | PATH_TYPE@[1389; 1396) | ||
837 | PATH@[1389; 1396) | ||
838 | PATH_SEGMENT@[1389; 1396) | ||
839 | COLONCOLON@[1389; 1391) | ||
840 | NAME_REF@[1391; 1396) | ||
841 | IDENT@[1391; 1396) "c_int" | ||
842 | COMMA@[1396; 1397) | ||
843 | WHITESPACE@[1397; 1398) | ||
844 | PARAM@[1398; 1419) | ||
845 | BIND_PAT@[1398; 1402) | ||
846 | NAME@[1398; 1402) | ||
847 | IDENT@[1398; 1402) "addr" | ||
848 | COLON@[1402; 1403) | ||
849 | WHITESPACE@[1403; 1404) | ||
850 | POINTER_TYPE@[1404; 1419) | ||
851 | STAR@[1404; 1405) | ||
852 | MUT_KW@[1405; 1408) | ||
853 | WHITESPACE@[1408; 1409) | ||
854 | PATH_TYPE@[1409; 1419) | ||
855 | PATH@[1409; 1419) | ||
856 | PATH_SEGMENT@[1409; 1419) | ||
857 | COLONCOLON@[1409; 1411) | ||
858 | NAME_REF@[1411; 1419) | ||
859 | IDENT@[1411; 1419) "sockaddr" | ||
860 | COMMA@[1419; 1420) | ||
861 | WHITESPACE@[1420; 1441) | ||
862 | PARAM@[1441; 1466) | ||
863 | BIND_PAT@[1441; 1448) | ||
864 | NAME@[1441; 1448) | ||
865 | IDENT@[1441; 1448) "addrlen" | ||
866 | COLON@[1448; 1449) | ||
867 | WHITESPACE@[1449; 1450) | ||
868 | POINTER_TYPE@[1450; 1466) | ||
869 | STAR@[1450; 1451) | ||
870 | MUT_KW@[1451; 1454) | ||
871 | WHITESPACE@[1454; 1455) | ||
872 | PATH_TYPE@[1455; 1466) | ||
873 | PATH@[1455; 1466) | ||
874 | PATH_SEGMENT@[1455; 1466) | ||
875 | COLONCOLON@[1455; 1457) | ||
876 | NAME_REF@[1457; 1466) | ||
877 | IDENT@[1457; 1466) "socklen_t" | ||
878 | R_PAREN@[1466; 1467) | ||
879 | WHITESPACE@[1467; 1468) | ||
880 | RET_TYPE@[1468; 1480) | ||
881 | THIN_ARROW@[1468; 1470) | ||
882 | WHITESPACE@[1470; 1471) | ||
883 | PATH_TYPE@[1471; 1480) | ||
884 | PATH@[1471; 1480) | ||
885 | PATH_SEGMENT@[1471; 1480) | ||
886 | COLONCOLON@[1471; 1473) | ||
887 | NAME_REF@[1473; 1480) | ||
888 | IDENT@[1473; 1480) "ssize_t" | ||
889 | SEMI@[1480; 1481) | ||
890 | WHITESPACE@[1481; 1486) | ||
891 | FN_DEF@[1486; 1595) | ||
892 | VISIBILITY@[1486; 1489) | ||
893 | PUB_KW@[1486; 1489) | ||
894 | WHITESPACE@[1489; 1490) | ||
895 | FN_KW@[1490; 1492) | ||
896 | WHITESPACE@[1492; 1493) | ||
897 | NAME@[1493; 1497) | ||
898 | IDENT@[1493; 1497) "recv" | ||
899 | PARAM_LIST@[1497; 1581) | ||
900 | L_PAREN@[1497; 1498) | ||
901 | PARAM@[1498; 1513) | ||
902 | BIND_PAT@[1498; 1504) | ||
903 | NAME@[1498; 1504) | ||
904 | IDENT@[1498; 1504) "socket" | ||
905 | COLON@[1504; 1505) | ||
906 | WHITESPACE@[1505; 1506) | ||
907 | PATH_TYPE@[1506; 1513) | ||
908 | PATH@[1506; 1513) | ||
909 | PATH_SEGMENT@[1506; 1513) | ||
910 | COLONCOLON@[1506; 1508) | ||
911 | NAME_REF@[1508; 1513) | ||
912 | IDENT@[1508; 1513) "c_int" | ||
913 | COMMA@[1513; 1514) | ||
914 | WHITESPACE@[1514; 1515) | ||
915 | PARAM@[1515; 1533) | ||
916 | BIND_PAT@[1515; 1518) | ||
917 | NAME@[1515; 1518) | ||
918 | IDENT@[1515; 1518) "buf" | ||
919 | COLON@[1518; 1519) | ||
920 | WHITESPACE@[1519; 1520) | ||
921 | POINTER_TYPE@[1520; 1533) | ||
922 | STAR@[1520; 1521) | ||
923 | MUT_KW@[1521; 1524) | ||
924 | WHITESPACE@[1524; 1525) | ||
925 | PATH_TYPE@[1525; 1533) | ||
926 | PATH@[1525; 1533) | ||
927 | PATH_SEGMENT@[1525; 1533) | ||
928 | COLONCOLON@[1525; 1527) | ||
929 | NAME_REF@[1527; 1533) | ||
930 | IDENT@[1527; 1533) "c_void" | ||
931 | COMMA@[1533; 1534) | ||
932 | WHITESPACE@[1534; 1535) | ||
933 | PARAM@[1535; 1548) | ||
934 | BIND_PAT@[1535; 1538) | ||
935 | NAME@[1535; 1538) | ||
936 | IDENT@[1535; 1538) "len" | ||
937 | COLON@[1538; 1539) | ||
938 | WHITESPACE@[1539; 1540) | ||
939 | PATH_TYPE@[1540; 1548) | ||
940 | PATH@[1540; 1548) | ||
941 | PATH_SEGMENT@[1540; 1548) | ||
942 | COLONCOLON@[1540; 1542) | ||
943 | NAME_REF@[1542; 1548) | ||
944 | IDENT@[1542; 1548) "size_t" | ||
945 | COMMA@[1548; 1549) | ||
946 | WHITESPACE@[1549; 1566) | ||
947 | PARAM@[1566; 1580) | ||
948 | BIND_PAT@[1566; 1571) | ||
949 | NAME@[1566; 1571) | ||
950 | IDENT@[1566; 1571) "flags" | ||
951 | COLON@[1571; 1572) | ||
952 | WHITESPACE@[1572; 1573) | ||
953 | PATH_TYPE@[1573; 1580) | ||
954 | PATH@[1573; 1580) | ||
955 | PATH_SEGMENT@[1573; 1580) | ||
956 | COLONCOLON@[1573; 1575) | ||
957 | NAME_REF@[1575; 1580) | ||
958 | IDENT@[1575; 1580) "c_int" | ||
959 | R_PAREN@[1580; 1581) | ||
960 | WHITESPACE@[1581; 1582) | ||
961 | RET_TYPE@[1582; 1594) | ||
962 | THIN_ARROW@[1582; 1584) | ||
963 | WHITESPACE@[1584; 1585) | ||
964 | PATH_TYPE@[1585; 1594) | ||
965 | PATH@[1585; 1594) | ||
966 | PATH_SEGMENT@[1585; 1594) | ||
967 | COLONCOLON@[1585; 1587) | ||
968 | NAME_REF@[1587; 1594) | ||
969 | IDENT@[1587; 1594) "ssize_t" | ||
970 | SEMI@[1594; 1595) | ||
971 | WHITESPACE@[1595; 1596) | ||
972 | R_CURLY@[1596; 1597) | ||
973 | WHITESPACE@[1597; 1598) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0032_where_for.rs b/crates/ra_syntax/tests/data/parser/ok/0032_where_for.rs new file mode 100644 index 000000000..588170fbe --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0032_where_for.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn test_serialization<SER>() | ||
2 | where | ||
3 | SER: Serialize + for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug, | ||
4 | {} | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0032_where_for.txt b/crates/ra_syntax/tests/data/parser/ok/0032_where_for.txt new file mode 100644 index 000000000..e3b9386a8 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0032_where_for.txt | |||
@@ -0,0 +1,85 @@ | |||
1 | ROOT@[0; 116) | ||
2 | FN_DEF@[0; 115) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 21) | ||
6 | IDENT@[3; 21) "test_serialization" | ||
7 | TYPE_PARAM_LIST@[21; 26) | ||
8 | L_ANGLE@[21; 22) | ||
9 | TYPE_PARAM@[22; 25) | ||
10 | NAME@[22; 25) | ||
11 | IDENT@[22; 25) "SER" | ||
12 | R_ANGLE@[25; 26) | ||
13 | PARAM_LIST@[26; 28) | ||
14 | L_PAREN@[26; 27) | ||
15 | R_PAREN@[27; 28) | ||
16 | WHITESPACE@[28; 29) | ||
17 | WHERE_CLAUSE@[29; 112) | ||
18 | WHERE_KW@[29; 34) | ||
19 | WHITESPACE@[34; 39) | ||
20 | WHERE_PRED@[39; 111) | ||
21 | PATH_TYPE@[39; 42) | ||
22 | PATH@[39; 42) | ||
23 | PATH_SEGMENT@[39; 42) | ||
24 | NAME_REF@[39; 42) | ||
25 | IDENT@[39; 42) "SER" | ||
26 | COLON@[42; 43) | ||
27 | WHITESPACE@[43; 44) | ||
28 | PATH_TYPE@[44; 111) | ||
29 | PATH@[44; 53) | ||
30 | PATH_SEGMENT@[44; 53) | ||
31 | NAME_REF@[44; 53) | ||
32 | IDENT@[44; 53) "Serialize" | ||
33 | WHITESPACE@[53; 54) | ||
34 | PLUS@[54; 55) | ||
35 | WHITESPACE@[55; 56) | ||
36 | FOR_TYPE@[56; 81) | ||
37 | FOR_KW@[56; 59) | ||
38 | TYPE_PARAM_LIST@[59; 64) | ||
39 | L_ANGLE@[59; 60) | ||
40 | LIFETIME_PARAM@[60; 63) | ||
41 | LIFETIME@[60; 63) "'de" | ||
42 | R_ANGLE@[63; 64) | ||
43 | WHITESPACE@[64; 65) | ||
44 | PATH_TYPE@[65; 81) | ||
45 | PATH@[65; 81) | ||
46 | PATH_SEGMENT@[65; 81) | ||
47 | NAME_REF@[65; 76) | ||
48 | IDENT@[65; 76) "Deserialize" | ||
49 | TYPE_ARG_LIST@[76; 81) | ||
50 | L_ANGLE@[76; 77) | ||
51 | LIFETIME_ARG@[77; 80) | ||
52 | LIFETIME@[77; 80) "'de" | ||
53 | R_ANGLE@[80; 81) | ||
54 | WHITESPACE@[81; 82) | ||
55 | PLUS@[82; 83) | ||
56 | WHITESPACE@[83; 84) | ||
57 | PATH_TYPE@[84; 111) | ||
58 | PATH@[84; 93) | ||
59 | PATH_SEGMENT@[84; 93) | ||
60 | NAME_REF@[84; 93) | ||
61 | IDENT@[84; 93) "PartialEq" | ||
62 | WHITESPACE@[93; 94) | ||
63 | PLUS@[94; 95) | ||
64 | WHITESPACE@[95; 96) | ||
65 | PATH_TYPE@[96; 111) | ||
66 | PATH@[96; 111) | ||
67 | PATH@[96; 104) | ||
68 | PATH@[96; 99) | ||
69 | PATH_SEGMENT@[96; 99) | ||
70 | NAME_REF@[96; 99) | ||
71 | IDENT@[96; 99) "std" | ||
72 | COLONCOLON@[99; 101) | ||
73 | PATH_SEGMENT@[101; 104) | ||
74 | NAME_REF@[101; 104) | ||
75 | IDENT@[101; 104) "fmt" | ||
76 | COLONCOLON@[104; 106) | ||
77 | PATH_SEGMENT@[106; 111) | ||
78 | NAME_REF@[106; 111) | ||
79 | IDENT@[106; 111) "Debug" | ||
80 | COMMA@[111; 112) | ||
81 | WHITESPACE@[112; 113) | ||
82 | BLOCK@[113; 115) | ||
83 | L_CURLY@[113; 114) | ||
84 | R_CURLY@[114; 115) | ||
85 | WHITESPACE@[115; 116) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0033_label_break.rs b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.rs new file mode 100644 index 000000000..728d78137 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.rs | |||
@@ -0,0 +1,28 @@ | |||
1 | // format with label break value. | ||
2 | fn main() { | ||
3 | 'empty_block: {} | ||
4 | |||
5 | 'block: { | ||
6 | do_thing(); | ||
7 | if condition_not_met() { | ||
8 | break 'block; | ||
9 | } | ||
10 | do_next_thing(); | ||
11 | if condition_not_met() { | ||
12 | break 'block; | ||
13 | } | ||
14 | do_last_thing(); | ||
15 | } | ||
16 | |||
17 | let result = 'block: { | ||
18 | if foo() { | ||
19 | // comment | ||
20 | break 'block 1; | ||
21 | } | ||
22 | if bar() { | ||
23 | /* comment */ | ||
24 | break 'block 2; | ||
25 | } | ||
26 | 3 | ||
27 | }; | ||
28 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt new file mode 100644 index 000000000..6abb9234c --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0033_label_break.txt | |||
@@ -0,0 +1,215 @@ | |||
1 | ROOT@[0; 506) | ||
2 | COMMENT@[0; 33) | ||
3 | WHITESPACE@[33; 34) | ||
4 | FN_DEF@[34; 505) | ||
5 | FN_KW@[34; 36) | ||
6 | WHITESPACE@[36; 37) | ||
7 | NAME@[37; 41) | ||
8 | IDENT@[37; 41) "main" | ||
9 | PARAM_LIST@[41; 43) | ||
10 | L_PAREN@[41; 42) | ||
11 | R_PAREN@[42; 43) | ||
12 | WHITESPACE@[43; 44) | ||
13 | BLOCK@[44; 505) | ||
14 | L_CURLY@[44; 45) | ||
15 | WHITESPACE@[45; 50) | ||
16 | EXPR_STMT@[50; 66) | ||
17 | BLOCK_EXPR@[50; 66) | ||
18 | LABEL@[50; 63) | ||
19 | LIFETIME@[50; 62) "'empty_block" | ||
20 | COLON@[62; 63) | ||
21 | WHITESPACE@[63; 64) | ||
22 | BLOCK@[64; 66) | ||
23 | L_CURLY@[64; 65) | ||
24 | R_CURLY@[65; 66) | ||
25 | WHITESPACE@[66; 72) | ||
26 | EXPR_STMT@[72; 295) | ||
27 | BLOCK_EXPR@[72; 295) | ||
28 | LABEL@[72; 79) | ||
29 | LIFETIME@[72; 78) "'block" | ||
30 | COLON@[78; 79) | ||
31 | WHITESPACE@[79; 80) | ||
32 | BLOCK@[80; 295) | ||
33 | L_CURLY@[80; 81) | ||
34 | WHITESPACE@[81; 90) | ||
35 | EXPR_STMT@[90; 101) | ||
36 | CALL_EXPR@[90; 100) | ||
37 | PATH_EXPR@[90; 98) | ||
38 | PATH@[90; 98) | ||
39 | PATH_SEGMENT@[90; 98) | ||
40 | NAME_REF@[90; 98) | ||
41 | IDENT@[90; 98) "do_thing" | ||
42 | ARG_LIST@[98; 100) | ||
43 | L_PAREN@[98; 99) | ||
44 | R_PAREN@[99; 100) | ||
45 | SEMI@[100; 101) | ||
46 | WHITESPACE@[101; 110) | ||
47 | EXPR_STMT@[110; 170) | ||
48 | IF_EXPR@[110; 170) | ||
49 | IF_KW@[110; 112) | ||
50 | WHITESPACE@[112; 113) | ||
51 | CONDITION@[113; 132) | ||
52 | CALL_EXPR@[113; 132) | ||
53 | PATH_EXPR@[113; 130) | ||
54 | PATH@[113; 130) | ||
55 | PATH_SEGMENT@[113; 130) | ||
56 | NAME_REF@[113; 130) | ||
57 | IDENT@[113; 130) "condition_not_met" | ||
58 | ARG_LIST@[130; 132) | ||
59 | L_PAREN@[130; 131) | ||
60 | R_PAREN@[131; 132) | ||
61 | WHITESPACE@[132; 133) | ||
62 | BLOCK@[133; 170) | ||
63 | L_CURLY@[133; 134) | ||
64 | WHITESPACE@[134; 147) | ||
65 | EXPR_STMT@[147; 160) | ||
66 | BREAK_EXPR@[147; 159) | ||
67 | BREAK_KW@[147; 152) | ||
68 | WHITESPACE@[152; 153) | ||
69 | LIFETIME@[153; 159) "'block" | ||
70 | SEMI@[159; 160) | ||
71 | WHITESPACE@[160; 169) | ||
72 | R_CURLY@[169; 170) | ||
73 | WHITESPACE@[170; 179) | ||
74 | EXPR_STMT@[179; 195) | ||
75 | CALL_EXPR@[179; 194) | ||
76 | PATH_EXPR@[179; 192) | ||
77 | PATH@[179; 192) | ||
78 | PATH_SEGMENT@[179; 192) | ||
79 | NAME_REF@[179; 192) | ||
80 | IDENT@[179; 192) "do_next_thing" | ||
81 | ARG_LIST@[192; 194) | ||
82 | L_PAREN@[192; 193) | ||
83 | R_PAREN@[193; 194) | ||
84 | SEMI@[194; 195) | ||
85 | WHITESPACE@[195; 204) | ||
86 | EXPR_STMT@[204; 264) | ||
87 | IF_EXPR@[204; 264) | ||
88 | IF_KW@[204; 206) | ||
89 | WHITESPACE@[206; 207) | ||
90 | CONDITION@[207; 226) | ||
91 | CALL_EXPR@[207; 226) | ||
92 | PATH_EXPR@[207; 224) | ||
93 | PATH@[207; 224) | ||
94 | PATH_SEGMENT@[207; 224) | ||
95 | NAME_REF@[207; 224) | ||
96 | IDENT@[207; 224) "condition_not_met" | ||
97 | ARG_LIST@[224; 226) | ||
98 | L_PAREN@[224; 225) | ||
99 | R_PAREN@[225; 226) | ||
100 | WHITESPACE@[226; 227) | ||
101 | BLOCK@[227; 264) | ||
102 | L_CURLY@[227; 228) | ||
103 | WHITESPACE@[228; 241) | ||
104 | EXPR_STMT@[241; 254) | ||
105 | BREAK_EXPR@[241; 253) | ||
106 | BREAK_KW@[241; 246) | ||
107 | WHITESPACE@[246; 247) | ||
108 | LIFETIME@[247; 253) "'block" | ||
109 | SEMI@[253; 254) | ||
110 | WHITESPACE@[254; 263) | ||
111 | R_CURLY@[263; 264) | ||
112 | WHITESPACE@[264; 273) | ||
113 | EXPR_STMT@[273; 289) | ||
114 | CALL_EXPR@[273; 288) | ||
115 | PATH_EXPR@[273; 286) | ||
116 | PATH@[273; 286) | ||
117 | PATH_SEGMENT@[273; 286) | ||
118 | NAME_REF@[273; 286) | ||
119 | IDENT@[273; 286) "do_last_thing" | ||
120 | ARG_LIST@[286; 288) | ||
121 | L_PAREN@[286; 287) | ||
122 | R_PAREN@[287; 288) | ||
123 | SEMI@[288; 289) | ||
124 | WHITESPACE@[289; 294) | ||
125 | R_CURLY@[294; 295) | ||
126 | WHITESPACE@[295; 301) | ||
127 | LET_STMT@[301; 503) | ||
128 | LET_KW@[301; 304) | ||
129 | WHITESPACE@[304; 305) | ||
130 | BIND_PAT@[305; 311) | ||
131 | NAME@[305; 311) | ||
132 | IDENT@[305; 311) "result" | ||
133 | WHITESPACE@[311; 312) | ||
134 | EQ@[312; 313) | ||
135 | WHITESPACE@[313; 314) | ||
136 | BLOCK_EXPR@[314; 502) | ||
137 | LABEL@[314; 321) | ||
138 | LIFETIME@[314; 320) "'block" | ||
139 | COLON@[320; 321) | ||
140 | WHITESPACE@[321; 322) | ||
141 | BLOCK@[322; 502) | ||
142 | L_CURLY@[322; 323) | ||
143 | WHITESPACE@[323; 332) | ||
144 | EXPR_STMT@[332; 403) | ||
145 | IF_EXPR@[332; 403) | ||
146 | IF_KW@[332; 334) | ||
147 | WHITESPACE@[334; 335) | ||
148 | CONDITION@[335; 340) | ||
149 | CALL_EXPR@[335; 340) | ||
150 | PATH_EXPR@[335; 338) | ||
151 | PATH@[335; 338) | ||
152 | PATH_SEGMENT@[335; 338) | ||
153 | NAME_REF@[335; 338) | ||
154 | IDENT@[335; 338) "foo" | ||
155 | ARG_LIST@[338; 340) | ||
156 | L_PAREN@[338; 339) | ||
157 | R_PAREN@[339; 340) | ||
158 | WHITESPACE@[340; 341) | ||
159 | BLOCK@[341; 403) | ||
160 | L_CURLY@[341; 342) | ||
161 | WHITESPACE@[342; 355) | ||
162 | COMMENT@[355; 365) | ||
163 | WHITESPACE@[365; 378) | ||
164 | EXPR_STMT@[378; 393) | ||
165 | BREAK_EXPR@[378; 392) | ||
166 | BREAK_KW@[378; 383) | ||
167 | WHITESPACE@[383; 384) | ||
168 | LIFETIME@[384; 390) "'block" | ||
169 | WHITESPACE@[390; 391) | ||
170 | LITERAL@[391; 392) | ||
171 | INT_NUMBER@[391; 392) "1" | ||
172 | SEMI@[392; 393) | ||
173 | WHITESPACE@[393; 402) | ||
174 | R_CURLY@[402; 403) | ||
175 | WHITESPACE@[403; 412) | ||
176 | EXPR_STMT@[412; 486) | ||
177 | IF_EXPR@[412; 486) | ||
178 | IF_KW@[412; 414) | ||
179 | WHITESPACE@[414; 415) | ||
180 | CONDITION@[415; 420) | ||
181 | CALL_EXPR@[415; 420) | ||
182 | PATH_EXPR@[415; 418) | ||
183 | PATH@[415; 418) | ||
184 | PATH_SEGMENT@[415; 418) | ||
185 | NAME_REF@[415; 418) | ||
186 | IDENT@[415; 418) "bar" | ||
187 | ARG_LIST@[418; 420) | ||
188 | L_PAREN@[418; 419) | ||
189 | R_PAREN@[419; 420) | ||
190 | WHITESPACE@[420; 421) | ||
191 | BLOCK@[421; 486) | ||
192 | L_CURLY@[421; 422) | ||
193 | WHITESPACE@[422; 435) | ||
194 | COMMENT@[435; 448) | ||
195 | WHITESPACE@[448; 461) | ||
196 | EXPR_STMT@[461; 476) | ||
197 | BREAK_EXPR@[461; 475) | ||
198 | BREAK_KW@[461; 466) | ||
199 | WHITESPACE@[466; 467) | ||
200 | LIFETIME@[467; 473) "'block" | ||
201 | WHITESPACE@[473; 474) | ||
202 | LITERAL@[474; 475) | ||
203 | INT_NUMBER@[474; 475) "2" | ||
204 | SEMI@[475; 476) | ||
205 | WHITESPACE@[476; 485) | ||
206 | R_CURLY@[485; 486) | ||
207 | WHITESPACE@[486; 495) | ||
208 | LITERAL@[495; 496) | ||
209 | INT_NUMBER@[495; 496) "3" | ||
210 | WHITESPACE@[496; 501) | ||
211 | R_CURLY@[501; 502) | ||
212 | SEMI@[502; 503) | ||
213 | WHITESPACE@[503; 504) | ||
214 | R_CURLY@[504; 505) | ||
215 | WHITESPACE@[505; 506) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.rs b/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.rs new file mode 100644 index 000000000..2a70ee83a --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.rs | |||
@@ -0,0 +1,16 @@ | |||
1 | macro parse_use_trees($($s:expr),* $(,)*) { | ||
2 | vec![ | ||
3 | $(parse_use_tree($s),)* | ||
4 | ] | ||
5 | } | ||
6 | |||
7 | #[test] | ||
8 | fn test_use_tree_merge() { | ||
9 | macro test_merge([$($input:expr),* $(,)*], [$($output:expr),* $(,)*]) { | ||
10 | assert_eq!( | ||
11 | merge_use_trees(parse_use_trees!($($input,)*)), | ||
12 | parse_use_trees!($($output,)*), | ||
13 | ); | ||
14 | } | ||
15 | } | ||
16 | |||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.txt b/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.txt new file mode 100644 index 000000000..74af9d71b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0034_macro_2.0.txt | |||
@@ -0,0 +1,317 @@ | |||
1 | ROOT@[0; 350) | ||
2 | MACRO_CALL@[0; 41) | ||
3 | PATH@[0; 5) | ||
4 | PATH_SEGMENT@[0; 5) | ||
5 | NAME_REF@[0; 5) | ||
6 | IDENT@[0; 5) "macro" | ||
7 | err: `expected EXCL` | ||
8 | WHITESPACE@[5; 6) | ||
9 | IDENT@[6; 21) "parse_use_trees" | ||
10 | TOKEN_TREE@[21; 41) | ||
11 | L_PAREN@[21; 22) | ||
12 | DOLLAR@[22; 23) | ||
13 | TOKEN_TREE@[23; 32) | ||
14 | L_PAREN@[23; 24) | ||
15 | DOLLAR@[24; 25) | ||
16 | IDENT@[25; 26) "s" | ||
17 | COLON@[26; 27) | ||
18 | IDENT@[27; 31) "expr" | ||
19 | R_PAREN@[31; 32) | ||
20 | COMMA@[32; 33) | ||
21 | STAR@[33; 34) | ||
22 | WHITESPACE@[34; 35) | ||
23 | DOLLAR@[35; 36) | ||
24 | TOKEN_TREE@[36; 39) | ||
25 | L_PAREN@[36; 37) | ||
26 | COMMA@[37; 38) | ||
27 | R_PAREN@[38; 39) | ||
28 | STAR@[39; 40) | ||
29 | R_PAREN@[40; 41) | ||
30 | err: `expected SEMI` | ||
31 | WHITESPACE@[41; 42) | ||
32 | err: `expected an item` | ||
33 | ERROR@[42; 93) | ||
34 | L_CURLY@[42; 43) | ||
35 | WHITESPACE@[43; 48) | ||
36 | IDENT@[48; 51) "vec" | ||
37 | EXCL@[51; 52) | ||
38 | L_BRACK@[52; 53) | ||
39 | WHITESPACE@[53; 62) | ||
40 | DOLLAR@[62; 63) | ||
41 | L_PAREN@[63; 64) | ||
42 | IDENT@[64; 78) "parse_use_tree" | ||
43 | L_PAREN@[78; 79) | ||
44 | DOLLAR@[79; 80) | ||
45 | IDENT@[80; 81) "s" | ||
46 | R_PAREN@[81; 82) | ||
47 | COMMA@[82; 83) | ||
48 | R_PAREN@[83; 84) | ||
49 | STAR@[84; 85) | ||
50 | WHITESPACE@[85; 90) | ||
51 | R_BRACK@[90; 91) | ||
52 | WHITESPACE@[91; 92) | ||
53 | R_CURLY@[92; 93) | ||
54 | WHITESPACE@[93; 95) | ||
55 | FN_DEF@[95; 348) | ||
56 | ATTR@[95; 102) | ||
57 | POUND@[95; 96) | ||
58 | TOKEN_TREE@[96; 102) | ||
59 | L_BRACK@[96; 97) | ||
60 | IDENT@[97; 101) "test" | ||
61 | R_BRACK@[101; 102) | ||
62 | WHITESPACE@[102; 103) | ||
63 | FN_KW@[103; 105) | ||
64 | WHITESPACE@[105; 106) | ||
65 | NAME@[106; 125) | ||
66 | IDENT@[106; 125) "test_use_tree_merge" | ||
67 | PARAM_LIST@[125; 127) | ||
68 | L_PAREN@[125; 126) | ||
69 | R_PAREN@[126; 127) | ||
70 | WHITESPACE@[127; 128) | ||
71 | BLOCK@[128; 348) | ||
72 | L_CURLY@[128; 129) | ||
73 | WHITESPACE@[129; 134) | ||
74 | EXPR_STMT@[134; 139) | ||
75 | PATH_EXPR@[134; 139) | ||
76 | PATH@[134; 139) | ||
77 | PATH_SEGMENT@[134; 139) | ||
78 | NAME_REF@[134; 139) | ||
79 | IDENT@[134; 139) "macro" | ||
80 | err: `expected SEMI` | ||
81 | WHITESPACE@[139; 140) | ||
82 | EXPR_STMT@[140; 154) | ||
83 | CALL_EXPR@[140; 154) | ||
84 | PATH_EXPR@[140; 150) | ||
85 | PATH@[140; 150) | ||
86 | PATH_SEGMENT@[140; 150) | ||
87 | NAME_REF@[140; 150) | ||
88 | IDENT@[140; 150) "test_merge" | ||
89 | ARG_LIST@[150; 154) | ||
90 | L_PAREN@[150; 151) | ||
91 | ARRAY_EXPR@[151; 154) | ||
92 | L_BRACK@[151; 152) | ||
93 | err: `expected expression` | ||
94 | ERROR@[152; 153) | ||
95 | DOLLAR@[152; 153) | ||
96 | err: `expected COMMA` | ||
97 | PAREN_EXPR@[153; 154) | ||
98 | L_PAREN@[153; 154) | ||
99 | err: `expected expression` | ||
100 | err: `expected R_PAREN` | ||
101 | err: `expected COMMA` | ||
102 | err: `expected expression` | ||
103 | err: `expected R_BRACK` | ||
104 | err: `expected COMMA` | ||
105 | err: `expected SEMI` | ||
106 | err: `expected expression` | ||
107 | EXPR_STMT@[154; 155) | ||
108 | ERROR@[154; 155) | ||
109 | DOLLAR@[154; 155) | ||
110 | err: `expected SEMI` | ||
111 | EXPR_STMT@[155; 160) | ||
112 | PATH_EXPR@[155; 160) | ||
113 | PATH@[155; 160) | ||
114 | PATH_SEGMENT@[155; 160) | ||
115 | NAME_REF@[155; 160) | ||
116 | IDENT@[155; 160) "input" | ||
117 | err: `expected SEMI` | ||
118 | err: `expected expression` | ||
119 | EXPR_STMT@[160; 161) | ||
120 | ERROR@[160; 161) | ||
121 | COLON@[160; 161) | ||
122 | err: `expected SEMI` | ||
123 | EXPR_STMT@[161; 165) | ||
124 | PATH_EXPR@[161; 165) | ||
125 | PATH@[161; 165) | ||
126 | PATH_SEGMENT@[161; 165) | ||
127 | NAME_REF@[161; 165) | ||
128 | IDENT@[161; 165) "expr" | ||
129 | err: `expected SEMI` | ||
130 | err: `expected expression` | ||
131 | EXPR_STMT@[165; 166) | ||
132 | ERROR@[165; 166) | ||
133 | R_PAREN@[165; 166) | ||
134 | err: `expected SEMI` | ||
135 | err: `expected expression` | ||
136 | EXPR_STMT@[166; 167) | ||
137 | ERROR@[166; 167) | ||
138 | COMMA@[166; 167) | ||
139 | err: `expected SEMI` | ||
140 | EXPR_STMT@[167; 170) | ||
141 | PREFIX_EXPR@[167; 170) | ||
142 | STAR@[167; 168) | ||
143 | WHITESPACE@[168; 169) | ||
144 | err: `expected expression` | ||
145 | ERROR@[169; 170) | ||
146 | DOLLAR@[169; 170) | ||
147 | err: `expected SEMI` | ||
148 | EXPR_STMT@[170; 171) | ||
149 | PAREN_EXPR@[170; 171) | ||
150 | L_PAREN@[170; 171) | ||
151 | err: `expected expression` | ||
152 | err: `expected R_PAREN` | ||
153 | err: `expected SEMI` | ||
154 | err: `expected expression` | ||
155 | EXPR_STMT@[171; 172) | ||
156 | ERROR@[171; 172) | ||
157 | COMMA@[171; 172) | ||
158 | err: `expected SEMI` | ||
159 | err: `expected expression` | ||
160 | EXPR_STMT@[172; 173) | ||
161 | ERROR@[172; 173) | ||
162 | R_PAREN@[172; 173) | ||
163 | err: `expected SEMI` | ||
164 | EXPR_STMT@[173; 175) | ||
165 | PREFIX_EXPR@[173; 175) | ||
166 | STAR@[173; 174) | ||
167 | err: `expected expression` | ||
168 | ERROR@[174; 175) | ||
169 | R_BRACK@[174; 175) | ||
170 | err: `expected SEMI` | ||
171 | err: `expected expression` | ||
172 | EXPR_STMT@[175; 176) | ||
173 | ERROR@[175; 176) | ||
174 | COMMA@[175; 176) | ||
175 | err: `expected SEMI` | ||
176 | WHITESPACE@[176; 177) | ||
177 | EXPR_STMT@[177; 180) | ||
178 | ARRAY_EXPR@[177; 180) | ||
179 | L_BRACK@[177; 178) | ||
180 | err: `expected expression` | ||
181 | ERROR@[178; 179) | ||
182 | DOLLAR@[178; 179) | ||
183 | err: `expected COMMA` | ||
184 | PAREN_EXPR@[179; 180) | ||
185 | L_PAREN@[179; 180) | ||
186 | err: `expected expression` | ||
187 | err: `expected R_PAREN` | ||
188 | err: `expected COMMA` | ||
189 | err: `expected expression` | ||
190 | err: `expected R_BRACK` | ||
191 | err: `expected SEMI` | ||
192 | err: `expected expression` | ||
193 | EXPR_STMT@[180; 181) | ||
194 | ERROR@[180; 181) | ||
195 | DOLLAR@[180; 181) | ||
196 | err: `expected SEMI` | ||
197 | EXPR_STMT@[181; 187) | ||
198 | PATH_EXPR@[181; 187) | ||
199 | PATH@[181; 187) | ||
200 | PATH_SEGMENT@[181; 187) | ||
201 | NAME_REF@[181; 187) | ||
202 | IDENT@[181; 187) "output" | ||
203 | err: `expected SEMI` | ||
204 | err: `expected expression` | ||
205 | EXPR_STMT@[187; 188) | ||
206 | ERROR@[187; 188) | ||
207 | COLON@[187; 188) | ||
208 | err: `expected SEMI` | ||
209 | EXPR_STMT@[188; 192) | ||
210 | PATH_EXPR@[188; 192) | ||
211 | PATH@[188; 192) | ||
212 | PATH_SEGMENT@[188; 192) | ||
213 | NAME_REF@[188; 192) | ||
214 | IDENT@[188; 192) "expr" | ||
215 | err: `expected SEMI` | ||
216 | err: `expected expression` | ||
217 | EXPR_STMT@[192; 193) | ||
218 | ERROR@[192; 193) | ||
219 | R_PAREN@[192; 193) | ||
220 | err: `expected SEMI` | ||
221 | err: `expected expression` | ||
222 | EXPR_STMT@[193; 194) | ||
223 | ERROR@[193; 194) | ||
224 | COMMA@[193; 194) | ||
225 | err: `expected SEMI` | ||
226 | EXPR_STMT@[194; 197) | ||
227 | PREFIX_EXPR@[194; 197) | ||
228 | STAR@[194; 195) | ||
229 | WHITESPACE@[195; 196) | ||
230 | err: `expected expression` | ||
231 | ERROR@[196; 197) | ||
232 | DOLLAR@[196; 197) | ||
233 | err: `expected SEMI` | ||
234 | EXPR_STMT@[197; 198) | ||
235 | PAREN_EXPR@[197; 198) | ||
236 | L_PAREN@[197; 198) | ||
237 | err: `expected expression` | ||
238 | err: `expected R_PAREN` | ||
239 | err: `expected SEMI` | ||
240 | err: `expected expression` | ||
241 | EXPR_STMT@[198; 199) | ||
242 | ERROR@[198; 199) | ||
243 | COMMA@[198; 199) | ||
244 | err: `expected SEMI` | ||
245 | err: `expected expression` | ||
246 | EXPR_STMT@[199; 200) | ||
247 | ERROR@[199; 200) | ||
248 | R_PAREN@[199; 200) | ||
249 | err: `expected SEMI` | ||
250 | EXPR_STMT@[200; 202) | ||
251 | PREFIX_EXPR@[200; 202) | ||
252 | STAR@[200; 201) | ||
253 | err: `expected expression` | ||
254 | ERROR@[201; 202) | ||
255 | R_BRACK@[201; 202) | ||
256 | err: `expected SEMI` | ||
257 | err: `expected expression` | ||
258 | EXPR_STMT@[202; 203) | ||
259 | ERROR@[202; 203) | ||
260 | R_PAREN@[202; 203) | ||
261 | err: `expected SEMI` | ||
262 | WHITESPACE@[203; 204) | ||
263 | BLOCK_EXPR@[204; 346) | ||
264 | BLOCK@[204; 346) | ||
265 | L_CURLY@[204; 205) | ||
266 | WHITESPACE@[205; 214) | ||
267 | EXPR_STMT@[214; 340) | ||
268 | MACRO_CALL@[214; 339) | ||
269 | PATH@[214; 223) | ||
270 | PATH_SEGMENT@[214; 223) | ||
271 | NAME_REF@[214; 223) | ||
272 | IDENT@[214; 223) "assert_eq" | ||
273 | EXCL@[223; 224) | ||
274 | TOKEN_TREE@[224; 339) | ||
275 | L_PAREN@[224; 225) | ||
276 | WHITESPACE@[225; 238) | ||
277 | IDENT@[238; 253) "merge_use_trees" | ||
278 | TOKEN_TREE@[253; 284) | ||
279 | L_PAREN@[253; 254) | ||
280 | IDENT@[254; 269) "parse_use_trees" | ||
281 | EXCL@[269; 270) | ||
282 | TOKEN_TREE@[270; 283) | ||
283 | L_PAREN@[270; 271) | ||
284 | DOLLAR@[271; 272) | ||
285 | TOKEN_TREE@[272; 281) | ||
286 | L_PAREN@[272; 273) | ||
287 | DOLLAR@[273; 274) | ||
288 | IDENT@[274; 279) "input" | ||
289 | COMMA@[279; 280) | ||
290 | R_PAREN@[280; 281) | ||
291 | STAR@[281; 282) | ||
292 | R_PAREN@[282; 283) | ||
293 | R_PAREN@[283; 284) | ||
294 | COMMA@[284; 285) | ||
295 | WHITESPACE@[285; 298) | ||
296 | IDENT@[298; 313) "parse_use_trees" | ||
297 | EXCL@[313; 314) | ||
298 | TOKEN_TREE@[314; 328) | ||
299 | L_PAREN@[314; 315) | ||
300 | DOLLAR@[315; 316) | ||
301 | TOKEN_TREE@[316; 326) | ||
302 | L_PAREN@[316; 317) | ||
303 | DOLLAR@[317; 318) | ||
304 | IDENT@[318; 324) "output" | ||
305 | COMMA@[324; 325) | ||
306 | R_PAREN@[325; 326) | ||
307 | STAR@[326; 327) | ||
308 | R_PAREN@[327; 328) | ||
309 | COMMA@[328; 329) | ||
310 | WHITESPACE@[329; 338) | ||
311 | R_PAREN@[338; 339) | ||
312 | SEMI@[339; 340) | ||
313 | WHITESPACE@[340; 345) | ||
314 | R_CURLY@[345; 346) | ||
315 | WHITESPACE@[346; 347) | ||
316 | R_CURLY@[347; 348) | ||
317 | WHITESPACE@[348; 350) | ||
diff --git a/crates/ra_syntax/tests/data/parser/ok/0034_macro_stuck.txt b/crates/ra_syntax/tests/data/parser/ok/0034_macro_stuck.txt new file mode 100644 index 000000000..1a8ca761d --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/ok/0034_macro_stuck.txt | |||
@@ -0,0 +1,250 @@ | |||
1 | ROOT@[0; 350) | ||
2 | MACRO_CALL@[0; 41) | ||
3 | PATH@[0; 5) | ||
4 | PATH_SEGMENT@[0; 5) | ||
5 | NAME_REF@[0; 5) | ||
6 | IDENT@[0; 5) "macro" | ||
7 | err: `expected EXCL` | ||
8 | WHITESPACE@[5; 6) | ||
9 | IDENT@[6; 21) "parse_use_trees" | ||
10 | TOKEN_TREE@[21; 41) | ||
11 | L_PAREN@[21; 22) | ||
12 | DOLLAR@[22; 23) | ||
13 | TOKEN_TREE@[23; 32) | ||
14 | L_PAREN@[23; 24) | ||
15 | DOLLAR@[24; 25) | ||
16 | IDENT@[25; 26) "s" | ||
17 | COLON@[26; 27) | ||
18 | IDENT@[27; 31) "expr" | ||
19 | R_PAREN@[31; 32) | ||
20 | COMMA@[32; 33) | ||
21 | STAR@[33; 34) | ||
22 | WHITESPACE@[34; 35) | ||
23 | DOLLAR@[35; 36) | ||
24 | TOKEN_TREE@[36; 39) | ||
25 | L_PAREN@[36; 37) | ||
26 | COMMA@[37; 38) | ||
27 | R_PAREN@[38; 39) | ||
28 | STAR@[39; 40) | ||
29 | R_PAREN@[40; 41) | ||
30 | err: `expected SEMI` | ||
31 | WHITESPACE@[41; 42) | ||
32 | err: `expected an item` | ||
33 | ERROR@[42; 93) | ||
34 | L_CURLY@[42; 43) | ||
35 | WHITESPACE@[43; 48) | ||
36 | IDENT@[48; 51) "vec" | ||
37 | EXCL@[51; 52) | ||
38 | L_BRACK@[52; 53) | ||
39 | WHITESPACE@[53; 62) | ||
40 | DOLLAR@[62; 63) | ||
41 | L_PAREN@[63; 64) | ||
42 | IDENT@[64; 78) "parse_use_tree" | ||
43 | L_PAREN@[78; 79) | ||
44 | DOLLAR@[79; 80) | ||
45 | IDENT@[80; 81) "s" | ||
46 | R_PAREN@[81; 82) | ||
47 | COMMA@[82; 83) | ||
48 | R_PAREN@[83; 84) | ||
49 | STAR@[84; 85) | ||
50 | WHITESPACE@[85; 90) | ||
51 | R_BRACK@[90; 91) | ||
52 | WHITESPACE@[91; 92) | ||
53 | R_CURLY@[92; 93) | ||
54 | WHITESPACE@[93; 95) | ||
55 | FN_DEF@[95; 348) | ||
56 | ATTR@[95; 102) | ||
57 | POUND@[95; 96) | ||
58 | TOKEN_TREE@[96; 102) | ||
59 | L_BRACK@[96; 97) | ||
60 | IDENT@[97; 101) "test" | ||
61 | R_BRACK@[101; 102) | ||
62 | WHITESPACE@[102; 103) | ||
63 | FN_KW@[103; 105) | ||
64 | WHITESPACE@[105; 106) | ||
65 | NAME@[106; 125) | ||
66 | IDENT@[106; 125) "test_use_tree_merge" | ||
67 | PARAM_LIST@[125; 127) | ||
68 | L_PAREN@[125; 126) | ||
69 | R_PAREN@[126; 127) | ||
70 | WHITESPACE@[127; 128) | ||
71 | BLOCK@[128; 348) | ||
72 | L_CURLY@[128; 129) | ||
73 | WHITESPACE@[129; 134) | ||
74 | EXPR_STMT@[134; 139) | ||
75 | PATH_EXPR@[134; 139) | ||
76 | PATH@[134; 139) | ||
77 | PATH_SEGMENT@[134; 139) | ||
78 | NAME_REF@[134; 139) | ||
79 | IDENT@[134; 139) "macro" | ||
80 | err: `expected SEMI` | ||
81 | WHITESPACE@[139; 140) | ||
82 | EXPR_STMT@[140; 203) | ||
83 | CALL_EXPR@[140; 203) | ||
84 | PATH_EXPR@[140; 150) | ||
85 | PATH@[140; 150) | ||
86 | PATH_SEGMENT@[140; 150) | ||
87 | NAME_REF@[140; 150) | ||
88 | IDENT@[140; 150) "test_merge" | ||
89 | ARG_LIST@[150; 203) | ||
90 | L_PAREN@[150; 151) | ||
91 | ARRAY_EXPR@[151; 202) | ||
92 | L_BRACK@[151; 152) | ||
93 | err: `expected expression` | ||
94 | ERROR@[152; 153) | ||
95 | DOLLAR@[152; 153) | ||
96 | err: `expected COMMA` | ||
97 | TUPLE_EXPR@[153; 166) | ||
98 | L_PAREN@[153; 154) | ||
99 | err: `expected expression` | ||
100 | ERROR@[154; 155) | ||
101 | DOLLAR@[154; 155) | ||
102 | err: `expected COMMA` | ||
103 | PATH_EXPR@[155; 160) | ||
104 | PATH@[155; 160) | ||
105 | PATH_SEGMENT@[155; 160) | ||
106 | NAME_REF@[155; 160) | ||
107 | IDENT@[155; 160) "input" | ||
108 | err: `expected COMMA` | ||
109 | err: `expected expression` | ||
110 | ERROR@[160; 161) | ||
111 | COLON@[160; 161) | ||
112 | err: `expected COMMA` | ||
113 | PATH_EXPR@[161; 165) | ||
114 | PATH@[161; 165) | ||
115 | PATH_SEGMENT@[161; 165) | ||
116 | NAME_REF@[161; 165) | ||
117 | IDENT@[161; 165) "expr" | ||
118 | R_PAREN@[165; 166) | ||
119 | COMMA@[166; 167) | ||
120 | PREFIX_EXPR@[167; 170) | ||
121 | STAR@[167; 168) | ||
122 | WHITESPACE@[168; 169) | ||
123 | err: `expected expression` | ||
124 | ERROR@[169; 170) | ||
125 | DOLLAR@[169; 170) | ||
126 | err: `expected COMMA` | ||
127 | BIN_EXPR@[170; 175) | ||
128 | PAREN_EXPR@[170; 173) | ||
129 | L_PAREN@[170; 171) | ||
130 | err: `expected expression` | ||
131 | ERROR@[171; 172) | ||
132 | COMMA@[171; 172) | ||
133 | R_PAREN@[172; 173) | ||
134 | STAR@[173; 174) | ||
135 | err: `expected expression` | ||
136 | ERROR@[174; 175) | ||
137 | R_BRACK@[174; 175) | ||
138 | COMMA@[175; 176) | ||
139 | WHITESPACE@[176; 177) | ||
140 | ARRAY_EXPR@[177; 202) | ||
141 | L_BRACK@[177; 178) | ||
142 | err: `expected expression` | ||
143 | ERROR@[178; 179) | ||
144 | DOLLAR@[178; 179) | ||
145 | err: `expected COMMA` | ||
146 | TUPLE_EXPR@[179; 193) | ||
147 | L_PAREN@[179; 180) | ||
148 | err: `expected expression` | ||
149 | ERROR@[180; 181) | ||
150 | DOLLAR@[180; 181) | ||
151 | err: `expected COMMA` | ||
152 | PATH_EXPR@[181; 187) | ||
153 | PATH@[181; 187) | ||
154 | PATH_SEGMENT@[181; 187) | ||
155 | NAME_REF@[181; 187) | ||
156 | IDENT@[181; 187) "output" | ||
157 | err: `expected COMMA` | ||
158 | err: `expected expression` | ||
159 | ERROR@[187; 188) | ||
160 | COLON@[187; 188) | ||
161 | err: `expected COMMA` | ||
162 | PATH_EXPR@[188; 192) | ||
163 | PATH@[188; 192) | ||
164 | PATH_SEGMENT@[188; 192) | ||
165 | NAME_REF@[188; 192) | ||
166 | IDENT@[188; 192) "expr" | ||
167 | R_PAREN@[192; 193) | ||
168 | COMMA@[193; 194) | ||
169 | PREFIX_EXPR@[194; 197) | ||
170 | STAR@[194; 195) | ||
171 | WHITESPACE@[195; 196) | ||
172 | err: `expected expression` | ||
173 | ERROR@[196; 197) | ||
174 | DOLLAR@[196; 197) | ||
175 | err: `expected COMMA` | ||
176 | BIN_EXPR@[197; 202) | ||
177 | PAREN_EXPR@[197; 200) | ||
178 | L_PAREN@[197; 198) | ||
179 | err: `expected expression` | ||
180 | ERROR@[198; 199) | ||
181 | COMMA@[198; 199) | ||
182 | R_PAREN@[199; 200) | ||
183 | STAR@[200; 201) | ||
184 | err: `expected expression` | ||
185 | ERROR@[201; 202) | ||
186 | R_BRACK@[201; 202) | ||
187 | err: `expected COMMA` | ||
188 | err: `expected expression` | ||
189 | err: `expected R_BRACK` | ||
190 | err: `expected COMMA` | ||
191 | err: `expected expression` | ||
192 | err: `expected R_BRACK` | ||
193 | R_PAREN@[202; 203) | ||
194 | err: `expected SEMI` | ||
195 | WHITESPACE@[203; 204) | ||
196 | BLOCK_EXPR@[204; 346) | ||
197 | BLOCK@[204; 346) | ||
198 | L_CURLY@[204; 205) | ||
199 | WHITESPACE@[205; 214) | ||
200 | EXPR_STMT@[214; 340) | ||
201 | MACRO_CALL@[214; 339) | ||
202 | PATH@[214; 223) | ||
203 | PATH_SEGMENT@[214; 223) | ||
204 | NAME_REF@[214; 223) | ||
205 | IDENT@[214; 223) "assert_eq" | ||
206 | EXCL@[223; 224) | ||
207 | TOKEN_TREE@[224; 339) | ||
208 | L_PAREN@[224; 225) | ||
209 | WHITESPACE@[225; 238) | ||
210 | IDENT@[238; 253) "merge_use_trees" | ||
211 | TOKEN_TREE@[253; 284) | ||
212 | L_PAREN@[253; 254) | ||
213 | IDENT@[254; 269) "parse_use_trees" | ||
214 | EXCL@[269; 270) | ||
215 | TOKEN_TREE@[270; 283) | ||
216 | L_PAREN@[270; 271) | ||
217 | DOLLAR@[271; 272) | ||
218 | TOKEN_TREE@[272; 281) | ||
219 | L_PAREN@[272; 273) | ||
220 | DOLLAR@[273; 274) | ||
221 | IDENT@[274; 279) "input" | ||
222 | COMMA@[279; 280) | ||
223 | R_PAREN@[280; 281) | ||
224 | STAR@[281; 282) | ||
225 | R_PAREN@[282; 283) | ||
226 | R_PAREN@[283; 284) | ||
227 | COMMA@[284; 285) | ||
228 | WHITESPACE@[285; 298) | ||
229 | IDENT@[298; 313) "parse_use_trees" | ||
230 | EXCL@[313; 314) | ||
231 | TOKEN_TREE@[314; 328) | ||
232 | L_PAREN@[314; 315) | ||
233 | DOLLAR@[315; 316) | ||
234 | TOKEN_TREE@[316; 326) | ||
235 | L_PAREN@[316; 317) | ||
236 | DOLLAR@[317; 318) | ||
237 | IDENT@[318; 324) "output" | ||
238 | COMMA@[324; 325) | ||
239 | R_PAREN@[325; 326) | ||
240 | STAR@[326; 327) | ||
241 | R_PAREN@[327; 328) | ||
242 | COMMA@[328; 329) | ||
243 | WHITESPACE@[329; 338) | ||
244 | R_PAREN@[338; 339) | ||
245 | SEMI@[339; 340) | ||
246 | WHITESPACE@[340; 345) | ||
247 | R_CURLY@[345; 346) | ||
248 | WHITESPACE@[346; 347) | ||
249 | R_CURLY@[347; 348) | ||
250 | WHITESPACE@[348; 350) | ||
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs new file mode 100644 index 000000000..27380efef --- /dev/null +++ b/crates/ra_syntax/tests/test.rs | |||
@@ -0,0 +1,151 @@ | |||
1 | extern crate ra_syntax; | ||
2 | #[macro_use] | ||
3 | extern crate test_utils; | ||
4 | extern crate walkdir; | ||
5 | |||
6 | use std::{ | ||
7 | fs, | ||
8 | path::{Path, PathBuf}, | ||
9 | fmt::Write, | ||
10 | }; | ||
11 | |||
12 | use ra_syntax::{ | ||
13 | File, | ||
14 | utils::{dump_tree, check_fuzz_invariants}, | ||
15 | }; | ||
16 | |||
17 | #[test] | ||
18 | fn lexer_tests() { | ||
19 | dir_tests(&["lexer"], |text| { | ||
20 | let tokens = ra_syntax::tokenize(text); | ||
21 | dump_tokens(&tokens, text) | ||
22 | }) | ||
23 | } | ||
24 | |||
25 | #[test] | ||
26 | fn parser_tests() { | ||
27 | dir_tests(&["parser/inline", "parser/ok", "parser/err"], |text| { | ||
28 | let file = File::parse(text); | ||
29 | dump_tree(file.syntax()) | ||
30 | }) | ||
31 | } | ||
32 | |||
33 | #[test] | ||
34 | fn parser_fuzz_tests() { | ||
35 | for (_, text) in collect_tests(&["parser/fuzz-failures"]) { | ||
36 | check_fuzz_invariants(&text) | ||
37 | } | ||
38 | } | ||
39 | |||
40 | |||
41 | /// Read file and normalize newlines. | ||
42 | /// | ||
43 | /// `rustc` seems to always normalize `\r\n` newlines to `\n`: | ||
44 | /// | ||
45 | /// ``` | ||
46 | /// let s = " | ||
47 | /// "; | ||
48 | /// assert_eq!(s.as_bytes(), &[10]); | ||
49 | /// ``` | ||
50 | /// | ||
51 | /// so this should always be correct. | ||
52 | fn read_text(path: &Path) -> String { | ||
53 | fs::read_to_string(path).unwrap().replace("\r\n", "\n") | ||
54 | } | ||
55 | |||
56 | pub fn dir_tests<F>(paths: &[&str], f: F) | ||
57 | where | ||
58 | F: Fn(&str) -> String, | ||
59 | { | ||
60 | for (path, input_code) in collect_tests(paths) { | ||
61 | let parse_tree = f(&input_code); | ||
62 | let path = path.with_extension("txt"); | ||
63 | if !path.exists() { | ||
64 | println!("\nfile: {}", path.display()); | ||
65 | println!("No .txt file with expected result, creating...\n"); | ||
66 | println!("{}\n{}", input_code, parse_tree); | ||
67 | fs::write(&path, parse_tree).unwrap(); | ||
68 | panic!("No expected result") | ||
69 | } | ||
70 | let expected = read_text(&path); | ||
71 | let expected = expected.as_str(); | ||
72 | let parse_tree = parse_tree.as_str(); | ||
73 | assert_equal_text(expected, parse_tree, &path); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | const REWRITE: bool = false; | ||
78 | |||
79 | fn assert_equal_text(expected: &str, actual: &str, path: &Path) { | ||
80 | if expected == actual { | ||
81 | return; | ||
82 | } | ||
83 | let dir = project_dir(); | ||
84 | let pretty_path = path.strip_prefix(&dir).unwrap_or_else(|_| path); | ||
85 | if expected.trim() == actual.trim() { | ||
86 | println!("whitespace difference, rewriting"); | ||
87 | println!("file: {}\n", pretty_path.display()); | ||
88 | fs::write(path, actual).unwrap(); | ||
89 | return; | ||
90 | } | ||
91 | if REWRITE { | ||
92 | println!("rewriting {}", pretty_path.display()); | ||
93 | fs::write(path, actual).unwrap(); | ||
94 | return; | ||
95 | } | ||
96 | assert_eq_text!(expected, actual, "file: {}", pretty_path.display()); | ||
97 | } | ||
98 | |||
99 | fn collect_tests(paths: &[&str]) -> Vec<(PathBuf, String)> { | ||
100 | paths | ||
101 | .iter() | ||
102 | .flat_map(|path| { | ||
103 | let path = test_data_dir().join(path); | ||
104 | test_from_dir(&path).into_iter() | ||
105 | }) | ||
106 | .map(|path| { | ||
107 | let text = read_text(&path); | ||
108 | (path, text) | ||
109 | }) | ||
110 | .collect() | ||
111 | } | ||
112 | |||
113 | fn test_from_dir(dir: &Path) -> Vec<PathBuf> { | ||
114 | let mut acc = Vec::new(); | ||
115 | for file in fs::read_dir(&dir).unwrap() { | ||
116 | let file = file.unwrap(); | ||
117 | let path = file.path(); | ||
118 | if path.extension().unwrap_or_default() == "rs" { | ||
119 | acc.push(path); | ||
120 | } | ||
121 | } | ||
122 | acc.sort(); | ||
123 | acc | ||
124 | } | ||
125 | |||
126 | fn project_dir() -> PathBuf { | ||
127 | let dir = env!("CARGO_MANIFEST_DIR"); | ||
128 | PathBuf::from(dir) | ||
129 | .parent() | ||
130 | .unwrap() | ||
131 | .parent() | ||
132 | .unwrap() | ||
133 | .to_owned() | ||
134 | } | ||
135 | |||
136 | fn test_data_dir() -> PathBuf { | ||
137 | project_dir().join("crates/ra_syntax/tests/data") | ||
138 | } | ||
139 | |||
140 | fn dump_tokens(tokens: &[ra_syntax::Token], text: &str) -> String { | ||
141 | let mut acc = String::new(); | ||
142 | let mut offset = 0; | ||
143 | for token in tokens { | ||
144 | let len: u32 = token.len.into(); | ||
145 | let len = len as usize; | ||
146 | let token_text = &text[offset..offset + len]; | ||
147 | offset += len; | ||
148 | write!(acc, "{:?} {} {:?}\n", token.kind, token.len, token_text).unwrap() | ||
149 | } | ||
150 | acc | ||
151 | } | ||