diff options
author | Aleksey Kladov <[email protected]> | 2018-01-12 17:32:37 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2018-01-12 17:32:37 +0000 |
commit | ca0c5ea38b623422e1a25388817e224c2c4f4ae2 (patch) | |
tree | f4b3c05e35020ff6dcd3cef7fbf890bbce03c9e5 /src/parser/event_parser | |
parent | 15ae9026cf270d898cad16678032a5460e77404c (diff) |
Support tree rebalancing
Diffstat (limited to 'src/parser/event_parser')
-rw-r--r-- | src/parser/event_parser/grammar/items.rs | 11 | ||||
-rw-r--r-- | src/parser/event_parser/mod.rs | 5 | ||||
-rw-r--r-- | src/parser/event_parser/parser.rs | 20 |
3 files changed, 32 insertions, 4 deletions
diff --git a/src/parser/event_parser/grammar/items.rs b/src/parser/event_parser/grammar/items.rs index 522986ed0..725f04d1e 100644 --- a/src/parser/event_parser/grammar/items.rs +++ b/src/parser/event_parser/grammar/items.rs | |||
@@ -32,6 +32,7 @@ fn mod_contents_item(p: &mut Parser) { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | fn item(p: &mut Parser) -> bool { | 34 | fn item(p: &mut Parser) -> bool { |
35 | let attrs_start = p.mark(); | ||
35 | attributes::outer_attributes(p); | 36 | attributes::outer_attributes(p); |
36 | visibility(p); | 37 | visibility(p); |
37 | // node_if(p, USE_KW, USE_ITEM, use_item) | 38 | // node_if(p, USE_KW, USE_ITEM, use_item) |
@@ -41,11 +42,17 @@ fn item(p: &mut Parser) -> bool { | |||
41 | // || unsafe trait, impl | 42 | // || unsafe trait, impl |
42 | // || node_if(p, FN_KW, FN_ITEM, fn_item) | 43 | // || node_if(p, FN_KW, FN_ITEM, fn_item) |
43 | // || node_if(p, TYPE_KW, TYPE_ITEM, type_item) | 44 | // || node_if(p, TYPE_KW, TYPE_ITEM, type_item) |
44 | node_if(p, [EXTERN_KW, CRATE_KW], EXTERN_CRATE_ITEM, extern_crate_item) | 45 | let item_start = p.mark(); |
46 | let item_parsed = node_if(p, [EXTERN_KW, CRATE_KW], EXTERN_CRATE_ITEM, extern_crate_item) | ||
45 | || node_if(p, MOD_KW, MOD_ITEM, mod_item) | 47 | || node_if(p, MOD_KW, MOD_ITEM, mod_item) |
46 | || node_if(p, USE_KW, USE_ITEM, use_item) | 48 | || node_if(p, USE_KW, USE_ITEM, use_item) |
47 | || node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item) | 49 | || node_if(p, STRUCT_KW, STRUCT_ITEM, struct_item) |
48 | || node_if(p, FN_KW, FN_ITEM, fn_item) | 50 | || node_if(p, FN_KW, FN_ITEM, fn_item); |
51 | |||
52 | if item_parsed && attrs_start != item_start { | ||
53 | p.forward_parent(attrs_start, item_start); | ||
54 | } | ||
55 | item_parsed | ||
49 | } | 56 | } |
50 | 57 | ||
51 | fn struct_item(p: &mut Parser) { | 58 | fn struct_item(p: &mut Parser) { |
diff --git a/src/parser/event_parser/mod.rs b/src/parser/event_parser/mod.rs index 87b317c84..c89a3ebe7 100644 --- a/src/parser/event_parser/mod.rs +++ b/src/parser/event_parser/mod.rs | |||
@@ -5,7 +5,10 @@ mod parser; | |||
5 | 5 | ||
6 | #[derive(Debug)] | 6 | #[derive(Debug)] |
7 | pub(crate) enum Event { | 7 | pub(crate) enum Event { |
8 | Start { kind: SyntaxKind }, | 8 | Start { |
9 | kind: SyntaxKind, | ||
10 | forward_parent: Option<u32>, | ||
11 | }, | ||
9 | Finish, | 12 | Finish, |
10 | Token { | 13 | Token { |
11 | kind: SyntaxKind, | 14 | kind: SyntaxKind, |
diff --git a/src/parser/event_parser/parser.rs b/src/parser/event_parser/parser.rs index 8bc382b12..14c0efe2d 100644 --- a/src/parser/event_parser/parser.rs +++ b/src/parser/event_parser/parser.rs | |||
@@ -22,6 +22,9 @@ pub(crate) struct Parser<'t> { | |||
22 | #[derive(Debug, Clone, Copy,PartialEq, Eq)] | 22 | #[derive(Debug, Clone, Copy,PartialEq, Eq)] |
23 | pub(crate) struct Pos(u32); | 23 | pub(crate) struct Pos(u32); |
24 | 24 | ||
25 | #[derive(Debug, Clone, Copy,PartialEq, Eq)] | ||
26 | pub(crate) struct Mark(u32); | ||
27 | |||
25 | impl<'t> Parser<'t> { | 28 | impl<'t> Parser<'t> { |
26 | pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> Parser<'t> { | 29 | pub(crate) fn new(text: &'t str, raw_tokens: &'t [Token]) -> Parser<'t> { |
27 | let mut tokens = Vec::new(); | 30 | let mut tokens = Vec::new(); |
@@ -47,6 +50,21 @@ impl<'t> Parser<'t> { | |||
47 | } | 50 | } |
48 | } | 51 | } |
49 | 52 | ||
53 | pub(crate) fn mark(&self) -> Mark { | ||
54 | Mark(self.events.len() as u32) | ||
55 | } | ||
56 | |||
57 | pub(crate) fn forward_parent(&mut self, child: Mark, parent: Mark) { | ||
58 | assert!(child.0 < parent.0); | ||
59 | let diff = parent.0 - child.0; | ||
60 | match self.events[child.0 as usize] { | ||
61 | Event::Start { ref mut forward_parent, .. } => { | ||
62 | *forward_parent = Some(diff); | ||
63 | } | ||
64 | _ => unreachable!() | ||
65 | } | ||
66 | } | ||
67 | |||
50 | pub(crate) fn pos(&self) -> Pos { | 68 | pub(crate) fn pos(&self) -> Pos { |
51 | Pos(self.pos as u32) | 69 | Pos(self.pos as u32) |
52 | } | 70 | } |
@@ -71,7 +89,7 @@ impl<'t> Parser<'t> { | |||
71 | } | 89 | } |
72 | 90 | ||
73 | pub(crate) fn start(&mut self, kind: SyntaxKind) { | 91 | pub(crate) fn start(&mut self, kind: SyntaxKind) { |
74 | self.event(Event::Start { kind }); | 92 | self.event(Event::Start { kind, forward_parent: None }); |
75 | } | 93 | } |
76 | 94 | ||
77 | pub(crate) fn finish(&mut self) { | 95 | pub(crate) fn finish(&mut self) { |