aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax')
-rw-r--r--crates/ra_syntax/src/lib.rs16
-rw-r--r--crates/ra_syntax/src/parsing/reparsing.rs12
-rw-r--r--crates/ra_syntax/src/syntax_node.rs30
-rw-r--r--crates/ra_syntax/tests/test.rs25
4 files changed, 36 insertions, 47 deletions
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index f765f621b..37320e1ba 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -31,7 +31,7 @@ pub mod ast;
31#[doc(hidden)] 31#[doc(hidden)]
32pub mod fuzz; 32pub mod fuzz;
33 33
34use std::sync::Arc; 34use std::{sync::Arc, fmt::Write};
35 35
36use ra_text_edit::AtomTextEdit; 36use ra_text_edit::AtomTextEdit;
37 37
@@ -68,6 +68,14 @@ impl Parse {
68 Err(self.errors) 68 Err(self.errors)
69 } 69 }
70 } 70 }
71
72 pub fn debug_dump(&self) -> String {
73 let mut buf = self.tree.syntax().debug_dump();
74 for err in self.errors.iter() {
75 writeln!(buf, "err: `{}`", err).unwrap();
76 }
77 buf
78 }
71} 79}
72 80
73/// `SourceFile` represents a parse tree for a single Rust file. 81/// `SourceFile` represents a parse tree for a single Rust file.
@@ -83,6 +91,12 @@ impl SourceFile {
83 TreeArc::cast(root) 91 TreeArc::cast(root)
84 } 92 }
85 93
94 pub fn parse2(text: &str) -> Parse {
95 let (green, errors) = parsing::parse_text(text);
96 let tree = SourceFile::new(green);
97 Parse { tree, errors: Arc::new(errors) }
98 }
99
86 pub fn parse(text: &str) -> TreeArc<SourceFile> { 100 pub fn parse(text: &str) -> TreeArc<SourceFile> {
87 let (green, _errors) = parsing::parse_text(text); 101 let (green, _errors) = parsing::parse_text(text);
88 SourceFile::new(green) 102 SourceFile::new(green)
diff --git a/crates/ra_syntax/src/parsing/reparsing.rs b/crates/ra_syntax/src/parsing/reparsing.rs
index 3b6687f61..dc913cf2b 100644
--- a/crates/ra_syntax/src/parsing/reparsing.rs
+++ b/crates/ra_syntax/src/parsing/reparsing.rs
@@ -166,9 +166,11 @@ fn merge_errors(
166 166
167#[cfg(test)] 167#[cfg(test)]
168mod tests { 168mod tests {
169 use std::sync::Arc;
170
169 use test_utils::{extract_range, assert_eq_text}; 171 use test_utils::{extract_range, assert_eq_text};
170 172
171 use crate::{SourceFile, AstNode}; 173 use crate::{SourceFile, AstNode, Parse};
172 use super::*; 174 use super::*;
173 175
174 fn do_check(before: &str, replace_with: &str, reparsed_len: u32) { 176 fn do_check(before: &str, replace_with: &str, reparsed_len: u32) {
@@ -176,19 +178,19 @@ mod tests {
176 let edit = AtomTextEdit::replace(range, replace_with.to_owned()); 178 let edit = AtomTextEdit::replace(range, replace_with.to_owned());
177 let after = edit.apply(before.clone()); 179 let after = edit.apply(before.clone());
178 180
179 let fully_reparsed = SourceFile::parse(&after); 181 let fully_reparsed = SourceFile::parse2(&after);
180 let incrementally_reparsed = { 182 let incrementally_reparsed = {
181 let f = SourceFile::parse(&before); 183 let f = SourceFile::parse(&before);
182 let edit = AtomTextEdit { delete: range, insert: replace_with.to_string() }; 184 let edit = AtomTextEdit { delete: range, insert: replace_with.to_string() };
183 let (green, new_errors, range) = 185 let (green, new_errors, range) =
184 incremental_reparse(f.syntax(), &edit, f.errors()).unwrap(); 186 incremental_reparse(f.syntax(), &edit, f.errors()).unwrap();
185 assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length"); 187 assert_eq!(range.len(), reparsed_len.into(), "reparsed fragment has wrong length");
186 SourceFile::new(green, new_errors) 188 Parse { tree: SourceFile::new(green), errors: Arc::new(new_errors) }
187 }; 189 };
188 190
189 assert_eq_text!( 191 assert_eq_text!(
190 &fully_reparsed.syntax().debug_dump(), 192 &fully_reparsed.tree.syntax().debug_dump(),
191 &incrementally_reparsed.syntax().debug_dump(), 193 &incrementally_reparsed.tree.syntax().debug_dump(),
192 ); 194 );
193 } 195 }
194 196
diff --git a/crates/ra_syntax/src/syntax_node.rs b/crates/ra_syntax/src/syntax_node.rs
index ef7a51686..769125d11 100644
--- a/crates/ra_syntax/src/syntax_node.rs
+++ b/crates/ra_syntax/src/syntax_node.rs
@@ -256,37 +256,18 @@ impl SyntaxNode {
256 } 256 }
257 257
258 pub fn debug_dump(&self) -> String { 258 pub fn debug_dump(&self) -> String {
259 let mut errors: Vec<_> = match self.ancestors().find_map(SourceFile::cast) {
260 Some(file) => file.errors(),
261 None => self.root_data().to_vec(),
262 };
263 errors.sort_by_key(|e| e.offset());
264 let mut err_pos = 0;
265 let mut level = 0; 259 let mut level = 0;
266 let mut buf = String::new(); 260 let mut buf = String::new();
267 macro_rules! indent {
268 () => {
269 for _ in 0..level {
270 buf.push_str(" ");
271 }
272 };
273 }
274 261
275 for event in self.preorder_with_tokens() { 262 for event in self.preorder_with_tokens() {
276 match event { 263 match event {
277 WalkEvent::Enter(element) => { 264 WalkEvent::Enter(element) => {
278 indent!(); 265 for _ in 0..level {
266 buf.push_str(" ");
267 }
279 match element { 268 match element {
280 SyntaxElement::Node(node) => writeln!(buf, "{:?}", node).unwrap(), 269 SyntaxElement::Node(node) => writeln!(buf, "{:?}", node).unwrap(),
281 SyntaxElement::Token(token) => { 270 SyntaxElement::Token(token) => writeln!(buf, "{:?}", token).unwrap(),
282 writeln!(buf, "{:?}", token).unwrap();
283 let off = token.range().end();
284 while err_pos < errors.len() && errors[err_pos].offset() <= off {
285 indent!();
286 writeln!(buf, "err: `{}`", errors[err_pos]).unwrap();
287 err_pos += 1;
288 }
289 }
290 } 271 }
291 level += 1; 272 level += 1;
292 } 273 }
@@ -295,9 +276,6 @@ impl SyntaxNode {
295 } 276 }
296 277
297 assert_eq!(level, 0); 278 assert_eq!(level, 0);
298 for err in errors[err_pos..].iter() {
299 writeln!(buf, "err: `{}`", err).unwrap();
300 }
301 279
302 buf 280 buf
303 } 281 }
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs
index 91799f8b5..4b711f271 100644
--- a/crates/ra_syntax/tests/test.rs
+++ b/crates/ra_syntax/tests/test.rs
@@ -8,7 +8,7 @@ use std::{
8}; 8};
9 9
10use test_utils::{project_dir, dir_tests, read_text, collect_tests}; 10use test_utils::{project_dir, dir_tests, read_text, collect_tests};
11use ra_syntax::{SourceFile, AstNode, fuzz}; 11use ra_syntax::{SourceFile, fuzz};
12 12
13#[test] 13#[test]
14fn lexer_tests() { 14fn lexer_tests() {
@@ -21,26 +21,21 @@ fn lexer_tests() {
21#[test] 21#[test]
22fn parser_tests() { 22fn parser_tests() {
23 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| { 23 dir_tests(&test_data_dir(), &["parser/inline/ok", "parser/ok"], |text, path| {
24 let file = SourceFile::parse(text); 24 let parse = SourceFile::parse2(text);
25 let errors = file.errors(); 25 let errors = parse.errors.as_slice();
26 assert_eq!( 26 assert_eq!(
27 &*errors, 27 errors,
28 &[] as &[ra_syntax::SyntaxError], 28 &[] as &[ra_syntax::SyntaxError],
29 "There should be no errors in the file {:?}", 29 "There should be no errors in the file {:?}",
30 path.display() 30 path.display(),
31 ); 31 );
32 file.syntax().debug_dump() 32 parse.debug_dump()
33 }); 33 });
34 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| { 34 dir_tests(&test_data_dir(), &["parser/err", "parser/inline/err"], |text, path| {
35 let file = SourceFile::parse(text); 35 let parse = SourceFile::parse2(text);
36 let errors = file.errors(); 36 let errors = parse.errors.as_slice();
37 assert_ne!( 37 assert!(!errors.is_empty(), "There should be errors in the file {:?}", path.display());
38 &*errors, 38 parse.debug_dump()
39 &[] as &[ra_syntax::SyntaxError],
40 "There should be errors in the file {:?}",
41 path.display()
42 );
43 file.syntax().debug_dump()
44 }); 39 });
45} 40}
46 41