aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_analysis/src/syntax_ptr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_analysis/src/syntax_ptr.rs')
-rw-r--r--crates/ra_analysis/src/syntax_ptr.rs45
1 files changed, 37 insertions, 8 deletions
diff --git a/crates/ra_analysis/src/syntax_ptr.rs b/crates/ra_analysis/src/syntax_ptr.rs
index 863ad2672..adbff4806 100644
--- a/crates/ra_analysis/src/syntax_ptr.rs
+++ b/crates/ra_analysis/src/syntax_ptr.rs
@@ -1,3 +1,5 @@
1use std::marker::PhantomData;
2
1use ra_syntax::{ 3use ra_syntax::{
2 File, TextRange, SyntaxKind, SyntaxNode, SyntaxNodeRef, 4 File, TextRange, SyntaxKind, SyntaxNode, SyntaxNodeRef,
3 ast::{self, AstNode}, 5 ast::{self, AstNode},
@@ -6,10 +8,24 @@ use ra_syntax::{
6use crate::FileId; 8use crate::FileId;
7use crate::db::SyntaxDatabase; 9use crate::db::SyntaxDatabase;
8 10
11salsa::query_group! {
12 pub(crate) trait SyntaxPtrDatabase: SyntaxDatabase {
13 fn resolve_syntax_ptr(ptr: SyntaxPtr) -> SyntaxNode {
14 type ResolveSyntaxPtrQuery;
15 storage volatile;
16 }
17 }
18}
19
20fn resolve_syntax_ptr(db: &impl SyntaxDatabase, ptr: SyntaxPtr) -> SyntaxNode {
21 let syntax = db.file_syntax(ptr.file_id);
22 ptr.local.resolve(&syntax)
23}
24
9/// SyntaxPtr is a cheap `Copy` id which identifies a particular syntax node, 25/// SyntaxPtr is a cheap `Copy` id which identifies a particular syntax node,
10/// without retainig syntax tree in memory. You need to explicitelly `resovle` 26/// without retainig syntax tree in memory. You need to explicitelly `resovle`
11/// `SyntaxPtr` to get a `SyntaxNode` 27/// `SyntaxPtr` to get a `SyntaxNode`
12#[derive(Debug, Clone, Copy, PartialEq, Eq)] 28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
13pub(crate) struct SyntaxPtr { 29pub(crate) struct SyntaxPtr {
14 file_id: FileId, 30 file_id: FileId,
15 local: LocalSyntaxPtr, 31 local: LocalSyntaxPtr,
@@ -20,30 +36,43 @@ impl SyntaxPtr {
20 let local = LocalSyntaxPtr::new(node); 36 let local = LocalSyntaxPtr::new(node);
21 SyntaxPtr { file_id, local } 37 SyntaxPtr { file_id, local }
22 } 38 }
39}
40
41struct OwnedAst<T> {
42 syntax: SyntaxNode,
43 phantom: PhantomData<T>,
44}
45
46trait ToAst {
47 type Ast;
48 fn to_ast(self) -> Self::Ast;
49}
23 50
24 pub(crate) fn resolve(self, db: &impl SyntaxDatabase) -> SyntaxNode { 51impl<'a> ToAst for &'a OwnedAst<ast::FnDef<'static>> {
25 let syntax = db.file_syntax(self.file_id); 52 type Ast = ast::FnDef<'a>;
26 self.local.resolve(&syntax) 53 fn to_ast(self) -> ast::FnDef<'a> {
54 ast::FnDef::cast(self.syntax.borrowed())
55 .unwrap()
27 } 56 }
28} 57}
29 58
30 59
31/// A pionter to a syntax node inside a file. 60/// A pionter to a syntax node inside a file.
32#[derive(Debug, Clone, Copy, PartialEq, Eq)] 61#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
33struct LocalSyntaxPtr { 62pub(crate) struct LocalSyntaxPtr {
34 range: TextRange, 63 range: TextRange,
35 kind: SyntaxKind, 64 kind: SyntaxKind,
36} 65}
37 66
38impl LocalSyntaxPtr { 67impl LocalSyntaxPtr {
39 fn new(node: SyntaxNodeRef) -> LocalSyntaxPtr { 68 pub(crate) fn new(node: SyntaxNodeRef) -> LocalSyntaxPtr {
40 LocalSyntaxPtr { 69 LocalSyntaxPtr {
41 range: node.range(), 70 range: node.range(),
42 kind: node.kind(), 71 kind: node.kind(),
43 } 72 }
44 } 73 }
45 74
46 fn resolve(self, file: &File) -> SyntaxNode { 75 pub(crate) fn resolve(self, file: &File) -> SyntaxNode {
47 let mut curr = file.syntax(); 76 let mut curr = file.syntax();
48 loop { 77 loop {
49 if curr.range() == self.range && curr.kind() == self.kind { 78 if curr.range() == self.range && curr.kind() == self.kind {