aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/yellow/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/yellow/mod.rs')
-rw-r--r--crates/ra_syntax/src/yellow/mod.rs174
1 files changed, 108 insertions, 66 deletions
diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs
index 0596e702f..c621b1d6a 100644
--- a/crates/ra_syntax/src/yellow/mod.rs
+++ b/crates/ra_syntax/src/yellow/mod.rs
@@ -1,100 +1,142 @@
1mod builder; 1mod builder;
2mod green;
3mod red;
4mod syntax;
5mod syntax_text; 2mod syntax_text;
6 3
7use std::{ 4use std::{
8 sync::Arc, 5 fmt,
9 ptr, 6 hash::{Hash, Hasher},
10};
11pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren};
12pub(crate) use self::{
13 builder::GreenBuilder,
14 green::GreenNode,
15 red::RedNode,
16 syntax_text::SyntaxText,
17}; 7};
8use rowan::Types;
9use {SyntaxKind, TextUnit, TextRange, SmolStr};
10use self::syntax_text::SyntaxText;
18 11
19#[derive(Debug)] 12pub use rowan::{TreeRoot};
20pub struct SyntaxRoot { 13pub(crate) use self::builder::GreenBuilder;
21 red: RedNode, 14
22 pub(crate) errors: Vec<SyntaxError>, 15#[derive(Debug, Clone, Copy)]
16pub enum RaTypes {}
17impl Types for RaTypes {
18 type Kind = SyntaxKind;
19 type RootData = Vec<SyntaxError>;
23} 20}
24 21
25pub trait TreeRoot: Clone + Send + Sync { 22pub type OwnedRoot = ::rowan::OwnedRoot<RaTypes>;
26 fn borrowed(&self) -> RefRoot; 23pub type RefRoot<'a> = ::rowan::RefRoot<'a, RaTypes>;
27 fn owned(&self) -> OwnedRoot; 24
25pub type GreenNode = ::rowan::GreenNode<RaTypes>;
28 26
29 #[doc(hidden)] 27#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
30 fn syntax_root(&self) -> &SyntaxRoot; 28pub struct SyntaxError {
29 pub msg: String,
30 pub offset: TextUnit,
31} 31}
32#[derive(Clone, Debug)]
33pub struct OwnedRoot(Arc<SyntaxRoot>);
34#[derive(Clone, Copy, Debug)]
35pub struct RefRoot<'a>(&'a OwnedRoot); // TODO: shared_from_this instead of double indirection
36 32
37impl<'a> RefRoot<'a> { 33#[derive(Clone, Copy)]
38 fn syntax_root(&self) -> &'a SyntaxRoot { 34pub struct SyntaxNode<R: TreeRoot<RaTypes> = OwnedRoot>(
39 self.0.syntax_root() 35 ::rowan::SyntaxNode<RaTypes, R>,
36);
37pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>;
38
39impl<R1, R2> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2>
40where
41 R1: TreeRoot<RaTypes>,
42 R2: TreeRoot<RaTypes>,
43{
44 fn eq(&self, other: &SyntaxNode<R1>) -> bool {
45 self.0 == other.0
40 } 46 }
41} 47}
42 48
43impl TreeRoot for OwnedRoot { 49impl<R: TreeRoot<RaTypes>> Eq for SyntaxNode<R> {}
44 fn borrowed(&self) -> RefRoot { 50impl<R: TreeRoot<RaTypes>> Hash for SyntaxNode<R> {
45 RefRoot(&self) 51 fn hash<H: Hasher>(&self, state: &mut H) {
46 } 52 self.0.hash(state)
47 fn owned(&self) -> OwnedRoot {
48 self.clone()
49 } 53 }
54}
50 55
51 fn syntax_root(&self) -> &SyntaxRoot { 56impl SyntaxNode<OwnedRoot> {
52 &*self.0 57 pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
58 SyntaxNode(::rowan::SyntaxNode::new(green, errors))
59 }
60}
61impl<'a> SyntaxNode<RefRoot<'a>> {
62 pub fn leaf_text(self) -> Option<&'a SmolStr> {
63 self.0.leaf_text()
53 } 64 }
54} 65}
55 66
56impl<'a> TreeRoot for RefRoot<'a> { 67impl<R: TreeRoot<RaTypes>> SyntaxNode<R> {
57 fn borrowed(&self) -> RefRoot { 68 pub(crate) fn root_data(&self) -> &Vec<SyntaxError> {
58 *self 69 self.0.root_data()
70 }
71 pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
72 self.0.replace_with(replacement)
73 }
74 pub fn borrowed<'a>(&'a self) -> SyntaxNode<RefRoot<'a>> {
75 SyntaxNode(self.0.borrowed())
76 }
77 pub fn owned(&self) -> SyntaxNode<OwnedRoot> {
78 SyntaxNode(self.0.owned())
79 }
80 pub fn kind(&self) -> SyntaxKind {
81 self.0.kind()
59 } 82 }
60 fn owned(&self) -> OwnedRoot { 83 pub fn range(&self) -> TextRange {
61 self.0.clone() 84 self.0.range()
62 } 85 }
63 fn syntax_root(&self) -> &SyntaxRoot { 86 pub fn text(&self) -> SyntaxText {
64 self.0.syntax_root() 87 SyntaxText::new(self.borrowed())
88 }
89 pub fn is_leaf(&self) -> bool {
90 self.0.is_leaf()
91 }
92 pub fn parent(&self) -> Option<SyntaxNode<R>> {
93 self.0.parent().map(SyntaxNode)
94 }
95 pub fn first_child(&self) -> Option<SyntaxNode<R>> {
96 self.0.first_child().map(SyntaxNode)
97 }
98 pub fn last_child(&self) -> Option<SyntaxNode<R>> {
99 self.0.last_child().map(SyntaxNode)
100 }
101 pub fn next_sibling(&self) -> Option<SyntaxNode<R>> {
102 self.0.next_sibling().map(SyntaxNode)
103 }
104 pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> {
105 self.0.prev_sibling().map(SyntaxNode)
106 }
107 pub fn children(&self) -> SyntaxNodeChildren<R> {
108 SyntaxNodeChildren(self.0.children())
65 } 109 }
66} 110}
67 111
68impl SyntaxRoot { 112impl<R: TreeRoot<RaTypes>> fmt::Debug for SyntaxNode<R> {
69 pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxRoot { 113 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
70 SyntaxRoot { 114 write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
71 red: RedNode::new_root(green), 115 if has_short_text(self.kind()) {
72 errors, 116 write!(fmt, " \"{}\"", self.text())?;
73 } 117 }
118 Ok(())
74 } 119 }
75} 120}
76 121
77#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 122#[derive(Debug)]
78pub(crate) struct RedPtr(ptr::NonNull<RedNode>); 123pub struct SyntaxNodeChildren<R: TreeRoot<RaTypes>>(
79 124 ::rowan::SyntaxNodeChildren<RaTypes, R>
80unsafe impl Send for RedPtr {} 125);
81
82unsafe impl Sync for RedPtr {}
83 126
84impl RedPtr { 127impl<R: TreeRoot<RaTypes>> Iterator for SyntaxNodeChildren<R> {
85 fn new(red: &RedNode) -> RedPtr { 128 type Item = SyntaxNode<R>;
86 RedPtr(red.into())
87 }
88 129
89 unsafe fn get<'a>(self, _root: &'a SyntaxRoot) -> &'a RedNode { 130 fn next(&mut self) -> Option<SyntaxNode<R>> {
90 &*self.0.as_ptr() 131 self.0.next().map(SyntaxNode)
91 } 132 }
92} 133}
93 134
94#[test] 135
95fn assert_send_sync() { 136fn has_short_text(kind: SyntaxKind) -> bool {
96 fn f<T: Send + Sync>() {} 137 use SyntaxKind::*;
97 f::<GreenNode>(); 138 match kind {
98 f::<RedNode>(); 139 IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true,
99 f::<SyntaxNode>(); 140 _ => false,
141 }
100} 142}