From fbbee537228538f448a335bb0b2dabec2b3d443e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 31 Oct 2018 02:08:54 +0300 Subject: Add ModuleScope as a query This is a first step towards queryifing completion and resolve. Some code currently duplicates ra_editor: the plan is to move all completion from ra_editor, but it'll take more than one commit. --- crates/ra_analysis/src/syntax_ptr.rs | 45 +++++++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'crates/ra_analysis/src/syntax_ptr.rs') 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 @@ +use std::marker::PhantomData; + use ra_syntax::{ File, TextRange, SyntaxKind, SyntaxNode, SyntaxNodeRef, ast::{self, AstNode}, @@ -6,10 +8,24 @@ use ra_syntax::{ use crate::FileId; use crate::db::SyntaxDatabase; +salsa::query_group! { + pub(crate) trait SyntaxPtrDatabase: SyntaxDatabase { + fn resolve_syntax_ptr(ptr: SyntaxPtr) -> SyntaxNode { + type ResolveSyntaxPtrQuery; + storage volatile; + } + } +} + +fn resolve_syntax_ptr(db: &impl SyntaxDatabase, ptr: SyntaxPtr) -> SyntaxNode { + let syntax = db.file_syntax(ptr.file_id); + ptr.local.resolve(&syntax) +} + /// 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)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub(crate) struct SyntaxPtr { file_id: FileId, local: LocalSyntaxPtr, @@ -20,30 +36,43 @@ impl SyntaxPtr { let local = LocalSyntaxPtr::new(node); SyntaxPtr { file_id, local } } +} + +struct OwnedAst { + syntax: SyntaxNode, + phantom: PhantomData, +} + +trait ToAst { + type Ast; + fn to_ast(self) -> Self::Ast; +} - pub(crate) fn resolve(self, db: &impl SyntaxDatabase) -> SyntaxNode { - let syntax = db.file_syntax(self.file_id); - self.local.resolve(&syntax) +impl<'a> ToAst for &'a OwnedAst> { + type Ast = ast::FnDef<'a>; + fn to_ast(self) -> ast::FnDef<'a> { + ast::FnDef::cast(self.syntax.borrowed()) + .unwrap() } } /// A pionter to a syntax node inside a file. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -struct LocalSyntaxPtr { +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct LocalSyntaxPtr { range: TextRange, kind: SyntaxKind, } impl LocalSyntaxPtr { - fn new(node: SyntaxNodeRef) -> LocalSyntaxPtr { + pub(crate) fn new(node: SyntaxNodeRef) -> LocalSyntaxPtr { LocalSyntaxPtr { range: node.range(), kind: node.kind(), } } - fn resolve(self, file: &File) -> SyntaxNode { + pub(crate) fn resolve(self, file: &File) -> SyntaxNode { let mut curr = file.syntax(); loop { if curr.range() == self.range && curr.kind() == self.kind { -- cgit v1.2.3