From 7b901f86cd1d0198994e5a2ab7eea18f444dd148 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 23 Jan 2019 17:37:10 +0300 Subject: move SyntaxPtr to ra_syntax --- crates/ra_db/src/lib.rs | 2 - crates/ra_db/src/syntax_ptr.rs | 52 --------------------- .../ra_hir/src/code_model_impl/function/scope.rs | 13 +++--- crates/ra_hir/src/expr.rs | 50 ++++++++++---------- crates/ra_hir/src/macros.rs | 13 +++--- crates/ra_hir/src/nameres/lower.rs | 10 ++-- crates/ra_hir/src/ty/tests.rs | 2 +- crates/ra_ide_api/src/call_info.rs | 4 +- crates/ra_ide_api/src/imp.rs | 2 +- crates/ra_ide_api/src/symbol_index.rs | 14 +++--- crates/ra_syntax/src/lib.rs | 2 + crates/ra_syntax/src/ptr.rs | 53 ++++++++++++++++++++++ 12 files changed, 109 insertions(+), 108 deletions(-) delete mode 100644 crates/ra_db/src/syntax_ptr.rs create mode 100644 crates/ra_syntax/src/ptr.rs diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index dbeb9ec71..32d7e09b9 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs @@ -1,6 +1,5 @@ //! ra_db defines basic database traits. The concrete DB is defined by ra_ide_api. mod cancellation; -mod syntax_ptr; mod input; mod loc2id; pub mod mock; @@ -12,7 +11,6 @@ use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; pub use ::salsa as salsa; pub use crate::{ cancellation::Canceled, - syntax_ptr::LocalSyntaxPtr, input::{ FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, FileTextQuery, FileSourceRootQuery, SourceRootQuery, LocalRootsQuery, LibraryRootsQuery, CrateGraphQuery, diff --git a/crates/ra_db/src/syntax_ptr.rs b/crates/ra_db/src/syntax_ptr.rs deleted file mode 100644 index 5270826da..000000000 --- a/crates/ra_db/src/syntax_ptr.rs +++ /dev/null @@ -1,52 +0,0 @@ -use ra_syntax::{AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, TreeArc}; - -/// A pointer to a syntax node inside a file. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct LocalSyntaxPtr { - range: TextRange, - kind: SyntaxKind, -} - -impl LocalSyntaxPtr { - pub fn new(node: &SyntaxNode) -> LocalSyntaxPtr { - LocalSyntaxPtr { - range: node.range(), - kind: node.kind(), - } - } - - pub fn resolve(self, file: &SourceFile) -> TreeArc { - let mut curr = file.syntax(); - loop { - if curr.range() == self.range && curr.kind() == self.kind { - return curr.to_owned(); - } - curr = curr - .children() - .find(|it| self.range.is_subrange(&it.range())) - .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) - } - } - - pub fn range(self) -> TextRange { - self.range - } - - pub fn kind(self) -> SyntaxKind { - self.kind - } -} - -#[test] -fn test_local_syntax_ptr() { - use ra_syntax::{ast, AstNode}; - let file = SourceFile::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_hir/src/code_model_impl/function/scope.rs b/crates/ra_hir/src/code_model_impl/function/scope.rs index 3a7d53a93..c5d1de5eb 100644 --- a/crates/ra_hir/src/code_model_impl/function/scope.rs +++ b/crates/ra_hir/src/code_model_impl/function/scope.rs @@ -3,12 +3,11 @@ use std::sync::Arc; use rustc_hash::{FxHashMap, FxHashSet}; use ra_syntax::{ - AstNode, SyntaxNode, TextUnit, TextRange, + AstNode, SyntaxNode, TextUnit, TextRange, SyntaxNodePtr, algo::generate, ast, }; use ra_arena::{Arena, RawId, impl_arena_id}; -use ra_db::LocalSyntaxPtr; use crate::{Name, AsName, expr::{PatId, ExprId, Pat, Expr, Body, Statement, BodySyntaxMapping}}; @@ -126,7 +125,7 @@ pub struct ScopesWithSyntaxMapping { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ScopeEntryWithSyntax { name: Name, - ptr: LocalSyntaxPtr, + ptr: SyntaxNodePtr, } impl ScopeEntryWithSyntax { @@ -134,7 +133,7 @@ impl ScopeEntryWithSyntax { &self.name } - pub fn ptr(&self) -> LocalSyntaxPtr { + pub fn ptr(&self) -> SyntaxNodePtr { self.ptr } } @@ -169,7 +168,7 @@ impl ScopesWithSyntaxMapping { // XXX: during completion, cursor might be outside of any particular // expression. Try to figure out the correct scope... - fn adjust(&self, ptr: LocalSyntaxPtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { + fn adjust(&self, ptr: SyntaxNodePtr, original_scope: ScopeId, offset: TextUnit) -> ScopeId { let r = ptr.range(); let child_scopes = self .scopes @@ -212,7 +211,7 @@ impl ScopesWithSyntaxMapping { pub fn find_all_refs(&self, pat: &ast::BindPat) -> Vec { let fn_def = pat.syntax().ancestors().find_map(ast::FnDef::cast).unwrap(); - let name_ptr = LocalSyntaxPtr::new(pat.syntax()); + let name_ptr = SyntaxNodePtr::new(pat.syntax()); fn_def .syntax() .descendants() @@ -230,7 +229,7 @@ impl ScopesWithSyntaxMapping { fn scope_for(&self, node: &SyntaxNode) -> Option { node.ancestors() - .map(LocalSyntaxPtr::new) + .map(SyntaxNodePtr::new) .filter_map(|ptr| self.syntax_mapping.syntax_expr(ptr)) .find_map(|it| self.scopes.scope_for(it)) } diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 51dae8e25..1a3821692 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -4,8 +4,10 @@ use std::sync::Arc; use rustc_hash::FxHashMap; use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; -use ra_db::LocalSyntaxPtr; -use ra_syntax::ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor}; +use ra_syntax::{ + SyntaxNodePtr, AstNode, + ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor} +}; use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; @@ -38,10 +40,10 @@ pub struct Body { #[derive(Debug, Eq, PartialEq)] pub struct BodySyntaxMapping { body: Arc, - expr_syntax_mapping: FxHashMap, - expr_syntax_mapping_back: ArenaMap, - pat_syntax_mapping: FxHashMap, - pat_syntax_mapping_back: ArenaMap, + expr_syntax_mapping: FxHashMap, + expr_syntax_mapping_back: ArenaMap, + pat_syntax_mapping: FxHashMap, + pat_syntax_mapping_back: ArenaMap, } impl Body { @@ -71,31 +73,31 @@ impl Index for Body { } impl BodySyntaxMapping { - pub fn expr_syntax(&self, expr: ExprId) -> Option { + pub fn expr_syntax(&self, expr: ExprId) -> Option { self.expr_syntax_mapping_back.get(expr).cloned() } - pub fn syntax_expr(&self, ptr: LocalSyntaxPtr) -> Option { + pub fn syntax_expr(&self, ptr: SyntaxNodePtr) -> Option { self.expr_syntax_mapping.get(&ptr).cloned() } pub fn node_expr(&self, node: &ast::Expr) -> Option { self.expr_syntax_mapping - .get(&LocalSyntaxPtr::new(node.syntax())) + .get(&SyntaxNodePtr::new(node.syntax())) .cloned() } - pub fn pat_syntax(&self, pat: PatId) -> Option { + pub fn pat_syntax(&self, pat: PatId) -> Option { self.pat_syntax_mapping_back.get(pat).cloned() } - pub fn syntax_pat(&self, ptr: LocalSyntaxPtr) -> Option { + pub fn syntax_pat(&self, ptr: SyntaxNodePtr) -> Option { self.pat_syntax_mapping.get(&ptr).cloned() } pub fn node_pat(&self, node: &ast::Pat) -> Option { self.pat_syntax_mapping - .get(&LocalSyntaxPtr::new(node.syntax())) + .get(&SyntaxNodePtr::new(node.syntax())) .cloned() } @@ -440,10 +442,10 @@ pub(crate) fn body_hir(db: &impl HirDatabase, def_id: DefId) -> Arc { struct ExprCollector { exprs: Arena, pats: Arena, - expr_syntax_mapping: FxHashMap, - expr_syntax_mapping_back: ArenaMap, - pat_syntax_mapping: FxHashMap, - pat_syntax_mapping_back: ArenaMap, + expr_syntax_mapping: FxHashMap, + expr_syntax_mapping_back: ArenaMap, + pat_syntax_mapping: FxHashMap, + pat_syntax_mapping_back: ArenaMap, } impl ExprCollector { @@ -458,14 +460,14 @@ impl ExprCollector { } } - fn alloc_expr(&mut self, expr: Expr, syntax_ptr: LocalSyntaxPtr) -> ExprId { + fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId { let id = self.exprs.alloc(expr); self.expr_syntax_mapping.insert(syntax_ptr, id); self.expr_syntax_mapping_back.insert(id, syntax_ptr); id } - fn alloc_pat(&mut self, pat: Pat, syntax_ptr: LocalSyntaxPtr) -> PatId { + fn alloc_pat(&mut self, pat: Pat, syntax_ptr: SyntaxNodePtr) -> PatId { let id = self.pats.alloc(pat); self.pat_syntax_mapping.insert(syntax_ptr, id); self.pat_syntax_mapping_back.insert(id, syntax_ptr); @@ -481,7 +483,7 @@ impl ExprCollector { } fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId { - let syntax_ptr = LocalSyntaxPtr::new(expr.syntax()); + let syntax_ptr = SyntaxNodePtr::new(expr.syntax()); match expr.kind() { ast::ExprKind::IfExpr(e) => { if let Some(pat) = e.condition().and_then(|c| c.pat()) { @@ -643,9 +645,9 @@ impl ExprCollector { // field shorthand let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr))); self.expr_syntax_mapping - .insert(LocalSyntaxPtr::new(nr.syntax()), id); + .insert(SyntaxNodePtr::new(nr.syntax()), id); self.expr_syntax_mapping_back - .insert(id, LocalSyntaxPtr::new(nr.syntax())); + .insert(id, SyntaxNodePtr::new(nr.syntax())); id } else { self.exprs.alloc(Expr::Missing) @@ -806,7 +808,7 @@ impl ExprCollector { let tail = block.expr().map(|e| self.collect_expr(e)); self.alloc_expr( Expr::Block { statements, tail }, - LocalSyntaxPtr::new(block.syntax()), + SyntaxNodePtr::new(block.syntax()), ) } @@ -883,7 +885,7 @@ impl ExprCollector { // TODO: implement ast::PatKind::SlicePat(_) | ast::PatKind::RangePat(_) => Pat::Missing, }; - let syntax_ptr = LocalSyntaxPtr::new(pat.syntax()); + let syntax_ptr = SyntaxNodePtr::new(pat.syntax()); self.alloc_pat(pattern, syntax_ptr) } @@ -919,7 +921,7 @@ pub(crate) fn collect_fn_body_syntax(node: &ast::FnDef) -> BodySyntaxMapping { let mut params = Vec::new(); if let Some(self_param) = param_list.self_param() { - let self_param = LocalSyntaxPtr::new( + let self_param = SyntaxNodePtr::new( self_param .self_kw() .expect("self param without self keyword") diff --git a/crates/ra_hir/src/macros.rs b/crates/ra_hir/src/macros.rs index 220bee94e..7ca34d434 100644 --- a/crates/ra_hir/src/macros.rs +++ b/crates/ra_hir/src/macros.rs @@ -9,9 +9,8 @@ /// those yet, so all macros are string based at the moment! use std::sync::Arc; -use ra_db::LocalSyntaxPtr; use ra_syntax::{ - TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, + TextRange, TextUnit, SourceFile, AstNode, SyntaxNode, TreeArc, SyntaxNodePtr, ast::{self, NameOwner}, }; @@ -80,7 +79,7 @@ impl MacroDef { let file = SourceFile::parse(&text); let match_expr = file.syntax().descendants().find_map(ast::MatchExpr::cast)?; let match_arg = match_expr.expr()?; - let ptr = LocalSyntaxPtr::new(match_arg.syntax()); + let ptr = SyntaxNodePtr::new(match_arg.syntax()); let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); let ranges_map = vec![(src_range, match_arg.syntax().range())]; let res = MacroExpansion { @@ -94,7 +93,7 @@ impl MacroDef { let text = format!(r"fn dummy() {{ {}; }}", input.text); let file = SourceFile::parse(&text); let array_expr = file.syntax().descendants().find_map(ast::ArrayExpr::cast)?; - let ptr = LocalSyntaxPtr::new(array_expr.syntax()); + let ptr = SyntaxNodePtr::new(array_expr.syntax()); let src_range = TextRange::offset_len(0.into(), TextUnit::of_str(&input.text)); let ranges_map = vec![(src_range, array_expr.syntax().range())]; let res = MacroExpansion { @@ -119,7 +118,7 @@ impl MacroDef { let file = SourceFile::parse(&text); let trait_def = file.syntax().descendants().find_map(ast::TraitDef::cast)?; let name = trait_def.name()?; - let ptr = LocalSyntaxPtr::new(trait_def.syntax()); + let ptr = SyntaxNodePtr::new(trait_def.syntax()); let ranges_map = vec![(src_range, name.syntax().range())]; let res = MacroExpansion { text, @@ -146,7 +145,7 @@ pub struct MacroExpansion { /// Implementation detail: internally, a macro is expanded to the whole file, /// even if it is an expression. This `ptr` selects the actual expansion from /// the expanded file. - ptr: LocalSyntaxPtr, + ptr: SyntaxNodePtr, } impl MacroExpansion { @@ -157,7 +156,7 @@ impl MacroExpansion { } pub fn syntax(&self) -> TreeArc { - self.ptr.resolve(&self.file()) + self.ptr.to_node(&self.file()).to_owned() } /// Maps range in the source code to the range in the expanded code. pub fn map_range_forward(&self, src_range: TextRange) -> Option { diff --git a/crates/ra_hir/src/nameres/lower.rs b/crates/ra_hir/src/nameres/lower.rs index 52448644c..ab6f3a9bc 100644 --- a/crates/ra_hir/src/nameres/lower.rs +++ b/crates/ra_hir/src/nameres/lower.rs @@ -1,10 +1,10 @@ use std::sync::Arc; use ra_syntax::{ - SyntaxKind, AstNode, SourceFile, TreeArc, + SyntaxKind, AstNode, SourceFile, TreeArc, SyntaxNodePtr, ast::{self, ModuleItemOwner}, }; -use ra_db::{SourceRootId, LocalSyntaxPtr}; +use ra_db::{SourceRootId}; use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; use crate::{ @@ -72,13 +72,13 @@ pub struct LoweredModule { #[derive(Debug, Default, PartialEq, Eq)] pub struct ImportSourceMap { - map: ArenaMap, + map: ArenaMap, } impl ImportSourceMap { fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { self.map - .insert(import, LocalSyntaxPtr::new(segment.syntax())) + .insert(import, SyntaxNodePtr::new(segment.syntax())) } pub fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc { @@ -87,7 +87,7 @@ impl ImportSourceMap { ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), }; - ast::PathSegment::cast(&self.map[import].resolve(file)) + ast::PathSegment::cast(self.map[import].to_node(file)) .unwrap() .to_owned() } diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 9bf1fd3b2..92c74cf00 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -562,7 +562,7 @@ fn infer(content: &str) -> String { // sort ranges for consistency types.sort_by_key(|(ptr, _)| (ptr.range().start(), ptr.range().end())); for (syntax_ptr, ty) in &types { - let node = syntax_ptr.resolve(&source_file); + let node = syntax_ptr.to_node(&source_file); write!( acc, "{} '{}': {}\n", diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 798fb7c13..0449c1902 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -23,8 +23,8 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option(syntax, resolved.range().end())?; Some((binding, descr)) } diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index b563dfe88..1b5d1eb1d 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs @@ -27,13 +27,13 @@ use std::{ use fst::{self, Streamer}; use ra_syntax::{ - SyntaxNode, SourceFile, SmolStr, TreeArc, AstNode, + SyntaxNode, SyntaxNodePtr, SourceFile, SmolStr, TreeArc, AstNode, algo::{visit::{visitor, Visitor}, find_covering_node}, SyntaxKind::{self, *}, ast::{self, NameOwner}, }; use ra_db::{ - SourceRootId, FilesDatabase, LocalSyntaxPtr, + SourceRootId, FilesDatabase, salsa::{self, ParallelDatabase}, }; use rayon::prelude::*; @@ -62,7 +62,7 @@ fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Arc for (name, text_range) in hir::source_binder::macro_symbols(db, file_id) { let node = find_covering_node(source_file.syntax(), text_range); - let ptr = LocalSyntaxPtr::new(node); + let ptr = SyntaxNodePtr::new(node); symbols.push(FileSymbol { file_id, name, ptr }) } @@ -196,13 +196,13 @@ fn is_type(kind: SyntaxKind) -> bool { pub(crate) struct FileSymbol { pub(crate) file_id: FileId, pub(crate) name: SmolStr, - pub(crate) ptr: LocalSyntaxPtr, + pub(crate) ptr: SyntaxNodePtr, } -fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, LocalSyntaxPtr)> { - fn decl(node: &N) -> Option<(SmolStr, LocalSyntaxPtr)> { +fn to_symbol(node: &SyntaxNode) -> Option<(SmolStr, SyntaxNodePtr)> { + fn decl(node: &N) -> Option<(SmolStr, SyntaxNodePtr)> { let name = node.name()?.text().clone(); - let ptr = LocalSyntaxPtr::new(node.syntax()); + let ptr = SyntaxNodePtr::new(node.syntax()); Some((name, ptr)) } visitor() diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index bc311cbbc..97b196118 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -35,6 +35,7 @@ mod syntax_kinds; pub mod utils; mod validation; mod yellow; +mod ptr; pub use rowan::{SmolStr, TextRange, TextUnit}; pub use crate::{ @@ -42,6 +43,7 @@ pub use crate::{ lexer::{tokenize, Token}, syntax_kinds::SyntaxKind, yellow::{Direction, SyntaxError, SyntaxNode, WalkEvent, Location, TreeArc}, + ptr::SyntaxNodePtr, }; use ra_text_edit::AtomTextEdit; diff --git a/crates/ra_syntax/src/ptr.rs b/crates/ra_syntax/src/ptr.rs new file mode 100644 index 000000000..e8c40e5d3 --- /dev/null +++ b/crates/ra_syntax/src/ptr.rs @@ -0,0 +1,53 @@ +use crate::{ + AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, + algo::generate, +}; + +/// A pointer to a syntax node inside a file. It can be used to remember a +/// specific node across reparses of the same file. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct SyntaxNodePtr { + range: TextRange, + kind: SyntaxKind, +} + +impl SyntaxNodePtr { + pub fn new(node: &SyntaxNode) -> SyntaxNodePtr { + SyntaxNodePtr { + range: node.range(), + kind: node.kind(), + } + } + + pub fn to_node(self, source_file: &SourceFile) -> &SyntaxNode { + generate(Some(source_file.syntax()), |&node| { + node.children() + .find(|it| self.range.is_subrange(&it.range())) + }) + .find(|it| it.range() == self.range && it.kind() == self.kind) + .unwrap_or_else(|| panic!("can't resolve local ptr to SyntaxNode: {:?}", self)) + } + + pub fn range(self) -> TextRange { + self.range + } + + pub fn kind(self) -> SyntaxKind { + self.kind + } +} + +#[test] +fn test_local_syntax_ptr() { + use crate::{ast, AstNode}; + + let file = SourceFile::parse("struct Foo { f: u32, }"); + let field = file + .syntax() + .descendants() + .find_map(ast::NamedFieldDef::cast) + .unwrap(); + let ptr = SyntaxNodePtr::new(field.syntax()); + let field_syntax = ptr.to_node(&file); + assert_eq!(field.syntax(), &*field_syntax); +} -- cgit v1.2.3