diff options
author | Aleksey Kladov <[email protected]> | 2018-07-31 20:14:56 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-07-31 20:14:56 +0100 |
commit | 8105c14454f8c4f575f16b44ec616ffd045be57f (patch) | |
tree | d8d2aba889583afa2e6045f024656918b5f273db /src | |
parent | 5d8cef4c0eec3718d92560337f9a1d4fcf04d01f (diff) |
Improve debug_dump performance
Diffstat (limited to 'src')
-rw-r--r-- | src/algo/walk.rs | 4 | ||||
-rw-r--r-- | src/lib.rs | 2 | ||||
-rw-r--r-- | src/utils.rs | 76 |
3 files changed, 41 insertions, 41 deletions
diff --git a/src/algo/walk.rs b/src/algo/walk.rs index c6d050251..a50ec2a09 100644 --- a/src/algo/walk.rs +++ b/src/algo/walk.rs | |||
@@ -8,12 +8,12 @@ pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeR | |||
8 | } | 8 | } |
9 | 9 | ||
10 | #[derive(Debug, Copy, Clone)] | 10 | #[derive(Debug, Copy, Clone)] |
11 | enum WalkEvent<'a> { | 11 | pub enum WalkEvent<'a> { |
12 | Enter(SyntaxNodeRef<'a>), | 12 | Enter(SyntaxNodeRef<'a>), |
13 | Exit(SyntaxNodeRef<'a>), | 13 | Exit(SyntaxNodeRef<'a>), |
14 | } | 14 | } |
15 | 15 | ||
16 | fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> { | 16 | pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> { |
17 | let mut done = false; | 17 | let mut done = false; |
18 | ::itertools::unfold(WalkEvent::Enter(root), move |pos| { | 18 | ::itertools::unfold(WalkEvent::Enter(root), move |pos| { |
19 | if done { | 19 | if done { |
diff --git a/src/lib.rs b/src/lib.rs index 953c9b860..a72d9e3cb 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
@@ -41,8 +41,6 @@ pub use { | |||
41 | yellow::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot}, | 41 | yellow::{SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot}, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | pub(crate) use yellow::SyntaxError; | ||
45 | |||
46 | pub fn parse(text: String) -> SyntaxNode { | 44 | pub fn parse(text: String) -> SyntaxNode { |
47 | let tokens = tokenize(&text); | 45 | let tokens = tokenize(&text); |
48 | parser::parse::<yellow::GreenBuilder>(text, &tokens) | 46 | parser::parse::<yellow::GreenBuilder>(text, &tokens) |
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 @@ | |||
1 | use std::{collections::BTreeSet, fmt::Write}; | 1 | use std::{fmt::Write}; |
2 | use {SyntaxError, SyntaxNode, SyntaxNodeRef}; | 2 | use { |
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. |
5 | pub fn dump_tree(syntax: &SyntaxNode) -> String { | 8 | pub 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 | } |