Skip to content

Commit 7a86fe3

Browse files
bors[bot]matklad
andauthored
Merge #81
81: Store relative offsets in green nodes r=matklad a=matklad bors r+ Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 5cf7c24 + 52af0db commit 7a86fe3

File tree

7 files changed

+167
-279
lines changed

7 files changed

+167
-279
lines changed

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
[package]
22
name = "rowan"
3-
version = "0.10.0"
3+
version = "0.10.1"
44
authors = ["Aleksey Kladov <[email protected]>"]
55
repository = "https://github.com/rust-analyzer/rowan"
66
license = "MIT OR Apache-2.0"
77
description = "Library for generic lossless syntax trees"
88
edition = "2018"
99

1010
[dependencies]
11-
erasable = "1.2.1"
1211
rustc-hash = "1.0.1"
13-
serde = { version = "1.0.89", optional = true, default-features = false }
14-
slice-dst = "1.4.1"
1512
smol_str = "0.1.10"
16-
text-size = "1.0.0"
13+
text-size = "1.1.0"
14+
triomphe = "0.1.1"
15+
16+
serde = { version = "1.0.89", optional = true, default-features = false }
1717

1818
[dev-dependencies]
1919
m_lexer = "0.0.4"

src/api.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ impl<L: Language> SyntaxNode<L> {
149149
pub fn new_root(green: GreenNode) -> SyntaxNode<L> {
150150
SyntaxNode::from(cursor::SyntaxNode::new_root(green))
151151
}
152+
/// Returns a green tree, equal to the green tree this node
153+
/// belongs two, except with this node substitute. The complexity
154+
/// of operation is proportional to the depth of the tree
152155
pub fn replace_with(&self, replacement: GreenNode) -> GreenNode {
153156
self.raw.replace_with(replacement)
154157
}
@@ -217,10 +220,12 @@ impl<L: Language> SyntaxNode<L> {
217220
self.raw.prev_sibling_or_token().map(NodeOrToken::from)
218221
}
219222

223+
/// Return the leftmost token in the subtree of this node.
220224
pub fn first_token(&self) -> Option<SyntaxToken<L>> {
221225
self.raw.first_token().map(SyntaxToken::from)
222226
}
223227

228+
/// Return the rightmost token in the subtree of this node.
224229
pub fn last_token(&self) -> Option<SyntaxToken<L>> {
225230
self.raw.last_token().map(SyntaxToken::from)
226231
}
@@ -244,24 +249,41 @@ impl<L: Language> SyntaxNode<L> {
244249
self.raw.descendants_with_tokens().map(NodeOrToken::from)
245250
}
246251

252+
/// Traverse the subtree rooted at the current node (including the current
253+
/// node) in preorder, excluding tokens.
247254
pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<SyntaxNode<L>>> {
248255
self.raw.preorder().map(|event| event.map(SyntaxNode::from))
249256
}
250257

258+
/// Traverse the subtree rooted at the current node (including the current
259+
/// node) in preorder, including tokens.
251260
pub fn preorder_with_tokens(&self) -> impl Iterator<Item = WalkEvent<SyntaxElement<L>>> {
252261
self.raw.preorder_with_tokens().map(|event| event.map(NodeOrToken::from))
253262
}
254263

264+
/// Find a token in the subtree corresponding to this node, which covers the offset.
265+
/// Precondition: offset must be withing node's range.
255266
pub fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken<L>> {
256267
self.raw.token_at_offset(offset).map(SyntaxToken::from)
257268
}
258269

270+
/// Return the deepest node or token in the current subtree that fully
271+
/// contains the range. If the range is empty and is contained in two leaf
272+
/// nodes, either one can be returned. Precondition: range must be contained
273+
/// withing the current node
259274
pub fn covering_element(&self, range: TextRange) -> SyntaxElement<L> {
260275
NodeOrToken::from(self.raw.covering_element(range))
261276
}
277+
278+
pub fn child_or_token_at_range(&self, range: TextRange) -> Option<SyntaxElement<L>> {
279+
self.raw.child_or_token_at_range(range).map(SyntaxElement::from)
280+
}
262281
}
263282

264283
impl<L: Language> SyntaxToken<L> {
284+
/// Returns a green tree, equal to the green tree this token
285+
/// belongs two, except with this token substitute. The complexity
286+
/// of operation is proportional to the depth of the tree
265287
pub fn replace_with(&self, new_token: GreenToken) -> GreenNode {
266288
self.raw.replace_with(new_token)
267289
}
@@ -305,10 +327,12 @@ impl<L: Language> SyntaxToken<L> {
305327
self.raw.siblings_with_tokens(direction).map(SyntaxElement::from)
306328
}
307329

330+
/// Next token in the tree (i.e, not necessary a sibling).
308331
pub fn next_token(&self) -> Option<SyntaxToken<L>> {
309332
self.raw.next_token().map(SyntaxToken::from)
310333
}
311334

335+
/// Previous token in the tree (i.e, not necessary a sibling).
312336
pub fn prev_token(&self) -> Option<SyntaxToken<L>> {
313337
self.raw.prev_token().map(SyntaxToken::from)
314338
}

src/cursor.rs

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -209,23 +209,12 @@ impl SyntaxNode {
209209
SyntaxNode::new(data)
210210
}
211211

212-
/// Returns a green tree, equal to the green tree this node
213-
/// belongs two, except with this node substitute. The complexity
214-
/// of operation is proportional to the depth of the tree
215212
pub fn replace_with(&self, replacement: GreenNode) -> GreenNode {
216213
assert_eq!(self.kind(), replacement.kind());
217214
match self.0.kind.as_child() {
218215
None => replacement,
219216
Some((parent, me, _offset)) => {
220-
let mut replacement = Some(replacement);
221-
let children = parent.green().children().enumerate().map(|(i, child)| {
222-
if i as u32 == me {
223-
replacement.take().unwrap().into()
224-
} else {
225-
child.cloned()
226-
}
227-
});
228-
let new_parent = GreenNode::new(parent.kind(), children);
217+
let new_parent = parent.green().replace_child(me as usize, replacement.into());
229218
parent.replace_with(new_parent)
230219
}
231220
}
@@ -342,13 +331,11 @@ impl SyntaxNode {
342331
Some(SyntaxElement::new(element, parent.clone(), index as u32, offset))
343332
}
344333

345-
/// Return the leftmost token in the subtree of this node
346334
#[inline]
347335
pub fn first_token(&self) -> Option<SyntaxToken> {
348336
self.first_child_or_token()?.first_token()
349337
}
350338

351-
/// Return the rightmost token in the subtree of this node
352339
#[inline]
353340
pub fn last_token(&self) -> Option<SyntaxToken> {
354341
self.last_child_or_token()?.last_token()
@@ -386,8 +373,6 @@ impl SyntaxNode {
386373
})
387374
}
388375

389-
/// Traverse the subtree rooted at the current node (including the current
390-
/// node) in preorder, excluding tokens.
391376
#[inline]
392377
pub fn preorder(&self) -> impl Iterator<Item = WalkEvent<SyntaxNode>> {
393378
let this = self.clone();
@@ -411,8 +396,6 @@ impl SyntaxNode {
411396
})
412397
}
413398

414-
/// Traverse the subtree rooted at the current node (including the current
415-
/// node) in preorder, including tokens.
416399
#[inline]
417400
pub fn preorder_with_tokens<'a>(&'a self) -> impl Iterator<Item = WalkEvent<SyntaxElement>> {
418401
let start: SyntaxElement = self.clone().into();
@@ -439,8 +422,6 @@ impl SyntaxNode {
439422
})
440423
}
441424

442-
/// Find a token in the subtree corresponding to this node, which covers the offset.
443-
/// Precondition: offset must be withing node's range.
444425
pub fn token_at_offset(&self, offset: TextSize) -> TokenAtOffset<SyntaxToken> {
445426
// TODO: this could be faster if we first drill-down to node, and only
446427
// then switch to token search. We should also replace explicit
@@ -478,10 +459,6 @@ impl SyntaxNode {
478459
}
479460
}
480461

481-
/// Return the deepest node or token in the current subtree that fully
482-
/// contains the range. If the range is empty and is contained in two leaf
483-
/// nodes, either one can be returned. Precondition: range must be contained
484-
/// withing the current node
485462
pub fn covering_element(&self, range: TextRange) -> SyntaxElement {
486463
let mut res: SyntaxElement = self.clone().into();
487464
loop {
@@ -493,28 +470,36 @@ impl SyntaxNode {
493470
);
494471
res = match &res {
495472
NodeOrToken::Token(_) => return res,
496-
NodeOrToken::Node(node) => {
497-
match node
498-
.children_with_tokens()
499-
.find(|child| child.text_range().contains_range(range))
500-
{
501-
Some(child) => child,
502-
None => return res,
503-
}
504-
}
473+
NodeOrToken::Node(node) => match node.child_or_token_at_range(range) {
474+
Some(it) => it,
475+
None => return res,
476+
},
505477
};
506478
}
507479
}
480+
481+
pub fn child_or_token_at_range(&self, range: TextRange) -> Option<SyntaxElement> {
482+
let start_offset = self.text_range().start();
483+
let (index, offset, child) = self.green().child_at_range(range - start_offset)?;
484+
let index = index as u32;
485+
let offset = offset + start_offset;
486+
let res: SyntaxElement = match child {
487+
NodeOrToken::Node(node) => {
488+
let data =
489+
NodeData::new(Kind::Child { parent: self.clone(), index, offset }, node.into());
490+
SyntaxNode::new(data).into()
491+
}
492+
NodeOrToken::Token(_token) => SyntaxToken::new(self.clone(), index, offset).into(),
493+
};
494+
Some(res)
495+
}
508496
}
509497

510498
impl SyntaxToken {
511499
fn new(parent: SyntaxNode, index: u32, offset: TextSize) -> SyntaxToken {
512500
SyntaxToken { parent, index, offset }
513501
}
514502

515-
/// Returns a green tree, equal to the green tree this token
516-
/// belongs two, except with this token substitute. The complexity
517-
/// of operation is proportional to the depth of the tree
518503
pub fn replace_with(&self, replacement: GreenToken) -> GreenNode {
519504
assert_eq!(self.kind(), replacement.kind());
520505
let mut replacement = Some(replacement);
@@ -588,7 +573,6 @@ impl SyntaxToken {
588573
})
589574
}
590575

591-
/// Next token in the tree (i.e, not necessary a sibling)
592576
pub fn next_token(&self) -> Option<SyntaxToken> {
593577
match self.next_sibling_or_token() {
594578
Some(element) => element.first_token(),
@@ -599,7 +583,7 @@ impl SyntaxToken {
599583
.and_then(|element| element.first_token()),
600584
}
601585
}
602-
/// Previous token in the tree (i.e, not necessary a sibling)
586+
603587
pub fn prev_token(&self) -> Option<SyntaxToken> {
604588
match self.prev_sibling_or_token() {
605589
Some(element) => element.last_token(),

src/green.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ mod token;
33
mod element;
44
mod builder;
55

6+
use self::element::GreenElement;
67
pub(crate) use self::element::GreenElementRef;
7-
use self::element::{GreenElement, PackedGreenElement};
88

99
pub use self::{
1010
builder::{Checkpoint, GreenNodeBuilder, NodeCache},
@@ -26,7 +26,6 @@ mod tests {
2626
f::<GreenNode>();
2727
f::<GreenToken>();
2828
f::<GreenElement>();
29-
f::<PackedGreenElement>();
3029
}
3130

3231
#[test]
@@ -36,6 +35,5 @@ mod tests {
3635
eprintln!("GreenNode {}", size_of::<GreenNode>());
3736
eprintln!("GreenToken {}", size_of::<GreenToken>());
3837
eprintln!("GreenElement {}", size_of::<GreenElement>());
39-
eprintln!("PackedGreenElement {}", size_of::<PackedGreenElement>());
4038
}
4139
}

0 commit comments

Comments
 (0)