aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_syntax/src/lib.rs35
-rw-r--r--crates/ra_syntax/src/parsing.rs32
-rw-r--r--crates/ra_syntax/src/tests.rs66
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/expr/err/0000_truncated_add.rast1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/expr/err/0000_truncated_add.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/expr/ok/0000_add.rast8
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/expr/ok/0000_add.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/item/err/0000_extra_keyword.rast1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/item/err/0000_extra_keyword.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/item/ok/0000_fn.rast12
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/item/ok/0000_fn.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/path/err/0000_reserved_word.rast1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/path/err/0000_reserved_word.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/path/err/0001_expression.rast1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/path/err/0001_expression.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/path/ok/0000_single_ident.rast4
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/path/ok/0000_single_ident.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/path/ok/0001_multipart.rast14
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/path/ok/0001_multipart.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/pattern/err/0000_reserved_word.rast1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/pattern/err/0000_reserved_word.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/pattern/err/0001_missing_paren.rast1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/pattern/err/0001_missing_paren.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/pattern/ok/0000_enum.rast10
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/pattern/ok/0000_enum.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/type/err/0000_missing_close.rast1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/type/err/0000_missing_close.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/type/ok/0000_result.rast22
-rw-r--r--crates/ra_syntax/test_data/parser/fragments/type/ok/0000_result.rs1
29 files changed, 222 insertions, 1 deletions
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index a33a35cc1..9b7664576 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -168,6 +168,41 @@ impl SourceFile {
168 } 168 }
169} 169}
170 170
171impl ast::Path {
172 /// Returns `text`, parsed as a path, but only if it has no errors.
173 pub fn parse(text: &str) -> Result<Self, ()> {
174 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Path)
175 }
176}
177
178impl ast::Pat {
179 /// Returns `text`, parsed as a pattern, but only if it has no errors.
180 pub fn parse(text: &str) -> Result<Self, ()> {
181 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Pattern)
182 }
183}
184
185impl ast::Expr {
186 /// Returns `text`, parsed as an expression, but only if it has no errors.
187 pub fn parse(text: &str) -> Result<Self, ()> {
188 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Expr)
189 }
190}
191
192impl ast::ModuleItem {
193 /// Returns `text`, parsed as an item, but only if it has no errors.
194 pub fn parse(text: &str) -> Result<Self, ()> {
195 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Item)
196 }
197}
198
199impl ast::TypeRef {
200 /// Returns `text`, parsed as an type reference, but only if it has no errors.
201 pub fn parse(text: &str) -> Result<Self, ()> {
202 parsing::parse_text_fragment(text, ra_parser::FragmentKind::Type)
203 }
204}
205
171/// Matches a `SyntaxNode` against an `ast` type. 206/// Matches a `SyntaxNode` against an `ast` type.
172/// 207///
173/// # Example: 208/// # Example:
diff --git a/crates/ra_syntax/src/parsing.rs b/crates/ra_syntax/src/parsing.rs
index e5eb80850..0ed3c20ef 100644
--- a/crates/ra_syntax/src/parsing.rs
+++ b/crates/ra_syntax/src/parsing.rs
@@ -6,13 +6,14 @@ mod text_token_source;
6mod text_tree_sink; 6mod text_tree_sink;
7mod reparsing; 7mod reparsing;
8 8
9use crate::{syntax_node::GreenNode, SyntaxError}; 9use crate::{syntax_node::GreenNode, AstNode, SyntaxError, SyntaxNode};
10use text_token_source::TextTokenSource; 10use text_token_source::TextTokenSource;
11use text_tree_sink::TextTreeSink; 11use text_tree_sink::TextTreeSink;
12 12
13pub use lexer::*; 13pub use lexer::*;
14 14
15pub(crate) use self::reparsing::incremental_reparse; 15pub(crate) use self::reparsing::incremental_reparse;
16use ra_parser::SyntaxKind;
16 17
17pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) { 18pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) {
18 let (tokens, lexer_errors) = tokenize(&text); 19 let (tokens, lexer_errors) = tokenize(&text);
@@ -27,3 +28,32 @@ pub(crate) fn parse_text(text: &str) -> (GreenNode, Vec<SyntaxError>) {
27 28
28 (tree, parser_errors) 29 (tree, parser_errors)
29} 30}
31
32/// Returns `text` parsed as a `T` provided there are no parse errors.
33pub(crate) fn parse_text_fragment<T: AstNode>(
34 text: &str,
35 fragment_kind: ra_parser::FragmentKind,
36) -> Result<T, ()> {
37 let (tokens, lexer_errors) = tokenize(&text);
38 if !lexer_errors.is_empty() {
39 return Err(());
40 }
41
42 let mut token_source = TextTokenSource::new(text, &tokens);
43 let mut tree_sink = TextTreeSink::new(text, &tokens);
44
45 // TextTreeSink assumes that there's at least some root node to which it can attach errors and
46 // tokens. We arbitrarily give it a SourceFile.
47 use ra_parser::TreeSink;
48 tree_sink.start_node(SyntaxKind::SOURCE_FILE);
49 ra_parser::parse_fragment(&mut token_source, &mut tree_sink, fragment_kind);
50 tree_sink.finish_node();
51
52 let (tree, parser_errors) = tree_sink.finish();
53 use ra_parser::TokenSource;
54 if !parser_errors.is_empty() || token_source.current().kind != SyntaxKind::EOF {
55 return Err(());
56 }
57
58 SyntaxNode::new_root(tree).first_child().and_then(T::cast).ok_or(())
59}
diff --git a/crates/ra_syntax/src/tests.rs b/crates/ra_syntax/src/tests.rs
index aee57db62..959967b79 100644
--- a/crates/ra_syntax/src/tests.rs
+++ b/crates/ra_syntax/src/tests.rs
@@ -55,6 +55,51 @@ fn parser_tests() {
55} 55}
56 56
57#[test] 57#[test]
58fn expr_parser_tests() {
59 fragment_parser_dir_test(
60 &["parser/fragments/expr/ok"],
61 &["parser/fragments/expr/err"],
62 crate::ast::Expr::parse,
63 );
64}
65
66#[test]
67fn path_parser_tests() {
68 fragment_parser_dir_test(
69 &["parser/fragments/path/ok"],
70 &["parser/fragments/path/err"],
71 crate::ast::Path::parse,
72 );
73}
74
75#[test]
76fn pattern_parser_tests() {
77 fragment_parser_dir_test(
78 &["parser/fragments/pattern/ok"],
79 &["parser/fragments/pattern/err"],
80 crate::ast::Pat::parse,
81 );
82}
83
84#[test]
85fn item_parser_tests() {
86 fragment_parser_dir_test(
87 &["parser/fragments/item/ok"],
88 &["parser/fragments/item/err"],
89 crate::ast::ModuleItem::parse,
90 );
91}
92
93#[test]
94fn type_parser_tests() {
95 fragment_parser_dir_test(
96 &["parser/fragments/type/ok"],
97 &["parser/fragments/type/err"],
98 crate::ast::TypeRef::parse,
99 );
100}
101
102#[test]
58fn parser_fuzz_tests() { 103fn parser_fuzz_tests() {
59 for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) { 104 for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) {
60 fuzz::check_parser(&text) 105 fuzz::check_parser(&text)
@@ -134,3 +179,24 @@ fn dump_tokens_and_errors(tokens: &[Token], errors: &[SyntaxError], text: &str)
134 } 179 }
135 acc 180 acc
136} 181}
182
183fn fragment_parser_dir_test<T, F>(ok_paths: &[&str], err_paths: &[&str], f: F)
184where
185 T: crate::AstNode,
186 F: Fn(&str) -> Result<T, ()>,
187{
188 dir_tests(&test_data_dir(), ok_paths, "rast", |text, path| {
189 if let Ok(node) = f(text) {
190 format!("{:#?}", crate::ast::AstNode::syntax(&node))
191 } else {
192 panic!("Failed to parse '{:?}'", path);
193 }
194 });
195 dir_tests(&test_data_dir(), err_paths, "rast", |text, path| {
196 if let Ok(_) = f(text) {
197 panic!("'{:?}' successfully parsed when it should have errored", path);
198 } else {
199 "ERROR\n".to_owned()
200 }
201 });
202}
diff --git a/crates/ra_syntax/test_data/parser/fragments/expr/err/0000_truncated_add.rast b/crates/ra_syntax/test_data/parser/fragments/expr/err/0000_truncated_add.rast
new file mode 100644
index 000000000..5df7507e2
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/expr/err/0000_truncated_add.rast
@@ -0,0 +1 @@
ERROR
diff --git a/crates/ra_syntax/test_data/parser/fragments/expr/err/0000_truncated_add.rs b/crates/ra_syntax/test_data/parser/fragments/expr/err/0000_truncated_add.rs
new file mode 100644
index 000000000..ca49acb07
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/expr/err/0000_truncated_add.rs
@@ -0,0 +1 @@
1 +
diff --git a/crates/ra_syntax/test_data/parser/fragments/expr/ok/0000_add.rast b/crates/ra_syntax/test_data/parser/fragments/expr/ok/0000_add.rast
new file mode 100644
index 000000000..fa78a02a6
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/expr/ok/0000_add.rast
@@ -0,0 +1,8 @@
1[email protected]
2 [email protected]
3 [email protected] "1"
4 [email protected] " "
5 [email protected] "+"
6 [email protected] " "
7 [email protected]
8 [email protected] "2"
diff --git a/crates/ra_syntax/test_data/parser/fragments/expr/ok/0000_add.rs b/crates/ra_syntax/test_data/parser/fragments/expr/ok/0000_add.rs
new file mode 100644
index 000000000..e0ef58402
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/expr/ok/0000_add.rs
@@ -0,0 +1 @@
1 + 2
diff --git a/crates/ra_syntax/test_data/parser/fragments/item/err/0000_extra_keyword.rast b/crates/ra_syntax/test_data/parser/fragments/item/err/0000_extra_keyword.rast
new file mode 100644
index 000000000..5df7507e2
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/item/err/0000_extra_keyword.rast
@@ -0,0 +1 @@
ERROR
diff --git a/crates/ra_syntax/test_data/parser/fragments/item/err/0000_extra_keyword.rs b/crates/ra_syntax/test_data/parser/fragments/item/err/0000_extra_keyword.rs
new file mode 100644
index 000000000..dc32389bb
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/item/err/0000_extra_keyword.rs
@@ -0,0 +1 @@
fn fn foo() {}
diff --git a/crates/ra_syntax/test_data/parser/fragments/item/ok/0000_fn.rast b/crates/ra_syntax/test_data/parser/fragments/item/ok/0000_fn.rast
new file mode 100644
index 000000000..f1e78f388
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/item/ok/0000_fn.rast
@@ -0,0 +1,12 @@
1[email protected]
2 [email protected] "fn"
3 [email protected] " "
4 [email protected]
5 [email protected] "foo"
6 [email protected]
7 [email protected] "("
8 [email protected] ")"
9 [email protected] " "
10 [email protected]
11 [email protected] "{"
12 [email protected] "}"
diff --git a/crates/ra_syntax/test_data/parser/fragments/item/ok/0000_fn.rs b/crates/ra_syntax/test_data/parser/fragments/item/ok/0000_fn.rs
new file mode 100644
index 000000000..8f3b7ef11
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/item/ok/0000_fn.rs
@@ -0,0 +1 @@
fn foo() {}
diff --git a/crates/ra_syntax/test_data/parser/fragments/path/err/0000_reserved_word.rast b/crates/ra_syntax/test_data/parser/fragments/path/err/0000_reserved_word.rast
new file mode 100644
index 000000000..5df7507e2
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/path/err/0000_reserved_word.rast
@@ -0,0 +1 @@
ERROR
diff --git a/crates/ra_syntax/test_data/parser/fragments/path/err/0000_reserved_word.rs b/crates/ra_syntax/test_data/parser/fragments/path/err/0000_reserved_word.rs
new file mode 100644
index 000000000..2046de049
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/path/err/0000_reserved_word.rs
@@ -0,0 +1 @@
struct
diff --git a/crates/ra_syntax/test_data/parser/fragments/path/err/0001_expression.rast b/crates/ra_syntax/test_data/parser/fragments/path/err/0001_expression.rast
new file mode 100644
index 000000000..5df7507e2
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/path/err/0001_expression.rast
@@ -0,0 +1 @@
ERROR
diff --git a/crates/ra_syntax/test_data/parser/fragments/path/err/0001_expression.rs b/crates/ra_syntax/test_data/parser/fragments/path/err/0001_expression.rs
new file mode 100644
index 000000000..745e8d376
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/path/err/0001_expression.rs
@@ -0,0 +1 @@
a + b
diff --git a/crates/ra_syntax/test_data/parser/fragments/path/ok/0000_single_ident.rast b/crates/ra_syntax/test_data/parser/fragments/path/ok/0000_single_ident.rast
new file mode 100644
index 000000000..0c5d4360f
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/path/ok/0000_single_ident.rast
@@ -0,0 +1,4 @@
1[email protected]
2 [email protected]
3 [email protected]
4 [email protected] "foo"
diff --git a/crates/ra_syntax/test_data/parser/fragments/path/ok/0000_single_ident.rs b/crates/ra_syntax/test_data/parser/fragments/path/ok/0000_single_ident.rs
new file mode 100644
index 000000000..257cc5642
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/path/ok/0000_single_ident.rs
@@ -0,0 +1 @@
foo
diff --git a/crates/ra_syntax/test_data/parser/fragments/path/ok/0001_multipart.rast b/crates/ra_syntax/test_data/parser/fragments/path/ok/0001_multipart.rast
new file mode 100644
index 000000000..4a2b45e6a
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/path/ok/0001_multipart.rast
@@ -0,0 +1,14 @@
1[email protected]
2 [email protected]
3 [email protected]
4 [email protected]
5 [email protected]
6 [email protected] "foo"
7 [email protected] "::"
8 [email protected]
9 [email protected]
10 [email protected] "bar"
11 [email protected] "::"
12 [email protected]
13 [email protected]
14 [email protected] "baz"
diff --git a/crates/ra_syntax/test_data/parser/fragments/path/ok/0001_multipart.rs b/crates/ra_syntax/test_data/parser/fragments/path/ok/0001_multipart.rs
new file mode 100644
index 000000000..81e0b21cd
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/path/ok/0001_multipart.rs
@@ -0,0 +1 @@
foo::bar::baz
diff --git a/crates/ra_syntax/test_data/parser/fragments/pattern/err/0000_reserved_word.rast b/crates/ra_syntax/test_data/parser/fragments/pattern/err/0000_reserved_word.rast
new file mode 100644
index 000000000..5df7507e2
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/pattern/err/0000_reserved_word.rast
@@ -0,0 +1 @@
ERROR
diff --git a/crates/ra_syntax/test_data/parser/fragments/pattern/err/0000_reserved_word.rs b/crates/ra_syntax/test_data/parser/fragments/pattern/err/0000_reserved_word.rs
new file mode 100644
index 000000000..ae26fc455
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/pattern/err/0000_reserved_word.rs
@@ -0,0 +1 @@
fn
diff --git a/crates/ra_syntax/test_data/parser/fragments/pattern/err/0001_missing_paren.rast b/crates/ra_syntax/test_data/parser/fragments/pattern/err/0001_missing_paren.rast
new file mode 100644
index 000000000..5df7507e2
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/pattern/err/0001_missing_paren.rast
@@ -0,0 +1 @@
ERROR
diff --git a/crates/ra_syntax/test_data/parser/fragments/pattern/err/0001_missing_paren.rs b/crates/ra_syntax/test_data/parser/fragments/pattern/err/0001_missing_paren.rs
new file mode 100644
index 000000000..61a391d08
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/pattern/err/0001_missing_paren.rs
@@ -0,0 +1 @@
Some(x
diff --git a/crates/ra_syntax/test_data/parser/fragments/pattern/ok/0000_enum.rast b/crates/ra_syntax/test_data/parser/fragments/pattern/ok/0000_enum.rast
new file mode 100644
index 000000000..15eb7f9c6
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/pattern/ok/0000_enum.rast
@@ -0,0 +1,10 @@
1[email protected]
2 [email protected]
3 [email protected]
4 [email protected]
5 [email protected] "Some"
6 [email protected] "("
7 [email protected]
8 [email protected]
9 [email protected] "x"
10 [email protected] ")"
diff --git a/crates/ra_syntax/test_data/parser/fragments/pattern/ok/0000_enum.rs b/crates/ra_syntax/test_data/parser/fragments/pattern/ok/0000_enum.rs
new file mode 100644
index 000000000..87114dd78
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/pattern/ok/0000_enum.rs
@@ -0,0 +1 @@
Some(x)
diff --git a/crates/ra_syntax/test_data/parser/fragments/type/err/0000_missing_close.rast b/crates/ra_syntax/test_data/parser/fragments/type/err/0000_missing_close.rast
new file mode 100644
index 000000000..5df7507e2
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/type/err/0000_missing_close.rast
@@ -0,0 +1 @@
ERROR
diff --git a/crates/ra_syntax/test_data/parser/fragments/type/err/0000_missing_close.rs b/crates/ra_syntax/test_data/parser/fragments/type/err/0000_missing_close.rs
new file mode 100644
index 000000000..caa4d7c09
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/type/err/0000_missing_close.rs
@@ -0,0 +1 @@
Result<Foo, Bar
diff --git a/crates/ra_syntax/test_data/parser/fragments/type/ok/0000_result.rast b/crates/ra_syntax/test_data/parser/fragments/type/ok/0000_result.rast
new file mode 100644
index 000000000..8831cfa6c
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/type/ok/0000_result.rast
@@ -0,0 +1,22 @@
1[email protected]
2 [email protected]
3 [email protected]
4 [email protected]
5 [email protected] "Result"
6 [email protected]
7 [email protected] "<"
8 [email protected]
9 [email protected]
10 [email protected]
11 [email protected]
12 [email protected]
13 [email protected] "Foo"
14 [email protected] ","
15 [email protected] " "
16 [email protected]
17 [email protected]
18 [email protected]
19 [email protected]
20 [email protected]
21 [email protected] "Bar"
22 [email protected] ">"
diff --git a/crates/ra_syntax/test_data/parser/fragments/type/ok/0000_result.rs b/crates/ra_syntax/test_data/parser/fragments/type/ok/0000_result.rs
new file mode 100644
index 000000000..b50b3bb3b
--- /dev/null
+++ b/crates/ra_syntax/test_data/parser/fragments/type/ok/0000_result.rs
@@ -0,0 +1 @@
Result<Foo, Bar>