diff options
Diffstat (limited to 'crates/ra_syntax/src/yellow/mod.rs')
-rw-r--r-- | crates/ra_syntax/src/yellow/mod.rs | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs new file mode 100644 index 000000000..0596e702f --- /dev/null +++ b/crates/ra_syntax/src/yellow/mod.rs | |||
@@ -0,0 +1,100 @@ | |||
1 | mod builder; | ||
2 | mod green; | ||
3 | mod red; | ||
4 | mod syntax; | ||
5 | mod syntax_text; | ||
6 | |||
7 | use std::{ | ||
8 | sync::Arc, | ||
9 | ptr, | ||
10 | }; | ||
11 | pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren}; | ||
12 | pub(crate) use self::{ | ||
13 | builder::GreenBuilder, | ||
14 | green::GreenNode, | ||
15 | red::RedNode, | ||
16 | syntax_text::SyntaxText, | ||
17 | }; | ||
18 | |||
19 | #[derive(Debug)] | ||
20 | pub struct SyntaxRoot { | ||
21 | red: RedNode, | ||
22 | pub(crate) errors: Vec<SyntaxError>, | ||
23 | } | ||
24 | |||
25 | pub trait TreeRoot: Clone + Send + Sync { | ||
26 | fn borrowed(&self) -> RefRoot; | ||
27 | fn owned(&self) -> OwnedRoot; | ||
28 | |||
29 | #[doc(hidden)] | ||
30 | fn syntax_root(&self) -> &SyntaxRoot; | ||
31 | } | ||
32 | #[derive(Clone, Debug)] | ||
33 | pub struct OwnedRoot(Arc<SyntaxRoot>); | ||
34 | #[derive(Clone, Copy, Debug)] | ||
35 | pub struct RefRoot<'a>(&'a OwnedRoot); // TODO: shared_from_this instead of double indirection | ||
36 | |||
37 | impl<'a> RefRoot<'a> { | ||
38 | fn syntax_root(&self) -> &'a SyntaxRoot { | ||
39 | self.0.syntax_root() | ||
40 | } | ||
41 | } | ||
42 | |||
43 | impl TreeRoot for OwnedRoot { | ||
44 | fn borrowed(&self) -> RefRoot { | ||
45 | RefRoot(&self) | ||
46 | } | ||
47 | fn owned(&self) -> OwnedRoot { | ||
48 | self.clone() | ||
49 | } | ||
50 | |||
51 | fn syntax_root(&self) -> &SyntaxRoot { | ||
52 | &*self.0 | ||
53 | } | ||
54 | } | ||
55 | |||
56 | impl<'a> TreeRoot for RefRoot<'a> { | ||
57 | fn borrowed(&self) -> RefRoot { | ||
58 | *self | ||
59 | } | ||
60 | fn owned(&self) -> OwnedRoot { | ||
61 | self.0.clone() | ||
62 | } | ||
63 | fn syntax_root(&self) -> &SyntaxRoot { | ||
64 | self.0.syntax_root() | ||
65 | } | ||
66 | } | ||
67 | |||
68 | impl SyntaxRoot { | ||
69 | pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxRoot { | ||
70 | SyntaxRoot { | ||
71 | red: RedNode::new_root(green), | ||
72 | errors, | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | |||
77 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | ||
78 | pub(crate) struct RedPtr(ptr::NonNull<RedNode>); | ||
79 | |||
80 | unsafe impl Send for RedPtr {} | ||
81 | |||
82 | unsafe impl Sync for RedPtr {} | ||
83 | |||
84 | impl RedPtr { | ||
85 | fn new(red: &RedNode) -> RedPtr { | ||
86 | RedPtr(red.into()) | ||
87 | } | ||
88 | |||
89 | unsafe fn get<'a>(self, _root: &'a SyntaxRoot) -> &'a RedNode { | ||
90 | &*self.0.as_ptr() | ||
91 | } | ||
92 | } | ||
93 | |||
94 | #[test] | ||
95 | fn assert_send_sync() { | ||
96 | fn f<T: Send + Sync>() {} | ||
97 | f::<GreenNode>(); | ||
98 | f::<RedNode>(); | ||
99 | f::<SyntaxNode>(); | ||
100 | } | ||