aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs9
-rw-r--r--src/yellow/builder.rs5
-rw-r--r--src/yellow/mod.rs4
-rw-r--r--src/yellow/syntax.rs45
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;
27pub use { 27pub 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 @@
1use { 1use {
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;
6pub(crate) use self::{ 6pub(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};
12pub use self::syntax::SyntaxNode; 12pub 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)]
14pub struct SyntaxNode { 14pub 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)] 20pub type SyntaxNodeRef<'a> = SyntaxNode<&'a SyntaxRoot>;
21
22#[derive(Debug)]
21pub struct SyntaxRoot { 23pub struct SyntaxRoot {
22 red: Arc<RedNode>, 24 red: RedNode,
23 pub(crate) errors: Arc<Vec<SyntaxError>>, 25 pub(crate) errors: Vec<SyntaxError>,
26}
27
28impl 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
32impl SyntaxNode { 43impl 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
51impl<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
74impl fmt::Debug for SyntaxNode { 93impl<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()) {