diff options
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r-- | crates/ra_syntax/src/ast.rs | 24 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/make.rs | 6 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/traits.rs | 19 | ||||
-rw-r--r-- | crates/ra_syntax/src/lib.rs | 14 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt | 91 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.rs | 5 | ||||
-rw-r--r-- | crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.txt | 101 |
7 files changed, 200 insertions, 60 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 1b2ce921a..a12da5be2 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -173,7 +173,7 @@ fn test_doc_comment_single_line_block_strips_suffix_whitespace() { | |||
173 | .ok() | 173 | .ok() |
174 | .unwrap(); | 174 | .unwrap(); |
175 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); | 175 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); |
176 | assert_eq!("this is mod foo", module.doc_comment_text().unwrap()); | 176 | assert_eq!("this is mod foo ", module.doc_comment_text().unwrap()); |
177 | } | 177 | } |
178 | 178 | ||
179 | #[test] | 179 | #[test] |
@@ -191,7 +191,27 @@ fn test_doc_comment_multi_line_block_strips_suffix() { | |||
191 | .ok() | 191 | .ok() |
192 | .unwrap(); | 192 | .unwrap(); |
193 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); | 193 | let module = file.syntax().descendants().find_map(Module::cast).unwrap(); |
194 | assert_eq!(" this\n is\n mod foo", module.doc_comment_text().unwrap()); | 194 | assert_eq!( |
195 | " this\n is\n mod foo\n ", | ||
196 | module.doc_comment_text().unwrap() | ||
197 | ); | ||
198 | } | ||
199 | |||
200 | #[test] | ||
201 | fn test_comments_preserve_trailing_whitespace() { | ||
202 | let file = SourceFile::parse( | ||
203 | r#" | ||
204 | /// Representation of a Realm. | ||
205 | /// In the specification these are called Realm Records. | ||
206 | struct Realm {}"#, | ||
207 | ) | ||
208 | .ok() | ||
209 | .unwrap(); | ||
210 | let def = file.syntax().descendants().find_map(StructDef::cast).unwrap(); | ||
211 | assert_eq!( | ||
212 | "Representation of a Realm. \nIn the specification these are called Realm Records.", | ||
213 | def.doc_comment_text().unwrap() | ||
214 | ); | ||
195 | } | 215 | } |
196 | 216 | ||
197 | #[test] | 217 | #[test] |
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs index 00422ea91..3d5f18bfa 100644 --- a/crates/ra_syntax/src/ast/make.rs +++ b/crates/ra_syntax/src/ast/make.rs | |||
@@ -77,7 +77,7 @@ pub fn tuple_struct_pat( | |||
77 | 77 | ||
78 | pub fn record_pat(path: ast::Path, pats: impl Iterator<Item = ast::Pat>) -> ast::RecordPat { | 78 | pub fn record_pat(path: ast::Path, pats: impl Iterator<Item = ast::Pat>) -> ast::RecordPat { |
79 | let pats_str = pats.map(|p| p.syntax().to_string()).join(", "); | 79 | let pats_str = pats.map(|p| p.syntax().to_string()).join(", "); |
80 | return from_text(&format!("{}{{ {} }}", path.syntax(), pats_str)); | 80 | return from_text(&format!("{} {{ {} }}", path.syntax(), pats_str)); |
81 | 81 | ||
82 | fn from_text(text: &str) -> ast::RecordPat { | 82 | fn from_text(text: &str) -> ast::RecordPat { |
83 | ast_from_text(&format!("fn f({}: ())", text)) | 83 | ast_from_text(&format!("fn f({}: ())", text)) |
@@ -129,11 +129,11 @@ pub fn where_clause(preds: impl Iterator<Item = ast::WherePred>) -> ast::WhereCl | |||
129 | } | 129 | } |
130 | 130 | ||
131 | pub fn if_expression(condition: &ast::Expr, statement: &str) -> ast::IfExpr { | 131 | pub fn if_expression(condition: &ast::Expr, statement: &str) -> ast::IfExpr { |
132 | return ast_from_text(&format!( | 132 | ast_from_text(&format!( |
133 | "fn f() {{ if !{} {{\n {}\n}}\n}}", | 133 | "fn f() {{ if !{} {{\n {}\n}}\n}}", |
134 | condition.syntax().text(), | 134 | condition.syntax().text(), |
135 | statement | 135 | statement |
136 | )); | 136 | )) |
137 | } | 137 | } |
138 | 138 | ||
139 | fn ast_from_text<N: AstNode>(text: &str) -> N { | 139 | fn ast_from_text<N: AstNode>(text: &str) -> N { |
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index f275a4955..c2b005886 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs | |||
@@ -6,6 +6,7 @@ use itertools::Itertools; | |||
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | ast::{self, child_opt, children, AstChildren, AstNode, AstToken}, | 8 | ast::{self, child_opt, children, AstChildren, AstNode, AstToken}, |
9 | match_ast, | ||
9 | syntax_node::{SyntaxElementChildren, SyntaxNodeChildren}, | 10 | syntax_node::{SyntaxElementChildren, SyntaxNodeChildren}, |
10 | }; | 11 | }; |
11 | 12 | ||
@@ -68,11 +69,12 @@ impl Iterator for ItemOrMacroIter { | |||
68 | fn next(&mut self) -> Option<ItemOrMacro> { | 69 | fn next(&mut self) -> Option<ItemOrMacro> { |
69 | loop { | 70 | loop { |
70 | let n = self.0.next()?; | 71 | let n = self.0.next()?; |
71 | if let Some(item) = ast::ModuleItem::cast(n.clone()) { | 72 | match_ast! { |
72 | return Some(ItemOrMacro::Item(item)); | 73 | match n { |
73 | } | 74 | ast::ModuleItem(it) => { return Some(ItemOrMacro::Item(it)) }, |
74 | if let Some(call) = ast::MacroCall::cast(n) { | 75 | ast::MacroCall(it) => { return Some(ItemOrMacro::Macro(it)) }, |
75 | return Some(ItemOrMacro::Macro(call)); | 76 | _ => {}, |
77 | } | ||
76 | } | 78 | } |
77 | } | 79 | } |
78 | } | 80 | } |
@@ -120,7 +122,7 @@ pub trait DocCommentsOwner: AstNode { | |||
120 | has_comments = true; | 122 | has_comments = true; |
121 | let prefix_len = comment.prefix().len(); | 123 | let prefix_len = comment.prefix().len(); |
122 | 124 | ||
123 | let line = comment.text().as_str(); | 125 | let line: &str = comment.text().as_str(); |
124 | 126 | ||
125 | // Determine if the prefix or prefix + 1 char is stripped | 127 | // Determine if the prefix or prefix + 1 char is stripped |
126 | let pos = | 128 | let pos = |
@@ -136,7 +138,10 @@ pub trait DocCommentsOwner: AstNode { | |||
136 | line.len() | 138 | line.len() |
137 | }; | 139 | }; |
138 | 140 | ||
139 | line[pos..end].trim_end().to_owned() | 141 | // Note that we do not trim the end of the line here |
142 | // since whitespace can have special meaning at the end | ||
143 | // of a line in markdown. | ||
144 | line[pos..end].to_owned() | ||
140 | }) | 145 | }) |
141 | .join("\n"); | 146 | .join("\n"); |
142 | 147 | ||
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index c315ba552..5dcb6a95a 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs | |||
@@ -160,6 +160,20 @@ impl SourceFile { | |||
160 | } | 160 | } |
161 | } | 161 | } |
162 | 162 | ||
163 | /// Matches a `SyntaxNode` against an `ast` type. | ||
164 | /// | ||
165 | /// # Example: | ||
166 | /// | ||
167 | /// ```ignore | ||
168 | /// match_ast! { | ||
169 | /// match node { | ||
170 | /// ast::CallExpr(it) => { ... }, | ||
171 | /// ast::MethodCallExpr(it) => { ... }, | ||
172 | /// ast::MacroCall(it) => { ... }, | ||
173 | /// _ => None, | ||
174 | /// } | ||
175 | /// } | ||
176 | /// ``` | ||
163 | #[macro_export] | 177 | #[macro_export] |
164 | macro_rules! match_ast { | 178 | macro_rules! match_ast { |
165 | (match $node:ident { | 179 | (match $node:ident { |
diff --git a/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt b/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt index 198daf7b4..0a93e11a5 100644 --- a/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt +++ b/crates/ra_syntax/test_data/parser/err/0024_many_type_parens.txt | |||
@@ -179,50 +179,47 @@ SOURCE_FILE@[0; 240) | |||
179 | ERROR@[148; 149) | 179 | ERROR@[148; 149) |
180 | PLUS@[148; 149) "+" | 180 | PLUS@[148; 149) "+" |
181 | WHITESPACE@[149; 150) " " | 181 | WHITESPACE@[149; 150) " " |
182 | EXPR_STMT@[150; 151) | 182 | EXPR_STMT@[150; 180) |
183 | PAREN_EXPR@[150; 151) | 183 | TUPLE_EXPR@[150; 180) |
184 | L_PAREN@[150; 151) "(" | 184 | L_PAREN@[150; 151) "(" |
185 | EXPR_STMT@[151; 157) | 185 | BIN_EXPR@[151; 180) |
186 | FOR_EXPR@[151; 157) | 186 | BIN_EXPR@[151; 178) |
187 | FOR_KW@[151; 154) "for" | 187 | BIN_EXPR@[151; 169) |
188 | ERROR@[154; 155) | 188 | BIN_EXPR@[151; 167) |
189 | L_ANGLE@[154; 155) "<" | 189 | BIN_EXPR@[151; 164) |
190 | ERROR@[155; 157) | 190 | FOR_EXPR@[151; 157) |
191 | LIFETIME@[155; 157) "\'a" | 191 | FOR_KW@[151; 154) "for" |
192 | EXPR_STMT@[157; 158) | 192 | ERROR@[154; 155) |
193 | ERROR@[157; 158) | 193 | L_ANGLE@[154; 155) "<" |
194 | R_ANGLE@[157; 158) ">" | 194 | ERROR@[155; 157) |
195 | WHITESPACE@[158; 159) " " | 195 | LIFETIME@[155; 157) "\'a" |
196 | EXPR_STMT@[159; 180) | 196 | R_ANGLE@[157; 158) ">" |
197 | BIN_EXPR@[159; 180) | 197 | WHITESPACE@[158; 159) " " |
198 | BIN_EXPR@[159; 178) | 198 | PATH_EXPR@[159; 164) |
199 | BIN_EXPR@[159; 169) | 199 | PATH@[159; 164) |
200 | BIN_EXPR@[159; 167) | 200 | PATH_SEGMENT@[159; 164) |
201 | PATH_EXPR@[159; 164) | 201 | NAME_REF@[159; 164) |
202 | PATH@[159; 164) | 202 | IDENT@[159; 164) "Trait" |
203 | PATH_SEGMENT@[159; 164) | 203 | L_ANGLE@[164; 165) "<" |
204 | NAME_REF@[159; 164) | 204 | ERROR@[165; 167) |
205 | IDENT@[159; 164) "Trait" | 205 | LIFETIME@[165; 167) "\'a" |
206 | L_ANGLE@[164; 165) "<" | 206 | R_ANGLE@[167; 168) ">" |
207 | ERROR@[165; 167) | 207 | ERROR@[168; 169) |
208 | LIFETIME@[165; 167) "\'a" | 208 | R_PAREN@[168; 169) ")" |
209 | R_ANGLE@[167; 168) ">" | 209 | WHITESPACE@[169; 170) " " |
210 | ERROR@[168; 169) | 210 | PLUS@[170; 171) "+" |
211 | R_PAREN@[168; 169) ")" | 211 | WHITESPACE@[171; 172) " " |
212 | WHITESPACE@[169; 170) " " | 212 | PAREN_EXPR@[172; 178) |
213 | PLUS@[170; 171) "+" | 213 | L_PAREN@[172; 173) "(" |
214 | WHITESPACE@[171; 172) " " | 214 | PATH_EXPR@[173; 177) |
215 | PAREN_EXPR@[172; 178) | 215 | PATH@[173; 177) |
216 | L_PAREN@[172; 173) "(" | 216 | PATH_SEGMENT@[173; 177) |
217 | PATH_EXPR@[173; 177) | 217 | NAME_REF@[173; 177) |
218 | PATH@[173; 177) | 218 | IDENT@[173; 177) "Copy" |
219 | PATH_SEGMENT@[173; 177) | 219 | R_PAREN@[177; 178) ")" |
220 | NAME_REF@[173; 177) | 220 | R_ANGLE@[178; 179) ">" |
221 | IDENT@[173; 177) "Copy" | 221 | ERROR@[179; 180) |
222 | R_PAREN@[177; 178) ")" | 222 | SEMI@[179; 180) ";" |
223 | R_ANGLE@[178; 179) ">" | ||
224 | ERROR@[179; 180) | ||
225 | SEMI@[179; 180) ";" | ||
226 | WHITESPACE@[180; 185) "\n " | 223 | WHITESPACE@[180; 185) "\n " |
227 | LET_STMT@[185; 235) | 224 | LET_STMT@[185; 235) |
228 | LET_KW@[185; 188) "let" | 225 | LET_KW@[185; 188) "let" |
@@ -307,18 +304,16 @@ error 146: expected expression | |||
307 | error 147: expected SEMI | 304 | error 147: expected SEMI |
308 | error 148: expected expression | 305 | error 148: expected expression |
309 | error 149: expected SEMI | 306 | error 149: expected SEMI |
310 | error 151: expected expression | ||
311 | error 151: expected R_PAREN | ||
312 | error 151: expected SEMI | ||
313 | error 154: expected pattern | 307 | error 154: expected pattern |
314 | error 155: expected IN_KW | 308 | error 155: expected IN_KW |
315 | error 155: expected expression | 309 | error 155: expected expression |
316 | error 157: expected a block | 310 | error 157: expected a block |
317 | error 157: expected expression | ||
318 | error 158: expected SEMI | ||
319 | error 165: expected expression | 311 | error 165: expected expression |
320 | error 168: expected expression | 312 | error 168: expected expression |
321 | error 179: expected expression | 313 | error 179: expected expression |
314 | error 180: expected COMMA | ||
315 | error 180: expected expression | ||
316 | error 180: expected R_PAREN | ||
322 | error 180: expected SEMI | 317 | error 180: expected SEMI |
323 | error 215: expected COMMA | 318 | error 215: expected COMMA |
324 | error 215: expected R_ANGLE | 319 | error 215: expected R_ANGLE |
diff --git a/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.rs b/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.rs new file mode 100644 index 000000000..6e8b718aa --- /dev/null +++ b/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | fn main() { | ||
2 | Some(for _ in [1].into_iter() {}); | ||
3 | Some(loop { break; }); | ||
4 | Some(while true {}); | ||
5 | } | ||
diff --git a/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.txt b/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.txt new file mode 100644 index 000000000..c011187ea --- /dev/null +++ b/crates/ra_syntax/test_data/parser/ok/0059_loops_in_parens.txt | |||
@@ -0,0 +1,101 @@ | |||
1 | SOURCE_FILE@[0; 105) | ||
2 | FN_DEF@[0; 104) | ||
3 | FN_KW@[0; 2) "fn" | ||
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_EXPR@[10; 104) | ||
12 | BLOCK@[10; 104) | ||
13 | L_CURLY@[10; 11) "{" | ||
14 | WHITESPACE@[11; 16) "\n " | ||
15 | EXPR_STMT@[16; 50) | ||
16 | CALL_EXPR@[16; 49) | ||
17 | PATH_EXPR@[16; 20) | ||
18 | PATH@[16; 20) | ||
19 | PATH_SEGMENT@[16; 20) | ||
20 | NAME_REF@[16; 20) | ||
21 | IDENT@[16; 20) "Some" | ||
22 | ARG_LIST@[20; 49) | ||
23 | L_PAREN@[20; 21) "(" | ||
24 | FOR_EXPR@[21; 48) | ||
25 | FOR_KW@[21; 24) "for" | ||
26 | WHITESPACE@[24; 25) " " | ||
27 | PLACEHOLDER_PAT@[25; 26) | ||
28 | UNDERSCORE@[25; 26) "_" | ||
29 | WHITESPACE@[26; 27) " " | ||
30 | IN_KW@[27; 29) "in" | ||
31 | WHITESPACE@[29; 30) " " | ||
32 | METHOD_CALL_EXPR@[30; 45) | ||
33 | ARRAY_EXPR@[30; 33) | ||
34 | L_BRACK@[30; 31) "[" | ||
35 | LITERAL@[31; 32) | ||
36 | INT_NUMBER@[31; 32) "1" | ||
37 | R_BRACK@[32; 33) "]" | ||
38 | DOT@[33; 34) "." | ||
39 | NAME_REF@[34; 43) | ||
40 | IDENT@[34; 43) "into_iter" | ||
41 | ARG_LIST@[43; 45) | ||
42 | L_PAREN@[43; 44) "(" | ||
43 | R_PAREN@[44; 45) ")" | ||
44 | WHITESPACE@[45; 46) " " | ||
45 | BLOCK_EXPR@[46; 48) | ||
46 | BLOCK@[46; 48) | ||
47 | L_CURLY@[46; 47) "{" | ||
48 | R_CURLY@[47; 48) "}" | ||
49 | R_PAREN@[48; 49) ")" | ||
50 | SEMI@[49; 50) ";" | ||
51 | WHITESPACE@[50; 55) "\n " | ||
52 | EXPR_STMT@[55; 77) | ||
53 | CALL_EXPR@[55; 76) | ||
54 | PATH_EXPR@[55; 59) | ||
55 | PATH@[55; 59) | ||
56 | PATH_SEGMENT@[55; 59) | ||
57 | NAME_REF@[55; 59) | ||
58 | IDENT@[55; 59) "Some" | ||
59 | ARG_LIST@[59; 76) | ||
60 | L_PAREN@[59; 60) "(" | ||
61 | LOOP_EXPR@[60; 75) | ||
62 | LOOP_KW@[60; 64) "loop" | ||
63 | WHITESPACE@[64; 65) " " | ||
64 | BLOCK_EXPR@[65; 75) | ||
65 | BLOCK@[65; 75) | ||
66 | L_CURLY@[65; 66) "{" | ||
67 | WHITESPACE@[66; 67) " " | ||
68 | EXPR_STMT@[67; 73) | ||
69 | BREAK_EXPR@[67; 72) | ||
70 | BREAK_KW@[67; 72) "break" | ||
71 | SEMI@[72; 73) ";" | ||
72 | WHITESPACE@[73; 74) " " | ||
73 | R_CURLY@[74; 75) "}" | ||
74 | R_PAREN@[75; 76) ")" | ||
75 | SEMI@[76; 77) ";" | ||
76 | WHITESPACE@[77; 82) "\n " | ||
77 | EXPR_STMT@[82; 102) | ||
78 | CALL_EXPR@[82; 101) | ||
79 | PATH_EXPR@[82; 86) | ||
80 | PATH@[82; 86) | ||
81 | PATH_SEGMENT@[82; 86) | ||
82 | NAME_REF@[82; 86) | ||
83 | IDENT@[82; 86) "Some" | ||
84 | ARG_LIST@[86; 101) | ||
85 | L_PAREN@[86; 87) "(" | ||
86 | WHILE_EXPR@[87; 100) | ||
87 | WHILE_KW@[87; 92) "while" | ||
88 | WHITESPACE@[92; 93) " " | ||
89 | CONDITION@[93; 97) | ||
90 | LITERAL@[93; 97) | ||
91 | TRUE_KW@[93; 97) "true" | ||
92 | WHITESPACE@[97; 98) " " | ||
93 | BLOCK_EXPR@[98; 100) | ||
94 | BLOCK@[98; 100) | ||
95 | L_CURLY@[98; 99) "{" | ||
96 | R_CURLY@[99; 100) "}" | ||
97 | R_PAREN@[100; 101) ")" | ||
98 | SEMI@[101; 102) ";" | ||
99 | WHITESPACE@[102; 103) "\n" | ||
100 | R_CURLY@[103; 104) "}" | ||
101 | WHITESPACE@[104; 105) "\n" | ||