From 950e8b8182897da60bcece70d84e9f0b6dc88632 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 30 Oct 2018 21:23:23 +0300 Subject: introduce syntax-ptr --- Cargo.lock | 11 +++--- crates/ra_analysis/src/lib.rs | 1 + crates/ra_analysis/src/syntax_ptr.rs | 67 ++++++++++++++++++++++++++++++++++++ crates/ra_syntax/Cargo.toml | 1 + 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 crates/ra_analysis/src/syntax_ptr.rs diff --git a/Cargo.lock b/Cargo.lock index 16eaf3738..88c7ba356 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -661,7 +661,7 @@ dependencies = [ "serde_json 1.0.32 (registry+https://github.com/rust-lang/crates.io-index)", "smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -675,6 +675,7 @@ dependencies = [ "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)", "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)", "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -798,7 +799,7 @@ 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)", "smol_str 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1038,12 +1039,12 @@ version = "0.1.0" dependencies = [ "difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", - "text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "text_unit" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1372,7 +1373,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tera 0.11.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6c87cae42cc4fc480278c7583792cc5da2d51a25be916b7921cbb45c43063b8d" "checksum teraron 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0d89ad4617d1dec55331067fadaa041e813479e1779616f3d3ce9308bf46184e" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum text_unit 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "93fc86da66d0b9aa8d359b0ec31b4342c6bc52637eadef05b91b098551a9f8e9" +"checksum text_unit 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8009d7bdbd896a7e09b595f8f9325a19047fc708653e60d0895202b82135048f" "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" "checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b" diff --git a/crates/ra_analysis/src/lib.rs b/crates/ra_analysis/src/lib.rs index a67cac21e..363c72c0b 100644 --- a/crates/ra_analysis/src/lib.rs +++ b/crates/ra_analysis/src/lib.rs @@ -12,6 +12,7 @@ mod descriptors; mod imp; mod symbol_index; mod completion; +mod syntax_ptr; use std::{ fmt, diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_analysis/src/syntax_ptr.rs new file mode 100644 index 000000000..863ad2672 --- /dev/null +++ b/crates/ra_analysis/src/syntax_ptr.rs @@ -0,0 +1,67 @@ +use ra_syntax::{ + File, TextRange, SyntaxKind, SyntaxNode, SyntaxNodeRef, + ast::{self, AstNode}, +}; + +use crate::FileId; +use crate::db::SyntaxDatabase; + +/// SyntaxPtr is a cheap `Copy` id which identifies a particular syntax node, +/// without retainig syntax tree in memory. You need to explicitelly `resovle` +/// `SyntaxPtr` to get a `SyntaxNode` +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub(crate) struct SyntaxPtr { + file_id: FileId, + local: LocalSyntaxPtr, +} + +impl SyntaxPtr { + pub(crate) fn new(file_id: FileId, node: SyntaxNodeRef) -> SyntaxPtr { + let local = LocalSyntaxPtr::new(node); + SyntaxPtr { file_id, local } + } + + pub(crate) fn resolve(self, db: &impl SyntaxDatabase) -> SyntaxNode { + let syntax = db.file_syntax(self.file_id); + self.local.resolve(&syntax) + } +} + + +/// A pionter to a syntax node inside a file. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +struct LocalSyntaxPtr { + range: TextRange, + kind: SyntaxKind, +} + +impl LocalSyntaxPtr { + fn new(node: SyntaxNodeRef) -> LocalSyntaxPtr { + LocalSyntaxPtr { + range: node.range(), + kind: node.kind(), + } + } + + fn resolve(self, file: &File) -> SyntaxNode { + let mut curr = file.syntax(); + loop { + if curr.range() == self.range && curr.kind() == self.kind { + return curr.owned(); + } + curr = curr.children() + .find(|it| self.range.is_subrange(&it.range())) + .unwrap_or_else(|| panic!("can't resovle local ptr to SyntaxNode: {:?}", self)) + } + } +} + + +#[test] +fn test_local_syntax_ptr() { + let file = File::parse("struct Foo { f: u32, }"); + let field = file.syntax().descendants().find_map(ast::NamedFieldDef::cast).unwrap(); + let ptr = LocalSyntaxPtr::new(field.syntax()); + let field_syntax = ptr.resolve(&file); + assert_eq!(field.syntax(), field_syntax); +} diff --git a/crates/ra_syntax/Cargo.toml b/crates/ra_syntax/Cargo.toml index 7efebab8b..043c9bacd 100644 --- a/crates/ra_syntax/Cargo.toml +++ b/crates/ra_syntax/Cargo.toml @@ -11,6 +11,7 @@ itertools = "0.7.8" drop_bomb = "0.1.4" parking_lot = "0.6.0" rowan = "0.1.1" +text_unit = "0.1.5" [dev-dependencies] test_utils = { path = "../test_utils" } -- cgit v1.2.3