aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-07-30 00:23:01 +0100
committerAleksey Kladov <[email protected]>2018-07-30 00:23:07 +0100
commit4e79073e3872df718eb189dd5301ffc000f87d58 (patch)
treeee8b6fd71aeb6d3ed1f4c1c686e5753fdf72e62a
parentb87291a8a46025fa9b709cd9860483528308735f (diff)
Use raw pointers
-rw-r--r--src/yellow/mod.rs31
-rw-r--r--src/yellow/red.rs10
-rw-r--r--src/yellow/syntax.rs19
3 files changed, 15 insertions, 45 deletions
diff --git a/src/yellow/mod.rs b/src/yellow/mod.rs
index 9a6203cc1..4fd0d24d7 100644
--- a/src/yellow/mod.rs
+++ b/src/yellow/mod.rs
@@ -3,10 +3,6 @@ mod red;
3mod syntax; 3mod syntax;
4mod builder; 4mod builder;
5 5
6use std::{
7 sync::{Arc, Weak},
8 mem
9};
10pub(crate) use self::{ 6pub(crate) use self::{
11 green::{GreenNode, GreenNodeBuilder}, 7 green::{GreenNode, GreenNodeBuilder},
12 red::RedNode, 8 red::RedNode,
@@ -14,30 +10,3 @@ pub(crate) use self::{
14 builder::GreenBuilder, 10 builder::GreenBuilder,
15}; 11};
16pub use self::syntax::SyntaxNode; 12pub use self::syntax::SyntaxNode;
17
18// This could be just `*const T`, but we use `Weak` for additional checks
19#[derive(Debug)]
20pub(crate) struct Ptr<T>(Weak<T>);
21
22impl<T> Clone for Ptr<T> {
23 fn clone(&self) -> Self {
24 Ptr(self.0.clone())
25 }
26}
27
28impl<T> Ptr<T> {
29 fn clone(self_: &Ptr<T>) -> Ptr<T> {
30 Ptr(Weak::clone(&self_.0))
31 }
32
33 fn new(arc: &Arc<T>) -> Ptr<T> {
34 Ptr(Arc::downgrade(arc))
35 }
36
37 unsafe fn get(&self) -> &T {
38 let t = self.0.upgrade()
39 .expect("caller must guarantee that Ptr is not null");
40 let t: &T = &*t;
41 mem::transmute(t)
42 }
43}
diff --git a/src/yellow/red.rs b/src/yellow/red.rs
index e2dbceeae..3fdbfe0c5 100644
--- a/src/yellow/red.rs
+++ b/src/yellow/red.rs
@@ -1,7 +1,7 @@
1use std::sync::{Arc, RwLock}; 1use std::sync::{Arc, RwLock};
2use { 2use {
3 TextUnit, 3 TextUnit,
4 yellow::{Ptr, GreenNode}, 4 yellow::GreenNode,
5}; 5};
6 6
7#[derive(Debug)] 7#[derive(Debug)]
@@ -13,7 +13,7 @@ pub(crate) struct RedNode {
13 13
14#[derive(Debug)] 14#[derive(Debug)]
15struct ParentData { 15struct ParentData {
16 parent: Ptr<RedNode>, 16 parent: *const RedNode,
17 start_offset: TextUnit, 17 start_offset: TextUnit,
18 index_in_parent: usize, 18 index_in_parent: usize,
19} 19}
@@ -27,7 +27,7 @@ impl RedNode {
27 27
28 fn new_child( 28 fn new_child(
29 green: GreenNode, 29 green: GreenNode,
30 parent: Ptr<RedNode>, 30 parent: *const RedNode,
31 start_offset: TextUnit, 31 start_offset: TextUnit,
32 index_in_parent: usize, 32 index_in_parent: usize,
33 ) -> RedNode { 33 ) -> RedNode {
@@ -62,7 +62,7 @@ impl RedNode {
62 self.green.children().len() 62 self.green.children().len()
63 } 63 }
64 64
65 pub(crate) fn nth_child(&self, me: Ptr<RedNode>, idx: usize) -> Arc<RedNode> { 65 pub(crate) fn nth_child(&self, idx: usize) -> Arc<RedNode> {
66 match &self.children.read().unwrap()[idx] { 66 match &self.children.read().unwrap()[idx] {
67 Some(child) => return child.clone(), 67 Some(child) => return child.clone(),
68 None => (), 68 None => (),
@@ -72,7 +72,7 @@ impl RedNode {
72 let green_children = self.green.children(); 72 let green_children = self.green.children();
73 let start_offset = self.start_offset() 73 let start_offset = self.start_offset()
74 + green_children[..idx].iter().map(|x| x.text_len()).sum::<TextUnit>(); 74 + green_children[..idx].iter().map(|x| x.text_len()).sum::<TextUnit>();
75 let child = RedNode::new_child(green_children[idx].clone(), me, start_offset, idx); 75 let child = RedNode::new_child(green_children[idx].clone(), self, start_offset, idx);
76 children[idx] = Some(Arc::new(child)) 76 children[idx] = Some(Arc::new(child))
77 } 77 }
78 children[idx].as_ref().unwrap().clone() 78 children[idx].as_ref().unwrap().clone()
diff --git a/src/yellow/syntax.rs b/src/yellow/syntax.rs
index 53d8c82b9..fa51e8d13 100644
--- a/src/yellow/syntax.rs
+++ b/src/yellow/syntax.rs
@@ -1,18 +1,20 @@
1use std::{ 1use std::{
2 fmt, 2 fmt,
3 sync::Arc, 3 sync::Arc,
4 ptr
4}; 5};
5 6
6use { 7use {
7 TextRange, TextUnit, 8 TextRange, TextUnit,
8 SyntaxKind::{self, *}, 9 SyntaxKind::{self, *},
9 yellow::{Ptr, RedNode, GreenNode}, 10 yellow::{RedNode, GreenNode},
10}; 11};
11 12
12#[derive(Clone)] 13#[derive(Clone)]
13pub struct SyntaxNode { 14pub struct SyntaxNode {
14 pub(crate) root: SyntaxRoot, 15 pub(crate) root: SyntaxRoot,
15 red: Ptr<RedNode>, 16 // guaranteed to be alive bc SyntaxRoot holds a strong ref
17 red: ptr::NonNull<RedNode>,
16} 18}
17 19
18#[derive(Clone)] 20#[derive(Clone)]
@@ -29,10 +31,10 @@ pub(crate) struct SyntaxError {
29 31
30impl SyntaxNode { 32impl SyntaxNode {
31 pub(crate) fn new(root: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode { 33 pub(crate) fn new(root: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
32 let root = Arc::new(RedNode::new_root(root)); 34 let red = Arc::new(RedNode::new_root(root));
33 let red = Ptr::new(&root); 35 let red_weak: ptr::NonNull<RedNode> = (&*red).into();
34 let root = SyntaxRoot { red: root, errors: Arc::new(errors) }; 36 let root = SyntaxRoot { red, errors: Arc::new(errors) };
35 SyntaxNode { root, red } 37 SyntaxNode { root, red: red_weak }
36 } 38 }
37 39
38 pub fn kind(&self) -> SyntaxKind { 40 pub fn kind(&self) -> SyntaxKind {
@@ -58,15 +60,14 @@ impl SyntaxNode {
58 for i in 0..n_children { 60 for i in 0..n_children {
59 res.push(SyntaxNode { 61 res.push(SyntaxNode {
60 root: self.root.clone(), 62 root: self.root.clone(),
61 red: Ptr::new(&red.nth_child(Ptr::clone(&self.red), i)), 63 red: (&*red.nth_child(i)).into(),
62 }); 64 });
63 } 65 }
64 res 66 res
65 } 67 }
66 68
67 fn red(&self) -> &RedNode { 69 fn red(&self) -> &RedNode {
68 // Safe b/c root ptr keeps red alive 70 unsafe { self.red.as_ref() }
69 unsafe { self.red.get() }
70 } 71 }
71} 72}
72 73