aboutsummaryrefslogtreecommitdiff
path: root/src/utils.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-07-31 20:14:56 +0100
committerAleksey Kladov <[email protected]>2018-07-31 20:14:56 +0100
commit8105c14454f8c4f575f16b44ec616ffd045be57f (patch)
treed8d2aba889583afa2e6045f024656918b5f273db /src/utils.rs
parent5d8cef4c0eec3718d92560337f9a1d4fcf04d01f (diff)
Improve debug_dump performance
Diffstat (limited to 'src/utils.rs')
-rw-r--r--src/utils.rs76
1 files changed, 39 insertions, 37 deletions
diff --git a/src/utils.rs b/src/utils.rs
index f99d31b36..327d89a24 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -1,46 +1,48 @@
1use std::{collections::BTreeSet, fmt::Write}; 1use std::{fmt::Write};
2use {SyntaxError, SyntaxNode, SyntaxNodeRef}; 2use {
3 SyntaxNode,
4 algo::walk::{WalkEvent, walk},
5};
3 6
4/// Parse a file and create a string representation of the resulting parse tree. 7/// Parse a file and create a string representation of the resulting parse tree.
5pub fn dump_tree(syntax: &SyntaxNode) -> String { 8pub fn dump_tree(syntax: &SyntaxNode) -> String {
6 let syntax = syntax.as_ref(); 9 let syntax = syntax.as_ref();
7 let mut errors: BTreeSet<_> = syntax.root.errors.iter().cloned().collect(); 10 let mut errors: Vec<_> = syntax.root.errors.iter().cloned().collect();
8 let mut result = String::new(); 11 errors.sort_by_key(|e| e.offset);
9 go(syntax, &mut result, 0, &mut errors); 12 let mut err_pos = 0;
10 return result; 13 let mut level = 0;
11 14 let mut buf = String::new();
12 fn go( 15 macro_rules! indent {
13 node: SyntaxNodeRef, 16 () => {
14 buff: &mut String, 17 for _ in 0..level {
15 level: usize, 18 buf.push_str(" ");
16 errors: &mut BTreeSet<SyntaxError>, 19 }
17 ) { 20 };
18 buff.push_str(&String::from(" ").repeat(level)); 21 }
19 writeln!(buff, "{:?}", node).unwrap();
20 let my_errors: Vec<_> = errors
21 .iter()
22 .filter(|e| e.offset == node.range().start())
23 .cloned()
24 .collect();
25 for err in my_errors {
26 errors.remove(&err);
27 buff.push_str(&String::from(" ").repeat(level));
28 writeln!(buff, "err: `{}`", err.message).unwrap();
29 }
30 22
31 for child in node.children() { 23 for event in walk(syntax) {
32 go(child, buff, level + 1, errors) 24 match event {
25 WalkEvent::Enter(node) => {
26 indent!();
27 writeln!(buf, "{:?}", node).unwrap();
28 if node.first_child().is_none() {
29 let off = node.range().end();
30 while err_pos < errors.len() && errors[err_pos].offset <= off {
31 indent!();
32 writeln!(buf, "err: `{}`", errors[err_pos].message).unwrap();
33 err_pos += 1;
34 }
35 }
36 level += 1;
37 },
38 WalkEvent::Exit(_) => level -= 1,
33 } 39 }
40 }
34 41
35 let my_errors: Vec<_> = errors 42 assert_eq!(level, 0);
36 .iter() 43 for err in errors[err_pos..].iter() {
37 .filter(|e| e.offset == node.range().end()) 44 writeln!(buf, "err: `{}`", err.message).unwrap();
38 .cloned()
39 .collect();
40 for err in my_errors {
41 errors.remove(&err);
42 buff.push_str(&String::from(" ").repeat(level));
43 writeln!(buff, "err: `{}`", err.message).unwrap();
44 }
45 } 45 }
46
47 return buf;
46} 48}