diff options
-rw-r--r-- | src/lib.rs | 9 | ||||
-rw-r--r-- | src/yellow/builder.rs | 5 | ||||
-rw-r--r-- | src/yellow/mod.rs | 4 | ||||
-rw-r--r-- | src/yellow/syntax.rs | 45 |
4 files changed, 42 insertions, 21 deletions
diff --git a/src/lib.rs b/src/lib.rs index 4260e22e7..34c71fd2c 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
@@ -27,7 +27,7 @@ mod syntax_kinds; | |||
27 | pub use { | 27 | pub use { |
28 | text_unit::{TextRange, TextUnit}, | 28 | text_unit::{TextRange, TextUnit}, |
29 | syntax_kinds::SyntaxKind, | 29 | syntax_kinds::SyntaxKind, |
30 | yellow::{SyntaxNode}, | 30 | yellow::{SyntaxNode, SyntaxNodeRef}, |
31 | lexer::{tokenize, Token}, | 31 | lexer::{tokenize, Token}, |
32 | }; | 32 | }; |
33 | 33 | ||
@@ -48,16 +48,17 @@ pub mod utils { | |||
48 | collections::BTreeSet | 48 | collections::BTreeSet |
49 | }; | 49 | }; |
50 | 50 | ||
51 | use {SyntaxNode, SyntaxError}; | 51 | use {SyntaxNode, SyntaxNodeRef, SyntaxError}; |
52 | 52 | ||
53 | /// Parse a file and create a string representation of the resulting parse tree. | 53 | /// Parse a file and create a string representation of the resulting parse tree. |
54 | pub fn dump_tree_green(syntax: &SyntaxNode) -> String { | 54 | pub fn dump_tree_green(syntax: &SyntaxNode) -> String { |
55 | let syntax = syntax.borrow(); | ||
55 | let mut errors: BTreeSet<_> = syntax.root.errors.iter().cloned().collect(); | 56 | let mut errors: BTreeSet<_> = syntax.root.errors.iter().cloned().collect(); |
56 | let mut result = String::new(); | 57 | let mut result = String::new(); |
57 | go(syntax, &mut result, 0, &mut errors); | 58 | go(syntax, &mut result, 0, &mut errors); |
58 | return result; | 59 | return result; |
59 | 60 | ||
60 | fn go(node: &SyntaxNode, buff: &mut String, level: usize, errors: &mut BTreeSet<SyntaxError>) { | 61 | fn go(node: SyntaxNodeRef, buff: &mut String, level: usize, errors: &mut BTreeSet<SyntaxError>) { |
61 | buff.push_str(&String::from(" ").repeat(level)); | 62 | buff.push_str(&String::from(" ").repeat(level)); |
62 | write!(buff, "{:?}\n", node).unwrap(); | 63 | write!(buff, "{:?}\n", node).unwrap(); |
63 | let my_errors: Vec<_> = errors.iter().filter(|e| e.offset == node.range().start()) | 64 | let my_errors: Vec<_> = errors.iter().filter(|e| e.offset == node.range().start()) |
@@ -68,7 +69,7 @@ pub mod utils { | |||
68 | write!(buff, "err: `{}`\n", err.message).unwrap(); | 69 | write!(buff, "err: `{}`\n", err.message).unwrap(); |
69 | } | 70 | } |
70 | 71 | ||
71 | for child in node.children().iter() { | 72 | for child in node.children() { |
72 | go(child, buff, level + 1, errors) | 73 | go(child, buff, level + 1, errors) |
73 | } | 74 | } |
74 | 75 | ||
diff --git a/src/yellow/builder.rs b/src/yellow/builder.rs index 73b4b5ff9..65cc97ff9 100644 --- a/src/yellow/builder.rs +++ b/src/yellow/builder.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use { | 1 | use { |
2 | SyntaxKind, TextRange, TextUnit, | 2 | SyntaxKind, TextRange, TextUnit, |
3 | yellow::{SyntaxNode, GreenNode, GreenNodeBuilder, SyntaxError}, | 3 | yellow::{SyntaxNode, SyntaxRoot, GreenNode, GreenNodeBuilder, SyntaxError}, |
4 | parser::Sink | 4 | parser::Sink |
5 | }; | 5 | }; |
6 | 6 | ||
@@ -57,7 +57,8 @@ impl Sink for GreenBuilder { | |||
57 | } | 57 | } |
58 | 58 | ||
59 | fn finish(self) -> SyntaxNode { | 59 | fn finish(self) -> SyntaxNode { |
60 | SyntaxNode::new(self.root.unwrap(), self.errors) | 60 | let root = SyntaxRoot::new(self.root.unwrap(), self.errors); |
61 | SyntaxNode::new_owned(root) | ||
61 | } | 62 | } |
62 | } | 63 | } |
63 | 64 | ||
diff --git a/src/yellow/mod.rs b/src/yellow/mod.rs index 4fd0d24d7..89eefc98b 100644 --- a/src/yellow/mod.rs +++ b/src/yellow/mod.rs | |||
@@ -6,7 +6,7 @@ mod builder; | |||
6 | pub(crate) use self::{ | 6 | pub(crate) use self::{ |
7 | green::{GreenNode, GreenNodeBuilder}, | 7 | green::{GreenNode, GreenNodeBuilder}, |
8 | red::RedNode, | 8 | red::RedNode, |
9 | syntax::SyntaxError, | 9 | syntax::{SyntaxError, SyntaxRoot}, |
10 | builder::GreenBuilder, | 10 | builder::GreenBuilder, |
11 | }; | 11 | }; |
12 | pub use self::syntax::SyntaxNode; | 12 | pub use self::syntax::{SyntaxNode, SyntaxNodeRef}; |
diff --git a/src/yellow/syntax.rs b/src/yellow/syntax.rs index cc6122689..0fa24fb47 100644 --- a/src/yellow/syntax.rs +++ b/src/yellow/syntax.rs | |||
@@ -10,17 +10,28 @@ use { | |||
10 | yellow::{RedNode, GreenNode}, | 10 | yellow::{RedNode, GreenNode}, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | #[derive(Clone)] | 13 | #[derive(Clone, Copy)] |
14 | pub struct SyntaxNode { | 14 | pub struct SyntaxNode<ROOT: ::std::ops::Deref<Target=SyntaxRoot> + Clone = Arc<SyntaxRoot>> { |
15 | pub(crate) root: SyntaxRoot, | 15 | pub(crate) root: ROOT, |
16 | // guaranteed to be alive bc SyntaxRoot holds a strong ref | 16 | // guaranteed to be alive bc SyntaxRoot holds a strong ref |
17 | red: ptr::NonNull<RedNode>, | 17 | red: ptr::NonNull<RedNode>, |
18 | } | 18 | } |
19 | 19 | ||
20 | #[derive(Clone)] | 20 | pub type SyntaxNodeRef<'a> = SyntaxNode<&'a SyntaxRoot>; |
21 | |||
22 | #[derive(Debug)] | ||
21 | pub struct SyntaxRoot { | 23 | pub struct SyntaxRoot { |
22 | red: Arc<RedNode>, | 24 | red: RedNode, |
23 | pub(crate) errors: Arc<Vec<SyntaxError>>, | 25 | pub(crate) errors: Vec<SyntaxError>, |
26 | } | ||
27 | |||
28 | impl SyntaxRoot { | ||
29 | pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxRoot { | ||
30 | SyntaxRoot { | ||
31 | red: RedNode::new_root(green), | ||
32 | errors, | ||
33 | } | ||
34 | } | ||
24 | } | 35 | } |
25 | 36 | ||
26 | #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] | 37 | #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] |
@@ -29,13 +40,21 @@ pub(crate) struct SyntaxError { | |||
29 | pub(crate) offset: TextUnit, | 40 | pub(crate) offset: TextUnit, |
30 | } | 41 | } |
31 | 42 | ||
32 | impl SyntaxNode { | 43 | impl SyntaxNode<Arc<SyntaxRoot>> { |
33 | pub(crate) fn new(root: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode { | 44 | pub(crate) fn new_owned(root: SyntaxRoot) -> Self { |
34 | let red = Arc::new(RedNode::new_root(root)); | 45 | let root = Arc::new(root); |
35 | let red_weak: ptr::NonNull<RedNode> = (&*red).into(); | 46 | let red_weak = ptr::NonNull::from(&root.red); |
36 | let root = SyntaxRoot { red, errors: Arc::new(errors) }; | ||
37 | SyntaxNode { root, red: red_weak } | 47 | SyntaxNode { root, red: red_weak } |
38 | } | 48 | } |
49 | } | ||
50 | |||
51 | impl<ROOT: ::std::ops::Deref<Target=SyntaxRoot> + Clone> SyntaxNode<ROOT> { | ||
52 | pub fn borrow<'a>(&'a self) -> SyntaxNode<&'a SyntaxRoot> { | ||
53 | SyntaxNode { | ||
54 | root: &*self.root, | ||
55 | red: ptr::NonNull::clone(&self.red), | ||
56 | } | ||
57 | } | ||
39 | 58 | ||
40 | pub fn kind(&self) -> SyntaxKind { | 59 | pub fn kind(&self) -> SyntaxKind { |
41 | self.red().green().kind() | 60 | self.red().green().kind() |
@@ -53,7 +72,7 @@ impl SyntaxNode { | |||
53 | self.red().green().text() | 72 | self.red().green().text() |
54 | } | 73 | } |
55 | 74 | ||
56 | pub fn children(&self) -> Vec<SyntaxNode> { | 75 | pub fn children(&self) -> Vec<SyntaxNode<ROOT>> { |
57 | let red = self.red(); | 76 | let red = self.red(); |
58 | let n_children = red.n_children(); | 77 | let n_children = red.n_children(); |
59 | let mut res = Vec::with_capacity(n_children); | 78 | let mut res = Vec::with_capacity(n_children); |
@@ -71,7 +90,7 @@ impl SyntaxNode { | |||
71 | } | 90 | } |
72 | } | 91 | } |
73 | 92 | ||
74 | impl fmt::Debug for SyntaxNode { | 93 | impl<ROOT: ::std::ops::Deref<Target=SyntaxRoot> + Clone> fmt::Debug for SyntaxNode<ROOT> { |
75 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { | 94 | fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { |
76 | write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; | 95 | write!(fmt, "{:?}@{:?}", self.kind(), self.range())?; |
77 | if has_short_text(self.kind()) { | 96 | if has_short_text(self.kind()) { |