aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/yellow.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_syntax/src/yellow.rs')
-rw-r--r--crates/ra_syntax/src/yellow.rs161
1 files changed, 161 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/yellow.rs b/crates/ra_syntax/src/yellow.rs
new file mode 100644
index 000000000..cacd89dc8
--- /dev/null
+++ b/crates/ra_syntax/src/yellow.rs
@@ -0,0 +1,161 @@
1mod builder;
2pub mod syntax_error;
3mod syntax_text;
4
5use self::syntax_text::SyntaxText;
6use crate::{SmolStr, SyntaxKind, TextRange};
7use rowan::Types;
8use std::{
9 fmt,
10 hash::{Hash, Hasher},
11};
12
13pub(crate) use self::builder::GreenBuilder;
14pub use self::syntax_error::{SyntaxError, SyntaxErrorKind, Location};
15pub use rowan::{TreeRoot, WalkEvent};
16
17#[derive(Debug, Clone, Copy)]
18pub enum RaTypes {}
19impl Types for RaTypes {
20 type Kind = SyntaxKind;
21 type RootData = Vec<SyntaxError>;
22}
23
24pub type OwnedRoot = ::rowan::OwnedRoot<RaTypes>;
25pub type RefRoot<'a> = ::rowan::RefRoot<'a, RaTypes>;
26
27pub type GreenNode = ::rowan::GreenNode<RaTypes>;
28
29#[derive(Clone, Copy)]
30pub struct SyntaxNode<R: TreeRoot<RaTypes> = OwnedRoot>(pub(crate) ::rowan::SyntaxNode<RaTypes, R>);
31pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>;
32
33impl<R1, R2> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2>
34where
35 R1: TreeRoot<RaTypes>,
36 R2: TreeRoot<RaTypes>,
37{
38 fn eq(&self, other: &SyntaxNode<R1>) -> bool {
39 self.0 == other.0
40 }
41}
42
43impl<R: TreeRoot<RaTypes>> Eq for SyntaxNode<R> {}
44impl<R: TreeRoot<RaTypes>> Hash for SyntaxNode<R> {
45 fn hash<H: Hasher>(&self, state: &mut H) {
46 self.0.hash(state)
47 }
48}
49
50impl SyntaxNode {
51 pub(crate) fn new(green: GreenNode, errors: Vec<SyntaxError>) -> SyntaxNode {
52 SyntaxNode(::rowan::SyntaxNode::new(green, errors))
53 }
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub enum Direction {
58 Next,
59 Prev,
60}
61
62impl<'a> SyntaxNodeRef<'a> {
63 pub fn leaf_text(self) -> Option<&'a SmolStr> {
64 self.0.leaf_text()
65 }
66 pub fn ancestors(self) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
67 crate::algo::generate(Some(self), |&node| node.parent())
68 }
69 pub fn descendants(self) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
70 self.preorder().filter_map(|event| match event {
71 WalkEvent::Enter(node) => Some(node),
72 WalkEvent::Leave(_) => None,
73 })
74 }
75 pub fn siblings(self, direction: Direction) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
76 crate::algo::generate(Some(self), move |&node| match direction {
77 Direction::Next => node.next_sibling(),
78 Direction::Prev => node.prev_sibling(),
79 })
80 }
81 pub fn preorder(self) -> impl Iterator<Item = WalkEvent<SyntaxNodeRef<'a>>> {
82 self.0.preorder().map(|event| match event {
83 WalkEvent::Enter(n) => WalkEvent::Enter(SyntaxNode(n)),
84 WalkEvent::Leave(n) => WalkEvent::Leave(SyntaxNode(n)),
85 })
86 }
87}
88
89impl<R: TreeRoot<RaTypes>> SyntaxNode<R> {
90 pub(crate) fn root_data(&self) -> &Vec<SyntaxError> {
91 self.0.root_data()
92 }
93 pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode {
94 self.0.replace_with(replacement)
95 }
96 pub fn borrowed<'a>(&'a self) -> SyntaxNode<RefRoot<'a>> {
97 SyntaxNode(self.0.borrowed())
98 }
99 pub fn owned(&self) -> SyntaxNode<OwnedRoot> {
100 SyntaxNode(self.0.owned())
101 }
102 pub fn kind(&self) -> SyntaxKind {
103 self.0.kind()
104 }
105 pub fn range(&self) -> TextRange {
106 self.0.range()
107 }
108 pub fn text(&self) -> SyntaxText {
109 SyntaxText::new(self.borrowed())
110 }
111 pub fn is_leaf(&self) -> bool {
112 self.0.is_leaf()
113 }
114 pub fn parent(&self) -> Option<SyntaxNode<R>> {
115 self.0.parent().map(SyntaxNode)
116 }
117 pub fn first_child(&self) -> Option<SyntaxNode<R>> {
118 self.0.first_child().map(SyntaxNode)
119 }
120 pub fn last_child(&self) -> Option<SyntaxNode<R>> {
121 self.0.last_child().map(SyntaxNode)
122 }
123 pub fn next_sibling(&self) -> Option<SyntaxNode<R>> {
124 self.0.next_sibling().map(SyntaxNode)
125 }
126 pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> {
127 self.0.prev_sibling().map(SyntaxNode)
128 }
129 pub fn children(&self) -> SyntaxNodeChildren<R> {
130 SyntaxNodeChildren(self.0.children())
131 }
132}
133
134impl<R: TreeRoot<RaTypes>> fmt::Debug for SyntaxNode<R> {
135 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
136 write!(fmt, "{:?}@{:?}", self.kind(), self.range())?;
137 if has_short_text(self.kind()) {
138 write!(fmt, " \"{}\"", self.text())?;
139 }
140 Ok(())
141 }
142}
143
144#[derive(Debug)]
145pub struct SyntaxNodeChildren<R: TreeRoot<RaTypes>>(::rowan::SyntaxNodeChildren<RaTypes, R>);
146
147impl<R: TreeRoot<RaTypes>> Iterator for SyntaxNodeChildren<R> {
148 type Item = SyntaxNode<R>;
149
150 fn next(&mut self) -> Option<SyntaxNode<R>> {
151 self.0.next().map(SyntaxNode)
152 }
153}
154
155fn has_short_text(kind: SyntaxKind) -> bool {
156 use crate::SyntaxKind::*;
157 match kind {
158 IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true,
159 _ => false,
160 }
161}