From dafe747dcc069084fc8bc771c5dcf72e7cb9ec23 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 6 Nov 2018 20:56:32 +0300 Subject: [PATCH] upstream basic tree algorithms to rowan --- Cargo.lock | 6 +- crates/ra_syntax/Cargo.toml | 2 +- crates/ra_syntax/src/algo/mod.rs | 113 ++--------------------------- crates/ra_syntax/src/yellow/mod.rs | 2 +- 4 files changed, 13 insertions(+), 110 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fd1fb5ea5a..80fbda23c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,7 +674,7 @@ dependencies = [ "drop_bomb 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "rowan 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rowan 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -795,7 +795,7 @@ dependencies = [ [[package]] name = "rowan" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1346,7 +1346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum relative-path 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0e7790c7f1cc73d831d28dc5a7deb316a006e7848e6a7f467cdb10a0a9e0fb1c" "checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" "checksum ron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c48677d8a9247a4e0d1f3f9cb4b0a8e29167fdc3c04f383a5e669cd7a960ae0f" -"checksum rowan 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4bb1f952404091f61bfea7cd09c564090a0fcee3d22223f98084e8756e01c04d" +"checksum rowan 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "795b1c830f5335e89f93415315518e9727307308c44c1e5adebe8a38f856c334" "checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395" "checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index de4b25e673..97d2595709 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml @@ -12,7 +12,7 @@ unicode-xid = "0.1.0" itertools = "0.7.8" drop_bomb = "0.1.4" parking_lot = "0.6.0" -rowan = "0.1.1" +rowan = "0.1.2" text_unit = "0.1.5" [dev-dependencies] diff --git a/crates/ra_syntax/src/algo/mod.rs b/crates/ra_syntax/src/algo/mod.rs index faf5a62111..4b3548ea9d 100644 --- a/crates/ra_syntax/src/algo/mod.rs +++ b/crates/ra_syntax/src/algo/mod.rs @@ -1,116 +1,19 @@ pub mod visit; -// pub mod walk; -use crate::{text_utils::contains_offset_nonstrict, SyntaxNodeRef, TextRange, TextUnit}; +use crate::{SyntaxNode, SyntaxNodeRef, TextRange, TextUnit}; -pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { - let range = node.range(); - assert!( - contains_offset_nonstrict(range, offset), - "Bad offset: range {:?} offset {:?}", - range, - offset - ); - if range.is_empty() { - return LeafAtOffset::None; - } +pub use rowan::LeafAtOffset; - if node.is_leaf() { - return LeafAtOffset::Single(node); - } - - let mut children = node.children().filter(|child| { - let child_range = child.range(); - !child_range.is_empty() && contains_offset_nonstrict(child_range, offset) - }); - - let left = children.next().unwrap(); - let right = children.next(); - assert!(children.next().is_none()); - - if let Some(right) = right { - match ( - find_leaf_at_offset(left, offset), - find_leaf_at_offset(right, offset), - ) { - (LeafAtOffset::Single(left), LeafAtOffset::Single(right)) => { - LeafAtOffset::Between(left, right) - } - _ => unreachable!(), - } - } else { - find_leaf_at_offset(left, offset) - } -} - -#[derive(Clone, Debug)] -pub enum LeafAtOffset<'a> { - None, - Single(SyntaxNodeRef<'a>), - Between(SyntaxNodeRef<'a>, SyntaxNodeRef<'a>), -} - -impl<'a> LeafAtOffset<'a> { - pub fn right_biased(self) -> Option> { - match self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => Some(node), - LeafAtOffset::Between(_, right) => Some(right), - } - } - - pub fn left_biased(self) -> Option> { - match self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => Some(node), - LeafAtOffset::Between(left, _) => Some(left), - } - } -} - -impl<'f> Iterator for LeafAtOffset<'f> { - type Item = SyntaxNodeRef<'f>; - - fn next(&mut self) -> Option> { - match *self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => { - *self = LeafAtOffset::None; - Some(node) - } - LeafAtOffset::Between(left, right) => { - *self = LeafAtOffset::Single(right); - Some(left) - } - } +pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { + match node.0.leaf_at_offset(offset) { + LeafAtOffset::None => LeafAtOffset::None, + LeafAtOffset::Single(n) => LeafAtOffset::Single(SyntaxNode(n)), + LeafAtOffset::Between(l, r) => LeafAtOffset::Between(SyntaxNode(l), SyntaxNode(r)), } } pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef { - assert!( - range.is_subrange(&root.range()), - "node range: {:?}, target range: {:?}", - root.range(), - range, - ); - let (left, right) = match ( - find_leaf_at_offset(root, range.start()).right_biased(), - find_leaf_at_offset(root, range.end()).left_biased(), - ) { - (Some(l), Some(r)) => (l, r), - _ => return root, - }; - - common_ancestor(left, right) -} - -fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { - for p in n1.ancestors() { - if n2.ancestors().any(|a| a == p) { - return p; - } - } - panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) + SyntaxNode(root.0.covering_node(range)) } pub fn generate(seed: Option, step: impl Fn(&T) -> Option) -> impl Iterator { diff --git a/crates/ra_syntax/src/yellow/mod.rs b/crates/ra_syntax/src/yellow/mod.rs index 6da9486489..cacd89dc89 100644 --- a/crates/ra_syntax/src/yellow/mod.rs +++ b/crates/ra_syntax/src/yellow/mod.rs @@ -27,7 +27,7 @@ pub type RefRoot<'a> = ::rowan::RefRoot<'a, RaTypes>; pub type GreenNode = ::rowan::GreenNode; #[derive(Clone, Copy)] -pub struct SyntaxNode = OwnedRoot>(::rowan::SyntaxNode); +pub struct SyntaxNode = OwnedRoot>(pub(crate) ::rowan::SyntaxNode); pub type SyntaxNodeRef<'a> = SyntaxNode>; impl PartialEq> for SyntaxNode