diff options
Diffstat (limited to 'crates/syntax/src')
-rw-r--r-- | crates/syntax/src/algo.rs | 2 | ||||
-rw-r--r-- | crates/syntax/src/ast/generated/nodes.rs | 2 | ||||
-rw-r--r-- | crates/syntax/src/lib.rs | 9 | ||||
-rw-r--r-- | crates/syntax/src/parsing/reparsing.rs | 56 | ||||
-rw-r--r-- | crates/syntax/src/tests.rs | 9 |
5 files changed, 47 insertions, 31 deletions
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 5696c014f..22ab36cd2 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | 19 | ||
20 | /// Returns ancestors of the node at the offset, sorted by length. This should | 20 | /// Returns ancestors of the node at the offset, sorted by length. This should |
21 | /// do the right thing at an edge, e.g. when searching for expressions at `{ | 21 | /// do the right thing at an edge, e.g. when searching for expressions at `{ |
22 | /// <|>foo }` we will get the name reference instead of the whole block, which | 22 | /// $0foo }` we will get the name reference instead of the whole block, which |
23 | /// we would get if we just did `find_token_at_offset(...).flat_map(|t| | 23 | /// we would get if we just did `find_token_at_offset(...).flat_map(|t| |
24 | /// t.parent().ancestors())`. | 24 | /// t.parent().ancestors())`. |
25 | pub fn ancestors_at_offset( | 25 | pub fn ancestors_at_offset( |
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index c5b80bffe..92ed2ee9d 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs | |||
@@ -484,7 +484,7 @@ impl ast::AttrsOwner for BlockExpr {} | |||
484 | impl BlockExpr { | 484 | impl BlockExpr { |
485 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) } | 485 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) } |
486 | pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) } | 486 | pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) } |
487 | pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } | 487 | pub fn tail_expr(&self) -> Option<Expr> { support::child(&self.syntax) } |
488 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } | 488 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } |
489 | } | 489 | } |
490 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 490 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 4d272f367..ea7482bb1 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs | |||
@@ -212,6 +212,13 @@ impl ast::Attr { | |||
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | impl ast::Stmt { | ||
216 | /// Returns `text`, parsed as statement, but only if it has no errors. | ||
217 | pub fn parse(text: &str) -> Result<Self, ()> { | ||
218 | parsing::parse_text_fragment(text, parser::FragmentKind::StatementOptionalSemi) | ||
219 | } | ||
220 | } | ||
221 | |||
215 | /// Matches a `SyntaxNode` against an `ast` type. | 222 | /// Matches a `SyntaxNode` against an `ast` type. |
216 | /// | 223 | /// |
217 | /// # Example: | 224 | /// # Example: |
@@ -283,7 +290,7 @@ fn api_walkthrough() { | |||
283 | 290 | ||
284 | // Let's get the `1 + 1` expression! | 291 | // Let's get the `1 + 1` expression! |
285 | let body: ast::BlockExpr = func.body().unwrap(); | 292 | let body: ast::BlockExpr = func.body().unwrap(); |
286 | let expr: ast::Expr = body.expr().unwrap(); | 293 | let expr: ast::Expr = body.tail_expr().unwrap(); |
287 | 294 | ||
288 | // Enums are used to group related ast nodes together, and can be used for | 295 | // Enums are used to group related ast nodes together, and can be used for |
289 | // matching. However, because there are no public fields, it's possible to | 296 | // matching. However, because there are no public fields, it's possible to |
diff --git a/crates/syntax/src/parsing/reparsing.rs b/crates/syntax/src/parsing/reparsing.rs index 190f5f67a..78eaf3410 100644 --- a/crates/syntax/src/parsing/reparsing.rs +++ b/crates/syntax/src/parsing/reparsing.rs | |||
@@ -223,7 +223,7 @@ mod tests { | |||
223 | do_check( | 223 | do_check( |
224 | r" | 224 | r" |
225 | fn foo() { | 225 | fn foo() { |
226 | let x = foo + <|>bar<|> | 226 | let x = foo + $0bar$0 |
227 | } | 227 | } |
228 | ", | 228 | ", |
229 | "baz", | 229 | "baz", |
@@ -232,7 +232,7 @@ fn foo() { | |||
232 | do_check( | 232 | do_check( |
233 | r" | 233 | r" |
234 | fn foo() { | 234 | fn foo() { |
235 | let x = foo<|> + bar<|> | 235 | let x = foo$0 + bar$0 |
236 | } | 236 | } |
237 | ", | 237 | ", |
238 | "baz", | 238 | "baz", |
@@ -241,7 +241,7 @@ fn foo() { | |||
241 | do_check( | 241 | do_check( |
242 | r" | 242 | r" |
243 | struct Foo { | 243 | struct Foo { |
244 | f: foo<|><|> | 244 | f: foo$0$0 |
245 | } | 245 | } |
246 | ", | 246 | ", |
247 | ",\n g: (),", | 247 | ",\n g: (),", |
@@ -252,7 +252,7 @@ struct Foo { | |||
252 | fn foo { | 252 | fn foo { |
253 | let; | 253 | let; |
254 | 1 + 1; | 254 | 1 + 1; |
255 | <|>92<|>; | 255 | $092$0; |
256 | } | 256 | } |
257 | ", | 257 | ", |
258 | "62", | 258 | "62", |
@@ -261,7 +261,7 @@ fn foo { | |||
261 | do_check( | 261 | do_check( |
262 | r" | 262 | r" |
263 | mod foo { | 263 | mod foo { |
264 | fn <|><|> | 264 | fn $0$0 |
265 | } | 265 | } |
266 | ", | 266 | ", |
267 | "bar", | 267 | "bar", |
@@ -271,7 +271,7 @@ mod foo { | |||
271 | do_check( | 271 | do_check( |
272 | r" | 272 | r" |
273 | trait Foo { | 273 | trait Foo { |
274 | type <|>Foo<|>; | 274 | type $0Foo$0; |
275 | } | 275 | } |
276 | ", | 276 | ", |
277 | "Output", | 277 | "Output", |
@@ -280,17 +280,17 @@ trait Foo { | |||
280 | do_check( | 280 | do_check( |
281 | r" | 281 | r" |
282 | impl IntoIterator<Item=i32> for Foo { | 282 | impl IntoIterator<Item=i32> for Foo { |
283 | f<|><|> | 283 | f$0$0 |
284 | } | 284 | } |
285 | ", | 285 | ", |
286 | "n next(", | 286 | "n next(", |
287 | 9, | 287 | 9, |
288 | ); | 288 | ); |
289 | do_check(r"use a::b::{foo,<|>,bar<|>};", "baz", 10); | 289 | do_check(r"use a::b::{foo,$0,bar$0};", "baz", 10); |
290 | do_check( | 290 | do_check( |
291 | r" | 291 | r" |
292 | pub enum A { | 292 | pub enum A { |
293 | Foo<|><|> | 293 | Foo$0$0 |
294 | } | 294 | } |
295 | ", | 295 | ", |
296 | "\nBar;\n", | 296 | "\nBar;\n", |
@@ -298,7 +298,7 @@ pub enum A { | |||
298 | ); | 298 | ); |
299 | do_check( | 299 | do_check( |
300 | r" | 300 | r" |
301 | foo!{a, b<|><|> d} | 301 | foo!{a, b$0$0 d} |
302 | ", | 302 | ", |
303 | ", c[3]", | 303 | ", c[3]", |
304 | 8, | 304 | 8, |
@@ -306,7 +306,7 @@ foo!{a, b<|><|> d} | |||
306 | do_check( | 306 | do_check( |
307 | r" | 307 | r" |
308 | fn foo() { | 308 | fn foo() { |
309 | vec![<|><|>] | 309 | vec![$0$0] |
310 | } | 310 | } |
311 | ", | 311 | ", |
312 | "123", | 312 | "123", |
@@ -315,7 +315,7 @@ fn foo() { | |||
315 | do_check( | 315 | do_check( |
316 | r" | 316 | r" |
317 | extern { | 317 | extern { |
318 | fn<|>;<|> | 318 | fn$0;$0 |
319 | } | 319 | } |
320 | ", | 320 | ", |
321 | " exit(code: c_int)", | 321 | " exit(code: c_int)", |
@@ -326,7 +326,7 @@ extern { | |||
326 | #[test] | 326 | #[test] |
327 | fn reparse_token_tests() { | 327 | fn reparse_token_tests() { |
328 | do_check( | 328 | do_check( |
329 | r"<|><|> | 329 | r"$0$0 |
330 | fn foo() -> i32 { 1 } | 330 | fn foo() -> i32 { 1 } |
331 | ", | 331 | ", |
332 | "\n\n\n \n", | 332 | "\n\n\n \n", |
@@ -334,49 +334,49 @@ fn foo() -> i32 { 1 } | |||
334 | ); | 334 | ); |
335 | do_check( | 335 | do_check( |
336 | r" | 336 | r" |
337 | fn foo() -> <|><|> {} | 337 | fn foo() -> $0$0 {} |
338 | ", | 338 | ", |
339 | " \n", | 339 | " \n", |
340 | 2, | 340 | 2, |
341 | ); | 341 | ); |
342 | do_check( | 342 | do_check( |
343 | r" | 343 | r" |
344 | fn <|>foo<|>() -> i32 { 1 } | 344 | fn $0foo$0() -> i32 { 1 } |
345 | ", | 345 | ", |
346 | "bar", | 346 | "bar", |
347 | 3, | 347 | 3, |
348 | ); | 348 | ); |
349 | do_check( | 349 | do_check( |
350 | r" | 350 | r" |
351 | fn foo<|><|>foo() { } | 351 | fn foo$0$0foo() { } |
352 | ", | 352 | ", |
353 | "bar", | 353 | "bar", |
354 | 6, | 354 | 6, |
355 | ); | 355 | ); |
356 | do_check( | 356 | do_check( |
357 | r" | 357 | r" |
358 | fn foo /* <|><|> */ () {} | 358 | fn foo /* $0$0 */ () {} |
359 | ", | 359 | ", |
360 | "some comment", | 360 | "some comment", |
361 | 6, | 361 | 6, |
362 | ); | 362 | ); |
363 | do_check( | 363 | do_check( |
364 | r" | 364 | r" |
365 | fn baz <|><|> () {} | 365 | fn baz $0$0 () {} |
366 | ", | 366 | ", |
367 | " \t\t\n\n", | 367 | " \t\t\n\n", |
368 | 2, | 368 | 2, |
369 | ); | 369 | ); |
370 | do_check( | 370 | do_check( |
371 | r" | 371 | r" |
372 | fn baz <|><|> () {} | 372 | fn baz $0$0 () {} |
373 | ", | 373 | ", |
374 | " \t\t\n\n", | 374 | " \t\t\n\n", |
375 | 2, | 375 | 2, |
376 | ); | 376 | ); |
377 | do_check( | 377 | do_check( |
378 | r" | 378 | r" |
379 | /// foo <|><|>omment | 379 | /// foo $0$0omment |
380 | mod { } | 380 | mod { } |
381 | ", | 381 | ", |
382 | "c", | 382 | "c", |
@@ -384,28 +384,28 @@ mod { } | |||
384 | ); | 384 | ); |
385 | do_check( | 385 | do_check( |
386 | r#" | 386 | r#" |
387 | fn -> &str { "Hello<|><|>" } | 387 | fn -> &str { "Hello$0$0" } |
388 | "#, | 388 | "#, |
389 | ", world", | 389 | ", world", |
390 | 7, | 390 | 7, |
391 | ); | 391 | ); |
392 | do_check( | 392 | do_check( |
393 | r#" | 393 | r#" |
394 | fn -> &str { // "Hello<|><|>" | 394 | fn -> &str { // "Hello$0$0" |
395 | "#, | 395 | "#, |
396 | ", world", | 396 | ", world", |
397 | 10, | 397 | 10, |
398 | ); | 398 | ); |
399 | do_check( | 399 | do_check( |
400 | r##" | 400 | r##" |
401 | fn -> &str { r#"Hello<|><|>"# | 401 | fn -> &str { r#"Hello$0$0"# |
402 | "##, | 402 | "##, |
403 | ", world", | 403 | ", world", |
404 | 10, | 404 | 10, |
405 | ); | 405 | ); |
406 | do_check( | 406 | do_check( |
407 | r" | 407 | r" |
408 | #[derive(<|>Copy<|>)] | 408 | #[derive($0Copy$0)] |
409 | enum Foo { | 409 | enum Foo { |
410 | 410 | ||
411 | } | 411 | } |
@@ -417,12 +417,12 @@ enum Foo { | |||
417 | 417 | ||
418 | #[test] | 418 | #[test] |
419 | fn reparse_str_token_with_error_unchanged() { | 419 | fn reparse_str_token_with_error_unchanged() { |
420 | do_check(r#""<|>Unclosed<|> string literal"#, "Still unclosed", 24); | 420 | do_check(r#""$0Unclosed$0 string literal"#, "Still unclosed", 24); |
421 | } | 421 | } |
422 | 422 | ||
423 | #[test] | 423 | #[test] |
424 | fn reparse_str_token_with_error_fixed() { | 424 | fn reparse_str_token_with_error_fixed() { |
425 | do_check(r#""unterinated<|><|>"#, "\"", 12); | 425 | do_check(r#""unterinated$0$0"#, "\"", 12); |
426 | } | 426 | } |
427 | 427 | ||
428 | #[test] | 428 | #[test] |
@@ -430,7 +430,7 @@ enum Foo { | |||
430 | do_check( | 430 | do_check( |
431 | r#"fn main() { | 431 | r#"fn main() { |
432 | if {} | 432 | if {} |
433 | 32 + 4<|><|> | 433 | 32 + 4$0$0 |
434 | return | 434 | return |
435 | if {} | 435 | if {} |
436 | }"#, | 436 | }"#, |
@@ -444,7 +444,7 @@ enum Foo { | |||
444 | do_check( | 444 | do_check( |
445 | r#"fn main() { | 445 | r#"fn main() { |
446 | if {} | 446 | if {} |
447 | 32 + 4<|><|> | 447 | 32 + 4$0$0 |
448 | return | 448 | return |
449 | if {} | 449 | if {} |
450 | }"#, | 450 | }"#, |
diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs index 8c217dfe0..9d3433c9d 100644 --- a/crates/syntax/src/tests.rs +++ b/crates/syntax/src/tests.rs | |||
@@ -103,6 +103,15 @@ fn type_parser_tests() { | |||
103 | } | 103 | } |
104 | 104 | ||
105 | #[test] | 105 | #[test] |
106 | fn stmt_parser_tests() { | ||
107 | fragment_parser_dir_test( | ||
108 | &["parser/fragments/stmt/ok"], | ||
109 | &["parser/fragments/stmt/err"], | ||
110 | crate::ast::Stmt::parse, | ||
111 | ); | ||
112 | } | ||
113 | |||
114 | #[test] | ||
106 | fn parser_fuzz_tests() { | 115 | fn parser_fuzz_tests() { |
107 | for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) { | 116 | for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) { |
108 | fuzz::check_parser(&text) | 117 | fuzz::check_parser(&text) |