aboutsummaryrefslogtreecommitdiff
path: root/src/yellow
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-07-30 01:21:17 +0100
committerAleksey Kladov <[email protected]>2018-07-30 01:21:17 +0100
commitae849cf134f3ff21261e175d95ba994e86ffe81a (patch)
treebe123a10589615f38518e294db56e8821c972e09 /src/yellow
parent83acbc06bd01cd7045566170148e2150f568f77c (diff)
Owned&Borrowed nodes
HOLLY COW, UNLIKE C++, WE CAN BE GENERIC WRT OWNERSHIP/BORROWING, SO WE CAN BOTH MAKE SYNTAX NODES OWNED (WHICH IS CONVENIENT) AND BORROWED (WHICH IS CONVENIENT FOR LOCAL PROCESSING, BC YOU DON'T NEED TO BUMP REFCOUNTS).
Diffstat (limited to 'src/yellow')
-rw-r--r--src/yellow/builder.rs5
-rw-r--r--src/yellow/mod.rs4
-rw-r--r--src/yellow/syntax.rs45
3 files changed, 37 insertions, 17 deletions
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()) {