]> git.lizzy.rs Git - rust.git/commitdiff
introduce syntax-ptr
authorAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 30 Oct 2018 18:23:23 +0000 (21:23 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 30 Oct 2018 18:23:23 +0000 (21:23 +0300)
Cargo.lock
crates/ra_analysis/src/lib.rs
crates/ra_analysis/src/syntax_ptr.rs [new file with mode: 0644]
crates/ra_syntax/Cargo.toml

index 16eaf3738afdfee0b3458e5fac6954c55f90ad5e..88c7ba356c177db719d04685b9456901a3b3e75b 100644 (file)
@@ -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"
index a67cac21ee930fa158301b5b36f3aea4712795a5..363c72c0b774631df822b80cd305d3deae2b057b 100644 (file)
@@ -12,6 +12,7 @@
 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 (file)
index 0000000..863ad26
--- /dev/null
@@ -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);
+}
index 7efebab8bde0637b51a3450b3442ccc339bab57d..043c9bacd85f1e11999bfbac6438cd93f1268bcf 100644 (file)
@@ -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" }