diff options
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r-- | crates/ra_syntax/src/ast/generated.rs | 60 | ||||
-rw-r--r-- | crates/ra_syntax/src/grammar.ron | 19 | ||||
-rw-r--r-- | crates/ra_syntax/tests/test.rs | 157 |
3 files changed, 96 insertions, 140 deletions
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index bf056131e..c73533861 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -523,7 +523,15 @@ impl<R: TreeRoot<RaTypes>> CastExprNode<R> { | |||
523 | } | 523 | } |
524 | 524 | ||
525 | 525 | ||
526 | impl<'a> CastExpr<'a> {} | 526 | impl<'a> CastExpr<'a> { |
527 | pub fn expr(self) -> Option<Expr<'a>> { | ||
528 | super::child_opt(self) | ||
529 | } | ||
530 | |||
531 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
532 | super::child_opt(self) | ||
533 | } | ||
534 | } | ||
527 | 535 | ||
528 | // Char | 536 | // Char |
529 | #[derive(Debug, Clone, Copy,)] | 537 | #[derive(Debug, Clone, Copy,)] |
@@ -1553,6 +1561,10 @@ impl<'a> LetStmt<'a> { | |||
1553 | super::child_opt(self) | 1561 | super::child_opt(self) |
1554 | } | 1562 | } |
1555 | 1563 | ||
1564 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
1565 | super::child_opt(self) | ||
1566 | } | ||
1567 | |||
1556 | pub fn initializer(self) -> Option<Expr<'a>> { | 1568 | pub fn initializer(self) -> Option<Expr<'a>> { |
1557 | super::child_opt(self) | 1569 | super::child_opt(self) |
1558 | } | 1570 | } |
@@ -2312,6 +2324,10 @@ impl<'a> Param<'a> { | |||
2312 | pub fn pat(self) -> Option<Pat<'a>> { | 2324 | pub fn pat(self) -> Option<Pat<'a>> { |
2313 | super::child_opt(self) | 2325 | super::child_opt(self) |
2314 | } | 2326 | } |
2327 | |||
2328 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
2329 | super::child_opt(self) | ||
2330 | } | ||
2315 | } | 2331 | } |
2316 | 2332 | ||
2317 | // ParamList | 2333 | // ParamList |
@@ -2394,7 +2410,11 @@ impl<R: TreeRoot<RaTypes>> ParenExprNode<R> { | |||
2394 | } | 2410 | } |
2395 | 2411 | ||
2396 | 2412 | ||
2397 | impl<'a> ParenExpr<'a> {} | 2413 | impl<'a> ParenExpr<'a> { |
2414 | pub fn expr(self) -> Option<Expr<'a>> { | ||
2415 | super::child_opt(self) | ||
2416 | } | ||
2417 | } | ||
2398 | 2418 | ||
2399 | // ParenType | 2419 | // ParenType |
2400 | #[derive(Debug, Clone, Copy,)] | 2420 | #[derive(Debug, Clone, Copy,)] |
@@ -2681,7 +2701,11 @@ impl<R: TreeRoot<RaTypes>> PathTypeNode<R> { | |||
2681 | } | 2701 | } |
2682 | 2702 | ||
2683 | 2703 | ||
2684 | impl<'a> PathType<'a> {} | 2704 | impl<'a> PathType<'a> { |
2705 | pub fn path(self) -> Option<Path<'a>> { | ||
2706 | super::child_opt(self) | ||
2707 | } | ||
2708 | } | ||
2685 | 2709 | ||
2686 | // PlaceholderPat | 2710 | // PlaceholderPat |
2687 | #[derive(Debug, Clone, Copy,)] | 2711 | #[derive(Debug, Clone, Copy,)] |
@@ -2829,7 +2853,11 @@ impl<R: TreeRoot<RaTypes>> PrefixExprNode<R> { | |||
2829 | } | 2853 | } |
2830 | 2854 | ||
2831 | 2855 | ||
2832 | impl<'a> PrefixExpr<'a> {} | 2856 | impl<'a> PrefixExpr<'a> { |
2857 | pub fn expr(self) -> Option<Expr<'a>> { | ||
2858 | super::child_opt(self) | ||
2859 | } | ||
2860 | } | ||
2833 | 2861 | ||
2834 | // RangeExpr | 2862 | // RangeExpr |
2835 | #[derive(Debug, Clone, Copy,)] | 2863 | #[derive(Debug, Clone, Copy,)] |
@@ -2940,7 +2968,11 @@ impl<R: TreeRoot<RaTypes>> RefExprNode<R> { | |||
2940 | } | 2968 | } |
2941 | 2969 | ||
2942 | 2970 | ||
2943 | impl<'a> RefExpr<'a> {} | 2971 | impl<'a> RefExpr<'a> { |
2972 | pub fn expr(self) -> Option<Expr<'a>> { | ||
2973 | super::child_opt(self) | ||
2974 | } | ||
2975 | } | ||
2944 | 2976 | ||
2945 | // RefPat | 2977 | // RefPat |
2946 | #[derive(Debug, Clone, Copy,)] | 2978 | #[derive(Debug, Clone, Copy,)] |
@@ -3051,7 +3083,11 @@ impl<R: TreeRoot<RaTypes>> RetTypeNode<R> { | |||
3051 | } | 3083 | } |
3052 | 3084 | ||
3053 | 3085 | ||
3054 | impl<'a> RetType<'a> {} | 3086 | impl<'a> RetType<'a> { |
3087 | pub fn type_ref(self) -> Option<TypeRef<'a>> { | ||
3088 | super::child_opt(self) | ||
3089 | } | ||
3090 | } | ||
3055 | 3091 | ||
3056 | // ReturnExpr | 3092 | // ReturnExpr |
3057 | #[derive(Debug, Clone, Copy,)] | 3093 | #[derive(Debug, Clone, Copy,)] |
@@ -3088,7 +3124,11 @@ impl<R: TreeRoot<RaTypes>> ReturnExprNode<R> { | |||
3088 | } | 3124 | } |
3089 | 3125 | ||
3090 | 3126 | ||
3091 | impl<'a> ReturnExpr<'a> {} | 3127 | impl<'a> ReturnExpr<'a> { |
3128 | pub fn expr(self) -> Option<Expr<'a>> { | ||
3129 | super::child_opt(self) | ||
3130 | } | ||
3131 | } | ||
3092 | 3132 | ||
3093 | // SelfParam | 3133 | // SelfParam |
3094 | #[derive(Debug, Clone, Copy,)] | 3134 | #[derive(Debug, Clone, Copy,)] |
@@ -3578,7 +3618,11 @@ impl<R: TreeRoot<RaTypes>> TryExprNode<R> { | |||
3578 | } | 3618 | } |
3579 | 3619 | ||
3580 | 3620 | ||
3581 | impl<'a> TryExpr<'a> {} | 3621 | impl<'a> TryExpr<'a> { |
3622 | pub fn expr(self) -> Option<Expr<'a>> { | ||
3623 | super::child_opt(self) | ||
3624 | } | ||
3625 | } | ||
3582 | 3626 | ||
3583 | // TupleExpr | 3627 | // TupleExpr |
3584 | #[derive(Debug, Clone, Copy,)] | 3628 | #[derive(Debug, Clone, Copy,)] |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index eed67637e..e3b9032a0 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -254,7 +254,7 @@ Grammar( | |||
254 | ], | 254 | ], |
255 | options: [ "ParamList", ["body", "Block"], "RetType" ], | 255 | options: [ "ParamList", ["body", "Block"], "RetType" ], |
256 | ), | 256 | ), |
257 | "RetType": (), | 257 | "RetType": (options: ["TypeRef"]), |
258 | "StructDef": ( | 258 | "StructDef": ( |
259 | traits: [ | 259 | traits: [ |
260 | "NameOwner", | 260 | "NameOwner", |
@@ -304,7 +304,7 @@ Grammar( | |||
304 | "ParenType": (), | 304 | "ParenType": (), |
305 | "TupleType": (), | 305 | "TupleType": (), |
306 | "NeverType": (), | 306 | "NeverType": (), |
307 | "PathType": (), | 307 | "PathType": (options: ["Path"]), |
308 | "PointerType": (), | 308 | "PointerType": (), |
309 | "ArrayType": (), | 309 | "ArrayType": (), |
310 | "SliceType": (), | 310 | "SliceType": (), |
@@ -346,7 +346,7 @@ Grammar( | |||
346 | 346 | ||
347 | "TupleExpr": (), | 347 | "TupleExpr": (), |
348 | "ArrayExpr": (), | 348 | "ArrayExpr": (), |
349 | "ParenExpr": (), | 349 | "ParenExpr": (options: ["Expr"]), |
350 | "PathExpr": (options: ["Path"]), | 350 | "PathExpr": (options: ["Path"]), |
351 | "LambdaExpr": ( | 351 | "LambdaExpr": ( |
352 | options: [ | 352 | options: [ |
@@ -377,7 +377,7 @@ Grammar( | |||
377 | "BlockExpr": ( | 377 | "BlockExpr": ( |
378 | options: [ "Block" ] | 378 | options: [ "Block" ] |
379 | ), | 379 | ), |
380 | "ReturnExpr": (), | 380 | "ReturnExpr": (options: ["Expr"]), |
381 | "MatchExpr": ( | 381 | "MatchExpr": ( |
382 | options: [ "Expr", "MatchArmList" ], | 382 | options: [ "Expr", "MatchArmList" ], |
383 | ), | 383 | ), |
@@ -405,10 +405,10 @@ Grammar( | |||
405 | ), | 405 | ), |
406 | "IndexExpr": (), | 406 | "IndexExpr": (), |
407 | "FieldExpr": (), | 407 | "FieldExpr": (), |
408 | "TryExpr": (), | 408 | "TryExpr": (options: ["Expr"]), |
409 | "CastExpr": (), | 409 | "CastExpr": (options: ["Expr", "TypeRef"]), |
410 | "RefExpr": (), | 410 | "RefExpr": (options: ["Expr"]), |
411 | "PrefixExpr": (), | 411 | "PrefixExpr": (options: ["Expr"]), |
412 | "RangeExpr": (), | 412 | "RangeExpr": (), |
413 | "BinExpr": (), | 413 | "BinExpr": (), |
414 | "String": (), | 414 | "String": (), |
@@ -499,6 +499,7 @@ Grammar( | |||
499 | ), | 499 | ), |
500 | "LetStmt": ( options: [ | 500 | "LetStmt": ( options: [ |
501 | ["pat", "Pat"], | 501 | ["pat", "Pat"], |
502 | ["type_ref", "TypeRef"], | ||
502 | ["initializer", "Expr"], | 503 | ["initializer", "Expr"], |
503 | ]), | 504 | ]), |
504 | "Condition": ( | 505 | "Condition": ( |
@@ -521,7 +522,7 @@ Grammar( | |||
521 | ), | 522 | ), |
522 | "SelfParam": (), | 523 | "SelfParam": (), |
523 | "Param": ( | 524 | "Param": ( |
524 | options: [ "Pat" ], | 525 | options: [ "Pat", "TypeRef" ], |
525 | ), | 526 | ), |
526 | "UseItem": ( | 527 | "UseItem": ( |
527 | options: [ "UseTree" ] | 528 | options: [ "UseTree" ] |
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs index 4266864bd..2235dc401 100644 --- a/crates/ra_syntax/tests/test.rs +++ b/crates/ra_syntax/tests/test.rs | |||
@@ -1,14 +1,13 @@ | |||
1 | extern crate ra_syntax; | 1 | extern crate ra_syntax; |
2 | #[macro_use] | ||
3 | extern crate test_utils; | 2 | extern crate test_utils; |
4 | extern crate walkdir; | 3 | extern crate walkdir; |
5 | 4 | ||
6 | use std::{ | 5 | use std::{ |
7 | fmt::Write, | 6 | fmt::Write, |
8 | fs, | 7 | path::{PathBuf, Component}, |
9 | path::{Path, PathBuf, Component}, | ||
10 | }; | 8 | }; |
11 | 9 | ||
10 | use test_utils::{project_dir, dir_tests, read_text, collect_tests}; | ||
12 | use ra_syntax::{ | 11 | use ra_syntax::{ |
13 | utils::{check_fuzz_invariants, dump_tree}, | 12 | utils::{check_fuzz_invariants, dump_tree}, |
14 | SourceFileNode, | 13 | SourceFileNode, |
@@ -16,7 +15,7 @@ use ra_syntax::{ | |||
16 | 15 | ||
17 | #[test] | 16 | #[test] |
18 | fn lexer_tests() { | 17 | fn lexer_tests() { |
19 | dir_tests(&["lexer"], |text, _| { | 18 | dir_tests(&test_data_dir(), &["lexer"], |text, _| { |
20 | let tokens = ra_syntax::tokenize(text); | 19 | let tokens = ra_syntax::tokenize(text); |
21 | dump_tokens(&tokens, text) | 20 | dump_tokens(&tokens, text) |
22 | }) | 21 | }) |
@@ -24,33 +23,41 @@ fn lexer_tests() { | |||
24 | 23 | ||
25 | #[test] | 24 | #[test] |
26 | fn parser_tests() { | 25 | fn parser_tests() { |
27 | dir_tests(&["parser/inline/ok", "parser/ok"], |text, path| { | 26 | dir_tests( |
28 | let file = SourceFileNode::parse(text); | 27 | &test_data_dir(), |
29 | let errors = file.errors(); | 28 | &["parser/inline/ok", "parser/ok"], |
30 | assert_eq!( | 29 | |text, path| { |
31 | &*errors, | 30 | let file = SourceFileNode::parse(text); |
32 | &[] as &[ra_syntax::SyntaxError], | 31 | let errors = file.errors(); |
33 | "There should be no errors in the file {:?}", | 32 | assert_eq!( |
34 | path.display() | 33 | &*errors, |
35 | ); | 34 | &[] as &[ra_syntax::SyntaxError], |
36 | dump_tree(file.syntax()) | 35 | "There should be no errors in the file {:?}", |
37 | }); | 36 | path.display() |
38 | dir_tests(&["parser/err", "parser/inline/err"], |text, path| { | 37 | ); |
39 | let file = SourceFileNode::parse(text); | 38 | dump_tree(file.syntax()) |
40 | let errors = file.errors(); | 39 | }, |
41 | assert_ne!( | 40 | ); |
42 | &*errors, | 41 | dir_tests( |
43 | &[] as &[ra_syntax::SyntaxError], | 42 | &test_data_dir(), |
44 | "There should be errors in the file {:?}", | 43 | &["parser/err", "parser/inline/err"], |
45 | path.display() | 44 | |text, path| { |
46 | ); | 45 | let file = SourceFileNode::parse(text); |
47 | dump_tree(file.syntax()) | 46 | let errors = file.errors(); |
48 | }); | 47 | assert_ne!( |
48 | &*errors, | ||
49 | &[] as &[ra_syntax::SyntaxError], | ||
50 | "There should be errors in the file {:?}", | ||
51 | path.display() | ||
52 | ); | ||
53 | dump_tree(file.syntax()) | ||
54 | }, | ||
55 | ); | ||
49 | } | 56 | } |
50 | 57 | ||
51 | #[test] | 58 | #[test] |
52 | fn parser_fuzz_tests() { | 59 | fn parser_fuzz_tests() { |
53 | for (_, text) in collect_tests(&["parser/fuzz-failures"]) { | 60 | for (_, text) in collect_tests(&test_data_dir(), &["parser/fuzz-failures"]) { |
54 | check_fuzz_invariants(&text) | 61 | check_fuzz_invariants(&text) |
55 | } | 62 | } |
56 | } | 63 | } |
@@ -92,102 +99,6 @@ fn self_hosting_parsing() { | |||
92 | "self_hosting_parsing found too few files - is it running in the right directory?" | 99 | "self_hosting_parsing found too few files - is it running in the right directory?" |
93 | ) | 100 | ) |
94 | } | 101 | } |
95 | /// Read file and normalize newlines. | ||
96 | /// | ||
97 | /// `rustc` seems to always normalize `\r\n` newlines to `\n`: | ||
98 | /// | ||
99 | /// ``` | ||
100 | /// let s = " | ||
101 | /// "; | ||
102 | /// assert_eq!(s.as_bytes(), &[10]); | ||
103 | /// ``` | ||
104 | /// | ||
105 | /// so this should always be correct. | ||
106 | fn read_text(path: &Path) -> String { | ||
107 | fs::read_to_string(path) | ||
108 | .expect(&format!("File at {:?} should be valid", path)) | ||
109 | .replace("\r\n", "\n") | ||
110 | } | ||
111 | |||
112 | fn dir_tests<F>(paths: &[&str], f: F) | ||
113 | where | ||
114 | F: Fn(&str, &Path) -> String, | ||
115 | { | ||
116 | for (path, input_code) in collect_tests(paths) { | ||
117 | let parse_tree = f(&input_code, &path); | ||
118 | let path = path.with_extension("txt"); | ||
119 | if !path.exists() { | ||
120 | println!("\nfile: {}", path.display()); | ||
121 | println!("No .txt file with expected result, creating...\n"); | ||
122 | println!("{}\n{}", input_code, parse_tree); | ||
123 | fs::write(&path, &parse_tree).unwrap(); | ||
124 | panic!("No expected result") | ||
125 | } | ||
126 | let expected = read_text(&path); | ||
127 | let expected = expected.as_str(); | ||
128 | let parse_tree = parse_tree.as_str(); | ||
129 | assert_equal_text(expected, parse_tree, &path); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | const REWRITE: bool = false; | ||
134 | |||
135 | fn assert_equal_text(expected: &str, actual: &str, path: &Path) { | ||
136 | if expected == actual { | ||
137 | return; | ||
138 | } | ||
139 | let dir = project_dir(); | ||
140 | let pretty_path = path.strip_prefix(&dir).unwrap_or_else(|_| path); | ||
141 | if expected.trim() == actual.trim() { | ||
142 | println!("whitespace difference, rewriting"); | ||
143 | println!("file: {}\n", pretty_path.display()); | ||
144 | fs::write(path, actual).unwrap(); | ||
145 | return; | ||
146 | } | ||
147 | if REWRITE { | ||
148 | println!("rewriting {}", pretty_path.display()); | ||
149 | fs::write(path, actual).unwrap(); | ||
150 | return; | ||
151 | } | ||
152 | assert_eq_text!(expected, actual, "file: {}", pretty_path.display()); | ||
153 | } | ||
154 | |||
155 | fn collect_tests(paths: &[&str]) -> Vec<(PathBuf, String)> { | ||
156 | paths | ||
157 | .iter() | ||
158 | .flat_map(|path| { | ||
159 | let path = test_data_dir().join(path); | ||
160 | test_from_dir(&path).into_iter() | ||
161 | }) | ||
162 | .map(|path| { | ||
163 | let text = read_text(&path); | ||
164 | (path, text) | ||
165 | }) | ||
166 | .collect() | ||
167 | } | ||
168 | |||
169 | fn test_from_dir(dir: &Path) -> Vec<PathBuf> { | ||
170 | let mut acc = Vec::new(); | ||
171 | for file in fs::read_dir(&dir).unwrap() { | ||
172 | let file = file.unwrap(); | ||
173 | let path = file.path(); | ||
174 | if path.extension().unwrap_or_default() == "rs" { | ||
175 | acc.push(path); | ||
176 | } | ||
177 | } | ||
178 | acc.sort(); | ||
179 | acc | ||
180 | } | ||
181 | |||
182 | fn project_dir() -> PathBuf { | ||
183 | let dir = env!("CARGO_MANIFEST_DIR"); | ||
184 | PathBuf::from(dir) | ||
185 | .parent() | ||
186 | .unwrap() | ||
187 | .parent() | ||
188 | .unwrap() | ||
189 | .to_owned() | ||
190 | } | ||
191 | 102 | ||
192 | fn test_data_dir() -> PathBuf { | 103 | fn test_data_dir() -> PathBuf { |
193 | project_dir().join("crates/ra_syntax/tests/data") | 104 | project_dir().join("crates/ra_syntax/tests/data") |